usbcbiufidevlib.c

来自「MPC5200 BSP 支持ATA,USB, I2C,扩展网口」· C语言 代码 · 共 2,132 行 · 第 1/5 页

C
2,132
字号
/* includes */#include "vxWorks.h"#include "string.h"#include "errno.h"#include "errnoLib.h"#include "ioLib.h"#include "blkIo.h"#include "stdio.h"#include "logLib.h"#include "usb/usbPlatform.h"#include "usb/ossLib.h"             /* operations system srvcs */#include "usb/usb.h"                /* general USB definitions */#include "usb/usbListLib.h"         /* linked list functions   */#include "usb/usbdLib.h"            /* USBD interface          */#include "usb/usbLib.h"             /* USB utility functions   */#include "drv/usb/usbCbiUfiDevLib.h"/* defines */#define USB_DEBUG_MSG        0x01#define USB_DEBUG_ERR        0x02#define USB_CBI_UFI_DEBUG 	                   \        if (usbCbiUfiDebug & USB_DEBUG_MSG)	   \            logMsg#define USB_CBI_UFI_ERR                    	\        if (usbCbiUfiDebug & USB_DEBUG_ERR)   	\            logMsg/* typedefs */typedef struct usbCbiUfiDev    {    BLK_DEV           blkDev;         /* Vxworks block device structure */                                      /* Must be the first one          */    USBD_NODE_ID      cbiUfiDevId;    /* USBD node ID of the device     */	     UINT16            configuration;  /* Configuration value            */        UINT16            interface;      /* Interface number               */    UINT16            altSetting;     /* Alternate setting of interface */     UINT16            outEpAddress;   /* Bulk out EP address            */       UINT16            inEpAddress;    /* Bulk in EP address             */    UINT16            intrEpAddress;  /* Interrupt EP address           */    USBD_PIPE_HANDLE  outPipeHandle;  /* Pipe handle for Bulk out EP    */    USBD_PIPE_HANDLE  inPipeHandle;   /* Pipe handle for Bulk in EP     */    USBD_PIPE_HANDLE  intrPipeHandle; /* Pipe handle for interrupt EP   */    USB_IRP           inIrp;          /* IRP used for bulk-in data      */    USB_IRP           outIrp;         /* IRP used for bulk-out data     */    USB_IRP           statusIrp;      /* IRP used for status data       */       USB_UFI_CMD_BLOCK ufiCmdBlk;      /* Store for UFI Command block    */    UINT8 *           bulkInData;     /* Pointer for bulk-in data       */    UINT8 *           bulkOutData;    /* Pointer for bulk-out data      */       UINT8             intrStatus[2];  /* Store for Status bytes         */    UINT16            lockCount;      /* Count of times structure locked*/    BOOL              connected;      /* TRUE if CBI_UFI device connected  */        LINK              cbiUfiDevLink;  /* Link to other USB_CBI_UFI devices */      } USB_CBI_UFI_DEV, *pUSB_CBI_UFI_DEV;/* Attach request for user callback */typedef struct attach_request    {    LINK reqLink;                       /* linked list of requests */    USB_UFI_ATTACH_CALLBACK callback;   /* client callback routine */    pVOID callbackArg;                  /* client callback argument*/    } ATTACH_REQUEST, *pATTACH_REQUEST;/* globals */BOOL usbCbiUfiDebug = 0;/* locals */LOCAL UINT16 initCount = 0;           /* Count for UFI device initialisation */LOCAL USBD_CLIENT_HANDLE usbdHandle;  /* Handle for this class driver */LOCAL MUTEX_HANDLE cbiUfiDevMutex;    /* Mutex used to protect internal structs */LOCAL SEM_HANDLE   cbiUfiIrpSem;      /* Semaphore for IRP Synchronisation */LOCAL LIST_HEAD    cbiUfiDevList;     /* Linked list of USB_CBI_UFI_DEV */LOCAL LIST_HEAD    reqList;           /* Attach callback request list *//* forward declarations */LOCAL  STATUS usbCbiUfiDescShow (USBD_NODE_ID nodeId);LOCAL  STATUS usbCbiUfiConfigDescShow  (USBD_NODE_ID nodeId, UINT8 index);LOCAL  pUSB_CBI_UFI_DEV usbCbiUfiPhysDevCreate (USBD_NODE_ID nodeId,                                                 UINT16 config, 						UINT16 interface);LOCAL  pUSB_CBI_UFI_DEV usbCbiUfiDevFind (USBD_NODE_ID nodeId);LOCAL  STATUS usbCbiUfiDevBlkRd (BLK_DEV *blkDev, 				 UINT32 offset, 				 UINT32 num, 				 char * buf);LOCAL  STATUS usbCbiUfiDevBlkWrt (BLK_DEV *blkDev, 				  UINT32 offset, 				  UINT32 num, 				  char * buf);LOCAL  STATUS usbCbiUfiDevStChk (BLK_DEV *blkDev);LOCAL  STATUS usbCbiUfiDevReset (BLK_DEV *blkDev);LOCAL  VOID   usbCbiUfiIrpCallback (pVOID p);LOCAL  STATUS usbCbiUfiFormCmd (pUSB_CBI_UFI_DEV pCbiUfiDev, 				UINT ufiCmd, 				UINT cmdParam1, 				UINT cmdParam2);LOCAL  USB_COMMAND_STATUS usbCbiUfiCmdExecute (pUSB_CBI_UFI_DEV pCbiUfiDev);LOCAL  VOID usbCbiUfiDevDestroy (pUSB_CBI_UFI_DEV pCbiUfiDev); LOCAL  VOID notifyAttach (USBD_NODE_ID nodeId, UINT16 attachCode);LOCAL VOID usbCbiUfiAttachCallback    (    USBD_NODE_ID nodeId,        /* USBD Node ID of the device attached       */    UINT16 attachAction,        /* Whether device attached / detached        */    UINT16 configuration,       /* Configur'n value for  MSC/CBI/UFI         */    UINT16 interface,           /* Interface number for  MSC/CBI/UFI         */    UINT16 deviceClass,         /* Interface class   - 0x8  for MSC          */    UINT16 deviceSubClass,      /* Device sub-class  - 0x4  for UFI command  */    UINT16 deviceProtocol       /* Interfaceprotocol - 0x00 for CBI          */    )    {    pUSB_CBI_UFI_DEV  pCbiUfiDev;      OSS_MUTEX_TAKE (cbiUfiDevMutex, OSS_BLOCK);     switch (attachAction)        {         case USBD_DYNA_ATTACH:             /* MSC/CBI/UFI Device attached */            USB_CBI_UFI_DEBUG ("usbCbiUfiAttachCallback : New MSC/CBI/UFI device "\                               "attached\n", 0, 0, 0, 0, 0, 0);            /* Check out whether we already have a structure for this device */            USB_CBI_UFI_DEBUG ("usbCbiUfiAttachCallback: Configuration = %d, " \                               "Interface = %d, Node Id = %d \n", configuration,                               interface, (UINT)nodeId, 0, 0, 0);             if (usbCbiUfiDevFind (nodeId) != NULL)                break;            /* create a USB_CBI_UFI_DEV structure for the device detected */                       if ((pCbiUfiDev = usbCbiUfiPhysDevCreate (nodeId, 						      configuration,                                                       interface)) ==NULL )                {                USB_CBI_UFI_ERR ("usbCbiUfiAttachCallback : Error creating " \                                 "MSC/CBI/UFI device\n", 0, 0, 0, 0, 0, 0);                break;                }                          /* Notify registered callers that a CBI_UFI_DEV has been added */	    notifyAttach (pCbiUfiDev->cbiUfiDevId, USB_UFI_ATTACH);             break;        case USBD_DYNA_REMOVE:            /* MSC/CBI/UFI Device detached */            USB_CBI_UFI_DEBUG ("usbCbiUfiAttachCallback : MSC/CBI/UFI Mass storage "\                               "device detached\n", 0, 0, 0, 0, 0, 0);            if ((pCbiUfiDev = usbCbiUfiDevFind (nodeId)) == NULL)                break;            /* Check the connected flag  */            if (pCbiUfiDev->connected == FALSE)                break;                        pCbiUfiDev->connected = FALSE;            pCbiUfiDev->lockCount++;             notifyAttach (pCbiUfiDev->cbiUfiDevId, USB_UFI_REMOVE);             pCbiUfiDev->lockCount--;                         if (pCbiUfiDev->lockCount == 0)                 usbCbiUfiDevDestroy (pCbiUfiDev);                             break;        default :            break;         }    OSS_MUTEX_RELEASE (cbiUfiDevMutex);      }STATUS usbCbiUfiDevInit (VOID)    {      if (initCount == 0)        {        memset (&cbiUfiDevList, 0, sizeof (cbiUfiDevList));        memset (&reqList, 0, sizeof (reqList));        cbiUfiDevMutex = NULL;        cbiUfiIrpSem   = NULL;        usbdHandle     = NULL;        if (OSS_MUTEX_CREATE (&cbiUfiDevMutex) != OK)            return (usbCbiUfiDevShutDown (S_usbCbiUfiDevLib_OUT_OF_RESOURCES));        if (OSS_SEM_CREATE (1, 1 , &cbiUfiIrpSem) != OK)            return (usbCbiUfiDevShutDown (S_usbCbiUfiDevLib_OUT_OF_RESOURCES));        /* Establish connection to USBD */        if (usbdClientRegister ("CBI_UFI_CLASS", &usbdHandle) != OK ||            usbdDynamicAttachRegister (usbdHandle, USB_CLASS_MASS_STORAGE,                                       USB_SUBCLASS_UFI_COMMAND_SET,                                        USB_INTERFACE_PROTOCOL_CBI,                                       usbCbiUfiAttachCallback) != OK)            {            USB_CBI_UFI_ERR ("usbCbiUfiDevInit: Client Registration Failed \n",                             0, 0, 0, 0, 0, 0);             return (usbCbiUfiDevShutDown (S_usbCbiUfiDevLib_USBD_FAULT));            }        }    initCount++;    return (OK);    }STATUS usbCbiUfiDevShutDown     (    int errCode                  /* Error code - reason for shutdown */    )    {    pUSB_CBI_UFI_DEV pCbiUfiDev;    pATTACH_REQUEST  pRequest;    if (initCount == 0)        return ossStatus (S_usbCbiUfiDevLib_NOT_INITIALIZED);    /* release any UFI devices */    while ((pCbiUfiDev = usbListFirst (&cbiUfiDevList)) != NULL)        usbCbiUfiDevDestroy (pCbiUfiDev);     /* Dispose of any outstanding notification requests */    while ((pRequest = usbListFirst (&reqList)) != NULL)        {      	usbListUnlink (&pRequest->reqLink);        OSS_FREE (pRequest);         }      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));     }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);        }    }STATUS usbCbiUfiDevIoctl    (    BLK_DEV * pBlkDev,           /* pointer to MSC/CBI/UFI device */    UINT32 request,	         /* request type                  */    UINT32 someArg		         /* arguments related to request  */    )    {    pUSB_CBI_UFI_DEV  pCbiUfiDev = (USB_CBI_UFI_DEV *)pBlkDev;       if ( pCbiUfiDev == (pUSB_CBI_UFI_DEV)NULL )        return (ERROR);    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);    } 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 

⌨️ 快捷键说明

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