usbdesc.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. //*****************************************************************************
  2. //
  3. // usbdesc.c - USB descriptor parsing functions.
  4. //
  5. // Copyright (c) 2008-2010 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of AM1808 Sitaraware USB Library and reused from revision 6288
  22. // of the Stellaris USB Library.
  23. //
  24. //*****************************************************************************
  25. #include "hw_types.h"
  26. #include "usblib.h"
  27. //*****************************************************************************
  28. //
  29. // Assumptions:
  30. // ------------
  31. //
  32. // The following assumptions are made in this module. From reading chapter 9
  33. // of the USB 2.0 specification, these appear to be perfectly valid.
  34. //
  35. // 1. The interface number, bInterfaceNumber in the interface descriptor, is
  36. // a zero based index and takes values between 0 and
  37. // (pConfigDescriptor->bNumInterfaces - 1) inclusive.
  38. // 2. Similarly, the alternate setting number, bAlternateSetting in the
  39. // interface descriptor, is a zero based index.
  40. // 3. Interface descriptors are ordered by interface number in the
  41. // configuration descriptor.
  42. // 4. If alternate settings are available for an interface, the interface
  43. // descriptors are ordered by alternate setting value bAlternateSetting.
  44. // 5. Although the endpoints associated with a given interface must follow
  45. // their associated interface descriptor, it is possible for other,
  46. // device specific descriptors to be found between an interface descriptor
  47. // and its endpoints or between endpoint descriptors for the same
  48. // interface.
  49. //
  50. //*****************************************************************************
  51. //*****************************************************************************
  52. //
  53. //! \addtogroup general_usblib_api
  54. //! @{
  55. //
  56. //*****************************************************************************
  57. //*****************************************************************************
  58. //
  59. //! Determines the number of individual descriptors of a particular type within
  60. //! a supplied buffer.
  61. //!
  62. //! \param psDesc points to the first byte of a block of standard USB
  63. //! descriptors.
  64. //! \param ulSize is the number of bytes of descriptor data found at pointer
  65. //! \e psDesc.
  66. //! \param ulType identifies the type of descriptor that is to be counted. If
  67. //! the value is \b USB_DESC_ANY, the function returns the total number of
  68. //! descriptors regardless of type.
  69. //!
  70. //! This function can be used to count the number of descriptors of a
  71. //! particular type within a block of descriptors. The caller can provide a
  72. //! specific type value which the function matches against the second byte of
  73. //! each descriptor or, alternatively, can specify \b USB_DESC_ANY to have the
  74. //! function count all descriptors regardless of their type.
  75. //!
  76. //! \return Returns the number of descriptors found in the supplied block of
  77. //! data.
  78. //
  79. //*****************************************************************************
  80. unsigned int
  81. USBDescGetNum(tDescriptorHeader *psDesc, unsigned int ulSize,
  82. unsigned int ulType)
  83. {
  84. tDescriptorHeader *psDescCheck;
  85. unsigned int ulTotLength;
  86. unsigned int ulCount;
  87. //
  88. // Set up for our descriptor counting loop.
  89. //
  90. psDescCheck = psDesc;
  91. ulTotLength = 0;
  92. ulCount = 0;
  93. //
  94. // Keep looking through the supplied data until we reach the end.
  95. //
  96. while(ulTotLength < ulSize)
  97. {
  98. //
  99. // Does this descriptor match the type passed (if a specific type
  100. // has been specified)?
  101. //
  102. if((ulType == USB_DESC_ANY) ||
  103. (psDescCheck->bDescriptorType == (unsigned char)(ulType & 0xFF)))
  104. {
  105. ulCount++;
  106. }
  107. //
  108. // Move on to the next descriptor.
  109. //
  110. ulTotLength += (unsigned int)psDescCheck->bLength;
  111. psDescCheck = NEXT_USB_DESCRIPTOR(psDescCheck);
  112. }
  113. //
  114. // Return the descriptor count to the caller.
  115. //
  116. return(ulCount);
  117. }
  118. //*****************************************************************************
  119. //
  120. //! Determines the number of individual descriptors of a particular type within
  121. //! a supplied buffer.
  122. //!
  123. //! \param psDesc points to the first byte of a block of standard USB
  124. //! descriptors.
  125. //! \param ulSize is the number of bytes of descriptor data found at pointer
  126. //! \e psDesc.
  127. //! \param ulType identifies the type of descriptor that is to be found. If
  128. //! the value is \b USB_DESC_ANY, the function returns a pointer to the n-th
  129. //! descriptor regardless of type.
  130. //! \param ulIndex is the zero based index of the descriptor whose pointer is
  131. //! to be returned. For example, passing value 1 in \e ulIndex returns the
  132. //! second matching descriptor.
  133. //!
  134. //! Return a pointer to the n-th descriptor of a particular type found in the
  135. //! block of \e ulSize bytes starting at \e psDesc.
  136. //!
  137. //! \return Returns a pointer to the header of the required descriptor if
  138. //! found or NULL otherwise.
  139. //
  140. //*****************************************************************************
  141. tDescriptorHeader *
  142. USBDescGet(tDescriptorHeader *psDesc, unsigned int ulSize,
  143. unsigned int ulType, unsigned int ulIndex)
  144. {
  145. tDescriptorHeader *psDescCheck;
  146. unsigned int ulTotLength;
  147. unsigned int ulCount;
  148. //
  149. // Set up for our descriptor counting loop.
  150. //
  151. psDescCheck = psDesc;
  152. ulTotLength = 0;
  153. ulCount = 0;
  154. //
  155. // Keep looking through the supplied data until we reach the end.
  156. //
  157. while(ulTotLength < ulSize)
  158. {
  159. //
  160. // Does this descriptor match the type passed (if a specific type
  161. // has been specified)?
  162. //
  163. if((ulType == USB_DESC_ANY) ||
  164. (psDescCheck->bDescriptorType == (unsigned char)(ulType & 0xFF)))
  165. {
  166. //
  167. // We found a matching descriptor. If our count matches the
  168. // supplied index, we are done so return the pointer.
  169. //
  170. if(ulCount == ulIndex)
  171. {
  172. return(psDescCheck);
  173. }
  174. //
  175. // We have not found enough descriptors yet to satisfy the supplied
  176. // index so increment our count and continue.
  177. //
  178. ulCount++;
  179. }
  180. //
  181. // Move on to the next descriptor.
  182. //
  183. ulTotLength += (unsigned int)psDescCheck->bLength;
  184. psDescCheck = NEXT_USB_DESCRIPTOR(psDescCheck);
  185. }
  186. //
  187. // If we get here, we reached the end of the data without finding the
  188. // required descriptor. Return NULL.
  189. //
  190. return((tDescriptorHeader *)0);
  191. }
  192. //*****************************************************************************
  193. //
  194. //! Determines the number of different alternate configurations for a given
  195. //! interface within a configuration descriptor.
  196. //!
  197. //! \param psConfig points to the first byte of a standard USB configuration
  198. //! descriptor.
  199. //! \param ucInterfaceNumber is the interface number for which the number of
  200. //! alternate configurations is to be counted.
  201. //!
  202. //! This function can be used to count the number of alternate settings for a
  203. //! specific interface within a configuration.
  204. //!
  205. //! \return Returns the number of alternate versions of the specified interface
  206. //! or 0 if the interface number supplied cannot be found in the config
  207. //! descriptor.
  208. //
  209. //*****************************************************************************
  210. unsigned int
  211. USBDescGetNumAlternateInterfaces(tConfigDescriptor *psConfig,
  212. unsigned char ucInterfaceNumber)
  213. {
  214. tDescriptorHeader *psDescCheck;
  215. unsigned int ulTotLength;
  216. unsigned int ulCount;
  217. //
  218. // Set up for our descriptor counting loop.
  219. //
  220. psDescCheck = (tDescriptorHeader *)psConfig;
  221. ulTotLength = 0;
  222. ulCount = 0;
  223. //
  224. // Keep looking through the supplied data until we reach the end.
  225. //
  226. while(ulTotLength < (unsigned int)psConfig->wTotalLength)
  227. {
  228. //
  229. // Is this an interface descriptor with the required interface number?
  230. //
  231. if((psDescCheck->bDescriptorType == USB_DTYPE_INTERFACE) &&
  232. (((tInterfaceDescriptor *)psDescCheck)->bInterfaceNumber ==
  233. ucInterfaceNumber))
  234. {
  235. //
  236. // Yes - increment our count.
  237. //
  238. ulCount++;
  239. }
  240. //
  241. // Move on to the next descriptor.
  242. //
  243. ulTotLength += (unsigned int)psDescCheck->bLength;
  244. psDescCheck = NEXT_USB_DESCRIPTOR(psDescCheck);
  245. }
  246. //
  247. // Return the descriptor count to the caller.
  248. //
  249. return(ulCount);
  250. }
  251. //*****************************************************************************
  252. //
  253. //! Returns a pointer to the n-th interface descriptor in a config descriptor
  254. //! with the supplied interface number.
  255. //!
  256. //! \param psConfig points to the first byte of a standard USB configuration
  257. //! descriptor.
  258. //! \param ucInterfaceNumber is the interface number of the descriptor that is
  259. //! being queried.
  260. //! \param ulIndex is the zero based index of the descriptor to return.
  261. //!
  262. //! This function returns a pointer to the n-th interface descriptor in the
  263. //! supplied configuration which has the requested interface number. It may be
  264. //! used by a client to retrieve the descriptors for each alternate setting
  265. //! of a given interface within the configuration passed.
  266. //!
  267. //! \return Returns a pointer to the n-th interface descriptor with interface
  268. //! number as specified or NULL of this descriptor does not exist.
  269. //
  270. //*****************************************************************************
  271. static tInterfaceDescriptor *
  272. USBDescGetAlternateInterface(tConfigDescriptor *psConfig,
  273. unsigned char ucInterfaceNumber,
  274. unsigned int ulIndex)
  275. {
  276. tDescriptorHeader *psDescCheck;
  277. unsigned int ulTotLength;
  278. unsigned int ulCount;
  279. //
  280. // Set up for our descriptor counting loop.
  281. //
  282. psDescCheck = (tDescriptorHeader *)psConfig;
  283. ulTotLength = 0;
  284. ulCount = 0;
  285. //
  286. // Keep looking through the supplied data until we reach the end.
  287. //
  288. while(ulTotLength < (unsigned int)psConfig->wTotalLength)
  289. {
  290. //
  291. // Does this descriptor match the type passed (if a specific type
  292. // has been specified)?
  293. //
  294. if((psDescCheck->bDescriptorType == USB_DTYPE_INTERFACE) &&
  295. (((tInterfaceDescriptor *)psDescCheck)->bInterfaceNumber ==
  296. ucInterfaceNumber))
  297. {
  298. //
  299. // This is an interface descriptor for interface ucInterfaceNumber.
  300. // Determine if this is the n-th one we have found and, if so,
  301. // return its pointer.
  302. //
  303. if(ulCount == ulIndex)
  304. {
  305. //
  306. // Found it - return the pointer.
  307. //
  308. return((tInterfaceDescriptor *)psDescCheck);
  309. }
  310. //
  311. // Increment our count of matching descriptors found and go back
  312. // to look for another since we have not yet reached the n-th
  313. // match.
  314. //
  315. ulCount++;
  316. }
  317. //
  318. // Move on to the next descriptor.
  319. //
  320. ulTotLength += (unsigned int)psDescCheck->bLength;
  321. psDescCheck = NEXT_USB_DESCRIPTOR(psDescCheck);
  322. }
  323. //
  324. // If we drop out the end of the loop, we did not find the requested
  325. // descriptor so return NULL.
  326. //
  327. return((tInterfaceDescriptor *)0);
  328. }
  329. //*****************************************************************************
  330. //
  331. //! Returns a pointer to the n-th interface descriptor in a configuration
  332. //! descriptor that applies to the supplied alternate setting number.
  333. //!
  334. //! \param psConfig points to the first byte of a standard USB configuration
  335. //! descriptor.
  336. //! \param ulIndex is the zero based index of the interface that is to be
  337. //! found. If ulAlt is set to a value other than \b USB_DESC_ANY, this will be
  338. //! equivalent to the interface number being searched for.
  339. //! \param ulAlt is the alternate setting number which is to be
  340. //! searched for. If this value is \b USB_DESC_ANY, the alternate setting
  341. //! is ignored and all interface descriptors are considered in the search.
  342. //!
  343. //! Return a pointer to the n-th interface descriptor found in the supplied
  344. //! configuration descriptor. If \e ulAlt is not \b USB_DESC_ANY, only
  345. //! interface descriptors which are part of the supplied alternate setting are
  346. //! considered in the search otherwise all interface descriptors are
  347. //! considered.
  348. //!
  349. //! Note that, although alternate settings can be applied on an interface-by-
  350. //! interface basis, the number of interfaces offered is fixed for a given
  351. //! config descriptor. Hence, this function will correctly find the unique
  352. //! interface descriptor for that interface's alternate setting number ulAlt
  353. //! if ulIndex is set to the required interface number and ulAlt is set to a
  354. //! valid alternate setting number for that interface.
  355. //!
  356. //! \return Returns a pointer to the required interface descriptor if
  357. //! found or NULL otherwise.
  358. //
  359. //*****************************************************************************
  360. tInterfaceDescriptor *
  361. USBDescGetInterface(tConfigDescriptor *psConfig, unsigned int ulIndex,
  362. unsigned int ulAlt)
  363. {
  364. //
  365. // If we are being told to ignore the alternate configuration, this boils
  366. // down to a very simple query.
  367. //
  368. if(ulAlt == USB_DESC_ANY)
  369. {
  370. //
  371. // Return the ulIndex-th interface descriptor we find in the
  372. // configuration descriptor.
  373. //
  374. return((tInterfaceDescriptor *)USBDescGet(
  375. (tDescriptorHeader *)psConfig,
  376. (unsigned int)psConfig->wTotalLength,
  377. USB_DTYPE_INTERFACE, ulIndex));
  378. }
  379. else
  380. {
  381. //
  382. // In this case, a specific alternate setting number is required.
  383. // Given that interface numbers are zero based indices, we can
  384. // pass the supplied ulIndex parameter directly as the interface
  385. // number to USBDescGetAlternateInterface to retrieve the requested
  386. // interface descriptor pointer.
  387. //
  388. return(USBDescGetAlternateInterface(psConfig, ulIndex, ulAlt));
  389. }
  390. }
  391. //*****************************************************************************
  392. //
  393. //! Return a pointer to the n-th endpoint descriptor in the supplied
  394. //! interface descriptor.
  395. //!
  396. //! \param psInterface points to the first byte of a standard USB interface
  397. //! descriptor.
  398. //! \param ulIndex is the zero based index of the endpoint that is to be
  399. //! found.
  400. //! \param ulSize contains the maximum number of bytes that the function may
  401. //! search beyond \e psInterface while looking for the requested endpoint
  402. //! descriptor.
  403. //!
  404. //! Return a pointer to the n-th endpoint descriptor found in the supplied
  405. //! interface descriptor. If the \e ulIndex parameter is invalid (greater
  406. //! than or equal to the bNumEndpoints field of the interface descriptor) or
  407. //! the endpoint cannot be found within \e ulSize bytes of the interface
  408. //! descriptor pointer, the function will return NULL.
  409. //!
  410. //! Note that, although the USB 2.0 specification states that endpoint
  411. //! descriptors must follow the interface descriptor that they relate to, it
  412. //! also states that device specific descriptors should follow any standard
  413. //! descriptor that they relate to. As a result, we cannot assume that each
  414. //! interface descriptor will be followed by nothing but an ordered list of
  415. //! its own endpoints and, hence, the function needs to be provided ulSize to
  416. //! limit the search range.
  417. //!
  418. //! \return Returns a pointer to the requested endpoint descriptor if
  419. //! found or NULL otherwise.
  420. //
  421. //*****************************************************************************
  422. tEndpointDescriptor *
  423. USBDescGetInterfaceEndpoint(tInterfaceDescriptor *psInterface,
  424. unsigned int ulIndex, unsigned int ulSize)
  425. {
  426. //
  427. // Is the index passed valid?
  428. //
  429. if(ulIndex >= psInterface->bNumEndpoints)
  430. {
  431. //
  432. // It's out of bounds so return a NULL.
  433. //
  434. return((tEndpointDescriptor *)0);
  435. }
  436. else
  437. {
  438. //
  439. // Endpoint index is valid so find the descriptor.
  440. //
  441. return((tEndpointDescriptor *)USBDescGet(
  442. (tDescriptorHeader *)psInterface,
  443. ulSize, USB_DTYPE_ENDPOINT, ulIndex));
  444. }
  445. }
  446. //*****************************************************************************
  447. //
  448. // Close the Doxygen group.
  449. //! @}
  450. //
  451. //*****************************************************************************