1 /* $FreeBSD: head/sys/dev/usb/template/usb_template.c 259218 2013-12-11 13:20:32Z hselasky $ */
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 #ifdef USB_GLOBAL_INCLUDE_FILE
33 #include USB_GLOBAL_INCLUDE_FILE
35 #include <sys/stdint.h>
36 #include <sys/param.h>
37 #include <sys/queue.h>
38 #include <sys/types.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
42 #include <sys/module.h>
44 #include <sys/condvar.h>
45 #include <sys/sysctl.h>
46 #include <sys/unistd.h>
47 #include <sys/callout.h>
48 #include <sys/malloc.h>
51 #include <bus/u4b/usb.h>
52 #include <bus/u4b/usb_ioctl.h>
53 #include <bus/u4b/usbdi.h>
54 #include <bus/u4b/usbdi_util.h>
57 #include <bus/u4b/usb_cdc.h>
58 #include <bus/u4b/usb_core.h>
59 #include <bus/u4b/usb_dynamic.h>
60 #include <bus/u4b/usb_busdma.h>
61 #include <bus/u4b/usb_process.h>
62 #include <bus/u4b/usb_device.h>
64 #define USB_DEBUG_VAR usb_debug
65 #include <bus/u4b/usb_debug.h>
67 #include <bus/u4b/usb_controller.h>
68 #include <bus/u4b/usb_bus.h>
69 #include <bus/u4b/usb_request.h>
70 #include <bus/u4b/template/usb_template.h>
71 #endif /* USB_GLOBAL_INCLUDE_FILE */
73 MODULE_DEPEND(usb_template
, usb
, 1, 1, 1);
74 MODULE_VERSION(usb_template
, 1);
76 /* function prototypes */
78 static void usb_make_raw_desc(struct usb_temp_setup
*, const uint8_t *);
79 static void usb_make_endpoint_desc(struct usb_temp_setup
*,
80 const struct usb_temp_endpoint_desc
*);
81 static void usb_make_interface_desc(struct usb_temp_setup
*,
82 const struct usb_temp_interface_desc
*);
83 static void usb_make_config_desc(struct usb_temp_setup
*,
84 const struct usb_temp_config_desc
*);
85 static void usb_make_device_desc(struct usb_temp_setup
*,
86 const struct usb_temp_device_desc
*);
87 static uint8_t usb_hw_ep_match(const struct usb_hw_ep_profile
*, uint8_t,
89 static uint8_t usb_hw_ep_find_match(struct usb_hw_ep_scratch
*,
90 struct usb_hw_ep_scratch_sub
*, uint8_t);
91 static uint8_t usb_hw_ep_get_needs(struct usb_hw_ep_scratch
*, uint8_t,
93 static usb_error_t
usb_hw_ep_resolve(struct usb_device
*,
94 struct usb_descriptor
*);
95 static const struct usb_temp_device_desc
*usb_temp_get_tdd(struct usb_device
*);
96 static void *usb_temp_get_device_desc(struct usb_device
*);
97 static void *usb_temp_get_qualifier_desc(struct usb_device
*);
98 static void *usb_temp_get_config_desc(struct usb_device
*, uint16_t *,
100 static const void *usb_temp_get_string_desc(struct usb_device
*, uint16_t,
102 static const void *usb_temp_get_vendor_desc(struct usb_device
*,
103 const struct usb_device_request
*, uint16_t *plen
);
104 static const void *usb_temp_get_hub_desc(struct usb_device
*);
105 static usb_error_t
usb_temp_get_desc(struct usb_device
*,
106 struct usb_device_request
*, const void **, uint16_t *);
107 static usb_error_t
usb_temp_setup_by_index(struct usb_device
*,
109 static void usb_temp_init(void *);
111 /*------------------------------------------------------------------------*
114 * This function will insert a raw USB descriptor into the generated
116 *------------------------------------------------------------------------*/
118 usb_make_raw_desc(struct usb_temp_setup
*temp
,
125 * The first byte of any USB descriptor gives the length.
130 dst
= USB_ADD_BYTES(temp
->buf
, temp
->size
);
131 memcpy(dst
, raw
, len
);
133 /* check if we have got a CDC union descriptor */
135 if ((raw
[0] >= sizeof(struct usb_cdc_union_descriptor
)) &&
136 (raw
[1] == UDESC_CS_INTERFACE
) &&
137 (raw
[2] == UDESCSUB_CDC_UNION
)) {
138 struct usb_cdc_union_descriptor
*ud
= (void *)dst
;
140 /* update the interface numbers */
142 ud
->bMasterInterface
+=
143 temp
->bInterfaceNumber
;
144 ud
->bSlaveInterface
[0] +=
145 temp
->bInterfaceNumber
;
148 /* check if we have got an interface association descriptor */
150 if ((raw
[0] >= sizeof(struct usb_interface_assoc_descriptor
)) &&
151 (raw
[1] == UDESC_IFACE_ASSOC
)) {
152 struct usb_interface_assoc_descriptor
*iad
= (void *)dst
;
154 /* update the interface number */
156 iad
->bFirstInterface
+=
157 temp
->bInterfaceNumber
;
160 /* check if we have got a call management descriptor */
162 if ((raw
[0] >= sizeof(struct usb_cdc_cm_descriptor
)) &&
163 (raw
[1] == UDESC_CS_INTERFACE
) &&
164 (raw
[2] == UDESCSUB_CDC_CM
)) {
165 struct usb_cdc_cm_descriptor
*ccd
= (void *)dst
;
167 /* update the interface number */
169 ccd
->bDataInterface
+=
170 temp
->bInterfaceNumber
;
177 /*------------------------------------------------------------------------*
178 * usb_make_endpoint_desc
180 * This function will generate an USB endpoint descriptor from the
181 * given USB template endpoint descriptor, which will be inserted into
182 * the USB configuration.
183 *------------------------------------------------------------------------*/
185 usb_make_endpoint_desc(struct usb_temp_setup
*temp
,
186 const struct usb_temp_endpoint_desc
*ted
)
188 struct usb_endpoint_descriptor
*ed
;
192 uint8_t ea
; /* Endpoint Address */
193 uint8_t et
; /* Endpiont Type */
196 old_size
= temp
->size
;
198 ea
= (ted
->bEndpointAddress
& (UE_ADDR
| UE_DIR_IN
| UE_DIR_OUT
));
199 et
= (ted
->bmAttributes
& UE_XFERTYPE
);
201 if (et
== UE_ISOCHRONOUS
) {
202 /* account for extra byte fields */
203 temp
->size
+= sizeof(*ed
) + 2;
205 temp
->size
+= sizeof(*ed
);
208 /* Scan all Raw Descriptors first */
212 usb_make_raw_desc(temp
, *rd
);
216 if (ted
->pPacketSize
== NULL
) {
217 /* not initialized */
218 temp
->err
= USB_ERR_INVAL
;
221 mps
= ted
->pPacketSize
->mps
[temp
->usb_speed
];
223 /* not initialized */
224 temp
->err
= USB_ERR_INVAL
;
226 } else if (mps
== UE_ZERO_MPS
) {
227 /* escape for Zero Max Packet Size */
232 * Fill out the real USB endpoint descriptor
233 * in case there is a buffer present:
236 ed
= USB_ADD_BYTES(temp
->buf
, old_size
);
237 if (et
== UE_ISOCHRONOUS
)
238 ed
->bLength
= sizeof(*ed
) + 2;
240 ed
->bLength
= sizeof(*ed
);
241 ed
->bDescriptorType
= UDESC_ENDPOINT
;
242 ed
->bEndpointAddress
= ea
;
243 ed
->bmAttributes
= ted
->bmAttributes
;
244 USETW(ed
->wMaxPacketSize
, mps
);
246 /* setup bInterval parameter */
248 if (ted
->pIntervals
&&
249 ted
->pIntervals
->bInterval
[temp
->usb_speed
]) {
251 ted
->pIntervals
->bInterval
[temp
->usb_speed
];
256 ed
->bInterval
= 0; /* not used */
259 switch (temp
->usb_speed
) {
262 ed
->bInterval
= 1; /* 1 ms */
265 ed
->bInterval
= 4; /* 1 ms */
269 default: /* UE_ISOCHRONOUS */
270 switch (temp
->usb_speed
) {
273 ed
->bInterval
= 1; /* 1 ms */
276 ed
->bInterval
= 1; /* 125 us */
283 temp
->bNumEndpoints
++;
286 /*------------------------------------------------------------------------*
287 * usb_make_interface_desc
289 * This function will generate an USB interface descriptor from the
290 * given USB template interface descriptor, which will be inserted
291 * into the USB configuration.
292 *------------------------------------------------------------------------*/
294 usb_make_interface_desc(struct usb_temp_setup
*temp
,
295 const struct usb_temp_interface_desc
*tid
)
297 struct usb_interface_descriptor
*id
;
298 const struct usb_temp_endpoint_desc
**ted
;
304 old_size
= temp
->size
;
305 temp
->size
+= sizeof(*id
);
307 /* Update interface and alternate interface numbers */
309 if (tid
->isAltInterface
== 0) {
310 temp
->bAlternateSetting
= 0;
311 temp
->bInterfaceNumber
++;
313 temp
->bAlternateSetting
++;
316 /* Scan all Raw Descriptors first */
322 usb_make_raw_desc(temp
, *rd
);
326 /* Reset some counters */
328 temp
->bNumEndpoints
= 0;
330 /* Scan all Endpoint Descriptors second */
332 ted
= tid
->ppEndpoints
;
335 usb_make_endpoint_desc(temp
, *ted
);
340 * Fill out the real USB interface descriptor
341 * in case there is a buffer present:
344 id
= USB_ADD_BYTES(temp
->buf
, old_size
);
345 id
->bLength
= sizeof(*id
);
346 id
->bDescriptorType
= UDESC_INTERFACE
;
347 id
->bInterfaceNumber
= temp
->bInterfaceNumber
;
348 id
->bAlternateSetting
= temp
->bAlternateSetting
;
349 id
->bNumEndpoints
= temp
->bNumEndpoints
;
350 id
->bInterfaceClass
= tid
->bInterfaceClass
;
351 id
->bInterfaceSubClass
= tid
->bInterfaceSubClass
;
352 id
->bInterfaceProtocol
= tid
->bInterfaceProtocol
;
353 id
->iInterface
= tid
->iInterface
;
357 /*------------------------------------------------------------------------*
358 * usb_make_config_desc
360 * This function will generate an USB config descriptor from the given
361 * USB template config descriptor, which will be inserted into the USB
363 *------------------------------------------------------------------------*/
365 usb_make_config_desc(struct usb_temp_setup
*temp
,
366 const struct usb_temp_config_desc
*tcd
)
368 struct usb_config_descriptor
*cd
;
369 const struct usb_temp_interface_desc
**tid
;
374 old_size
= temp
->size
;
375 temp
->size
+= sizeof(*cd
);
377 /* Reset some counters */
379 temp
->bInterfaceNumber
= 0xFF;
380 temp
->bAlternateSetting
= 0;
382 /* Scan all the USB interfaces */
384 tid
= tcd
->ppIfaceDesc
;
387 usb_make_interface_desc(temp
, *tid
);
392 * Fill out the real USB config descriptor
393 * in case there is a buffer present:
396 cd
= USB_ADD_BYTES(temp
->buf
, old_size
);
398 /* compute total size */
399 old_size
= temp
->size
- old_size
;
401 cd
->bLength
= sizeof(*cd
);
402 cd
->bDescriptorType
= UDESC_CONFIG
;
403 USETW(cd
->wTotalLength
, old_size
);
404 cd
->bNumInterface
= temp
->bInterfaceNumber
+ 1;
405 cd
->bConfigurationValue
= temp
->bConfigurationValue
;
406 cd
->iConfiguration
= tcd
->iConfiguration
;
407 cd
->bmAttributes
= tcd
->bmAttributes
;
408 cd
->bMaxPower
= tcd
->bMaxPower
;
409 cd
->bmAttributes
|= (UC_REMOTE_WAKEUP
| UC_BUS_POWERED
);
411 if (temp
->self_powered
) {
412 cd
->bmAttributes
|= UC_SELF_POWERED
;
414 cd
->bmAttributes
&= ~UC_SELF_POWERED
;
419 /*------------------------------------------------------------------------*
420 * usb_make_device_desc
422 * This function will generate an USB device descriptor from the
423 * given USB template device descriptor.
424 *------------------------------------------------------------------------*/
426 usb_make_device_desc(struct usb_temp_setup
*temp
,
427 const struct usb_temp_device_desc
*tdd
)
429 struct usb_temp_data
*utd
;
430 const struct usb_temp_config_desc
**tcd
;
435 old_size
= temp
->size
;
436 temp
->size
+= sizeof(*utd
);
438 /* Scan all the USB configs */
440 temp
->bConfigurationValue
= 1;
441 tcd
= tdd
->ppConfigDesc
;
444 usb_make_config_desc(temp
, *tcd
);
445 temp
->bConfigurationValue
++;
450 * Fill out the real USB device descriptor
451 * in case there is a buffer present:
455 utd
= USB_ADD_BYTES(temp
->buf
, old_size
);
457 /* Store a pointer to our template device descriptor */
460 /* Fill out USB device descriptor */
461 utd
->udd
.bLength
= sizeof(utd
->udd
);
462 utd
->udd
.bDescriptorType
= UDESC_DEVICE
;
463 utd
->udd
.bDeviceClass
= tdd
->bDeviceClass
;
464 utd
->udd
.bDeviceSubClass
= tdd
->bDeviceSubClass
;
465 utd
->udd
.bDeviceProtocol
= tdd
->bDeviceProtocol
;
466 USETW(utd
->udd
.idVendor
, tdd
->idVendor
);
467 USETW(utd
->udd
.idProduct
, tdd
->idProduct
);
468 USETW(utd
->udd
.bcdDevice
, tdd
->bcdDevice
);
469 utd
->udd
.iManufacturer
= tdd
->iManufacturer
;
470 utd
->udd
.iProduct
= tdd
->iProduct
;
471 utd
->udd
.iSerialNumber
= tdd
->iSerialNumber
;
472 utd
->udd
.bNumConfigurations
= temp
->bConfigurationValue
- 1;
475 * Fill out the USB device qualifier. Pretend that we
476 * don't support any other speeds by setting
477 * "bNumConfigurations" equal to zero. That saves us
478 * generating an extra set of configuration
481 utd
->udq
.bLength
= sizeof(utd
->udq
);
482 utd
->udq
.bDescriptorType
= UDESC_DEVICE_QUALIFIER
;
483 utd
->udq
.bDeviceClass
= tdd
->bDeviceClass
;
484 utd
->udq
.bDeviceSubClass
= tdd
->bDeviceSubClass
;
485 utd
->udq
.bDeviceProtocol
= tdd
->bDeviceProtocol
;
486 utd
->udq
.bNumConfigurations
= 0;
487 USETW(utd
->udq
.bcdUSB
, 0x0200);
488 utd
->udq
.bMaxPacketSize0
= 0;
490 switch (temp
->usb_speed
) {
492 USETW(utd
->udd
.bcdUSB
, 0x0110);
493 utd
->udd
.bMaxPacketSize
= 8;
496 USETW(utd
->udd
.bcdUSB
, 0x0110);
497 utd
->udd
.bMaxPacketSize
= 32;
500 USETW(utd
->udd
.bcdUSB
, 0x0200);
501 utd
->udd
.bMaxPacketSize
= 64;
503 case USB_SPEED_VARIABLE
:
504 USETW(utd
->udd
.bcdUSB
, 0x0250);
505 utd
->udd
.bMaxPacketSize
= 255; /* 512 bytes */
507 case USB_SPEED_SUPER
:
508 USETW(utd
->udd
.bcdUSB
, 0x0300);
509 utd
->udd
.bMaxPacketSize
= 9; /* 2**9 = 512 bytes */
512 temp
->err
= USB_ERR_INVAL
;
518 /*------------------------------------------------------------------------*
522 * 0: The endpoint profile does not match the criterias
523 * Else: The endpoint profile matches the criterias
524 *------------------------------------------------------------------------*/
526 usb_hw_ep_match(const struct usb_hw_ep_profile
*pf
,
527 uint8_t ep_type
, uint8_t ep_dir_in
)
529 if (ep_type
== UE_CONTROL
) {
531 return (pf
->support_control
);
533 if ((pf
->support_in
&& ep_dir_in
) ||
534 (pf
->support_out
&& !ep_dir_in
)) {
535 if ((pf
->support_interrupt
&& (ep_type
== UE_INTERRUPT
)) ||
536 (pf
->support_isochronous
&& (ep_type
== UE_ISOCHRONOUS
)) ||
537 (pf
->support_bulk
&& (ep_type
== UE_BULK
))) {
544 /*------------------------------------------------------------------------*
545 * usb_hw_ep_find_match
547 * This function is used to find the best matching endpoint profile
548 * for and endpoint belonging to an USB descriptor.
551 * 0: Success. Got a match.
552 * Else: Failure. No match.
553 *------------------------------------------------------------------------*/
555 usb_hw_ep_find_match(struct usb_hw_ep_scratch
*ues
,
556 struct usb_hw_ep_scratch_sub
*ep
, uint8_t is_simplex
)
558 const struct usb_hw_ep_profile
*pf
;
561 uint16_t max_frame_size
;
570 if ((!ep
->needs_in
) && (!ep
->needs_out
)) {
571 return (0); /* we are done */
573 if (ep
->needs_ep_type
== UE_CONTROL
) {
586 for (n
= 1; n
!= (USB_EP_MAX
/ 2); n
++) {
588 /* get HW endpoint profile */
589 (ues
->methods
->get_hw_ep_profile
) (ues
->udev
, &pf
, n
);
591 /* end of profiles */
594 /* check if IN-endpoint is reserved */
595 if (dir_in
|| pf
->is_simplex
) {
596 if (ues
->bmInAlloc
[n
/ 8] & (1 << (n
% 8))) {
601 /* check if OUT-endpoint is reserved */
602 if (dir_out
|| pf
->is_simplex
) {
603 if (ues
->bmOutAlloc
[n
/ 8] & (1 << (n
% 8))) {
609 if (pf
->is_simplex
== is_simplex
) {
613 /* check if HW endpoint matches */
614 if (!usb_hw_ep_match(pf
, ep
->needs_ep_type
, dir_in
)) {
618 /* get maximum frame size */
620 max_frame_size
= pf
->max_in_frame_size
;
622 max_frame_size
= pf
->max_out_frame_size
;
624 /* check if we have a matching profile */
625 if (max_frame_size
>= ep
->max_frame_size
) {
626 temp
= (max_frame_size
- ep
->max_frame_size
);
627 if (distance
> temp
) {
635 /* see if we got a match */
637 /* get the correct profile */
640 /* reserve IN-endpoint */
642 ues
->bmInAlloc
[best_n
/ 8] |=
644 ep
->hw_endpoint_in
= best_n
| UE_DIR_IN
;
647 /* reserve OUT-endpoint */
649 ues
->bmOutAlloc
[best_n
/ 8] |=
651 ep
->hw_endpoint_out
= best_n
| UE_DIR_OUT
;
654 return (0); /* got a match */
656 return (1); /* failure */
659 /*------------------------------------------------------------------------*
660 * usb_hw_ep_get_needs
662 * This function will figure out the type and number of endpoints
663 * which are needed for an USB configuration.
668 *------------------------------------------------------------------------*/
670 usb_hw_ep_get_needs(struct usb_hw_ep_scratch
*ues
,
671 uint8_t ep_type
, uint8_t is_complete
)
673 const struct usb_hw_ep_profile
*pf
;
674 struct usb_hw_ep_scratch_sub
*ep_iface
;
675 struct usb_hw_ep_scratch_sub
*ep_curr
;
676 struct usb_hw_ep_scratch_sub
*ep_max
;
677 struct usb_hw_ep_scratch_sub
*ep_end
;
678 struct usb_descriptor
*desc
;
679 struct usb_interface_descriptor
*id
;
680 struct usb_endpoint_descriptor
*ed
;
681 enum usb_dev_speed speed
;
682 uint16_t wMaxPacketSize
;
686 ep_iface
= ues
->ep_max
;
687 ep_curr
= ues
->ep_max
;
688 ep_end
= ues
->ep
+ USB_EP_MAX
;
689 ep_max
= ues
->ep_max
;
691 speed
= usbd_get_speed(ues
->udev
);
695 while ((desc
= usb_desc_foreach(ues
->cd
, desc
))) {
697 if ((desc
->bDescriptorType
== UDESC_INTERFACE
) &&
698 (desc
->bLength
>= sizeof(*id
))) {
702 if (id
->bAlternateSetting
== 0) {
710 if ((desc
->bDescriptorType
== UDESC_ENDPOINT
) &&
711 (desc
->bLength
>= sizeof(*ed
))) {
715 goto handle_endpoint_desc
;
718 ues
->ep_max
= ep_max
;
721 handle_endpoint_desc
:
722 temp
= (ed
->bmAttributes
& UE_XFERTYPE
);
724 if (temp
== ep_type
) {
726 if (ep_curr
== ep_end
) {
727 /* too many endpoints */
728 return (1); /* failure */
730 wMaxPacketSize
= UGETW(ed
->wMaxPacketSize
);
731 if ((wMaxPacketSize
& 0xF800) &&
732 (speed
== USB_SPEED_HIGH
)) {
733 /* handle packet multiplier */
734 temp
= (wMaxPacketSize
>> 11) & 3;
735 wMaxPacketSize
&= 0x7FF;
743 * Check if we have a fixed endpoint number, else the
744 * endpoint number is allocated dynamically:
746 ep_no
= (ed
->bEndpointAddress
& UE_ADDR
);
749 /* get HW endpoint profile */
750 (ues
->methods
->get_hw_ep_profile
)
751 (ues
->udev
, &pf
, ep_no
);
753 /* HW profile does not exist - failure */
754 DPRINTFN(0, "Endpoint profile %u "
755 "does not exist\n", ep_no
);
758 /* reserve fixed endpoint number */
759 if (ep_type
== UE_CONTROL
) {
760 ues
->bmInAlloc
[ep_no
/ 8] |=
762 ues
->bmOutAlloc
[ep_no
/ 8] |=
764 if ((pf
->max_in_frame_size
< wMaxPacketSize
) ||
765 (pf
->max_out_frame_size
< wMaxPacketSize
)) {
766 DPRINTFN(0, "Endpoint profile %u "
767 "has too small buffer\n", ep_no
);
770 } else if (ed
->bEndpointAddress
& UE_DIR_IN
) {
771 ues
->bmInAlloc
[ep_no
/ 8] |=
773 if (pf
->max_in_frame_size
< wMaxPacketSize
) {
774 DPRINTFN(0, "Endpoint profile %u "
775 "has too small buffer\n", ep_no
);
779 ues
->bmOutAlloc
[ep_no
/ 8] |=
781 if (pf
->max_out_frame_size
< wMaxPacketSize
) {
782 DPRINTFN(0, "Endpoint profile %u "
783 "has too small buffer\n", ep_no
);
787 } else if (is_complete
) {
789 /* check if we have enough buffer space */
791 ep_curr
->max_frame_size
) {
792 return (1); /* failure */
794 if (ed
->bEndpointAddress
& UE_DIR_IN
) {
795 ed
->bEndpointAddress
=
796 ep_curr
->hw_endpoint_in
;
798 ed
->bEndpointAddress
=
799 ep_curr
->hw_endpoint_out
;
804 /* compute the maximum frame size */
805 if (ep_curr
->max_frame_size
< wMaxPacketSize
) {
806 ep_curr
->max_frame_size
= wMaxPacketSize
;
808 if (temp
== UE_CONTROL
) {
809 ep_curr
->needs_in
= 1;
810 ep_curr
->needs_out
= 1;
812 if (ed
->bEndpointAddress
& UE_DIR_IN
) {
813 ep_curr
->needs_in
= 1;
815 ep_curr
->needs_out
= 1;
818 ep_curr
->needs_ep_type
= ep_type
;
822 if (ep_max
< ep_curr
) {
829 /*------------------------------------------------------------------------*
832 * This function will try to resolve endpoint requirements by the
833 * given endpoint profiles that the USB hardware reports.
838 *------------------------------------------------------------------------*/
840 usb_hw_ep_resolve(struct usb_device
*udev
,
841 struct usb_descriptor
*desc
)
843 struct usb_hw_ep_scratch
*ues
;
844 struct usb_hw_ep_scratch_sub
*ep
;
845 const struct usb_hw_ep_profile
*pf
;
846 const struct usb_bus_methods
*methods
;
847 struct usb_device_descriptor
*dd
;
851 return (USB_ERR_INVAL
);
853 /* get bus methods */
854 methods
= udev
->bus
->methods
;
856 if (methods
->get_hw_ep_profile
== NULL
)
857 return (USB_ERR_INVAL
);
859 if (desc
->bDescriptorType
== UDESC_DEVICE
) {
861 if (desc
->bLength
< sizeof(*dd
))
862 return (USB_ERR_INVAL
);
866 /* get HW control endpoint 0 profile */
867 (methods
->get_hw_ep_profile
) (udev
, &pf
, 0);
869 return (USB_ERR_INVAL
);
871 if (!usb_hw_ep_match(pf
, UE_CONTROL
, 0)) {
872 DPRINTFN(0, "Endpoint 0 does not "
873 "support control\n");
874 return (USB_ERR_INVAL
);
876 mps
= dd
->bMaxPacketSize
;
878 if (udev
->speed
== USB_SPEED_FULL
) {
880 * We can optionally choose another packet size !
883 /* check if "mps" is ok */
884 if (pf
->max_in_frame_size
>= mps
) {
887 /* reduce maximum packet size */
890 /* check if "mps" is too small */
892 return (USB_ERR_INVAL
);
896 dd
->bMaxPacketSize
= mps
;
899 /* We only have one choice */
903 /* Check if we support the specified wMaxPacketSize */
904 if (pf
->max_in_frame_size
< mps
) {
905 return (USB_ERR_INVAL
);
908 return (0); /* success */
910 if (desc
->bDescriptorType
!= UDESC_CONFIG
)
911 return (USB_ERR_INVAL
);
912 if (desc
->bLength
< sizeof(*(ues
->cd
)))
913 return (USB_ERR_INVAL
);
915 ues
= udev
->scratch
.hw_ep_scratch
;
917 memset(ues
, 0, sizeof(*ues
));
919 ues
->ep_max
= ues
->ep
;
920 ues
->cd
= (void *)desc
;
921 ues
->methods
= methods
;
924 /* Get all the endpoints we need */
926 if (usb_hw_ep_get_needs(ues
, UE_ISOCHRONOUS
, 0) ||
927 usb_hw_ep_get_needs(ues
, UE_INTERRUPT
, 0) ||
928 usb_hw_ep_get_needs(ues
, UE_CONTROL
, 0) ||
929 usb_hw_ep_get_needs(ues
, UE_BULK
, 0)) {
930 DPRINTFN(0, "Could not get needs\n");
931 return (USB_ERR_INVAL
);
933 for (ep
= ues
->ep
; ep
!= ues
->ep_max
; ep
++) {
935 while (ep
->needs_in
|| ep
->needs_out
) {
938 * First try to use a simplex endpoint.
939 * Then try to use a duplex endpoint.
941 if (usb_hw_ep_find_match(ues
, ep
, 1) &&
942 usb_hw_ep_find_match(ues
, ep
, 0)) {
943 DPRINTFN(0, "Could not find match\n");
944 return (USB_ERR_INVAL
);
949 ues
->ep_max
= ues
->ep
;
951 /* Update all endpoint addresses */
953 if (usb_hw_ep_get_needs(ues
, UE_ISOCHRONOUS
, 1) ||
954 usb_hw_ep_get_needs(ues
, UE_INTERRUPT
, 1) ||
955 usb_hw_ep_get_needs(ues
, UE_CONTROL
, 1) ||
956 usb_hw_ep_get_needs(ues
, UE_BULK
, 1)) {
957 DPRINTFN(0, "Could not update endpoint address\n");
958 return (USB_ERR_INVAL
);
960 return (0); /* success */
963 /*------------------------------------------------------------------------*
967 * NULL: No USB template device descriptor found.
968 * Else: Pointer to the USB template device descriptor.
969 *------------------------------------------------------------------------*/
970 static const struct usb_temp_device_desc
*
971 usb_temp_get_tdd(struct usb_device
*udev
)
973 if (udev
->usb_template_ptr
== NULL
) {
976 return (udev
->usb_template_ptr
->tdd
);
979 /*------------------------------------------------------------------------*
980 * usb_temp_get_device_desc
983 * NULL: No USB device descriptor found.
984 * Else: Pointer to USB device descriptor.
985 *------------------------------------------------------------------------*/
987 usb_temp_get_device_desc(struct usb_device
*udev
)
989 struct usb_device_descriptor
*dd
;
991 if (udev
->usb_template_ptr
== NULL
) {
994 dd
= &udev
->usb_template_ptr
->udd
;
995 if (dd
->bDescriptorType
!= UDESC_DEVICE
) {
996 /* sanity check failed */
1002 /*------------------------------------------------------------------------*
1003 * usb_temp_get_qualifier_desc
1006 * NULL: No USB device_qualifier descriptor found.
1007 * Else: Pointer to USB device_qualifier descriptor.
1008 *------------------------------------------------------------------------*/
1010 usb_temp_get_qualifier_desc(struct usb_device
*udev
)
1012 struct usb_device_qualifier
*dq
;
1014 if (udev
->usb_template_ptr
== NULL
) {
1017 dq
= &udev
->usb_template_ptr
->udq
;
1018 if (dq
->bDescriptorType
!= UDESC_DEVICE_QUALIFIER
) {
1019 /* sanity check failed */
1025 /*------------------------------------------------------------------------*
1026 * usb_temp_get_config_desc
1029 * NULL: No USB config descriptor found.
1030 * Else: Pointer to USB config descriptor having index "index".
1031 *------------------------------------------------------------------------*/
1033 usb_temp_get_config_desc(struct usb_device
*udev
,
1034 uint16_t *pLength
, uint8_t index
)
1036 struct usb_device_descriptor
*dd
;
1037 struct usb_config_descriptor
*cd
;
1040 if (udev
->usb_template_ptr
== NULL
) {
1043 dd
= &udev
->usb_template_ptr
->udd
;
1044 cd
= (void *)(udev
->usb_template_ptr
+ 1);
1046 if (index
>= dd
->bNumConfigurations
) {
1051 if (cd
->bDescriptorType
!= UDESC_CONFIG
) {
1052 /* sanity check failed */
1055 temp
= UGETW(cd
->wTotalLength
);
1056 cd
= USB_ADD_BYTES(cd
, temp
);
1060 *pLength
= UGETW(cd
->wTotalLength
);
1065 /*------------------------------------------------------------------------*
1066 * usb_temp_get_vendor_desc
1069 * NULL: No vendor descriptor found.
1070 * Else: Pointer to a vendor descriptor.
1071 *------------------------------------------------------------------------*/
1073 usb_temp_get_vendor_desc(struct usb_device
*udev
,
1074 const struct usb_device_request
*req
, uint16_t *plen
)
1076 const struct usb_temp_device_desc
*tdd
;
1078 tdd
= usb_temp_get_tdd(udev
);
1082 if (tdd
->getVendorDesc
== NULL
) {
1085 return ((tdd
->getVendorDesc
) (req
, plen
));
1088 /*------------------------------------------------------------------------*
1089 * usb_temp_get_string_desc
1092 * NULL: No string descriptor found.
1093 * Else: Pointer to a string descriptor.
1094 *------------------------------------------------------------------------*/
1096 usb_temp_get_string_desc(struct usb_device
*udev
,
1097 uint16_t lang_id
, uint8_t string_index
)
1099 const struct usb_temp_device_desc
*tdd
;
1101 tdd
= usb_temp_get_tdd(udev
);
1105 if (tdd
->getStringDesc
== NULL
) {
1108 return ((tdd
->getStringDesc
) (lang_id
, string_index
));
1111 /*------------------------------------------------------------------------*
1112 * usb_temp_get_hub_desc
1115 * NULL: No USB HUB descriptor found.
1116 * Else: Pointer to a USB HUB descriptor.
1117 *------------------------------------------------------------------------*/
1119 usb_temp_get_hub_desc(struct usb_device
*udev
)
1121 return (NULL
); /* needs to be implemented */
1124 /*------------------------------------------------------------------------*
1127 * This function is a demultiplexer for local USB device side control
1128 * endpoint requests.
1129 *------------------------------------------------------------------------*/
1131 usb_temp_get_desc(struct usb_device
*udev
, struct usb_device_request
*req
,
1132 const void **pPtr
, uint16_t *pLength
)
1140 switch (req
->bmRequestType
) {
1141 case UT_READ_DEVICE
:
1142 switch (req
->bRequest
) {
1143 case UR_GET_DESCRIPTOR
:
1144 goto tr_handle_get_descriptor
;
1148 case UT_READ_CLASS_DEVICE
:
1149 switch (req
->bRequest
) {
1150 case UR_GET_DESCRIPTOR
:
1151 goto tr_handle_get_class_descriptor
;
1159 tr_handle_get_descriptor
:
1160 switch (req
->wValue
[1]) {
1162 if (req
->wValue
[0]) {
1165 buf
= usb_temp_get_device_desc(udev
);
1167 case UDESC_DEVICE_QUALIFIER
:
1168 if (udev
->speed
!= USB_SPEED_HIGH
) {
1171 if (req
->wValue
[0]) {
1174 buf
= usb_temp_get_qualifier_desc(udev
);
1176 case UDESC_OTHER_SPEED_CONFIGURATION
:
1177 if (udev
->speed
!= USB_SPEED_HIGH
) {
1181 buf
= usb_temp_get_config_desc(udev
,
1182 &len
, req
->wValue
[0]);
1185 buf
= usb_temp_get_string_desc(udev
,
1186 UGETW(req
->wIndex
), req
->wValue
[0]);
1192 tr_handle_get_class_descriptor
:
1193 if (req
->wValue
[0]) {
1196 buf
= usb_temp_get_hub_desc(udev
);
1206 return (0); /* success */
1209 /* try to get a vendor specific descriptor */
1211 buf
= usb_temp_get_vendor_desc(udev
, req
, &len
);
1216 return (0); /* we ignore failures */
1219 /*------------------------------------------------------------------------*
1222 * This function generates USB descriptors according to the given USB
1223 * template device descriptor. It will also try to figure out the best
1224 * matching endpoint addresses using the hardware endpoint profiles.
1229 *------------------------------------------------------------------------*/
1231 usb_temp_setup(struct usb_device
*udev
,
1232 const struct usb_temp_device_desc
*tdd
)
1234 struct usb_temp_setup
*uts
;
1244 /* Protect scratch area */
1245 do_unlock
= usbd_enum_lock(udev
);
1247 uts
= udev
->scratch
.temp_setup
;
1249 memset(uts
, 0, sizeof(*uts
));
1251 uts
->usb_speed
= udev
->speed
;
1252 uts
->self_powered
= udev
->flags
.self_powered
;
1256 usb_make_device_desc(uts
, tdd
);
1259 /* some error happened */
1263 if (uts
->size
== 0) {
1264 uts
->err
= USB_ERR_INVAL
;
1267 /* allocate zeroed memory */
1268 uts
->buf
= usbd_alloc_config_desc(udev
, uts
->size
);
1270 * Allow malloc() to return NULL regardless of M_WAITOK flag.
1271 * This helps when porting the software to non-FreeBSD
1274 if (uts
->buf
== NULL
) {
1275 /* could not allocate memory */
1276 uts
->err
= USB_ERR_NOMEM
;
1283 usb_make_device_desc(uts
, tdd
);
1286 * Store a pointer to our descriptors:
1288 udev
->usb_template_ptr
= uts
->buf
;
1291 /* some error happened during second pass */
1295 * Resolve all endpoint addresses !
1297 buf
= usb_temp_get_device_desc(udev
);
1298 uts
->err
= usb_hw_ep_resolve(udev
, buf
);
1300 DPRINTFN(0, "Could not resolve endpoints for "
1301 "Device Descriptor, error = %s\n",
1302 usbd_errstr(uts
->err
));
1307 buf
= usb_temp_get_config_desc(udev
, NULL
, n
);
1311 uts
->err
= usb_hw_ep_resolve(udev
, buf
);
1313 DPRINTFN(0, "Could not resolve endpoints for "
1314 "Config Descriptor %u, error = %s\n", n
,
1315 usbd_errstr(uts
->err
));
1322 usb_temp_unsetup(udev
);
1324 usbd_enum_unlock(udev
);
1328 /*------------------------------------------------------------------------*
1331 * This function frees any memory associated with the currently
1332 * setup template, if any.
1333 *------------------------------------------------------------------------*/
1335 usb_temp_unsetup(struct usb_device
*udev
)
1337 usbd_free_config_desc(udev
, udev
->usb_template_ptr
);
1338 udev
->usb_template_ptr
= NULL
;
1342 usb_temp_setup_by_index(struct usb_device
*udev
, uint16_t index
)
1348 err
= usb_temp_setup(udev
, &usb_template_msc
);
1351 err
= usb_temp_setup(udev
, &usb_template_cdce
);
1354 err
= usb_temp_setup(udev
, &usb_template_mtp
);
1356 case USB_TEMP_MODEM
:
1357 err
= usb_temp_setup(udev
, &usb_template_modem
);
1359 case USB_TEMP_AUDIO
:
1360 err
= usb_temp_setup(udev
, &usb_template_audio
);
1363 err
= usb_temp_setup(udev
, &usb_template_kbd
);
1365 case USB_TEMP_MOUSE
:
1366 err
= usb_temp_setup(udev
, &usb_template_mouse
);
1368 case USB_TEMP_SERIALNET
:
1369 err
= usb_temp_setup(udev
, &usb_template_serialnet
);
1372 return (USB_ERR_INVAL
);
1379 usb_temp_init(void *arg
)
1381 /* register our functions */
1382 usb_temp_get_desc_p
= &usb_temp_get_desc
;
1383 usb_temp_setup_by_index_p
= &usb_temp_setup_by_index
;
1384 usb_temp_unsetup_p
= &usb_temp_unsetup
;
1387 SYSINIT(usb_temp_init
, SI_SUB_DRIVERS
, SI_ORDER_FIRST
, usb_temp_init
, NULL
);
1388 SYSUNINIT(usb_temp_unload
, SI_SUB_DRIVERS
, SI_ORDER_ANY
, usb_temp_unload
, NULL
);