亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? atapipci.cpp

?? 三星2410,WinCE5.0下的硬盤IDE驅動.
?? CPP
?? 第 1 頁 / 共 2 頁
字號:
    DWORD iPage = 0, iPFN, iBuffer;
    BOOL fUnalign = FALSE;

    DMA_ADAPTER_OBJECT Adapter;

    Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);
    Adapter.InterfaceType = (INTERFACE_TYPE)m_pPort->m_pController->m_dwi.dwInterfaceType;
    Adapter.BusNumber = m_pPort->m_pController->m_dwi.dwBusNumber;

    DEBUGMSG(ZONE_DMA, (_T(
        "Atapi!CPCIDisk::SetupDMA> Request(%s), SgCount(%d)\r\n"
        ), fRead ? (_T("Read")) : (_T("Write")), dwSgCount));

    // disable bus master
    WriteBMCommand(0);

    if (!m_pPRD) {
        m_pPRD = (PDMATable)HalAllocateCommonBuffer(&Adapter,
            UserKInfo[KINX_PAGESIZE], (PPHYSICAL_ADDRESS)&m_pPRDPhys, FALSE);
        if (!m_pPRD) {
            goto ExitFailure;
        }
    }

    // m_pPhysList tracks pages used for DMA buffers when the scatter/gather
    // buffer is unaligned
    if (!m_pPhysList) {
        m_pPhysList = (PPhysTable)VirtualAlloc(m_pStartMemory, UserKInfo[KINX_PAGESIZE], MEM_COMMIT, PAGE_READWRITE);
        if (!m_pPhysList) {
            goto ExitFailure;
        }
        // allocate the minimum number of fixed pages
        for (DWORD i = 0; i < MIN_PHYS_PAGES; i++) {
            PHYSICAL_ADDRESS PhysicalAddress = {0};
            m_pPhysList[i].pVirtualAddress = (LPBYTE)HalAllocateCommonBuffer(&Adapter,
                UserKInfo[KINX_PAGESIZE], &PhysicalAddress, FALSE);
            m_pPhysList[i].pPhysicalAddress = (LPBYTE)PhysicalAddress.QuadPart;
            if (!m_pPhysList[i].pVirtualAddress) {
                goto ExitFailure;
            }
        }
    }
    m_dwPhysCount = 0;

    // m_pSGCopy tracks the mapping between scatter/gather buffers and DMA
    // buffers when the scatter/gather buffer is unaligned and we are reading,
    // so we can copy the read data back to the scatter/gather buffer; when the
    // scatter/gather buffer is aligned, m_pSGCopy tracks the scatter/gather
    // buffers of a particular DMA transfer, so we can unlock the buffers at
    // completion

    if (!m_pSGCopy) {
        m_pSGCopy = (PSGCopyTable)VirtualAlloc(
            m_pStartMemory + UserKInfo[KINX_PAGESIZE],
            UserKInfo[KINX_PAGESIZE],
            MEM_COMMIT,
            PAGE_READWRITE);
        if (!m_pSGCopy) {
            goto ExitFailure;
        }
    }
    m_dwSGCount = 0;

    if (!m_pPFNs) {
        m_pPFNs = (PDWORD)VirtualAlloc(
            m_pStartMemory + 2*UserKInfo[KINX_PAGESIZE],
            UserKInfo[KINX_PAGESIZE],
            MEM_COMMIT,
            PAGE_READWRITE);
        if (!m_pPFNs) {
            goto ExitFailure;
        }
    }

    // determine whether the a buffer or the buffer length is unaligned
    for (iBuffer = 0; iBuffer < dwSgCount; iBuffer++) {
        if (
            ((DWORD)pSgBuf[iBuffer].sb_buf & dwAlignMask) ||
            ((DWORD)pSgBuf[iBuffer].sb_len & dwAlignMask)
        ) {
            fUnalign = TRUE;
            break;
        }
    }

    if (fUnalign) {

        DWORD dwCurPageOffset = 0;

        for (iBuffer = 0; iBuffer < dwSgCount; iBuffer++) {

            // Map address and check for security violation
            LPBYTE pBuffer = (LPBYTE)MapCallerPtr((LPVOID)pSgBuf[iBuffer].sb_buf, pSgBuf[iBuffer].sb_len);
            if (pSgBuf[iBuffer].sb_buf != NULL && pBuffer == NULL) {
                // security violation
                DEBUGMSG(ZONE_ERROR, (TEXT(
                    "Atapi!CPCIDisk::SetupDMA> Failed to map pointer to caller\r\n"
                    )));
                goto ExitFailure;
            }

            DWORD dwBufferLeft = pSgBuf[iBuffer].sb_len;
            while (dwBufferLeft) {

                DWORD dwBytesInCurPage = UserKInfo[KINX_PAGESIZE] - dwCurPageOffset;
                DWORD dwBytesToTransfer = (dwBufferLeft > dwBytesInCurPage) ? dwBytesInCurPage : dwBufferLeft;

                // allocate a new page, if necessary
                if ((dwCurPageOffset == 0) && (m_dwPhysCount >= MIN_PHYS_PAGES)) {
                    PHYSICAL_ADDRESS PhysicalAddress = {0};
                    m_pPhysList[m_dwPhysCount].pVirtualAddress = (LPBYTE)HalAllocateCommonBuffer(
                        &Adapter, UserKInfo[KINX_PAGESIZE], &PhysicalAddress, FALSE);
                    m_pPhysList[m_dwPhysCount].pPhysicalAddress = (LPBYTE)PhysicalAddress.QuadPart;
                    if (!m_pPhysList[m_dwPhysCount].pVirtualAddress) {
                        goto ExitFailure;
                    }
                }

                if (fRead) {

                    // prepare a scatter/gather copy entry on read, so we can
                    // copy data from the DMA buffer to the scatter/gather
                    // buffer after this DMA transfer is complete

                    m_pSGCopy[m_dwSGCount].pSrcAddress = m_pPhysList[m_dwPhysCount].pVirtualAddress + dwCurPageOffset;
                    m_pSGCopy[m_dwSGCount].pDstAddress = pBuffer;
                    m_pSGCopy[m_dwSGCount].dwSize = dwBytesToTransfer;
                    m_dwSGCount++;

                }
                else {
                    memcpy(m_pPhysList[m_dwPhysCount].pVirtualAddress + dwCurPageOffset, pBuffer, dwBytesToTransfer);
                }

                // if this buffer is larger than the space remaining on the page,
                // then finish processing this page by setting @dwCurPageOffset<-0

                if (dwBufferLeft >= dwBytesInCurPage) {
                    dwCurPageOffset = 0;
                }
                else {
                    dwCurPageOffset += dwBytesToTransfer;
                }

                // have we finished a page? (i.e., offset was reset or this is the last buffer)
                if ((dwCurPageOffset == 0) || (iBuffer == (dwSgCount - 1))) {
                    // add this to the PRD table
                    m_pPRD[m_dwPhysCount].physAddr = (DWORD)m_pPhysList[m_dwPhysCount].pPhysicalAddress;
                    m_pPRD[m_dwPhysCount].size = dwCurPageOffset ? (USHORT)dwCurPageOffset : (USHORT)UserKInfo[KINX_PAGESIZE];
                    m_pPRD[m_dwPhysCount].EOTpad = 0;
                    m_dwPhysCount++;
                }

                // update transfer
                dwBufferLeft -= dwBytesToTransfer;
                pBuffer += dwBytesToTransfer;
           }
        }

        m_pPRD[m_dwPhysCount - 1].EOTpad = 0x8000;

    }
    else {

        DWORD dwTotalBytes = 0;

        for (iBuffer = 0; iBuffer < dwSgCount; iBuffer++) {

            // Map address and check for security violation
            LPBYTE pBuffer = (LPBYTE)MapCallerPtr((LPVOID)pSgBuf[iBuffer].sb_buf, pSgBuf[iBuffer].sb_len);
            if (pSgBuf[iBuffer].sb_buf != NULL && pBuffer == NULL) {
                // security violation
                DEBUGMSG(ZONE_ERROR, (TEXT(
                    "Atapi!CPCIDisk::SetupDMA> Failed to map pointer to caller\r\n"
                    )));
                goto ExitFailure;
            }

            // determine the number of bytes remaining to be placed in PRD
            dwTotalBytes = pSgBuf[iBuffer].sb_len;
            if (!LockPages (
                pBuffer,
                dwTotalBytes,
                m_pPFNs,
                fRead ? LOCKFLAG_WRITE : LOCKFLAG_READ)
            ) {
                goto ExitFailure;
            }

            // add a scatter/gather copy entry for the area we lock, so that
            // we can unlock it when we are finished
            m_pSGCopy[m_dwSGCount].pSrcAddress = pBuffer;
            m_pSGCopy[m_dwSGCount].pDstAddress = 0;
            m_pSGCopy[m_dwSGCount].dwSize = dwTotalBytes;
            m_dwSGCount++;

            iPFN = 0;
            while (dwTotalBytes) {

                DWORD dwBytesToTransfer = UserKInfo[KINX_PAGESIZE];

                if ((DWORD)pBuffer & dwPageMask) {
                    // the buffer is not page aligned; use up the next page
                    // boundary
                    dwBytesToTransfer = UserKInfo[KINX_PAGESIZE] - ((DWORD)pBuffer & dwPageMask);
                }

                if (dwTotalBytes < dwBytesToTransfer) {
                    // use what remains
                    dwBytesToTransfer = dwTotalBytes;
                }

                m_pPRD[iPage].physAddr = (m_pPFNs[iPFN] << UserKInfo[KINX_PFN_SHIFT]) + ((DWORD)pBuffer & dwPageMask);

                if (!TranslateAddress(&m_pPRD[iPage].physAddr)) {
                    goto ExitFailure;
                }

                m_pPRD[iPage].size = (USHORT)dwBytesToTransfer;
                m_pPRD[iPage].EOTpad = 0;

                iPage++;
                iPFN++;

                // update transfer
                pBuffer += dwBytesToTransfer;
                dwTotalBytes -= dwBytesToTransfer;
            }
        }

        m_dwPhysCount = 0;
        m_pPRD[iPage-1].EOTpad = 0x8000;
    }

    return TRUE;

ExitFailure:

    DEBUGCHK(0);

    // clean up
    // FreeDMABuffers();

    return FALSE;
}

// ----------------------------------------------------------------------------
// Function: BeginDMA
//     Begin DMA transfer
//
// Parameters:
//     fRead -
// ----------------------------------------------------------------------------

BOOL
CPCIDisk::BeginDMA(
    BOOL fRead
    )
{
    BYTE bStatus, bCommand;

    CacheSync(CACHE_SYNC_DISCARD);

    WriteBMCommand(0);
    WriteBMTable(m_pPRDPhys);

    bStatus = ReadBMStatus();
    bStatus |= 0x06;
    // bStatus |= 0x66;

    WriteBMStatus(bStatus);

    if (fRead) {
        bCommand = 0x08 | 0x01;
    }
    else {
        bCommand = 0x00 | 0x01;
    }

    WriteBMCommand(bCommand);

    bStatus = ReadBMStatus();

    return TRUE;
}

// ----------------------------------------------------------------------------
// Function: EndDMA
//     End DMA transfer
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

BOOL
CPCIDisk::EndDMA(
    )
{
    BYTE bStatus = ReadBMStatus();

    if ((bStatus & BM_STATUS_INTR) && (bStatus & BM_STATUS_ACTIVE)) {
        DEBUGMSG(ZONE_DMA, (_T(
            "Atapi!CPCIDisk::EndDMA> Status: active; status(0x%x)\r\n"
            ), bStatus));
    }
    else if ((bStatus & BM_STATUS_INTR) && !(bStatus & BM_STATUS_ACTIVE)) {
        DEBUGMSG(ZONE_DMA, (_T(
            "Atapi!CPCIDisk::EndDMA> Status: inactive; status(0x%x)\r\n"
            ), bStatus));
    }
    else if (!(bStatus & BM_STATUS_INTR)&& (bStatus & BM_STATUS_ACTIVE)) {

        DEBUGMSG(ZONE_ERROR|ZONE_DMA, (_T(
            "Atapi!CPCIDisk::EndDMA> Interrupt delayed; status(0x%x)\r\n"
            ), bStatus));

        BOOL bCount = 0;

        while (TRUE) {

            StallExecution(100);

            bCount++;
            bStatus = ReadBMStatus();

            if ((bStatus & BM_STATUS_INTR) && !(bStatus & BM_STATUS_ACTIVE)) {
                DEBUGMSG(ZONE_DMA, (_T(
                    "Atapi!CPCIDisk::EndDMA> DMA complete after delay; status(0x%x)\r\n"
                    ), bStatus));
                break;
            }
            else {
                DEBUGMSG(ZONE_ERROR|ZONE_DMA, (_T(
                    "Atapi!CPCIDisk::EndDMA> Interrupt still delayed; status(0x%x)\r\n"
                    ), bStatus));
                if (bCount > 10) {
                    WriteBMCommand(0);
                    return FALSE;
                }
            }
        }
    }
    else {
        if (bStatus & BM_STATUS_ERROR) {
            DEBUGMSG(ZONE_ERROR|ZONE_DMA, (_T(
                "Atapi!CPCIDisk::EndDMA> Error; (0x%x)\r\n"
                ), bStatus));
            DEBUGCHK(0);
            return FALSE;
        }
    }

    WriteBMCommand(0);

    return TRUE;
}

// ----------------------------------------------------------------------------
// Function: AbortDMA
//     Abort DMA transfer
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

BOOL
CPCIDisk::AbortDMA(
    )
{
    DWORD i;

    WriteBMCommand(0);

    for (i = 0; i < m_dwSGCount; i++) {
        if (!m_pSGCopy[i].pDstAddress) {
            UnlockPages(m_pSGCopy[i].pSrcAddress, m_pSGCopy[i].dwSize);
        }
    }

    // free all but the first @MIN_PHYS_PAGES pages; these are fixed
    for (i = MIN_PHYS_PAGES; i < m_dwPhysCount; i++) {
        FreePhysMem(m_pPhysList[i].pVirtualAddress);
    }

    return FALSE;
}

// ----------------------------------------------------------------------------
// Function: CompleteDMA
//     Complete DMA transfer
//
// Parameters:
//     pSgBuf -
//     dwSgCount -
//     fRead -
// ----------------------------------------------------------------------------

BOOL
CPCIDisk::CompleteDMA(
    PSG_BUF pSgBuf,
    DWORD dwSgCount,
    BOOL fRead
    )
{
    DWORD i;

    for (i = 0; i < m_dwSGCount; i++) {
        if (m_pSGCopy[i].pDstAddress) {
            // this corresponds to an unaligned region; copy it back to the
            // scatter/gather buffer
            memcpy(m_pSGCopy[i].pDstAddress, m_pSGCopy[i].pSrcAddress, m_pSGCopy[i].dwSize);
        }
        else {
            // this memory region needs to be unlocked
            UnlockPages(m_pSGCopy[i].pSrcAddress, m_pSGCopy[i].dwSize);
        }
    }

    // free all but the first @MIN_PHYS_PAGES pages; the first @MIN_PHYS_PAGES
    // pages are fixed

    for (i = MIN_PHYS_PAGES; i < m_dwPhysCount; i++) {
        FreePhysMem(m_pPhysList[i].pVirtualAddress);
    }

    return TRUE;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美二区乱c少妇| 日韩黄色在线观看| 国产三级欧美三级日产三级99| 亚洲蜜臀av乱码久久精品| av电影天堂一区二区在线| 亚洲视频免费在线观看| 91国偷自产一区二区三区观看| 亚洲欧美日韩电影| 欧美日韩黄色一区二区| 免费观看一级特黄欧美大片| 精品少妇一区二区三区日产乱码| 粉嫩av一区二区三区| 亚洲免费观看高清完整版在线观看| 91一区在线观看| 一区二区三区在线影院| 51精品视频一区二区三区| 免费一级片91| 亚洲国产一二三| 国产亚洲精品7777| 欧美一级一区二区| 在线视频国内自拍亚洲视频| 日本一区二区免费在线观看视频| 99视频国产精品| 久久99国产精品久久99 | av亚洲精华国产精华精华| 亚洲成av人片一区二区三区| 久久久99久久| 国产女主播在线一区二区| 3751色影院一区二区三区| av亚洲精华国产精华精华| 国产综合久久久久久鬼色 | 自拍偷拍亚洲综合| 国产欧美日韩不卡免费| 欧美精品一区二区在线播放| 51午夜精品国产| 欧美老肥妇做.爰bbww| 91精品久久久久久蜜臀| 欧美日韩视频在线一区二区 | 国产精品久久久久久久久搜平片 | 久久精品亚洲精品国产欧美kt∨ | 国产成人av一区| 国产不卡免费视频| 成人精品国产免费网站| 一本到不卡免费一区二区| 欧美日韩一区在线观看| 欧美性大战久久久久久久| 欧美亚洲一区三区| 欧美人牲a欧美精品| 日韩免费高清av| 国产欧美精品日韩区二区麻豆天美| 日韩精品一区二区三区中文不卡| 欧美大肚乱孕交hd孕妇| 亚洲女同女同女同女同女同69| 成人一区二区三区视频在线观看| 国产成人午夜电影网| 91香蕉视频在线| 日韩精品一区二区三区视频播放| 精品91自产拍在线观看一区| 中文字幕一区二区三区视频| 亚洲成av人在线观看| 成人国产亚洲欧美成人综合网| 欧美在线视频你懂得| 国产性色一区二区| 香蕉av福利精品导航| 九九九精品视频| 日本韩国欧美一区| 国产精品少妇自拍| 国产永久精品大片wwwapp| 一本色道久久加勒比精品| 久久久久久一二三区| 美脚の诱脚舐め脚责91 | 亚洲在线视频一区| 91丨九色丨黑人外教| 中文av一区二区| 成人美女在线视频| 亚洲特黄一级片| 一本色道久久综合狠狠躁的推荐| 国产精品视频你懂的| 国产91丝袜在线观看| 国产精品天美传媒沈樵| 成人激情小说网站| 亚洲欧洲国产日本综合| 91视视频在线观看入口直接观看www | 樱桃国产成人精品视频| 欧美日韩精品欧美日韩精品一综合| 亚洲成av人片观看| 久久精品亚洲国产奇米99| 国产在线麻豆精品观看| 蜜臀久久久99精品久久久久久| 亚洲伦在线观看| 亚洲猫色日本管| 亚洲国产精品久久人人爱蜜臀| 国产精品美女www爽爽爽| 久久久亚洲欧洲日产国码αv| 日韩欧美在线影院| 精品国产人成亚洲区| 久99久精品视频免费观看| 91精品在线麻豆| 色综合色狠狠天天综合色| 免费在线成人网| 一区二区三区四区不卡在线| 中国av一区二区三区| 日韩视频一区二区三区在线播放| 91亚洲午夜精品久久久久久| 美女一区二区三区| 蜜臀av性久久久久蜜臀aⅴ四虎| 亚洲欧洲精品一区二区三区 | 国产精品一区二区三区乱码| 亚洲综合色在线| 一区二区三区 在线观看视频| 欧美精彩视频一区二区三区| 亚洲精品一区二区三区影院| 欧美精选在线播放| 555夜色666亚洲国产免| 欧美日韩在线一区二区| 欧美手机在线视频| 欧美系列日韩一区| 欧美精选一区二区| 在线不卡一区二区| 欧美精品一区二区精品网| 日韩免费电影网站| 不卡免费追剧大全电视剧网站| 18成人在线视频| 91在线观看污| 久久精品国产免费| 亚洲一区在线看| 亚洲美女一区二区三区| 久久久精品国产免大香伊| 欧美日韩国产一级片| 欧美群妇大交群的观看方式| 91精品婷婷国产综合久久性色| 欧美一级淫片007| 日本一区二区电影| 亚洲高清不卡在线观看| 韩国一区二区三区| 在线精品视频免费播放| 欧美一区二区在线免费观看| 中文字幕av免费专区久久| 伊人一区二区三区| 国产一区二区不卡在线 | 亚洲日本丝袜连裤袜办公室| 亚洲高清视频的网址| 国产成人精品影视| 欧美日韩美少妇| 日韩伦理免费电影| 精品一区二区三区在线观看国产| 不卡区在线中文字幕| xnxx国产精品| 丝袜美腿高跟呻吟高潮一区| 国产不卡免费视频| 久久综合九色综合久久久精品综合| 亚洲欧美国产三级| 成人国产精品免费| 中文字幕欧美一区| 国产乱码精品一区二区三| 91精品在线免费观看| 婷婷开心激情综合| 欧美视频在线观看一区二区| 亚洲免费在线观看| 在线观看亚洲一区| 亚洲国产va精品久久久不卡综合| av午夜精品一区二区三区| 成人欧美一区二区三区在线播放| 高清在线观看日韩| 1024成人网| 欧洲av一区二区嗯嗯嗯啊| 亚洲精品视频免费看| 欧美亚洲国产一区二区三区va| 亚洲国产精品尤物yw在线观看| 欧美亚洲综合另类| 久久99国产精品免费网站| 国产亚洲精品中文字幕| 丰满亚洲少妇av| 亚洲高清视频中文字幕| 精品久久一区二区三区| 丁香一区二区三区| 日韩av午夜在线观看| 久久久99精品免费观看| 91国内精品野花午夜精品| 日本91福利区| 亚洲桃色在线一区| 精品欧美黑人一区二区三区| aaa欧美日韩| 精彩视频一区二区三区 | 亚洲国产精品综合小说图片区| 欧美日韩精品三区| 成人精品视频一区二区三区尤物| 亚洲丰满少妇videoshd| 国产一区二区视频在线播放| 欧美日韩在线观看一区二区| 国产精品99久| 国内精品国产成人国产三级粉色| 亚洲激情av在线| 精品国产91九色蝌蚪| 国内成+人亚洲+欧美+综合在线| 日韩三级电影网址| 国产不卡视频在线播放| 欧美男男青年gay1069videost| 国产一区二区三区免费看| 男女性色大片免费观看一区二区|