📄 usbcbiufidevlib.c
字号:
pCbiUfiDev->ufiCmdBlk.dataXferLen = 0x0; pCbiUfiDev->ufiCmdBlk.direction = 0; pCbiUfiDev->ufiCmdBlk.cmd[0] = USB_UFI_START_STOP_UNIT; pCbiUfiDev->ufiCmdBlk.cmd[1] = 0; pCbiUfiDev->ufiCmdBlk.cmd[4] = 0x01; /* Start the media */ break; case USB_UFI_TEST_UNIT_READY: /* UFI Test Unit Ready Command */ /* This command checks if the device is ready or not */ pCbiUfiDev->ufiCmdBlk.dataXferLen = 0x0; pCbiUfiDev->ufiCmdBlk.direction = 0; pCbiUfiDev->ufiCmdBlk.cmd[0] = USB_UFI_TEST_UNIT_READY; pCbiUfiDev->ufiCmdBlk.cmd[1] = 0; break; case USB_UFI_WRITE10: /* UFI 10-byte Write Command */ pCbiUfiDev->ufiCmdBlk.dataXferLen = ((cmdParam2) * (pCbiUfiDev->blkDev.bd_bytesPerBlk)); pCbiUfiDev->ufiCmdBlk.direction = USB_UFI_DIR_OUT; pCbiUfiDev->ufiCmdBlk.cmd[0] = USB_UFI_WRITE10; pCbiUfiDev->ufiCmdBlk.cmd[1] = 0; /* * cmdParam1 for this command will indicate the logical block * address at which the write operation begins. cmdParam2 will * indicate the number of logical blocks to be written. */ pCbiUfiDev->ufiCmdBlk.cmd[2] = (cmdParam1 & 0xFF000000) >> 24; pCbiUfiDev->ufiCmdBlk.cmd[3] = (cmdParam1 & 0x00FF0000) >> 16; pCbiUfiDev->ufiCmdBlk.cmd[4] = (cmdParam1 & 0x0000FF00) >> 8; pCbiUfiDev->ufiCmdBlk.cmd[5] = (cmdParam1 & 0xFF); pCbiUfiDev->ufiCmdBlk.cmd[7] = (cmdParam2 & 0xFF00) >> 8; pCbiUfiDev->ufiCmdBlk.cmd[8] = (cmdParam2 & 0xFF); break; default: return (ERROR); } return (OK); } /***************************************************************************** usbCbiUfiCmdExecute - Executes an UFI command block. ** This routine executes previously formed UFI Command as per the CBI protocol.* First, the command block formed by usbCbiUfiFormCmd() is sent to the device* via the control endpoint. This is done using Accept Device Specific Command* (ADSC) class specific request. If the command block requires any data * transfer to/from the device, then an IRP is submitted to perform the data* tranport via bulk in/out endpoints. Finally, status bytes are read from the* interrupt endpoint.** RETURNS: USB_COMMAND_STATUS, command execution status.*/LOCAL USB_COMMAND_STATUS usbCbiUfiCmdExecute ( pUSB_CBI_UFI_DEV pCbiUfiDev /* pointer to cbi_ufi device */ ) { UINT16 actLen = 0xFFFF; /* Send the UFI Command block along with the ADSC request */ if ((usbdVendorSpecific (usbdHandle, pCbiUfiDev->cbiUfiDevId, USB_RT_HOST_TO_DEV | USB_RT_CLASS | USB_RT_INTERFACE, 0, 0, pCbiUfiDev->interface, USB_UFI_MAX_CMD_LEN, (UINT8 *)&(pCbiUfiDev->ufiCmdBlk.cmd), &actLen )) != OK ) { USB_CBI_UFI_ERR ("usbCbiUfiCmdExecute: Failed to execute ADSC \n", 0, 0, 0, 0, 0, 0); return (USB_COMMAND_FAILED); } if ( pCbiUfiDev->ufiCmdBlk.dataXferLen > 0 ) { if ( OSS_SEM_TAKE (cbiUfiIrpSem, USB_CBI_IRP_TIME_OUT + 1000) == ERROR ) { /* This should never occur unless the stack does'nt call * callback at all */ USB_CBI_UFI_DEBUG ("usbCbiUfiCmdExecute: Irp in Use \n", 0, 0, 0, 0, 0, 0); return (USB_INTERNAL_ERROR); } if (pCbiUfiDev->ufiCmdBlk.direction == USB_UFI_DIR_IN) { /* data is expected from the device. read from BULK_IN pipe */ memset (&(pCbiUfiDev->inIrp), 0, sizeof (USB_IRP)); /* form an IRP to read from BULK_IN pipe */ pCbiUfiDev->inIrp.irpLen = sizeof(USB_IRP); pCbiUfiDev->inIrp.userCallback = usbCbiUfiIrpCallback; pCbiUfiDev->inIrp.timeout = USB_CBI_IRP_TIME_OUT; pCbiUfiDev->inIrp.transferLen = pCbiUfiDev->ufiCmdBlk.dataXferLen; pCbiUfiDev->inIrp.bfrCount = 0x01; pCbiUfiDev->inIrp.bfrList[0].pid = USB_PID_IN; pCbiUfiDev->inIrp.bfrList[0].pBfr = pCbiUfiDev->bulkInData; pCbiUfiDev->inIrp.bfrList[0].bfrLen = pCbiUfiDev->ufiCmdBlk.dataXferLen; pCbiUfiDev->inIrp.userPtr = pCbiUfiDev; /* Submit IRP */ if (usbdTransfer (usbdHandle, pCbiUfiDev->inPipeHandle, &(pCbiUfiDev->inIrp)) != OK) { USB_CBI_UFI_ERR ("usbCbiUfiCmdExecute: Unable to submit IRP for "\ "BULK_IN data transfer\n", 0, 0, 0, 0, 0, 0); return (USB_INTERNAL_ERROR); } /* * wait till the data transfer ends on bulk in pipe before reading * the command status */ if ( OSS_SEM_TAKE (cbiUfiIrpSem, USB_CBI_IRP_TIME_OUT + 1000) == ERROR ) { USB_CBI_UFI_DEBUG ("usbCbiUfiCmdExecute: Irp time out \n", 0, 0, 0, 0, 0, 0); OSS_SEM_GIVE (cbiUfiIrpSem); return (USB_INTERNAL_ERROR); } /* Check whether data transfer was complete or not */ if ( pCbiUfiDev->inIrp.result != OK) { USB_CBI_UFI_DEBUG ("usbCbiUfiCmdExecute: Data transfer failed \n", 0, 0, 0, 0, 0, 0); OSS_SEM_GIVE (cbiUfiIrpSem); return (USB_COMMAND_FAILED); } } else if (pCbiUfiDev->ufiCmdBlk.direction == USB_UFI_DIR_OUT) { /* device is expecting data over BULK_OUT pipe. send it */ memset (&pCbiUfiDev->outIrp, 0, sizeof (USB_IRP)); /* form an IRP to write to BULK_OUT pipe */ pCbiUfiDev->outIrp.irpLen = sizeof(USB_IRP); pCbiUfiDev->outIrp.userCallback = usbCbiUfiIrpCallback; pCbiUfiDev->outIrp.timeout = USB_CBI_IRP_TIME_OUT; pCbiUfiDev->outIrp.transferLen = pCbiUfiDev->ufiCmdBlk.dataXferLen; pCbiUfiDev->outIrp.bfrCount = 0x01; pCbiUfiDev->outIrp.bfrList[0].pid = USB_PID_OUT; pCbiUfiDev->outIrp.bfrList[0].pBfr = pCbiUfiDev->bulkOutData; pCbiUfiDev->outIrp.bfrList[0].bfrLen = pCbiUfiDev->ufiCmdBlk.dataXferLen; pCbiUfiDev->outIrp.userPtr = pCbiUfiDev; /* Submit IRP */ if (usbdTransfer (usbdHandle, pCbiUfiDev->outPipeHandle, &(pCbiUfiDev->outIrp)) != OK) { USB_CBI_UFI_ERR ("usbCbiUfiCmdExecute: Unable to submit IRP for "\ "BULK_OUT data transfer\n", 0, 0, 0, 0, 0, 0); return (USB_INTERNAL_ERROR); } /* * wait till the data transfer ends on bulk out pipe before reading * the command status */ if ( OSS_SEM_TAKE (cbiUfiIrpSem, USB_CBI_IRP_TIME_OUT + 1000) == ERROR ) { USB_CBI_UFI_DEBUG ("usbCbiUfiCmdExecute: Irp time out \n", 0, 0, 0, 0, 0, 0); OSS_SEM_GIVE (cbiUfiIrpSem); return (USB_INTERNAL_ERROR); } /* Check whether data transfer was complete or not */ if (pCbiUfiDev->outIrp.result != OK) { USB_CBI_UFI_DEBUG ("usbCbiUfiCmdExecute: Data transfer failed \n", 0, 0, 0, 0, 0, 0); OSS_SEM_GIVE (cbiUfiIrpSem); return (USB_COMMAND_FAILED); } } OSS_SEM_GIVE (cbiUfiIrpSem); } if ( OSS_SEM_TAKE (cbiUfiIrpSem, USB_CBI_IRP_TIME_OUT + 1000) == ERROR ) { USB_CBI_UFI_DEBUG ("usbCbiUfiCmdExecute: Irp time out \n", 0, 0, 0, 0, 0, 0); OSS_SEM_GIVE (cbiUfiIrpSem); return (USB_INTERNAL_ERROR); } /* Read the status from the interrupt endpoint */ memset (&(pCbiUfiDev->statusIrp), 0, sizeof (USB_IRP)); /* form an IRP to read status from interrupt endpoint */ pCbiUfiDev->statusIrp.irpLen = sizeof(USB_IRP); pCbiUfiDev->statusIrp.userCallback = usbCbiUfiIrpCallback; pCbiUfiDev->statusIrp.timeout = USB_TIMEOUT_NONE; pCbiUfiDev->statusIrp.transferLen = 0x02; pCbiUfiDev->statusIrp.bfrCount = 0x01; pCbiUfiDev->statusIrp.bfrList[0].pid = USB_PID_IN; pCbiUfiDev->statusIrp.bfrList[0].pBfr = pCbiUfiDev->intrStatus; pCbiUfiDev->statusIrp.bfrList[0].bfrLen = 0x02; pCbiUfiDev->statusIrp.userPtr = pCbiUfiDev; /* Submit IRP */ if (usbdTransfer (usbdHandle, pCbiUfiDev->intrPipeHandle, &(pCbiUfiDev->statusIrp)) != OK) { USB_CBI_UFI_ERR ("usbCbiUfiCmdExecute: Unable to submit IRP for "\ "Interrupt status\n", 0, 0, 0, 0, 0, 0); return (USB_INTERNAL_ERROR); } /* wait till the status bytes are read */ if ( OSS_SEM_TAKE (cbiUfiIrpSem, USB_CBI_IRP_TIME_OUT + 1000) == ERROR ) { USB_CBI_UFI_DEBUG ("usbCbiUfiCmdExecute: Irp time out \n", 0, 0, 0, 0, 0, 0); OSS_SEM_GIVE (cbiUfiIrpSem); return (USB_INTERNAL_ERROR); } OSS_SEM_GIVE (cbiUfiIrpSem); /* check for the status bytes read..stalled condition */ if (pCbiUfiDev->statusIrp.result != OK) { return (USB_BULK_IO_ERROR); } else { return (USB_COMMAND_SUCCESS); } } /***************************************************************************** usbCbiUfiReqSense - Executes an Request Sense command block. ** Forms and executes Request Sense command on the specified device.** RETURNS: N/A*/LOCAL VOID usbCbiUfiReqSense ( pUSB_CBI_UFI_DEV pCbiUfiDev /* pointer to cbi_ufi device */ ) { UINT8 reqSense [UFI_STD_REQ_SENSE_LEN]; UINT16 status = 0xFFFF; pCbiUfiDev->bulkInData = reqSense; if ( usbCbiUfiFormCmd (pCbiUfiDev, USB_UFI_REQUEST_SENSE, NULL, NULL) != OK ) { USB_CBI_UFI_ERR ("usbCbiUfiReqSense: Error forming command\n", 0, 0, 0, 0, 0, 0); OSS_MUTEX_RELEASE (cbiUfiDevMutex); } if ( usbCbiUfiCmdExecute (pCbiUfiDev) != USB_COMMAND_SUCCESS ) { USB_CBI_UFI_ERR ("usbCbiUfiReqSense: Error executing "\ "USB_UFI_REQUEST_SENSE command\n", 0, 0, 0, 0, 0, 0); OSS_MUTEX_RELEASE (cbiUfiDevMutex); } else { /* Request Sense command success. Check the sense key & qualifiers. */ switch (reqSense [USB_UFI_SENSE_KEY_OFFSET]) { case USB_UFI_NO_SENSE: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: No Sense key, %d, %d\n", reqSense[USB_UFI_SENSE_ASC], reqSense[USB_UFI_SENSE_ASCQ], 0, 0, 0, 0); break; case USB_UFI_RECOVERED_ERROR: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Recovered Error, %d, %d\n", reqSense[USB_UFI_SENSE_ASC], reqSense[USB_UFI_SENSE_ASCQ], 0, 0, 0, 0); break; case USB_UFI_NOT_READY: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Device not ready, %d, %d \n", reqSense[USB_UFI_SENSE_ASC], reqSense[USB_UFI_SENSE_ASCQ], 0, 0, 0, 0); break; case USB_UFI_MEDIUM_ERROR: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Medium Error, %d, %d\n", reqSense[USB_UFI_SENSE_ASC], reqSense[USB_UFI_SENSE_ASCQ], 0, 0, 0, 0); break; case USB_UFI_HARDWARE_ERROR: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Hardware Error, %d, %d\n", reqSense[USB_UFI_SENSE_ASC], reqSense[USB_UFI_SENSE_ASCQ], 0, 0, 0, 0); break; case USB_UFI_ILL_REQUEST: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Illegal Request, %d, %d\n", reqSense[USB_UFI_SENSE_ASC], reqSense[USB_UFI_SENSE_ASCQ], 0, 0, 0, 0); break; case USB_UFI_UNIT_ATTN: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Unit Attention, %d, %d\n", reqSense[USB_UFI_SENSE_ASC], reqSense[USB_UFI_SENSE_ASCQ], 0, 0, 0, 0); /* If Unit attention condition, check the ASC and ASCQ */ status = (reqSense[12] << 8) & 0xFF00; status = status | reqSense[13]; switch (status) { case USB_UFI_WRITE_PROTECT : USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Media write "\ "protected\n", 0, 0, 0, 0, 0 ,0); break; case USB_UFI_MEDIA_CHANGE : USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Media changed\n", 0, 0, 0, 0, 0 ,0); break; case USB_UFI_POWER_ON_RESET :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -