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

📄 usbmpc5200sffdevlib.c

📁 MPC5200 BSP 支持ATA,USB, I2C,扩展网口
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 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 "dosFsLib.h"

#include "usb/usbPlatform.h"
#include "usb/ossLib.h"	            
#include "usb/usb.h"	            
#include "usb/usbListLib.h"         
#include "usb/usbdLib.h"           
#include "usb/usbLib.h"	           

#include "usbSFFBulkDevLib.h"


/* defines */

#define USB_SFF_DEBUG_MSG        0x01
#define USB_SFF_DEBUG_ERR        0x02

#define USB_SFF_BULK_DEBUG                  \
        if (usbSFFBulkDebug & USB_SFF_DEBUG_MSG)   \
            logMsg

#define USB_SFF_BULK_ERR                    \
        if (usbSFFBulkDebug & USB_SFF_DEBUG_ERR)   \
            logMsg

#define USB_SFF_BULK_OFFS  1000

typedef struct usbSFFBulkDev
    {
    BLK_DEV           blkDev;         /* Vxworks block device structure */
                                      /* Must be the first one          */
    USBD_NODE_ID      bulkDevId;      /* 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             */
    USBD_PIPE_HANDLE  outPipeHandle;  /* Pipe handle for Bulk out EP    */
    USBD_PIPE_HANDLE  inPipeHandle;   /* Pipe handle for Bulk in 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 reading status    */ 
    UINT8             maxLun;         /* Max. number of LUN supported   */
    USB_SFF_BULK_CBW      bulkCbw;        /* Structure for Command block    */
    USB_SFF_BULK_CSW      bulkCsw;        /* Structure for Command status   */
    UINT8 *           bulkInData;     /* Pointer for bulk-in data       */
    UINT8 *           bulkOutData;    /* Pointer for bulk-out data      */   
    UINT32            numBlks;	      /* Number of blocks on device     */	 
    UINT32            blkOffset;      /* Offset of the starting block   */
    UINT16            lockCount;      /* Count of times structure locked*/
    BOOL              connected;      /* TRUE if USB_SFF_BULK device connected */    
    LINK              bulkDevLink;    /* Link to other USB_SFF_BULK devices    */  
    BOOL              read10Able;     /* Which read/write command the device  */
				      /* supports.  If TRUE, the device uses  */
				      /* READ10/WRITE10, if FALSE uses READ12 / */
				      /* WRITE12 */
    } USB_SFF_BULK_DEV, *pUSB_SFF_BULK_DEV;    

typedef struct attach_sff_request
    {
    LINK reqLink;                       /* linked list of requests */
    USB_SFF_BULK_ATTACH_CALLBACK callback;  /* client callback routine */
    pVOID callbackArg;                  /* client callback argument*/
    } ATTACH_SFF_REQUEST, *pATTACH_SFF_REQUEST;

/* globals */

BOOL usbSFFBulkDebug =  0;

/* locals */

LOCAL UINT16 initSFFCount = 0;           /* Count for Bulk device initialisation */

LOCAL USBD_CLIENT_HANDLE usbdSFFHandle;  /* Handle for this class driver */

LOCAL LIST_HEAD sffbulkDevList;          /* linked list of USB_SFF_BULK_DEV */

LOCAL LIST_HEAD    sffreqList;           /* Attach callback request list */

MUTEX_HANDLE sffbulkDevMutex;      /* mutex used to protect internal structs */

SEM_HANDLE   sffbulkIrpSem;        /* Semaphore for IRP Synchronisation */

LOCAL UINT32 usbSFFBulkIrpTimeOut = USB_SFF_BULK_IRP_TIME_OUT; /* Time out for IRP */

/* forward declarations */

LOCAL  STATUS usbSFFBulkDescShow (USBD_NODE_ID nodeId);
LOCAL  STATUS usbSFFBulkConfigDescShow  (USBD_NODE_ID nodeId, UINT8 index);
LOCAL  STATUS usbSFFBulkPhysDevCreate (USBD_NODE_ID nodeId, UINT16 config, 
                                    UINT16 interface);
LOCAL  pUSB_SFF_BULK_DEV usbSFFBulkDevFind (USBD_NODE_ID nodeId);
LOCAL  STATUS usbSFFBulkDevBlkRd (BLK_DEV *blkDev, int offset, int num, 
			       char * buf);
LOCAL  STATUS usbSFFBulkDevBlkWrt (BLK_DEV *blkDev, int offset, int num, 
				char * buf);
LOCAL  STATUS usbSFFBulkDevStatusChk (BLK_DEV *blkDev);
LOCAL  STATUS usbSFFBulkDevReset (BLK_DEV *blkDev);
LOCAL  void   usbSFFBulkIrpCallback (pVOID p);
LOCAL  STATUS usbSFFBulkFormSFFCmd (pUSB_SFF_BULK_DEV pBulkDev, UINT SFFCmd, 
                                  UINT cmdParam1, UINT cmdParam2);
                                   
LOCAL  USB_COMMAND_STATUS usbSFFBulkCmdExecute (pUSB_SFF_BULK_DEV pBulkDev);
LOCAL  void   usbSFFBulkDevDestroy (pUSB_SFF_BULK_DEV pBulkDev);
LOCAL  STATUS usbSFFBulkDevResetRecovery (pUSB_SFF_BULK_DEV  pBulkDev);
LOCAL  VOID notifySFFAttach (USBD_NODE_ID nodeId, UINT16 attachCode);

LOCAL VOID usbSFFBulkDevAttachCallback
    (
    USBD_NODE_ID nodeId,         /* USBD Node ID of the device attached */
    UINT16       attachAction,   /* Whether device attached / detached */
    UINT16       configuration,  /* Configur'n value for  MSC/SFF/BULK-ONLY */
    UINT16       interface,      /* Interface number for  MSC/SFF/BULK-ONLY */
    UINT16       deviceClass,    /* Interface class   - 0x8  for MSC */
    UINT16       deviceSubClass, /* Device sub-class  - 0x5  for SFF8070i 
				  * command 
				  */ 
    UINT16       deviceProtocol  /* Interfaceprotocol - 0x50 for Bulk only */ 
    )
    {
    pUSB_SFF_BULK_DEV  pBulkDev;     /* Pointer to bulk device,in case of 
				  * removal 
				  */
		USB_SFF_BULK_DEBUG ("usbSFFBulkDevAttachCallback: deviceClass = %d, " \
                            "deviceSubClass = %d, deviceSubClass = %d \n", deviceClass,
                            deviceSubClass, deviceProtocol, 0, 0, 0); 

    OSS_MUTEX_TAKE (sffbulkDevMutex, OSS_BLOCK);
 
    switch (attachAction)
        { 
        case USBD_DYNA_ATTACH: 

            /* MSC/SFF/BULK-ONLY Device attached */

            /* Check out whether we already have a structure for this device */

            if (usbSFFBulkDevFind (nodeId) != NULL)
                break;

            USB_SFF_BULK_DEBUG ("usbSFFBulkDevAttachCallback : New Bulk-only device "\
                            "attached\n", 0, 0, 0, 0, 0, 0);

            USB_SFF_BULK_DEBUG ("usbSFFBulkDevAttachCallback: Configuration = %d, " \
                            "Interface = %d, Node Id = %d \n", configuration,
                            interface, (UINT)nodeId, 0, 0, 0); 

            /* create a USB_SFF_BULK_DEV structure for the device attached */
           
            if ( usbSFFBulkPhysDevCreate (nodeId, configuration,interface) != OK )
                {
                USB_SFF_BULK_ERR ("usbSFFBulkDevAttachCallback : Error creating Bulk"\
                              "device\n", 0, 0, 0, 0, 0, 0);
                break; 
                } 

            /* Notify registered callers that a USB_SFF_BULK_DEV has been added */

	    notifySFFAttach (nodeId, USB_SFF_BULK_ATTACH); 
 
            break;

        case USBD_DYNA_REMOVE:

            /* MSC/SFF/BULK-ONLY Device detached */

            if ((pBulkDev = usbSFFBulkDevFind (nodeId)) == NULL)
                break;

            /* Check the connected flag  */

            if (pBulkDev->connected == FALSE)
                break;
            
            pBulkDev->connected = FALSE;

	    /* Notify registered callers that the SFF/BULK-ONLY device has 
             * been removed 
	     *
	     * NOTE: We temporarily increment the device's lock count
	     * to prevent usbSFFBulkDevUnlock() from destroying the
	     * structure while we're still using it.
	     */

            pBulkDev->lockCount++; 

            notifySFFAttach (pBulkDev->bulkDevId, USB_SFF_BULK_REMOVE); 

            pBulkDev->lockCount--; 
           
            if (pBulkDev->lockCount == 0) 
                usbSFFBulkDevDestroy (pBulkDev); 

            USB_SFF_BULK_DEBUG ("usbSFFBulkDevAttachCallback : Bulk only Mass \
			     storage device detached\n", 0, 0, 0, 0, 0, 0);

            break;

        default :
            break; 
        }

    OSS_MUTEX_RELEASE (sffbulkDevMutex);  
    }


STATUS usbSFFBulkDevShutDown 
    (
    int   errCode                /* Error code - reason for shutdown */
    )
    {

    pUSB_SFF_BULK_DEV pBulkDev;      /* Pointer to bulk device */
    pATTACH_SFF_REQUEST  pRequest;

    if (initSFFCount == 0)
        return ossStatus (S_usbSFFBulkDevLib_NOT_INITIALIZED);

    /* release any bulk devices */

    while ((pBulkDev = usbListFirst (&sffbulkDevList)) != NULL)
        usbSFFBulkDevDestroy (pBulkDev); 

    /* Dispose of any outstanding notification requests */

    while ((pRequest = usbListFirst (&sffreqList)) != NULL)
        {
      	usbListUnlink (&pRequest->reqLink);
        OSS_FREE (pRequest); 
        }

    /* 
     * Unregister with the USBD. USBD will automatically release any pending
     * IRPs or attach requests.
     */

    if (usbdSFFHandle != NULL)
        {
        usbdClientUnregister (usbdSFFHandle);
        usbdSFFHandle = NULL;
        USB_SFF_BULK_DEBUG ("usbSFFBulkDevShutDown : Bulk Only class driver "\
                        "unregistered \n", 0, 0, 0, 0, 0, 0);
        }

    /* release resources */

    if (sffbulkDevMutex != NULL)
        {
        OSS_MUTEX_DESTROY (sffbulkDevMutex);
        sffbulkDevMutex = NULL;
        }

    if (sffbulkIrpSem != NULL)
        {
        OSS_SEM_DESTROY (sffbulkIrpSem);
        sffbulkIrpSem = NULL;
        }

    initSFFCount--; 
   
    return ossStatus (errCode); 
    }


STATUS usbSFFBulkDevInit (void)
    {

    /* 
     * Check whether already initilized. If not, then initialise the required
     * structures and register the class driver with USBD.
     */

    if (initSFFCount == 0)
        {

        memset (&sffbulkDevList, 0, sizeof (sffbulkDevList));
        memset (&sffreqList, 0, sizeof (sffreqList));
        sffbulkDevMutex = NULL;
        sffbulkIrpSem   = NULL;
        usbdSFFHandle   = NULL;


        if (OSS_MUTEX_CREATE (&sffbulkDevMutex) != OK)
            return (usbSFFBulkDevShutDown (S_usbSFFBulkDevLib_OUT_OF_RESOURCES));

        if (OSS_SEM_CREATE (1, 1 , &sffbulkIrpSem) != OK)
            return (usbSFFBulkDevShutDown (S_usbSFFBulkDevLib_OUT_OF_RESOURCES));

        /* Establish connection to USBD and register for attach callback */

        if (usbdClientRegister ("BULK_CLASS_SFF", &usbdSFFHandle) != OK ||
            usbdDynamicAttachRegister (usbdSFFHandle, USB_CLASS_MASS_STORAGE,
                                       USB_SUBCLASS_SFF_COMMAND_SET, 
                                       USB_INTERFACE_PROTOCOL_BULK_ONLY,
                                       usbSFFBulkDevAttachCallback) != OK)
            {
            USB_SFF_BULK_ERR ("usbSFFBulkDevInit: Client Registration Failed \n",
                          0, 0, 0, 0, 0, 0); 
            return usbSFFBulkDevShutDown (S_usbSFFBulkDevLib_USBD_FAULT);
            }
        }

    initSFFCount++;

    return (OK);
    }

STATUS usbSFFBulkDevIoctl
    (
    BLK_DEV * pBlkDev,           /* pointer to bulk device       */
    int request,                 /* request type                 */
    int someArg                  /* arguments related to request */
    )
    {
    UINT16 actLen= 0xffff;       

    /* get a pointer to the bulk device */

    pUSB_SFF_BULK_DEV  pBulkDev = (USB_SFF_BULK_DEV *)pBlkDev;   

    if ( pBulkDev == (pUSB_SFF_BULK_DEV)NULL )
        return (ERROR);

    /* Check whether the device exists or not */

    if (usbSFFBulkDevFind (pBulkDev->bulkDevId) != pBulkDev)
        {
        USB_SFF_BULK_ERR ("usbSFFBulkDevIoctl: Bulk Device not found\n", 
                        0, 0, 0, 0, 0, 0);
        return (ERROR);
        }

    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 ( usbSFFBulkFormSFFCmd (pBulkDev, 
				     USB_SFF_FORMAT_UNIT, 
				     NULL, 
				     NULL) 
				   != OK )
                return (ERROR); 

            if ( usbSFFBulkCmdExecute (pBulkDev) != USB_COMMAND_SUCCESS )
                {
                USB_SFF_BULK_ERR ("usbSFFBulkDevIoctl: FORMAT UNIT Command failed\n", 
                              0, 0, 0, 0, 0, 0);  
                return (ERROR); 
                }   
                
            return (OK);

        case USB_SFF_BULK_DESCRIPTOR_GET:

            /* invoke routine to display all descriptors */

            return (usbSFFBulkDescShow (pBulkDev->bulkDevId));

        case USB_SFF_BULK_DEV_RESET:

            /* send a class-specific mass storage reset command */
             
            return (usbSFFBulkDevResetRecovery (pBulkDev));

⌨️ 快捷键说明

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