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

📄 atamain.cpp

📁 SMDK2450的BSP 有很多新的特性,记得升级PB啊.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    }
    dwUndo |= IDEINIT_UNDO_DEL_REG_IDE;
    if (!GetIDERegistryValueSet(hDevKey, pBus->m_pIdeReg)) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
            "Atapi!IDE_Init> Failed to read IDE_ registry value set from registry; device key(%s)\r\n"
            ), szDevKey));
        goto exit;
    }

    // assign IRQs

    pBus->m_pPrimaryPort->m_dwIrq = pBus->m_pIdeReg->dwIrq;
    pBus->m_pSecondaryPort->m_dwIrq = pBus->m_pIdeReg->dwIrq;

    // if IDE/ATA controller is legacy ISA/PCI, then IRQ of secondary channel is
    // (IRQ of primary channel + 1); otherwise, the primary and secondary
    // channels must share an interrupt and employ an ISR

    if (pBus->m_pIdeReg->dwLegacy) {
        pBus->m_pSecondaryPort->m_dwIrq =pBus->m_pPrimaryPort->m_dwIrq + 1;
    }

    // no SysIntr provided; we have to map IRQ to SysIntr ourselves; note that,
    // even if the primary and secondary channels share an IRQ, each channel is
    // required to have its own IRQ-SysIntr mapping

    if (!pBus->m_pIdeReg->dwSysIntr) {

        DWORD dwReturned = 0;

        if (!KernelIoControl(
            IOCTL_HAL_TRANSLATE_IRQ,
            (LPVOID)&pBus->m_pPrimaryPort->m_dwIrq, sizeof(DWORD),
            (LPVOID)&pBus->m_pPrimaryPort->m_dwSysIntr, sizeof(DWORD),
            &dwReturned
        )) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
                "Atapi!IDE_Init> Failed to map IRQ(%d) to SysIntr for primary channel of device(%s)\r\n"
                ), pBus->m_pPrimaryPort->m_dwIrq, szDevKey));
            goto exit;
        }

        // even if primary and secondary channels use the same IRQ, we need two
        // separate SysIntr mappings

        if (pBus->m_pSecondaryPort->m_fInitialized) {
            if (!KernelIoControl(
                IOCTL_HAL_TRANSLATE_IRQ,
                (LPVOID)&pBus->m_pSecondaryPort->m_dwIrq, sizeof(DWORD),
                (LPVOID)&pBus->m_pSecondaryPort->m_dwSysIntr, sizeof(DWORD),
                &dwReturned
            )) {
                DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
                    "Atapi!IDE_Init> Failed to map IRQ(%d) to SysIntr for secondary channel on device(%s)\r\n"
                    ), pBus->m_pSecondaryPort->m_dwIrq, szDevKey));
                goto exit;
            }
        }
    }
    else {

        DWORD dwReturned = 0;

        // the SysIntr corresponds to the primary channel; we need to request
        // a separate SysIntr for the secondary channel

        pBus->m_pPrimaryPort->m_dwSysIntr = pBus->m_pIdeReg->dwSysIntr;

        if (pBus->m_pSecondaryPort->m_fInitialized) {
            if (!KernelIoControl(
                IOCTL_HAL_TRANSLATE_IRQ,
                (LPVOID)&pBus->m_pSecondaryPort->m_dwIrq, sizeof(DWORD),
                (LPVOID)&pBus->m_pSecondaryPort->m_dwSysIntr, sizeof(DWORD),
                &dwReturned
            )) {
                DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
                    "Atapi!IDE_Init> Failed to map IRQ(%d) to SysIntr for secondary channel on device(%s)\r\n"
                    ), pBus->m_pSecondaryPort->m_dwIrq, szDevKey));
                goto exit;
            }
        }
    }

    // if this IDE/ATA controller only has a single channel, e.g., PC Card,
    // then destroy the secondary channel's port

    DEBUGCHK(pBus->m_pPrimaryPort->m_fInitialized);
    if (!pBus->m_pSecondaryPort->m_fInitialized) {
        delete pBus->m_pSecondaryPort;
        pBus->m_pSecondaryPort = NULL;
        dwUndo &= ~IDEINIT_UNDO_DEL_PORT_SEC;
    }

    // IDE/ATA "bus" enumeration; scan the current IDE/ATA controller's instance
    // key for DeviceX subkeys

    DEBUGMSG(ZONE_INIT, (_T(
        "Atapi!IDE_Init> Start of IDE/ATA device enumeration\r\n"
        )));

    DWORD dwIndex = 0;        // index of next DeviceX subkey to fetch/enumerate
    HKEY hKey;                // handle to DeviceX subkey
    TCHAR szNewKey[MAX_PATH]; // name of DeviceX subkey
    DWORD dwNewKeySize;       // size of name of DeviceX subkey
    DWORD dwDeviceId;         // "DeviceId" read from DeviceX subkey and resolved to 0, 1

    dwNewKeySize = (sizeof(szNewKey) / sizeof(TCHAR));

    while (
        ERROR_SUCCESS == RegEnumKeyEx(
            hDevKey,       // IDE/ATA controller's instance key
            dwIndex,       // index of the subkey to fetch
            szNewKey,      // name of subkey (e.g., "Device0")
            &dwNewKeySize, // size of name of subkey
            NULL,          // lpReserved; set to NULL
            NULL,          // lpClass; not required
            NULL,          // lpcbClass; lpClass is NULL; hence, NULL
            NULL           // lpftLastWriteTime; set to NULL
    )) {

        dwIndex += 1;
        dwNewKeySize = (sizeof(szNewKey) / sizeof(TCHAR));
        pDskReg = NULL;

        // open the DeviceX subkey; copy configuration information from the
        // IDE/ATA controller's instance key to the device's DeviceX key

        if (ERROR_SUCCESS != RegOpenKeyEx(hDevKey, szNewKey, 0, 0, &hKey)) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
                "Atapi!IDE_Init> Failed to open DeviceX subkey; device key(%s)\r\n"
                ), szDevKey));
            goto exit;
        }
        if (
            (NULL == pBus->m_pSecondaryPort) &&
            ((0 == wcscmp(szNewKey, REG_KEY_SECONDARY_MASTER)) || (0 == wcscmp(szNewKey, REG_KEY_SECONDARY_SLAVE)))
        ) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
                "Atapi!IDE_Init> Secondary channel does not exist, but Device2 and Device3 subkeys exist in %s; ignoring\r\n"
                ), szDevKey));
            dwIndex -= 1;
            continue;
        }
        if (
            (0 != wcscmp(szNewKey, REG_KEY_PRIMARY_MASTER)) && (0 != wcscmp(szNewKey, REG_KEY_PRIMARY_SLAVE)) &&
            (0 != wcscmp(szNewKey, REG_KEY_SECONDARY_MASTER)) && (0 != wcscmp(szNewKey, REG_KEY_SECONDARY_SLAVE))
        ) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
                "Atapi!IDE_Init> Found bad DeviceX subkey(%s) in device's(%s) key; ignoring\r\n"
                ), szNewKey, szDevKey));
            dwIndex -= 1;
            continue;
        }

        // fetch the device's registry value set

        pDskReg = (PDSKREG)LocalAlloc(LPTR, sizeof(DSKREG));
        if (!pDskReg) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
                "Atapi!IDE_Init> Failed to allocate DSK_ registry value set; device key(%s)\r\n"
                ), szNewKey));
            goto exit;
        }
        dwUndo |= IDEINIT_UNDO_DEL_REG_DSK;
        if (!GetDSKRegistryValueSet(hKey, pDskReg)) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
                "Atapi!IDE_Init> Failed to read DSK_ registry value set from registry; device key(%s)\r\n"
                ), szNewKey));
            goto exit;
        }

        // resolve DeviceX subkey's "DeviceId" to (0, 1), so a CDisk instance can
        // reference the correct m_pBus->m_p(Primary, Secondary)Port->(m_pDisk, m_pDskReg)
        // array element

        dwDeviceId = pDskReg->dwDeviceId; // store the original value
        pDskReg->dwDeviceId &= 0x01;

        // write the new device ID value back to the device's instance key

        if (!AtaSetRegistryValue(hKey, REG_VAL_DSK_DEVICEID, pDskReg->dwDeviceId)) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
                "Atapi!IDE_Init> Failed to write %s(%d) DSK_ registry value to device's instance key(%s)\r\n"
                ), REG_VAL_DSK_DEVICEID, dwDeviceId, szNewKey));
            goto exit;
        }


        // the master and slave CDisk instances of a particular channel have to
        // share the port instance associated with the channel; write the heap
        // address of the port instance to the device's instance key

        if ((0 == wcscmp(szNewKey, REG_KEY_PRIMARY_MASTER)) || (0 == wcscmp(szNewKey, REG_KEY_PRIMARY_SLAVE))) {

            // store the DSK_ register value set of the master/slave device in
            // the appropriate slot of the port instance

            pBus->m_pPrimaryPort->m_pDskReg[pDskReg->dwDeviceId] = pDskReg;

            if (!AtaSetRegistryValue(hKey, REG_VALUE_PORT, (DWORD)pBus->m_pPrimaryPort)) {
                DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
                    "Atapi!IDE_Init> Failed to write address of primary port instance to device's(%s) DeviceX subkey(%s)\r\n"
                    ), szDevKey, szNewKey));
                RETAILMSG(1, (_T(
                    "Atapi!IDE_Init> Failed to write address of primary port instance to device's(%s) DeviceX subkey(%s)\r\n"
                    ), szDevKey, szNewKey));                    
                goto exit;
            }

        }
        else if ((0 == wcscmp(szNewKey, REG_KEY_SECONDARY_MASTER)) || (0 == wcscmp(szNewKey, REG_KEY_SECONDARY_SLAVE))) {

            // store the DSK_ register value set of the master/slave device in
            // the appropriate slot of the port instance

            pBus->m_pSecondaryPort->m_pDskReg[pDskReg->dwDeviceId] = pDskReg;

            if (!AtaSetRegistryValue(hKey, REG_VALUE_PORT, (DWORD)pBus->m_pSecondaryPort)) {
                DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
                    "Atapi!IDE_Init> Failed to write address of secondary port instance to device's(%s) DeviceX subkey(%s)\r\n"
                    ), szDevKey, szNewKey));
                goto exit;
            }

        }

        if (!pBus->m_szDevice[dwDeviceId]) {

            // save name of device's full registry key path; when we've finished
            // enumerating the "bus", we'll call ActivateDevice against all of
            // these paths

            pBus->m_szDevice[dwDeviceId] = new TCHAR[wcslen(szDevKey) + wcslen(szNewKey) + 10];
            wcscpy(pBus->m_szDevice[dwDeviceId], szDevKey);
            wcscat(pBus->m_szDevice[dwDeviceId], L"\\");
            wcscat(pBus->m_szDevice[dwDeviceId], szNewKey);

            DEBUGMSG(ZONE_INIT, (_T(
                "Atapi!IDE_Init> Enumerated IDE/ATA device %s\r\n"
                ), pBus->m_szDevice[dwDeviceId]));
        }

    } // while

    DEBUGMSG(ZONE_INIT, (_T(
        "Atapi!IDE_Init> End of IDE/ATA device enumeration\r\n"
        )));

    // initialize enumerated devices; it's imperative that we activate the
    // channel master before the channel slave

    for (dwDeviceId = 0; dwDeviceId < 4; dwDeviceId += 1) {
        if (pBus->m_szDevice[dwDeviceId]) {
            DEBUGMSG(ZONE_INIT, (_T(
                "Atapi!IDE_Init> Activating IDE/ATA device %s\r\n"
                ), pBus->m_szDevice[dwDeviceId]));
            pBus->m_hDevice[dwDeviceId] = ActivateDeviceEx(pBus->m_szDevice[dwDeviceId], NULL, 0, NULL);
        }
    }

    dwUndo &= ~IDEINIT_UNDO_DEL_BUS;
    dwUndo &= ~IDEINIT_UNDO_DEL_PORT_PRI;
    dwUndo &= ~IDEINIT_UNDO_DEL_PORT_SEC;

exit:;

    if (dwUndo & IDEINIT_UNDO_CLS_KEY_ACTIVE) {
        RegCloseKey(hActiveKey);
    }
    if (dwUndo & IDEINIT_UNDO_CLS_KEY_DEVICE) {
        RegCloseKey(hDevKey);
    }
    if (szDevKey) {
        LocalFree(szDevKey);
    }
    if ((NULL != pBus) && (dwUndo & IDEINIT_UNDO_DEL_BUS)) {
        delete pBus;
        pBus = NULL;
    }

    return (DWORD)pBus;
}

/*++

IDE_Deinit
    This function deallocates the associated IDE/ATA controller ("bus") instance.

Parameters:
    dwHandle - pointer to associated bus instance (initially returned by
    IDE_Init)

Return:
    This function always succeeds.

--*/
EXTERN_C
BOOL
IDE_Deinit(
    DWORD dwHandle
    )
{   
    CIDEBUS *pBus = (CIDEBUS *)dwHandle;

    DEBUGCHK(pBus != NULL);
    delete pBus;

    return TRUE;
}

/*++

IDE_Open
    This function is not supported.

Parameters:
    N/A

Return:
    This function always fails.

--*/
EXTERN_C
DWORD
IDE_Open(
    HANDLE dwHandle,
    DWORD dwAccess,
    DWORD dwShareMode
    )
{
    SetLastError(ERROR_NOT_SUPPORTED);
    return NULL;
}


/*++

IDE_Close
    This function is not supported.

Parameters:
    N/A

Return:
    This function always fails.

--*/
EXTERN_C
BOOL
IDE_Close(
    DWORD dwHandle
    )
{
    SetLastError(ERROR_NOT_SUPPORTED);
    return FALSE;
}

/*++

IDE_IOControl
    This function is not supported.

Parameters:
    N/A

Return:
    This function always fails.

--*/
EXTERN_C
BOOL
IDE_IOControl(
    DWORD dwHandle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned,
    PDWORD pOverlapped
    )
{
    SetLastError(ERROR_NOT_SUPPORTED);
    return FALSE;
}

/*++

DllMain
    This function is the main ATAPI.DLL entry point.

Parameters:
    hInstance - a handle to the dll; this value is the base address of the DLL
    dwReason - the reason for the DLL is being entered
    lpReserved - not used

Return:
    On success, return true.  Otherwise, return false.

--*/
BOOL
WINAPI
DllMain(
    HANDLE hInstance,
    DWORD dwReason,
    LPVOID lpReserved
    )
{
    switch (dwReason) {

    case DLL_PROCESS_ATTACH:

        // initialize global data
        g_hInstance = (HINSTANCE)hInstance;
        InitializeCriticalSection(&g_csMain);
        // register debug zones
        RegisterDbgZones((HMODULE)hInstance, &dpCurSettings);
        DisableThreadLibraryCalls((HMODULE)hInstance);
        DEBUGMSG(ZONE_INIT, (_T("ATAPI DLL_PROCESS_ATTACH\r\n")));

        break;

    case DLL_PROCESS_DETACH:

        // deinitialize global data
        DeleteCriticalSection(&g_csMain);
        DEBUGMSG(ZONE_INIT, (TEXT("ATAPI DLL_PROCESS_DETACH\r\n")));

        break;
    }

    return TRUE;
}

⌨️ 快捷键说明

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