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