⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbbulkdevlib.c

📁 This the compressed USB driver source code for vxworks5.6. It has device controller driver and other
💻 C
📖 第 1 页 / 共 5 页
字号:
* This routine unregisters the driver from USBD and releases any resources * allocated for the devices.** RETURNS: OK or ERROR depending on errCode** ERRNO:* \is * \i S_usbBulkDevLib_NOT_INITIALIZED* Not initialized* \ie*/STATUS usbBulkDevShutDown     (    int   errCode                /* Error code - reason for shutdown */    )    {    pUSB_BULK_DEV pBulkDev;      /* Pointer to bulk device */    pATTACH_REQUEST  pRequest;    if (initCount == 0)        return ossStatus (S_usbBulkDevLib_NOT_INITIALIZED);    /* release any bulk devices */    while ((pBulkDev = usbListFirst (&bulkDevList)) != NULL)        usbBulkDevDestroy (pBulkDev);     /* 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_BULK_DEBUG ("usbBulkDevShutDown : Bulk Only class driver "\                        "unregistered \n", 0, 0, 0, 0, 0, 0);        }    /* release resources */    if (bulkMutex != NULL)        {        OSS_MUTEX_DESTROY (bulkMutex);        bulkMutex = NULL;        }    initCount--;        return ossStatus (errCode);     }/***************************************************************************** usbBulkDevInit - registers USB Bulk only mass storage class driver** This routine registers the mass storage class driver with USB driver.  It* also registers attach callback routine to get notified of the USB/MSC/BULK* ONLY devices.  ** RETURNS: OK, or ERROR if unable to register with USBD.** ERRNO:* \is* \i S_usbbulkDevLib_OUT_OF_RESOURCES* Resources not available** \i S_usbbulkDevLib_USBD_FAULT* Error in USBD layer* \ie*/STATUS usbBulkDevInit (void)    {    /*      * Check whether already initilized. If not, then initialise the required     * structures and register the class driver with USBD.     */    if (initCount == 0)        {        memset (&bulkDevList, 0, sizeof (bulkDevList));        memset (&reqList, 0, sizeof (reqList));        bulkMutex = NULL;        usbdHandle   = NULL;        if (OSS_MUTEX_CREATE (&bulkMutex) != OK)            return (usbBulkDevShutDown (S_usbBulkDevLib_OUT_OF_RESOURCES));        /* Establish connection to USBD and register for attach callback */        if (usbdClientRegister ("BULK_CLASS", &usbdHandle) != OK ||            usbdDynamicAttachRegister (usbdHandle, USB_CLASS_MASS_STORAGE,                                       USB_SUBCLASS_SCSI_COMMAND_SET,                                        USB_INTERFACE_PROTOCOL_BULK_ONLY,                                       usbBulkDevAttachCallback) != OK)            {            USB_BULK_ERR ("usbBulkDevInit: Client Registration Failed \n",                          0, 0, 0, 0, 0, 0);             return usbBulkDevShutDown (S_usbBulkDevLib_USBD_FAULT);            }        }    initCount++;    return (OK);    }/***************************************************************************** usbBulkDevIoctl - perform a device-specific control** Typically called to invoke device-specific functions which are not needed* by a file system.  ** RETURNS: The status of the request, or ERROR if the request is unsupported.** ERRNO: none*/STATUS usbBulkDevIoctl    (    BLK_DEV * pBlkDev,           /* pointer to bulk device       */    int request,                 /* request type                 */    int someArg                  /* arguments related to request */    )    {    UINT16 actLen= 0xffff;           USB_COMMAND_STATUS status;    /* get a pointer to the bulk device */    pUSB_BULK_DEV_LUN  pBulkDevLun = (pUSB_BULK_DEV_LUN)(pBlkDev);    pUSB_BULK_DEV      pBulkDev    = (pUSB_BULK_DEV) (pBulkDevLun - pBulkDevLun->blkLun);    UINT8              lun         = pBulkDevLun->blkLun;    if ( pBulkDev == (pUSB_BULK_DEV)NULL )        return (ERROR);    /* Check whether the device exists or not */    if (usbBulkDevFind (pBulkDev->bulkDevId) != pBulkDev)        {        USB_BULK_ERR ("usbBulkDevIoctl: Bulk Device not found\n",                         0, 0, 0, 0, 0, 0);        return (ERROR);        }    /* Make sure that no one else is doing anything with this USB device */      OSS_MUTEX_TAKE(pBulkDev->bulkDevMutex, OSS_BLOCK);    switch (request)        {        case FIODISKFORMAT:             /*               * This is the IO control function supported by file system,             * but supplied by the device driver. Other IO control functions              * are directly handled by file system with out the use of this              * routine.             */            if ( usbBulkFormScsiCmd (pBulkDev,                                      lun,				     USB_SCSI_FORMAT_UNIT, 				     0, 				     0) 				   != OK )                {                OSS_MUTEX_RELEASE(pBulkDev->bulkDevMutex);                return (ERROR);                 }            if ((status = usbBulkCmdExecute (pBulkDev)) != USB_COMMAND_SUCCESS )                {                USB_BULK_ERR ("usbBulkDevIoctl: FORMAT UNIT Command failed\n",                               0, 0, 0, 0, 0, 0);                  if (status == USB_COMMAND_FAILED)                    {                    /* Clear the error condition on the device */                    usbBulkRequestSense(pBlkDev,                                        &bulkSenseKey,                                        &bulkAsc,                                        &bulkAscq);                    }                OSS_MUTEX_RELEASE(pBulkDev->bulkDevMutex);                return (ERROR);                 }                               return (OK);        case USB_BULK_DESCRIPTOR_GET:            OSS_MUTEX_RELEASE(pBulkDev->bulkDevMutex);            /* invoke routine to display all descriptors */            return (usbBulkDescShow (pBulkDev->bulkDevId));        case USB_BULK_DEV_RESET:            OSS_MUTEX_RELEASE(pBulkDev->bulkDevMutex);            /* send a class-specific mass storage reset command */            return (usbBulkDevResetRecovery (pBulkDev));        case USB_BULK_EJECT_MEDIA:            /* Only applicable if media is removable */            if ( pBlkDev->bd_removable  != TRUE )                {                OSS_MUTEX_RELEASE(pBulkDev->bulkDevMutex);                return (ERROR);                  }            else                {                if ( usbBulkFormScsiCmd (pBulkDev,                                          lun,                                         USB_SCSI_START_STOP_START,                                          USB_SCSI_START_STOP_LOEJ,                                          0) 					!= OK )                    {                    OSS_MUTEX_RELEASE(pBulkDev->bulkDevMutex);                    return (ERROR);                     }                if ( (status = usbBulkCmdExecute (pBulkDev)) != USB_COMMAND_SUCCESS )                    {                    USB_BULK_ERR ("usbBulkDevIoctl: EJECT Command " \                                  "failed\n", 0, 0, 0, 0, 0, 0);                      if (status == USB_COMMAND_FAILED)                        {                        /* Clear the error condition on the device */                        usbBulkRequestSense(pBlkDev,                                            &bulkSenseKey,                                            &bulkAsc,                                            &bulkAscq);                        }                    OSS_MUTEX_RELEASE(pBulkDev->bulkDevMutex);                    return (ERROR);                     }                }            OSS_MUTEX_RELEASE(pBulkDev->bulkDevMutex);            return (OK); 	                case USB_BULK_MAX_LUN:            /* May not be supported by devices having single LUN */                    if (usbdVendorSpecific (usbdHandle, pBulkDev->bulkDevId,                USB_RT_DEV_TO_HOST | USB_RT_CLASS | USB_RT_INTERFACE,                USB_BULK_GET_MAX_LUN, 0, pBulkDev->interface, 1,                 &(pBulkDev->maxLun), &actLen) != OK )                {                USB_BULK_ERR ("usbBulkDevIoctl: Failed to acquire max lun \n",                               0, 0, 0, 0, 0, 0);                  pBulkDev->maxLun = 0;                }            else                 {                  USB_BULK_DEBUG ("usbBulkDevIoctl: Max Lun = %c \n",                                  pBulkDev->maxLun, 0, 0, 0, 0, 0);                }                     if (pBulkDev->maxLun > MAX_LUN-1)                {                USB_BULK_DEBUG ("USB Bulk Mass Storage Device Maximum LUN exceeded\n",                       0,0,0,0,0,0);                pBulkDev->maxLun = MAX_LUN-1;                }            OSS_MUTEX_RELEASE(pBulkDev->bulkDevMutex);            return (OK);                          default:            errnoSet (S_ioLib_UNKNOWN_REQUEST);            USB_BULK_DEBUG ("usbBulkDevIoctl: Unknown Request\n",                             0, 0, 0, 0, 0, 0);            OSS_MUTEX_RELEASE(pBulkDev->bulkDevMutex);            return (ERROR);        }    }/***************************************************************************** usbBulkDevResetRecovery - performs reset recovery on the specified device** Reset recovery shall be done when device returns a phase error status * while executing a CBW.  It is also done, when a stall condition is detected* on bulk-out endpoint during CBW transport.  The following sequence is * performed on the device ** - BulkOnly Mass Storage Reset * - Clear HALT feature on the Bulk-in Endpoint* - Clear HALT feature on the Bulk-out Endpoint** RETURNS: OK, if reset sequence successful otherwise ERROR** ERRNO: none**\NOMANUAL*/LOCAL STATUS usbBulkDevResetRecovery    (    pUSB_BULK_DEV  pBulkDev           /* pointer to bulk device */    )    {    /* Verify the Bulk Pointer is valid */    if (pBulkDev == NULL)        return ERROR;    OSS_MUTEX_TAKE (pBulkDev->bulkDevMutex, OSS_BLOCK);          /* issue bulk-only mass storage reset request on control End point */    if ((usbdVendorSpecific (usbdHandle, 			     pBulkDev->bulkDevId,			     USB_RT_HOST_TO_DEV | USB_RT_CLASS | USB_RT_INTERFACE,			     USB_BULK_RESET, 			     0, 			     pBulkDev->interface, 			     0, 			     NULL, 			     NULL)) 			   != OK )        {        USB_BULK_ERR ("usbBulkDevResetRecovery: Failed to reset %x\n",                       0, 0, 0, 0, 0, 0);                  OSS_MUTEX_RELEASE (pBulkDev->bulkDevMutex);        return (ERROR);         }    else        {        USB_BULK_DEBUG ("usbBulkDevResetRecovery: Reset...done\n",                        0, 0, 0, 0, 0, 0);       }    /* clear HALT feature on bulk in and bulk out end points */    if ((usbdFeatureClear (usbdHandle, 			   pBulkDev->bulkDevId, 			   USB_RT_ENDPOINT, 			   USB_FSEL_DEV_ENDPOINT_HALT, 			   (pBulkDev->inEpAddress & 0xFF))) 			 != OK)        {        USB_BULK_ERR ("usbBulkDevResetRecovery: Failed to clear HALT feauture"\                      " on bulk in Endpoint %x\n", 0, 0, 0, 0, 0, 0);        }      if ((usbdFeatureClear (usbdHandle, 			   pBulkDev->bulkDevId, 			   USB_RT_ENDPOINT,                            			   USB_FSEL_DEV_ENDPOINT_HALT, 			   (pBulkDev->outEpAddress & 0xFF))) 			 != OK)        {        USB_BULK_ERR ("usbBulkDevResetRecovery: Failed to clear HALT feauture"\                      " on bulk out Endpoint %x\n", 0, 0, 0, 0, 0, 0);        }     OSS_MUTEX_RELEASE (pBulkDev->bulkDevMutex);    return (OK);      }/***************************************************************************** usbBulkFormScsiCmd - forms command block wrapper(CBW) for requested SCSI command** This routine forms SCSI command blocks as per the Bulk-only command   * specifications and SCSI protocol.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -