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

📄 system.c

📁 WinCE下的ATADISK驱动
💻 C
📖 第 1 页 / 共 3 页
字号:


//
// 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 + -