📄 usbbulkdevlib.c
字号:
&(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 & 0x0F))) != 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 & 0x0F))) != OK) { USB_BULK_ERR ("usbBulkPhysDevCreate: Failed to clear HALT feauture "\ "on bulk in Endpoint %x\n", 0, 0, 0, 0, 0, 0); } /* Link the newly created structure. */ usbListLink (&bulkDevList, pBulkDev, &pBulkDev->bulkDevLink, LINK_TAIL); 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.*/BLK_DEV * usbBulkBlkDevCreate ( USBD_NODE_ID nodeId, /* nodeId of the bulk-only device */ UINT32 numBlks, /* number of logical blocks on device */ UINT32 blkOffset, /* offset of the starting block */ UINT32 flags /* optional flags */ ) { UINT8 * pInquiry; /* store for INQUIRY data */ pUSB_BULK_DEV pBulkDev = usbBulkDevFind (nodeId); OSS_MUTEX_TAKE (bulkDevMutex, OSS_BLOCK); if ((pInquiry = OSS_MALLOC (USB_SCSI_STD_INQUIRY_LEN)) == NULL) { USB_BULK_ERR ("usbBulkBlkDevCreate: Error allocating memory\n", 0, 0, 0, 0, 0, 0); OSS_MUTEX_RELEASE (bulkDevMutex); return (NULL); } if (pBulkDev == NULL) { USB_BULK_ERR ("usbBulkBlkDevCreate: No MSC/SCSI/BULK-ONLY found\n", 0, 0, 0, 0, 0, 0); OSS_FREE (pInquiry); OSS_MUTEX_RELEASE (bulkDevMutex); return (NULL); } /* * Initialize the standard block device structure for use with file * systems. */ pBulkDev->blkDev.bd_blkRd = (FUNCPTR) usbBulkDevBlkRd; pBulkDev->blkDev.bd_blkWrt = (FUNCPTR) usbBulkDevBlkWrt; pBulkDev->blkDev.bd_ioctl = (FUNCPTR) usbBulkDevIoctl; pBulkDev->blkDev.bd_reset = (FUNCPTR) usbBulkDevReset; pBulkDev->blkDev.bd_statusChk = (FUNCPTR) usbBulkDevStatusChk; pBulkDev->blkDev.bd_retry = 1; pBulkDev->blkDev.bd_mode = O_RDWR; pBulkDev->blkDev.bd_readyChanged = TRUE; /* * Read out the standard INQUIRY information from the device, mainly to * check whether the media is removable or not. */ pBulkDev->bulkInData = pInquiry; if ( usbBulkFormScsiCmd (pBulkDev, USB_SCSI_INQUIRY, 0, 0) != OK ) { USB_BULK_ERR ("usbBulkBlkDevCreate: Error forming command\n", 0, 0, 0, 0, 0, 0); OSS_FREE (pInquiry); OSS_MUTEX_RELEASE (bulkDevMutex); return (NULL); } if ( usbBulkCmdExecute (pBulkDev) != USB_COMMAND_SUCCESS ) { USB_BULK_ERR ("usbBulkBlkDevCreate: Error executing USB_SCSI_INQUIRY "\ "command\n", 0, 0, 0, 0, 0, 0); OSS_FREE (pInquiry); OSS_MUTEX_RELEASE (bulkDevMutex); return (NULL); } /* Check the media type bit */ if (*(pInquiry+1) & USB_SCSI_INQUIRY_RMB_BIT) { pBulkDev->blkDev.bd_removable = TRUE; } else { pBulkDev->blkDev.bd_removable = FALSE; } /* read the block size and capacity of device (in terms of blocks) */ if ( usbBulkFormScsiCmd (pBulkDev, USB_SCSI_READ_CAPACITY, 0, 0) != OK ) { OSS_FREE (pInquiry); OSS_MUTEX_RELEASE (bulkDevMutex); return (NULL); } /* * Read Capacity command will usually return CHECK CONDITION status * very first time, just try again. */ if ( usbBulkCmdExecute (pBulkDev) != USB_COMMAND_SUCCESS ) { if ( usbBulkCmdExecute (pBulkDev) != USB_COMMAND_SUCCESS ) { USB_BULK_ERR ("usbBulkBlkDevCreate: Read Capacity command failed\n", 0, 0, 0, 0, 0, 0); OSS_FREE (pInquiry); OSS_MUTEX_RELEASE (bulkDevMutex); return (NULL); } } /* * Response is in BIG endian format. Swap it to get correct value. * Also, READ_CAPACITY returns the address of the last logical block, * NOT the number of blocks. Since the blkDev structure wants the * number of blocks, we add 1 (numBlocks = last address + 1). */ pBulkDev->numBlks = USB_SCSI_SWAP_32(*((UINT32 *) pInquiry)) + 1; pBulkDev->blkOffset = blkOffset; if ( numBlks == 0 ) pBulkDev->blkDev.bd_nBlocks = (pBulkDev->numBlks - blkOffset); else pBulkDev->blkDev.bd_nBlocks = numBlks; pBulkDev->blkDev.bd_bytesPerBlk = \ USB_SCSI_SWAP_32(*((UINT32 *)(pInquiry+4))); /* determine which type of SCSI read command is implemnted */ if ( (flags & USB_SCSI_FLAG_READ_WRITE10) == 1 ) pBulkDev->read10Able = TRUE; else pBulkDev->read10Able = FALSE; OSS_FREE (pInquiry); OSS_MUTEX_RELEASE (bulkDevMutex); return (&pBulkDev->blkDev); } /***************************************************************************** usbBulkDevBlkRd - routine to read one or more blocks from the device.** This routine reads the specified physical sector(s) from a specified* physical device. Typically called by file system when data is to be* read from a particular device.** RETURNS: OK on success, or ERROR if failed to read from device*/LOCAL STATUS usbBulkDevBlkRd ( BLK_DEV * pBlkDev, /* pointer to bulk device */ int blkNum, /* logical block number */ int numBlks, /* number of blocks to read */ char * pBuf /* store for data */ ) { pUSB_BULK_DEV pBulkDev = (USB_BULK_DEV *)pBlkDev; UINT readType; /* Ensure that the device has not been removed during a transfer */ if ( pBulkDev->connected == FALSE ) return ERROR; USB_BULK_DEBUG ("usbBulkDevBlkRd: Number of blocks = %d, Starting blk = %d\n", numBlks, blkNum, 0, 0, 0, 0); OSS_MUTEX_TAKE (bulkDevMutex, OSS_BLOCK); /* intialise the pointer to store bulk in data */ pBulkDev->bulkInData = (UINT8 *)pBuf ; if (pBulkDev->read10Able) readType = USB_SCSI_READ10; else readType = USB_SCSI_READ6; if ( usbBulkFormScsiCmd (pBulkDev, readType, blkNum, numBlks) != OK ) { OSS_MUTEX_RELEASE (bulkDevMutex); return (ERROR); } if ( usbBulkCmdExecute (pBulkDev) != USB_COMMAND_SUCCESS ) { OSS_MUTEX_RELEASE (bulkDevMutex); return (ERROR); } OSS_MUTEX_RELEASE (bulkDevMutex); return (OK); }/***************************************************************************** usbBulkDevBlkWrt - routine to write one or more blocks to the device.** This routine writes the specified physical sector(s) to a specified physical* device.** RETURNS: OK on success, or ERROR if failed to write to device*/LOCAL STATUS usbBulkDevBlkWrt ( BLK_DEV * pBlkDev, /* pointer to bulk device */ int blkNum, /* logical block number */ int numBlks, /* number of blocks to write */ char * pBuf /* data to be written */ ) { pUSB_BULK_DEV pBulkDev = (USB_BULK_DEV *)pBlkDev; UINT writeType; /* Ensure that the device has not been removed during a transfer */ if ( pBulkDev->connected == FALSE ) return ERROR; USB_BULK_DEBUG ("usbBulkDevBlkWrt: Number of blocks = %d, Starting blk = %d\n", numBlks, blkNum, 0, 0, 0, 0); OSS_MUTEX_TAKE (bulkDevMutex, OSS_BLOCK); /* initialise the pointer to fetch bulk out data */ pBulkDev->bulkOutData = (UINT8 *)pBuf; if (pBulkDev->read10Able) writeType = USB_SCSI_WRITE10; else writeType = USB_SCSI_WRITE6; if ( usbBulkFormScsiCmd (pBulkDev, writeType, blkNum, numBlks) != OK ) { OSS_MUTEX_RELEASE (bulkDevMutex); return (ERROR); } if ( usbBulkCmdExecute (pBulkDev) != USB_COMMAND_SUCCESS ) { OSS_MUTEX_RELEASE (bulkDevMutex); return (ERROR); } OSS_MUTEX_RELEASE (bulkDevMutex); return (OK); }/***************************************************************************** usbBulkIrpCallback - Invoked upon IRP completion** Examines the status of the IRP submitted. * ** RETURNS: N/A*/LOCAL void usbBulkIrpCallback ( pVOID p /* pointer to the IRP submitted */ ) { pUSB_IRP pIrp = (pUSB_IRP) p; pUSB_BULK_DEV pBulkDev = pIrp->userPtr; /* check whether the IRP was for bulk out/ bulk in / status transport */ if (pIrp == &(pBulkDev->outIrp)) { if (pIrp->result == OK) /* check the result of IRP */ { USB_BULK_DEBUG ("usbBulkIrpCallback: Num of Bytes transferred on "\ "out pipe %d\n", pIrp->bfrList[0].actLen, 0, 0, 0, 0, 0); } else { USB_BULK_ERR ("usbBulkIrpCallback: Irp failed on Bulk Out %x \n", pIrp->result, 0, 0, 0, 0, 0); /* Clear HALT Feature on Bulk out Endpoint */ if ((usbdFeatureClear (usbdHandle, pBulkDev->bulkDevId, USB_RT_ENDPOINT, USB_FSEL_DEV_ENDPOINT_HALT, (pBulkDev->outEpAddress & 0x0F))) != OK) { USB_BULK_ERR ("usbBulkIrpCallback: Failed to clear HALT "\ "feauture on bulk out Endpoint %x\
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -