usbcbiufidevlib.c
来自「MPC5200 BSP 支持ATA,USB, I2C,扩展网口」· C语言 代码 · 共 2,132 行 · 第 1/5 页
C
2,132 行
* length LSB */ break; case USB_UFI_INQUIRY: /* UFI Inquiry command */ pCbiUfiDev->ufiCmdBlk.dataXferLen = UFI_STD_INQUIRY_LEN; pCbiUfiDev->ufiCmdBlk.direction = USB_UFI_DIR_IN; pCbiUfiDev->ufiCmdBlk.cmd[0] = USB_UFI_INQUIRY; pCbiUfiDev->ufiCmdBlk.cmd[1] = 0; /* Enable Vital * Product data */ pCbiUfiDev->ufiCmdBlk.cmd[2] = 0; /* Page Code * Field */ pCbiUfiDev->ufiCmdBlk.cmd[4] = UFI_STD_INQUIRY_LEN; break; case USB_UFI_MODE_SELECT: /* UFI Mode Select Command */ pCbiUfiDev->ufiCmdBlk.cmd[0] = USB_UFI_MODE_SELECT; pCbiUfiDev->ufiCmdBlk.cmd[1] = USB_UFI_MODE_SEL_PF; /* TODO : Set the number of bytes as per the mode pages */ pCbiUfiDev->ufiCmdBlk.cmd[7] = 0; /* Parameter list length MSB */ pCbiUfiDev->ufiCmdBlk.cmd[8] = 0; /* Parameter list length LSB */ break; case USB_UFI_MODE_SENSE: /* UFI Request Mode Sense command */ pCbiUfiDev->ufiCmdBlk.dataXferLen = USB_UFI_MS_HEADER_LEN; pCbiUfiDev->ufiCmdBlk.direction = USB_UFI_DIR_IN; pCbiUfiDev->ufiCmdBlk.cmd[0] = USB_UFI_MODE_SENSE; pCbiUfiDev->ufiCmdBlk.cmd[1] = 0; /* Check the basic header information only. */ pCbiUfiDev->ufiCmdBlk.cmd[2] = 1; pCbiUfiDev->ufiCmdBlk.cmd[7] = 0; /* Parameter list length MSB */ pCbiUfiDev->ufiCmdBlk.cmd[8] = USB_UFI_MS_HEADER_LEN; /* Parameter list length LSB */ break; case USB_UFI_PREVENT_MEDIA_REMOVAL: /* Enable or disable media * removal */ pCbiUfiDev->ufiCmdBlk.dataXferLen = 0; pCbiUfiDev->ufiCmdBlk.direction = 0; pCbiUfiDev->ufiCmdBlk.cmd[0] = USB_UFI_PREVENT_MEDIA_REMOVAL; pCbiUfiDev->ufiCmdBlk.cmd[1] = 0; pCbiUfiDev->ufiCmdBlk.cmd[4] = USB_UFI_MEDIA_REMOVAL_BIT; break; case USB_UFI_READ10: /* UFI 10 byte READ Command */ pCbiUfiDev->ufiCmdBlk.dataXferLen = ((cmdParam2) * (pCbiUfiDev->blkDev.bd_bytesPerBlk)); pCbiUfiDev->ufiCmdBlk.direction = USB_UFI_DIR_IN; pCbiUfiDev->ufiCmdBlk.cmd[0] = USB_UFI_READ10; pCbiUfiDev->ufiCmdBlk.cmd[1] = 0; /* * cmdParam1 for this command will indicate the logical block * address at which the read operation begins. cmdParam2 will * indicate the number of logical blocks to be read. */ 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; case USB_UFI_READ_CAPACITY: /* UFI Read Capacity command */ pCbiUfiDev->ufiCmdBlk.dataXferLen = 0x8; pCbiUfiDev->ufiCmdBlk.direction = USB_UFI_DIR_IN; pCbiUfiDev->ufiCmdBlk.cmd[0] = USB_UFI_READ_CAPACITY; pCbiUfiDev->ufiCmdBlk.cmd[1] = 0; /* RelAdr bit should be zero */ pCbiUfiDev->ufiCmdBlk.cmd[2] = 0; /* Logical block address */ pCbiUfiDev->ufiCmdBlk.cmd[3] = 0; /* should be set to zero */ pCbiUfiDev->ufiCmdBlk.cmd[4] = 0; pCbiUfiDev->ufiCmdBlk.cmd[5] = 0; pCbiUfiDev->ufiCmdBlk.cmd[8] = 0; /* PMI bit should be zero */ break; case USB_UFI_REQUEST_SENSE: /* UFI Request Sense command */ pCbiUfiDev->ufiCmdBlk.dataXferLen = 0x12; pCbiUfiDev->ufiCmdBlk.direction = USB_UFI_DIR_IN; pCbiUfiDev->ufiCmdBlk.cmd[0] = USB_UFI_REQUEST_SENSE; pCbiUfiDev->ufiCmdBlk.cmd[1] = 0; pCbiUfiDev->ufiCmdBlk.cmd[4] = UFI_STD_REQ_SENSE_LEN; break; case USB_UFI_SEND_DIAGNOSTIC: /* UFI Send Diagnostics command */ /* Requests the device to perform self-test or reset */ pCbiUfiDev->ufiCmdBlk.cmd[0] = USB_UFI_SEND_DIAGNOSTIC; pCbiUfiDev->ufiCmdBlk.cmd[1] = 0x04; /* Perform default * self test */ break; case USB_UFI_START_STOP_UNIT: /* UFI Start Stop unit command */ /* This command is basically used to update the media type and the * write protect status. Load eject bit is not supported by * USB-FDU. */ 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); } 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); } } 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);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?