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

📄 diskmain.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    CDiskPower *pDiskPower = new CDiskPower;
    return pDiskPower;
}

// ----------------------------------------------------------------------------
// Function: SetDiskPowerState
//     Map a power state to an ATA power management command and issue the
//     command
//
// Parameters:
//     newDx -
// ----------------------------------------------------------------------------

BOOL
CDisk::SetDiskPowerState(
    CEDEVICE_POWER_STATE newDx
    )
{
    BYTE bCmd;

    DEBUGMSG(ZONE_FUNC,(TEXT("CDisk: SetDiskPowerState+\r\n")));

    if (ZONE_CELOG) {
        DWORD dwDx = (DWORD) newDx;
        CeLogData(TRUE, CELID_ATA_SETDEVICEPOWER, &dwDx, sizeof(dwDx), 0, CELZONE_ALWAYSON, 0, FALSE);
    }

    // on D0 go to IDLE to minimize latency during disk accesses
    if(newDx == D0 || newDx == D1) {
        bCmd = ATA_CMD_IDLE_IMMEDIATE;
    }
    else if(newDx == D2) {
        bCmd = ATA_CMD_STANDBY_IMMEDIATE;
    }
    else if(newDx == D3 || newDx == D4) {
        bCmd = ATA_CMD_SLEEP;
    }
    else {
        DEBUGMSG(ZONE_WARNING, (_T(
            "CDisk::SetDiskPowerState> Invalid power state value(%u)\r\n"
            ), newDx));
        return FALSE;
    }

    DEBUGMSG(ZONE_FUNC,(TEXT("CDisk: SetDiskPowerState-\r\n")));
    // update the disk power state
    return SendDiskPowerCommand(bCmd);
}

// ----------------------------------------------------------------------------
// Function: WakeUp
//     Wake the device up from sleep
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

BOOL
CDisk::WakeUp(
    )
{
    if (!ResetController(FALSE)) {
        return FALSE;
    }
    return SendIdentifyDevice(IsAtapiDevice());
}

// ----------------------------------------------------------------------------
// Function: MainIoctl
//     Process IOCTL_DISK_ and DISK_IOCTL_ I/O controls
//
// Parameters:
//     pIOReq -
// ----------------------------------------------------------------------------

DWORD
CDisk::MainIoctl(
    PIOREQ pIOReq
    )
{
    DWORD dwError = ERROR_SUCCESS;

    DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl+\r\n")));
#if 0
    DEBUGMSG(ZONE_IOCTL, (TEXT(
        "Ata!CDisk::MainIoctl> IOCTL(%x), device(%x)\r\n"
        ), pIOReq->dwCode, m_dwDeviceId));
#endif
    // device is powering down; fail

    if (m_dwDeviceFlags & DFLAGS_DEVICE_PWRDN) {
        SetLastError(ERROR_DEVICE_NOT_AVAILABLE);
        return FALSE;
    }

    switch(pIOReq->dwCode) {
        case IOCTL_DISK_GETINFO:
        case DISK_IOCTL_GETINFO:
            DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:DISK_IOCTL_GETINFO\r\n")));
            if (IsCDRomDevice()) {
                dwError = ERROR_BAD_COMMAND;
            }
            else {
                dwError = GetDiskInfo(pIOReq);
            }
            break;
        case IOCTL_DISK_DEVICE_INFO:
            DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_DEVICE_INFO\r\n")));
            dwError = GetDeviceInfo(pIOReq);
            break;
        case DISK_IOCTL_GETNAME:
        case IOCTL_DISK_GETNAME:
            DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_GETNAME\r\n")));
            dwError = GetDiskName(pIOReq);
            break;
        case DISK_IOCTL_SETINFO:
        case IOCTL_DISK_SETINFO:
            DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_SETINFO\r\n")));
            dwError = SetDiskInfo(pIOReq);
            break;
        case DISK_IOCTL_READ:
        case IOCTL_DISK_READ:
            DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_READ\r\n")));
            if (!ValidateSg((PSG_REQ)pIOReq->pInBuf,pIOReq->dwInBufSize)) {
                dwError = ERROR_INVALID_PARAMETER;
            }
            else {
                if (IsDMASupported()) {
                    dwError = ReadWriteDiskDMA(pIOReq, TRUE);
                }
                else {
                    dwError = ReadWriteDisk(pIOReq, TRUE);
                }
            }
            break;
        case DISK_IOCTL_WRITE:
        case IOCTL_DISK_WRITE:
            DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_WRITE\r\n")));
            if (!ValidateSg((PSG_REQ)pIOReq->pInBuf,pIOReq->dwInBufSize)) {
                dwError=ERROR_INVALID_PARAMETER;
            }
            else {
                if (IsDMASupported()) {
                    dwError = ReadWriteDiskDMA(pIOReq, FALSE);
                }
                else {
                    dwError = ReadWriteDisk(pIOReq, FALSE);
                }
            }
            break;
        case IOCTL_DISK_GET_STORAGEID:
            DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_GET_STORAGEID\r\n")));
            dwError = GetStorageId(pIOReq);
            break;
        case DISK_IOCTL_FORMAT_MEDIA:
        case IOCTL_DISK_FORMAT_MEDIA:
            DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_FORMAT_MEDIA\r\n")));
            dwError = ERROR_SUCCESS;
            break;;
        case IOCTL_DISK_FLUSH_CACHE:
            DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl:IOCTL_DISK_FLUSH_CACHE\r\n")));
            dwError = FlushCache();
            break;

        default:
            dwError = ERROR_NOT_SUPPORTED;
            break;
    }

    DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: MainIoctl-\r\n")));
    return dwError;
}

// ----------------------------------------------------------------------------
// Function: PerformIoctl
//     This is the top-most IOCTL processor and is used to trap IOCTL_POWER_
//     I/O controls to pass to the associated power management object
//
// Parameters:
//     pIOReq -
// ----------------------------------------------------------------------------

BOOL
CDisk::PerformIoctl(
    PIOREQ pIOReq
    )
{
    DWORD dwError = ERROR_SUCCESS;

    DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: PerformIoctl+\r\n")));
#if 0
    DEBUGMSG(ZONE_IOCTL, (TEXT(
        "Ata!CDisk::PerformIoctl> IOCTL(%x), device(%x)\r\n"
        ), pIOReq->dwCode, m_dwDeviceId));
#endif
    if (pIOReq->pBytesReturned) {
        *(pIOReq->pBytesReturned) = 0;
    }

    TakeCS();
    m_pPort->TakeCS();

    if (ZONE_CELOG) CeLogData(TRUE, CELID_ATA_STARTIOCTL, pIOReq, sizeof(*pIOReq), 0, CELZONE_ALWAYSON, 0, FALSE);

    __try {

        if (pIOReq->dwCode == IOCTL_POWER_CAPABILITIES) {

			DEBUGMSG(ZONE_FUNC,(TEXT("CDisk: PerformIoctl:IOCTL_POWER_CAPABILITIES\r\n")));
            // instantiate DiskPower object on first use, if necessary

            if (m_pDiskPower == NULL) {
                CDiskPower *pDiskPower = GetDiskPowerInterface();
                if (pDiskPower == NULL) {
                    DEBUGMSG(ZONE_WARNING, (_T(
                        "Ata!CDisk::PerformIoctl> Failed to create power management object\r\n"
                        )));
                }
                else if (!pDiskPower->Init(this)) {
                    DEBUGMSG(ZONE_WARNING, (_T(
                        "Ata!CDisk::PerformIoctl> Failed to initialize power management\r\n"
                        )));
                    delete pDiskPower;
                }
                else {
                    m_pDiskPower = pDiskPower;
                }
            }
        }

        if (m_pDiskPower != NULL) {

            // is this a power IOCTL?
            dwError = m_pDiskPower->DiskPowerIoctl(pIOReq);
            if (dwError != ERROR_NOT_SUPPORTED) {
                goto done;
            }

            // request that the disk spin up (if it's not up already)
            if (!m_pDiskPower->RequestDevice()) {
                // the disk is powered down
                dwError = ERROR_RESOURCE_DISABLED;
                goto done;
            }
        }

        // call the driver
        dwError = MainIoctl(pIOReq);


        // indicate we're done with the disk
        if (m_pDiskPower != NULL) {
            m_pDiskPower->ReleaseDevice();
        }

done:;

    } __except(EXCEPTION_EXECUTE_HANDLER) {
        dwError = ERROR_GEN_FAILURE;
    }

    if (ZONE_CELOG) CeLogData(TRUE, CELID_ATA_COMPLETEIOCTL, &dwError, sizeof(dwError), 0, CELZONE_ALWAYSON, 0, FALSE);

    m_pPort->ReleaseCS();
    ReleaseCS();

    if (dwError != ERROR_SUCCESS) {
        SetLastError(dwError);
    }

    DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: PerformIoctl-\r\n")));
    return (ERROR_SUCCESS == dwError);
}

// ----------------------------------------------------------------------------
// Function: PostInit
//     This function facilitates backward compatibility
//
// Parameters:
//     pPostInitBuf -
// ----------------------------------------------------------------------------

BOOL
CDisk::PostInit(
    PPOST_INIT_BUF pPostInitBuf
    )
{
    DWORD dwError = ERROR_SUCCESS;

//    DEBUGMSG(ZONEID_INIT, (TEXT("Ata!CDisk::PostInit> device(%d)\r\n"), m_dwDeviceId));

    m_hDevice = pPostInitBuf->p_hDevice;

    return (dwError == ERROR_SUCCESS);
}

// ----------------------------------------------------------------------------
// Function: GetDiskInfo
//     Implement IOCTL_DISK_GETINFO
//
// Parameters:
//     pIOReq -
// ----------------------------------------------------------------------------

DWORD
CDisk::GetDiskInfo(
    PIOREQ pIOReq
    )
{
    DWORD dwError = ERROR_SUCCESS;
    DISK_INFO *pInfo = NULL;

    DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: GetDiskInfo+\r\n")));
    // for B/C, this call has three forms; only pInBuf, only pOutBuf, or both
    // if both, then use pOutBuf

    if (pIOReq->pInBuf) {
        if (pIOReq->dwInBufSize != sizeof(DISK_INFO)) {
            return ERROR_INVALID_PARAMETER;
        }
        pInfo = (DISK_INFO *)pIOReq->pInBuf;
    }

    if (pIOReq->pOutBuf) {
        if (pIOReq->dwOutBufSize!= sizeof(DISK_INFO)) {
            return ERROR_INVALID_PARAMETER;
        }
        pInfo = (DISK_INFO *)pIOReq->pOutBuf;
    }

    if (!pInfo) {
        DEBUGMSG(ZONE_ERROR|ZONE_IOCTL, (_T(
            "Ata!CDisk::GetDiskInfo> bad argument; pInBuf/pOutBuf null\r\n")));
        return ERROR_INVALID_PARAMETER;
    }

    // TODO: if device is ATAPI, call AtapiGetDiskInfo

    if (ERROR_SUCCESS == dwError) {
        __try {
            if (0 == CeSafeCopyMemory((LPVOID)pInfo, (LPVOID)&m_DiskInfo, sizeof(DISK_INFO))) {
                return ERROR_INVALID_PARAMETER;
            }

            pInfo->di_flags |= DISK_INFO_FLAG_PAGEABLE;
            pInfo->di_flags &= ~DISK_INFO_FLAG_UNFORMATTED;

            if (pIOReq->pBytesReturned){
                *(pIOReq->pBytesReturned) = sizeof(DISK_INFO);
            }
        } __except(EXCEPTION_EXECUTE_HANDLER) {
            dwError = ERROR_INVALID_PARAMETER;
        }
    }

    DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: GetDiskInfo-\r\n")));
    return dwError;
}

// ----------------------------------------------------------------------------
// Function: SetDiskInfo
//     Implement IOCTL_DISK_SETINFO
//
// Parameters:
//     pSgReq -
//     InBufLen -
// ----------------------------------------------------------------------------

DWORD
CDisk::SetDiskInfo(
    PIOREQ pIOReq
    )
{
    DWORD dwError = ERROR_SUCCESS;
    DISK_INFO *pInfo = (DISK_INFO *)pIOReq->pInBuf;

    DEBUGMSG(ZONE_FUNC, (TEXT("CDisk: SetDiskInfo+\r\n")));
    if ((pIOReq->pInBuf == NULL) || (pIOReq->dwInBufSize != sizeof(DISK_INFO))) {
        return ERROR_INVALID_PARAMETER;
    }

    if (0 == CeSafeCopyMemory((LPVOID)&m_DiskInfo, (LPVOID)pInfo, sizeof(DISK_INFO))) {
        return ERROR_INVALID_PARAMETER;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -