usbLib.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:15k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* usbLib.c - USB utility functions */
  2. /* Copyright 2000-2002 Wind River Systems, Inc. */
  3. /*
  4. Modification history
  5. --------------------
  6. 01l,09nov01,wef  Test for NULL on OSS_xALLOC calls, change sizeof () to 
  7.  structure size macros
  8. 01k,25oct01,wef  repalce automatic buffer creations with calls to OSS_MALLOC
  9.                  in places where the buffer is passed to the hardware (related
  10.                  to SPR 70492).
  11. 01j,18sep01,wef  merge from wrs.tor2_0.usb1_1-f for veloce
  12. 01e,25jul01,jgn  fixed spr 69287
  13. 01d,26jan00,rcb  Modify usbRecurringTime() to accept <bandwidth> instead
  14.  of <bytesPerFrame>.
  15.  Add usbDescrCopy32() and usbDescrStrCopy32().
  16. 01c,17jan00,rcb  Add usbConfigDescrGet() function.
  17. 01b,23nov99,rcb  Add usbRecurringTime() function.
  18. 01a,16jul99,rcb  First.
  19. */
  20. /*
  21. DESCRIPTION
  22. This modules contains miscellaneous functions which may be used by the
  23. USB driver (USBD), USB HCD (USB Host Controller Driver), or by USBD clients.
  24. */
  25. /* includes */
  26. #include "usb/usbPlatform.h"
  27. #include "string.h"
  28. #include "usb/usbdLib.h"
  29. #include "usb/usbLib.h"
  30. /* defines */
  31. /* USB time constants.
  32.  *
  33.  * NOTE: The following constants use units of picoseconds for improved
  34.  * calculation resolution.  The calcTdTime() function - below - rounds
  35.  * the final calculated to the next higher nanosecond, and returns the
  36.  * calculated value in terms of nanoseconds.
  37.  */
  38. #define TIME_OVRHD_INPUT_NON_ISOCH  ((UINT32) 9107000L)
  39. #define TIME_OVRHD_INPUT_ISOCH     ((UINT32) 7268000L)
  40. #define TIME_OVRHD_OUTPUT_NON_ISOCH ((UINT32) 9107000L)
  41. #define TIME_OVRHD_OUTPUT_ISOCH     ((UINT32) 6265000L)
  42. #define TIME_OVRHD_INPUT_LS     ((UINT32) 64060000L)
  43. #define TIME_OVRHD_OUTPUT_LS     ((UINT32) 64107000L)
  44. #define TIME_BIT     ((UINT32) 83540L)
  45. #define TIME_BIT_LS_INPUT     ((UINT32) 676670L)
  46. #define TIME_BIT_LS_OUTPUT     ((UINT32) 667000L)
  47. /* BIT_STUFF calculates the worst case number of bits for the indicated
  48.  * number of bytes.  (The "19" in the following equation is equal to
  49.  * 3.167*6.  Since 19 is added to the bit total which is then divided by
  50.  * 6, this has the effect of ading 3.167 bit times to the total.
  51.  */
  52. #define BIT_STUFF(bytes)    ((UINT32) ((((UINT32) bytes) * 8 * 7 + 19) / 6))
  53. /* functions */
  54. /***************************************************************************
  55. *
  56. * usbTransferTime - Calculates bus time required for a USB transfer
  57. *
  58. * This function calculates the amount of time a transfer of a given number
  59. * of bytes will require on the bus - measured in nanoseconds (10E-9 seconds).  
  60. * The formulas used here are taken from Section 5.9.3 of Revision 1.1 of the 
  61. * USB spec.
  62. *
  63. * <transferType>, <direction>, and <speed> should describe the characteristics
  64. * of the pipe/transfer as USB_XFRTYPE_xxxx, USB_DIR_xxxx, and USB_SPEED_xxxx,
  65. * repsectively.  <bytes> is the size of the packet for which the transfer time 
  66. * should be calculated. <hostDelay> and <hostHubLsSetup> are the host delay and 
  67. * low-speed hub setup times in nanoseconds, respectively, and are host-controller 
  68. * specific.
  69. *
  70. * RETURNS: Worst case number of nanoseconds required for transfer
  71. */
  72. UINT32 usbTransferTime
  73.     (
  74.     UINT16 transferType, /* transfer type */
  75.     UINT16 direction, /* transfer direction */
  76.     UINT16 speed, /* speed of pipe */
  77.     UINT32 bytes, /* number of bytes for packet to be calc'd */
  78.     UINT32 hostDelay, /* host controller delay per packet */
  79.     UINT32 hostHubLsSetup /* host controller time for low-speed setup */
  80.     )
  81.     {
  82.     UINT32 bits = BIT_STUFF (bytes);
  83.     UINT32 ps;
  84.     if (speed == USB_SPEED_FULL)
  85. {
  86. if (direction == USB_DIR_IN)
  87.     {
  88.     if (transferType == USB_XFRTYPE_ISOCH)
  89. {
  90. ps = TIME_OVRHD_INPUT_ISOCH + TIME_BIT * bits;
  91. }
  92.     else
  93. {
  94. ps = TIME_OVRHD_INPUT_NON_ISOCH + TIME_BIT * bits;
  95. }
  96.     }
  97. else
  98.     {
  99.     if (transferType == USB_XFRTYPE_ISOCH)
  100. {
  101. ps = TIME_OVRHD_OUTPUT_ISOCH + TIME_BIT * bits;
  102. }
  103.     else
  104. {
  105. ps = TIME_OVRHD_OUTPUT_NON_ISOCH + TIME_BIT * bits;
  106. }
  107.     }
  108. }
  109.     else
  110. {
  111. if (direction == USB_DIR_IN)
  112.     {
  113.     ps = TIME_OVRHD_INPUT_LS + 2 * hostHubLsSetup * 1000L + 
  114. TIME_BIT_LS_INPUT * bits;
  115.     }
  116. else
  117.     {
  118.     ps = TIME_OVRHD_OUTPUT_LS + 2 * hostHubLsSetup * 1000L +
  119. TIME_BIT_LS_OUTPUT * bits;
  120.     }
  121. }
  122.     ps += hostDelay * 1000L;
  123.     return (ps + 999L) / 1000L;     /* returns value in nanoseconds */
  124.     }
  125. /***************************************************************************
  126. *
  127. * usbRecurringTime - calculates recurring time for interrupt/isoch transfers
  128. *
  129. * For recurring transfers (e.g., interrupt or isochronous transfers) an HCD
  130. * needs to be able to calculate the amount of bus time - measured in 
  131. * nanoseconds - which will be used by the transfer.
  132. *
  133. * <transferType> specifies the type of transfer.  For USB_XFRTYPE_CONTROL and
  134. * USB_XFRTYPE_BULK, the calculated time is always 0...these are not recurring
  135. * transfers.  For USB_XFRTYPE_INTERRUPT, <bandwidth> must express the number
  136. * of bytes to be transferred in each frame.  For USB_XFRTYPE_ISOCH, <bandwidth>
  137. * must express the number of bytes to be transferred in each second.  The
  138. * parameter is treated differently to allow greater flexibility in determining
  139. * the true bandwidth requirements for each type of pipe.
  140. *
  141. * RETURNS: worst case number of nanoseconds required for transfer.
  142. */
  143. UINT32 usbRecurringTime
  144.     (
  145.     UINT16 transferType, /* transfer type */
  146.     UINT16 direction, /* transfer direction */
  147.     UINT16 speed, /* speed of pipe */
  148.     UINT16 packetSize, /* max packet size for endpoint */
  149.     UINT32 bandwidth, /* bytes/frame or bytes/sec depending on pipe */
  150.     UINT32 hostDelay, /* host controller delay per packet */
  151.     UINT32 hostHubLsSetup /* host controller time for low-speed setup */
  152.     )
  153.     {
  154.     UINT16 packets;
  155.     UINT32 nanosecondsPerPacket;
  156.     UINT16 remainderBytes;
  157.     UINT32 remainderNanoseconds;
  158.     UINT32 bytesPerFrame;
  159.     /* Non-recurring transfers always return 0. */
  160.     if (transferType == USB_XFRTYPE_CONTROL || transferType == USB_XFRTYPE_BULK)
  161. return 0;
  162.     /* Calculate time for recurring transfer */
  163.     if (transferType == USB_XFRTYPE_INTERRUPT)
  164. bytesPerFrame = bandwidth;
  165.     else /* transferType == USB_XFRTYPE_ISOCH */
  166. bytesPerFrame = (bandwidth + 999L) / 1000L;
  167.     packets = bytesPerFrame / packetSize;
  168.     remainderBytes = bytesPerFrame % packetSize;
  169.     nanosecondsPerPacket = usbTransferTime (transferType, direction,
  170. speed, packetSize, hostDelay, hostHubLsSetup);
  171.     if (remainderBytes > 0)
  172. remainderNanoseconds = usbTransferTime (transferType, direction, 
  173.     speed, remainderBytes, hostDelay, hostHubLsSetup);
  174.     else
  175. remainderNanoseconds = 0;
  176.     return packets * nanosecondsPerPacket + remainderNanoseconds;
  177.     }
  178. /***************************************************************************
  179. *
  180. * usbDescrParseSkip - search for a descriptor and increment buffer
  181. *
  182. * Searches <ppBfr> up to <pBfrLen> bytes for a descriptor of type matching
  183. * <descriptorType>.  Returns a pointer to the descriptor if found.  <ppBfr> 
  184. * and <pBfrLen> are updated to reflect the next location in the buffer and 
  185. * the remaining size of the buffer, respectively.
  186. *
  187. * RETURNS: pointer to indicated descriptor, or NULL if descr not found.
  188. */
  189. pVOID usbDescrParseSkip
  190.     (
  191.     pUINT8 *ppBfr, /* buffer to parse */
  192.     pUINT16 pBfrLen, /* length of buffer to parse */
  193.     UINT8 descriptorType /* type of descriptor being sought */
  194.     )
  195.     {
  196.     pUSB_DESCR_HDR pHdr;
  197.     /* The remaining buffer length must be at least two bytes to accommodate
  198.      * the descriptor length and descriptorType fields.  If not, we're done. 
  199.      */
  200.     while (*pBfrLen >= sizeof (pHdr->length) + sizeof (pHdr->descriptorType))
  201. {
  202. pHdr = (pUSB_DESCR_HDR) *ppBfr;
  203. if (pHdr->length == 0)
  204.     return NULL; /* must be invalid */
  205. *ppBfr += min (pHdr->length, *pBfrLen);
  206. *pBfrLen -= min (pHdr->length, *pBfrLen);
  207. if (pHdr->descriptorType == descriptorType)
  208.     return (pVOID) pHdr;
  209. }
  210.     return NULL;
  211.     }
  212.     
  213. /***************************************************************************
  214. *
  215. * usbDescrParse - search a buffer for the a particular USB descriptor
  216. *
  217. * Searches <pBfr> up to <bfrLen> bytes for a descriptor of type matching
  218. * <descriptorType>.  Returns a pointer to the descriptor if found. 
  219. *
  220. * RETURNS: pointer to indicated descriptor, or NULL if descr not found
  221. */
  222. pVOID usbDescrParse
  223.     (
  224.     pUINT8 pBfr, /* buffer to parse */
  225.     UINT16 bfrLen, /* length of buffer to parse */
  226.     UINT8 descriptorType /* type of descriptor being sought */
  227.     )
  228.     {
  229.     return usbDescrParseSkip (&pBfr, &bfrLen, descriptorType);
  230.     }
  231. /***************************************************************************
  232. *
  233. * usbConfigCountGet - Retrieves number of device configurations
  234. *
  235. * Using the <usbdClientHandle> provided by the caller, this function
  236. * reads the <nodeId>'s device descriptor and returns the number of 
  237. * configurations supported by the device in <pNumConfig>.
  238. *
  239. * RETURNS: OK, or ERROR if unable to read device descriptor
  240. */
  241. STATUS usbConfigCountGet
  242.     (
  243.     USBD_CLIENT_HANDLE usbdClientHandle,    /* caller's USBD client handle */
  244.     USBD_NODE_ID nodeId,     /* device node ID */
  245.     pUINT16 pNumConfig     /* bfr to receive nbr of config */
  246.     )
  247.     {
  248.     USB_DEVICE_DESCR * pDevDescr;
  249.     UINT16 actLen;
  250.     if ((pDevDescr = OSS_MALLOC (USB_DEVICE_DESCR_LEN)) == NULL)
  251. return ERROR;
  252.     /* Read the device descriptor to determine the number of configurations. */
  253.     if (usbdDescriptorGet (usbdClientHandle, 
  254.    nodeId, 
  255.    USB_RT_STANDARD | USB_RT_DEVICE, USB_DESCR_DEVICE, 
  256.    0, 
  257.    0, 
  258.    USB_DEVICE_DESCR_LEN, 
  259.    (UINT8 *) pDevDescr, 
  260.    &actLen) != OK ||
  261. actLen < USB_DEVICE_DESCR_LEN)
  262. {
  263. OSS_FREE (pDevDescr);
  264. return ERROR;
  265. }
  266.     if (pNumConfig)
  267. *pNumConfig = pDevDescr->numConfigurations;
  268.     OSS_FREE (pDevDescr);
  269.     return OK;
  270.     }
  271. /***************************************************************************
  272. *
  273. * usbConfigDescrGet - reads full configuration descriptor from device
  274. *
  275. * This function reads the configuration descriptor <cfgNo> and all associated
  276. * descriptors (interface, endpoint, etc.) for the device specified by
  277. * <nodeId>.  The total amount of data returned by a device is variable,
  278. * so, this function pre-reads just the configuration descriptor and uses
  279. * the "totalLength" field from that descriptor to determine the total
  280. * length of the configuration descriptor and its associated descriptors.
  281. *
  282. * This function uses the macro OSS_MALLOC() to allocate a buffer for the
  283. * complete descriptor. The size and location of the buffer are returned
  284. * in <ppBfr and pBfrLen>.  It is the caller's responsibility to free the
  285. * buffer using the OSS_FREE() macro.
  286. *
  287. * RETURNS: OK, or ERROR if unable to read descriptor
  288. */
  289. STATUS usbConfigDescrGet
  290.     (
  291.     USBD_CLIENT_HANDLE usbdClientHandle,    /* caller's USBD client handle */
  292.     USBD_NODE_ID nodeId,     /* device node ID */
  293.     UINT16 cfgNo,     /* specifies configuration nbr */
  294.     pUINT16 pBfrLen,     /* receives length of buffer */
  295.     pUINT8 *ppBfr     /* receives pointer to buffer */
  296.     )
  297.     {
  298.     USB_CONFIG_DESCR * pCfgDescr;
  299.     UINT16 actLen;
  300.     UINT16 totalLength;
  301.     pUINT8 pBfr;
  302.     if ((pCfgDescr = OSS_MALLOC (USB_CONFIG_DESCR_LEN)) == NULL)
  303. return ERROR;
  304.     /* Validate parameters.  ppBfr must be non-NULL */
  305.     if (ppBfr == NULL)
  306. return ERROR;
  307.     *ppBfr = NULL;
  308.     /* Read the configuration descriptor to determine the totalLengh of the
  309.      * configuration.
  310.      */
  311.     if (usbdDescriptorGet (usbdClientHandle, 
  312.    nodeId, 
  313.    USB_RT_STANDARD | USB_RT_DEVICE, 
  314.    USB_DESCR_CONFIGURATION, 
  315.    cfgNo, 
  316.    0, 
  317.    USB_CONFIG_DESCR_LEN, 
  318.    (UINT8 *) pCfgDescr, 
  319.    &actLen) 
  320. != OK ||
  321. actLen < USB_CONFIG_DESCR_LEN)
  322. {
  323. OSS_FREE (pCfgDescr);
  324. return ERROR;
  325. }
  326.     totalLength = FROM_LITTLEW (pCfgDescr->totalLength);
  327.     OSS_FREE (pCfgDescr);
  328.     if (pBfrLen != NULL)
  329. *pBfrLen = totalLength;
  330.     /* Allocate a buffer of totalLength bytes. */
  331.     if ((pBfr = OSS_MALLOC (totalLength)) == NULL)
  332. return ERROR;
  333.     /* Read the full configuration descriptor. */
  334.     if (usbdDescriptorGet (usbdClientHandle, nodeId,
  335. USB_RT_STANDARD | USB_RT_DEVICE, USB_DESCR_CONFIGURATION, 
  336. cfgNo, 0, totalLength, pBfr, NULL) != OK)
  337. {
  338. OSS_FREE (pBfr);
  339. return ERROR;
  340. }
  341.     *ppBfr = pBfr;
  342.     return OK;
  343.     }
  344. /***************************************************************************
  345. *
  346. * usbHidReportSet - Issues a SET_REPORT request to a USB HID
  347. *
  348. * Using the <usbdClientHandle> provided by the caller, this function 
  349. * issues a SET_REPORT request to the indicated <nodeId>.  The caller
  350. * must also specify the <interface>, <reportType>, <reportId>, <reportBfr>,
  351. * and <reportLen>.  Refer to Section 7.2.2 of the USB HID specification
  352. * for further detail.
  353. *
  354. * RETURNS: OK, or ERROR if unable to issue SET_REPORT request.
  355. */
  356. STATUS usbHidReportSet
  357.     (
  358.     USBD_CLIENT_HANDLE usbdClientHandle,    /* caller's USBD client handle */
  359.     USBD_NODE_ID nodeId,     /* desired node */
  360.     UINT16 interface,     /* desired interface */
  361.     UINT16 reportType,     /* report type */
  362.     UINT16 reportId,     /* report Id */
  363.     pUINT8 reportBfr,     /* report value */
  364.     UINT16 reportLen     /* length of report */
  365.     )
  366.     {
  367.     UINT16 actLen;
  368.     if (usbdVendorSpecific (usbdClientHandle, nodeId,
  369. USB_RT_HOST_TO_DEV | USB_RT_CLASS | USB_RT_INTERFACE,
  370. USB_REQ_HID_SET_REPORT, (reportType << 8) | reportId, interface,
  371. reportLen, reportBfr, &actLen) != OK ||
  372. actLen < reportLen)
  373. return ERROR;
  374.     return OK;
  375.     }
  376. /***************************************************************************
  377. *
  378. * usbHidIdleSet - Issues a SET_IDLE request to a USB HID
  379. *
  380. * Using the <usbdClientHandle> provided by the caller, this function
  381. * issues a SET_IDLE request to the indicated <nodeId>. The caller must
  382. * also specify the <interface>, <reportId>, and <duration>.  If the 
  383. * <duration> is zero, the idle period is infinite.  If <duration> is
  384. * non-zero, then it expresses time in 4msec units (e.g., a <duration>
  385. * of 1 = 4msec, 2 = 8msec, and so forth).  Refer to Section 7.2.4 of the 
  386. * USB HID specification for further details.
  387. *
  388. * RETURNS: OK, or ERROR if unable to issue SET_IDLE request.
  389. */
  390. STATUS usbHidIdleSet
  391.     (
  392.     USBD_CLIENT_HANDLE usbdClientHandle,    /* caller's USBD client handle */
  393.     USBD_NODE_ID nodeId,     /* desired node */
  394.     UINT16 interface,     /* desired interface */
  395.     UINT16 reportId,     /* desired report */
  396.     UINT16 duration     /* idle duration */
  397.     )
  398.     {
  399.     return usbdVendorSpecific (usbdClientHandle, nodeId,
  400. USB_RT_HOST_TO_DEV | USB_RT_CLASS | USB_RT_INTERFACE,
  401. USB_REQ_HID_SET_IDLE, (duration << 8) | reportId, interface,
  402. 0, NULL, NULL);
  403.     }
  404. /***************************************************************************
  405. *
  406. * usbHidProtocolSet - Issues a SET_PROTOCOL request to a USB HID
  407. *
  408. * Using the <usbdClientHandle> provided by the caller, this function
  409. * issues a SET_PROTOCOL request to the indicated <nodeId>.  The caller
  410. * must specify the <interface> and the desired <protocol>.  The <protocol>
  411. * is expressed as USB_HID_PROTOCOL_xxxx.  Refer to Section 7.2.6 of the
  412. * USB HID specification for further details.
  413. *
  414. * RETURNS: OK, or ERROR if unable to issue SET_PROTOCOL request.
  415. */
  416. STATUS usbHidProtocolSet
  417.     (
  418.     USBD_CLIENT_HANDLE usbdClientHandle,    /* caller's USBD client handle */
  419.     USBD_NODE_ID nodeId,     /* desired node */
  420.     UINT16 interface,     /* desired interface */
  421.     UINT16 protocol     /* USB_HID_PROTOCOL_xxxx */
  422.     )
  423.     {
  424.     return usbdVendorSpecific (usbdClientHandle, nodeId,
  425. USB_RT_HOST_TO_DEV | USB_RT_CLASS | USB_RT_INTERFACE,
  426. USB_REQ_HID_SET_PROTOCOL, protocol, interface, 0, NULL, NULL);
  427.     }
  428. /* End of file. */