3 * Copyright (c) 2007 Hans Petter Selasky. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
28 * This file contains sub-routines to build up USB descriptors from
32 #include <sys/stdint.h>
33 #include <sys/stddef.h>
34 #include <sys/param.h>
35 #include <sys/queue.h>
36 #include <sys/types.h>
37 #include <sys/systm.h>
38 #include <sys/kernel.h>
40 #include <sys/module.h>
42 #include <sys/mutex.h>
43 #include <sys/condvar.h>
44 #include <sys/sysctl.h>
46 #include <sys/unistd.h>
47 #include <sys/callout.h>
48 #include <sys/malloc.h>
51 #include <dev/usb/usb.h>
52 #include <dev/usb/usbdi.h>
53 #include <dev/usb/usbdi_util.h>
56 #include <dev/usb/usb_cdc.h>
57 #include <dev/usb/usb_core.h>
58 #include <dev/usb/usb_dynamic.h>
59 #include <dev/usb/usb_busdma.h>
60 #include <dev/usb/usb_process.h>
61 #include <dev/usb/usb_device.h>
63 #define USB_DEBUG_VAR usb_debug
64 #include <dev/usb/usb_debug.h>
66 #include <dev/usb/usb_controller.h>
67 #include <dev/usb/usb_bus.h>
68 #include <dev/usb/template/usb_template.h>
70 MODULE_DEPEND(usb_template, usb, 1, 1, 1);
71 MODULE_VERSION(usb_template, 1);
73 /* function prototypes */
75 static void usb_make_raw_desc(struct usb_temp_setup *, const uint8_t *);
76 static void usb_make_endpoint_desc(struct usb_temp_setup *,
77 const struct usb_temp_endpoint_desc *);
78 static void usb_make_interface_desc(struct usb_temp_setup *,
79 const struct usb_temp_interface_desc *);
80 static void usb_make_config_desc(struct usb_temp_setup *,
81 const struct usb_temp_config_desc *);
82 static void usb_make_device_desc(struct usb_temp_setup *,
83 const struct usb_temp_device_desc *);
84 static uint8_t usb_hw_ep_match(const struct usb_hw_ep_profile *, uint8_t,
86 static uint8_t usb_hw_ep_find_match(struct usb_hw_ep_scratch *,
87 struct usb_hw_ep_scratch_sub *, uint8_t);
88 static uint8_t usb_hw_ep_get_needs(struct usb_hw_ep_scratch *, uint8_t,
90 static usb_error_t usb_hw_ep_resolve(struct usb_device *,
91 struct usb_descriptor *);
92 static const struct usb_temp_device_desc *usb_temp_get_tdd(struct usb_device *);
93 static void *usb_temp_get_device_desc(struct usb_device *);
94 static void *usb_temp_get_qualifier_desc(struct usb_device *);
95 static void *usb_temp_get_config_desc(struct usb_device *, uint16_t *,
97 static const void *usb_temp_get_string_desc(struct usb_device *, uint16_t,
99 static const void *usb_temp_get_vendor_desc(struct usb_device *,
100 const struct usb_device_request *, uint16_t *plen);
101 static const void *usb_temp_get_hub_desc(struct usb_device *);
102 static usb_error_t usb_temp_get_desc(struct usb_device *,
103 struct usb_device_request *, const void **, uint16_t *);
104 static usb_error_t usb_temp_setup_by_index(struct usb_device *,
106 static void usb_temp_init(void *);
108 /*------------------------------------------------------------------------*
111 * This function will insert a raw USB descriptor into the generated
113 *------------------------------------------------------------------------*/
115 usb_make_raw_desc(struct usb_temp_setup *temp,
122 * The first byte of any USB descriptor gives the length.
127 dst = USB_ADD_BYTES(temp->buf, temp->size);
128 memcpy(dst, raw, len);
130 /* check if we have got a CDC union descriptor */
132 if ((raw[0] >= sizeof(struct usb_cdc_union_descriptor)) &&
133 (raw[1] == UDESC_CS_INTERFACE) &&
134 (raw[2] == UDESCSUB_CDC_UNION)) {
135 struct usb_cdc_union_descriptor *ud = (void *)dst;
137 /* update the interface numbers */
139 ud->bMasterInterface +=
140 temp->bInterfaceNumber;
141 ud->bSlaveInterface[0] +=
142 temp->bInterfaceNumber;
149 /*------------------------------------------------------------------------*
150 * usb_make_endpoint_desc
152 * This function will generate an USB endpoint descriptor from the
153 * given USB template endpoint descriptor, which will be inserted into
154 * the USB configuration.
155 *------------------------------------------------------------------------*/
157 usb_make_endpoint_desc(struct usb_temp_setup *temp,
158 const struct usb_temp_endpoint_desc *ted)
160 struct usb_endpoint_descriptor *ed;
164 uint8_t ea; /* Endpoint Address */
165 uint8_t et; /* Endpiont Type */
168 old_size = temp->size;
170 ea = (ted->bEndpointAddress & (UE_ADDR | UE_DIR_IN | UE_DIR_OUT));
171 et = (ted->bmAttributes & UE_XFERTYPE);
173 if (et == UE_ISOCHRONOUS) {
174 /* account for extra byte fields */
175 temp->size += sizeof(*ed) + 2;
177 temp->size += sizeof(*ed);
180 /* Scan all Raw Descriptors first */
184 usb_make_raw_desc(temp, *rd);
188 if (ted->pPacketSize == NULL) {
189 /* not initialized */
190 temp->err = USB_ERR_INVAL;
193 mps = ted->pPacketSize->mps[temp->usb_speed];
195 /* not initialized */
196 temp->err = USB_ERR_INVAL;
198 } else if (mps == UE_ZERO_MPS) {
199 /* escape for Zero Max Packet Size */
204 * Fill out the real USB endpoint descriptor
205 * in case there is a buffer present:
208 ed = USB_ADD_BYTES(temp->buf, old_size);
209 if (et == UE_ISOCHRONOUS)
210 ed->bLength = sizeof(*ed) + 2;
212 ed->bLength = sizeof(*ed);
213 ed->bDescriptorType = UDESC_ENDPOINT;
214 ed->bEndpointAddress = ea;
215 ed->bmAttributes = ted->bmAttributes;
216 USETW(ed->wMaxPacketSize, mps);
218 /* setup bInterval parameter */
220 if (ted->pIntervals &&
221 ted->pIntervals->bInterval[temp->usb_speed]) {
223 ted->pIntervals->bInterval[temp->usb_speed];
228 ed->bInterval = 0; /* not used */
231 switch (temp->usb_speed) {
234 ed->bInterval = 1; /* 1 ms */
237 ed->bInterval = 8; /* 8*125 us */
241 default: /* UE_ISOCHRONOUS */
242 switch (temp->usb_speed) {
245 ed->bInterval = 1; /* 1 ms */
248 ed->bInterval = 1; /* 125 us */
255 temp->bNumEndpoints++;
258 /*------------------------------------------------------------------------*
259 * usb_make_interface_desc
261 * This function will generate an USB interface descriptor from the
262 * given USB template interface descriptor, which will be inserted
263 * into the USB configuration.
264 *------------------------------------------------------------------------*/
266 usb_make_interface_desc(struct usb_temp_setup *temp,
267 const struct usb_temp_interface_desc *tid)
269 struct usb_interface_descriptor *id;
270 const struct usb_temp_endpoint_desc **ted;
276 old_size = temp->size;
277 temp->size += sizeof(*id);
279 /* Update interface and alternate interface numbers */
281 if (tid->isAltInterface == 0) {
282 temp->bAlternateSetting = 0;
283 temp->bInterfaceNumber++;
285 temp->bAlternateSetting++;
288 /* Scan all Raw Descriptors first */
294 usb_make_raw_desc(temp, *rd);
298 /* Reset some counters */
300 temp->bNumEndpoints = 0;
302 /* Scan all Endpoint Descriptors second */
304 ted = tid->ppEndpoints;
307 usb_make_endpoint_desc(temp, *ted);
312 * Fill out the real USB interface descriptor
313 * in case there is a buffer present:
316 id = USB_ADD_BYTES(temp->buf, old_size);
317 id->bLength = sizeof(*id);
318 id->bDescriptorType = UDESC_INTERFACE;
319 id->bInterfaceNumber = temp->bInterfaceNumber;
320 id->bAlternateSetting = temp->bAlternateSetting;
321 id->bNumEndpoints = temp->bNumEndpoints;
322 id->bInterfaceClass = tid->bInterfaceClass;
323 id->bInterfaceSubClass = tid->bInterfaceSubClass;
324 id->bInterfaceProtocol = tid->bInterfaceProtocol;
325 id->iInterface = tid->iInterface;
329 /*------------------------------------------------------------------------*
330 * usb_make_config_desc
332 * This function will generate an USB config descriptor from the given
333 * USB template config descriptor, which will be inserted into the USB
335 *------------------------------------------------------------------------*/
337 usb_make_config_desc(struct usb_temp_setup *temp,
338 const struct usb_temp_config_desc *tcd)
340 struct usb_config_descriptor *cd;
341 const struct usb_temp_interface_desc **tid;
346 old_size = temp->size;
347 temp->size += sizeof(*cd);
349 /* Reset some counters */
351 temp->bInterfaceNumber = 0 - 1;
352 temp->bAlternateSetting = 0;
354 /* Scan all the USB interfaces */
356 tid = tcd->ppIfaceDesc;
359 usb_make_interface_desc(temp, *tid);
364 * Fill out the real USB config descriptor
365 * in case there is a buffer present:
368 cd = USB_ADD_BYTES(temp->buf, old_size);
370 /* compute total size */
371 old_size = temp->size - old_size;
373 cd->bLength = sizeof(*cd);
374 cd->bDescriptorType = UDESC_CONFIG;
375 USETW(cd->wTotalLength, old_size);
376 cd->bNumInterface = temp->bInterfaceNumber + 1;
377 cd->bConfigurationValue = temp->bConfigurationValue;
378 cd->iConfiguration = tcd->iConfiguration;
379 cd->bmAttributes = tcd->bmAttributes;
380 cd->bMaxPower = tcd->bMaxPower;
381 cd->bmAttributes |= (UC_REMOTE_WAKEUP | UC_BUS_POWERED);
383 if (temp->self_powered) {
384 cd->bmAttributes |= UC_SELF_POWERED;
386 cd->bmAttributes &= ~UC_SELF_POWERED;
391 /*------------------------------------------------------------------------*
392 * usb_make_device_desc
394 * This function will generate an USB device descriptor from the
395 * given USB template device descriptor.
396 *------------------------------------------------------------------------*/
398 usb_make_device_desc(struct usb_temp_setup *temp,
399 const struct usb_temp_device_desc *tdd)
401 struct usb_temp_data *utd;
402 const struct usb_temp_config_desc **tcd;
407 old_size = temp->size;
408 temp->size += sizeof(*utd);
410 /* Scan all the USB configs */
412 temp->bConfigurationValue = 1;
413 tcd = tdd->ppConfigDesc;
416 usb_make_config_desc(temp, *tcd);
417 temp->bConfigurationValue++;
422 * Fill out the real USB device descriptor
423 * in case there is a buffer present:
427 utd = USB_ADD_BYTES(temp->buf, old_size);
429 /* Store a pointer to our template device descriptor */
432 /* Fill out USB device descriptor */
433 utd->udd.bLength = sizeof(utd->udd);
434 utd->udd.bDescriptorType = UDESC_DEVICE;
435 utd->udd.bDeviceClass = tdd->bDeviceClass;
436 utd->udd.bDeviceSubClass = tdd->bDeviceSubClass;
437 utd->udd.bDeviceProtocol = tdd->bDeviceProtocol;
438 USETW(utd->udd.idVendor, tdd->idVendor);
439 USETW(utd->udd.idProduct, tdd->idProduct);
440 USETW(utd->udd.bcdDevice, tdd->bcdDevice);
441 utd->udd.iManufacturer = tdd->iManufacturer;
442 utd->udd.iProduct = tdd->iProduct;
443 utd->udd.iSerialNumber = tdd->iSerialNumber;
444 utd->udd.bNumConfigurations = temp->bConfigurationValue - 1;
447 * Fill out the USB device qualifier. Pretend that we
448 * don't support any other speeds by setting
449 * "bNumConfigurations" equal to zero. That saves us
450 * generating an extra set of configuration
453 utd->udq.bLength = sizeof(utd->udq);
454 utd->udq.bDescriptorType = UDESC_DEVICE_QUALIFIER;
455 utd->udq.bDeviceClass = tdd->bDeviceClass;
456 utd->udq.bDeviceSubClass = tdd->bDeviceSubClass;
457 utd->udq.bDeviceProtocol = tdd->bDeviceProtocol;
458 utd->udq.bNumConfigurations = 0;
459 USETW(utd->udq.bcdUSB, 0x0200);
460 utd->udq.bMaxPacketSize0 = 0;
462 switch (temp->usb_speed) {
464 USETW(utd->udd.bcdUSB, 0x0110);
465 utd->udd.bMaxPacketSize = 8;
468 USETW(utd->udd.bcdUSB, 0x0110);
469 utd->udd.bMaxPacketSize = 32;
472 USETW(utd->udd.bcdUSB, 0x0200);
473 utd->udd.bMaxPacketSize = 64;
475 case USB_SPEED_VARIABLE:
476 USETW(utd->udd.bcdUSB, 0x0250);
477 utd->udd.bMaxPacketSize = 255; /* 512 bytes */
480 temp->err = USB_ERR_INVAL;
486 /*------------------------------------------------------------------------*
490 * 0: The endpoint profile does not match the criterias
491 * Else: The endpoint profile matches the criterias
492 *------------------------------------------------------------------------*/
494 usb_hw_ep_match(const struct usb_hw_ep_profile *pf,
495 uint8_t ep_type, uint8_t ep_dir_in)
497 if (ep_type == UE_CONTROL) {
499 return (pf->support_control);
501 if ((pf->support_in && ep_dir_in) ||
502 (pf->support_out && !ep_dir_in)) {
503 if ((pf->support_interrupt && (ep_type == UE_INTERRUPT)) ||
504 (pf->support_isochronous && (ep_type == UE_ISOCHRONOUS)) ||
505 (pf->support_bulk && (ep_type == UE_BULK))) {
512 /*------------------------------------------------------------------------*
513 * usb_hw_ep_find_match
515 * This function is used to find the best matching endpoint profile
516 * for and endpoint belonging to an USB descriptor.
519 * 0: Success. Got a match.
520 * Else: Failure. No match.
521 *------------------------------------------------------------------------*/
523 usb_hw_ep_find_match(struct usb_hw_ep_scratch *ues,
524 struct usb_hw_ep_scratch_sub *ep, uint8_t is_simplex)
526 const struct usb_hw_ep_profile *pf;
529 uint16_t max_frame_size;
538 if ((!ep->needs_in) && (!ep->needs_out)) {
539 return (0); /* we are done */
541 if (ep->needs_ep_type == UE_CONTROL) {
554 for (n = 1; n != (USB_EP_MAX / 2); n++) {
556 /* get HW endpoint profile */
557 (ues->methods->get_hw_ep_profile) (ues->udev, &pf, n);
559 /* end of profiles */
562 /* check if IN-endpoint is reserved */
563 if (dir_in || pf->is_simplex) {
564 if (ues->bmInAlloc[n / 8] & (1 << (n % 8))) {
569 /* check if OUT-endpoint is reserved */
570 if (dir_out || pf->is_simplex) {
571 if (ues->bmOutAlloc[n / 8] & (1 << (n % 8))) {
577 if (pf->is_simplex == is_simplex) {
581 /* check if HW endpoint matches */
582 if (!usb_hw_ep_match(pf, ep->needs_ep_type, dir_in)) {
586 /* get maximum frame size */
588 max_frame_size = pf->max_in_frame_size;
590 max_frame_size = pf->max_out_frame_size;
592 /* check if we have a matching profile */
593 if (max_frame_size >= ep->max_frame_size) {
594 temp = (max_frame_size - ep->max_frame_size);
595 if (distance > temp) {
603 /* see if we got a match */
605 /* get the correct profile */
608 /* reserve IN-endpoint */
610 ues->bmInAlloc[best_n / 8] |=
612 ep->hw_endpoint_in = best_n | UE_DIR_IN;
615 /* reserve OUT-endpoint */
617 ues->bmOutAlloc[best_n / 8] |=
619 ep->hw_endpoint_out = best_n | UE_DIR_OUT;
622 return (0); /* got a match */
624 return (1); /* failure */
627 /*------------------------------------------------------------------------*
628 * usb_hw_ep_get_needs
630 * This function will figure out the type and number of endpoints
631 * which are needed for an USB configuration.
636 *------------------------------------------------------------------------*/
638 usb_hw_ep_get_needs(struct usb_hw_ep_scratch *ues,
639 uint8_t ep_type, uint8_t is_complete)
641 const struct usb_hw_ep_profile *pf;
642 struct usb_hw_ep_scratch_sub *ep_iface;
643 struct usb_hw_ep_scratch_sub *ep_curr;
644 struct usb_hw_ep_scratch_sub *ep_max;
645 struct usb_hw_ep_scratch_sub *ep_end;
646 struct usb_descriptor *desc;
647 struct usb_interface_descriptor *id;
648 struct usb_endpoint_descriptor *ed;
649 enum usb_dev_speed speed;
650 uint16_t wMaxPacketSize;
654 ep_iface = ues->ep_max;
655 ep_curr = ues->ep_max;
656 ep_end = ues->ep + USB_EP_MAX;
657 ep_max = ues->ep_max;
659 speed = usbd_get_speed(ues->udev);
663 while ((desc = usb_desc_foreach(ues->cd, desc))) {
665 if ((desc->bDescriptorType == UDESC_INTERFACE) &&
666 (desc->bLength >= sizeof(*id))) {
670 if (id->bAlternateSetting == 0) {
678 if ((desc->bDescriptorType == UDESC_ENDPOINT) &&
679 (desc->bLength >= sizeof(*ed))) {
683 goto handle_endpoint_desc;
686 ues->ep_max = ep_max;
689 handle_endpoint_desc:
690 temp = (ed->bmAttributes & UE_XFERTYPE);
692 if (temp == ep_type) {
694 if (ep_curr == ep_end) {
695 /* too many endpoints */
696 return (1); /* failure */
698 wMaxPacketSize = UGETW(ed->wMaxPacketSize);
699 if ((wMaxPacketSize & 0xF800) &&
700 (speed == USB_SPEED_HIGH)) {
701 /* handle packet multiplier */
702 temp = (wMaxPacketSize >> 11) & 3;
703 wMaxPacketSize &= 0x7FF;
711 * Check if we have a fixed endpoint number, else the
712 * endpoint number is allocated dynamically:
714 ep_no = (ed->bEndpointAddress & UE_ADDR);
717 /* get HW endpoint profile */
718 (ues->methods->get_hw_ep_profile)
719 (ues->udev, &pf, ep_no);
721 /* HW profile does not exist - failure */
722 DPRINTFN(0, "Endpoint profile %u "
723 "does not exist\n", ep_no);
726 /* reserve fixed endpoint number */
727 if (ep_type == UE_CONTROL) {
728 ues->bmInAlloc[ep_no / 8] |=
730 ues->bmOutAlloc[ep_no / 8] |=
732 if ((pf->max_in_frame_size < wMaxPacketSize) ||
733 (pf->max_out_frame_size < wMaxPacketSize)) {
734 DPRINTFN(0, "Endpoint profile %u "
735 "has too small buffer\n", ep_no);
738 } else if (ed->bEndpointAddress & UE_DIR_IN) {
739 ues->bmInAlloc[ep_no / 8] |=
741 if (pf->max_in_frame_size < wMaxPacketSize) {
742 DPRINTFN(0, "Endpoint profile %u "
743 "has too small buffer\n", ep_no);
747 ues->bmOutAlloc[ep_no / 8] |=
749 if (pf->max_out_frame_size < wMaxPacketSize) {
750 DPRINTFN(0, "Endpoint profile %u "
751 "has too small buffer\n", ep_no);
755 } else if (is_complete) {
757 /* check if we have enough buffer space */
759 ep_curr->max_frame_size) {
760 return (1); /* failure */
762 if (ed->bEndpointAddress & UE_DIR_IN) {
763 ed->bEndpointAddress =
764 ep_curr->hw_endpoint_in;
766 ed->bEndpointAddress =
767 ep_curr->hw_endpoint_out;
772 /* compute the maximum frame size */
773 if (ep_curr->max_frame_size < wMaxPacketSize) {
774 ep_curr->max_frame_size = wMaxPacketSize;
776 if (temp == UE_CONTROL) {
777 ep_curr->needs_in = 1;
778 ep_curr->needs_out = 1;
780 if (ed->bEndpointAddress & UE_DIR_IN) {
781 ep_curr->needs_in = 1;
783 ep_curr->needs_out = 1;
786 ep_curr->needs_ep_type = ep_type;
790 if (ep_max < ep_curr) {
797 /*------------------------------------------------------------------------*
800 * This function will try to resolve endpoint requirements by the
801 * given endpoint profiles that the USB hardware reports.
806 *------------------------------------------------------------------------*/
808 usb_hw_ep_resolve(struct usb_device *udev,
809 struct usb_descriptor *desc)
811 struct usb_hw_ep_scratch *ues;
812 struct usb_hw_ep_scratch_sub *ep;
813 const struct usb_hw_ep_profile *pf;
814 struct usb_bus_methods *methods;
815 struct usb_device_descriptor *dd;
819 return (USB_ERR_INVAL);
821 /* get bus methods */
822 methods = udev->bus->methods;
824 if (methods->get_hw_ep_profile == NULL) {
825 return (USB_ERR_INVAL);
827 if (desc->bDescriptorType == UDESC_DEVICE) {
829 if (desc->bLength < sizeof(*dd)) {
830 return (USB_ERR_INVAL);
834 /* get HW control endpoint 0 profile */
835 (methods->get_hw_ep_profile) (udev, &pf, 0);
837 return (USB_ERR_INVAL);
839 if (!usb_hw_ep_match(pf, UE_CONTROL, 0)) {
840 DPRINTFN(0, "Endpoint 0 does not "
841 "support control\n");
842 return (USB_ERR_INVAL);
844 mps = dd->bMaxPacketSize;
846 if (udev->speed == USB_SPEED_FULL) {
848 * We can optionally choose another packet size !
851 /* check if "mps" is ok */
852 if (pf->max_in_frame_size >= mps) {
855 /* reduce maximum packet size */
858 /* check if "mps" is too small */
860 return (USB_ERR_INVAL);
864 dd->bMaxPacketSize = mps;
867 /* We only have one choice */
871 /* Check if we support the specified wMaxPacketSize */
872 if (pf->max_in_frame_size < mps) {
873 return (USB_ERR_INVAL);
876 return (0); /* success */
878 if (desc->bDescriptorType != UDESC_CONFIG) {
879 return (USB_ERR_INVAL);
881 if (desc->bLength < sizeof(*(ues->cd))) {
882 return (USB_ERR_INVAL);
884 ues = udev->bus->scratch[0].hw_ep_scratch;
886 bzero(ues, sizeof(*ues));
888 ues->ep_max = ues->ep;
889 ues->cd = (void *)desc;
890 ues->methods = methods;
893 /* Get all the endpoints we need */
895 if (usb_hw_ep_get_needs(ues, UE_ISOCHRONOUS, 0) ||
896 usb_hw_ep_get_needs(ues, UE_INTERRUPT, 0) ||
897 usb_hw_ep_get_needs(ues, UE_CONTROL, 0) ||
898 usb_hw_ep_get_needs(ues, UE_BULK, 0)) {
899 DPRINTFN(0, "Could not get needs\n");
900 return (USB_ERR_INVAL);
902 for (ep = ues->ep; ep != ues->ep_max; ep++) {
904 while (ep->needs_in || ep->needs_out) {
907 * First try to use a simplex endpoint.
908 * Then try to use a duplex endpoint.
910 if (usb_hw_ep_find_match(ues, ep, 1) &&
911 usb_hw_ep_find_match(ues, ep, 0)) {
912 DPRINTFN(0, "Could not find match\n");
913 return (USB_ERR_INVAL);
918 ues->ep_max = ues->ep;
920 /* Update all endpoint addresses */
922 if (usb_hw_ep_get_needs(ues, UE_ISOCHRONOUS, 1) ||
923 usb_hw_ep_get_needs(ues, UE_INTERRUPT, 1) ||
924 usb_hw_ep_get_needs(ues, UE_CONTROL, 1) ||
925 usb_hw_ep_get_needs(ues, UE_BULK, 1)) {
926 DPRINTFN(0, "Could not update endpoint address\n");
927 return (USB_ERR_INVAL);
929 return (0); /* success */
932 /*------------------------------------------------------------------------*
936 * NULL: No USB template device descriptor found.
937 * Else: Pointer to the USB template device descriptor.
938 *------------------------------------------------------------------------*/
939 static const struct usb_temp_device_desc *
940 usb_temp_get_tdd(struct usb_device *udev)
942 if (udev->usb_template_ptr == NULL) {
945 return (udev->usb_template_ptr->tdd);
948 /*------------------------------------------------------------------------*
949 * usb_temp_get_device_desc
952 * NULL: No USB device descriptor found.
953 * Else: Pointer to USB device descriptor.
954 *------------------------------------------------------------------------*/
956 usb_temp_get_device_desc(struct usb_device *udev)
958 struct usb_device_descriptor *dd;
960 if (udev->usb_template_ptr == NULL) {
963 dd = &udev->usb_template_ptr->udd;
964 if (dd->bDescriptorType != UDESC_DEVICE) {
965 /* sanity check failed */
971 /*------------------------------------------------------------------------*
972 * usb_temp_get_qualifier_desc
975 * NULL: No USB device_qualifier descriptor found.
976 * Else: Pointer to USB device_qualifier descriptor.
977 *------------------------------------------------------------------------*/
979 usb_temp_get_qualifier_desc(struct usb_device *udev)
981 struct usb_device_qualifier *dq;
983 if (udev->usb_template_ptr == NULL) {
986 dq = &udev->usb_template_ptr->udq;
987 if (dq->bDescriptorType != UDESC_DEVICE_QUALIFIER) {
988 /* sanity check failed */
994 /*------------------------------------------------------------------------*
995 * usb_temp_get_config_desc
998 * NULL: No USB config descriptor found.
999 * Else: Pointer to USB config descriptor having index "index".
1000 *------------------------------------------------------------------------*/
1002 usb_temp_get_config_desc(struct usb_device *udev,
1003 uint16_t *pLength, uint8_t index)
1005 struct usb_device_descriptor *dd;
1006 struct usb_config_descriptor *cd;
1009 if (udev->usb_template_ptr == NULL) {
1012 dd = &udev->usb_template_ptr->udd;
1013 cd = (void *)(udev->usb_template_ptr + 1);
1015 if (index >= dd->bNumConfigurations) {
1020 if (cd->bDescriptorType != UDESC_CONFIG) {
1021 /* sanity check failed */
1024 temp = UGETW(cd->wTotalLength);
1025 cd = USB_ADD_BYTES(cd, temp);
1029 *pLength = UGETW(cd->wTotalLength);
1034 /*------------------------------------------------------------------------*
1035 * usb_temp_get_vendor_desc
1038 * NULL: No vendor descriptor found.
1039 * Else: Pointer to a vendor descriptor.
1040 *------------------------------------------------------------------------*/
1042 usb_temp_get_vendor_desc(struct usb_device *udev,
1043 const struct usb_device_request *req, uint16_t *plen)
1045 const struct usb_temp_device_desc *tdd;
1047 tdd = usb_temp_get_tdd(udev);
1051 if (tdd->getVendorDesc == NULL) {
1054 return ((tdd->getVendorDesc) (req, plen));
1057 /*------------------------------------------------------------------------*
1058 * usb_temp_get_string_desc
1061 * NULL: No string descriptor found.
1062 * Else: Pointer to a string descriptor.
1063 *------------------------------------------------------------------------*/
1065 usb_temp_get_string_desc(struct usb_device *udev,
1066 uint16_t lang_id, uint8_t string_index)
1068 const struct usb_temp_device_desc *tdd;
1070 tdd = usb_temp_get_tdd(udev);
1074 if (tdd->getStringDesc == NULL) {
1077 return ((tdd->getStringDesc) (lang_id, string_index));
1080 /*------------------------------------------------------------------------*
1081 * usb_temp_get_hub_desc
1084 * NULL: No USB HUB descriptor found.
1085 * Else: Pointer to a USB HUB descriptor.
1086 *------------------------------------------------------------------------*/
1088 usb_temp_get_hub_desc(struct usb_device *udev)
1090 return (NULL); /* needs to be implemented */
1093 /*------------------------------------------------------------------------*
1096 * This function is a demultiplexer for local USB device side control
1097 * endpoint requests.
1098 *------------------------------------------------------------------------*/
1100 usb_temp_get_desc(struct usb_device *udev, struct usb_device_request *req,
1101 const void **pPtr, uint16_t *pLength)
1109 switch (req->bmRequestType) {
1110 case UT_READ_DEVICE:
1111 switch (req->bRequest) {
1112 case UR_GET_DESCRIPTOR:
1113 goto tr_handle_get_descriptor;
1117 case UT_READ_CLASS_DEVICE:
1118 switch (req->bRequest) {
1119 case UR_GET_DESCRIPTOR:
1120 goto tr_handle_get_class_descriptor;
1128 tr_handle_get_descriptor:
1129 switch (req->wValue[1]) {
1131 if (req->wValue[0]) {
1134 buf = usb_temp_get_device_desc(udev);
1136 case UDESC_DEVICE_QUALIFIER:
1137 if (udev->speed != USB_SPEED_HIGH) {
1140 if (req->wValue[0]) {
1143 buf = usb_temp_get_qualifier_desc(udev);
1145 case UDESC_OTHER_SPEED_CONFIGURATION:
1146 if (udev->speed != USB_SPEED_HIGH) {
1150 buf = usb_temp_get_config_desc(udev,
1151 &len, req->wValue[0]);
1154 buf = usb_temp_get_string_desc(udev,
1155 UGETW(req->wIndex), req->wValue[0]);
1161 tr_handle_get_class_descriptor:
1162 if (req->wValue[0]) {
1165 buf = usb_temp_get_hub_desc(udev);
1175 return (0); /* success */
1178 /* try to get a vendor specific descriptor */
1180 buf = usb_temp_get_vendor_desc(udev, req, &len);
1185 return (0); /* we ignore failures */
1188 /*------------------------------------------------------------------------*
1191 * This function generates USB descriptors according to the given USB
1192 * template device descriptor. It will also try to figure out the best
1193 * matching endpoint addresses using the hardware endpoint profiles.
1198 *------------------------------------------------------------------------*/
1200 usb_temp_setup(struct usb_device *udev,
1201 const struct usb_temp_device_desc *tdd)
1203 struct usb_temp_setup *uts;
1211 uts = udev->bus->scratch[0].temp_setup;
1213 bzero(uts, sizeof(*uts));
1215 uts->usb_speed = udev->speed;
1216 uts->self_powered = udev->flags.self_powered;
1220 usb_make_device_desc(uts, tdd);
1223 /* some error happened */
1227 if (uts->size == 0) {
1228 return (USB_ERR_INVAL);
1230 /* allocate zeroed memory */
1231 uts->buf = malloc(uts->size, M_USB, M_WAITOK | M_ZERO);
1232 if (uts->buf == NULL) {
1233 /* could not allocate memory */
1234 return (USB_ERR_NOMEM);
1240 usb_make_device_desc(uts, tdd);
1243 * Store a pointer to our descriptors:
1245 udev->usb_template_ptr = uts->buf;
1248 /* some error happened during second pass */
1252 * Resolve all endpoint addresses !
1254 buf = usb_temp_get_device_desc(udev);
1255 uts->err = usb_hw_ep_resolve(udev, buf);
1257 DPRINTFN(0, "Could not resolve endpoints for "
1258 "Device Descriptor, error = %s\n",
1259 usbd_errstr(uts->err));
1264 buf = usb_temp_get_config_desc(udev, NULL, n);
1268 uts->err = usb_hw_ep_resolve(udev, buf);
1270 DPRINTFN(0, "Could not resolve endpoints for "
1271 "Config Descriptor %u, error = %s\n", n,
1272 usbd_errstr(uts->err));
1279 usb_temp_unsetup(udev);
1283 /*------------------------------------------------------------------------*
1286 * This function frees any memory associated with the currently
1287 * setup template, if any.
1288 *------------------------------------------------------------------------*/
1290 usb_temp_unsetup(struct usb_device *udev)
1292 if (udev->usb_template_ptr) {
1294 free(udev->usb_template_ptr, M_USB);
1296 udev->usb_template_ptr = NULL;
1301 usb_temp_setup_by_index(struct usb_device *udev, uint16_t index)
1307 err = usb_temp_setup(udev, &usb_template_msc);
1310 err = usb_temp_setup(udev, &usb_template_cdce);
1313 err = usb_temp_setup(udev, &usb_template_mtp);
1316 return (USB_ERR_INVAL);
1323 usb_temp_init(void *arg)
1325 /* register our functions */
1326 usb_temp_get_desc_p = &usb_temp_get_desc;
1327 usb_temp_setup_by_index_p = &usb_temp_setup_by_index;
1328 usb_temp_unsetup_p = &usb_temp_unsetup;
1331 SYSINIT(usb_temp_init, SI_SUB_LOCK, SI_ORDER_FIRST, usb_temp_init, NULL);
1332 SYSUNINIT(usb_temp_unload, SI_SUB_LOCK, SI_ORDER_ANY, usb_temp_unload, NULL);