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 + -
显示快捷键?