📄 atapipcmcia.cpp
字号:
DEBUGMSG(ZONE_INIT, (TEXT("ATAPIPCMCIA: PcmciaCallBack(%s)\r\n"), FindEventName(EventCode)));
// pDisk = DiskFromSocket(hSock);
switch (EventCode) {
case CE_EXCLUSIVE_REQUEST:
// TODO: Need to figure out how to handle this
return CERR_IN_USE;
case CE_CARD_REMOVAL:
//
// If this is not an artificial removal notice, then indicate that in the
// disk's global state.
//
if (pDisk && AtaIsValidDisk(pDisk))
pDisk->RemoveCardEvent(hSock);
break;
default:
break;
}
return CERR_SUCCESS;
} // PcmciaCallBack
VOID PcmciaIntr(DWORD dwContext)
{
CPCMCIADisk *pDisk = (CPCMCIADisk *)dwContext;
if (AtaIsValidDisk(pDisk) == FALSE) {
DEBUGMSG(ZONE_PCMCIA, (TEXT("ATAPI: PcmciaIntr - Invalid PDISK\r\n")));
return;
}
#if defined(DEBUG)
TCHAR szStatus[70];
BYTE bStatus, bError;
bStatus = ATA_READ_BYTE(pDisk->m_pATAReg + ATA_REG_STATUS);
if (ZONE_IO) {
szStatus[0] = 0;
//
// Display ATA status register
//
if (bStatus & ATA_STATUS_ERROR) {
_tcscat(szStatus, TEXT("ERROR "));
}
if (bStatus & ATA_STATUS_CORRECTED_ERROR) {
_tcscat(szStatus, TEXT("CORRECTED_ERROR "));
}
if (bStatus & ATA_STATUS_DATA_REQ) {
_tcscat(szStatus, TEXT("DATA_REQ "));
}
if (bStatus & ATA_STATUS_SEEK_DONE) {
_tcscat(szStatus, TEXT("SEEK_DONE "));
}
if (bStatus & ATA_STATUS_WRITE_FAULT) {
_tcscat(szStatus, TEXT("WRITE_FAULT "));
}
if (bStatus & ATA_STATUS_READY) {
_tcscat(szStatus, TEXT("READY "));
}
if (bStatus & ATA_STATUS_BUSY) {
_tcscat(szStatus, TEXT("BUSY "));
}
DEBUGMSG(ZONE_IO, (TEXT("ATAPIPCMCIA: PcmciaIntr - ATA Status = %s\r\n"),
szStatus));
}
if (ZONE_ERROR) {
if (bStatus & ATA_STATUS_ERROR) {
bError = ATA_READ_BYTE(pDisk->m_pATAReg+ ATA_REG_ERROR);
szStatus[0] = 0;
if (bError & ATA_ERROR_GENERAL) {
_tcscat(szStatus, TEXT("GENERAL "));
}
if (bError & ATA_ERROR_ABORTED) {
_tcscat(szStatus, TEXT("ABORTED "));
}
if (bError & ATA_ERROR_BAD_SECT_NUM) {
_tcscat(szStatus, TEXT("BAD_SECT_NUM "));
}
if (bError & ATA_ERROR_UNCORRECTABLE) {
_tcscat(szStatus, TEXT("UNCORRECTABLE "));
}
if (bError & ATA_ERROR_BAD_BLOCK) {
_tcscat(szStatus, TEXT("BAD_BLOCK "));
}
DEBUGMSG(ZONE_ERROR,
(TEXT("ATAPIPCMCIA:PcmciaIntr - ATA Error = %s\r\n"), szStatus));
}
}
#endif
#ifdef USE_INTERRUPT
//
// Signal the I/O thread
//
pDisk->SetEvent();
#endif
}
/*****************************************************************************************************/
// CPCMCIADisk Class
/*****************************************************************************************************/
CPCMCIADisk::~CPCMCIADisk()
{
// Check to see if we have configured the card
if (m_bState & STATE_CARD_CONFIGURED) {
DEBUGMSG( ZONE_DEINIT, (TEXT("ATAPIPCMCIA:Destructor Releasing Card Configuration\r\n")));
g_pfnCardReleaseConfiguration(m_hPcmcia, m_hSock);
}
// Check to see if we have requested an IRQ from PCMCIA
if (m_bState & STATE_CARD_IRQ_REQUESTED) {
DEBUGMSG( ZONE_DEINIT, (TEXT("ATAPIPCMCIA:Destructor Releasing Card IRQ\r\n")));
g_pfnCardReleaseIRQ(m_hPcmcia, m_hSock);
}
// If we Regiestered the client then Deregister
if (m_hPcmcia) {
DEBUGMSG( ZONE_DEINIT, (TEXT("ATAPIPCMCIA:Destructor Deregistering client\r\n")));
g_pfnCardDeregisterClient(m_hPcmcia);
}
if (m_pAlignBuf)
LocalFree( m_pAlignBuf);
if (m_hIRQEvent)
CloseHandle(m_hIRQEvent);
}
BOOL CPCMCIADisk::Init(HKEY hActiveKey)
{
DWORD dwValueLen = sizeof(CARD_SOCKET_HANDLE);
BOOL bRet = TRUE;
#ifdef USE_INTERRUPT
m_fInterruptSupported = TRUE;
#else
m_fInterruptSupported = FALSE;
#endif
if (ERROR_SUCCESS == RegQueryValueEx( hActiveKey,
DEVLOAD_SOCKET_VALNAME,
NULL,
NULL,
(PBYTE)&m_hSock,
&dwValueLen))
{
DEBUGMSG(ZONE_INIT, (TEXT("ATAPI:AtaInitPCMCIA %s = %08X\r\n"), DEVLOAD_SOCKET_VALNAME, m_hSock));
CARD_REGISTER_PARMS crp;
DEBUGMSG(ZONE_INIT,(TEXT("ATAPIPCMCIA: Attempting to register with PCMCIA.DLL\r\n")));
if (!g_hPcmciaDll) { // Check to se if we have already initialized our PCMCIA pointers
if (!InitPcmciaDll()) {
// If we can't initialize bail out
goto ExitFail;
}
}
crp.fEventMask = EVENT_MASK_CARD_DETECT;
crp.uClientData = (DWORD)this;
crp.fAttributes = CLIENT_ATTR_IO_DRIVER |
CLIENT_ATTR_NOTIFY_SHARED |
CLIENT_ATTR_NOTIFY_EXCLUSIVE;
if (!(m_hPcmcia = (CARD_CLIENT_HANDLE)g_pfnCardRegisterClient(PcmciaCallBack,&crp))) {
DEBUGMSG( ZONE_INIT, (TEXT("ATAPIPCMCIA: CardRegisterClient failed %d\r\n"), GetLastError()));
goto ExitFail;
}
if (!Config(hActiveKey)) {
goto ExitFail;
}
} else {
DEBUGMSG( ZONE_INIT | ZONE_PCMCIA, (TEXT("ATAPCMCIA: Failed to read socket handle from registry !!!\r\n")));
goto ExitFail;
}
WaitForInterrupt(DISK_IO_TIME_OUT);
// m_szDiskName = g_szPCMCIAVolumeName;
m_szDiskName = L"";
bRet = CDisk::Init( hActiveKey);
// TODO: Currently we don't support any DMA in the PCMCIA version
if (IsDMASupported()) {
m_Id.Capabilities = m_Id.Capabilities & (WORD)~IDENTIFY_CAPABILITIES_DMA_SUPPORTED;
}
ExitFail:
return bRet;
}
//
// ATAConfig - get required PCMCIA resources
// 1. Ask for status notifications on the socket
// 2. Find which PCMCIA I/O card configuration to use.
// 3. Request and map an I/O window to the ATA registers.
// 4. Request the PCMCIA interrupt
// 5. Request the configuration
//
// Return: CERR_SUCCESS or one of the CERR_* return codes.
//
BOOL CPCMCIADisk::Config(HKEY hActiveKey)
{
CARD_CONFIG_INFO CfgInfo;
PARSED_CFTABLE CfTable[10];
DWORD i,k;
UINT nCfg;
DWORD status;
DWORD dwRegBase;
UCHAR req_vcc;
BOOL fPowerAC;
HANDLE hEvent = NULL;
//
// 1. Ask for status notifications on the socket
//
status = g_pfnCardRequestSocketMask(
m_hPcmcia,
m_hSock,
0xff); // all events for now
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: CardRequestSocketMask failed %d\r\n"), status));
return status;
}
//
// 2. Choose which configuration to use
//
nCfg = sizeof(CfTable)/sizeof(PARSED_CFTABLE);
status = g_pfnCardGetParsedTuple(
m_hSock,
CISTPL_CFTABLE_ENTRY,
CfTable,
&nCfg);
if (status) {
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: CardGetParsedTuple(CISTPL_CFTABLE_ENTRY) failed %d\r\n"),
status));
return status;
}
// if info is unavailable, try for performance rather than power-savings
fPowerAC = TRUE;
if (g_pfnGetSystemPowerStatusEx && (hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, (TEXT("SYSTEM/GweApiSetReady")))) != NULL) {
SYSTEM_POWER_STATUS_EX PowerStatus;
WaitForSingleObject(hEvent, INFINITE);
if (g_pfnGetSystemPowerStatusEx(&PowerStatus, TRUE))
fPowerAC = (PowerStatus.ACLineStatus == AC_LINE_ONLINE);
}
req_vcc = fPowerAC ? 50 : 33;
dwRegBase = ATA_IO_REG_BASE;
ac_try_again:
m_f16Bit = FALSE;
for (i = 0; i < nCfg; i++) {
DEBUGMSG(ZONE_PCMCIA, (TEXT("ATADISK Cfg[%d] = x%02x: def:%c %d dV %d ranges\n"),
i, CfTable[i].ConfigIndex, CfTable[i].ContainsDefaults?'Y':'N',
CfTable[i].VccDescr.NominalV, CfTable[i].NumIOEntries));
if (((CfTable[i].VccDescr.ValidMask & PWR_DESCR_NOMINALV) &&
!isVoltageNear(req_vcc, CfTable[i].VccDescr.NominalV)) ||
CfTable[i].NumIOEntries != 2)
continue;
k = CfTable[i].NumIOAddrLines;
if (CfTable[i].IOLength[0] >= 7 && CfTable[i].IOLength[1] >= 1) {
if (GetATAWindows(CfTable[i].IOAccess, CfTable[i].IOBase[0],
CfTable[i].IOBase[1], (k >= 16) ? 0 : (1 << k)) == GAW_SUCCESS)
goto ac_address_ok;
} else if (CfTable[i].IOLength[1] >= 7 && CfTable[i].IOLength[0] >= 1) {
if (GetATAWindows(CfTable[i].IOAccess, CfTable[i].IOBase[1],
CfTable[i].IOBase[0], (k >= 16) ? 0 : (1 << k)) == GAW_SUCCESS)
goto ac_address_ok;
}
}
// No I/O configurations matched our requested voltage so fall back and try again
if ((fPowerAC ? 50 : 33) == req_vcc) {
req_vcc = fPowerAC ? 33 : 50;
// we assume that any I/O window available at one voltage is supported at both,
// so the only way to get here is if no windows are supported at the preferred voltage;
// hence there is no need to reset dwRegBase.
goto ac_try_again;
}
//
// Couldn't map a valid I/O address range (perhaps device doesn't support I/O access for this
// slot). Try a common memory window.
//
for (i = 0; i < nCfg; i++) {
if (CfTable[i].IFacePresent && (CfTable[i].IFaceType == 0)) { /* Constant defined somewhere? */
DEBUGMSG(ZONE_PCMCIA, (TEXT("ATADISK: Config 0x%x (Mem) supports "), CfTable[i].ConfigIndex));
//
// For now, just use 8 bit access
//
DEBUGMSG(ZONE_PCMCIA, (TEXT("8-bit only access\r\n")));
if (GetATAWindows(ACCESS_MEMORY_ONLY, 0, 0, 0) == GAW_SUCCESS) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -