usbdLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:72k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* usbdLib.c - USBD functional interface */
  2. /* Copyright 2000-2001 Wind River Systems, Inc. */
  3. /*
  4. Modification history
  5. --------------------
  6. 01f,18sep01,wef  merge from wrs.tor2_0.usb1_1-f for veloce
  7. 01e,08aug01,dat  Removing warnings
  8. 01d,26jan00,rcb  Redefine <bandwidth> parameter to usbdPipeCreate() to
  9.  express the number of bytes per second or bytes per frame
  10.  depending on type of pipe.
  11. 01c,29nov99,rcb  Increase frame number fields to 32-bits in 
  12.  usbdCurrentFrameGet().
  13. 01b,07sep99,rcb  Add management callbacks and set-bus-state API.
  14. 01a,03jun99,rcb  First.
  15. */
  16. /*
  17. DESCRIPTION
  18. Implements the USBD functional interface.  Functions are provided to invoke
  19. each of the underlying USBD URBs (request blocks).
  20. In order to use the USBD, it is first necessary to invoke usbdInitialize().
  21. Multiple calls to usbdInitialize() may be nested so long as a corresponding
  22. number of calls to usbdShutdown() are also made.  This allows multiple USBD
  23. clients to be written independently and without concern for coordinating the
  24. initialization of the independent clients.
  25. After calling usbdInitialize(), a typical system will call usbdHcdAttach()
  26. at least one time in order to attach a USB HCD (Host Controller Driver) to 
  27. the USBD.  The call to usbdHcdAttach() is not typically made by normal USBD
  28. clients.  Rather, this call is generally made by a "super client" or by
  29. system initialization code.  
  30. After the USBD has been initialized and at least one HCD has been attached,
  31. then normal USBD operation may begin.  Normal USBD clients must register
  32. with the USBD by calling usbdClientRegister(). In response to this call, the
  33. USBD allocates per-client data structures and a client callback task.
  34. Callbacks for each client are invoked from this client-unique task.  This
  35. improves the USBD's ability to shield clients from one-another and to help
  36. ensure the real-time response for all clients.
  37. After a client has registered, it will most often also register for dynamic
  38. attachment notification using usbdDynamicAttachRegister().  This function
  39. allows a special client callback routine to be invoked each time a USB device
  40. is attached or removed from the system.  In this way, clients may discover the
  41. real-time attachment and removal of devices.
  42. Finally, clients may use a combination of the USBD configuration and transfer
  43. functions to configure and exchange data with USB devices.
  44. */
  45. /* includes */
  46. #include "usb/usbPlatform.h"
  47. #include "string.h"
  48. #include "usb/ossLib.h"  /* OS services */
  49. #include "usb/usbQueueLib.h"
  50. #include "usb/usbdLib.h" /* our API */
  51. #include "usb/usbdCoreLib.h" /* interface to USBD core library */
  52. /* defines */
  53. #define MAX_SYNCH_SEM     8 /* Max simultaneous requests which */
  54. /* can be synchronized */
  55. #define SYNCH_SEM_TIMEOUT   1000 /* Time to wait for synch sem to be */
  56. /* released during shutdown */
  57. /* locals */
  58. LOCAL int initCount = 0; /* init nesting count */
  59. LOCAL BOOL ossInitialized = FALSE; /* TRUE if we initialized ossLib */
  60. LOCAL BOOL coreLibInitialized = FALSE; /* TRUE if we initialized usbdCoreLib */
  61. LOCAL QUEUE_HANDLE semPoolQueue = NULL; /* pool of synchronizing semaphores */
  62. /***************************************************************************
  63. *
  64. * urbInit - Initialize a URB
  65. *
  66. * Initialize the caller's URB to zeros, then store the <clientHandle>,
  67. * <function>, <callback>, <userPtr>, and <totalLen> fields passed by the
  68. * caller.
  69. *
  70. * RETURNS: N/A
  71. */
  72. LOCAL VOID urbInit
  73.     (
  74.     pURB_HEADER pUrb, /* Clients URB */
  75.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  76.     UINT16 function, /* USBD function code for header */
  77.     URB_CALLBACK callback, /* Completion callback routine */
  78.     pVOID userPtr, /* User-defined pointer */
  79.     UINT16 totalLen /* Total len of URB to be allocated */
  80.     )
  81.     {
  82.     memset (pUrb, 0, totalLen);
  83.     pUrb->handle = clientHandle;
  84.     pUrb->function = function;
  85.     pUrb->callback = callback;
  86.     pUrb->userPtr = userPtr;
  87.     pUrb->urbLength = totalLen;
  88.     }
  89. /***************************************************************************
  90. *
  91. * urbCallback - Internal callback used for asynchronous USBD functions
  92. *
  93. * This callback will be used by urbExecBlock() as the URB_HEADER.callback
  94. * routine when urbExecBlock() executes an asynchronous USBD function.
  95. * By convention, the URB_HEADER.userPtr field will contain the SEM_HANDLE
  96. * of a semaphore which should be signalled.
  97. *
  98. * RETURNS: N/A
  99. */
  100. LOCAL VOID urbCallback
  101.     (
  102.     pVOID pUrb /* Completed URB */
  103.     )
  104.     {
  105.     OSS_SEM_GIVE ((SEM_HANDLE) ((pURB_HEADER) pUrb)->userPtr);
  106.     }
  107. /***************************************************************************
  108. *
  109. * urbExecBlock - Block on the execution of the caller's URB
  110. *
  111. * Execute the <pUrb> passed by the caller and block until execution
  112. * completes. 
  113. *
  114. * RETURNS: OK, or ERROR if error detected while trying to execute URB
  115. */
  116. LOCAL STATUS urbExecBlock
  117.     (
  118.     pURB_HEADER pUrb /* Caller's URB */
  119.     )
  120.     {
  121.     USB_MESSAGE msg;
  122.     
  123.     /* Have we been initialized? */
  124.     if (initCount == 0)
  125. return ossStatus (S_usbdLib_NOT_INITIALIZED);
  126.     /* Get a semaphore from the pool of synchronization semaphores to be
  127.      * used for this URB.
  128.      */
  129.     if (usbQueueGet (semPoolQueue, &msg, OSS_BLOCK) != OK)
  130. return ossStatus (S_usbdLib_OUT_OF_RESOURCES);
  131.     /* msg.lParam is an available SEM_HANDLE. */
  132.     pUrb->callback = urbCallback;
  133.     pUrb->userPtr = (pVOID) msg.lParam;
  134.     if (usbdCoreEntry (pUrb) == OK)
  135. {
  136. /* wait for the URB to complete */
  137. OSS_SEM_TAKE ((SEM_HANDLE) msg.lParam, OSS_BLOCK);
  138. }
  139.     else
  140. {
  141. /* If the USBD reported an error, we don't know if the URB
  142.  * callback was invoked or not (depends on how bad an error
  143.  * the USBD detected, e.g., malformed URB).  So, we need to
  144.  * make sure the semaphore is returned to the cleared state
  145.  * before we put it back on the queue.
  146.  */
  147. OSS_SEM_TAKE ((SEM_HANDLE) msg.lParam, OSS_DONT_BLOCK);
  148. }
  149.     usbQueuePut (semPoolQueue, 0, 0, msg.lParam, OSS_BLOCK);
  150.     return (pUrb->result == OK) ? OK : ERROR;
  151.     }
  152. /***************************************************************************
  153. *
  154. * usbdInitialize - Initialize the USBD
  155. *
  156. * usbdInitialize() must be called at least once prior to calling other
  157. * USBD functions.  usbdInitialize() prepares the USBD to process URBs.
  158. * Calls to usbdInitialize() may be nested, allowing multiple USBD clients
  159. * to be written independently.
  160. *
  161. * RETURNS: OK, or ERROR if initialization failed.
  162. *
  163. * ERRNO:
  164. *  S_usbdLib_GENERAL_FAULT
  165. *  S_usbdLib_OUT_OF_RESOURCES
  166. *  S_usbdLib_INTERNAL_FAULT
  167. */
  168. STATUS usbdInitialize (void)
  169.     {
  170.     URB_CLIENT_UNREG urb;
  171.     SEM_HANDLE semHandle;
  172.     STATUS s = OK;
  173.     int i;
  174.     /* If not already initialized... */
  175.     if (++initCount == 1)
  176. {
  177. /* Initialize osServices */
  178. if (ossInitialize () != OK)
  179.     {
  180.     s = ossStatus (S_usbdLib_GENERAL_FAULT);
  181.     }
  182. else
  183.     {
  184.     ossInitialized = TRUE;
  185.     /* Create a pool of semaphores which will be used to synchronize 
  186.      * URB completion. */
  187.     if (usbQueueCreate (MAX_SYNCH_SEM, &semPoolQueue) != OK)
  188. {
  189. s = ossStatus (S_usbdLib_OUT_OF_RESOURCES);
  190. }
  191.     else
  192. {
  193. for (i = 0; s == OK && i < MAX_SYNCH_SEM; i++)
  194.     {
  195.     if (OSS_SEM_CREATE (1, 0, &semHandle) != OK ||
  196. usbQueuePut (semPoolQueue, 0, 0, (UINT32) semHandle,
  197.     OSS_DONT_BLOCK) != OK)
  198. {
  199. s = ossStatus (S_usbdLib_INTERNAL_FAULT);
  200. }
  201.     }
  202. /* Initialize USBD core library */
  203. if (s == OK)
  204.     {
  205.     urbInit (&urb.header, NULL, USBD_FNC_INITIALIZE, NULL, NULL,
  206. sizeof (urb));
  207.     if ((s = urbExecBlock (&urb.header)) == OK)
  208. {
  209. coreLibInitialized = TRUE;
  210. }
  211.     }
  212. }
  213.     }
  214. }
  215.     if (s != OK)
  216. usbdShutdown ();
  217.     return s;
  218.     }
  219. /***************************************************************************
  220. *
  221. * usbdShutdown - Shuts down the USBD
  222. *
  223. * usbdShutdown() should be called once for every successful call to 
  224. * usbdInitialize().  This function frees memory and other resources used
  225. * by the USBD.
  226. *
  227. * RETURNS: OK, or ERROR if shutdown failed.
  228. *
  229. * ERRNO:
  230. *  S_usbdLib_NOT_INITIALIZED
  231. */
  232. STATUS usbdShutdown (void)
  233.     {
  234.     URB_CLIENT_UNREG urb;
  235.     USB_MESSAGE msg;
  236.     STATUS s = OK;
  237.     int i;
  238.     if (initCount == 0)
  239. {
  240. /* Not initialized */
  241. s = ossStatus (S_usbdLib_NOT_INITIALIZED);
  242. }
  243.     else
  244. {
  245. /* We've been initialized at least once. */
  246. if (initCount == 1)
  247.     {
  248.     if (coreLibInitialized)
  249. {
  250. /* Execute Shutdown URB */
  251. urbInit (&urb.header, NULL, USBD_FNC_SHUTDOWN, NULL, NULL,
  252.     sizeof (urb));
  253. urbExecBlock (&urb.header);
  254. coreLibInitialized = FALSE;
  255. }
  256.     if (semPoolQueue != NULL)
  257. {
  258. for (i = 0; i < MAX_SYNCH_SEM &&
  259.     usbQueueGet (semPoolQueue, &msg, SYNCH_SEM_TIMEOUT) == OK; 
  260.     i++)
  261.     {
  262.     OSS_SEM_DESTROY ((SEM_HANDLE) msg.lParam); 
  263.     }
  264. usbQueueDestroy (semPoolQueue);
  265. semPoolQueue = NULL;
  266. }
  267.     if (ossInitialized)
  268. {
  269. /* Shut down osServices library */
  270. ossShutdown ();
  271. ossInitialized = FALSE;
  272. }
  273.     }
  274. --initCount;
  275. }
  276.     return s;
  277.     }
  278. /***************************************************************************
  279. *
  280. * usbdClientRegister - Registers a new client with the USBD
  281. *
  282. * This routine invokes the USBD function to register a new client.  
  283. * <pClientName> should point to a string of not more than USBD_NAME_LEN 
  284. * characters (excluding terminating NULL) which can be used to uniquely 
  285. * identify the client. If successful, upon return the <pClientHandle>
  286. * will be filled with a newly assigned USBD_CLIENT_HANDLE.
  287. *
  288. * RETURNS: OK, or ERROR if unable to register new client.
  289. */
  290. STATUS usbdClientRegister 
  291.     (
  292.     pCHAR pClientName, /* Client name */
  293.     pUSBD_CLIENT_HANDLE pClientHandle /* Client hdl returned by USBD */
  294.     )
  295.     {
  296.     URB_CLIENT_REG urb;
  297.     STATUS s;
  298.     
  299.     /* Initialize URB */
  300.     urbInit (&urb.header, 0, USBD_FNC_CLIENT_REG, NULL, NULL, sizeof (urb));
  301.     
  302.     if (pClientName != NULL)
  303. strncpy (urb.clientName, pClientName, USBD_NAME_LEN);
  304.     /* Execute URB */
  305.     s = urbExecBlock (&urb.header);
  306.     /* Return result */
  307.     if (pClientHandle != NULL)
  308. *pClientHandle = urb.header.handle;
  309.     return s;
  310.     }
  311. /***************************************************************************
  312. *
  313. * usbdClientUnregister - Unregisters a USBD client
  314. *
  315. * A client invokes this function to release a previously assigned 
  316. * USBD_CLIENT_HANDLE.  The USBD will release all resources allocated to 
  317. * the client, aborting any outstanding URBs which may exist for the client.  
  318. *
  319. * Once this function has been called with a given clientHandle, the client
  320. * must not attempt to reuse the indicated <clientHandle>.
  321. *
  322. * RETURNS: OK, or ERROR if unable to unregister client.
  323. */
  324. STATUS usbdClientUnregister
  325.     (
  326.     USBD_CLIENT_HANDLE clientHandle /* Client handle */
  327.     )
  328.     {
  329.     URB_CLIENT_UNREG urb;
  330.     /* Initialize URB */
  331.     urbInit (&urb.header, clientHandle, USBD_FNC_CLIENT_UNREG, NULL, NULL,
  332. sizeof (urb));
  333.     /* Execute URB */
  334.     return urbExecBlock (&urb.header);
  335.     }
  336. /***************************************************************************
  337. *
  338. * usbdMngmtCallbackSet - sets management callback for a client
  339. *
  340. * Management callbacks provide a mechanism for the USBD to inform clients
  341. * of asynchronous management events on the USB.  For example, if the USB
  342. * is in the SUSPEND state - see usbdBusStateSet() - and a USB device
  343. * drives RESUME signalling, that event can be reported to a client through
  344. * its management callback.
  345. *
  346. * <clientHandle> is a client's registered handled with the USBD.  
  347. * <mngmtCallback> is the management callback routine of type
  348. * USBD_MNGMT_CALLBACK which will be invoked by the USBD when management
  349. * events are detected. <mngmtCallbackParam> is a client-defined parameter
  350. * which will be passed to the <mngmtCallback> each time it is invoked.
  351. * Passing a <mngmtCallback> of NULL cancels management event callbacks.
  352. *
  353. * When the <mngmtCallback> is invoked, the USBD will also pass it the
  354. * USBD_NODE_ID of the root node on the bus for which the management event
  355. * has been detected and a code signifying the type of management event
  356. * as USBD_MNGMT_xxxx.
  357. *
  358. * Clients are not required to register a management callback routine.
  359. * Clients that do use a management callback are permitted to register at
  360. * most one management callback per USBD_CLIENT_HANDLE.
  361. *
  362. * RETURNS: OK, or ERROR if unable to register management callback
  363. */
  364. STATUS usbdMngmtCallbackSet
  365.     (
  366.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  367.     USBD_MNGMT_CALLBACK mngmtCallback, /* management callback */
  368.     pVOID mngmtCallbackParam /* client-defined parameter */
  369.     )
  370.     {
  371.     URB_MNGMT_CALLBACK_SET urb;
  372.     /* Initialize URB */
  373.     urbInit (&urb.header, clientHandle, USBD_FNC_MNGMT_CALLBACK_SET, NULL, 
  374. NULL, sizeof (urb));
  375.     urb.mngmtCallback = mngmtCallback;
  376.     urb.mngmtCallbackParam = mngmtCallbackParam;
  377.     /* Execute URB */
  378.     return urbExecBlock (&urb.header);
  379.     }
  380. /***************************************************************************
  381. *
  382. * usbdBusStateSet - Sets bus state (e.g., suspend/resume)
  383. *
  384. * This function allows a client to set the state of the bus to which
  385. * the specified <nodeId> is attached.  The desired <busState> is specified
  386. * as USBD_BUS_xxxx.
  387. *
  388. * Typically, a client will use this function to set a bus to the SUSPEND
  389. * or RESUME state.  Clients must use this capability with care, as it will
  390. * affect all devices on a given bus - and hence all clients communicating
  391. * with those devices.
  392. *
  393. * When setting a bus to the SUSPEND state, a client must also be aware
  394. * that the USBD will not automatically return the bus to the RESUME state...
  395. * the client must RESUME the bus explicitly through this function.  This
  396. * point is most important when considering the USB "remote wakeup" feature.
  397. * This feature allows a remote device to drive RESUME signalling on the
  398. * bus. However, it is the client's responsibility to recognize this
  399. * condition by monitoring management events through the use of management
  400. * callbacks - see usbdMngmtCallbackSet().  When a USBD_MNGMT_RESUME event
  401. * is detected, the client chooses to RESUME the bus (or not).
  402. *
  403. * RETURNS: OK, or ERROR if unable to set specified bus state
  404. */
  405. STATUS usbdBusStateSet
  406.     (
  407.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  408.     USBD_NODE_ID nodeId, /* node ID */
  409.     UINT16 busState /* new bus state: USBD_BUS_xxxx */
  410.     )
  411.     {
  412.     URB_BUS_STATE_SET urb;
  413.     /* Initialize URB */
  414.     urbInit (&urb.header, clientHandle, USBD_FNC_BUS_STATE_SET, NULL, 
  415. NULL, sizeof (urb));
  416.     urb.nodeId = nodeId;
  417.     urb.busState = busState;
  418.     /* Execute URB */
  419.     return urbExecBlock (&urb.header);
  420.     }
  421. /***************************************************************************
  422. *
  423. * usbdBusCountGet - Get number of USBs attached to the host.
  424. *
  425. * This function returns the total number of USB host controllers in the 
  426. * system.  Each host controller has its own root hub as required by the USB 
  427. * specification; and clients planning to enumerate USB devices using the Bus 
  428. * Enumeration Functions need to know the total number of host controllers in 
  429. * order to retrieve the Node Ids for each root hub.
  430. *
  431. * <pBusCount> must point to a UINT16 variable in which the total number of 
  432. * USB host controllers will be stored.
  433. *
  434. * Note: The number of USB host controllers is not constant.  Bus controllers 
  435. * can be added by calling usbdHcdAttach() and removed by calling 
  436. * usbdHcdDetach().  Again, the Dynamic Attach Functions deal with these 
  437. * situations automatically, and are the preferred mechanism by which most 
  438. * clients should be informed of device attachment and removal.
  439. *
  440. * RETURNS: OK, or ERROR if unable to retrieve bus count
  441. */
  442. STATUS usbdBusCountGet
  443.     (
  444.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  445.     pUINT16 pBusCount /* Word bfr to receive bus count */
  446.     )
  447.     {
  448.     URB_BUS_COUNT_GET urb;
  449.     STATUS s;
  450.     /* Initalize URB */
  451.     urbInit (&urb.header, clientHandle, USBD_FNC_BUS_COUNT_GET, NULL, NULL,
  452. sizeof (urb));
  453.     /* Execute URB */
  454.     s = urbExecBlock (&urb.header);
  455.     /* Return result */
  456.     if (pBusCount != NULL)
  457. *pBusCount = urb.busCount;
  458.     return s;
  459.     }
  460. /***************************************************************************
  461. *
  462. * usbdRootNodeIdGet - Returns root node for a specific USB
  463. *
  464. * This function returns the Node Id for the root hub for the specified 
  465. * USB host controller. <busIndex> is the index of the desired USB host 
  466. * controller.  The first host controller is index 0 and the last host 
  467. * controller's index is the total number of USB host controllers - as 
  468. * returned by usbdBusCountGet() - minus 1. < pRootId> must point to a 
  469. * USBD_NODE_ID variable in which the Node Id of the root hub will be stored.
  470. * RETURNS: OK, or ERROR if unable to get root node ID.
  471. */
  472. STATUS usbdRootNodeIdGet
  473.     (
  474.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  475.     UINT16 busIndex, /* Bus index */
  476.     pUSBD_NODE_ID pRootId /* bfr to receive Root Id */
  477.     )
  478.     {
  479.     URB_ROOT_ID_GET urb;
  480.     STATUS s;
  481.     /* Initalize URB */
  482.     urbInit (&urb.header, clientHandle, USBD_FNC_ROOT_ID_GET, NULL, NULL,
  483. sizeof (urb));
  484.     urb.busIndex = busIndex;
  485.     /* Execute URB */
  486.     s = urbExecBlock (&urb.header);
  487.     /* Return result */
  488.     if (pRootId != NULL)
  489. *pRootId = urb.rootId;
  490.     return s;
  491.     }
  492. /***************************************************************************
  493. *
  494. * usbdHubPortCountGet - Returns number of ports connected to a hub
  495. *
  496. * usbdHubPortCountGet() provides clients with a convenient mechanism to 
  497. * retrieve the number of downstream ports provided by the specified hub. 
  498. * Clients can also retrieve this information by retrieving configuration 
  499. * descriptors from the hub using the Configuration Functions describe in 
  500. * a following section.
  501. *
  502. * <hubId> must be the Node Id for the desired USB hub. An error will be 
  503. * returned if <hubId> does not refer to a hub. <pPortCount> must point to 
  504. * a UINT16 variable in which the total number of ports on the specified 
  505. * hub will be stored.
  506. *
  507. * RETURNS: OK, or ERROR if unable to get hub port count.
  508. */
  509. STATUS usbdHubPortCountGet
  510.     (
  511.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  512.     USBD_NODE_ID hubId,  /* Node Id for desired hub */
  513.     pUINT16 pPortCount /* bfr to receive port count */
  514.     )
  515.     {
  516.     URB_HUB_PORT_COUNT_GET urb;
  517.     STATUS s;
  518.     /* Initalize URB */
  519.     urbInit (&urb.header, clientHandle, USBD_FNC_HUB_PORT_COUNT_GET, NULL, NULL,
  520. sizeof (urb));
  521.     urb.hubId = hubId;
  522.     /* Execute URB */
  523.     s = urbExecBlock (&urb.header);
  524.     /* Return result */
  525.     if (pPortCount != NULL)
  526. *pPortCount = urb.portCount;
  527.     return s;
  528.     }
  529. /***************************************************************************
  530. *
  531. * usbdNodeIdGet - Gets the id of the node connected to a hub port
  532. *
  533. * Clients use this function to retrieve the Node Id for devices attached to
  534. * each of a hub抯 ports.  <hubId> and <portIndex> identify the hub and port 
  535. * to which a device may be attached.  <pNodeType> must point to a UINT16 
  536. * variable to receive a type code as follows:
  537. *
  538. * .IP "USB_NODETYPE_NONE"
  539. * No device is attached to the specified port.
  540. * .IP "USB_NODETYPE_HUB"
  541. * A hub is attached to the specified port.
  542. * .IP "USB_NODETYPE_DEVICE"
  543. * A device (non-hub) is attached to the specified port.
  544. *
  545. * If the node type is returned as USBD_NODE_TYPE_NONE, then a Node Id is 
  546. * not returned and the value returned in <pNodeId> is undefined.  If the 
  547. * node type indicates a hub or device is attached to the port, then 
  548. * <pNodeId> will contain that hub or device抯 nodeId upon return.
  549. *
  550. * RETURNS: OK, or ERROR if unable to get node ID.
  551. */
  552. STATUS usbdNodeIdGet
  553.     (
  554.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  555.     USBD_NODE_ID hubId,  /* Node Id for desired hub */
  556.     UINT16 portIndex, /* Port index */
  557.     pUINT16 pNodeType, /* bfr to receive node type */
  558.     pUSBD_NODE_ID pNodeId /* bfr to receive Node Id */
  559.     )
  560.     {
  561.     URB_NODE_ID_GET urb;
  562.     STATUS s;
  563.     /* Initalize URB */
  564.     urbInit (&urb.header, clientHandle, USBD_FNC_NODE_ID_GET, NULL, NULL,
  565. sizeof (urb));
  566.     urb.hubId = hubId;
  567.     urb.portIndex = portIndex;
  568.     /* Execute URB */
  569.     s = urbExecBlock (&urb.header);
  570.     /* Return result */
  571.     if (pNodeType != NULL)
  572. *pNodeType = urb.nodeType;
  573.     if (pNodeId != NULL)
  574. *pNodeId = urb.nodeId;
  575.     return s;
  576.     }
  577. /***************************************************************************
  578. *
  579. * usbdNodeInfoGet - Returns information about a USB node
  580. *
  581. * This function retrieves information about the USB device specified by 
  582. * <nodeId>.  The USBD copies node information into the <pNodeInfo> structure 
  583. * provided by the caller.  This structure is of the form USBD_NODEINFO as
  584. * shown below:
  585. *
  586. * .CS
  587. * typedef struct usbd_nodeinfo
  588. *     {
  589. *     UINT16 nodeType;
  590. *     UINT16 nodeSpeed;
  591. *     USBD_NODE_ID parentHubId;
  592. *     UINT16 parentHubPort;
  593. *     USBD_NODE_ID rootId;
  594. *     } USBD_NODEINFO, *pUSBD_NODEINFO;
  595. * .CE
  596. *
  597. * <nodeType> specifies the type of node identified by <nodeId> and is defined 
  598. * as USB_NODETYPE_xxxx.  <nodeSpeed> identifies the speed of the device and 
  599. * is defined as USB_SPEED_xxxx.  <parentHubId> and <parentHubPort> identify 
  600. * the Node Id and port of the hub to which the indicated node is attached 
  601. * upstream.  If the indicated <nodeId> happens to be a root hub, then 
  602. * <parentHubId> and <parentHubPort> will both be 0.  
  603. *
  604. * Similarly, <rootId> identifies the Node Id of the root hub for the USB to 
  605. * which nodeId is attached.  If <nodeId> itself happens to be the root hub, 
  606. * then the same value will be returned in <rootId>.
  607. *
  608. * It is anticipated that this structure may grow over time.  To provide 
  609. * backwards compatibility, the client must pass the total size of the 
  610. * USBD_NODEINFO structure it has allocated in <infoLen>.  The USBD will copy 
  611. * fields into this structure only up to the <infoLen> indicated by the caller.
  612. *
  613. * RETURNS: OK, or ERROR if unable to retrieve node information.
  614. */
  615. STATUS usbdNodeInfoGet
  616.     (
  617.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  618.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  619.     pUSBD_NODE_INFO pNodeInfo, /* Structure to receive node info */
  620.     UINT16 infoLen /* Len of bfr allocated by client */
  621.     )
  622.     {
  623.     URB_NODE_INFO_GET urb;
  624.     /* Initalize URB */
  625.     urbInit (&urb.header, clientHandle, USBD_FNC_NODE_INFO_GET, NULL, NULL,
  626. sizeof (urb));
  627.     urb.nodeId = nodeId;
  628.     urb.pNodeInfo = pNodeInfo;
  629.     urb.infoLen = infoLen;
  630.     /* Execute URB */
  631.     return urbExecBlock (&urb.header);
  632.     }
  633. /***************************************************************************
  634. *
  635. * usbdDynamicAttachRegister - Registers client for dynamic attach notification
  636. *
  637. * Clients call this function to indicate to the USBD that they wish to be 
  638. * notified whenever a device of the indicated class/sub-class/protocol is attached 
  639. * or removed from the USB.  A client may specify that it wants to receive 
  640. * notification for an entire device class or only for specific sub-classes
  641. * within that class.
  642. *
  643. * <deviceClass>, <deviceSubClass>, and <deviceProtocol> must specify a USB 
  644. * class/sub-class/protocol combination according to the USB specification.  For 
  645. * the client抯 convenience, usbdLib.h automatically includes usb.h which defines a 
  646. * number of USB device classes as USB_CLASS_xxxx and USB_SUBCLASS_xxxx.  A 
  647. * value of USBD_NOTIFY_ALL in any/all of these parameters acts like a wildcard
  648. * and matches any value reported by the device for the corresponding field. 
  649. *
  650. * <attachCallback> must be a non-NULL pointer to a client-supplied callback 
  651. * routine of the form USBD_ATTACH_CALLBACK:
  652. *
  653. * .CS
  654. * typedef VOID (*USBD_ATTACH_CALLBACK) 
  655. *     (
  656. *     USBD_NODE_ID nodeId, 
  657. *     UINT16 attachAction, 
  658. *     UINT16 configuration,
  659. *     UINT16 interface,
  660. *     UINT16 deviceClass, 
  661. *     UINT16 deviceSubClass, 
  662. *     UINT16 deviceProtocol
  663. *     );
  664. * .CE
  665. *
  666. * Immediately upon registration the client should expect that it may begin 
  667. * receiving calls to the <attachCallback> routine.  Upon registration, USBD 
  668. * will call the <attachCallback> for each device of the specified class which 
  669. * is already attached to the system.  Thereafter, the USBD will call the 
  670. * <attachCallback> whenever a new device of the specified class is attached to 
  671. * the system or an already-attached device is removed.
  672. *
  673. * Each time the <attachCallback> is called, USBD will pass the Node Id of the 
  674. * device in <nodeId> and an attach code in <attachAction> which explains the 
  675. * reason for the callback.  Attach codes are defined as:
  676. *
  677. * .IP "USBD_DYNA_ATTACH"
  678. * USBD is notifying the client that nodeId is a device which is now attached 
  679. * to the system.
  680. * .IP "USBD_DYNA_REMOVE"
  681. * USBD is notifying the client that nodeId has been detached (removed) from 
  682. * the system.
  683. *
  684. * When the <attachAction> is USBD_DYNA_REMOVE the <nodeId> refers to a Node Id 
  685. * which is no longer valid.  The client should interrogate its internal data 
  686. * structures and delete any references to the specified Node Id.  If the client 
  687. * had outstanding requests to the specified <nodeId>, such as data transfer 
  688. * requests, then the USBD will fail those outstanding requests prior to calling 
  689. * the <attachCallback> to notify the client that the device has been removed.  
  690. * In general, therefore, transfer requests related to removed devices should 
  691. * already be taken care of before the <attachCallback> is called.
  692. *
  693. * A client may re-use a single <attachCallback> for multiple notification 
  694. * registrations.  As a convenience to the <attachCallback> routine, the USBD 
  695. * also passes the <deviceClass>, <deviceSubClass>, and <deviceProtocol> of the 
  696. * attached/removed <nodeId> each time it calls the <attachCallback>.  
  697. *
  698. * Finally, clients need to be aware that not all USB devices report their class
  699. * information at the "device" level.  Rather, some devices report class types
  700. * on an interface-by-interface basis.  When the device reports class information
  701. * at the device level, then the USBD passes a <configuration> value of zero to 
  702. * the attach callback and calls the callback only a single time for each device.
  703. * When the device reports class information at the interface level, then the
  704. * USBD invokes the attach callback once for each interface which matches the
  705. * client's <deviceClass>/<deviceSubClass>/<deviceProtocol> specification.  In this
  706. * case, the USBD also passes the corresponding configuration & interface numbers
  707. * in <configuration> and <interface> each time it invokes the callback.
  708. *
  709. * RETURNS: OK, or ERROR if unable to register for attach/removal notification.
  710. */
  711. STATUS usbdDynamicAttachRegister
  712.     (
  713.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  714.     UINT16 deviceClass,  /* USB class code */
  715.     UINT16 deviceSubClass, /* USB sub-class code */
  716.     UINT16 deviceProtocol, /* USB device protocol code */
  717.     USBD_ATTACH_CALLBACK attachCallback /* User-supplied callback routine */
  718.     )
  719.     {
  720.     URB_DYNA_ATTACH_REG_UNREG urb;
  721.     /* Initalize URB */
  722.     urbInit (&urb.header, clientHandle, USBD_FNC_DYNA_ATTACH_REG, NULL, NULL,
  723. sizeof (urb));
  724.     urb.deviceClass = deviceClass;
  725.     urb.deviceSubClass = deviceSubClass;
  726.     urb.deviceProtocol = deviceProtocol;
  727.     urb.attachCallback = attachCallback;
  728.     /* Execute URB */
  729.     return urbExecBlock (&urb.header);
  730.     }
  731. /***************************************************************************
  732. *
  733. * usbdDynamicAttachUnRegister - Unregisters client for attach notification
  734. *
  735. * This function cancels a client抯 earlier request to be notified for the 
  736. * attachment and removal of devices within the specified class.  <deviceClass>,
  737. * <deviceSubClass>, <deviceProtocol>, and <attachCallback> are defined as for the 
  738. * usbdDynamicAttachRegister() function and must match exactly the parameters
  739. * passed in an earlier call to usbdDynamicAttachRegister.
  740. *
  741. * RETURNS: OK, or ERROR if unable to unregister for attach/removal notification.
  742. */
  743. STATUS usbdDynamicAttachUnRegister
  744.     (
  745.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  746.     UINT16 deviceClass,  /* USB class code */
  747.     UINT16 deviceSubClass, /* USB sub-class code */
  748.     UINT16 deviceProtocol, /* USB device protocol code */
  749.     USBD_ATTACH_CALLBACK attachCallback /* user-supplied callback routine */
  750.     )
  751.     {
  752.     URB_DYNA_ATTACH_REG_UNREG urb;
  753.     /* Initalize URB */
  754.     urbInit (&urb.header, clientHandle, USBD_FNC_DYNA_ATTACH_UNREG, NULL, 
  755. NULL, sizeof (urb));
  756.     urb.deviceClass = deviceClass;
  757.     urb.deviceSubClass = deviceSubClass;
  758.     urb.deviceProtocol = deviceProtocol;
  759.     urb.attachCallback = attachCallback;
  760.     /* Execute URB */
  761.     return urbExecBlock (&urb.header);
  762.     }
  763. /***************************************************************************
  764. *
  765. * usbdFeatureClear - Clears a USB feature
  766. *
  767. * This function allows a client to "clear" a USB feature.  <nodeId> specifies 
  768. * the Node Id of the desired device and <requestType> specifies whether the 
  769. * feature is related to the device, to an interface, or to an endpoint as:
  770. *
  771. * .IP "USB_RT_DEVICE"
  772. * Device
  773. * .IP "USB_RT_INTERFACE"
  774. * Interface
  775. * .IP "USB_RT_ENDPOINT"
  776. * Endpoint
  777. *
  778. * <requestType> also specifies if the request is standard, class-specific,
  779. * etc., as:
  780. *
  781. * .IP "USB_RT_STANDARD"
  782. * Standard
  783. * .IP "USB_RT_CLASS"
  784. * Class-specific
  785. * .IP "USB_RT_VENDOR"
  786. * Vendor-specific
  787. *
  788. * For example, USB_RT_STANDARD | USB_RT_DEVICE in <requestType> specifies a
  789. * standard device request.  
  790. *
  791. * The client must pass the device抯 feature selector in <feature>.  If 
  792. * <featureType> specifies an interface or endpoint, then <index> must contain 
  793. * the interface or endpoint index.  <index> should be zero when <featureType> 
  794. * is USB_SELECT_DEVICE.
  795. *
  796. * RETURNS: OK, or ERROR if unable to clear feature.
  797. */
  798. STATUS usbdFeatureClear
  799.     (
  800.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  801.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  802.     UINT16 requestType,  /* Selects request type */
  803.     UINT16 feature, /* Feature selector */
  804.     UINT16 index /* Interface/endpoint index */
  805.     )
  806.     {
  807.     URB_FEATURE_CLEAR_SET urb;
  808.     /* Initalize URB */
  809.     urbInit (&urb.header, clientHandle, USBD_FNC_FEATURE_CLEAR, NULL, NULL,
  810. sizeof (urb));
  811.     urb.nodeId = nodeId;
  812.     urb.requestType = requestType;
  813.     urb.feature = feature;
  814.     urb.index = index;
  815.     /* Execute URB */
  816.     return urbExecBlock (&urb.header);
  817.     }
  818. /***************************************************************************
  819. *
  820. * usbdFeatureSet - Sets a USB feature
  821. *
  822. * This function allows a client to "set" a USB feature.  <nodeId> specifies 
  823. * the Node Id of the desired device and <requestType> specifies the nature
  824. * of the feature feature as defined for the usbdFeatureClear() function.
  825. * The client must pass the device抯 feature selector in <feature>.  If 
  826. * <requestType> specifies an interface or endpoint, then <index> must contain 
  827. * the interface or endpoint index.  <index> should be zero when <requestType>
  828. * includes USB_SELECT_DEVICE.
  829. *
  830. * RETURNS: OK, or ERROR if unable to set feature.
  831. */
  832. STATUS usbdFeatureSet
  833.     (
  834.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  835.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  836.     UINT16 requestType,  /* Selects request type */
  837.     UINT16 feature, /* Feature selector */
  838.     UINT16 index /* Interface/endpoint index */
  839.     )
  840.     {
  841.     URB_FEATURE_CLEAR_SET urb;
  842.     /* Initalize URB */
  843.     urbInit (&urb.header, clientHandle, USBD_FNC_FEATURE_SET, NULL, NULL,
  844. sizeof (urb));
  845.     urb.nodeId = nodeId;
  846.     urb.requestType = requestType;
  847.     urb.feature = feature;
  848.     urb.index = index;
  849.     /* Execute URB */
  850.     return urbExecBlock (&urb.header);
  851.     }
  852. /***************************************************************************
  853. *
  854. * usbdConfigurationGet - Gets USB configuration for a device
  855. *
  856. * This function returns the currently selected configuration for the device 
  857. * or hub indicated by <nodeId>.  The current configuration value is returned 
  858. * in the low byte of <pConfiguration>. The high byte is currently reserved 
  859. * and will be 0.
  860. *
  861. * RETURNS: OK, or ERROR if unable to get configuration.
  862. */
  863. STATUS usbdConfigurationGet
  864.     (
  865.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  866.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  867.     pUINT16 pConfiguration /* bfr to receive config value */
  868.     )
  869.     {
  870.     URB_CONFIG_GET_SET urb;
  871.     STATUS s;
  872.     /* Initalize URB */
  873.     urbInit (&urb.header, clientHandle, USBD_FNC_CONFIG_GET, NULL, NULL,
  874. sizeof (urb));
  875.     urb.nodeId = nodeId;
  876.     /* Execute URB */
  877.     s = urbExecBlock (&urb.header);
  878.     /* Return result */
  879.     if (pConfiguration != NULL)
  880. *pConfiguration = urb.configuration;
  881.     return s;
  882.     }
  883. /***************************************************************************
  884. *
  885. * usbdConfigurationSet - Sets USB configuration for a device
  886. *
  887. * This function sets the current configuration for the device identified 
  888. * by <nodeId>. The client should pass the desired configuration value in 
  889. * the low byte of <configuration>.  The high byte is currently reserved and 
  890. * should be 0.
  891. *
  892. * The client must also pass the maximum current which will be used by this
  893. * configuration in <maxPower>. Typically, the maximum power will be
  894. * determined by reading the corresponding configuration descriptor for a
  895. * device.  Prior to setting the chosen configuration, the USBD will verify
  896. * that the hub port to which <pNode> is connected is capable of providing
  897. * the requested current.  If the port cannot provide <maxPower>, then
  898. * the configuration will not be set and the function will return an error.
  899. * <maxPower> should be expressed in milliamps (e.g., 100 = 100mA).  For
  900. * self-powered devices, the caller may pass zero in <maxPower>.
  901. *
  902. * RETURNS: OK, or ERROR if unable to set configuration.
  903. */
  904. STATUS usbdConfigurationSet
  905.     (
  906.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  907.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  908.     UINT16 configuration, /* New configuration to be set */
  909.     UINT16 maxPower /* max power this config will draw */
  910.     )
  911.     {
  912.     URB_CONFIG_GET_SET urb;
  913.     /* Initalize URB */
  914.     urbInit (&urb.header, clientHandle, USBD_FNC_CONFIG_SET, NULL, NULL,
  915. sizeof (urb));
  916.     urb.nodeId = nodeId;
  917.     urb.configuration = configuration;
  918.     urb.maxPower = maxPower;
  919.     /* Execute URB */
  920.     return urbExecBlock (&urb.header);
  921.     }
  922. /***************************************************************************
  923. *
  924. * usbdDescriptorGet - Retrieves a USB descriptor
  925. *
  926. * A client uses this function to retrieve a descriptor from the USB device 
  927. * identified by <nodeId>.  <requestType> is defined as documented for the
  928. * usbdFeatureClear() function. <descriptorType> specifies the type of the 
  929. * descriptor to be retrieved and must be one of the following values:
  930. *
  931. * .IP "USB_DESCR_DEVICE"
  932. * Specifies the DEVICE descriptor.
  933. * .IP "USB_DESCR_CONFIG"
  934. * Specifies the CONFIGURATION descriptor.
  935. * .IP "USB_DESCR_STRING"
  936. * Specifies a STRING descriptor.
  937. * .IP "USB_DESCR_INTERFACE"
  938. * Specifies an INTERFACE descriptor.
  939. * .IP "USB_DESCR_ENDPOINT"
  940. * Specifies an ENDPOINT descriptor.
  941. *
  942. * <descriptorIndex> is the index of the desired descriptor.
  943. *
  944. * For string descriptors the <languageId> should specify the desired 
  945. * language for the string.  According to the USB Specification, strings 
  946. * descriptors are returned in UNICODE format and the <languageId> should 
  947. * be the "sixteen-bit language ID (LANGID) defined by Microsoft for 
  948. * Windows as described in .I "Developing International Software for Windows 
  949. * 95 and Windows NT."  Please refer to Section 9.6.5 of revision 1.1 of the 
  950. * USB Specification for more detail.  For device and configuration 
  951. * descriptors, <languageId> should be 0.
  952. *
  953. * The caller must provide a buffer to receive the descriptor data.  <pBfr> 
  954. * is a pointer to a caller-supplied buffer of length <bfrLen>. If the 
  955. * descriptor is too long to fit in the buffer provided, the descriptor will 
  956. * be truncated.  If a non-NULL pointer is passed in <pActLen>, the actual 
  957. * length of the data transferred will be stored in <pActLen> upon return.
  958. *
  959. * RETURNS: OK, or ERROR if unable to get descriptor.
  960. */
  961. STATUS usbdDescriptorGet
  962.     (
  963.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  964.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  965.     UINT8 requestType, /* specifies type of request */
  966.     UINT8 descriptorType, /* Type of descriptor */
  967.     UINT8 descriptorIndex, /* Index of descriptor */
  968.     UINT16 languageId, /* Language ID */
  969.     UINT16 bfrLen, /* Max length of data to be returned */
  970.     pUINT8 pBfr, /* Pointer to bfr to receive data */
  971.     pUINT16 pActLen /* bfr to receive actual length */
  972.     )
  973.     {
  974.     URB_DESCRIPTOR_GET_SET urb;
  975.     STATUS s;
  976.     /* Initalize URB */
  977.     urbInit (&urb.header, clientHandle, USBD_FNC_DESCRIPTOR_GET, NULL, NULL,
  978. sizeof (urb));
  979.     urb.nodeId = nodeId;
  980.     urb.requestType = requestType;
  981.     urb.descriptorType = descriptorType;
  982.     urb.descriptorIndex = descriptorIndex;
  983.     urb.languageId = languageId;
  984.     urb.bfrLen = bfrLen;
  985.     urb.pBfr = pBfr;
  986.     /* Execute URB */
  987.     s = urbExecBlock (&urb.header);
  988.     /* Return result */
  989.     if (pActLen != NULL)
  990. *pActLen = urb.actLen;
  991.     return s;
  992.     }
  993. /***************************************************************************
  994. *
  995. * usbdDescriptorSet - Sets a USB descriptor
  996. *
  997. * A client uses this function to set a descriptor on the USB device identified 
  998. * by <nodeId>. The parameters <requestType>, <descriptorType>, 
  999. * <descriptorIndex>, and <languageId> are the same as those described for the 
  1000. * usbdDescriptorGet() function.  <pBfr> is a pointer to a buffer of length 
  1001. * <bfrLen> which contains the descriptor data to be sent to the device.
  1002. *
  1003. * RETURNS: OK, or ERROR if unable to set descriptor.
  1004. */
  1005. STATUS usbdDescriptorSet
  1006.     (
  1007.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1008.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  1009.     UINT8 requestType, /* selects request type */
  1010.     UINT8 descriptorType, /* Type of descriptor */
  1011.     UINT8 descriptorIndex, /* Index of descriptor */
  1012.     UINT16 languageId, /* Language ID */
  1013.     UINT16 bfrLen, /* Max length of data to be returned */
  1014.     pUINT8 pBfr  /* Pointer to bfr to receive data */
  1015.     )
  1016.     {
  1017.     URB_DESCRIPTOR_GET_SET urb;
  1018.     /* Initalize URB */
  1019.     urbInit (&urb.header, clientHandle, USBD_FNC_DESCRIPTOR_SET, NULL, NULL,
  1020. sizeof (urb));
  1021.     urb.nodeId = nodeId;
  1022.     urb.requestType = requestType;
  1023.     urb.descriptorType = descriptorType;
  1024.     urb.descriptorIndex = descriptorIndex;
  1025.     urb.languageId = languageId;
  1026.     urb.bfrLen = bfrLen;
  1027.     urb.pBfr = pBfr;
  1028.     /* Execute URB */
  1029.     return urbExecBlock (&urb.header);
  1030.     }
  1031. /***************************************************************************
  1032. *
  1033. * usbdInterfaceGet - Retrieves a device's current interface
  1034. *
  1035. * This function allows a client to query the current alternate setting for 
  1036. * a given device抯 interface.  <nodeId> and <interfaceIndex> specify the 
  1037. * device and interface to be queried, respectively.  <pAlternateSetting> 
  1038. * points to a UINT16 variable in which the alternate setting will be stored 
  1039. * upon return.
  1040. *
  1041. * RETURNS: OK, or ERROR if unable to get interface.
  1042. */
  1043. STATUS usbdInterfaceGet
  1044.     (
  1045.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1046.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  1047.     UINT16 interfaceIndex, /* Index of interface */
  1048.     pUINT16 pAlternateSetting /* Current alternate setting */
  1049.     )
  1050.     {
  1051.     URB_INTERFACE_GET_SET urb;
  1052.     STATUS s;
  1053.     /* Initalize URB */
  1054.     urbInit (&urb.header, clientHandle, USBD_FNC_INTERFACE_GET, NULL, NULL,
  1055. sizeof (urb));
  1056.     urb.nodeId = nodeId;
  1057.     urb.interfaceIndex = interfaceIndex;
  1058.     /* Execute URB */
  1059.     s = urbExecBlock (&urb.header);
  1060.     /* Return result */
  1061.     if (pAlternateSetting != NULL)
  1062. *pAlternateSetting = urb.alternateSetting;
  1063.     return s;
  1064.     }
  1065. /***************************************************************************
  1066. *
  1067. * usbdInterfaceSet - Sets a device's current interface
  1068. *
  1069. * This function allows a client to select an alternate setting for a given 
  1070. * device抯 interface.  <nodeId> and <interfaceIndex> specify the device and 
  1071. * interface to be modified, respectively.  <alternateSetting> specifies the 
  1072. * new alternate setting.
  1073. *
  1074. * RETURNS: OK, or ERROR if unable to set interface.
  1075. */
  1076. STATUS usbdInterfaceSet
  1077.     (
  1078.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1079.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  1080.     UINT16 interfaceIndex, /* Index of interface */
  1081.     UINT16 alternateSetting /* Alternate setting */
  1082.     )
  1083.     {
  1084.     URB_INTERFACE_GET_SET urb;
  1085.     /* Initalize URB */
  1086.     urbInit (&urb.header, clientHandle, USBD_FNC_INTERFACE_SET, NULL, NULL,
  1087. sizeof (urb));
  1088.     urb.nodeId = nodeId;
  1089.     urb.interfaceIndex = interfaceIndex;
  1090.     urb.alternateSetting = alternateSetting;
  1091.     /* Execute URB */
  1092.     return urbExecBlock (&urb.header);
  1093.     }
  1094. /***************************************************************************
  1095. *
  1096. * usbdStatusGet - Retrieves USB status from a device/interface/etc.
  1097. *
  1098. * This function retrieves the current status from the device indicated
  1099. * by <nodeId>. <requestType> indicates the nature of the desired status
  1100. * as documented for the usbdFeatureClear() function.
  1101. *
  1102. * The status word is returned in <pBfr>.  The meaning of the status  
  1103. * varies depending on whether it was queried from the device, an interface, 
  1104. * or an endpoint, class-specific function, etc. as described in the USB 
  1105. * Specification.
  1106. *
  1107. * RETURNS: OK, or ERROR if unable to get status.
  1108. */
  1109. STATUS usbdStatusGet
  1110.     (
  1111.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1112.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  1113.     UINT16 requestType,  /* Selects device/interface/endpoint */
  1114.     UINT16 index, /* Interface/endpoint index */
  1115.     UINT16 bfrLen, /* length of bfr */
  1116.     pUINT8 pBfr, /* bfr to receive status */
  1117.     pUINT16 pActLen /* bfr to receive act len xfr'd */
  1118.     )
  1119.     {
  1120.     URB_STATUS_GET urb;
  1121.     STATUS s;
  1122.     /* Initalize URB */
  1123.     urbInit (&urb.header, clientHandle, USBD_FNC_STATUS_GET, NULL, NULL,
  1124. sizeof (urb));
  1125.     urb.nodeId = nodeId;
  1126.     urb.requestType = requestType;
  1127.     urb.index = index;
  1128.     urb.bfrLen = bfrLen;
  1129.     urb.pBfr = pBfr;
  1130.     /* Execute URB */
  1131.     s = urbExecBlock (&urb.header);
  1132.     /* Return result */
  1133.     if (pActLen != NULL)
  1134. *pActLen = urb.actLen;
  1135.     return s;
  1136.     }
  1137. /***************************************************************************
  1138. *
  1139. * usbdAddressGet - Gets the USB address for a given device
  1140. *
  1141. * This function returns the USB address assigned to device specified by 
  1142. * <nodeId>.  USB addresses are assigned by the USBD, so there is generally 
  1143. * no need for clients to query the USB device address. Furthermore, this 
  1144. * function has no counterpart in the USB functions described in Chapter 9 
  1145. * of the USB Specification.
  1146. *
  1147. * The USBD assigns device addresses such that they are unique within the 
  1148. * scope of each USB host controller.  However, it is possible that two or 
  1149. * more devices attached to different USB host controllers may have identical 
  1150. * addresses.
  1151. *
  1152. * RETURNS: OK, or ERROR if unable to set address.
  1153. */
  1154. STATUS usbdAddressGet
  1155.     (
  1156.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1157.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  1158.     pUINT16 pDeviceAddress /* Currently assigned device address */
  1159.     )
  1160.     {
  1161.     URB_ADDRESS_GET_SET urb;
  1162.     STATUS s;
  1163.     /* Initalize URB */
  1164.     urbInit (&urb.header, clientHandle, USBD_FNC_ADDRESS_GET, NULL, NULL,
  1165. sizeof (urb));
  1166.     urb.nodeId = nodeId;
  1167.     /* Execute URB */
  1168.     s = urbExecBlock (&urb.header);
  1169.     /* Return result */
  1170.     if (pDeviceAddress != NULL)
  1171. *pDeviceAddress = urb.deviceAddress;
  1172.     return s;
  1173.     }
  1174. /***************************************************************************
  1175. *
  1176. * usbdAddressSet - Sets the USB address for a given device
  1177. *
  1178. * This function sets the USB address at which a device will respond to future 
  1179. * requests.  Upon return, the address of the device identified by <nodeId> 
  1180. * will be changed to the value specified in <deviceAddress>.  <deviceAddress> 
  1181. * must be in the range from 0..127.  The <deviceAddress> must also be unique 
  1182. * within the scope of each USB host controller.
  1183. *
  1184. * The USBD manages USB device addresses automatically, and this function 
  1185. * should never be called by normal USBD clients.  Changing a device address 
  1186. * may cause serious problems, including device address conflicts, and may 
  1187. * cause the USB to cease operation.
  1188. *
  1189. * RETURNS: OK, or ERROR if unable to get current device address.
  1190. */
  1191. STATUS usbdAddressSet
  1192.     (
  1193.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1194.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  1195.     UINT16 deviceAddress /* New device address */
  1196.     )
  1197.     {
  1198.     URB_ADDRESS_GET_SET urb;
  1199.     /* Initalize URB */
  1200.     urbInit (&urb.header, clientHandle, USBD_FNC_ADDRESS_SET, NULL, NULL,
  1201. sizeof (urb));
  1202.     urb.nodeId = nodeId;
  1203.     urb.deviceAddress = deviceAddress;
  1204.     /* Execute URB */
  1205.     return urbExecBlock (&urb.header);
  1206.     }
  1207. /***************************************************************************
  1208. *
  1209. * usbdVendorSpecific - Allows clients to issue vendor-specific USB requests
  1210. *
  1211. * Certain devices may implement vendor-specific USB requests which cannot 
  1212. * be generated using the standard functions described elsewhere.  This 
  1213. * function allows a client to specify directly the exact parameters for a 
  1214. * USB control pipe request.
  1215. *
  1216. * <requestType>, <request>, <value>, <index>, and <length> correspond 
  1217. * exactly to the bmRequestType, bRequest, wValue, wIndex, and wLength fields 
  1218. * defined by the USB Specfication.  If <length> is greater than zero, then 
  1219. * <pBfr> must be a non-NULL pointer to a data buffer which will provide or 
  1220. * accept data, depending on the direction of the transfer. 
  1221. *
  1222. * Vendor specific requests issued through this function are always directed 
  1223. * to the control pipe of the device specified by <nodeId>.  This function
  1224. * formats and sends a Setup packet based on the parameters provided.  If a 
  1225. * non-NULL <pBfr> is also provided, then additional IN or OUT transfers
  1226. * will be performed following the Setup packet.  The direction of these
  1227. * transfers is inferred from the direction bit in the <requestType> param.
  1228. * For IN transfers, the actual length of the data transferred will be
  1229. * stored in <pActLen> if <pActLen> is not NULL.
  1230. *
  1231. * RETURNS: OK, or ERROR if unable to execute vendor-specific request.
  1232. */
  1233. STATUS usbdVendorSpecific
  1234.     (
  1235.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1236.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  1237.     UINT8 requestType, /* bmRequestType in USB spec. */
  1238.     UINT8 request, /* bRequest in USB spec. */
  1239.     UINT16 value, /* wValue in USB spec. */
  1240.     UINT16 index, /* wIndex in USB spec. */
  1241.     UINT16 length, /* wLength in USB spec. */
  1242.     pUINT8 pBfr, /* ptr to data buffer */
  1243.     pUINT16 pActLen /* actual length of IN */
  1244.     )
  1245.     {
  1246.     URB_VENDOR_SPECIFIC urb;
  1247.     STATUS s;
  1248.     /* Initalize URB */
  1249.     urbInit (&urb.header, clientHandle, USBD_FNC_VENDOR_SPECIFIC, NULL, NULL,
  1250. sizeof (urb));
  1251.     urb.nodeId = nodeId;
  1252.     urb.requestType = requestType;
  1253.     urb.request = request;
  1254.     urb.value = value;
  1255.     urb.index = index;
  1256.     urb.length = length;
  1257.     urb.pBfr = pBfr;
  1258.     /* Execute URB */
  1259.     s = urbExecBlock (&urb.header);
  1260.     /* return results */
  1261.     if (pActLen != NULL)
  1262. *pActLen = urb.actLen;
  1263.     return s;
  1264.     }
  1265. /***************************************************************************
  1266. *
  1267. * usbdPipeCreate - Creates a USB pipe for subsequent transfers
  1268. *
  1269. * This function establishes a pipe which can subsequently be used by a 
  1270. * client to exchange data with a USB device endpoint.  
  1271. *
  1272. * <nodeId> and <endpoint> identify the device and device endpoint, 
  1273. * respectively, to which the pipe should be "connected."  <configuration>
  1274. * and <interface> specify the configuration and interface, respectively,
  1275. * with which the pipe is associated.  (The USBD uses this information to
  1276. * keep track of "configuration events" associated with the pipe).
  1277. *
  1278. * <transferType> specifies the type of data transfers for which this pipe 
  1279. * will be used:
  1280. *
  1281. * .IP "USB_XFRTYPE_CONTROL"
  1282. * Control transfer pipe (message).
  1283. * .IP "USB_XFRTYPE_ISOCH"
  1284. * Isochronous transfer pipe (stream).
  1285. * .IP "USB_XFRTYPE_INTERRUPT"
  1286. * Interrupt transfer pipe (stream).
  1287. * .IP "USB_XFRTYPE_BULK"
  1288. * Bulk transfer pipe (stream).
  1289. *
  1290. * <direction> specifies the direction of the pipe as:
  1291. *
  1292. * .IP "USB_DIR_IN"
  1293. * Data moves from device to host.
  1294. * .IP "USB_DIR_OUT"
  1295. * Data moves from host to device.
  1296. * .IP "USB_DIR_INOUT"
  1297. * Data moves bidirectionally (message pipes only).
  1298. *
  1299. * If the <direction> is specified as USB_DIR_INOUT, the USBD assumes that 
  1300. * both the IN and OUT endpoints identified by endpoint will be used by 
  1301. * this pipe (see the discussion of message pipes in Chapter 5 of the USB 
  1302. * Specification).  USB_DIR_INOUT may be specified only for Control pipes.
  1303. *
  1304. * <maxPayload> specifies the largest data payload supported by this endpoint.  
  1305. * Normally a USB device will declare the maximum payload size it supports on 
  1306. * each endpoint in its configuration descriptors.  The client will typically 
  1307. * read these descriptors using the USBD Configuration Functions and then 
  1308. * parse the descriptors to retrieve the appropriate maximum payload value.
  1309. * <bandwidth> specifies the bandwidth required for this pipe.  For control
  1310. * and bulk pipes, this parameter should be 0.  For interrupt pipes, this
  1311. * parameter should express the number of bytes per frame to be transferred.
  1312. * for isochronous pipes, this parameter should express the number of bytes
  1313. * per second to be transferred.
  1314. *
  1315. * <serviceInterval> specifies the maximum latency for the pipe in 
  1316. * milliseconds.  So, if a pipe needs to be serviced, for example, at least 
  1317. * every 20 milliseconds, then the <serviceInterval> value should be 20.  The 
  1318. * <serviceInterval> parameter is required only for interrupt pipes.  For 
  1319. * other types of pipes, <serviceInterval> should be 0.
  1320. *
  1321. * If the USBD succeeds in creating the pipe it returns a pipe handle in 
  1322. * <pPipeHandle>.  The client must use the pipe handle to identify the pipe 
  1323. * in subsequent calls to the USBD Transfer Functions.  If there is 
  1324. * insufficient bus bandwidth available to create the pipe (as might happen 
  1325. * for an isochronous or interrupt pipe), then the USBD will return an error 
  1326. * and a NULL handle in <pPipeHandle>.
  1327. *
  1328. * RETURNS: OK, or ERROR if pipe could not be create
  1329. */
  1330. STATUS usbdPipeCreate
  1331.     (
  1332.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1333.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  1334.     UINT16 endpoint, /* Endpoint number */
  1335.     UINT16 configuration, /* config w/which pipe associated */
  1336.     UINT16 interface, /* interface w/which pipe associated */
  1337.     UINT16 transferType, /* Type of transfer: control, bulk... */
  1338.     UINT16 direction, /* Specifies IN or OUT endpoint */
  1339.     UINT16 maxPayload, /* Maximum data payload per packet */
  1340.     UINT32 bandwidth, /* Bandwidth required for pipe */
  1341.     UINT16 serviceInterval, /* Required service interval */
  1342.     pUSBD_PIPE_HANDLE pPipeHandle /* pipe handle returned by USBD */
  1343.     )
  1344.     {
  1345.     URB_PIPE_CREATE urb;
  1346.     STATUS s;
  1347.     /* Initalize URB */
  1348.     urbInit (&urb.header, clientHandle, USBD_FNC_PIPE_CREATE, NULL, NULL,
  1349. sizeof (urb));
  1350.     urb.nodeId = nodeId;
  1351.     urb.endpoint = endpoint;
  1352.     urb.configuration = configuration;
  1353.     urb.interface = interface;
  1354.     urb.transferType = transferType;
  1355.     urb.direction = direction;
  1356.     urb.maxPayload = maxPayload;
  1357.     urb.bandwidth = bandwidth;
  1358.     urb.serviceInterval = serviceInterval;
  1359.     /* Execute URB */
  1360.     s = urbExecBlock (&urb.header);
  1361.     /* Return result */
  1362.     if (pPipeHandle != NULL)
  1363. *pPipeHandle = urb.pipeHandle;
  1364.     return s;
  1365.     }
  1366. /***************************************************************************
  1367. *
  1368. * usbdPipeDestroy - Destroys a USB data transfer pipe
  1369. *
  1370. * This function destroys a pipe previous created by calling usbdPipeCreate().  
  1371. * The caller must pass the <pipeHandle> originally returned by usbdPipeCreate().
  1372. *
  1373. * If there are any outstanding transfer requests for the pipe, the USBD will 
  1374. * abort those transfers prior to destroying the pipe.  
  1375. *
  1376. * RETURNS: OK, or ERROR if unable to destroy pipe.
  1377. */
  1378. STATUS usbdPipeDestroy
  1379.     (
  1380.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1381.     USBD_PIPE_HANDLE pipeHandle  /* pipe handle */
  1382.     )
  1383.     {
  1384.     URB_PIPE_DESTROY urb;
  1385.     /* Initalize URB */
  1386.     urbInit (&urb.header, clientHandle, USBD_FNC_PIPE_DESTROY, NULL, NULL,
  1387. sizeof (urb));
  1388.     urb.pipeHandle = pipeHandle;
  1389.     /* Execute URB */
  1390.     return urbExecBlock (&urb.header);
  1391.     }
  1392. /***************************************************************************
  1393. *
  1394. * usbdTransfer - Initiates a transfer on a USB pipe
  1395. *
  1396. * A client uses this function to initiate an transfer on the pipe indicated 
  1397. * by <pipeHandle>.  The transfer is described by an IRP, or I/O request 
  1398. * packet, which must be allocated and initialized by the caller prior to 
  1399. * invoking usbdTransfer().
  1400. *
  1401. * The USB_IRP structure is defined in usb.h as:
  1402. *
  1403. * .CS
  1404. * typedef struct usb_bfr_list
  1405. *     {
  1406. *     UINT16 pid;
  1407. *     pUINT8 pBfr;
  1408. *     UINT16 bfrLen;
  1409. *     UINT16 actLen;
  1410. *     } USB_BFR_LIST;
  1411. *
  1412. * typedef struct usb_irp
  1413. *     {
  1414. *     LINK usbdLink;     // used by USBD
  1415. *     pVOID usbdPtr;     // used by USBD
  1416. *     LINK hcdLink;     // used by HCD
  1417. *     pVOID hcdPtr;     // used by HCD
  1418. *     pVOID userPtr;
  1419. *     UINT16 irpLen;
  1420. *     int result;     // returned by USBD/HCD
  1421. *     IRP_CALLBACK usbdCallback;    // used by USBD
  1422. *     IRP_CALLBACK userCallback;
  1423. *     UINT16 dataToggle;     // filled in by USBD
  1424. *     UINT16 flags; 
  1425. *     UINT32 timeout;     // defaults to 5 seconds if zero
  1426. *     UINT16 startFrame;
  1427. *     UINT16 transferLen;
  1428. *     UINT16 dataBlockSize;
  1429. *     UINT16 bfrCount;
  1430. *     USB_BFR_LIST bfrList [1];
  1431. *     } USB_IRP, *pUSB_IRP;
  1432. * .CE
  1433. *
  1434. * The length of the USB_IRP structure must be stored in <irpLen> and varies 
  1435. * depending on the number of <bfrList> elements allocated at the end of the 
  1436. * structure.  By default, the default structure contains a single <bfrList>
  1437. * element, but clients may allocate a longer structure to accommodate a larger 
  1438. * number of <bfrList> elements.  
  1439. *
  1440. * <flags> define additional transfer options.  The currently defined flags are:
  1441. *
  1442. * .IP "USB_FLAG_SHORT_OK"
  1443. * Treats receive (IN) data underrun as OK.
  1444. * .IP "USB_FLAG_SHORT_FAIL"
  1445. * Treats receive (IN) data underrun as error.
  1446. * .IP "USB_FLAG_ISO_ASAP"
  1447. * Start an isochronous transfer immediately.
  1448. *
  1449. * When the USB is transferring data from a device to the host the data may 
  1450. * "underrun".  That is, the device may transmit less data than anticipated by 
  1451. * the host.  This may or may not indicate an error condition depending on the 
  1452. * design of the device.  For many devices, the underrun is completely normal 
  1453. * and indicates the end of data stream from the device.  For other devices, 
  1454. * the underrun indicates a transfer failure.  By default, the USBD and 
  1455. * underlying USB HCD (Host Controller Driver) treat underrun as the end-of-data 
  1456. * indicator and do not declare an error.  If the USB_FLAG_SHORT_FAIL flag is 
  1457. * set, then the USBD/HCD will instead treat underrun as an error condition.
  1458. *
  1459. * For isochronous transfers the USB_FLAG_ISO_ASAP specifies that the 
  1460. * isochronous transfer should begin as soon as possible.  If USB_FLAG_ISO_ASAP
  1461. * is not specified, then <startFrame> must specify the starting frame number 
  1462. * for the transfer.  The usbdCurrentFrameGet() function allows a client to
  1463. * retrieve the current frame number and a value called the frame scheduling 
  1464. * window for the underlying USB host controller.  The frame window specifies 
  1465. * the maximum number of frames into the future (relative to the current frame 
  1466. * number) which may be specified by <startFrame>.  <startFrame> should be 
  1467. * specified only for isochronous transfers.
  1468. *
  1469. * <dataBlockSize> may also be specified for isochronous transfers.  If non-0,
  1470. * the <dataBlockSize> defines the granularity of isochronous data being sent.
  1471. * When the underlying Host Controller Driver (HCD) breaks up the transfer into
  1472. * individual frames, it will ensure that the amount of data transferred in 
  1473. * each frame is a multiple of this value.  
  1474. *
  1475. * <timeout> specifies the IRP timeout in milliseconds. If the caller passes
  1476. * a value of zero, then the USBD sets a default timeout of USB_TIMEOUT_DEFAULT.
  1477. * If no timeout is desired, then <timeout> should be set to USB_TIMEOUT_NONE.
  1478. * Timeouts apply only to control and bulk transfers.  Isochronous and
  1479. * interrupt transfers do not time out.
  1480. *
  1481. * <bfrList> is an array of buffer descriptors which describe data buffers to 
  1482. * be associated with this IRP. If more than the one <bfrList> element is 
  1483. * required then the caller must allocate the IRP by calculating the size as 
  1484. *
  1485. * .CS
  1486. * irpLen = sizeof (USB_IRP) + (sizeof (USB_BFR_DESCR) * (bfrCount - 1))
  1487. * .CE
  1488. *
  1489. * <transferLen> must be the total length of data to be transferred.  In other 
  1490. * words, transferLen is the sum of all <bfrLen> entries in the <bfrList>.
  1491. *
  1492. * <pid> specifies the packet type to use for the indicated buffer and is
  1493. * specified as USB_PID_xxxx.
  1494. *
  1495. * The IRP <userCallback> routine must point to a client-supplied IRP_CALLBACK
  1496. * routine.  The usbdTransfer() function returns as soon as the IRP has been
  1497. * successfully enqueued.  If there is a failure in delivering the IRP to the
  1498. * HCD, then usbdTransfer() returns an error.  The actual result of the IRP
  1499. * should be checked after the <userCallback> routine has been invoked.
  1500. *
  1501. * RETURNS: OK, or ERROR if unable to submit IRP for transfer.
  1502. */
  1503. STATUS usbdTransfer
  1504.     (
  1505.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1506.     USBD_PIPE_HANDLE pipeHandle, /* Pipe handle */
  1507.     pUSB_IRP pIrp /* ptr to I/O request packet */
  1508.     )
  1509.     {
  1510.     URB_TRANSFER urb;
  1511.     /* Initalize URB */
  1512.     urbInit (&urb.header, clientHandle, USBD_FNC_TRANSFER, NULL, NULL,
  1513. sizeof (urb));
  1514.     urb.pipeHandle = pipeHandle;
  1515.     urb.pIrp = pIrp;
  1516.     /* Execute URB */
  1517.     return urbExecBlock (&urb.header);
  1518.     }
  1519. /***************************************************************************
  1520. *
  1521. * usbdTransferAbort - Aborts a transfer
  1522. *
  1523. * This function aborts an IRP which was previously submitted through
  1524. * a call to usbdTransfer().  
  1525. *
  1526. * RETURNS: OK, or ERROR if unable to abort transfer.
  1527. */
  1528. STATUS usbdTransferAbort
  1529.     (
  1530.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1531.     USBD_PIPE_HANDLE pipeHandle,     /* Pipe handle */
  1532.     pUSB_IRP pIrp /* ptr to I/O to abort */
  1533.     )
  1534.     {
  1535.     URB_TRANSFER urb;
  1536.     /* Initalize URB */
  1537.     urbInit (&urb.header, clientHandle, USBD_FNC_TRANSFER_ABORT, NULL, NULL,
  1538. sizeof (urb));
  1539.     urb.pipeHandle = pipeHandle;
  1540.     urb.pIrp = pIrp;
  1541.     /* Execute URB */
  1542.     return urbExecBlock (&urb.header);
  1543.     }
  1544. /***************************************************************************
  1545. *
  1546. * usbdSynchFrameGet - Returns a device's isochronous synch. frame
  1547. *
  1548. * It is sometimes necessary for clients to re-synchronize with devices when 
  1549. * the two are exchanging data isochronously.  This function allows a client
  1550. * to query a reference frame number maintained by the device.  Please refer 
  1551. * to the USB Specification for more detail.
  1552. *
  1553. * <nodeId> specifies the node to query and <endpoint> specifies the endpoint 
  1554. * on that device.  Upon return the device抯 frame number for the specified 
  1555. * endpoint is returned in <pFrameNo>.
  1556. *
  1557. * RETURNS: OK, or ERROR if unable to retrieve synch. frame.
  1558. */
  1559. STATUS usbdSynchFrameGet
  1560.     (
  1561.     USBD_CLIENT_HANDLE clientHandle, /* Client Handle */
  1562.     USBD_NODE_ID nodeId, /* Node Id of device/hub */
  1563.     UINT16 endpoint, /* Endpoint to be queried */
  1564.     pUINT16 pFrameNo /* Frame number returned by device */
  1565.     )
  1566.     {
  1567.     URB_SYNCH_FRAME_GET urb;
  1568.     STATUS s;
  1569.     /* Initalize URB */
  1570.     urbInit (&urb.header, clientHandle, USBD_FNC_SYNCH_FRAME_GET, NULL, NULL,
  1571. sizeof (urb));
  1572.     urb.nodeId = nodeId;
  1573.     urb.endpoint = endpoint;
  1574.     /* Execute URB */
  1575.     s = urbExecBlock (&urb.header);
  1576.     /* Return result */
  1577.     if (pFrameNo != NULL)
  1578. *pFrameNo = urb.frameNo;
  1579.     return s;
  1580.     }
  1581. /***************************************************************************
  1582. *
  1583. * usbdCurrentFrameGet - Returns the current frame number for a USB
  1584. *
  1585. * It is sometimes necessary for clients to retrieve the current USB frame 
  1586. * number for a specified host controller.  This function allows a client to 
  1587. * retrieve the current USB frame number for the host controller to which
  1588. * <nodeId> is connected.  Upon return, the current frame number is stored 
  1589. * in <pFrameNo>.
  1590. *
  1591. * If <pFrameWindow> is not NULL, the USBD will also return the maximum frame 
  1592. * scheduling window for the indicated USB host controller.  The frame 
  1593. * scheduling window is essentially the number of unique frame numbers 
  1594. * tracked by the USB host controller.  Most USB host controllers maintain an 
  1595. * internal frame count which is a 10- or 11-bit number, allowing them to 
  1596. * track typically 1024 or 2048 unique frames.  When starting an isochronous 
  1597. * transfer, a client may wish to specify that the transfer will begin in a 
  1598. * specific USB frame.  For the given USB host controller, the starting frame 
  1599. * number can be no more than <frameWindow> frames from the current <frameNo>.
  1600. *
  1601. * Note: The USBD is capable of simultaneously managing multiple USB host 
  1602. * controllers, each of which operates independently.  Therefore, it is 
  1603. * important that the client specify the correct <nodeId> when retrieving the 
  1604. * current frame number.  Typically, a client will be interested in the 
  1605. * current frame number for the host controller to which a specific device is 
  1606. * attached.
  1607. *
  1608. * RETURNS: OK, or ERROR if unable to retrieve current frame number.
  1609. */
  1610. STATUS usbdCurrentFrameGet
  1611.     (
  1612.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1613.     USBD_NODE_ID nodeId, /* Node Id of node on desired USB */
  1614.     pUINT32 pFrameNo, /* bfr to receive current frame no. */
  1615.     pUINT32 pFrameWindow /* bfr to receive frame window */
  1616.     )
  1617.     {
  1618.     URB_CURRENT_FRAME_GET urb;
  1619.     STATUS s;
  1620.     /* Initalize URB */
  1621.     urbInit (&urb.header, clientHandle, USBD_FNC_CURRENT_FRAME_GET, NULL, NULL,
  1622. sizeof (urb));
  1623.     urb.nodeId = nodeId;
  1624.     /* Execute URB */
  1625.     s = urbExecBlock (&urb.header);
  1626.     /* Return result */
  1627.     if (pFrameNo != NULL)
  1628. *pFrameNo = urb.frameNo;
  1629.     if (pFrameWindow != NULL)
  1630. *pFrameWindow = urb.frameWindow;
  1631.     return s;
  1632.     }
  1633. /***************************************************************************
  1634. *
  1635. * usbdSofMasterTake - Takes SOF master ownership
  1636. *
  1637. * A client which is performing isochronous transfers may need to adjust
  1638. * the USB frame time by a small amount in order to synchronize correctly
  1639. * with one or more devices.  In order to adjust the USB frame interval,
  1640. * a client must first attempt to become the "SOF Master" for bus to which
  1641. * a device is attached.
  1642. *
  1643. * <nodeId> specifies the id of a node on the bus for which the client
  1644. * wishes to become the SOF master.  Each USB managed by the USBD may have
  1645. * a different SOF master.
  1646. *
  1647. * RETURNS: OK, or ERROR if client cannot become SOF master
  1648. */
  1649. STATUS usbdSofMasterTake
  1650.     (
  1651.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1652.     USBD_NODE_ID nodeId  /* Node Id of node on desired USB */
  1653.     )
  1654.     
  1655.     {
  1656.     URB_SOF_MASTER urb;
  1657.     /* Initalize URB */
  1658.     urbInit (&urb.header, clientHandle, USBD_FNC_SOF_MASTER_TAKE, NULL, NULL,
  1659. sizeof (urb));
  1660.     urb.nodeId = nodeId;
  1661.     /* Execute URB */
  1662.     return urbExecBlock (&urb.header);
  1663.     }
  1664. /***************************************************************************
  1665. *
  1666. * usbdSofMasterRelease - Releases ownership of SOF master
  1667. *
  1668. * A client which has previously become the SOF master for a given USB
  1669. * may release SOF master status by calling this function.  <nodeId> should
  1670. * identify a node on the USB for which SOF master ownership should be 
  1671. * released.
  1672. *
  1673. * RETURNS: OK, or ERROR if SOF ownership cannot be released
  1674. */
  1675. STATUS usbdSofMasterRelease
  1676.     (
  1677.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1678.     USBD_NODE_ID nodeId  /* Node Id of node on desired USB */
  1679.     )
  1680.     
  1681.     {
  1682.     URB_SOF_MASTER urb;
  1683.     /* Initalize URB */
  1684.     urbInit (&urb.header, clientHandle, USBD_FNC_SOF_MASTER_RELEASE, NULL, NULL,
  1685. sizeof (urb));
  1686.     urb.nodeId = nodeId;
  1687.     /* Execute URB */
  1688.     return urbExecBlock (&urb.header);
  1689.     }
  1690. /***************************************************************************
  1691. *
  1692. * usbdSofIntervalGet - Retrieves current SOF interval for a bus
  1693. *
  1694. * This function retrieves the current SOF interval for the bus to which
  1695. * <nodeId> is connected.  The SOF interval returned in <pSofInterval> is
  1696. * expressed in high speed bit times in a frame, with 12,000 being the 
  1697. * typical default value.
  1698. *
  1699. * NOTE: A client does not need to be the current SOF master in order to
  1700. * retrieve the SOF interval for a bus.
  1701. *
  1702. * RETURNS: OK, or ERROR if SOF interval cannot be retrieved.
  1703. */
  1704. STATUS usbdSofIntervalGet
  1705.     (
  1706.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1707.     USBD_NODE_ID nodeId, /* Node Id of node on desired USB */
  1708.     pUINT16 pSofInterval /* bfr to receive SOF interval */
  1709.     )
  1710.     {
  1711.     URB_SOF_INTERVAL_GET_SET urb;
  1712.     STATUS s;
  1713.     /* Initalize URB */
  1714.     urbInit (&urb.header, clientHandle, USBD_FNC_SOF_INTERVAL_GET, NULL, 
  1715. NULL, sizeof (urb));
  1716.     urb.nodeId = nodeId;
  1717.     /* Execute URB */
  1718.     s = urbExecBlock (&urb.header);
  1719.     /* return results */
  1720.     if (pSofInterval != NULL)
  1721. *pSofInterval = urb.sofInterval;
  1722.     return s;
  1723.     }
  1724. /***************************************************************************
  1725. *
  1726. * usbdSofIntervalSet - Sets current SOF interval for a bus
  1727. *
  1728. * This function sets the SOF interval for the bus to which <nodeId> is
  1729. * connected to the number of bit times specified in <sofInterval>.  In
  1730. * order to call this function, a client must first become the "SOF master"
  1731. * for the indicated bus by calling usbdSofMasterTake().
  1732. *
  1733. * RETURNS: OK, or ERROR if cannot set SOF interval.
  1734. */
  1735. STATUS usbdSofIntervalSet
  1736.     (
  1737.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1738.     USBD_NODE_ID nodeId, /* Node Id of node on desired USB */
  1739.     UINT16 sofInterval /* new SOF interval */
  1740.     )
  1741.     {
  1742.     URB_SOF_INTERVAL_GET_SET urb;
  1743.     /* Initalize URB */
  1744.     urbInit (&urb.header, clientHandle, USBD_FNC_SOF_INTERVAL_SET, NULL, NULL, 
  1745. sizeof (urb));
  1746.     urb.nodeId = nodeId;
  1747.     urb.sofInterval = sofInterval;
  1748.     /* Execute URB */
  1749.     return urbExecBlock (&urb.header);
  1750.     }
  1751. /***************************************************************************
  1752. *
  1753. * usbdVersionGet - Returns USBD version information
  1754. *
  1755. * This function returns the USBD version.  If <pVersion> is not NULL, the 
  1756. * USBD returns its version in BCD in <pVersion>.  For example, version 
  1757. * "1.02" would be coded as 01h in the high byte and 02h in the low byte.
  1758. *
  1759. * If <pMfg> is not NULL it must point to a buffer of at least USBD_NAME_LEN 
  1760. * bytes in length in which the USBD will store the NULL terminated name of
  1761. * the USBD manufacturer (e.g., "Wind River Systems" + ).
  1762. *
  1763. * RETURNS: OK, or ERROR if unable to retrieve USBD version info.
  1764. */
  1765. STATUS usbdVersionGet
  1766.     (
  1767.     pUINT16 pVersion, /* UINT16 bfr to receive version */
  1768.     pCHAR pMfg /* bfr to receive USBD mfg string */
  1769.     )
  1770.     {
  1771.     URB_VERSION_GET urb;
  1772.     STATUS s;
  1773.     /* Initalize URB */
  1774.     urbInit (&urb.header, NULL, USBD_FNC_VERSION_GET, NULL, NULL,
  1775. sizeof (urb));
  1776.     /* Execute URB */
  1777.     s = urbExecBlock (&urb.header);
  1778.     /* Return result */
  1779.     if (pVersion != NULL)
  1780. *pVersion = urb.version;
  1781.     if (pMfg != NULL)
  1782. strncpy (pMfg, (char *)urb.mfg, USBD_NAME_LEN + 1);
  1783.     return s;
  1784.     }
  1785. /***************************************************************************
  1786. *
  1787. * usbdHcdAttach - Attaches an HCD to the USBD
  1788. *
  1789. * A special client or system initialization code must call the
  1790. * usbdHcdAttach() function to register at least one HCD (Host Controller 
  1791. * Driver) with the USBD.  Most systems will call this function at system 
  1792. * initialization in order to register one or more HCDs.  However, the USBD 
  1793. * is capable of supporting the attachment and removal of host controllers 
  1794. * and their associated HCDs at runtime.  Systems which implement hot-swap 
  1795. * capabilities may find this of use.
  1796. * This is one of the few USBD functions which does not require a caller 
  1797. * first to register using the usbdClientRegister() function, so there is 
  1798. * no need to pass a USBD_CLIENT_HANDLE to this function as there is with 
  1799. * most other USBD functions.
  1800. *
  1801. * The <hcdExecFunc> passed by the caller must point to an HCD抯 primary
  1802. * entry point as defined below:
  1803. *
  1804. * .CS
  1805. * typedef UINT16 (*HCD_EXEC_FUNC) (pHRB_HEADER pHrb);
  1806. * .CE
  1807. *
  1808. * The USBD will invoke the <hcdExecFunc> with an "attach" request which
  1809. * includes the <param> passed to the usbdHcdAttach() function. The <param> 
  1810. * is HCD-specific and is not defined in this specification.  
  1811. *
  1812. * If the HCD attach is successful, the USBD will then proceed to 
  1813. * initialize the USB(s) associated with the HCD by calling its
  1814. * HCD_EXEC_FUNC repeatedly.  If the initialization is completely 
  1815. * successful, the USBD returns a non-NULL attach token in <pAttachToken>.  
  1816. * If the caller needs to request the USBD to detach this HCD in the 
  1817. * future, it must pass the attach token value to the usbdHcdDetach() 
  1818. * function.  If usbdHcdAttach() fails to initialize the HCD successfully, 
  1819. * it returns an error and a NULL value in <pAttachToken>.  The caller 
  1820. * should not call usbdHcdDetach() for an HCD which failed to initialize 
  1821. * successfully.
  1822. *
  1823. * A complete description of the <param>, the HCD_EXEC_FUNC, and the 
  1824. * USBD/HCD initialization sequence is beyond the scope of this document.  
  1825. * For a complete description of the HCD, please refer to the .I "Wind 
  1826. * River USB Host Controller Hardware Abstraction Interface Specification."
  1827. *
  1828. * Note: A system which implements multiple USB host controllers which are 
  1829. * compatible with a single HCD may select one of two approaches to 
  1830. * initialization.  In the first approach, the usbdHcdAttach() function 
  1831. * may be called a single time with the <hcdExecFunc> for the HCD and the 
  1832. * HCD may reveal multiple USB host controllers to the USBD.  In the second 
  1833. * approach, the usbdHcdAttach() function may be called multiple times, 
  1834. * once for each USB host controller, and the HCD may reveal only a single 
  1835. * USB host controller to the USBD each time.  Each approach has advantages 
  1836. * and the approach selected is up to the system vendor responsible for 
  1837. * implementing the HCD.
  1838. *
  1839. * RETURNS: OK, or ERROR if unable to attach HCD.
  1840. */
  1841. STATUS usbdHcdAttach
  1842.     (
  1843.     HCD_EXEC_FUNC hcdExecFunc, /* Ptr to HCD抯 primary entry point */
  1844.     pVOID param, /* HCD-specific parameter */
  1845.     pGENERIC_HANDLE pAttachToken /* Token to identify HCD in future */
  1846.     )
  1847.     {
  1848.     URB_HCD_ATTACH urb;
  1849.     STATUS s;
  1850.     /* Initalize URB */
  1851.     urbInit (&urb.header, NULL, USBD_FNC_HCD_ATTACH, NULL, NULL,
  1852. sizeof (urb));
  1853.     urb.hcdExecFunc = hcdExecFunc;
  1854.     urb.param = param;
  1855.     /* Execute URB */
  1856.     s = urbExecBlock (&urb.header);
  1857.     /* Return result */
  1858.     if (pAttachToken != NULL)
  1859. *pAttachToken = urb.attachToken;
  1860.     return s;
  1861.     }
  1862. /***************************************************************************
  1863. *
  1864. * usbdHcdDetach - Detaches an HCD from the USBD
  1865. *
  1866. * This function is typically called during system shutdown to instruct the 
  1867. * USBD to detach from an HCD to which it had previously attached in response 
  1868. * to a call to usbdHcdAttach().  Certain systems may also call this function 
  1869. * at runtime in order to detach a USB host controller and its associated HCD
  1870. * in order to implement hot-swapping.
  1871. *
  1872. * The <attachToken> must be the attach token originally returned by 
  1873. * usbdHcdAttach() when it first attached to the HCD. 
  1874. *
  1875. * RETURNS: OK, or ERROR if unable to detach HCD.
  1876. */
  1877. STATUS usbdHcdDetach
  1878.     (
  1879.     GENERIC_HANDLE attachToken /* AttachToken returned */
  1880.     )
  1881.     {
  1882.     URB_HCD_DETACH urb;
  1883.     /* Initalize URB */
  1884.     urbInit (&urb.header, NULL, USBD_FNC_HCD_DETACH, NULL, NULL,
  1885. sizeof (urb));
  1886.     urb.attachToken = attachToken;
  1887.     /* Execute URB */
  1888.     return urbExecBlock (&urb.header);
  1889.     }
  1890. /***************************************************************************
  1891. *
  1892. * usbdStatisticsGet - Retrieves USBD operating statistics
  1893. *
  1894. * This function returns operating statistics for the USB to which the
  1895. * specified <nodeId> is connected.    
  1896. *
  1897. * The USBD copies the current operating statistics into the <pStatistics>
  1898. * structure provided by the caller.  This structure is defined as:
  1899. *
  1900. * .CS
  1901. * typedef struct usbd_stats
  1902. *     {
  1903. *     UINT16 totalTransfersIn;
  1904. *     UINT16 totalTransfersOut;
  1905. *     UINT16 totalReceiveErrors;
  1906. *     UINT16 totalTransmitErrors;
  1907. *     } USBD_STATS, *pUSBD_STATS;
  1908. * .CE
  1909. *
  1910. * It is anticipated that this structure may grow over time.  To provide 
  1911. * backwards compatibility, the client must pass the total size of the 
  1912. * USBD_STATS structure it has allocated in <statLen>.  The USBD will copy 
  1913. * fields into this structure only up to the statLen indicated by the caller.
  1914. *
  1915. * RETURNS: OK, or ERROR if unable to retrieve operating statistics.
  1916. */
  1917. STATUS usbdStatisticsGet
  1918.     (
  1919.     USBD_CLIENT_HANDLE clientHandle, /* Client handle */
  1920.     USBD_NODE_ID nodeId, /* Node Id of node on desired USB */
  1921.     pUSBD_STATS pStatistics, /* Ptr to structure to receive stats */
  1922.     UINT16 statLen /* Len of bfr provided by caller */
  1923.     )
  1924.     {
  1925.     URB_STATISTICS_GET urb;
  1926.     /* Initalize URB */
  1927.     urbInit (&urb.header, clientHandle, USBD_FNC_STATISTICS_GET, NULL, NULL,
  1928. sizeof (urb));
  1929.     urb.nodeId = nodeId;
  1930.     urb.pStatistics = pStatistics;
  1931.     urb.statLen = statLen;
  1932.     /* Execute URB */
  1933.     return urbExecBlock (&urb.header);
  1934.     }
  1935. /* End of file. */