⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atamain.cpp

📁 这是运行在windows ce 4.2 版本下的关于硬盘加载的驱动程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -