📄 atamain.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include "atamain.h"
#include <nkintr.h>
#include <ceddk.h>
#include <devload.h>
#include "atapipcmcia.h"
#include "atapipci.h"
#include <promise.h>
#include <ali.h>
#include "XSC1.h"
#include "XSC1bd.h"
#include <drv_glob.h>
#include <oalintr.h>
#include "bcr.h"
#undef ZONE_MAIN
#define ZONE_MAIN 1
EXTERN_C PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);
volatile GPIO_REGS *v_pGPIOReg = NULL;
PDRIVER_GLOBALS v_pDriverGlobals = NULL;
CDisk *g_pDiskRoot = NULL;
CRITICAL_SECTION g_csMain;
extern CController *g_ControllerTable;
extern CPort *g_PortTable;
extern DWORD g_dwControllerIndex;
HINSTANCE g_hInstance=NULL;
BOOL EnableCS4()
{
#define MSCREGS_PHYSADDR 0x48000000
#define MSCREGS_SIZE (4*1024)
#define MSC0_OFFSET 0x08
#define MSC1_OFFSET 0x0c
#define MSC2_OFFSET 0x10
#define CS4_SETUP 0x00007FF8
UINT val;
LPVOID p_mscregs;
DWORD temp;
// map in MSC registers
p_mscregs = VirtualAlloc(0, MSCREGS_SIZE, MEM_RESERVE, PAGE_NOACCESS);
if (!p_mscregs) {
return FALSE;
}
if (!VirtualCopy(p_mscregs, (LPVOID)(MSCREGS_PHYSADDR/256), MSCREGS_SIZE,
PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL)) {
return FALSE;
}
temp = *(volatile unsigned int *)((unsigned int)p_mscregs + MSC2_OFFSET);
DEBUGMSG(1, (TEXT("--------MSC2:----%08X--------------\r\n"),temp));
val = CS4_SETUP;
// modify the setup for CS4
*(volatile unsigned int *)((unsigned int)p_mscregs + MSC2_OFFSET) &= 0xFFFF0000;
*(volatile unsigned int *)((unsigned int)p_mscregs + MSC2_OFFSET) |= val; //CS4_SETUP;
temp = *(volatile unsigned int *)((unsigned int)p_mscregs + MSC2_OFFSET);
DEBUGMSG(1, (TEXT("-----------MSC2:----%08X--------------\r\n"),temp));
return TRUE;
}
BOOL Init_GPIO()
{
if (v_pDriverGlobals == NULL)
{
v_pDriverGlobals = (PDRIVER_GLOBALS)
VirtualAllocCopy(DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,(char *)TEXT("DRIVER_GLOBALS"),
(PVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START);
if (v_pDriverGlobals)
{
if (v_pGPIOReg == NULL)
{
v_pGPIOReg = (volatile GPIO_REGS *)
VirtualAllocCopy(0x400,(char *)TEXT("GPIO_BASE_U_VIRTUAL"),
(PVOID)GPIO_BASE_U_VIRTUAL);
}
}
}
if (!v_pGPIOReg|| !v_pDriverGlobals )
{
if (v_pDriverGlobals)
{
VirtualFree(v_pDriverGlobals,DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,MEM_RELEASE);
v_pDriverGlobals = NULL;
}
if (v_pGPIOReg)
{
VirtualFree((void *)v_pGPIOReg,0x400,MEM_RELEASE);
v_pGPIOReg = NULL;
}
DEBUGMSG(1,(TEXT("Error %u\r\n"),GetLastError()));
return (FALSE);
}
v_pGPIOReg->GAFR0_x &= ~(GPIO_20_AF3);
v_pGPIOReg->GPDR_x &= ~(GPIO_20);
v_pGPIOReg->GRER_x |= (GPIO_20);
v_pGPIOReg->GFER_x &= ~GPIO_20;
EnableCS4();
return TRUE;
}
EXTERN_C CDisk *CreateAli(HKEY hDevKey)
{
return new CAli(hDevKey);
}
EXTERN_C CDisk *CreateGeneric(HKEY hDevKey)
{
return new CPCIDisk(hDevKey);
}
EXTERN_C CDisk *CreatePCMCIA(HKEY hDevKey)
{
#if 0
return new CPCMCIADisk(hDevKey);
#else
return NULL;
#endif
}
EXTERN_C CDisk *CreatePromise(HKEY hDevKey)
{
return new CPromise(hDevKey);
}
typedef CDisk *(* POBJECTFUNCTION)(HKEY hKey);
HKEY AtaLoadRegKey(HKEY hActiveKey, TCHAR **pszDevKey)
{
DWORD dwType;
PTSTR szDevKey = NULL;
DWORD dwValueLen = 0;
HKEY hDevKey = NULL;
// Find out how big the name of the device key is
// Since dwValueLen is 0 and the name is NULL we expect a ERROR_SUCCESS although the doc's
// say that it should return ERROR_MORE_DATA
if (ERROR_SUCCESS == RegQueryValueEx( hActiveKey, DEVLOAD_DEVKEY_VALNAME, NULL, &dwType, NULL, &dwValueLen)) {
szDevKey = (PTSTR)LocalAlloc( LPTR, dwValueLen);
// Read in the KeyName of the device
RegQueryValueEx( hActiveKey, DEVLOAD_DEVKEY_VALNAME, NULL, &dwType, (PBYTE)szDevKey, &dwValueLen);
// Now do the actual open of the key
if (ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, szDevKey, 0, 0, &hDevKey)) {
hDevKey = NULL;
DEBUGMSG( ZONE_INIT, (TEXT("Found a device key name %s but could not open it !!!\r\n"), szDevKey));
}
}
if (!hDevKey) {
LocalFree( szDevKey);
*pszDevKey = NULL;
} else {
*pszDevKey = szDevKey;
}
return hDevKey;
}
BOOL AtaIsValidDisk(CDisk *pDisk)
{
CDisk *pTemp = g_pDiskRoot;
while(pTemp) {
if (pTemp == pDisk)
return TRUE;
pTemp = pTemp->m_pNextDisk;
}
return FALSE;
}
//--------------------------------------------------------------------------
// DSK_Init - This function is called by the Device Manager to initialize a device.
//
// Input: Specifies a pointer to a string containing the registry path to the active
// key for the stream interface driver.
//
// Return: Handle - This handle is passed to the DSK_Open,
// (DSK_PowerDown, DSK_PowerUp,) and DSK_Deinit functions.
// NULL - error.
//
// NOTES The Device Manager calls this function as a result of a call to
// the RegisterDevice function. When the user starts using a device,
// such as when a PC Card is inserted, the Device Manager calls this function
// to initialize the device. This function is not called by applications.
//
// It checks the corresponding ATAPI controller and and the associated device.
// There must be an entry point in the registry for each device.
// The registry entry must contain the PortNumber and the DeviceNumber (0/1)
//
// The Device Manager specifies a pointer to a string containing the registry path
// to the active key of the specific device in the dwContext parameter.
// Usually, the string contains the registry path to a numbered subkey of
// the HKEY_LOCAL_MACHINE\Drivers\Active key. Your initialization function uses
// this information to access data stored in the registry.
//--------------------------------------------------------------------------
EXTERN_C DWORD DSK_Init(DWORD dwContext)
{
PTSTR szActiveKey = (PTSTR)dwContext;
DWORD dwHandle = 0;
HKEY hActiveKey;
CDisk *pDisk = NULL;
DEBUGMSG( ZONE_MAIN, (TEXT("ATAPI: DSK_Init ActiveKey = %s\r\n"), szActiveKey));
EnterCriticalSection( &g_csMain);
DWORD dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE, szActiveKey, 0, 0, &hActiveKey);
if (ERROR_SUCCESS == dwError) {
PTSTR szDevKey = NULL;
HKEY hDevKey;
DUMPREGKEY( ZONE_INIT, szActiveKey, hActiveKey);
if (hDevKey = AtaLoadRegKey( hActiveKey, &szDevKey)) {
DWORD dwLen = sizeof(DWORD);
DUMPREGKEY( ZONE_INIT, szDevKey, hDevKey);
TCHAR *szObject=NULL;
POBJECTFUNCTION pObject = NULL;
/* if (AtaGetRegistryString(hDevKey, L"Object", &szObject)) {
pObject = (POBJECTFUNCTION)GetProcAddress( g_hInstance, szObject);
}
if (pObject) {
pDisk = pObject( hDevKey);
}
if (szObject) {
LocalFree( szObject);
}
*/ // Just check again that this is ok.
pDisk = CreateGeneric(hDevKey);
if (pDisk && szActiveKey && szDevKey) {
pDisk->SetActiveKey(szActiveKey);
pDisk->SetDeviceKey(szDevKey);
// Go head and setup the chain so in case AtaIsValidDisk is accessed
pDisk->m_pNextDisk = g_pDiskRoot;
g_pDiskRoot = pDisk;
if(!Init_GPIO())return NULL;
if (pDisk->Init( hActiveKey)) {
} else {
// Reset the root back...
g_pDiskRoot = pDisk->m_pNextDisk;
delete pDisk;
pDisk = NULL;
}
}
}
if (szDevKey)
LocalFree( szDevKey);
RegCloseKey( hActiveKey);
}
LeaveCriticalSection( &g_csMain);
return ((DWORD)pDisk);
}
//--------------------------------------------------------------------------
//
// DSK_Deinit: Process Device Closing command.This function is called by
// the Device Manager to deinitialize previously initialized device.
//
// When the user stops using a device, such as when a PC Card
// is removed from its socket,the Device Manager calls it.
// This function is not called by applications.
// The Device Manager calls DSK_Deinit as a result
// of the call to the DeregisterDevice function.
//
// Input: pHandle - Pointer to Device Handle returned by DSK_Init.
//
// Return: TRUE - ok.
// FALSE - error.
//
// Notes: At the moment we do nothing, except resetting device flag.
//
//--------------------------------------------------------------------------
EXTERN_C BOOL DSK_Deinit(DWORD pHandle)
{
CDisk *pDiskPrev=NULL, *pDiskCur=g_pDiskRoot;
DEBUGMSG( ZONE_MAIN, (TEXT("ATAPI: DSK_Deinit pHandle = %08X\r\n"), pHandle));
EnterCriticalSection (&g_csMain);
while(pDiskCur) {
if(pDiskCur == (CDisk *)pHandle)
break;
pDiskPrev = pDiskCur;
pDiskCur = pDiskCur->m_pNextDisk;
}
if (pDiskCur) {
if (pDiskPrev)
pDiskPrev = pDiskCur->m_pNextDisk;
else
g_pDiskRoot = pDiskCur->m_pNextDisk;
delete pDiskCur;
}
LeaveCriticalSection( &g_csMain);
return TRUE;
}
//--------------------------------------------------------------------------
//
// DSK_Open - ATAPIPCI.DLL open command processing entry point
//
// Input: pHandle - Pointer to a Device Handle. The DSK_Init function
// creates and returns this handle.
//
// dwAccess - Specifies the requested access code of the device.
// The access is a combination of read and write.
//
// dwSharedMode - File share mode. The share mode is a combination
// of file read and write sharing
//
// Return: HANDLE - ok.
// NULL - error.
//
//--------------------------------------------------------------------------
EXTERN_C DWORD DSK_Open( HANDLE pHandle,
DWORD dwAccess,
DWORD dwShareMode)
{
CDisk *pDisk = (CDisk *)pHandle;
DEBUGMSG( ZONE_MAIN, (TEXT("ATAPI:DSK_Open request Handle = %08 dwAccess=%08X dwShareMode=%08X\r\n"), pHandle, dwAccess, dwShareMode));
EnterCriticalSection( &g_csMain);
if (!AtaIsValidDisk(pDisk)) {
pDisk = NULL;
}
LeaveCriticalSection( &g_csMain);
if (pDisk) {
pDisk->Open();
}
return (DWORD)pDisk;
}
//--------------------------------------------------------------------------
//
// DSK_Close - This function closes the device identified by DSK_Open.
//
// Input: pHandle - Pointer to Handle returned by DSK_Open function
// and used to identify the open context of the device
//
// Return: TRUE - ok.
// FALSE - error.
//
//--------------------------------------------------------------------------
EXTERN_C BOOL DSK_Close(DWORD pHandle)
{
CDisk *pDisk = (CDisk *)pHandle;
DEBUGMSG( ZONE_MAIN, (TEXT("ATAPI:DSK_Close request Handle = %08X\r\n"), pHandle));
EnterCriticalSection( &g_csMain);
if (!AtaIsValidDisk(pDisk)) {
pDisk = NULL;
}
LeaveCriticalSection( &g_csMain);
if (pDisk) {
pDisk->Close();
}
return (pDisk!= NULL);
}
//--------------------------------------------------------------------------
//
// DSK_IOcontrol: Ioctl command processing entry point
//
// Input: Standard Ioctl inputs.
//
// Return: TRUE - ok
// FALSE - error.
//
//
//--------------------------------------------------------------------------
EXTERN_C BOOL DSK_IOControl(DWORD pHandle, //Handle to the device
DWORD dwIoControlCode,//Specifies the control code
PBYTE pInBuf, //Pointer to a buffer that contains the data required to perform the operation.
DWORD nInBufSize, //Size, in bytes, of pInBuf
PBYTE pOutBuf, //Pointer to a buffer that receives the operation's output data.
DWORD nOutBufSize, //Size, in bytes, of pOutBuf
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -