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

📄 atapipcmcia.cpp

📁 这是运行在windows ce 4.2 版本下的关于硬盘加载的驱动程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    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 + -