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

📄 usbloopbacklib.c

📁 VxWorks BSP for S3C2510A
💻 C
📖 第 1 页 / 共 4 页
字号:
/* usbLoopbackLib.c - USB Loopback class driver *//* Copyright 2002 SAMSUNG ELECTRONICS *//*modification history--------------------01a,3Oct2003,Ajay Raj Sharma created.*//*DESCRIPTIONThis module implements the USB Loopback class driver for the vxWorks operatingsystem.This module handles the loopback devices which reports thier device class,subclass and protocol as follows:device class:    0xABdevice sublass:  0xCDdevice protocol tells types of loopback data transfers supported by the deviceControl loopback     : 0x01Bulk loopback        : 0x02Interrupt loopback   : 0x04Isochronous loopback : 0x08These corresponding protocol codes must ORed if the device supports multiple type of loopback data transfers.Bits other than 0-3 bits of protocol code are reserved and must be set to zero.This module itself is a client of the Universal Serial Bus Driver (USBD).  Allinteraction with the USB buses and devices is handled through the USBD.INITIALIZATIONThis driver must be initialized by callingusbLoopbackDevInit().  usbLoopbackDevInit() in turn initializes itsconnection to the USBD and other internal resources needed for operation.  Prior to calling usbLoopbackDevInit(), the caller must ensure that the USBDhas been properly initialized by calling - at a minimum - usbdInitialize().It is also the caller's responsibility to ensure that at least one USB HCD(USB Host Controller Driver) is attached to the USBD - using the USBD functionusbdHcdAttach() - before Loopback operation can begin.  However, it is not necessary for usbdHcdAttach() to be alled prior to initializating usbLoopbackLib.c.usbLoopbackLib.c uses the USBD dynamic attach services and is capable of recognizing USB Loopback attachment and removal on the fly.  Therefore, it is possible for USB HCDs to be attached to or detached from the USBD at run time- as may be required, for example, in systems supporting hot swapping ofhardware.OTHER FUNCTIONSDATA FLOWINCLUDE FILES:usbLoopbackLib.h*//* includes */#include "vxWorks.h"#include "string.h"#include "errno.h"#include "ctype.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 "usbLoopbackLib.h"  /* our API *//* defines */#define DEBUG 1#define USB_LOOPBACK_CLIENT_NAME     "usbLoopbackLib" /* our USBD client name */#define USB_LOOPBACK_TIMEOUT  20000	/* 20 second timeout */#define USB_LOOPBACK_CONTROL_WRITE 0xF0#define USB_LOOPBACK_CONTROL_READ  0xF1/*  * Following Parameters are used for bandwidth requirement  * for interrupt and isochronous endpoints  */#define USB_LOOPBACK_DEFAULT_BANDWIDTH_INT_IN    32 /* Number of bytes to be transferres per frame */#define USB_LOOPBACK_DEFAULT_BANDWIDTH_INT_OUT   32 /* Number of bytes to be transferres per frame */#define USB_LOOPBACK_DEFAULT_BANDWIDTH_ISOCH_IN  4096 /* Number of bytes to be transferres per second */#define USB_LOOPBACK_DEFAULT_BANDWIDTH_ISOCH_OUT 4096 /* Number of bytes to be transferres per second *//* Buffer Sizes required for data transfers *//* typedefs *//* * ATTACH_REQUEST */typedef struct attach_request    {    LINK reqLink;			/* linked list of requests */    USB_LOOPBACK_ATTACH_CALLBACK callback;	/* client callback routine */    pVOID callbackArg;			/* client callback argument */    } ATTACH_REQUEST, *pATTACH_REQUEST;/* USB_LOOPBACK_DEVICE is the internal data structure we use to track each USB * Loopback device. */typedef struct USB_LOOPBACK_DEVICE    {    USB_LOOPBACK_CHAN loopbackChan;		/* must be first field */    LINK loopbackLink;		/* linked list of Loopback structs */    UINT16 lockCount;		/* Count of times structure locked */    BOOL connected;		/* TRUE if Loopback currently connected */    USBD_NODE_ID nodeId;	/* Loopback node Id */    UINT16 configuration;	/* configuration/interface reported as */    UINT16 interface;		/* a Loopback by this device */    UINT8 alternateSetting;        UINT16 protocol;		/* protocol reported by device */    BOOL ctrlLoopbackInProgress;		/* TRUE while control loopback is outstanding */    BOOL bulkLoopbackInProgress;		/* TRUE while bulk loopback is outstanding */    BOOL intLoopbackInProgress;		/* TRUE while int loopback is outstanding */    BOOL isochLoopbackInProgress;		/* TRUE while isoch loopback is outstanding */    SEM_HANDLE   bulkLoopbackSem;        /* Semaphore for IRP Synchronisation */    SEM_HANDLE   intLoopbackSem;        /* Semaphore for IRP Synchronisation */    SEM_HANDLE   isochLoopbackSem;        /* Semaphore for IRP Synchronisation */        UINT16   bulkOutEpAddress;   /* Bulk out EP address */    UINT16   bulkInEpAddress;    /* Bulk in EP address */    UINT16   intOutEpAddress;   /* Int out EP address */    UINT16   intInEpAddress;    /* Int in EP address */    UINT16   isochOutEpAddress;   /* Isoch out EP address */    UINT16   isochInEpAddress;    /* Isoch in EP address */    USBD_PIPE_HANDLE bulkOutPipeHandle; /* USBD pipe handle for bulk OUT pipe */    USBD_PIPE_HANDLE intOutPipeHandle; /* USBD pipe handle for interrupt OUT pipe */    USBD_PIPE_HANDLE isochOutPipeHandle; /* USBD pipe handle for isoch OUT pipe */        USBD_PIPE_HANDLE bulkInPipeHandle;  /* USBD pipe handle for bulk IN pipe */    USBD_PIPE_HANDLE intInPipeHandle; /* USBD pipe handle for interrupt OUT pipe */    USBD_PIPE_HANDLE isochInPipeHandle; /* USBD pipe handle for isoch OUT pipe */    USB_IRP bulkOutIrp;		/* IRP to transmit bulk output data */    USB_IRP intOutIrp;		/* IRP to transmit interrupt output data */    USB_IRP isochOutIrp;		/* IRP to transmit isoch output data */    USB_IRP bulkInIrp;		/* IRP to receive bulk data */    USB_IRP intInIrp;		/* IRP to receive interrupt data */    USB_IRP isochInIrp;		/* IRP to receive isoch data */    USB_LOOPBACK_STAT deviceStat; /* device stats */    } USB_LOOPBACK_DEVICE, *pUSB_LOOPBACK_DEVICE;/* forward static declarations */LOCAL int usbLoopbackCtrl(USB_LOOPBACK_CHAN *pChan,char *outBfr,                          char *inBfr,int loopbackLen,int iteration);LOCAL int usbLoopbackBulk(USB_LOOPBACK_CHAN *pChan,char *outBfr,                          char *inBfr,int loopbackLen,int iteration);LOCAL int usbLoopbackInt(USB_LOOPBACK_CHAN *pChan,char *outBfr,                          char *inBfr,int loopbackLen,int iteration);LOCAL int usbLoopbackIsoch(USB_LOOPBACK_CHAN *pChan,char *outBfr,                           char *inBfr,int loopbackLen,int iteration);LOCAL int usbLoopbackIoctl (USB_LOOPBACK_CHAN *pChan, int request, void *arg);LOCAL VOID usbLoopbackIrpCallback (pVOID p);/* locals */LOCAL UINT16 initCount = 0;	/* Count of init nesting */LOCAL MUTEX_HANDLE loopbackMutex;	/* mutex used to protect internal structs */LOCAL LIST_HEAD loopbackList;	/* linked list of USB_LOOPBACK_DEVICE */LOCAL LIST_HEAD reqList;	/* Attach callback request list */LOCAL USBD_CLIENT_HANDLE usbdHandle; /* our USBD client handle *//* Channel function table. */LOCAL USB_LOOPBACK_DRV_FNC usbLoopbackDrvFuncs =    {    usbLoopbackCtrl,    usbLoopbackBulk,    usbLoopbackInt,    usbLoopbackIsoch,    usbLoopbackIoctl    };/***************************************************************************** usbLoopbackIrpCallback - Invoked upon IRP completion/cancellation** Examines the cause of the IRP completion.*/LOCAL VOID usbLoopbackIrpCallback    (    pVOID p	    /* completed IRP */    )    {    pUSB_IRP pIrp = (pUSB_IRP) p;    pUSB_LOOPBACK_DEVICE pLoopbackDev = pIrp->userPtr;       /* OSS_MUTEX_TAKE (loopbackMutex, OSS_BLOCK); */    /* if IRP for bulk out endpoint */    if (pIrp == &(pLoopbackDev->bulkOutIrp))    {        if (pIrp->result != OK)     /* check the result of IRP */        {            printf("Bulk out callback pIrp->result is %d \n",pIrp->result);            /* Clear HALT Feature on Bulk out Endpoint */            if ((usbdFeatureClear (usbdHandle,				   pLoopbackDev->nodeId,				   USB_RT_ENDPOINT,				   USB_FSEL_DEV_ENDPOINT_HALT,				   (pLoopbackDev->bulkOutEpAddress & 0x0F)))				 != OK)                {                printf("usbBulkIrpCallback: Failed to clear HALT on bulk OUT\n" );                }        }        OSS_SEM_GIVE (pLoopbackDev->bulkLoopbackSem);    }        /* if IRP for bulk IN endpoint */    if (pIrp == &(pLoopbackDev->bulkInIrp))    {        if (pIrp->result != OK)     /* check the result of IRP */        {            printf("Bulk in callback pIrp->result is %d \n",pIrp->result);            /* Clear HALT Feature on Bulk out Endpoint */            if ((usbdFeatureClear (usbdHandle,				   pLoopbackDev->nodeId,				   USB_RT_ENDPOINT,				   USB_FSEL_DEV_ENDPOINT_HALT,				   (pLoopbackDev->bulkInEpAddress & 0x0F)))				 != OK)                {                printf("usbBulkIrpCallback: Failed to clear HALT on bulk IN\n" );                }        }        OSS_SEM_GIVE (pLoopbackDev->bulkLoopbackSem);    }    /* if IRP for int out endpoint */    if (pIrp == &(pLoopbackDev->intOutIrp))    {        if (pIrp->result != OK)     /* check the result of IRP */        {            printf("Int out callback pIrp->result is %d \n",pIrp->result);            /* Clear HALT Feature on Bulk out Endpoint */            if ((usbdFeatureClear (usbdHandle,				   pLoopbackDev->nodeId,				   USB_RT_ENDPOINT,				   USB_FSEL_DEV_ENDPOINT_HALT,				   (pLoopbackDev->intOutEpAddress & 0x0F)))				 != OK)                {                printf("usbBulkIrpCallback: Failed to clear HALT on int OUT\n" );                }        }        OSS_SEM_GIVE (pLoopbackDev->intLoopbackSem);    }            /* if IRP for int in endpoint */    if (pIrp == &(pLoopbackDev->intInIrp))    {        if (pIrp->result != OK)     /* check the result of IRP */        {            printf("Int in callback pIrp->result is %d \n",pIrp->result);            /* Clear HALT Feature on Bulk out Endpoint */            if ((usbdFeatureClear (usbdHandle,				   pLoopbackDev->nodeId,				   USB_RT_ENDPOINT,				   USB_FSEL_DEV_ENDPOINT_HALT,				   (pLoopbackDev->intInEpAddress & 0x0F)))				 != OK)                {                printf("usbBulkIrpCallback: Failed to clear HALT on int IN\n" );                }        }        OSS_SEM_GIVE (pLoopbackDev->intLoopbackSem);    }    /* if IRP for isoch out endpoint */    if (pIrp == &(pLoopbackDev->isochOutIrp))    {        if (pIrp->result != OK)     /* check the result of IRP */        {            printf(" Isoch out callback pIrp->result is %d \n",pIrp->result);            /* Clear HALT Feature on Bulk out Endpoint */            if ((usbdFeatureClear (usbdHandle,				   pLoopbackDev->nodeId,				   USB_RT_ENDPOINT,				   USB_FSEL_DEV_ENDPOINT_HALT,				   (pLoopbackDev->isochOutEpAddress & 0x0F)))				 != OK)                {                printf("usbBulkIrpCallback: Failed to clear HALT on isoch OUT\n" );                }        }        OSS_SEM_GIVE (pLoopbackDev->intLoopbackSem);     }            /* if IRP for isoch IN endpoint */    if (pIrp == &(pLoopbackDev->isochOutIrp))    {        if (pIrp->result != OK)     /* check the result of IRP */        {            printf("Isoch In callback pIrp->result is %d \n",pIrp->result);            /* Clear HALT Feature on Bulk out Endpoint */            if ((usbdFeatureClear (usbdHandle,				   pLoopbackDev->nodeId,				   USB_RT_ENDPOINT,				   USB_FSEL_DEV_ENDPOINT_HALT,				   (pLoopbackDev->isochInEpAddress & 0x0F)))				 != OK)                {                printf("usbBulkIrpCallback: Failed to clear HALT on isoch IN\n" );                }        }        OSS_SEM_GIVE (pLoopbackDev->intLoopbackSem);     }   /* OSS_MUTEX_RELEASE (loopbackMutex);*/}/***************************************************************************** usbLoopbackControl - initiates loopback data transmission for default * control endpoint i.e. endpoint 0** If the control loopback is not already in use, this function submits the* USB_LOOPBACK_CONTROL_WRITE and USB_LOOPBACK_CONTROL_READ commands on endpoint* 0 for requested number of times.** This function assumes that the outBfr and inBfr are allocated with enough size to* hold the loopbackLen data.Here no need of specifying the length of loopback * buffer in the first two bytes of buffer as it is taken care by setup packet.** RETURNS: OK, or ERROR if unable to initiate transmission*/LOCAL int usbLoopbackCtrl(USB_LOOPBACK_CHAN *pChan,char *outBfr,                          char *inBfr,int loopbackLen,int iteration){  pUSB_LOOPBACK_DEVICE pLoopbackDev = (pUSB_LOOPBACK_DEVICE) pChan;  UINT16 count;  int status = ERROR;  UINT16 actLen = 0;  UINT32 ctrlOutErrors =0;  UINT32 ctrlInErrors =0;  UINT32 ctrlPacketMismatch =0;  /* Return if control looop back is not supported on the device */  if (! USB_IS_CTRL_LOOPBACK_SUPPORTED(pLoopbackDev->protocol))  {     printf("Control loopback is not supported on the device!!!\n");     return ENOSYS;  }  /* if we are requested for zero len control transfer */  if (loopbackLen != 0 )  {    /* validate the loopback buffer */    if ((outBfr  == NULL) ||(inBfr  == NULL))    {    	printf ("Invalid control loopback buffers!!\n" );    	return S_usbLoopbackLib_BAD_PARAM;    }  }    if (loopbackLen > USB_LOOPBACK_MAX_LEN)  {    loopbackLen = USB_LOOPBACK_MAX_LEN;  }    /* Return immediately if the output IRP is already in use. */  if (pLoopbackDev->ctrlLoopbackInProgress)	return OK;  /* mark the control loopback tarnsfer as in progress */  pLoopbackDev->ctrlLoopbackInProgress = TRUE;  while(iteration-- != 0)  {    status = usbdVendorSpecific (usbdHandle,                    	         pLoopbackDev->nodeId,                      		 USB_RT_HOST_TO_DEV | USB_RT_VENDOR | USB_RT_DEVICE,                      		 USB_LOOPBACK_CONTROL_WRITE,                      		 0,                      		 0,                      		 loopbackLen,                      		 (UCHAR *)outBfr,                      		 &actLen);  	if( (status != OK) || ( actLen < loopbackLen))  	{  	 ctrlOutErrors++;  	 continue;/* Continue for next iteration */  	}        actLen = 0;    status = usbdVendorSpecific (usbdHandle,                    		 pLoopbackDev->nodeId,                      		 USB_RT_DEV_TO_HOST | USB_RT_VENDOR | USB_RT_DEVICE,                      		 USB_LOOPBACK_CONTROL_READ,                      		 0,                      		 0,                      		 loopbackLen,                      		 (UCHAR *)inBfr,                      		 &actLen);  	if( (status != OK) || ( actLen < loopbackLen))  	{  	 ctrlInErrors++;  	 continue;/* Continue for next iteration */  	}    /* Match the inBfr with outBfr for equality */    for (count = 0; count < loopbackLen; count++)    {    	if( inBfr[count]!= outBfr[count])    	{    		ctrlPacketMismatch++;      }    }  }/* While loop */  printf("\nControl loopback report:\n");  printf("Control-Out errors:%d\n",ctrlOutErrors);  printf("Control-In errors:%d\n",ctrlInErrors);  printf("Control-Loopback packet mismatch:%d\n",ctrlPacketMismatch);    /* Update the stats in pLoopbackDevice */  pLoopbackDev->deviceStat.ctrlOutErrors += ctrlOutErrors;  pLoopbackDev->deviceStat.ctrlInErrors += ctrlInErrors;  pLoopbackDev->deviceStat.ctrlPacketMismatch += ctrlPacketMismatch;  pLoopbackDev->ctrlLoopbackInProgress = FALSE;  return OK;}/***************************************************************************** usbLoopbackBulk - initiates loopback data transmission for bulk endpoint.** If the bulk loopback is not already in use, this function populates the* bulkout and IN IRP with the buffer and submits the IRPs for* requested number of times.** This function assumes that the outBfr and inBfr are allocated with enough size to* hold the loopbackLen data.Also the first two bytes of buffer contains the * length of whole buffer including these length field*** RETURNS: OK, or ERROR if unable to initiate transmission*/LOCAL int usbLoopbackBulk(USB_LOOPBACK_CHAN *pChan,char *outBfr,                          char *inBfr,int loopbackLen,int iteration){  pUSB_LOOPBACK_DEVICE pLoopbackDev = (pUSB_LOOPBACK_DEVICE) pChan;  pUSB_IRP pIrp;  UINT16 count;  UINT32 bulkOutErrors =0;  UINT32 bulkInErrors =0;  UINT32 bulkPacketMismatch =0;  /* Return if Bulk looop back is not supported on the device */  if (!USB_IS_BULK_LOOPBACK_SUPPORTED(pLoopbackDev->protocol))  {    printf("Bulk loopback is not supported on the device!!!\n");    return ENOSYS;  }  /* validate the loopback buffer */  if ((outBfr == NULL) ||(inBfr == NULL))  {    printf ("Invalid bulk loopback buffers!!\n" );  	return S_usbLoopbackLib_BAD_PARAM;  }    /* Validate the length */  if(loopbackLen < 2 )  {  	printf ("Invalid bulk loopback length!!\n" );  	return S_usbLoopbackLib_BAD_PARAM;  }    if (loopbackLen > USB_LOOPBACK_MAX_LEN)  {    loopbackLen = USB_LOOPBACK_MAX_LEN;  }  

⌨️ 快捷键说明

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