📄 usbbulkdevlib.c
字号:
return (USB_INTERNAL_ERROR); } if (pBulkDev->outIrp.result == S_usbHcdLib_STALLED) { usbBulkDevResetRecovery (pBulkDev); OSS_SEM_GIVE (pBulkDev->bulkIrpSem); return (USB_BULK_IO_ERROR); }/* if (pBulkDev->outIrp.result != 0) { USB_BULK_DEBUG ("usbBulkCmdExecute: Out Irp Bad Value 0x%x \n", pBulkDev->outIrp.result, 0, 0, 0, 0, 0); }*/ /* * Check whether any data is to be transferred to/from the device. * If yes, form an IRP and submit it. */ if (pBulkDev->bulkCbw.dataXferLength > 0) { if (pBulkDev->bulkCbw.direction == USB_CBW_DIR_IN) { /* data is expected from the device. read from BULK_IN pipe */ pBulkDev->inIrp.result = 0; pBulkDev->inIrp.transferLen = USB_BULK_SWAP_32( pBulkDev->bulkCbw.dataXferLength); pBulkDev->inIrp.bfrList[0].pBfr = pBulkDev->bulkInData; pBulkDev->inIrp.bfrList[0].bfrLen = USB_BULK_SWAP_32( pBulkDev->bulkCbw.dataXferLength); /* Submit IRP */ if (usbdTransfer (usbdHandle, pBulkDev->inPipeHandle, &(pBulkDev->inIrp)) != OK) { USB_BULK_ERR ("usbBulkCmdExecute: Unable to submit IRP for "\ "BULK_IN data transfer\n", 0, 0, 0, 0, 0, 0); OSS_SEM_GIVE (pBulkDev->bulkIrpSem); return (USB_INTERNAL_ERROR); } /* * wait till the data transfer ends on the bulk in pipe, before * reading the command status */ if ( OSS_SEM_TAKE (pBulkDev->bulkIrpSem, usbBulkIrpTimeOut + USB_BULK_OFFS) == ERROR ) { USB_BULK_DEBUG ("usbBulkCmdExecute: Irp time out \n", 0, 0, 0, 0, 0, 0); /* Cancel the IRP */ usbdTransferAbort(usbdHandle, pBulkDev->inPipeHandle, &(pBulkDev->inIrp)); return (USB_INTERNAL_ERROR); } } else { /* device is expecting data over BULK_OUT pipe. send it */ pBulkDev->outIrp.result = 0; pBulkDev->outIrp.transferLen = USB_BULK_SWAP_32( pBulkDev->bulkCbw.dataXferLength); pBulkDev->outIrp.bfrList[0].pBfr = pBulkDev->bulkOutData; pBulkDev->outIrp.bfrList[0].bfrLen = USB_BULK_SWAP_32( pBulkDev->bulkCbw.dataXferLength); /* Submit IRP */ if (usbdTransfer (usbdHandle, pBulkDev->outPipeHandle, &(pBulkDev->outIrp)) != OK) { USB_BULK_ERR ("usbBulkCmdExecute: Unable to submit IRP for "\ "BULK_OUT data transfer\n", 0, 0, 0, 0, 0, 0); OSS_SEM_GIVE (pBulkDev->bulkIrpSem); return (USB_INTERNAL_ERROR); } /* * wait till the data transfer ends on bulk out pipe before reading * the command status */ if ( OSS_SEM_TAKE (pBulkDev->bulkIrpSem, usbBulkIrpTimeOut + USB_BULK_OFFS) == ERROR ) { USB_BULK_DEBUG ("usbBulkCmdExecute: Irp time out \n", 0, 0, 0, 0, 0, 0); /* Cancel the IRP */ usbdTransferAbort(usbdHandle, pBulkDev->outPipeHandle, &(pBulkDev->outIrp)); return (USB_INTERNAL_ERROR); } } } /* read the command status from the device. */ pBulkDev->statusIrp.result = 0; pBulkDev->statusIrp.transferLen = USB_CSW_LENGTH; pBulkDev->statusIrp.bfrList[0].pBfr = (UINT8 *)(&pBulkDev->bulkCsw); pBulkDev->statusIrp.bfrList[0].bfrLen = USB_CSW_LENGTH; /* Submit IRP */ if (usbdTransfer (usbdHandle, pBulkDev->inPipeHandle, &pBulkDev->statusIrp) != OK) { USB_BULK_ERR ("usbBulkCmdExecute: Unable to submit Status IRP\n", 0, 0, 0, 0, 0, 0); OSS_SEM_GIVE (pBulkDev->bulkIrpSem); return (USB_INTERNAL_ERROR); } if ( OSS_SEM_TAKE (pBulkDev->bulkIrpSem, usbBulkIrpTimeOut + USB_BULK_OFFS) == ERROR ) { USB_BULK_DEBUG ("usbBulkCmdExecute: Irp time out \n", 0, 0, 0, 0, 0, 0); /* Cancel the IRP */ usbdTransferAbort(usbdHandle, pBulkDev->inPipeHandle, &(pBulkDev->statusIrp)); return (USB_INTERNAL_ERROR); } /* Check whether status IRP was transferred */ if (pBulkDev->statusIrp.result == S_usbHcdLib_STALLED) /* if stalled */ { /* Clear STALL on the BULK IN endpoint */ if ((usbdFeatureClear (usbdHandle, pBulkDev->bulkDevId, USB_RT_ENDPOINT, USB_FSEL_DEV_ENDPOINT_HALT, (pBulkDev->inEpAddress & 0xFF))) != OK) { USB_BULK_ERR ("usbBulkCmdExecute: Failed to clear HALT feauture "\ "on bulk in Endpoint %x\n", 0, 0, 0, 0, 0, 0); } /* Try to read the CSW once again */ if (usbdTransfer (usbdHandle, pBulkDev->inPipeHandle, &pBulkDev->statusIrp) != OK) { USB_BULK_ERR ("usbBulkCmdExecute: Unable to submit Status IRP\n", 0, 0, 0, 0, 0, 0); OSS_SEM_GIVE (pBulkDev->bulkIrpSem); return (USB_INTERNAL_ERROR); } if ( OSS_SEM_TAKE (pBulkDev->bulkIrpSem, usbBulkIrpTimeOut + USB_BULK_OFFS) == ERROR ) { USB_BULK_DEBUG ("usbBulkCmdExecute: Irp time out \n", 0, 0, 0, 0, 0, 0); /* Cancel the IRP */ usbdTransferAbort(usbdHandle, pBulkDev->inPipeHandle, &(pBulkDev->statusIrp)); return (USB_INTERNAL_ERROR); } /* how about the status this time */ if (pBulkDev->statusIrp.result == S_usbHcdLib_STALLED) { /* Failed to read CSW again. Do reset recovery */ USB_BULK_DEBUG ("usbBulkCmdExecute: Irp stalled \n", 0, 0, 0, 0, 0, 0); OSS_SEM_GIVE (pBulkDev->bulkIrpSem); usbBulkDevResetRecovery (pBulkDev); return (USB_BULK_IO_ERROR); } } OSS_SEM_GIVE (pBulkDev->bulkIrpSem); /* If any error other than STALL on Endpoint. */ if ( pBulkDev->statusIrp.result != OK ) { return (USB_IRP_FAILED); } /* If successful in transferring the CSW IRP, check the buffer */ pCsw = (pUSB_BULK_CSW)(pBulkDev->statusIrp.bfrList[0].pBfr); /* Check the length of CSW received. If not USB_CSW_LENGTH, invalid CSW. */ if ( pBulkDev->statusIrp.bfrList[0].actLen != USB_CSW_LENGTH) { USB_BULK_ERR ("usbBulkCmdExecute: Invalid CSW\n", 0, 0, 0, 0, 0, 0); usbBulkDevResetRecovery (pBulkDev); return (USB_INVALID_CSW); } /* check the signature/tag/status in command status block */ if ( (pCsw->signature != USB_BULK_SWAP_32 (USB_CSW_SIGNATURE)) || (pCsw->tag != USB_BULK_SWAP_32 (USB_CBW_TAG)) || (pCsw->status > USB_CSW_PHASE_ERROR)) { USB_BULK_ERR ("usbBulkCmdExecute: Logical Error in status block\n", 0, 0, 0, 0, 0, 0); usbBulkDevResetRecovery (pBulkDev); return (USB_INVALID_CSW); } /* check for Data residue. */ if (pCsw->dataResidue > 0) { USB_BULK_ERR ("usbBulkCmdExecute: Data transfer incomplete\n", 0, 0, 0, 0, 0, 0); return (USB_DATA_INCOMPLETE); } /* It is a valid CSW. Check for the status of the CBW executed */ if ( pCsw->status == USB_CSW_STATUS_FAIL ) /* Command failed */ { USB_BULK_ERR ("usbBulkCmdExecute: CBW Failed \n", 0, 0, 0, 0, 0, 0); return (USB_COMMAND_FAILED); } else if (pCsw->status == USB_CSW_PHASE_ERROR) { /* Phase error while executing the command in CBW. Reset recovery */ USB_BULK_ERR ("usbBulkCmdExecute: Phase Error\n", 0, 0, 0, 0, 0, 0); /* fatal error. do a reset recovery */ usbBulkDevResetRecovery (pBulkDev); return (USB_PHASE_ERROR); } return (USB_COMMAND_SUCCESS); }/***************************************************************************** usbBulkDevDestroy - release USB_BULK_DEV structure and its links** Unlinks the indicated USB_BULK_DEV structure and de-allocates* resources associated with the device.** RETURNS: N/A** ERRNO : none**\NOMANUAL */LOCAL void usbBulkDevDestroy ( pUSB_BULK_DEV pBlkDev /* pointer to bulk device */ ) { pUSB_BULK_DEV pBulkDev = (pUSB_BULK_DEV) pBlkDev; if (pBulkDev != NULL) { /* Unlink the structure. */ usbListUnlink (&pBulkDev->bulkDevLink); /* Release pipes and wait for IRPs. */ if (pBulkDev->outPipeHandle != NULL) usbdPipeDestroy (usbdHandle, pBulkDev->outPipeHandle); if (pBulkDev->inPipeHandle != NULL) usbdPipeDestroy (usbdHandle, pBulkDev->inPipeHandle); /* wait for any IRP to complete then destroy the mutex */ OSS_SEM_TAKE (pBulkDev->bulkIrpSem, OSS_DONT_BLOCK); OSS_SEM_GIVE (pBulkDev->bulkIrpSem); if (pBulkDev->bulkIrpSem) OSS_SEM_DESTROY(pBulkDev->bulkIrpSem); /* Free up any mutex waiting for that USB device */ OSS_MUTEX_RELEASE(pBulkDev->bulkDevMutex); OSS_MUTEX_DESTROY(pBulkDev->bulkDevMutex); /* Release structure. */ OSS_FREE (pBulkDev); } }/***************************************************************************** usbBulkDevFind - Searches for a USB_BULK_DEV for indicated node ID** This fucntion searches for the pointer of USB_BULK_DEV for the indicated * <nodeId>. If the matching pointer is not found it returns NULL.** RETURNS: pointer to matching USB_BULK_DEV or NULL if not found** ERRNO: none*/LOCAL pUSB_BULK_DEV usbBulkDevFind ( USBD_NODE_ID nodeId /* node ID to be looked for */ ) { pUSB_BULK_DEV pBulkDev; OSS_MUTEX_TAKE(bulkMutex, OSS_BLOCK); pBulkDev = usbListFirst (&bulkDevList); /* browse through the list */ while (pBulkDev != NULL) { if (pBulkDev->bulkDevId == nodeId) break; pBulkDev = usbListNext (&pBulkDev->bulkDevLink); } OSS_MUTEX_RELEASE(bulkMutex); return (pBulkDev); }/***************************************************************************** findEndpoint - searches for a BULK endpoint of the indicated direction** This routine finds the Bulk Endpoint for inidicated endpoint** RETURNS: pointer to matching endpoint descriptor or NULL if not found** ERRNO: none*\NOMANUAL*/LOCAL pUSB_ENDPOINT_DESCR findEndpoint ( pUINT8 pBfr, UINT16 bfrLen, UINT16 direction ) { pUSB_ENDPOINT_DESCR pEp; while ((pEp = usbDescrParseSkip (&pBfr, &bfrLen, USB_DESCR_ENDPOINT)) != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -