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