📄 usbrndis.c
字号:
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 + -