📄 usbcbiufidevlib.c
字号:
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 * pReqSense; UINT16 status = 0xFFFF; if ((pReqSense = OSS_MALLOC (UFI_STD_REQ_SENSE_LEN)) == NULL) { return; } pCbiUfiDev->bulkInData = pReqSense; if ( usbCbiUfiFormCmd (pCbiUfiDev, USB_UFI_REQUEST_SENSE, 0, 0) != 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 (*(pReqSense + USB_UFI_SENSE_KEY_OFFSET)) { case USB_UFI_NO_SENSE: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: No Sense key, %d, %d\n", *(pReqSense + USB_UFI_SENSE_ASC), *(pReqSense + USB_UFI_SENSE_ASCQ), 0, 0, 0, 0); break; case USB_UFI_RECOVERED_ERROR: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Recovered Error, %d, %d\n", *(pReqSense + USB_UFI_SENSE_ASC), *(pReqSense + 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", *(pReqSense + USB_UFI_SENSE_ASC), *(pReqSense + USB_UFI_SENSE_ASCQ), 0, 0, 0, 0); break; case USB_UFI_MEDIUM_ERROR: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Medium Error, %d, %d\n", *(pReqSense + USB_UFI_SENSE_ASC), *(pReqSense + USB_UFI_SENSE_ASCQ), 0, 0, 0, 0); break; case USB_UFI_HARDWARE_ERROR: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Hardware Error, %d, %d\n", *(pReqSense + USB_UFI_SENSE_ASC), *(pReqSense + USB_UFI_SENSE_ASCQ), 0, 0, 0, 0); break; case USB_UFI_ILL_REQUEST: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Illegal Request, %d, %d\n", *(pReqSense + USB_UFI_SENSE_ASC), *(pReqSense + USB_UFI_SENSE_ASCQ), 0, 0, 0, 0); break; case USB_UFI_UNIT_ATTN: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Unit Attention, %d, %d\n", *(pReqSense + USB_UFI_SENSE_ASC), *(pReqSense + USB_UFI_SENSE_ASCQ), 0, 0, 0, 0); /* If Unit attention condition, check the ASC and ASCQ */ status = (*(pReqSense + 12) << 8) & 0xFF00; status = status | *(pReqSense + 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 : USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Power on reset"\ " Bus device reset\n",0, 0, 0, 0, 0 ,0); break; case USB_UFI_COMMAND_SUCCESS : USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: No sense"\ "Bus device reset\n",0, 0, 0, 0, 0 ,0); break; } break; case USB_UFI_DATA_PROTECT: USB_CBI_UFI_DEBUG ("usbCbiUfiReqSense: Write Protect\n", 0, 0, 0, 0, 0, 0); break; default : break; } } OSS_FREE (pReqSense); } /***************************************************************************** usbCbiUfiDevFind - Searches for a USB_CBI_UFI_DEV for indicated node ID** RETURNS: pointer to matching USB_CBI_UFI_DEV or NULL if not found*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -