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

📄 usbrndis.c

📁 6410BSP3
💻 C
📖 第 1 页 / 共 4 页
字号:
    DWORD transferflags
    )
{
    DWORD transferStatus = 0;
    // get transfer struct on epNum
    EPTransfer* pTransfer = &m_epTransfers[epNum];;

    // if ep0 and transfer is cancelled return
    if ((epNum == 0) && m_fSetupCancelled)
        return;

    // reset transfer struct
    pTransfer->pbBuffer = pData;
    pTransfer->cbTransferSize = cbDataLen;
    pTransfer->transferFlags = transferflags;
    pTransfer->status = USBDBG_TRANSFER_STATUS_INPROGRESS;
    pTransfer->cbTransferred = 0;

    // multiple of max pkt size?
    if ((pTransfer->cbTransferSize & (m_epMaxPktSize[epNum]-1)) == 0)
        pTransfer->SendRecvNULL = TRUE;     // yes, send a NULL packet
    else
        pTransfer->SendRecvNULL = FALSE;    // no

    if (dir == ENDPT_DIR_RX)
    {
        // call PDD to enable RX FIFO
        // PDD is expected to only start RX transfer and not return any
        // data when USBDBG_MDD_TRANSFER_START flag is passed

        pTransfer->cbToTransfer = m_pddIfc.pfnRecvData(
                        epNum,
                        pTransfer->pbBuffer, 
                        pTransfer->cbTransferSize,
                        pTransfer->transferFlags | USBDBG_MDD_TRANSFER_START,
                        &transferStatus);

        // if transfer is aborted, mark it
        if (pTransfer->cbToTransfer == -1)
        {
            pTransfer->status = USBDBG_TRANSFER_STATUS_ABORTED;
            goto clean;
        }
    
        // mark xfer complete if PDD signalled transfer complete
        if (transferStatus & USBDBG_PDD_TRANSFER_COMPLETE)
        {
            pTransfer->status = USBDBG_TRANSFER_STATUS_COMPLETE;
        }
        // else NOP (transfer continues)
    
    }
    else // dir == ENDPT_DIR_TX
    {
        // send first xfer
        pTransfer->cbToTransfer = m_pddIfc.pfnSendData(
                         epNum,
                         pTransfer->pbBuffer,
                         pTransfer->cbTransferSize,
                         pTransfer->transferFlags | USBDBG_MDD_TRANSFER_START,
                         &transferStatus);
                         
        if (pTransfer->cbToTransfer == -1)
        {
            pTransfer->status = USBDBG_TRANSFER_STATUS_ABORTED;
            goto clean;
        }

        // mark xfer complete if PDD signalled transfer complete
        if (transferStatus & USBDBG_PDD_TRANSFER_COMPLETE)
        {
            pTransfer->status = USBDBG_TRANSFER_STATUS_COMPLETE;
        }
    }

clean: ;
}


// continue a receive transfer already started on EP0 or EP2
static
void
ContinueRxTransfer(
    DWORD epNum
    )
{
    DWORD transferStatus = 0;
    EPTransfer* pTransfer = &m_epTransfers[epNum];

    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:+ContinueRxTransfer.\r\n"));

    // quit if transfer has already been aborted
    if (pTransfer->status & USBDBG_TRANSFER_STATUS_ABORTED)
        goto clean;

    // quit with an error message if transfer was never started
    if (!(pTransfer->status & USBDBG_TRANSFER_STATUS_INPROGRESS))
    {
        USBDBGMSG(USBDBG_ZONE_WARN, (
            L"WARN!:usbdbg:Rx xfer not in progress on ep=%d\r\n",
            epNum));
        goto clean;
    }
        
    // PDD's responsibility when pfnRecvData is called.
    // 1. BULK ENDPT OUT - if buffer is filled up or short packet received,
    //    disable RX FIFO and set USBDBG_PDD_TRANSFER_COMPLETE
    // 2. CONTROL DATA STAGE OUT - if buffer is filled up disable RX FIFO and
    //    set USBDBG_PDD_TRANSFER_COMPLETE
    // 3. CONTROL STATUS STAGE - if buffer (size passed is 0) is filled up
    //    disable RX FIFO and set USBDBG_PDD_TRANSFER_COMPLETE.

    // get data from PDD
    pTransfer->cbToTransfer = m_pddIfc.pfnRecvData(
                        epNum,
                        pTransfer->pbBuffer +  pTransfer->cbTransferred,
                        pTransfer->cbTransferSize -  pTransfer->cbTransferred,
                        pTransfer->transferFlags,
                        &transferStatus);

    // if transfer is aborted, mark it
    if (pTransfer->cbToTransfer == -1)
    {
        pTransfer->status = USBDBG_TRANSFER_STATUS_ABORTED;
        goto clean;
    }
    
    // a packet received on epNum
    pTransfer->cbTransferred += pTransfer->cbToTransfer;

    // mark xfer complete if RX buffer is full or PDD signalled transfer complet
    if ((pTransfer->cbTransferred >= pTransfer->cbTransferSize) ||
        (transferStatus & USBDBG_PDD_TRANSFER_COMPLETE))
    {
        pTransfer->status = USBDBG_TRANSFER_STATUS_COMPLETE;
    }
    // else NOP (transfer continues)

clean:    
    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:-ContinueRxTransfer.\r\n"));
}



static
ContinueTxTransfer(
    DWORD epNum
    )
{
    BOOL fTransferComplete = FALSE;
    DWORD cbLeft;
    DWORD transferStatus = 0;
    EPTransfer* pTransfer = &m_epTransfers[epNum];

    USBDBGMSG(USBDBG_ZONE_FUNC, (
        L"usbdbg:+ContinueTxTransfer. ep%d\r\n", epNum));
    
    // quit if transfer has already been aborted
    if (pTransfer->status & USBDBG_TRANSFER_STATUS_ABORTED)
        goto clean;

    // quit with an error message if transfer was never started
    if (!(pTransfer->status & USBDBG_TRANSFER_STATUS_INPROGRESS))
    {
        USBDBGMSG(USBDBG_ZONE_WARN, (
            L"WARN!:usbdbg:Tx xfer not in progress on ep=%d\r\n",
            epNum));
        goto clean;
    }
    
    // a packet transferred on epNum
    pTransfer->cbTransferred += pTransfer->cbToTransfer;
    cbLeft = pTransfer->cbTransferSize - pTransfer->cbTransferred;
    
    // if data left to send transfer not finished yet
    if (cbLeft > 0)
        fTransferComplete = FALSE;
    // if null packet not sent yet transfer not finished
    else if (pTransfer->SendRecvNULL && (pTransfer->cbToTransfer != 0))
        fTransferComplete = FALSE;
    else
        fTransferComplete = TRUE;
        

    // mark xfer complete
    if (fTransferComplete)
    {
        pTransfer->status = USBDBG_TRANSFER_STATUS_COMPLETE;
    }
    // xfer not finished. send more data
    else
    {
        pTransfer->cbToTransfer = m_pddIfc.pfnSendData(
                                epNum,
                                pTransfer->pbBuffer + pTransfer->cbTransferred,
                                cbLeft,
                                pTransfer->transferFlags,
                                &transferStatus);

        // if transfer is aborted, mark it
        if (pTransfer->cbToTransfer == -1)
            pTransfer->status = USBDBG_TRANSFER_STATUS_ABORTED;
        // mark xfer complete if PDD signalled transfer complete
        else if (transferStatus & USBDBG_PDD_TRANSFER_COMPLETE)
            pTransfer->status = USBDBG_TRANSFER_STATUS_COMPLETE;   
    }

clean:    
    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:-ContinueTxTransfer.\r\n"));
}

// abort transfer
static
void
AbortTransfer(
    DWORD epNum,
    DWORD dir
    )
{
    EPTransfer* pTransfer = &m_epTransfers[epNum];
   
    //disable transfer
    m_pddIfc.pfnSendCmd(USBDBG_CMD_TRANSFER_ABORT, epNum, dir);
    
    pTransfer->status = USBDBG_TRANSFER_STATUS_ABORTED;
}

static
void
AbortTransfers(
    BOOL abortEp0Transfers,
    BOOL abortEpxTransfers
)
{
    if (abortEp0Transfers)
    {
        AbortTransfer(CONTROL_ENDPT, ENDPT_DIR_IN);
        AbortTransfer(CONTROL_ENDPT, ENDPT_DIR_OUT);
    }

    if (abortEpxTransfers)
    {
        AbortTransfer(INTIN_ENDPT, ENDPT_DIR_IN);
        AbortTransfer(BULKIN_ENDPT, ENDPT_DIR_IN);
        AbortTransfer(BULKOUT_ENDPT, ENDPT_DIR_OUT);
    }
}

// blocking call starts a rx or tx transaction
static
DWORD
SendRecvData(
    UINT32 epNum,
    DWORD dir,
    UINT8 *pData, 
    UINT32 cbDataLen,
    DWORD flags
    )
{
    DWORD dwStartSec, dwSec;
    DWORD dwRet;
    EPTransfer* pTransfer = &m_epTransfers[epNum];

    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:+SendRecvData. ep%d\r\n", epNum));

    dwStartSec = OEMKitlGetSecs();

    // start rx or tx transfer
    StartTransfer(epNum, dir, pData, cbDataLen, flags);

    // loop until all data sent
    while(pTransfer->status & USBDBG_TRANSFER_STATUS_INPROGRESS)
    {
        UsbRndis_EventHandler();

        dwSec = OEMKitlGetSecs();
        // timed out sending data?
        if ((INT32)(dwSec - dwStartSec) > SEND_RECV_TIME_OUT)
        {
            USBDBGMSG(USBDBG_ZONE_ERROR, (
                L"ERROR!UsbDbg: ep%d dir=%d timed out tx/rx data."
                L"dwSec=%d, dwStartSec=%d\r\n",
                epNum, dir, dwSec, dwStartSec));
            dwRet = ERROR_TIMEOUT;
            goto clean;
        }
    }
    
    if (pTransfer->status & USBDBG_TRANSFER_STATUS_COMPLETE)
        dwRet = ERROR_SUCCESS;
    else
        dwRet = E_FAIL;

clean:
    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:-SendRecvData. ep%d\r\n", epNum));

    return dwRet;
}

static
DWORD 
SendControlStatusHandshake(
    )
{
    DWORD dwRet;
    
    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:+SendControlStatusHandshake\r\n"));

    // Send an empty packet to ACK the transfer
    dwRet = SendRecvData(CONTROL_ENDPT,
                          ENDPT_DIR_TX,
                          m_ep0MsgRxBuffer,
                          0,
                          USBDBG_MDD_EP0_STATUS_STAGE);

    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:-SendControlStatusHandshake\r\n"));

    return dwRet;

}

static
DWORD
RecvControlStatusHandshake(
    )
{
    DWORD dwRet;
    
    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:+RecvControlStatusHandshake\r\n"));

    // receive an empty packet
    dwRet = SendRecvData(CONTROL_ENDPT,
                          ENDPT_DIR_RX,
                          m_ep0MsgRxBuffer,
                          0,
                          USBDBG_MDD_EP0_STATUS_STAGE);

    USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:-RecvControlStatusHandshake\r\n"));

    return dwRet;
}

// for a GET_DESCRIPTOR setup request sends the descriptor
static
BOOL
SendDescriptor(
    USB_DEVICE_REQUEST* pUdr
    )
{
    UCHAR *pucData;
    WORD wLength;
    WORD wType = pUdr->wValue;
    BOOL fRet = TRUE;

    switch (HIBYTE(wType)) {
        case USB_DEVICE_DESCRIPTOR_TYPE:
            USBDBGMSG(USBDBG_ZONE_VERBOSE, (
                L"UsbDbg:Setup request [USB_REQUEST_GET_DESCRIPTOR: "
                L"USB_DEVICE_DESCRIPTOR_TYPE] Len:%d\r\n",
                pUdr->wLength));

⌨️ 快捷键说明

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