?? system.c
字號:
status = GAW_PRIMARY_FAIL;
goto gaw_error;
}
//
// Map the command window now. If this fails we can tell the caller to try
// the secondary ATA I/O port range.
//
pATAReg = (PVOID)v_pfnCardMapWindow(
hATAReg,
reg_base + modifier,
ATA_REG_LENGTH,
&v_MemGran);
if (pATAReg == NULL) {
//
// There may be another ATA device in the system. Tell the caller to
// use the secondary ATA I/O range.
//
status = GetLastError();
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: CardMapWindow(pATAReg) failed %d\r\n"),
status));
status = (wtype == ACCESS_MEMORY_ONLY) ?
GAW_MEMORY_FAIL : GAW_PRIMARY_FAIL;
goto gaw_error;
}
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT,
(TEXT("ATADISK: pATAReg = 0x%x\r\n"), pATAReg));
WndParms.uWindowSize = ATA_ALT_REG_LENGTH;
hATARegAlt = (CARD_WINDOW_HANDLE)v_pfnCardRequestWindow(pDisk->d_hPcmcia, &WndParms);
if (hATARegAlt == NULL) {
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: CardRequestWindow(hATARegAlt) failed %d\r\n"),
GetLastError()));
status = (wtype == ACCESS_MEMORY_ONLY) ?
GAW_MEMORY_FAIL : GAW_SECONDARY_FAIL;
goto gaw_error;
}
pATARegAlt = (PVOID)v_pfnCardMapWindow(
hATARegAlt,
alt_base + modifier,
ATA_ALT_REG_LENGTH,
&v_MemGran);
if (pATARegAlt == NULL) {
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: CardMapWindow(pATARegAlt) failed %d\r\n"),
GetLastError()));
status = (wtype == ACCESS_MEMORY_ONLY) ?
GAW_MEMORY_FAIL : GAW_SECONDARY_FAIL;
goto gaw_error;
}
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT,
(TEXT("ATADISK: pATARegAlt = 0x%x. v_MemGran = %d\r\n"),
pATARegAlt, v_MemGran));
pDisk->d_hATAReg = hATAReg;
pDisk->d_pATAReg = pATAReg;
pDisk->d_hATARegAlt = hATARegAlt;
pDisk->d_pATARegAlt = pATARegAlt;
if ((wtype == ACCESS_IO_16BIT) || ((wtype == ACCESS_IO_ANY) && !(pDisk->d_Flags & ATADISK_FLAG_TRY8BIT))) {
pDisk->d_f16Bit = TRUE;
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT, (TEXT("ATADISK: Using 16 bit I/O\r\n")));
}
return GAW_SUCCESS;
gaw_error:
if (hATAReg) {
v_pfnCardReleaseWindow(hATAReg);
}
if (hATARegAlt) {
v_pfnCardReleaseWindow(hATARegAlt);
}
return status;
} // GetATAWindows
//
// 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.
//
DWORD
ATAConfig(
PDISK pDisk
)
{
CARD_CONFIG_INFO CfgInfo;
PARSED_CFTABLE CfTable[10];
DWORD i,k;
DWORD nCfg;
DWORD status;
DWORD reg_base;
UCHAR req_vcc;
BOOL fPowerAC;
//
// 1. Ask for status notifications on the socket
//
status = v_pfnCardRequestSocketMask(
pDisk->d_hPcmcia,
pDisk->d_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 = v_pfnCardGetParsedTuple(
pDisk->d_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 (v_pfnGetSystemPowerStatusEx != NULL) {
SYSTEM_POWER_STATUS_EX PowerStatus;
if (v_pfnGetSystemPowerStatusEx(&PowerStatus, TRUE))
fPowerAC = (PowerStatus.ACLineStatus == AC_LINE_ONLINE);
}
req_vcc = fPowerAC ? 50 : 33;
reg_base = ATA_IO_REG_BASE;
ac_try_again:
pDisk->d_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 (k < 16) {
k = 15;
}
if (CfTable[i].IOLength[0] >= 7 && CfTable[i].IOLength[1] >= 1) {
if (GetATAWindows(pDisk, 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(pDisk, 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 reg_base.
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(pDisk, ACCESS_MEMORY_ONLY, 0, 0, 0) == GAW_SUCCESS) {
pDisk->d_Flags |= ATADISK_FLAG_MEMORY_MAPPED;
goto ac_address_ok;
}
}
}
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: Unable to find adequate configuration!\r\n")));
return CERR_BAD_BASE;
ac_address_ok:
//
// 4. Request the PCMCIA interrupt
//
status = v_pfnCardRequestIRQ(
pDisk->d_hPcmcia,
pDisk->d_hSock,
(CARD_ISR)PcmciaIntr,
(DWORD)pDisk);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: CardRequestIRQ failed %d\r\n"), status));
return status;
}
//
// 5. Request the configuration (this will enable the interrupt)
//
ac_req_config:
CfgInfo.hSocket = pDisk->d_hSock;
CfgInfo.fAttributes = CFG_ATTR_IRQ_STEERING | CFG_ATTR_NO_IO_IS_8 | CFG_ATTR_NO_SUSPEND_UNLOAD;
CfgInfo.fInterfaceType = CFG_IFACE_MEMORY_IO;
CfgInfo.uVcc = req_vcc;
CfgInfo.uVpp1 = 0;
CfgInfo.uVpp2 = 0;
CfgInfo.fRegisters = CFG_REGISTER_CONFIG|CFG_REGISTER_STATUS;
CfgInfo.uConfigReg = CfTable[i].ConfigIndex;
CfgInfo.uStatusReg = 0;
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT,
(TEXT("ATADISK: CardRequestConfiguration 0x%x at %d dV\r\n"),
CfgInfo.uConfigReg, CfgInfo.uVcc));
status = v_pfnCardRequestConfiguration(
pDisk->d_hPcmcia,
&CfgInfo);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: CardRequestConfiguration failed %d\r\n"), status));
if (status == CERR_BAD_VCC && (fPowerAC ? 50 : 33) == req_vcc) {
req_vcc = fPowerAC ? 33 : 50; // try the other known Vcc
goto ac_req_config;
}
}
return status;
} // ATAConfig
//
// ATAInit:
// 1. Find which socket the disk card is in by looking in the active device key
// 2. Register as a client driver with PCMCIA.DLL.
// 3. Find and set up the PCMCIA I/O card configuration to use.
// 4. Init the disk card
//
// ActivePath is the registry path to our device's active key under
// HKEY_LOCAL_MACHINE\Drivers\Active
//
// Return pointer to new disk structure or NULL.
//
PDISK
ATAInit(
CARD_SOCKET_HANDLE hSock,
LPTSTR ActiveKey
)
{
DWORD status;
CARD_REGISTER_PARMS Parms;
PDISK pDisk=NULL;
DWORD ValLen;
HKEY hKey;
pDisk = CreateDiskObject();
if (pDisk == NULL) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: LocalAlloc(PDISK) failed %d\r\n"), GetLastError()));
return NULL;
}
pDisk->d_hSock = hSock;
if (pDisk->d_ActivePath = LocalAlloc(LPTR, wcslen(ActiveKey)*sizeof(WCHAR)+sizeof(WCHAR))) {
wcscpy(pDisk->d_ActivePath, ActiveKey);
} else {
pDisk->d_ActivePath = NULL;
goto ai_fail;
}
//
// Register callback function with PCMCIA driver
//
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT,
(TEXT("ATADISK: Attempting to register with PCMCIA.DLL\r\n")));
Parms.fEventMask = EVENT_MASK_CARD_DETECT | EVENT_MASK_POWER_MGMT;
Parms.uClientData = (UINT32)pDisk;
Parms.fAttributes = CLIENT_ATTR_IO_DRIVER | CLIENT_ATTR_NOTIFY_SHARED |
CLIENT_ATTR_NOTIFY_EXCLUSIVE;
pDisk->d_hPcmcia = (CARD_CLIENT_HANDLE)v_pfnCardRegisterClient(PcmciaCallBack,&Parms);
if (pDisk->d_hPcmcia == 0) {
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: CardRegisterClient failed %d\r\n"), GetLastError()));
goto ai_fail;
}
ValLen = sizeof(DWORD);
hKey = OpenDriverKey( ActiveKey);
if (hKey) {
if (ERROR_SUCCESS != RegQueryValueEx(hKey, L"Settings", NULL, NULL, (PUCHAR)&pDisk->d_Flags, &ValLen)) {
pDisk->d_Flags = 0;
} else {
DEBUGMSG( ZONE_INIT, (L"ATADISK: Settings = %08X\r\n", pDisk->d_Flags));
}
RegCloseKey( hKey);
}
//
// ATAConfig figures out which configuration to use and maps an I/O window
// and does all the other PCMCIA specific setup.
//
status = ATAConfig(pDisk);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: ATAConfig failed %d\r\n"), status));
goto ai_fail;
}
//
// InitDisk
//
status = InitDisk(pDisk, ActiveKey);
if (status) {
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: InitDisk failed %d\r\n"), status));
goto ai_fail;
}
return pDisk;
ai_fail:
if (pDisk) {
if (pDisk->d_ActivePath) {
LocalFree( pDisk->d_ActivePath);
pDisk->d_ActivePath = NULL;
}
CloseDisk(pDisk);
}
return NULL;
} // ATAInit
//
// Function to retrieve the pcmcia socket handle from the device's active key
//
DWORD
ATAGetSocket(
LPTSTR ActivePath,
CARD_SOCKET_HANDLE * pSock
)
{
DWORD ValType;
DWORD ValLen;
HKEY hDiskCardKey;
DWORD status;
//
// Get CARD_SOCKET_HANDLE from active device registry key
//
status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
ActivePath,
0,
0,
&hDiskCardKey);
if (status) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK:ATAGetSocket RegOpenKeyEx(HLM\\%s) returned %d!!!\r\n"),
ActivePath, status));
return status;
}
ValLen = sizeof(CARD_SOCKET_HANDLE);
status = RegQueryValueEx(
hDiskCardKey,
DEVLOAD_SOCKET_VALNAME,
NULL,
&ValType,
(PUCHAR)pSock,
&ValLen);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK:ATAGetSocket - RegQueryValueEx(%s) returned %d\r\n"),
DEVLOAD_SOCKET_VALNAME, status));
}
RegCloseKey(hDiskCardKey);
return status;
} // ATAGetSocket
//
// Function to detect an ATA device. This detection relies on the fact that
// device.exe has already determined there is a disk device in this socket by
// looking at the CISTPL_FUNCID tuple. This function will look at the CISTPL_FUNCE
// tuples to see if it is an ATA device.
//
// Return TRUE if there is an ATA device in the specified socket; FALSE if not.
BOOL
ATADetect(
CARD_SOCKET_HANDLE hSock
)
{
DWORD status;
UCHAR buf[sizeof(CARD_DATA_PARMS) + 256];
PCARD_TUPLE_PARMS pParms;
PCARD_DATA_PARMS pTuple;
PUCHAR pData;
//
// A type 1 CISTPL_FUNCE will tell if it is an ATA device.
//
pParms = (PCARD_TUPLE_PARMS)buf;
pParms->hSocket = hSock;
pParms->uDesiredTuple = CISTPL_FUNCE;
pParms->fAttributes = 0;
status = v_pfnCardGetFirstTuple(pParms);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("ATADISK:CardGetFirstTuple returned %d\r\n"), status));
return FALSE;
}
while (status == CERR_SUCCESS) {
pTuple = (PCARD_DATA_PARMS)buf;
pTuple->uBufLen = sizeof(buf) - sizeof(CARD_DATA_PARMS);
pTuple->uTupleOffset = 0;
status = v_pfnCardGetTupleData(pTuple);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVLOAD: CardGetTupleData returned %d\r\n"), status));
return FALSE;
}
pData = buf + sizeof(CARD_DATA_PARMS);
//
// If the CISTPL_FUNCE is type 1 and its data is 1, then it is an ATA device
//
if ((pData[0] == 1) && (pData[1] == 1)) {
return TRUE;
}
status = v_pfnCardGetNextTuple(pParms);
} // while
return FALSE;
} // ATADetect
//
// Detection modules entrypoint. Device.exe will call here to give this
// driver a chance to detect a newly inserted card.
//
// Return NULL if undetected or device key name of driver to load.
//
LPTSTR
DetectATADisk(
CARD_SOCKET_HANDLE hSock,
UCHAR DevType,
LPTSTR DevKey,
DWORD DevKeyLen
)
{
if (DevType == PCCARD_TYPE_FIXED_DISK) {
if (ATADetect(hSock) == TRUE) {
_tcscpy(DevKey, TEXT("ATADisk"));
return DevKey;
}
}
return NULL;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -