📄 usbbulkdevlib.c
字号:
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** ERRNO: none**\NOMANUAL*/LOCAL STATUS usbBulkPhysDevCreate ( USBD_NODE_ID nodeId, /* USBD Node Id ofthe device */ UINT16 configuration, /* Configuration value */ UINT16 interface /* Interface Number */ ) { UINT16 actLength; UINT8 * pBfr; /* pointer to descriptor store */ UINT8 * pScratchBfr; /* another pointer to the above store */ UINT ifNo; UINT16 maxPacketSize; USB_BULK_DEV * pBulkDev; USB_CONFIG_DESCR * pCfgDescr; USB_INTERFACE_DESCR * pIfDescr; USB_ENDPOINT_DESCR * pOutEp; USB_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 a non-cacheable buffer for the descriptor's */ if ((pBfr = OSS_MALLOC (USB_MAX_DESCR_LEN)) == NULL) { USB_BULK_ERR ("usbBulkPhysDevCreate: Unable to allocate memory:pBfr\n", 0, 0, 0, 0, 0, 0); return ERROR; } /* 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:pBulkDev\n", 0, 0, 0, 0, 0, 0); goto errorExit; } pBulkDev->bulkDevId = nodeId; pBulkDev->configuration = configuration; pBulkDev->interface = interface; pBulkDev->connected = TRUE; pBulkDev->bulkCbw.signature = USB_BULK_SWAP_32 (USB_CBW_SIGNATURE); pBulkDev->bulkCbw.tag = USB_BULK_SWAP_32 (USB_CBW_TAG); /* Initialization for pBulkDev->outIrp */ pBulkDev->outIrp.irpLen = sizeof (USB_IRP); pBulkDev->outIrp.userCallback = usbBulkIrpCallback; pBulkDev->outIrp.timeout = usbBulkIrpTimeOut; pBulkDev->outIrp.bfrCount = 0x01; pBulkDev->outIrp.bfrList[0].pid = USB_PID_OUT; pBulkDev->outIrp.userPtr = pBulkDev; /* Initialization for p->BulkDev->inIrp */ pBulkDev->inIrp.irpLen = sizeof(USB_IRP); pBulkDev->inIrp.userCallback = usbBulkIrpCallback; pBulkDev->inIrp.timeout = usbBulkIrpTimeOut; pBulkDev->inIrp.bfrCount = 0x01; pBulkDev->inIrp.bfrList[0].pid = USB_PID_IN; pBulkDev->inIrp.userPtr = pBulkDev; /* Initialization for pBulkDev->statusIrp */ pBulkDev->statusIrp.irpLen = sizeof( USB_IRP ); pBulkDev->statusIrp.userCallback = usbBulkIrpCallback; pBulkDev->statusIrp.timeout = usbBulkIrpTimeOut; pBulkDev->statusIrp.transferLen = USB_CSW_LENGTH; pBulkDev->statusIrp.bfrCount = 0x01; pBulkDev->statusIrp.bfrList[0].pid = USB_PID_IN; pBulkDev->statusIrp.bfrList[0].pBfr = (UINT8 *)(&pBulkDev->bulkCsw); pBulkDev->statusIrp.bfrList[0].bfrLen = USB_CSW_LENGTH; pBulkDev->statusIrp.userPtr = pBulkDev; if (OSS_SEM_CREATE( 1, 1, &pBulkDev->bulkIrpSem) != OK) { return(usbBulkDevShutDown(S_usbBulkDevLib_OUT_OF_RESOURCES)); } if (OSS_MUTEX_CREATE(&pBulkDev->bulkDevMutex)!= OK) { return(usbBulkDevShutDown(S_usbBulkDevLib_OUT_OF_RESOURCES)); } /* 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, 0, USB_MAX_DESCR_LEN, pBfr, &actLength) != OK) { USB_BULK_ERR ("usbBulkPhysDevCreate: Unable to read configuration "\ "descriptor\n", 0, 0, 0, 0, 0, 0); goto errorExit; } if ((pCfgDescr = usbDescrParse (pBfr, actLength, USB_DESCR_CONFIGURATION)) == NULL) { USB_BULK_ERR ("usbBulkPhysDevCreate: Unable to find configuration "\ "descriptor\n", 0, 0, 0, 0, 0, 0); goto errorExit; } pBulkDev->configuration = pCfgDescr->configurationValue; /* Look for the interface representing the MSC/SCSI/BULK_ONLY. */ ifNo = 0; /* * usbDescrParseSkip() modifies the value of the pointer it recieves * so we pass it a copy of our buffer pointer */ pScratchBfr = pBfr; while ((pIfDescr = usbDescrParseSkip (&pScratchBfr, &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 (pScratchBfr, actLength, USB_ENDPOINT_OUT)) == NULL) goto errorExit; if ((pInEp = findEndpoint (pScratchBfr, 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; } /* Clear HALT feauture on the endpoints */ if ((usbdFeatureClear (usbdHandle, pBulkDev->bulkDevId, USB_RT_ENDPOINT, USB_FSEL_DEV_ENDPOINT_HALT, (pOutEp->endpointAddress & 0xFF))) != OK) { USB_BULK_ERR ("usbBulkPhysDevCreate: Failed to clear HALT feauture "\ "on bulk out Endpoint %x\n", 0, 0, 0, 0, 0, 0); } if ((usbdFeatureClear (usbdHandle, pBulkDev->bulkDevId, USB_RT_ENDPOINT, USB_FSEL_DEV_ENDPOINT_HALT, (pOutEp->endpointAddress & 0xFF))) != OK) { USB_BULK_ERR ("usbBulkPhysDevCreate: Failed to clear HALT feauture "\ "on bulk in Endpoint %x\n", 0, 0, 0, 0, 0, 0); } /* May not be supported by devices having single LUN */ if (usbdVendorSpecific (usbdHandle, pBulkDev->bulkDevId, USB_RT_DEV_TO_HOST | USB_RT_CLASS | USB_RT_INTERFACE, USB_BULK_GET_MAX_LUN, 0, pBulkDev->interface, 1, &(pBulkDev->maxLun), &actLength) != OK ) { USB_BULK_ERR ("usbBulkPhysDevCreate: Failed to acquire max lun \n", 0, 0, 0, 0, 0, 0); pBulkDev->maxLun = 0; } else { USB_BULK_DEBUG ("usbBulkPhysDevCreate: Max Lun = %d \n", pBulkDev->maxLun, 0, 0, 0, 0, 0); } /* Link the newly created structure. */ OSS_MUTEX_TAKE( bulkMutex, OSS_BLOCK ); usbListLink (&bulkDevList, pBulkDev, &pBulkDev->bulkDevLink, LINK_TAIL); OSS_MUTEX_RELEASE(bulkMutex); OSS_FREE (pBfr); return (OK);errorExit: /* Error in creating a bulk device ..destroy */ OSS_FREE (pBfr); usbBulkDevDestroy (pBulkDev); return (ERROR); }/***************************************************************************** usbBulkBlkDevCreate - create a block device** This routine initializes a BLK_DEV structure, which describes a * logical partition on a USB_BULK_DEV device. A logical partition is an array * of contiguously addressed blocks; it can be completely described by the number* of blocks and the address of the first block in the partition. ** NOTE:* If `numBlocks' is 0, the rest of device is used.* * This routine supplies an additional parameter called <flags>. This bitfield * currently only uses bit 1. This bit determines whether the driver will use a* SCSI READ6 or SCSI READ10 for read access.** RETURNS: A pointer to the BLK_DEV, or NULL if parameters exceed* physical device boundaries, or if no bulk device exists.** ERRNO: none*/BLK_DEV * usbBulkBlkDevCreate ( USBD_NODE_ID nodeId, /* nodeId of the bulk-only device */ UINT8 lun, /* Logical Unit Number */ UINT32 numBlks, /* number of logical blocks on device */ UINT32 blkOffset, /* offset of the starting block */ UINT32 flags /* optional flags */ ) { UINT32 driveNumBlocks; UINT32 bytesPerBlock =2; USB_COMMAND_STATUS ready; int retry=0; STATUS status; /* get a pointer to the bulk device */ pUSB_BULK_DEV_LUN pBulkDevLun; BLK_DEV *pBlkDev; pUSB_BULK_DEV pBulkDev = usbBulkDevFind (nodeId); if (pBulkDev == NULL) return NULL; USB_BULK_DEBUG ("usbBulkBlkDevCreate: Entered\n", 0, 0, 0, 0, 0, 0); OSS_MUTEX_TAKE (pBulkDev->bulkDevMutex, OSS_BLOCK); /* Create pointer shortcuts */ pBulkDevLun = (pUSB_BULK_DEV_LUN)&pBulkDev->blkDevLun[lun]; pBlkDev = (BLK_DEV *)&pBulkDevLun->blkDev; /* * Initialize the standard block device structure for use with file * systems. */ pBlkDev->bd_blkRd = (FUNCPTR) usbBulkDevBlkRd; pBlkDev->bd_blkWrt = (FUNCPTR) u
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -