📄 usbbulkdevlib.c
字号:
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 & 0x7F))) != 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 (bulkIrpSem); return (USB_INTERNAL_ERROR); } if ( OSS_SEM_TAKE (bulkIrpSem, usbBulkIrpTimeOut + USB_BULK_OFFS) == ERROR ) { USB_BULK_DEBUG ("usbBulkCmdExecute: Irp time out \n", 0, 0, 0, 0, 0, 0); OSS_SEM_GIVE (bulkIrpSem); 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 */ OSS_SEM_GIVE (bulkIrpSem); usbBulkDevResetRecovery (pBulkDev); return (USB_BULK_IO_ERROR); } } OSS_SEM_GIVE (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*/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 */ OSS_SEM_TAKE (bulkIrpSem, OSS_BLOCK); OSS_SEM_GIVE (bulkIrpSem); /* Release structure. */ OSS_FREE (pBulkDev); } }/***************************************************************************** usbBulkDevFind - Searches for a USB_BULK_DEV for indicated node ID** RETURNS: pointer to matching USB_BULK_DEV or NULL if not found*/LOCAL pUSB_BULK_DEV usbBulkDevFind ( USBD_NODE_ID nodeId /* node ID to be looked for */ ) { pUSB_BULK_DEV pBulkDev = usbListFirst (&bulkDevList); /* browse through the list */ while (pBulkDev != NULL) { if (pBulkDev->bulkDevId == nodeId) break; pBulkDev = usbListNext (&pBulkDev->bulkDevLink); } return (pBulkDev); }/***************************************************************************** findEndpoint - Searches for a BULK endpoint of the indicated direction.** RETURNS: pointer to matching endpoint descriptor or NULL if not found*/LOCAL pUSB_ENDPOINT_DESCR findEndpoint ( pUINT8 pBfr, UINT16 bfrLen, UINT16 direction ) { pUSB_ENDPOINT_DESCR pEp; while ((pEp = usbDescrParseSkip (&pBfr, &bfrLen, USB_DESCR_ENDPOINT)) != NULL) { if ((pEp->attributes & USB_ATTR_EPTYPE_MASK) == USB_ATTR_BULK && (pEp->endpointAddress & USB_ENDPOINT_DIR_MASK) == direction) break; } return pEp; }/***************************************************************************** usbBulkPhysDevCreate - create a USB_BULK_DEV Structure for the device attached** This function is invoked from the dynamic attach callback routine whenever * a USB_BULK_DEV device is attached. It allocates memory for the structure,* sets device configuration, and creates pipe for bulk-in and bulk-out endpoints.* * RETURNS: OK on success, ERROR if failed to create pipes, set configuration*/LOCAL STATUS usbBulkPhysDevCreate ( USBD_NODE_ID nodeId, /* USBD Node Id ofthe device */ UINT16 configuration, /* Configuration value */ UINT16 interface /* Interface Number */ ) { UINT16 actLength; UINT8 bfr[255]; /* store for descriptors */ UINT8 * pBfr = bfr; /* pointer to the above store*/ UINT ifNo; UINT16 maxPacketSize; pUSB_BULK_DEV pBulkDev; pUSB_CONFIG_DESCR pCfgDescr; pUSB_INTERFACE_DESCR pIfDescr; pUSB_ENDPOINT_DESCR pOutEp; pUSB_ENDPOINT_DESCR pInEp; /* * A new device is being attached. Check if we already * have a structure for this device. */ if (usbBulkDevFind (nodeId) != NULL) return (OK); /* Allocate memory for a new structure to represent this device */ if ((pBulkDev = OSS_CALLOC (sizeof (*pBulkDev))) == NULL) { USB_BULK_ERR ("usbBulkPhysDevCreate: Unable to allocate memory\n", 0, 0, 0, 0, 0, 0); goto errorExit; } pBulkDev->bulkDevId = nodeId; pBulkDev->configuration = configuration; pBulkDev->interface = interface; pBulkDev->connected = TRUE; /* Check out the device configuration */ /* Configuration index is assumed to be one less than config'n value */ if (usbdDescriptorGet (usbdHandle, pBulkDev->bulkDevId, USB_RT_STANDARD | USB_RT_DEVICE, USB_DESCR_CONFIGURATION, (configuration - 1), 0, 255, bfr, &actLength) != OK) { USB_BULK_ERR ("usbBulkPhysDevCreate: Unable to read configuration "\ "descriptor\n", 0, 0, 0, 0, 0, 0); goto errorExit; } if ((pCfgDescr = usbDescrParse (bfr, actLength, USB_DESCR_CONFIGURATION)) == NULL) { USB_BULK_ERR ("usbBulkPhysDevCreate: Unable to find configuration "\ "descriptor\n", 0, 0, 0, 0, 0, 0); goto errorExit; } /* Look for the interface representing the MSC/SCSI/BULK_ONLY. */ ifNo = 0; while ((pIfDescr = usbDescrParseSkip (&pBfr, &actLength, USB_DESCR_INTERFACE)) != NULL) { if (ifNo == pBulkDev->interface) break; ifNo++; } if (pIfDescr == NULL) goto errorExit; pBulkDev->altSetting = pIfDescr->alternateSetting; /* * Retrieve the endpoint descriptor(s) following the identified interface * descriptor. */ if ((pOutEp = findEndpoint (pBfr, actLength, USB_ENDPOINT_OUT)) == NULL) goto errorExit; if ((pInEp = findEndpoint (pBfr, actLength, USB_ENDPOINT_IN)) == NULL) goto errorExit; pBulkDev->outEpAddress = pOutEp->endpointAddress; pBulkDev->inEpAddress = pInEp->endpointAddress; /* Set the device configuration corresponding to MSC/SCSI/BULK-ONLY */ if ((usbdConfigurationSet (usbdHandle, pBulkDev->bulkDevId, pBulkDev->configuration, pCfgDescr->maxPower * USB_POWER_MA_PER_UNIT)) != OK ) { USB_BULK_ERR ("usbBulkPhysDevCreate: Unable to set device "\ "configuration \n", 0, 0, 0, 0, 0, 0); goto errorExit; } else { USB_BULK_DEBUG ("usbBulkPhysDevCreate: Configuration set to 0x%x \n", pBulkDev->configuration, 0, 0, 0, 0, 0); } /* Select interface * * NOTE: Some devices may reject this command, and this does not represent * a fatal error. Therefore, we ignore the return status. */ usbdInterfaceSet (usbdHandle, pBulkDev->bulkDevId, pBulkDev->interface, pBulkDev->altSetting); maxPacketSize = *((pUINT8) &pOutEp->maxPacketSize) | (*(((pUINT8) &pOutEp->maxPacketSize) + 1) << 8); /* Create a Bulk-out pipe for the MSC/SCSI/BULK-ONLY device */ if (usbdPipeCreate (usbdHandle, pBulkDev->bulkDevId, pOutEp->endpointAddress, pBulkDev->configuration, pBulkDev->interface, USB_XFRTYPE_BULK, USB_DIR_OUT, maxPacketSize, 0, 0, &(pBulkDev->outPipeHandle)) != OK) { USB_BULK_ERR ("usbBulkPhysDevCreate: Error creating bulk out pipe\n", 0, 0, 0, 0, 0, 0); goto errorExit; } maxPacketSize = *((pUINT8) &pInEp->maxPacketSize) | (*(((pUINT8) &pInEp->maxPacketSize) + 1) << 8); /* Create a Bulk-in pipe for the MSC/SCSI/BULK-ONLY device */ if (usbdPipeCreate (usbdHandle, pBulkDev->bulkDevId, pInEp->endpointAddress, pBulkDev->configuration, pBulkDev->interface, USB_XFRTYPE_BULK, USB_DIR_IN, maxPacketSize, 0, 0, &(pBulkDev->inPipeHandle)) != OK) { USB_BULK_ERR ("usbBulkPhysDevCreate: Error creating bulk in pipe\n", 0, 0, 0, 0, 0, 0); goto errorExit; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -