/sys/dev/usb/template/usb_template.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 1374 lines · 936 code · 148 blank · 290 comment · 214 complexity · fcee1da4c2f2c91708290323b272f540 MD5 · raw file

  1. /* $FreeBSD$ */
  2. /*-
  3. * Copyright (c) 2007 Hans Petter Selasky. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  15. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  18. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  20. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  22. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  23. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  24. * SUCH DAMAGE.
  25. */
  26. /*
  27. * This file contains sub-routines to build up USB descriptors from
  28. * USB templates.
  29. */
  30. #include <sys/stdint.h>
  31. #include <sys/stddef.h>
  32. #include <sys/param.h>
  33. #include <sys/queue.h>
  34. #include <sys/types.h>
  35. #include <sys/systm.h>
  36. #include <sys/kernel.h>
  37. #include <sys/bus.h>
  38. #include <sys/module.h>
  39. #include <sys/lock.h>
  40. #include <sys/mutex.h>
  41. #include <sys/condvar.h>
  42. #include <sys/sysctl.h>
  43. #include <sys/sx.h>
  44. #include <sys/unistd.h>
  45. #include <sys/callout.h>
  46. #include <sys/malloc.h>
  47. #include <sys/priv.h>
  48. #include <dev/usb/usb.h>
  49. #include <dev/usb/usb_ioctl.h>
  50. #include <dev/usb/usbdi.h>
  51. #include <dev/usb/usbdi_util.h>
  52. #include "usbdevs.h"
  53. #include <dev/usb/usb_cdc.h>
  54. #include <dev/usb/usb_core.h>
  55. #include <dev/usb/usb_dynamic.h>
  56. #include <dev/usb/usb_busdma.h>
  57. #include <dev/usb/usb_process.h>
  58. #include <dev/usb/usb_device.h>
  59. #define USB_DEBUG_VAR usb_debug
  60. #include <dev/usb/usb_debug.h>
  61. #include <dev/usb/usb_controller.h>
  62. #include <dev/usb/usb_bus.h>
  63. #include <dev/usb/template/usb_template.h>
  64. MODULE_DEPEND(usb_template, usb, 1, 1, 1);
  65. MODULE_VERSION(usb_template, 1);
  66. /* function prototypes */
  67. static void usb_make_raw_desc(struct usb_temp_setup *, const uint8_t *);
  68. static void usb_make_endpoint_desc(struct usb_temp_setup *,
  69. const struct usb_temp_endpoint_desc *);
  70. static void usb_make_interface_desc(struct usb_temp_setup *,
  71. const struct usb_temp_interface_desc *);
  72. static void usb_make_config_desc(struct usb_temp_setup *,
  73. const struct usb_temp_config_desc *);
  74. static void usb_make_device_desc(struct usb_temp_setup *,
  75. const struct usb_temp_device_desc *);
  76. static uint8_t usb_hw_ep_match(const struct usb_hw_ep_profile *, uint8_t,
  77. uint8_t);
  78. static uint8_t usb_hw_ep_find_match(struct usb_hw_ep_scratch *,
  79. struct usb_hw_ep_scratch_sub *, uint8_t);
  80. static uint8_t usb_hw_ep_get_needs(struct usb_hw_ep_scratch *, uint8_t,
  81. uint8_t);
  82. static usb_error_t usb_hw_ep_resolve(struct usb_device *,
  83. struct usb_descriptor *);
  84. static const struct usb_temp_device_desc *usb_temp_get_tdd(struct usb_device *);
  85. static void *usb_temp_get_device_desc(struct usb_device *);
  86. static void *usb_temp_get_qualifier_desc(struct usb_device *);
  87. static void *usb_temp_get_config_desc(struct usb_device *, uint16_t *,
  88. uint8_t);
  89. static const void *usb_temp_get_string_desc(struct usb_device *, uint16_t,
  90. uint8_t);
  91. static const void *usb_temp_get_vendor_desc(struct usb_device *,
  92. const struct usb_device_request *, uint16_t *plen);
  93. static const void *usb_temp_get_hub_desc(struct usb_device *);
  94. static usb_error_t usb_temp_get_desc(struct usb_device *,
  95. struct usb_device_request *, const void **, uint16_t *);
  96. static usb_error_t usb_temp_setup_by_index(struct usb_device *,
  97. uint16_t index);
  98. static void usb_temp_init(void *);
  99. /*------------------------------------------------------------------------*
  100. * usb_make_raw_desc
  101. *
  102. * This function will insert a raw USB descriptor into the generated
  103. * USB configuration.
  104. *------------------------------------------------------------------------*/
  105. static void
  106. usb_make_raw_desc(struct usb_temp_setup *temp,
  107. const uint8_t *raw)
  108. {
  109. void *dst;
  110. uint8_t len;
  111. /*
  112. * The first byte of any USB descriptor gives the length.
  113. */
  114. if (raw) {
  115. len = raw[0];
  116. if (temp->buf) {
  117. dst = USB_ADD_BYTES(temp->buf, temp->size);
  118. memcpy(dst, raw, len);
  119. /* check if we have got a CDC union descriptor */
  120. if ((raw[0] >= sizeof(struct usb_cdc_union_descriptor)) &&
  121. (raw[1] == UDESC_CS_INTERFACE) &&
  122. (raw[2] == UDESCSUB_CDC_UNION)) {
  123. struct usb_cdc_union_descriptor *ud = (void *)dst;
  124. /* update the interface numbers */
  125. ud->bMasterInterface +=
  126. temp->bInterfaceNumber;
  127. ud->bSlaveInterface[0] +=
  128. temp->bInterfaceNumber;
  129. }
  130. /* check if we have got an interface association descriptor */
  131. if ((raw[0] >= sizeof(struct usb_interface_assoc_descriptor)) &&
  132. (raw[1] == UDESC_IFACE_ASSOC)) {
  133. struct usb_interface_assoc_descriptor *iad = (void *)dst;
  134. /* update the interface number */
  135. iad->bFirstInterface +=
  136. temp->bInterfaceNumber;
  137. }
  138. /* check if we have got a call management descriptor */
  139. if ((raw[0] >= sizeof(struct usb_cdc_cm_descriptor)) &&
  140. (raw[1] == UDESC_CS_INTERFACE) &&
  141. (raw[2] == UDESCSUB_CDC_CM)) {
  142. struct usb_cdc_cm_descriptor *ccd = (void *)dst;
  143. /* update the interface number */
  144. ccd->bDataInterface +=
  145. temp->bInterfaceNumber;
  146. }
  147. }
  148. temp->size += len;
  149. }
  150. }
  151. /*------------------------------------------------------------------------*
  152. * usb_make_endpoint_desc
  153. *
  154. * This function will generate an USB endpoint descriptor from the
  155. * given USB template endpoint descriptor, which will be inserted into
  156. * the USB configuration.
  157. *------------------------------------------------------------------------*/
  158. static void
  159. usb_make_endpoint_desc(struct usb_temp_setup *temp,
  160. const struct usb_temp_endpoint_desc *ted)
  161. {
  162. struct usb_endpoint_descriptor *ed;
  163. const void **rd;
  164. uint16_t old_size;
  165. uint16_t mps;
  166. uint8_t ea; /* Endpoint Address */
  167. uint8_t et; /* Endpiont Type */
  168. /* Reserve memory */
  169. old_size = temp->size;
  170. ea = (ted->bEndpointAddress & (UE_ADDR | UE_DIR_IN | UE_DIR_OUT));
  171. et = (ted->bmAttributes & UE_XFERTYPE);
  172. if (et == UE_ISOCHRONOUS) {
  173. /* account for extra byte fields */
  174. temp->size += sizeof(*ed) + 2;
  175. } else {
  176. temp->size += sizeof(*ed);
  177. }
  178. /* Scan all Raw Descriptors first */
  179. rd = ted->ppRawDesc;
  180. if (rd) {
  181. while (*rd) {
  182. usb_make_raw_desc(temp, *rd);
  183. rd++;
  184. }
  185. }
  186. if (ted->pPacketSize == NULL) {
  187. /* not initialized */
  188. temp->err = USB_ERR_INVAL;
  189. return;
  190. }
  191. mps = ted->pPacketSize->mps[temp->usb_speed];
  192. if (mps == 0) {
  193. /* not initialized */
  194. temp->err = USB_ERR_INVAL;
  195. return;
  196. } else if (mps == UE_ZERO_MPS) {
  197. /* escape for Zero Max Packet Size */
  198. mps = 0;
  199. }
  200. /*
  201. * Fill out the real USB endpoint descriptor
  202. * in case there is a buffer present:
  203. */
  204. if (temp->buf) {
  205. ed = USB_ADD_BYTES(temp->buf, old_size);
  206. if (et == UE_ISOCHRONOUS)
  207. ed->bLength = sizeof(*ed) + 2;
  208. else
  209. ed->bLength = sizeof(*ed);
  210. ed->bDescriptorType = UDESC_ENDPOINT;
  211. ed->bEndpointAddress = ea;
  212. ed->bmAttributes = ted->bmAttributes;
  213. USETW(ed->wMaxPacketSize, mps);
  214. /* setup bInterval parameter */
  215. if (ted->pIntervals &&
  216. ted->pIntervals->bInterval[temp->usb_speed]) {
  217. ed->bInterval =
  218. ted->pIntervals->bInterval[temp->usb_speed];
  219. } else {
  220. switch (et) {
  221. case UE_BULK:
  222. case UE_CONTROL:
  223. ed->bInterval = 0; /* not used */
  224. break;
  225. case UE_INTERRUPT:
  226. switch (temp->usb_speed) {
  227. case USB_SPEED_LOW:
  228. case USB_SPEED_FULL:
  229. ed->bInterval = 1; /* 1 ms */
  230. break;
  231. default:
  232. ed->bInterval = 4; /* 1 ms */
  233. break;
  234. }
  235. break;
  236. default: /* UE_ISOCHRONOUS */
  237. switch (temp->usb_speed) {
  238. case USB_SPEED_LOW:
  239. case USB_SPEED_FULL:
  240. ed->bInterval = 1; /* 1 ms */
  241. break;
  242. default:
  243. ed->bInterval = 1; /* 125 us */
  244. break;
  245. }
  246. break;
  247. }
  248. }
  249. }
  250. temp->bNumEndpoints++;
  251. }
  252. /*------------------------------------------------------------------------*
  253. * usb_make_interface_desc
  254. *
  255. * This function will generate an USB interface descriptor from the
  256. * given USB template interface descriptor, which will be inserted
  257. * into the USB configuration.
  258. *------------------------------------------------------------------------*/
  259. static void
  260. usb_make_interface_desc(struct usb_temp_setup *temp,
  261. const struct usb_temp_interface_desc *tid)
  262. {
  263. struct usb_interface_descriptor *id;
  264. const struct usb_temp_endpoint_desc **ted;
  265. const void **rd;
  266. uint16_t old_size;
  267. /* Reserve memory */
  268. old_size = temp->size;
  269. temp->size += sizeof(*id);
  270. /* Update interface and alternate interface numbers */
  271. if (tid->isAltInterface == 0) {
  272. temp->bAlternateSetting = 0;
  273. temp->bInterfaceNumber++;
  274. } else {
  275. temp->bAlternateSetting++;
  276. }
  277. /* Scan all Raw Descriptors first */
  278. rd = tid->ppRawDesc;
  279. if (rd) {
  280. while (*rd) {
  281. usb_make_raw_desc(temp, *rd);
  282. rd++;
  283. }
  284. }
  285. /* Reset some counters */
  286. temp->bNumEndpoints = 0;
  287. /* Scan all Endpoint Descriptors second */
  288. ted = tid->ppEndpoints;
  289. if (ted) {
  290. while (*ted) {
  291. usb_make_endpoint_desc(temp, *ted);
  292. ted++;
  293. }
  294. }
  295. /*
  296. * Fill out the real USB interface descriptor
  297. * in case there is a buffer present:
  298. */
  299. if (temp->buf) {
  300. id = USB_ADD_BYTES(temp->buf, old_size);
  301. id->bLength = sizeof(*id);
  302. id->bDescriptorType = UDESC_INTERFACE;
  303. id->bInterfaceNumber = temp->bInterfaceNumber;
  304. id->bAlternateSetting = temp->bAlternateSetting;
  305. id->bNumEndpoints = temp->bNumEndpoints;
  306. id->bInterfaceClass = tid->bInterfaceClass;
  307. id->bInterfaceSubClass = tid->bInterfaceSubClass;
  308. id->bInterfaceProtocol = tid->bInterfaceProtocol;
  309. id->iInterface = tid->iInterface;
  310. }
  311. }
  312. /*------------------------------------------------------------------------*
  313. * usb_make_config_desc
  314. *
  315. * This function will generate an USB config descriptor from the given
  316. * USB template config descriptor, which will be inserted into the USB
  317. * configuration.
  318. *------------------------------------------------------------------------*/
  319. static void
  320. usb_make_config_desc(struct usb_temp_setup *temp,
  321. const struct usb_temp_config_desc *tcd)
  322. {
  323. struct usb_config_descriptor *cd;
  324. const struct usb_temp_interface_desc **tid;
  325. uint16_t old_size;
  326. /* Reserve memory */
  327. old_size = temp->size;
  328. temp->size += sizeof(*cd);
  329. /* Reset some counters */
  330. temp->bInterfaceNumber = 0xFF;
  331. temp->bAlternateSetting = 0;
  332. /* Scan all the USB interfaces */
  333. tid = tcd->ppIfaceDesc;
  334. if (tid) {
  335. while (*tid) {
  336. usb_make_interface_desc(temp, *tid);
  337. tid++;
  338. }
  339. }
  340. /*
  341. * Fill out the real USB config descriptor
  342. * in case there is a buffer present:
  343. */
  344. if (temp->buf) {
  345. cd = USB_ADD_BYTES(temp->buf, old_size);
  346. /* compute total size */
  347. old_size = temp->size - old_size;
  348. cd->bLength = sizeof(*cd);
  349. cd->bDescriptorType = UDESC_CONFIG;
  350. USETW(cd->wTotalLength, old_size);
  351. cd->bNumInterface = temp->bInterfaceNumber + 1;
  352. cd->bConfigurationValue = temp->bConfigurationValue;
  353. cd->iConfiguration = tcd->iConfiguration;
  354. cd->bmAttributes = tcd->bmAttributes;
  355. cd->bMaxPower = tcd->bMaxPower;
  356. cd->bmAttributes |= (UC_REMOTE_WAKEUP | UC_BUS_POWERED);
  357. if (temp->self_powered) {
  358. cd->bmAttributes |= UC_SELF_POWERED;
  359. } else {
  360. cd->bmAttributes &= ~UC_SELF_POWERED;
  361. }
  362. }
  363. }
  364. /*------------------------------------------------------------------------*
  365. * usb_make_device_desc
  366. *
  367. * This function will generate an USB device descriptor from the
  368. * given USB template device descriptor.
  369. *------------------------------------------------------------------------*/
  370. static void
  371. usb_make_device_desc(struct usb_temp_setup *temp,
  372. const struct usb_temp_device_desc *tdd)
  373. {
  374. struct usb_temp_data *utd;
  375. const struct usb_temp_config_desc **tcd;
  376. uint16_t old_size;
  377. /* Reserve memory */
  378. old_size = temp->size;
  379. temp->size += sizeof(*utd);
  380. /* Scan all the USB configs */
  381. temp->bConfigurationValue = 1;
  382. tcd = tdd->ppConfigDesc;
  383. if (tcd) {
  384. while (*tcd) {
  385. usb_make_config_desc(temp, *tcd);
  386. temp->bConfigurationValue++;
  387. tcd++;
  388. }
  389. }
  390. /*
  391. * Fill out the real USB device descriptor
  392. * in case there is a buffer present:
  393. */
  394. if (temp->buf) {
  395. utd = USB_ADD_BYTES(temp->buf, old_size);
  396. /* Store a pointer to our template device descriptor */
  397. utd->tdd = tdd;
  398. /* Fill out USB device descriptor */
  399. utd->udd.bLength = sizeof(utd->udd);
  400. utd->udd.bDescriptorType = UDESC_DEVICE;
  401. utd->udd.bDeviceClass = tdd->bDeviceClass;
  402. utd->udd.bDeviceSubClass = tdd->bDeviceSubClass;
  403. utd->udd.bDeviceProtocol = tdd->bDeviceProtocol;
  404. USETW(utd->udd.idVendor, tdd->idVendor);
  405. USETW(utd->udd.idProduct, tdd->idProduct);
  406. USETW(utd->udd.bcdDevice, tdd->bcdDevice);
  407. utd->udd.iManufacturer = tdd->iManufacturer;
  408. utd->udd.iProduct = tdd->iProduct;
  409. utd->udd.iSerialNumber = tdd->iSerialNumber;
  410. utd->udd.bNumConfigurations = temp->bConfigurationValue - 1;
  411. /*
  412. * Fill out the USB device qualifier. Pretend that we
  413. * don't support any other speeds by setting
  414. * "bNumConfigurations" equal to zero. That saves us
  415. * generating an extra set of configuration
  416. * descriptors.
  417. */
  418. utd->udq.bLength = sizeof(utd->udq);
  419. utd->udq.bDescriptorType = UDESC_DEVICE_QUALIFIER;
  420. utd->udq.bDeviceClass = tdd->bDeviceClass;
  421. utd->udq.bDeviceSubClass = tdd->bDeviceSubClass;
  422. utd->udq.bDeviceProtocol = tdd->bDeviceProtocol;
  423. utd->udq.bNumConfigurations = 0;
  424. USETW(utd->udq.bcdUSB, 0x0200);
  425. utd->udq.bMaxPacketSize0 = 0;
  426. switch (temp->usb_speed) {
  427. case USB_SPEED_LOW:
  428. USETW(utd->udd.bcdUSB, 0x0110);
  429. utd->udd.bMaxPacketSize = 8;
  430. break;
  431. case USB_SPEED_FULL:
  432. USETW(utd->udd.bcdUSB, 0x0110);
  433. utd->udd.bMaxPacketSize = 32;
  434. break;
  435. case USB_SPEED_HIGH:
  436. USETW(utd->udd.bcdUSB, 0x0200);
  437. utd->udd.bMaxPacketSize = 64;
  438. break;
  439. case USB_SPEED_VARIABLE:
  440. USETW(utd->udd.bcdUSB, 0x0250);
  441. utd->udd.bMaxPacketSize = 255; /* 512 bytes */
  442. break;
  443. case USB_SPEED_SUPER:
  444. USETW(utd->udd.bcdUSB, 0x0300);
  445. utd->udd.bMaxPacketSize = 9; /* 2**9 = 512 bytes */
  446. break;
  447. default:
  448. temp->err = USB_ERR_INVAL;
  449. break;
  450. }
  451. }
  452. }
  453. /*------------------------------------------------------------------------*
  454. * usb_hw_ep_match
  455. *
  456. * Return values:
  457. * 0: The endpoint profile does not match the criterias
  458. * Else: The endpoint profile matches the criterias
  459. *------------------------------------------------------------------------*/
  460. static uint8_t
  461. usb_hw_ep_match(const struct usb_hw_ep_profile *pf,
  462. uint8_t ep_type, uint8_t ep_dir_in)
  463. {
  464. if (ep_type == UE_CONTROL) {
  465. /* special */
  466. return (pf->support_control);
  467. }
  468. if ((pf->support_in && ep_dir_in) ||
  469. (pf->support_out && !ep_dir_in)) {
  470. if ((pf->support_interrupt && (ep_type == UE_INTERRUPT)) ||
  471. (pf->support_isochronous && (ep_type == UE_ISOCHRONOUS)) ||
  472. (pf->support_bulk && (ep_type == UE_BULK))) {
  473. return (1);
  474. }
  475. }
  476. return (0);
  477. }
  478. /*------------------------------------------------------------------------*
  479. * usb_hw_ep_find_match
  480. *
  481. * This function is used to find the best matching endpoint profile
  482. * for and endpoint belonging to an USB descriptor.
  483. *
  484. * Return values:
  485. * 0: Success. Got a match.
  486. * Else: Failure. No match.
  487. *------------------------------------------------------------------------*/
  488. static uint8_t
  489. usb_hw_ep_find_match(struct usb_hw_ep_scratch *ues,
  490. struct usb_hw_ep_scratch_sub *ep, uint8_t is_simplex)
  491. {
  492. const struct usb_hw_ep_profile *pf;
  493. uint16_t distance;
  494. uint16_t temp;
  495. uint16_t max_frame_size;
  496. uint8_t n;
  497. uint8_t best_n;
  498. uint8_t dir_in;
  499. uint8_t dir_out;
  500. distance = 0xFFFF;
  501. best_n = 0;
  502. if ((!ep->needs_in) && (!ep->needs_out)) {
  503. return (0); /* we are done */
  504. }
  505. if (ep->needs_ep_type == UE_CONTROL) {
  506. dir_in = 1;
  507. dir_out = 1;
  508. } else {
  509. if (ep->needs_in) {
  510. dir_in = 1;
  511. dir_out = 0;
  512. } else {
  513. dir_in = 0;
  514. dir_out = 1;
  515. }
  516. }
  517. for (n = 1; n != (USB_EP_MAX / 2); n++) {
  518. /* get HW endpoint profile */
  519. (ues->methods->get_hw_ep_profile) (ues->udev, &pf, n);
  520. if (pf == NULL) {
  521. /* end of profiles */
  522. break;
  523. }
  524. /* check if IN-endpoint is reserved */
  525. if (dir_in || pf->is_simplex) {
  526. if (ues->bmInAlloc[n / 8] & (1 << (n % 8))) {
  527. /* mismatch */
  528. continue;
  529. }
  530. }
  531. /* check if OUT-endpoint is reserved */
  532. if (dir_out || pf->is_simplex) {
  533. if (ues->bmOutAlloc[n / 8] & (1 << (n % 8))) {
  534. /* mismatch */
  535. continue;
  536. }
  537. }
  538. /* check simplex */
  539. if (pf->is_simplex == is_simplex) {
  540. /* mismatch */
  541. continue;
  542. }
  543. /* check if HW endpoint matches */
  544. if (!usb_hw_ep_match(pf, ep->needs_ep_type, dir_in)) {
  545. /* mismatch */
  546. continue;
  547. }
  548. /* get maximum frame size */
  549. if (dir_in)
  550. max_frame_size = pf->max_in_frame_size;
  551. else
  552. max_frame_size = pf->max_out_frame_size;
  553. /* check if we have a matching profile */
  554. if (max_frame_size >= ep->max_frame_size) {
  555. temp = (max_frame_size - ep->max_frame_size);
  556. if (distance > temp) {
  557. distance = temp;
  558. best_n = n;
  559. ep->pf = pf;
  560. }
  561. }
  562. }
  563. /* see if we got a match */
  564. if (best_n != 0) {
  565. /* get the correct profile */
  566. pf = ep->pf;
  567. /* reserve IN-endpoint */
  568. if (dir_in) {
  569. ues->bmInAlloc[best_n / 8] |=
  570. (1 << (best_n % 8));
  571. ep->hw_endpoint_in = best_n | UE_DIR_IN;
  572. ep->needs_in = 0;
  573. }
  574. /* reserve OUT-endpoint */
  575. if (dir_out) {
  576. ues->bmOutAlloc[best_n / 8] |=
  577. (1 << (best_n % 8));
  578. ep->hw_endpoint_out = best_n | UE_DIR_OUT;
  579. ep->needs_out = 0;
  580. }
  581. return (0); /* got a match */
  582. }
  583. return (1); /* failure */
  584. }
  585. /*------------------------------------------------------------------------*
  586. * usb_hw_ep_get_needs
  587. *
  588. * This function will figure out the type and number of endpoints
  589. * which are needed for an USB configuration.
  590. *
  591. * Return values:
  592. * 0: Success.
  593. * Else: Failure.
  594. *------------------------------------------------------------------------*/
  595. static uint8_t
  596. usb_hw_ep_get_needs(struct usb_hw_ep_scratch *ues,
  597. uint8_t ep_type, uint8_t is_complete)
  598. {
  599. const struct usb_hw_ep_profile *pf;
  600. struct usb_hw_ep_scratch_sub *ep_iface;
  601. struct usb_hw_ep_scratch_sub *ep_curr;
  602. struct usb_hw_ep_scratch_sub *ep_max;
  603. struct usb_hw_ep_scratch_sub *ep_end;
  604. struct usb_descriptor *desc;
  605. struct usb_interface_descriptor *id;
  606. struct usb_endpoint_descriptor *ed;
  607. enum usb_dev_speed speed;
  608. uint16_t wMaxPacketSize;
  609. uint16_t temp;
  610. uint8_t ep_no;
  611. ep_iface = ues->ep_max;
  612. ep_curr = ues->ep_max;
  613. ep_end = ues->ep + USB_EP_MAX;
  614. ep_max = ues->ep_max;
  615. desc = NULL;
  616. speed = usbd_get_speed(ues->udev);
  617. repeat:
  618. while ((desc = usb_desc_foreach(ues->cd, desc))) {
  619. if ((desc->bDescriptorType == UDESC_INTERFACE) &&
  620. (desc->bLength >= sizeof(*id))) {
  621. id = (void *)desc;
  622. if (id->bAlternateSetting == 0) {
  623. /* going forward */
  624. ep_iface = ep_max;
  625. } else {
  626. /* reset */
  627. ep_curr = ep_iface;
  628. }
  629. }
  630. if ((desc->bDescriptorType == UDESC_ENDPOINT) &&
  631. (desc->bLength >= sizeof(*ed))) {
  632. ed = (void *)desc;
  633. goto handle_endpoint_desc;
  634. }
  635. }
  636. ues->ep_max = ep_max;
  637. return (0);
  638. handle_endpoint_desc:
  639. temp = (ed->bmAttributes & UE_XFERTYPE);
  640. if (temp == ep_type) {
  641. if (ep_curr == ep_end) {
  642. /* too many endpoints */
  643. return (1); /* failure */
  644. }
  645. wMaxPacketSize = UGETW(ed->wMaxPacketSize);
  646. if ((wMaxPacketSize & 0xF800) &&
  647. (speed == USB_SPEED_HIGH)) {
  648. /* handle packet multiplier */
  649. temp = (wMaxPacketSize >> 11) & 3;
  650. wMaxPacketSize &= 0x7FF;
  651. if (temp == 1) {
  652. wMaxPacketSize *= 2;
  653. } else {
  654. wMaxPacketSize *= 3;
  655. }
  656. }
  657. /*
  658. * Check if we have a fixed endpoint number, else the
  659. * endpoint number is allocated dynamically:
  660. */
  661. ep_no = (ed->bEndpointAddress & UE_ADDR);
  662. if (ep_no != 0) {
  663. /* get HW endpoint profile */
  664. (ues->methods->get_hw_ep_profile)
  665. (ues->udev, &pf, ep_no);
  666. if (pf == NULL) {
  667. /* HW profile does not exist - failure */
  668. DPRINTFN(0, "Endpoint profile %u "
  669. "does not exist\n", ep_no);
  670. return (1);
  671. }
  672. /* reserve fixed endpoint number */
  673. if (ep_type == UE_CONTROL) {
  674. ues->bmInAlloc[ep_no / 8] |=
  675. (1 << (ep_no % 8));
  676. ues->bmOutAlloc[ep_no / 8] |=
  677. (1 << (ep_no % 8));
  678. if ((pf->max_in_frame_size < wMaxPacketSize) ||
  679. (pf->max_out_frame_size < wMaxPacketSize)) {
  680. DPRINTFN(0, "Endpoint profile %u "
  681. "has too small buffer\n", ep_no);
  682. return (1);
  683. }
  684. } else if (ed->bEndpointAddress & UE_DIR_IN) {
  685. ues->bmInAlloc[ep_no / 8] |=
  686. (1 << (ep_no % 8));
  687. if (pf->max_in_frame_size < wMaxPacketSize) {
  688. DPRINTFN(0, "Endpoint profile %u "
  689. "has too small buffer\n", ep_no);
  690. return (1);
  691. }
  692. } else {
  693. ues->bmOutAlloc[ep_no / 8] |=
  694. (1 << (ep_no % 8));
  695. if (pf->max_out_frame_size < wMaxPacketSize) {
  696. DPRINTFN(0, "Endpoint profile %u "
  697. "has too small buffer\n", ep_no);
  698. return (1);
  699. }
  700. }
  701. } else if (is_complete) {
  702. /* check if we have enough buffer space */
  703. if (wMaxPacketSize >
  704. ep_curr->max_frame_size) {
  705. return (1); /* failure */
  706. }
  707. if (ed->bEndpointAddress & UE_DIR_IN) {
  708. ed->bEndpointAddress =
  709. ep_curr->hw_endpoint_in;
  710. } else {
  711. ed->bEndpointAddress =
  712. ep_curr->hw_endpoint_out;
  713. }
  714. } else {
  715. /* compute the maximum frame size */
  716. if (ep_curr->max_frame_size < wMaxPacketSize) {
  717. ep_curr->max_frame_size = wMaxPacketSize;
  718. }
  719. if (temp == UE_CONTROL) {
  720. ep_curr->needs_in = 1;
  721. ep_curr->needs_out = 1;
  722. } else {
  723. if (ed->bEndpointAddress & UE_DIR_IN) {
  724. ep_curr->needs_in = 1;
  725. } else {
  726. ep_curr->needs_out = 1;
  727. }
  728. }
  729. ep_curr->needs_ep_type = ep_type;
  730. }
  731. ep_curr++;
  732. if (ep_max < ep_curr) {
  733. ep_max = ep_curr;
  734. }
  735. }
  736. goto repeat;
  737. }
  738. /*------------------------------------------------------------------------*
  739. * usb_hw_ep_resolve
  740. *
  741. * This function will try to resolve endpoint requirements by the
  742. * given endpoint profiles that the USB hardware reports.
  743. *
  744. * Return values:
  745. * 0: Success
  746. * Else: Failure
  747. *------------------------------------------------------------------------*/
  748. static usb_error_t
  749. usb_hw_ep_resolve(struct usb_device *udev,
  750. struct usb_descriptor *desc)
  751. {
  752. struct usb_hw_ep_scratch *ues;
  753. struct usb_hw_ep_scratch_sub *ep;
  754. const struct usb_hw_ep_profile *pf;
  755. struct usb_bus_methods *methods;
  756. struct usb_device_descriptor *dd;
  757. uint16_t mps;
  758. if (desc == NULL) {
  759. return (USB_ERR_INVAL);
  760. }
  761. /* get bus methods */
  762. methods = udev->bus->methods;
  763. if (methods->get_hw_ep_profile == NULL) {
  764. return (USB_ERR_INVAL);
  765. }
  766. if (desc->bDescriptorType == UDESC_DEVICE) {
  767. if (desc->bLength < sizeof(*dd)) {
  768. return (USB_ERR_INVAL);
  769. }
  770. dd = (void *)desc;
  771. /* get HW control endpoint 0 profile */
  772. (methods->get_hw_ep_profile) (udev, &pf, 0);
  773. if (pf == NULL) {
  774. return (USB_ERR_INVAL);
  775. }
  776. if (!usb_hw_ep_match(pf, UE_CONTROL, 0)) {
  777. DPRINTFN(0, "Endpoint 0 does not "
  778. "support control\n");
  779. return (USB_ERR_INVAL);
  780. }
  781. mps = dd->bMaxPacketSize;
  782. if (udev->speed == USB_SPEED_FULL) {
  783. /*
  784. * We can optionally choose another packet size !
  785. */
  786. while (1) {
  787. /* check if "mps" is ok */
  788. if (pf->max_in_frame_size >= mps) {
  789. break;
  790. }
  791. /* reduce maximum packet size */
  792. mps /= 2;
  793. /* check if "mps" is too small */
  794. if (mps < 8) {
  795. return (USB_ERR_INVAL);
  796. }
  797. }
  798. dd->bMaxPacketSize = mps;
  799. } else {
  800. /* We only have one choice */
  801. if (mps == 255) {
  802. mps = 512;
  803. }
  804. /* Check if we support the specified wMaxPacketSize */
  805. if (pf->max_in_frame_size < mps) {
  806. return (USB_ERR_INVAL);
  807. }
  808. }
  809. return (0); /* success */
  810. }
  811. if (desc->bDescriptorType != UDESC_CONFIG) {
  812. return (USB_ERR_INVAL);
  813. }
  814. if (desc->bLength < sizeof(*(ues->cd))) {
  815. return (USB_ERR_INVAL);
  816. }
  817. ues = udev->bus->scratch[0].hw_ep_scratch;
  818. memset(ues, 0, sizeof(*ues));
  819. ues->ep_max = ues->ep;
  820. ues->cd = (void *)desc;
  821. ues->methods = methods;
  822. ues->udev = udev;
  823. /* Get all the endpoints we need */
  824. if (usb_hw_ep_get_needs(ues, UE_ISOCHRONOUS, 0) ||
  825. usb_hw_ep_get_needs(ues, UE_INTERRUPT, 0) ||
  826. usb_hw_ep_get_needs(ues, UE_CONTROL, 0) ||
  827. usb_hw_ep_get_needs(ues, UE_BULK, 0)) {
  828. DPRINTFN(0, "Could not get needs\n");
  829. return (USB_ERR_INVAL);
  830. }
  831. for (ep = ues->ep; ep != ues->ep_max; ep++) {
  832. while (ep->needs_in || ep->needs_out) {
  833. /*
  834. * First try to use a simplex endpoint.
  835. * Then try to use a duplex endpoint.
  836. */
  837. if (usb_hw_ep_find_match(ues, ep, 1) &&
  838. usb_hw_ep_find_match(ues, ep, 0)) {
  839. DPRINTFN(0, "Could not find match\n");
  840. return (USB_ERR_INVAL);
  841. }
  842. }
  843. }
  844. ues->ep_max = ues->ep;
  845. /* Update all endpoint addresses */
  846. if (usb_hw_ep_get_needs(ues, UE_ISOCHRONOUS, 1) ||
  847. usb_hw_ep_get_needs(ues, UE_INTERRUPT, 1) ||
  848. usb_hw_ep_get_needs(ues, UE_CONTROL, 1) ||
  849. usb_hw_ep_get_needs(ues, UE_BULK, 1)) {
  850. DPRINTFN(0, "Could not update endpoint address\n");
  851. return (USB_ERR_INVAL);
  852. }
  853. return (0); /* success */
  854. }
  855. /*------------------------------------------------------------------------*
  856. * usb_temp_get_tdd
  857. *
  858. * Returns:
  859. * NULL: No USB template device descriptor found.
  860. * Else: Pointer to the USB template device descriptor.
  861. *------------------------------------------------------------------------*/
  862. static const struct usb_temp_device_desc *
  863. usb_temp_get_tdd(struct usb_device *udev)
  864. {
  865. if (udev->usb_template_ptr == NULL) {
  866. return (NULL);
  867. }
  868. return (udev->usb_template_ptr->tdd);
  869. }
  870. /*------------------------------------------------------------------------*
  871. * usb_temp_get_device_desc
  872. *
  873. * Returns:
  874. * NULL: No USB device descriptor found.
  875. * Else: Pointer to USB device descriptor.
  876. *------------------------------------------------------------------------*/
  877. static void *
  878. usb_temp_get_device_desc(struct usb_device *udev)
  879. {
  880. struct usb_device_descriptor *dd;
  881. if (udev->usb_template_ptr == NULL) {
  882. return (NULL);
  883. }
  884. dd = &udev->usb_template_ptr->udd;
  885. if (dd->bDescriptorType != UDESC_DEVICE) {
  886. /* sanity check failed */
  887. return (NULL);
  888. }
  889. return (dd);
  890. }
  891. /*------------------------------------------------------------------------*
  892. * usb_temp_get_qualifier_desc
  893. *
  894. * Returns:
  895. * NULL: No USB device_qualifier descriptor found.
  896. * Else: Pointer to USB device_qualifier descriptor.
  897. *------------------------------------------------------------------------*/
  898. static void *
  899. usb_temp_get_qualifier_desc(struct usb_device *udev)
  900. {
  901. struct usb_device_qualifier *dq;
  902. if (udev->usb_template_ptr == NULL) {
  903. return (NULL);
  904. }
  905. dq = &udev->usb_template_ptr->udq;
  906. if (dq->bDescriptorType != UDESC_DEVICE_QUALIFIER) {
  907. /* sanity check failed */
  908. return (NULL);
  909. }
  910. return (dq);
  911. }
  912. /*------------------------------------------------------------------------*
  913. * usb_temp_get_config_desc
  914. *
  915. * Returns:
  916. * NULL: No USB config descriptor found.
  917. * Else: Pointer to USB config descriptor having index "index".
  918. *------------------------------------------------------------------------*/
  919. static void *
  920. usb_temp_get_config_desc(struct usb_device *udev,
  921. uint16_t *pLength, uint8_t index)
  922. {
  923. struct usb_device_descriptor *dd;
  924. struct usb_config_descriptor *cd;
  925. uint16_t temp;
  926. if (udev->usb_template_ptr == NULL) {
  927. return (NULL);
  928. }
  929. dd = &udev->usb_template_ptr->udd;
  930. cd = (void *)(udev->usb_template_ptr + 1);
  931. if (index >= dd->bNumConfigurations) {
  932. /* out of range */
  933. return (NULL);
  934. }
  935. while (index--) {
  936. if (cd->bDescriptorType != UDESC_CONFIG) {
  937. /* sanity check failed */
  938. return (NULL);
  939. }
  940. temp = UGETW(cd->wTotalLength);
  941. cd = USB_ADD_BYTES(cd, temp);
  942. }
  943. if (pLength) {
  944. *pLength = UGETW(cd->wTotalLength);
  945. }
  946. return (cd);
  947. }
  948. /*------------------------------------------------------------------------*
  949. * usb_temp_get_vendor_desc
  950. *
  951. * Returns:
  952. * NULL: No vendor descriptor found.
  953. * Else: Pointer to a vendor descriptor.
  954. *------------------------------------------------------------------------*/
  955. static const void *
  956. usb_temp_get_vendor_desc(struct usb_device *udev,
  957. const struct usb_device_request *req, uint16_t *plen)
  958. {
  959. const struct usb_temp_device_desc *tdd;
  960. tdd = usb_temp_get_tdd(udev);
  961. if (tdd == NULL) {
  962. return (NULL);
  963. }
  964. if (tdd->getVendorDesc == NULL) {
  965. return (NULL);
  966. }
  967. return ((tdd->getVendorDesc) (req, plen));
  968. }
  969. /*------------------------------------------------------------------------*
  970. * usb_temp_get_string_desc
  971. *
  972. * Returns:
  973. * NULL: No string descriptor found.
  974. * Else: Pointer to a string descriptor.
  975. *------------------------------------------------------------------------*/
  976. static const void *
  977. usb_temp_get_string_desc(struct usb_device *udev,
  978. uint16_t lang_id, uint8_t string_index)
  979. {
  980. const struct usb_temp_device_desc *tdd;
  981. tdd = usb_temp_get_tdd(udev);
  982. if (tdd == NULL) {
  983. return (NULL);
  984. }
  985. if (tdd->getStringDesc == NULL) {
  986. return (NULL);
  987. }
  988. return ((tdd->getStringDesc) (lang_id, string_index));
  989. }
  990. /*------------------------------------------------------------------------*
  991. * usb_temp_get_hub_desc
  992. *
  993. * Returns:
  994. * NULL: No USB HUB descriptor found.
  995. * Else: Pointer to a USB HUB descriptor.
  996. *------------------------------------------------------------------------*/
  997. static const void *
  998. usb_temp_get_hub_desc(struct usb_device *udev)
  999. {
  1000. return (NULL); /* needs to be implemented */
  1001. }
  1002. /*------------------------------------------------------------------------*
  1003. * usb_temp_get_desc
  1004. *
  1005. * This function is a demultiplexer for local USB device side control
  1006. * endpoint requests.
  1007. *------------------------------------------------------------------------*/
  1008. static usb_error_t
  1009. usb_temp_get_desc(struct usb_device *udev, struct usb_device_request *req,
  1010. const void **pPtr, uint16_t *pLength)
  1011. {
  1012. const uint8_t *buf;
  1013. uint16_t len;
  1014. buf = NULL;
  1015. len = 0;
  1016. switch (req->bmRequestType) {
  1017. case UT_READ_DEVICE:
  1018. switch (req->bRequest) {
  1019. case UR_GET_DESCRIPTOR:
  1020. goto tr_handle_get_descriptor;
  1021. default:
  1022. goto tr_stalled;
  1023. }
  1024. case UT_READ_CLASS_DEVICE:
  1025. switch (req->bRequest) {
  1026. case UR_GET_DESCRIPTOR:
  1027. goto tr_handle_get_class_descriptor;
  1028. default:
  1029. goto tr_stalled;
  1030. }
  1031. default:
  1032. goto tr_stalled;
  1033. }
  1034. tr_handle_get_descriptor:
  1035. switch (req->wValue[1]) {
  1036. case UDESC_DEVICE:
  1037. if (req->wValue[0]) {
  1038. goto tr_stalled;
  1039. }
  1040. buf = usb_temp_get_device_desc(udev);
  1041. goto tr_valid;
  1042. case UDESC_DEVICE_QUALIFIER:
  1043. if (udev->speed != USB_SPEED_HIGH) {
  1044. goto tr_stalled;
  1045. }
  1046. if (req->wValue[0]) {
  1047. goto tr_stalled;
  1048. }
  1049. buf = usb_temp_get_qualifier_desc(udev);
  1050. goto tr_valid;
  1051. case UDESC_OTHER_SPEED_CONFIGURATION:
  1052. if (udev->speed != USB_SPEED_HIGH) {
  1053. goto tr_stalled;
  1054. }
  1055. case UDESC_CONFIG:
  1056. buf = usb_temp_get_config_desc(udev,
  1057. &len, req->wValue[0]);
  1058. goto tr_valid;
  1059. case UDESC_STRING:
  1060. buf = usb_temp_get_string_desc(udev,
  1061. UGETW(req->wIndex), req->wValue[0]);
  1062. goto tr_valid;
  1063. default:
  1064. goto tr_stalled;
  1065. }
  1066. tr_handle_get_class_descriptor:
  1067. if (req->wValue[0]) {
  1068. goto tr_stalled;
  1069. }
  1070. buf = usb_temp_get_hub_desc(udev);
  1071. goto tr_valid;
  1072. tr_valid:
  1073. if (buf == NULL)
  1074. goto tr_stalled;
  1075. if (len == 0)
  1076. len = buf[0];
  1077. *pPtr = buf;
  1078. *pLength = len;
  1079. return (0); /* success */
  1080. tr_stalled:
  1081. /* try to get a vendor specific descriptor */
  1082. len = 0;
  1083. buf = usb_temp_get_vendor_desc(udev, req, &len);
  1084. if (buf != NULL)
  1085. goto tr_valid;
  1086. *pPtr = NULL;
  1087. *pLength = 0;
  1088. return (0); /* we ignore failures */
  1089. }
  1090. /*------------------------------------------------------------------------*
  1091. * usb_temp_setup
  1092. *
  1093. * This function generates USB descriptors according to the given USB
  1094. * template device descriptor. It will also try to figure out the best
  1095. * matching endpoint addresses using the hardware endpoint profiles.
  1096. *
  1097. * Returns:
  1098. * 0: Success
  1099. * Else: Failure
  1100. *------------------------------------------------------------------------*/
  1101. usb_error_t
  1102. usb_temp_setup(struct usb_device *udev,
  1103. const struct usb_temp_device_desc *tdd)
  1104. {
  1105. struct usb_temp_setup *uts;
  1106. void *buf;
  1107. uint8_t n;
  1108. if (tdd == NULL) {
  1109. /* be NULL safe */
  1110. return (0);
  1111. }
  1112. uts = udev->bus->scratch[0].temp_setup;
  1113. memset(uts, 0, sizeof(*uts));
  1114. uts->usb_speed = udev->speed;
  1115. uts->self_powered = udev->flags.self_powered;
  1116. /* first pass */
  1117. usb_make_device_desc(uts, tdd);
  1118. if (uts->err) {
  1119. /* some error happened */
  1120. return (uts->err);
  1121. }
  1122. /* sanity check */
  1123. if (uts->size == 0) {
  1124. return (USB_ERR_INVAL);
  1125. }
  1126. /* allocate zeroed memory */
  1127. uts->buf = malloc(uts->size, M_USB, M_WAITOK | M_ZERO);
  1128. if (uts->buf == NULL) {
  1129. /* could not allocate memory */
  1130. return (USB_ERR_NOMEM);
  1131. }
  1132. /* second pass */
  1133. uts->size = 0;
  1134. usb_make_device_desc(uts, tdd);
  1135. /*
  1136. * Store a pointer to our descriptors:
  1137. */
  1138. udev->usb_template_ptr = uts->buf;
  1139. if (uts->err) {
  1140. /* some error happened during second pass */
  1141. goto error;
  1142. }
  1143. /*
  1144. * Resolve all endpoint addresses !
  1145. */
  1146. buf = usb_temp_get_device_desc(udev);
  1147. uts->err = usb_hw_ep_resolve(udev, buf);
  1148. if (uts->err) {
  1149. DPRINTFN(0, "Could not resolve endpoints for "
  1150. "Device Descriptor, error = %s\n",
  1151. usbd_errstr(uts->err));
  1152. goto error;
  1153. }
  1154. for (n = 0;; n++) {
  1155. buf = usb_temp_get_config_desc(udev, NULL, n);
  1156. if (buf == NULL) {
  1157. break;
  1158. }
  1159. uts->err = usb_hw_ep_resolve(udev, buf);
  1160. if (uts->err) {
  1161. DPRINTFN(0, "Could not resolve endpoints for "
  1162. "Config Descriptor %u, error = %s\n", n,
  1163. usbd_errstr(uts->err));
  1164. goto error;
  1165. }
  1166. }
  1167. return (uts->err);
  1168. error:
  1169. usb_temp_unsetup(udev);
  1170. return (uts->err);
  1171. }
  1172. /*------------------------------------------------------------------------*
  1173. * usb_temp_unsetup
  1174. *
  1175. * This function frees any memory associated with the currently
  1176. * setup template, if any.
  1177. *------------------------------------------------------------------------*/
  1178. void
  1179. usb_temp_unsetup(struct usb_device *udev)
  1180. {
  1181. if (udev->usb_template_ptr) {
  1182. free(udev->usb_template_ptr, M_USB);
  1183. udev->usb_template_ptr = NULL;
  1184. }
  1185. }
  1186. static usb_error_t
  1187. usb_temp_setup_by_index(struct usb_device *udev, uint16_t index)
  1188. {
  1189. usb_error_t err;
  1190. switch (index) {
  1191. case USB_TEMP_MSC:
  1192. err = usb_temp_setup(udev, &usb_template_msc);
  1193. break;
  1194. case USB_TEMP_CDCE:
  1195. err = usb_temp_setup(udev, &usb_template_cdce);
  1196. break;
  1197. case USB_TEMP_MTP:
  1198. err = usb_temp_setup(udev, &usb_template_mtp);
  1199. break;
  1200. case USB_TEMP_MODEM:
  1201. err = usb_temp_setup(udev, &usb_template_modem);
  1202. break;
  1203. case USB_TEMP_AUDIO:
  1204. err = usb_temp_setup(udev, &usb_template_audio);
  1205. break;
  1206. case USB_TEMP_KBD:
  1207. err = usb_temp_setup(udev, &usb_template_kbd);
  1208. break;
  1209. case USB_TEMP_MOUSE:
  1210. err = usb_temp_setup(udev, &usb_template_mouse);
  1211. break;
  1212. default:
  1213. return (USB_ERR_INVAL);
  1214. }
  1215. return (err);
  1216. }
  1217. static void
  1218. usb_temp_init(void *arg)
  1219. {
  1220. /* register our functions */
  1221. usb_temp_get_desc_p = &usb_temp_get_desc;
  1222. usb_temp_setup_by_index_p = &usb_temp_setup_by_index;
  1223. usb_temp_unsetup_p = &usb_temp_unsetup;
  1224. }
  1225. SYSINIT(usb_temp_init, SI_SUB_LOCK, SI_ORDER_FIRST, usb_temp_init, NULL);
  1226. SYSUNINIT(usb_temp_unload, SI_SUB_LOCK, SI_ORDER_ANY, usb_temp_unload, NULL);