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