?? system.c
字號:
//
// I/O Control function - responds to info, read and write control codes.
// The read and write take a scatter/gather list in pInBuf
//
BOOL
DSK_IOControl(
DWORD Handle,
DWORD dwIoControlCode,
PBYTE pInBuf,
DWORD nInBufSize,
PBYTE pOutBuf,
DWORD nOutBufSize,
PDWORD pBytesReturned
)
{
PDISK pDisk = (PDISK)Handle;
PSG_REQ pSG;
if (IsValidDisk(pDisk) == FALSE) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (OEM_CERTIFY_TRUST != PSLGetCallerTrust()) {
SetLastError(ERROR_ACCESS_DENIED);
return FALSE;
}
//
// Check parameters
//
switch (dwIoControlCode) {
case DISK_IOCTL_READ:
case DISK_IOCTL_WRITE:
case DISK_IOCTL_GETINFO:
case DISK_IOCTL_SETINFO:
case DISK_IOCTL_INITIALIZED:
if (pInBuf == NULL) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case IOCTL_DISK_DEVICE_INFO:
if ((nInBufSize== 0) || (pInBuf== NULL))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case DISK_IOCTL_GETNAME:
case IOCTL_DISK_GET_STORAGEID: // this is a new op, so use new codes //
if (pOutBuf == NULL) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case DISK_IOCTL_FORMAT_MEDIA:
SetLastError(ERROR_SUCCESS);
return TRUE;
case IOCTL_POWER_CAPABILITIES:
if (!pOutBuf || nOutBufSize < sizeof(POWER_CAPABILITIES) || !pBytesReturned) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case IOCTL_POWER_SET:
case IOCTL_POWER_QUERY:
if (!pOutBuf || nOutBufSize < sizeof(CEDEVICE_POWER_STATE) || !pBytesReturned) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
//
// Execute dwIoControlCode
//
switch (dwIoControlCode) {
case DISK_IOCTL_READ:
case DISK_IOCTL_WRITE:
pSG = (PSG_REQ)pInBuf;
if (!(pSG && nInBufSize >= (sizeof(SG_REQ) + sizeof(SG_BUF) * (pSG->sr_num_sg - 1)))) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
DoDiskIO(pDisk, dwIoControlCode, pSG);
if (pSG->sr_status) {
SetLastError(pSG->sr_status);
return FALSE;
}
return TRUE;
case DISK_IOCTL_GETINFO:
SetLastError(GetDiskInfo(pDisk, (PDISK_INFO)pInBuf));
return TRUE;
case DISK_IOCTL_SETINFO:
SetLastError(SetDiskInfo(pDisk, (PDISK_INFO)pInBuf));
return TRUE;
case DISK_IOCTL_INITIALIZED:
//
// Load and initialize the associated file system driver
//
if (InitFSD((PPOST_INIT_BUF)pInBuf)) {
DEBUGMSG(ZONE_INIT, (TEXT("ATADISK: InitFSD succeeded\r\n")));
} else {
DEBUGMSG(ZONE_INIT, (TEXT("ATADISK: InitFSD failed\r\n")));
}
return TRUE;
case IOCTL_DISK_DEVICE_INFO:
if (pBytesReturned)
*(pBytesReturned) = sizeof(STORAGEDEVICEINFO);
return GetDeviceInfo(pDisk, (STORAGEDEVICEINFO *)pInBuf);
case DISK_IOCTL_GETNAME:
return GetFolderName(pDisk, (LPWSTR)pOutBuf, nOutBufSize, pBytesReturned);
case IOCTL_DISK_GET_STORAGEID:
return GetStorageID(pDisk,
(PSTORAGE_IDENTIFICATION)pOutBuf,
nOutBufSize,
pBytesReturned);
case IOCTL_POWER_CAPABILITIES:
{
PPOWER_CAPABILITIES ppc = (PPOWER_CAPABILITIES)pOutBuf;
memset(ppc, 0, sizeof(POWER_CAPABILITIES));
// TODO: get these from the device
// Fake it for now...
ppc->DeviceDx = 0x11; // supports D0
// supported power & latency info
ppc->Power[D0] = PwrDeviceUnspecified; // mW
ppc->Latency[D0] = 0; // mSec
ppc->WakeFromDx = 0; // no device wake
ppc->InrushDx = 0; // no inrush
ppc->Flags = 0;
*pBytesReturned = sizeof(POWER_CAPABILITIES);
return TRUE;
} break;
case IOCTL_POWER_QUERY: {
CEDEVICE_POWER_STATE Dx = *(PCEDEVICE_POWER_STATE)pOutBuf;
DEBUGMSG(1, (TEXT("ATADISK: IOCTL_POWER_QUERY: D%d\r\n"), Dx));
// return PwrDeviceUnspecified if the device needs to reject the query
*pBytesReturned = sizeof(Dx);
return TRUE;
} break;
case IOCTL_POWER_SET:
{
CEDEVICE_POWER_STATE Dx = *(PCEDEVICE_POWER_STATE)pOutBuf;
switch (Dx) {
case D0:
{
#if 0 // Don't do anything here but do it on the PM_RESUME call
EnterCriticalSection( &pDisk->d_DiskCardCrit);
if (pDisk->lPwrOff) {
pDisk->lPwrOff--;
}
if (!pDisk->lPwrOff) {
SetEvent(pDisk->hPwrEvent);
}
DEBUGMSG(1, (TEXT("ATADISK: Powering on system: D%d Count=%ld\r\n"), Dx,pDisk->lPwrOff));
LeaveCriticalSection( &pDisk->d_DiskCardCrit);
#endif
}
break;
case D4:
{
if (pDisk->lPwrOff != -1) {
EnterCriticalSection( &pDisk->d_DiskCardCrit);
pDisk->lPwrOff = 1;
DEBUGMSG(1, (TEXT("ATADISK: Powering off system: D%d Count=%ld\r\n"), Dx,pDisk->lPwrOff));
ResetEvent(pDisk->hPwrEvent);
LeaveCriticalSection( &pDisk->d_DiskCardCrit);
}
}
break;
default:
break;
}
*pBytesReturned = sizeof(Dx);
return TRUE;
}
}
return FALSE;
} // DSK_IOControl
DWORD DSK_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes){return 0;}
DWORD DSK_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes){return 0;}
DWORD DSK_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod){return 0;}
void DSK_PowerUp(void){}
//
// Mark all disks on power down to avoid race between DCD wakeup activity
// and forced PCMCIA card removal due to power up.
//
void
DSK_PowerDown(void){}
//
// Returns TRUE if there is a card inserted in the specified socket
//
BOOL
IsCardInserted(
CARD_SOCKET_HANDLE hSock
)
{
STATUS status;
CARD_STATUS CardStatus;
CardStatus.hSocket = hSock;
status = v_pfnCardGetStatus(&CardStatus);
if (status == CERR_SUCCESS) {
if (CardStatus.fCardState & EVENT_MASK_CARD_DETECT) {
return TRUE;
}
} else {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("ATADISK: CardGetStatus returned %d\r\n"), status));
}
return FALSE;
} // IsCardInserted
#ifdef DEBUG
typedef struct _EVENT_NAME_TBL {
CARD_EVENT EventCode;
LPTSTR pEventName;
} EVENT_NAME_TBL, *PEVENT_NAME_TBL;
#define LAST_EVENT_CODE ((CARD_EVENT) -1)
//
// Table of callback event codes and their names.
// NOTE: The names with ! at the end are not expected.
//
EVENT_NAME_TBL v_EventNames[] = {
{ CE_BATTERY_DEAD, TEXT("CE_BATTERY_DEAD") },
{ CE_BATTERY_LOW, TEXT("CE_BATTERY_LOW") },
{ CE_CARD_LOCK, TEXT("CE_CARD_LOCK") },
{ CE_CARD_READY, TEXT("CE_CARD_READY") },
{ CE_CARD_REMOVAL, TEXT("CE_CARD_REMOVAL") },
{ CE_CARD_UNLOCK, TEXT("CE_CARD_UNLOCK") },
{ CE_EJECTION_COMPLETE, TEXT("CE_EJECTION_COMPLETE!") },
{ CE_EJECTION_REQUEST, TEXT("CE_EJECTION_REQUEST!") },
{ CE_INSERTION_COMPLETE, TEXT("CE_INSERTION_COMPLETE!") },
{ CE_INSERTION_REQUEST, TEXT("CE_INSERTION_REQUEST!") },
{ CE_PM_RESUME, TEXT("CE_PM_RESUME!") },
{ CE_PM_SUSPEND, TEXT("CE_PM_SUSPEND!") },
{ CE_EXCLUSIVE_COMPLETE, TEXT("CE_EXCLUSIVE_COMPLETE") },
{ CE_EXCLUSIVE_REQUEST, TEXT("CE_EXCLUSIVE_REQUEST") },
{ CE_RESET_PHYSICAL, TEXT("CE_RESET_PHYSICAL") },
{ CE_RESET_REQUEST, TEXT("CE_RESET_REQUEST") },
{ CE_CARD_RESET, TEXT("CE_CARD_RESET") },
{ CE_MTD_REQUEST, TEXT("CE_MTD_REQUEST!") },
{ CE_CLIENT_INFO, TEXT("CE_CLIENT_INFO!") },
{ CE_TIMER_EXPIRED, TEXT("CE_TIMER_EXPIRED!") },
{ CE_SS_UPDATED, TEXT("CE_SS_UPDATED!") },
{ CE_WRITE_PROTECT, TEXT("CE_WRITE_PROTECT") },
{ CE_CARD_INSERTION, TEXT("CE_CARD_INSERTION") },
{ CE_RESET_COMPLETE, TEXT("CE_RESET_COMPLETE") },
{ CE_ERASE_COMPLETE, TEXT("CE_ERASE_COMPLETE!") },
{ CE_REGISTRATION_COMPLETE, TEXT("CE_REGISTRATION_COMPLETE") },
{ LAST_EVENT_CODE, TEXT("Unknown Event!") },
};
LPTSTR
FindEventName(
CARD_EVENT EventCode
)
{
PEVENT_NAME_TBL pEvent = v_EventNames;
while (pEvent->EventCode != LAST_EVENT_CODE) {
if (pEvent->EventCode == EventCode) {
return pEvent->pEventName;
}
pEvent++;
}
return pEvent->pEventName;
}
#endif // DEBUG
//
// This is the PCMCIA callback function specified in CardRegisterClient.
// PCMCIA indicates card insertions and removals by calling this function.
//
STATUS PcmciaCallBack(
CARD_EVENT EventCode,
CARD_SOCKET_HANDLE hSock,
PCARD_EVENT_PARMS pParms
)
{
PDISK pDisk;
DEBUGMSG(ZONE_PCMCIA,
(TEXT("ATADISK: PcmciaCallBack(%s)\r\n"), FindEventName(EventCode)));
pDisk = (PDISK)pParms->uClientData;
switch (EventCode) {
case CE_EXCLUSIVE_REQUEST:
if (pDisk != NULL) {
return CERR_IN_USE;
}
case CE_CARD_INSERTION:
break;
case CE_PM_RESUME:
if (pDisk) {
if (pDisk->lPwrOff != -1) {
EnterCriticalSection( &pDisk->d_DiskCardCrit);
DEBUGMSG( 1, (L"PCMCIACallback disk %08X is being resumed count=%ld\r\n", pDisk, pDisk->lPwrOff));
pDisk->lPwrOff = 0;
SetEvent(pDisk->hPwrEvent);
LeaveCriticalSection( &pDisk->d_DiskCardCrit);
}
} else {
DebugBreak();
}
break;
case CE_CARD_REMOVAL:
break;
case CE_PM_SUSPEND:
#if 0
if (pDisk) {
EnterCriticalSection( &pDisk->d_DiskCardCrit);
DEBUGMSG( 1, (L"PCMCIACallback disk is being %s Count=%ld\r\n", EventCode == CE_CARD_REMOVAL ? L"Removed" : L"Suspended", pDisk->lPwrOff));
pDisk->lPwrOff++;
ResetEvent(pDisk->hPwrEvent);
LeaveCriticalSection( &pDisk->d_DiskCardCrit);
}
#endif
break;
default:
break;
}
return CERR_SUCCESS;
} // PcmciaCallBack
static BOOL isVoltageNear (USHORT supply, USHORT demand)
{
// Some cards don't report any power usage! They probably mean to be 5V.
if (demand == 0)
demand = 50;
// True iff demand is in [0.9*supply, supply]
// We need this because some cards ask for a nominal voltage of 3.0 V
// rather than 3.3 V, and then don't specify min and peak values.
// The 0.9 constant is arbitrary but sufficient for the 3.0/3.3 comparison
// without matching the 5 V entries.
return (demand <= supply && demand >= 9*supply/10);
}
//
// GetATAWindows return codes:
//
#define GAW_SUCCESS 0
#define GAW_PRIMARY_FAIL 1
#define GAW_SECONDARY_FAIL 2
#define GAW_MEMORY_FAIL 3
//
// I/O access capabilities (wtype)
//
#define ACCESS_MEMORY_ONLY 0
#define ACCESS_IO_8BIT 1
#define ACCESS_IO_16BIT 2
#define ACCESS_IO_ANY 3
//
// GetATAWindows - Function to request and map memory or I/O windows
// required for the ATA interface.
//
// wtype is the I/O access capabilities for the card configuration.
//
// Return: one of the GAW_* codes defined above.
//
DWORD
GetATAWindows(
PDISK pDisk,
DWORD wtype,
DWORD reg_base,
DWORD alt_base,
DWORD modifier
)
{
CARD_WINDOW_PARMS WndParms;
DWORD status;
CARD_WINDOW_HANDLE hATAReg; // Handle to ATA register window
PUCHAR pATAReg;
CARD_WINDOW_HANDLE hATARegAlt;// Handle to ATA alternate reg window
PUCHAR pATARegAlt;
hATARegAlt = NULL;
if (pDisk->d_Flags & ATADISK_FLAG_NO_MODIFIER) {
modifier = 0;
}
//
// Get a window handle for the ATA card's registers
//
WndParms.hSocket = pDisk->d_hSock;
if (wtype == ACCESS_MEMORY_ONLY) alt_base = ATA_ALT_MEM_REG_BASE;
switch (wtype) {
case ACCESS_MEMORY_ONLY: // memory configuration
WndParms.fAttributes = 0; // Common memory 8bit window
break;
case ACCESS_IO_8BIT:
WndParms.fAttributes = WIN_ATTR_IO_SPACE;
break;
case ACCESS_IO_16BIT:
WndParms.fAttributes = WIN_ATTR_IO_SPACE|WIN_ATTR_16BIT;
break;
case ACCESS_IO_ANY:
if (pDisk->d_Flags & ATADISK_FLAG_TRY8BIT) {
WndParms.fAttributes = WIN_ATTR_IO_SPACE;
} else {
WndParms.fAttributes = WIN_ATTR_IO_SPACE|WIN_ATTR_16BIT;
}
break;
default:
return GAW_MEMORY_FAIL;
}
WndParms.uWindowSize = ATA_REG_LENGTH;
WndParms.fAccessSpeed = WIN_SPEED_USE_WAIT;
hATAReg = (CARD_WINDOW_HANDLE)v_pfnCardRequestWindow(pDisk->d_hPcmcia, &WndParms);
if (!(pDisk->d_Flags & ATADISK_FLAG_TRY8BIT)) {
if (hATAReg == NULL) {
//
// The host may not have 16 bit I/O. Since the device allows 8 bit, try it.
//
if (wtype == ACCESS_IO_ANY) {
wtype = ACCESS_IO_8BIT;
WndParms.fAttributes = WIN_ATTR_IO_SPACE;
hATAReg = (CARD_WINDOW_HANDLE)v_pfnCardRequestWindow(pDisk->d_hPcmcia, &WndParms);
}
}
}
if (hATAReg == NULL) {
//
// Device may not support I/O access - try to get a memory config
//
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK: CardRequestWindow(hATAReg) failed %d, looking for memory configuration\r\n"),
GetLastError()));
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -