📄 atamain.cpp
字号:
//
// Copyright(C) Renesas Technology Corp. 2005. All rights reserved.
//
// ATAPI(UDFS) driver for ITS-DS7
//
// FILE : atamain.cpp
// CREATED : 2005.02.10
// MODIFIED :
// AUTHOR : Renesas Technology Corp.
// HARDWARE : RENESAS ITS-DS7
// HISTORY :
// 2005.02.10
// - Created release code.
// (based on PUBLIC ATAPI driver for WCE5.0)
//
// 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 <atamain.h>
// DLL instance handle; differentiate this driver from other ATAPI instances
// (what other buses?)
HINSTANCE g_hInstance;
// List of active devices/disks
CDisk *g_pDiskRoot = NULL;
// Protect global variables
CRITICAL_SECTION g_csMain;
// Debug
extern "C" BOOL RegisterDbgZones(HMODULE hMod, LPDBGPARAM lpdbgparam);
// Definitions
typedef CDisk *(* POBJECTFUNCTION)(HKEY hKey);
// IDE/ATA bus implementation
// Constructor
CIDEBUS::CIDEBUS(
)
{
// initialize device handle table and device registry key name table
for (int i = 0; i < MAX_DEVICES_PER_CONTROLLER; i++) {
m_hDevice[i] = NULL;
m_szDevice[i] = NULL;
}
// initialize port structures
m_pIdeReg = NULL;
m_pPrimaryPort = NULL;
}
// Destructor
CIDEBUS::~CIDEBUS(
)
{
// deinitialize device handle table and device registry key name table
for (int i = 0; i < MAX_DEVICES_PER_CONTROLLER; i++) {
if (m_hDevice[i]) {
BOOL fOk = DeactivateDevice(m_hDevice[i]);
DEBUGCHK(fOk);
DEBUGCHK(m_szDevice[i] != NULL);
}
if (m_szDevice[i] != NULL) {
delete m_szDevice[i];
}
}
// delete IDE_ registry value set
if (m_pIdeReg) {
if (m_pIdeReg->pszSpawnFunction) {
LocalFree(m_pIdeReg->pszSpawnFunction);
}
if (m_pIdeReg->pszIsrDll) {
LocalFree(m_pIdeReg->pszIsrDll);
}
if (m_pIdeReg->pszIsrHandler) {
LocalFree(m_pIdeReg->pszIsrHandler);
}
LocalFree(m_pIdeReg);
}
// deinitialize port structures
if (m_pPrimaryPort) {
delete m_pPrimaryPort;
}
}
// IDE/ATA channel/port implementation
// Constructor
CPort::CPort(
CIDEBUS *pParent
)
{
DEBUGCHK(pParent);
InitializeCriticalSection(&m_csPort);
// hook up bus
m_pController = pParent;
// initialize flags
m_fInitialized = 0;
m_dwFlag = 0;
// initialize I/O ports
m_dwRegBase = 0;
m_dwRegAlt = 0;
// initialize interrupt data
m_hIRQEvent = NULL;
m_dwSysIntr = SYSINTR_NOP;
m_dwIrq = IRQ_UNSPECIFIED;
// initialize master/slave registry value set
m_pDskReg[0] = NULL;
m_pDskReg[1] = NULL;
}
// Destructor
CPort::~CPort(
)
{
DeleteCriticalSection(&m_csPort);
// unmap ATA channel's I/O windows
if (m_dwRegBase) {
VirtualFree( (PVOID)m_dwRegBase, 0, MEM_RELEASE );
}
if (m_dwAtapiBuffer) {
VirtualFree( (PVOID)m_dwAtapiBuffer, 0, MEM_RELEASE );
}
// close interrupt event handle
if (m_hIRQEvent) {
CloseHandle(m_hIRQEvent);
}
// disable interrupt
if (m_dwSysIntr != SYSINTR_NOP) {
InterruptDisable(m_dwSysIntr);
}
// free DSK_ registry value set
if (m_pDskReg[0]) {
LocalFree(m_pDskReg[0]);
}
if (m_pDskReg[1]) {
LocalFree(m_pDskReg[1]);
}
}
// Acquire exclusive access to IDE/ATA channel's I/O window
VOID
CPort::TakeCS(
)
{
EnterCriticalSection(&m_csPort);
}
// Release exclusive access to IDE/ATA channel's I/O window
VOID
CPort::ReleaseCS(
)
{
LeaveCriticalSection(&m_csPort);
}
// Write I/O window and interrupt data to debug output
VOID
CPort::PrintInfo(
)
{
DEBUGMSG(ZONE_INIT, (TEXT("dwRegBase = %08X\r\n"), m_dwRegBase));
DEBUGMSG(ZONE_INIT, (TEXT("dwRegAlt = %08X\r\n"), m_dwRegAlt));
DEBUGMSG(ZONE_INIT, (TEXT("dwSysIntr = %08X\r\n"), m_dwSysIntr));
DEBUGMSG(ZONE_INIT, (TEXT("dwIrq = %08X\r\n"), m_dwIrq));
}
// Helper functions
// This function is used by an Xxx_Init function to fetch the name of and return
// a handle to the instance/device ("Key") key from an Active key
HKEY
AtaLoadRegKey(
HKEY hActiveKey,
TCHAR **pszDevKey
)
{
DWORD dwValueType; // registry value type
DWORD dwValueLength = 0; // registry value length
PTSTR szDeviceKey = NULL; // name of device key; value associated with "Key"
HKEY hDeviceKey = NULL; // handle to device key; handle to "Key"
// query the value of "Key" with @dwValueLength=0, to determine the actual
// length of the value (so as to allocate the exact amount of memory)
if (ERROR_SUCCESS == RegQueryValueEx(hActiveKey, DEVLOAD_DEVKEY_VALNAME, NULL, &dwValueType, NULL, &dwValueLength)) {
// allocate just enough memory to store the value of "Key"
szDeviceKey = (PTSTR)LocalAlloc(LPTR, dwValueLength);
if (szDeviceKey) {
// read the actual value of "Key" and null terminate the target buffer
RegQueryValueEx(hActiveKey, DEVLOAD_DEVKEY_VALNAME, NULL, &dwValueType, (PBYTE)szDeviceKey, &dwValueLength);
DEBUGCHK(dwValueLength != 0);
szDeviceKey[(dwValueLength / sizeof(TCHAR)) - 1] = 0;
// open the device key
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, szDeviceKey, 0, 0, &hDeviceKey)) {
DEBUGMSG(ZONE_INIT, (_T(
"AtaLoadRegyKey> Failed to open %s\r\n"
), szDeviceKey));
hDeviceKey = NULL;
}
}
}
if (!hDeviceKey) {
if (szDeviceKey) {
LocalFree(szDeviceKey);
}
*pszDevKey = NULL;
}
else {
*pszDevKey = szDeviceKey;
}
return hDeviceKey;
}
// This function is used to determine whether a target disk instance is valid
BOOL
AtaIsValidDisk(
CDisk *pDisk
)
{
CDisk *pTemp = g_pDiskRoot;
while (pTemp) {
if (pTemp == pDisk) {
return TRUE;
}
pTemp = pTemp->m_pNextDisk;
}
return FALSE;
}
PUCHAR MapAddress(ULONG HWAddress, ULONG Size)
{
PUCHAR ioPortBase;
ioPortBase = (PUCHAR)VirtualAlloc(0, Size, MEM_RESERVE, PAGE_NOACCESS);
if (ioPortBase == NULL ) {
}else if (!VirtualCopy((PVOID)ioPortBase, (PVOID)HWAddress, Size, PAGE_READWRITE|PAGE_NOCACHE)) {
VirtualFree( (PVOID)ioPortBase, 0, MEM_RELEASE );
ioPortBase = 0;
}
return ioPortBase;
}
// This function reads the IDE registry value set from the IDE/ATA controller's
// registry key
BOOL
GetIDERegistryValueSet(
HKEY hIDEInstanceKey,
PIDEREG pIdeReg
)
{
BOOL fRet;
DEBUGCHK(NULL != pIdeReg);
// fetch legacy boolean
fRet = AtaGetRegistryValue(hIDEInstanceKey, REG_VAL_IDE_LEGACY, &pIdeReg->dwLegacy);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetIDERegistryValueSet> Failed to read %s from IDE instance key\r\n"
), REG_VAL_IDE_LEGACY));
return FALSE;
}
if (pIdeReg->dwLegacy >= 2) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetIDERegistryValueSet> Bad value(%d) for %s in IDE instance key; valid: {0, 1}\r\n"
), pIdeReg->dwLegacy, REG_VAL_IDE_LEGACY));
return FALSE;
}
// fetch IRQ; this value is not mandatory
fRet = AtaGetRegistryValue(hIDEInstanceKey, REG_VAL_IDE_IRQ, &pIdeReg->dwIrq);
if (!fRet) {
pIdeReg->dwIrq = IRQ_UNSPECIFIED;
}
// fetch SysIntr; this is not mandatory
fRet = AtaGetRegistryValue(hIDEInstanceKey, REG_VAL_IDE_SYSINTR, &pIdeReg->dwSysIntr);
if (!fRet) {
pIdeReg->dwSysIntr = SYSINTR_NOP;
}
// fetch vendor id; this is not mandatory
fRet = AtaGetRegistryValue(hIDEInstanceKey, REG_VAL_IDE_VENDORID, &pIdeReg->dwVendorId);
if (!fRet) {
pIdeReg->dwVendorId = 0;
}
// fetch DMA alignment; this is not mandatory
fRet = AtaGetRegistryValue(hIDEInstanceKey, REG_VAL_IDE_DMAALIGNMENT, &pIdeReg->dwDMAAlignment);
if (!fRet) {
pIdeReg->dwDMAAlignment = 0;
}
// fetch soft reset timeout
fRet = AtaGetRegistryValue(hIDEInstanceKey, REG_VAL_IDE_SOFTRESETTIMEOUT, &pIdeReg->dwSoftResetTimeout);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetIDERegistryValueSet> Failed to read %s from IDE instance key\r\n"
), REG_VAL_IDE_SOFTRESETTIMEOUT));
return FALSE;
}
// fetch Status register poll cycles
fRet = AtaGetRegistryValue(hIDEInstanceKey, REG_VAL_IDE_STATUSPOLLCYCLES, &pIdeReg->dwStatusPollCycles);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetIDERegistryValueSet> Failed to read %s from IDE instance key\r\n"
), REG_VAL_IDE_STATUSPOLLCYCLES));
return FALSE;
}
// fetch Status register polls per cycle
fRet = AtaGetRegistryValue(hIDEInstanceKey, REG_VAL_IDE_STATUSPOLLSPERCYCLE, &pIdeReg->dwStatusPollsPerCycle);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetIDERegistryValueSet> Failed to read %s from IDE instance key\r\n"
), REG_VAL_IDE_STATUSPOLLSPERCYCLE));
return FALSE;
}
// fetch Status register poll cycle pause
fRet = AtaGetRegistryValue(hIDEInstanceKey, REG_VAL_IDE_STATUSPOLLCYCLEPAUSE, &pIdeReg->dwStatusPollCyclePause);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetIDERegistryValueSet> Failed to read %s from IDE instance key\r\n"
), REG_VAL_IDE_STATUSPOLLCYCLEPAUSE));
return FALSE;
}
// fetch spawn function
fRet = AtaGetRegistryString(hIDEInstanceKey, REG_VAL_IDE_SPAWNFUNCTION, &pIdeReg->pszSpawnFunction);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetIDERegistryValueSet> Failed to read %s from IDE instance key\r\n"
), REG_VAL_IDE_SPAWNFUNCTION));
return FALSE;
}
// fetch ISR dll; this is not mandatory; allocate pszIsrDll
fRet = AtaGetRegistryString(hIDEInstanceKey, REG_VAL_IDE_ISRDLL, &pIdeReg->pszIsrDll, 0);
if (!fRet) {
pIdeReg->pszIsrDll = NULL;
}
// fetch ISR handler; this is not mandatory; allocate pszIsrHandler
fRet = AtaGetRegistryString(hIDEInstanceKey, REG_VAL_IDE_ISRHANDLER, &pIdeReg->pszIsrHandler, 0);
if (!fRet) {
pIdeReg->pszIsrHandler = NULL;
}
// fetch device control offset; this is not mandatory
fRet = AtaGetRegistryValue(hIDEInstanceKey, REG_VAL_IDE_DEVICECONTROLOFFSET, &pIdeReg->dwDeviceControlOffset);
if (!fRet) {
// this value is only used by atapipcmcia
pIdeReg->dwDeviceControlOffset = ATA_REG_ALT_STATUS;
}
// fetch alternate status offset; this is not mandatory
fRet = AtaGetRegistryValue(hIDEInstanceKey, REG_VAL_IDE_ALTERNATESTATUSOFFSET, &pIdeReg->dwAlternateStatusOffset);
if (!fRet) {
// this value is only used by atapipcmcia
pIdeReg->dwAlternateStatusOffset = ATA_REG_DRV_CTRL;
}
// fetch register stride
fRet = AtaGetRegistryValue(hIDEInstanceKey, REG_VAL_IDE_REGISTERSTRIDE, &pIdeReg->dwRegisterStride);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetIDERegistryValueSet> Failed to read %s from IDE instance key\r\n"
), REG_VAL_IDE_REGISTERSTRIDE));
return FALSE;
}
if (0 == pIdeReg->dwRegisterStride) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetIDERegistryValueSet> Bad value(%d) for %s in IDE instance key; valid: > 0\r\n"
), pIdeReg->dwRegisterStride, REG_VAL_IDE_REGISTERSTRIDE));
return FALSE;
}
return TRUE;
}
// This function reads the DSK registry value set from the IDE/ATA controller's
// registry key
BOOL
GetDSKRegistryValueSet(
HKEY hDSKInstanceKey,
PDSKREG pDskReg
)
{
BOOL fRet;
// fetch device ID
fRet = AtaGetRegistryValue(hDSKInstanceKey, REG_VAL_DSK_DEVICEID, &pDskReg->dwDeviceId);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetDSKRegistryValueSet> Failed to read %s from DSK instance key\r\n"
), REG_VAL_DSK_DEVICEID));
return FALSE;
}
if (!((0 <= pDskReg->dwDeviceId) && (pDskReg->dwDeviceId <= 3))) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetDSKRegistryValueSet> Bad value(%d) for %s in DSK instance key; valid: {0, 1, 2, 3}\r\n"
), pDskReg->dwDeviceId, REG_VAL_DSK_DEVICEID));
return FALSE;
}
// fetch interrupt driven I/O boolean
fRet = AtaGetRegistryValue(hDSKInstanceKey, REG_VAL_DSK_INTERRUPTDRIVEN, &pDskReg->dwInterruptDriven);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetDSKRegistryValueSet> Failed to read %s from DSK instance key\r\n"
), REG_VAL_DSK_INTERRUPTDRIVEN));
return FALSE;
}
if (pDskReg->dwInterruptDriven >= 2) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetDSKRegistryValueSet> Bad value(%d) for %s in DSK instance key; valid: {0, 1}\r\n"
), pDskReg->dwInterruptDriven, REG_VAL_DSK_INTERRUPTDRIVEN));
return FALSE;
}
// fetch DMA triple
fRet = AtaGetRegistryValue(hDSKInstanceKey, REG_VAL_DSK_DMA, &pDskReg->dwDMA);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetDSKRegistryValueSet> Failed to read %s from DSK instance key\r\n"
), REG_VAL_DSK_DMA));
return FALSE;
}
if (pDskReg->dwDMA >= 3) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetDSKRegistryValueSet> Bad value(%d) for %s in DSK instance key; valid: {0=no DMA, 1=DMA, 2=ATA DMA only}\r\n"
), pDskReg->dwDMA, REG_VAL_DSK_DMA));
return FALSE;
}
// fetch double buffer size
fRet = AtaGetRegistryValue(hDSKInstanceKey, REG_VAL_DSK_DOUBLEBUFFERSIZE, &pDskReg->dwDoubleBufferSize);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetDSKRegistryValueSet> Failed to read %s from DSK instance key\r\n"
), REG_VAL_DSK_DOUBLEBUFFERSIZE));
return FALSE;
}
if (
(pDskReg->dwDoubleBufferSize < REG_VAL_DSK_DOUBLEBUFFERSIZE_MIN) ||
(pDskReg->dwDoubleBufferSize > REG_VAL_DSK_DOUBLEBUFFERSIZE_MAX)
) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetDSKRegistryValueSet> Bad value(%d) for %s in DSK instance key; valid: {%d, ..., %d}\r\n"
), pDskReg->dwDoubleBufferSize, REG_VAL_DSK_DOUBLEBUFFERSIZE, REG_VAL_DSK_DOUBLEBUFFERSIZE_MIN, REG_VAL_DSK_DOUBLEBUFFERSIZE_MAX));
return FALSE;
}
// fetch DRQ data block size; this has to be validated by a sub-class
fRet = AtaGetRegistryValue(hDSKInstanceKey, REG_VAL_DSK_DRQDATABLOCKSIZE, &pDskReg->dwDrqDataBlockSize);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetDSKRegistryValueSet> Failed to read %s from DSK instance key\r\n"
), REG_VAL_DSK_DRQDATABLOCKSIZE));
return FALSE;
}
// fetch write cache boolean
fRet = AtaGetRegistryValue(hDSKInstanceKey, REG_VAL_DSK_WRITECACHE, &pDskReg->dwWriteCache);
if (!fRet) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
"Atapi!GetDSKRegistryValueSet> Failed to read %s from DSK instance key\r\n"
), REG_VAL_DSK_WRITECACHE));
return FALSE;
}
if (pDskReg->dwWriteCache >= 2) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -