📄 usbbulkdevlib.c
字号:
* For WRITE6 command, cmdParam1 refers to the block number from
* which cmdParam2 number of blocks are to be written. Calculate
* the transfer length based on the block size and num. of blocks
*/
pBulkDev->bulkCbw.dataXferLength = USB_BULK_SWAP_32(((cmdParam2) *
(pBulkDev->blkDev.bd_bytesPerBlk)));
pBulkDev->bulkCbw.direction = USB_CBW_DIR_OUT;
pBulkDev->bulkCbw.length = 0x06;
pBulkDev->bulkCbw.CBD[0] = USB_SCSI_WRITE6;
pBulkDev->bulkCbw.CBD[1] = 0x0;
pBulkDev->bulkCbw.CBD[2] = (UINT8)((cmdParam1 & 0xFF00) >>8) ;
pBulkDev->bulkCbw.CBD[3] = (UINT8)(cmdParam1 & 0xFF);
pBulkDev->bulkCbw.CBD[4] = (UINT8)cmdParam2;
pBulkDev->bulkCbw.CBD[5] = 0x0;
break;
case USB_SCSI_READ10: /* 10-byte SCSI READ command */
cmdParam1 += pBulkDev->blkOffset;
/*
* For READ10 command, cmdParam1 refers to the block number from
* which cmdParam2 number of blocks are to be read. Calculate
* the transfer length based on the block size and num. of blocks
*/
pBulkDev->bulkCbw.dataXferLength = USB_BULK_SWAP_32(((cmdParam2) *
(pBulkDev->blkDev.bd_bytesPerBlk)));
pBulkDev->bulkCbw.direction = USB_CBW_DIR_IN;
pBulkDev->bulkCbw.length = 0x0A;
pBulkDev->bulkCbw.CBD[0] = 0x28; /* op code */
pBulkDev->bulkCbw.CBD[1] = 0x0; /* DPU, FOA, and RELADR bits*/
#if 0
pBulkDev->bulkCbw.CBD[2] = 0x0; /* lba is bytes 2-5 MSB */
pBulkDev->bulkCbw.CBD[3] = 0x0; /* lba is bytes 2-5 */
#else
pBulkDev->bulkCbw.CBD[2] = (UINT8)((cmdParam1 & 0xFF000000) >>24); /* lba is bytes 2-5 MSB */
pBulkDev->bulkCbw.CBD[3] = (UINT8)((cmdParam1 & 0xFF0000) >>16); /* lba is bytes 2-5 */
#endif
pBulkDev->bulkCbw.CBD[4] = (UINT8)((cmdParam1 & 0xFF00) >>8); /* lba is bytes 2-5 */
pBulkDev->bulkCbw.CBD[5] = (UINT8)(cmdParam1 & 0xFF); /* lba is bytes 2-5 LSB*/
pBulkDev->bulkCbw.CBD[6] = 0x0; /* Reserved */
pBulkDev->bulkCbw.CBD[7] = (UINT8)((cmdParam2 & 0xFF00) >>8); /* transfer length MSB */
pBulkDev->bulkCbw.CBD[8] = (UINT8)(cmdParam2 & 0xFF); /* transfer length LSB */
pBulkDev->bulkCbw.CBD[9] = 0x0; /* Control */
break;
case USB_SCSI_READ6: /* 6-byte SCSI READ command */
cmdParam1 += pBulkDev->blkOffset;
/*
* For READ6 command, cmdParam1 refers to the block number from
* which cmdParam2 number of blocks are to be read. Calculate
* the transfer length based on the block size and num. of blocks
*/
pBulkDev->bulkCbw.dataXferLength = USB_BULK_SWAP_32(((cmdParam2) *
(pBulkDev->blkDev.bd_bytesPerBlk)));
pBulkDev->bulkCbw.direction = USB_CBW_DIR_IN;
pBulkDev->bulkCbw.length = 0x06;
pBulkDev->bulkCbw.CBD[0] = USB_SCSI_READ6;
pBulkDev->bulkCbw.CBD[1] = 0x0;
pBulkDev->bulkCbw.CBD[2] = (UINT8)((cmdParam1 & 0xFF00) >>8) ;
pBulkDev->bulkCbw.CBD[3] = (UINT8)(cmdParam1 & 0xFF);
pBulkDev->bulkCbw.CBD[4] = (UINT8)cmdParam2;
pBulkDev->bulkCbw.CBD[5] = 0x0;
break;
case USB_SCSI_INQUIRY: /* Standard 36-byte INQUIRY command */
pBulkDev->bulkCbw.dataXferLength = USB_BULK_SWAP_32 (USB_SCSI_STD_INQUIRY_LEN);
pBulkDev->bulkCbw.direction = USB_CBW_DIR_IN;
pBulkDev->bulkCbw.length = 0x06;
pBulkDev->bulkCbw.CBD[0] = USB_SCSI_INQUIRY;
pBulkDev->bulkCbw.CBD[1] = 0x0;
pBulkDev->bulkCbw.CBD[2] = 0x0;
pBulkDev->bulkCbw.CBD[3] = 0x0;
pBulkDev->bulkCbw.CBD[4] = USB_SCSI_STD_INQUIRY_LEN;
pBulkDev->bulkCbw.CBD[5] = 0x0;
break;
case USB_SCSI_START_STOP_UNIT: /* for Eject/start media command */
/* Eject applicable only for removable media */
if ((cmdParam1 == USB_SCSI_START_STOP_LOEJ) &
(pBulkDev->blkDev.bd_removable != TRUE))
{
status = ERROR;
break;
}
pBulkDev->bulkCbw.dataXferLength = 0;
pBulkDev->bulkCbw.direction = USB_CBW_DIR_NONE;
pBulkDev->bulkCbw.length = 0x06;
pBulkDev->bulkCbw.CBD[0] = USB_SCSI_START_STOP_UNIT;
pBulkDev->bulkCbw.CBD[1] = 0x0;
pBulkDev->bulkCbw.CBD[2] = 0x0;
pBulkDev->bulkCbw.CBD[3] = 0x0;
pBulkDev->bulkCbw.CBD[4] = (UINT8)cmdParam1;
pBulkDev->bulkCbw.CBD[5] = 0x0;
break;
case USB_SCSI_TEST_UNIT_READY: /* Test unit ready command */
pBulkDev->bulkCbw.dataXferLength = 0;
pBulkDev->bulkCbw.direction = USB_CBW_DIR_NONE;
pBulkDev->bulkCbw.length = 0x06;
pBulkDev->bulkCbw.CBD[0] = USB_SCSI_TEST_UNIT_READY;
pBulkDev->bulkCbw.CBD[1] = 0x0;
pBulkDev->bulkCbw.CBD[2] = 0x0;
pBulkDev->bulkCbw.CBD[3] = 0x0;
pBulkDev->bulkCbw.CBD[4] = 0x0;
pBulkDev->bulkCbw.CBD[5] = 0x0;
break;
case USB_SCSI_REQ_SENSE: /* Request sense command */
pBulkDev->bulkCbw.dataXferLength =
USB_BULK_SWAP_32(USB_SCSI_REQ_SENSE_LEN);
pBulkDev->bulkCbw.direction = USB_CBW_DIR_IN;
pBulkDev->bulkCbw.length = 0x06;
pBulkDev->bulkCbw.CBD[0] = USB_SCSI_REQ_SENSE;
pBulkDev->bulkCbw.CBD[1] = 0x0;
pBulkDev->bulkCbw.CBD[2] = 0x0;
pBulkDev->bulkCbw.CBD[3] = 0x0;
pBulkDev->bulkCbw.CBD[4] = USB_SCSI_REQ_SENSE_LEN;
pBulkDev->bulkCbw.CBD[5] = 0x0;
break;
case USB_SCSI_FORMAT_UNIT: /* Format Unit command */
/* issue a FORMAT UNIT command with default parameters */
pBulkDev->bulkCbw.dataXferLength = 0;
pBulkDev->bulkCbw.direction = USB_CBW_DIR_NONE;
pBulkDev->bulkCbw.length = 0x06;
pBulkDev->bulkCbw.CBD[0] = USB_SCSI_FORMAT_UNIT;
pBulkDev->bulkCbw.CBD[1] = 0x0;
pBulkDev->bulkCbw.CBD[2] = 0x0;
pBulkDev->bulkCbw.CBD[3] = 0x0;
pBulkDev->bulkCbw.CBD[4] = 0x0;
pBulkDev->bulkCbw.CBD[5] = 0x0;
break;
case USB_SCSI_READ_CAPACITY: /* Read capacity command */
/*
* Provides a means to request information regarding the capacity
* of the logical unit. The response will consists of number of
* logical blocks present and the size of the block.
*/
pBulkDev->bulkCbw.dataXferLength =
USB_BULK_SWAP_32(USB_SCSI_READ_CAP_LEN);
pBulkDev->bulkCbw.direction = USB_CBW_DIR_IN;
pBulkDev->bulkCbw.length = 0x0A;
pBulkDev->bulkCbw.CBD[0] = USB_SCSI_READ_CAPACITY;
pBulkDev->bulkCbw.CBD[1] = 0x0;
pBulkDev->bulkCbw.CBD[2] = 0x0;
pBulkDev->bulkCbw.CBD[3] = 0x0;
pBulkDev->bulkCbw.CBD[4] = 0x0;
pBulkDev->bulkCbw.CBD[5] = 0x0;
pBulkDev->bulkCbw.CBD[6] = 0x0;
pBulkDev->bulkCbw.CBD[7] = 0x0;
pBulkDev->bulkCbw.CBD[8] = 0x0;
pBulkDev->bulkCbw.CBD[9] = 0x0;
break;
case USB_SCSI_PREVENT_REMOVAL: /* Prevent media removal command */
/* Applicable only for removable media. Disables removal of media */
if (pBulkDev->blkDev.bd_removable != TRUE)
{
status = ERROR;
break;
}
pBulkDev->bulkCbw.dataXferLength = 0;
pBulkDev->bulkCbw.direction = USB_CBW_DIR_NONE;
pBulkDev->bulkCbw.length = 0x06;
pBulkDev->bulkCbw.CBD[0] = USB_SCSI_PREVENT_REMOVAL;
pBulkDev->bulkCbw.CBD[1] = 0x0;
pBulkDev->bulkCbw.CBD[2] = 0x0;
pBulkDev->bulkCbw.CBD[3] = 0x0;
pBulkDev->bulkCbw.CBD[4] = 0x0;
pBulkDev->bulkCbw.CBD[5] = 0x0;
break;
default:
status= ERROR;
}
return (status);
}
/***************************************************************************
*
* usbBulkCmdExecute - Executes a previously formed command block.
*
* This routine transports the CBW across the BULK_OUT endpoint followed by
* a data transfer phase(if required) to/from the device depending on the
* direction bit. After data transfer, CSW is received from the device.
*
* All transactions to the device are done by forming IRP's initilized with
* command dependent values.
*
* RETURNS: OK on success, or ERROR if failed to execute
*/
LOCAL USB_COMMAND_STATUS usbBulkCmdExecute
(
pUSB_BULK_DEV pBulkDev /* pointer to bulk device */
)
{
pUSB_BULK_CSW pCsw ;
if ( pBulkDev->connected == FALSE )
return (USB_INTERNAL_ERROR);
if ( OSS_SEM_TAKE (bulkIrpSem, usbBulkIrpTimeOut + 1000) == ERROR )
{
USB_BULK_DEBUG ("usbBulkCmdExecute: Irp in Use \n", 0, 0, 0, 0, 0, 0);
return (USB_INTERNAL_ERROR);
}
/* Form an IRP to submit the command block on BULK OUT pipe */
memset (&(pBulkDev->outIrp), 0, sizeof (USB_IRP));
pBulkDev->outIrp.irpLen = sizeof (USB_IRP);
pBulkDev->outIrp.userCallback = usbBulkIrpCallback;
pBulkDev->outIrp.timeout = usbBulkIrpTimeOut;
pBulkDev->outIrp.transferLen = USB_CBW_LENGTH;
pBulkDev->outIrp.bfrCount = 0x01;
pBulkDev->outIrp.bfrList[0].pid = USB_PID_OUT;
pBulkDev->outIrp.bfrList[0].pBfr = (UINT8 *)&(pBulkDev->bulkCbw);
pBulkDev->outIrp.bfrList[0].bfrLen = USB_CBW_LENGTH;
pBulkDev->outIrp.userPtr = pBulkDev;
/* Submit IRP */
if (usbdTransfer (usbdHandle,
pBulkDev->outPipeHandle,
&(pBulkDev->outIrp))
!= OK)
{
USB_BULK_ERR ("usbBulkCmdExecute: Unable to submit CBW IRP for transfer\n",
0, 0, 0, 0, 0, 0);
return (USB_INTERNAL_ERROR);
}
/* Wait till the transfer of IRP completes or time out */
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);
}
if (pBulkDev->outIrp.result == S_usbHcdLib_STALLED)
{
usbBulkDevResetRecovery (pBulkDev);
OSS_SEM_GIVE (bulkIrpSem);
return (USB_BULK_IO_ERROR);
}
/*
* 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 */
memset (&(pBulkDev->inIrp), 0, sizeof (USB_IRP));
/* form an IRP to read from BULK_IN pipe */
pBulkDev->inIrp.irpLen = sizeof(USB_IRP);
pBulkDev->inIrp.userCallback = usbBulkIrpCallback;
pBulkDev->inIrp.timeout = usbBulkIrpTimeOut;
pBulkDev->inIrp.transferLen = USB_BULK_SWAP_32(
pBulkDev->bulkCbw.dataXferLength);
pBulkDev->inIrp.bfrCount = 0x01;
pBulkDev->inIrp.bfrList[0].pid = USB_PID_IN;
pBulkDev->inIrp.bfrList[0].pBfr = pBulkDev->bulkInData;
pBulkDev->inIrp.bfrList[0].bfrLen = USB_BULK_SWAP_32(
pBulkDev->bulkCbw.dataXferLength);
pBulkDev->inIrp.userPtr = pBulkDev;
/* 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 (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 (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);
}
}
else
{
/* device is expecting data over BULK_OUT pipe. send it */
memset (&pBulkDev->outIrp, 0, sizeof (USB_IRP));
/* form an IRP to write to BULK_OUT pipe */
pBulkDev->outIrp.irpLen = sizeof(USB_IRP);
pBulkDev->outIrp.userCallback = usbBulkIrpCallback;
pBulkDev->outIrp.timeout = usbBulkIrpTimeOut;
pBulkDev->outIrp.transferLen = USB_BULK_SWAP_32(
pBulkDev->bulkCbw.dataXferLength);
pBulkDev->outIrp.bfrCount = 0x01;
pBulkDev->outIrp.bfrList[0].pid = USB_PID_OUT;
pBulkDev->outIrp.bfrList[0].pBfr = pBulkDev->bulkOutData;
pBulkDev->outIrp.bfrList[0].bfrLen = USB_BULK_SWAP_32(
pBulkDev->bulkCbw.dataXferLength);
pBulkDev->outIrp.userPtr = pBulkDev;
/* 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -