📄 usbcbiufidevlib.c
字号:
while ((pCbiUfiDev = usbListFirst (&cbiUfiDevList)) != NULL) usbCbiUfiDevDestroy (pCbiUfiDev); /* Dispose of any outstanding notification requests */ while ((pRequest = usbListFirst (&reqList)) != NULL) { usbListUnlink (&pRequest->reqLink); OSS_FREE (pRequest); } /* * Unregister with the USBD. USBD will automatically release any pending * IRPs or attach requests. */ if (usbdHandle != NULL) { usbdClientUnregister (usbdHandle); usbdHandle = NULL; USB_CBI_UFI_DEBUG ("usbCbiUfiDevShutDown : CBI Mass storage class driver "\ "for UFI devices unregistered \n", 0, 0, 0, 0, 0, 0); } /* release resources */ if (cbiUfiDevMutex != NULL) { OSS_MUTEX_DESTROY (cbiUfiDevMutex); cbiUfiDevMutex = NULL; } if (cbiUfiIrpSem != NULL) { OSS_MUTEX_DESTROY (cbiUfiIrpSem); cbiUfiIrpSem = NULL; } initCount--; return (ossStatus (errCode)); }/***************************************************************************** usbCbiUfiDevDestroy - releases USB_CBI_UFI_DEV structure and its links** Unlinks the indicated USB_CBI_UFI_DEV structure and de-allocates* resources associated with the device.** RETURNS: N/A*/LOCAL VOID usbCbiUfiDevDestroy ( pUSB_CBI_UFI_DEV pCbiUfiDev /* pointer to MSC/CBI/UFI device */ ) { if (pCbiUfiDev != NULL) { /* Unlink the structure. */ usbListUnlink (&pCbiUfiDev->cbiUfiDevLink); /* Release pipes and wait for IRPs. */ if (pCbiUfiDev->outPipeHandle != NULL) usbdPipeDestroy (usbdHandle, pCbiUfiDev->outPipeHandle); if (pCbiUfiDev->inPipeHandle != NULL) usbdPipeDestroy (usbdHandle, pCbiUfiDev->inPipeHandle); /* wait for any IRP to complete */ OSS_SEM_TAKE (cbiUfiIrpSem, OSS_BLOCK); OSS_SEM_GIVE (cbiUfiIrpSem); /* Release structure. */ OSS_FREE (pCbiUfiDev); } }/***************************************************************************** usbCbiUfiDevIoctl - perform a device-specific control.** Typically called by file system to invoke device-specific functions beyond * file handling. The following control requests are supported** .IP "FIODISKFORMAT (0x05)"* Formats the entire disk with appropriate hardware track and sector marks. * No file system is initialized on the disk by this request. This control* function is defined by the file system, but provided by the driver.* .IP "USB UFI ALL DESCRIPTOR GET (0xF0)"* Invokes show routine for displaying configuration, device and interface * descriptors.* .IP "USB UFI DEV RESET (0xF1)" * Issues a command block reset and clears stall condition on bulk-in and * bulk-out endpoints.** RETURNS: The status of the request, or ERROR if the request is unsupported.*/STATUS usbCbiUfiDevIoctl ( BLK_DEV * pBlkDev, /* pointer to MSC/CBI/UFI device */ UINT32 request, /* request type */ UINT32 someArg /* arguments related to request */ ) { /* get a pointer to the MSC/CBI/UFI device */ pUSB_CBI_UFI_DEV pCbiUfiDev = (USB_CBI_UFI_DEV *)pBlkDev; if ( pCbiUfiDev == (pUSB_CBI_UFI_DEV)NULL ) return (ERROR); /* Check whether the device exists or not */ if (usbCbiUfiDevFind (pCbiUfiDev->cbiUfiDevId) != pCbiUfiDev) { USB_CBI_UFI_ERR ("usbCbiUfiDevIoctl: MSC/CBI/UFI Device not found\n", 0, 0, 0, 0, 0, 0); return (ERROR); } switch (request) { case FIODISKFORMAT: if ( usbCbiUfiFormCmd (pCbiUfiDev, USB_UFI_FORMAT_UNIT, 0, 0) != OK) { USB_CBI_UFI_ERR ("usbCbiUfiDevIoctl: Error forming command\n", 0, 0, 0, 0, 0, 0); return (ERROR); } if ( usbCbiUfiCmdExecute (pCbiUfiDev) != USB_COMMAND_SUCCESS ) { USB_CBI_UFI_ERR ("usbCbiUfiDevIoctl: Error executing "\ "USB_UFI_FORMAT_UNIT command\n", 0, 0, 0, 0, 0, 0); OSS_MUTEX_RELEASE (cbiUfiDevMutex); return (ERROR); } break; case USB_UFI_ALL_DESCRIPTOR_GET: /* invoke routine to display all descriptors */ return (usbCbiUfiDescShow (pCbiUfiDev->cbiUfiDevId)); case USB_UFI_DEV_RESET: /* send a command block reset */ return (usbCbiUfiDevReset ((BLK_DEV *)pCbiUfiDev)); default: errnoSet (S_ioLib_UNKNOWN_REQUEST); USB_CBI_UFI_DEBUG ("usbCbiUfiDevIoctl: Unknown Request\n", 0, 0, 0, 0, 0, 0); return (ERROR); break; } return (OK); } /***************************************************************************** usbCbiUfiFormCmd - forms a command block for requested UFI command. ** This routine forms UFI command blocks as per the UFI command specifications. * The following are the input parameters ** .IP <pCbiUfiDev>* pointer to USB/CBI/UFI device for which the command has to be formed.** .IP <ufiCmd>* identifies the UFI command to be formed.* * .IP <cmdParam1>* parameter required to form a complete UFI comamnd, if any.** .IP <cmdParam2>* parameter required to form a complete UFI comamnd, if any.** RETURNS: OK, or ERROR if the command is unsupported.*/LOCAL STATUS usbCbiUfiFormCmd ( pUSB_CBI_UFI_DEV pCbiUfiDev, /* pointer to cbi_ufi device */ UINT ufiCmd, /* UFI command */ UINT cmdParam1, /* command parameter */ UINT cmdParam2 /* command parameter */ ) { memset (&(pCbiUfiDev->ufiCmdBlk), 0, sizeof(USB_UFI_CMD_BLOCK)); switch (ufiCmd) { case USB_UFI_FORMAT_UNIT: /* UFI Format Unit Command */ pCbiUfiDev->ufiCmdBlk.dataXferLen = 0; pCbiUfiDev->ufiCmdBlk.direction = 0; pCbiUfiDev->ufiCmdBlk.cmd[0] = USB_UFI_FORMAT_UNIT; pCbiUfiDev->ufiCmdBlk.cmd[1] = (USB_UFI_FORMAT_FMTDATA | USB_UFI_FORMAT_FMT_DEFECT); pCbiUfiDev->ufiCmdBlk.cmd[2] = 0; /* Track Number */ pCbiUfiDev->ufiCmdBlk.cmd[3] = 0; /* Interleave factor MSB */ pCbiUfiDev->ufiCmdBlk.cmd[4] = 0; /* Interleave factor LSB */ pCbiUfiDev->ufiCmdBlk.cmd[7] = 0; /* Parameter List length MSB */ pCbiUfiDev->ufiCmdBlk.cmd[8] = 0x0C; /* Parameter List * 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -