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

📄 usbdlib.c

📁 This the USB source code for vxworks5.5. It has OSS library source code and also the complete targ
💻 C
📖 第 1 页 / 共 5 页
字号:
/* usbdLib.c - USBD functional interface *//* Copyright 2000-2001 Wind River Systems, Inc. *//*Modification history--------------------01f,18sep01,wef  merge from wrs.tor2_0.usb1_1-f for veloce01e,08aug01,dat  Removing warnings01d,26jan00,rcb  Redefine <bandwidth> parameter to usbdPipeCreate() to		 express the number of bytes per second or bytes per frame		 depending on type of pipe.01c,29nov99,rcb  Increase frame number fields to 32-bits in 		 usbdCurrentFrameGet().01b,07sep99,rcb  Add management callbacks and set-bus-state API.01a,03jun99,rcb  First.*//*DESCRIPTIONImplements the USBD functional interface.  Functions are provided to invokeeach of the underlying USBD URBs (request blocks).In order to use the USBD, it is first necessary to invoke usbdInitialize().Multiple calls to usbdInitialize() may be nested so long as a correspondingnumber of calls to usbdShutdown() are also made.  This allows multiple USBDclients to be written independently and without concern for coordinating theinitialization of the independent clients.After calling usbdInitialize(), a typical system will call usbdHcdAttach()at least one time in order to attach a USB HCD (Host Controller Driver) to the USBD.  The call to usbdHcdAttach() is not typically made by normal USBDclients.  Rather, this call is generally made by a "super client" or bysystem initialization code.  After the USBD has been initialized and at least one HCD has been attached,then normal USBD operation may begin.  Normal USBD clients must registerwith the USBD by calling usbdClientRegister().	In response to this call, theUSBD allocates per-client data structures and a client callback task.Callbacks for each client are invoked from this client-unique task.  Thisimproves the USBD's ability to shield clients from one-another and to helpensure the real-time response for all clients.After a client has registered, it will most often also register for dynamicattachment notification using usbdDynamicAttachRegister().  This functionallows a special client callback routine to be invoked each time a USB deviceis attached or removed from the system.  In this way, clients may discover thereal-time attachment and removal of devices.Finally, clients may use a combination of the USBD configuration and transferfunctions to configure and exchange data with USB devices.*//* includes */#include "usb/usbPlatform.h"#include "string.h"#include "usb/ossLib.h" 	/* OS services */#include "usb/usbQueueLib.h"#include "usb/usbdLib.h"	/* our API */#include "usb/usbdCoreLib.h"	/* interface to USBD core library *//* defines */#define MAX_SYNCH_SEM	    8		/* Max simultaneous requests which */					/* can be synchronized */#define SYNCH_SEM_TIMEOUT   1000	/* Time to wait for synch sem to be */					/* released during shutdown *//* locals */LOCAL int initCount = 0;		/* init nesting count */LOCAL BOOL ossInitialized = FALSE;	/* TRUE if we initialized ossLib */LOCAL BOOL coreLibInitialized = FALSE;	/* TRUE if we initialized usbdCoreLib */LOCAL QUEUE_HANDLE semPoolQueue = NULL; /* pool of synchronizing semaphores *//***************************************************************************** urbInit - Initialize a URB** Initialize the caller's URB to zeros, then store the <clientHandle>,* <function>, <callback>, <userPtr>, and <totalLen> fields passed by the* caller.** RETURNS: N/A*/LOCAL VOID urbInit    (    pURB_HEADER pUrb,			/* Clients URB */    USBD_CLIENT_HANDLE clientHandle,	/* Client handle */    UINT16 function,			/* USBD function code for header */    URB_CALLBACK callback,		/* Completion callback routine */    pVOID userPtr,			/* User-defined pointer */    UINT16 totalLen			/* Total len of URB to be allocated */    )    {    memset (pUrb, 0, totalLen);    pUrb->handle = clientHandle;    pUrb->function = function;    pUrb->callback = callback;    pUrb->userPtr = userPtr;    pUrb->urbLength = totalLen;    }/***************************************************************************** urbCallback - Internal callback used for asynchronous USBD functions** This callback will be used by urbExecBlock() as the URB_HEADER.callback* routine when urbExecBlock() executes an asynchronous USBD function.* By convention, the URB_HEADER.userPtr field will contain the SEM_HANDLE* of a semaphore which should be signalled.** RETURNS: N/A*/LOCAL VOID urbCallback    (    pVOID pUrb				/* Completed URB */    )    {    OSS_SEM_GIVE ((SEM_HANDLE) ((pURB_HEADER) pUrb)->userPtr);    }/***************************************************************************** urbExecBlock - Block on the execution of the caller's URB** Execute the <pUrb> passed by the caller and block until execution* completes. ** RETURNS: OK, or ERROR if error detected while trying to execute URB*/LOCAL STATUS urbExecBlock    (    pURB_HEADER pUrb			/* Caller's URB */    )    {    USB_MESSAGE msg;        /* Have we been initialized? */    if (initCount == 0)	return ossStatus (S_usbdLib_NOT_INITIALIZED);    /* Get a semaphore from the pool of synchronization semaphores to be     * used for this URB.     */    if (usbQueueGet (semPoolQueue, &msg, OSS_BLOCK) != OK)	return ossStatus (S_usbdLib_OUT_OF_RESOURCES);    /* msg.lParam is an available SEM_HANDLE. */    pUrb->callback = urbCallback;    pUrb->userPtr = (pVOID) msg.lParam;    if (usbdCoreEntry (pUrb) == OK)	{	/* wait for the URB to complete */	OSS_SEM_TAKE ((SEM_HANDLE) msg.lParam, OSS_BLOCK);	}    else	{	/* If the USBD reported an error, we don't know if the URB	 * callback was invoked or not (depends on how bad an error	 * the USBD detected, e.g., malformed URB).  So, we need to	 * make sure the semaphore is returned to the cleared state	 * before we put it back on the queue.	 */	OSS_SEM_TAKE ((SEM_HANDLE) msg.lParam, OSS_DONT_BLOCK);	}    usbQueuePut (semPoolQueue, 0, 0, msg.lParam, OSS_BLOCK);    return (pUrb->result == OK) ? OK : ERROR;    }/***************************************************************************** usbdInitialize - Initialize the USBD** usbdInitialize() must be called at least once prior to calling other* USBD functions.  usbdInitialize() prepares the USBD to process URBs.* Calls to usbdInitialize() may be nested, allowing multiple USBD clients* to be written independently.** RETURNS: OK, or ERROR if initialization failed.** ERRNO:*  S_usbdLib_GENERAL_FAULT*  S_usbdLib_OUT_OF_RESOURCES*  S_usbdLib_INTERNAL_FAULT*/STATUS usbdInitialize (void)    {    URB_CLIENT_UNREG urb;    SEM_HANDLE semHandle;    STATUS s = OK;    int i;    /* If not already initialized... */    if (++initCount == 1)	{	/* Initialize osServices */	if (ossInitialize () != OK)	    {	    s = ossStatus (S_usbdLib_GENERAL_FAULT);	    }	else	    {	    ossInitialized = TRUE;	    /* Create a pool of semaphores which will be used to synchronize 	     * URB completion. */	    if (usbQueueCreate (MAX_SYNCH_SEM, &semPoolQueue) != OK)		{		s = ossStatus (S_usbdLib_OUT_OF_RESOURCES);		}	    else		{		for (i = 0; s == OK && i < MAX_SYNCH_SEM; i++)		    {		    if (OSS_SEM_CREATE (1, 0, &semHandle) != OK ||			usbQueuePut (semPoolQueue, 0, 0, (UINT32) semHandle,			    OSS_DONT_BLOCK) != OK)			{			s = ossStatus (S_usbdLib_INTERNAL_FAULT);			}		    }		/* Initialize USBD core library */		if (s == OK)		    {		    urbInit (&urb.header, NULL, USBD_FNC_INITIALIZE, NULL, NULL,			sizeof (urb));		    if ((s = urbExecBlock (&urb.header)) == OK)			{			coreLibInitialized = TRUE;			}		    }		}	    }	}    if (s != OK)	usbdShutdown ();    return s;    }/***************************************************************************** usbdShutdown - Shuts down the USBD** usbdShutdown() should be called once for every successful call to * usbdInitialize().  This function frees memory and other resources used* by the USBD.** RETURNS: OK, or ERROR if shutdown failed.** ERRNO:*  S_usbdLib_NOT_INITIALIZED*/STATUS usbdShutdown (void)    {    URB_CLIENT_UNREG urb;    USB_MESSAGE msg;    STATUS s = OK;    int i;    if (initCount == 0)	{	/* Not initialized */	s = ossStatus (S_usbdLib_NOT_INITIALIZED);	}    else	{	/* We've been initialized at least once. */	if (initCount == 1)	    {	    if (coreLibInitialized)		{		/* Execute Shutdown URB */		urbInit (&urb.header, NULL, USBD_FNC_SHUTDOWN, NULL, NULL,		    sizeof (urb));		urbExecBlock (&urb.header);		coreLibInitialized = FALSE;		}	    if (semPoolQueue != NULL)		{		for (i = 0; i < MAX_SYNCH_SEM &&		    usbQueueGet (semPoolQueue, &msg, SYNCH_SEM_TIMEOUT) == OK; 		    i++)		    {		    OSS_SEM_DESTROY ((SEM_HANDLE) msg.lParam); 		    }		usbQueueDestroy (semPoolQueue);		semPoolQueue = NULL;		}	    if (ossInitialized)		{		/* Shut down osServices library */		ossShutdown ();		ossInitialized = FALSE;		}	    }	--initCount;	}    return s;    }/***************************************************************************** usbdClientRegister - Registers a new client with the USBD** This routine invokes the USBD function to register a new client.  * <pClientName> should point to a string of not more than USBD_NAME_LEN * characters (excluding terminating NULL) which can be used to uniquely * identify the client.	If successful, upon return the <pClientHandle>* will be filled with a newly assigned USBD_CLIENT_HANDLE.** RETURNS: OK, or ERROR if unable to register new client.*/STATUS usbdClientRegister     (    pCHAR pClientName,			/* Client name */    pUSBD_CLIENT_HANDLE pClientHandle	/* Client hdl returned by USBD */    )    {    URB_CLIENT_REG urb;    STATUS s;        /* Initialize URB */    urbInit (&urb.header, 0, USBD_FNC_CLIENT_REG, NULL, NULL, sizeof (urb));        if (pClientName != NULL)	strncpy (urb.clientName, pClientName, USBD_NAME_LEN);    /* Execute URB */    s = urbExecBlock (&urb.header);    /* Return result */    if (pClientHandle != NULL)	*pClientHandle = urb.header.handle;    return s;    }/***************************************************************************** usbdClientUnregister - Unregisters a USBD client** A client invokes this function to release a previously assigned * USBD_CLIENT_HANDLE.  The USBD will release all resources allocated to * the client, aborting any outstanding URBs which may exist for the client.  ** Once this function has been called with a given clientHandle, the client* must not attempt to reuse the indicated <clientHandle>.** RETURNS: OK, or ERROR if unable to unregister client.*/STATUS usbdClientUnregister    (    USBD_CLIENT_HANDLE clientHandle	/* Client handle */    )    {    URB_CLIENT_UNREG urb;    /* Initialize URB */    urbInit (&urb.header, clientHandle, USBD_FNC_CLIENT_UNREG, NULL, NULL,	sizeof (urb));    /* Execute URB */

⌨️ 快捷键说明

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