usb_generic.c revision 222786
1/* $FreeBSD: head/sys/dev/usb/usb_generic.c 222786 2011-06-06 21:45:09Z hselasky $ */
2/*-
3 * Copyright (c) 2008 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#include <sys/stdint.h>
28#include <sys/stddef.h>
29#include <sys/param.h>
30#include <sys/queue.h>
31#include <sys/types.h>
32#include <sys/systm.h>
33#include <sys/kernel.h>
34#include <sys/bus.h>
35#include <sys/module.h>
36#include <sys/lock.h>
37#include <sys/mutex.h>
38#include <sys/condvar.h>
39#include <sys/sysctl.h>
40#include <sys/sx.h>
41#include <sys/unistd.h>
42#include <sys/callout.h>
43#include <sys/malloc.h>
44#include <sys/priv.h>
45#include <sys/conf.h>
46#include <sys/fcntl.h>
47
48#include <dev/usb/usb.h>
49#include <dev/usb/usb_ioctl.h>
50#include <dev/usb/usbdi.h>
51#include <dev/usb/usbdi_util.h>
52
53#define	USB_DEBUG_VAR ugen_debug
54
55#include <dev/usb/usb_core.h>
56#include <dev/usb/usb_dev.h>
57#include <dev/usb/usb_mbuf.h>
58#include <dev/usb/usb_process.h>
59#include <dev/usb/usb_device.h>
60#include <dev/usb/usb_debug.h>
61#include <dev/usb/usb_request.h>
62#include <dev/usb/usb_busdma.h>
63#include <dev/usb/usb_util.h>
64#include <dev/usb/usb_hub.h>
65#include <dev/usb/usb_generic.h>
66#include <dev/usb/usb_transfer.h>
67
68#include <dev/usb/usb_controller.h>
69#include <dev/usb/usb_bus.h>
70
71#if USB_HAVE_UGEN
72
73/* defines */
74
75#define	UGEN_BULK_FS_BUFFER_SIZE	(64*32)	/* bytes */
76#define	UGEN_BULK_HS_BUFFER_SIZE	(1024*32)	/* bytes */
77#define	UGEN_HW_FRAMES	50		/* number of milliseconds per transfer */
78
79/* function prototypes */
80
81static usb_callback_t ugen_read_clear_stall_callback;
82static usb_callback_t ugen_write_clear_stall_callback;
83static usb_callback_t ugen_ctrl_read_callback;
84static usb_callback_t ugen_ctrl_write_callback;
85static usb_callback_t ugen_isoc_read_callback;
86static usb_callback_t ugen_isoc_write_callback;
87static usb_callback_t ugen_ctrl_fs_callback;
88
89static usb_fifo_open_t ugen_open;
90static usb_fifo_close_t ugen_close;
91static usb_fifo_ioctl_t ugen_ioctl;
92static usb_fifo_ioctl_t ugen_ioctl_post;
93static usb_fifo_cmd_t ugen_start_read;
94static usb_fifo_cmd_t ugen_start_write;
95static usb_fifo_cmd_t ugen_stop_io;
96
97static int	ugen_transfer_setup(struct usb_fifo *,
98		     const struct usb_config *, uint8_t);
99static int	ugen_open_pipe_write(struct usb_fifo *);
100static int	ugen_open_pipe_read(struct usb_fifo *);
101static int	ugen_set_config(struct usb_fifo *, uint8_t);
102static int	ugen_set_interface(struct usb_fifo *, uint8_t, uint8_t);
103static int	ugen_get_cdesc(struct usb_fifo *, struct usb_gen_descriptor *);
104static int	ugen_get_sdesc(struct usb_fifo *, struct usb_gen_descriptor *);
105static int	ugen_get_iface_driver(struct usb_fifo *f, struct usb_gen_descriptor *ugd);
106static int	usb_gen_fill_deviceinfo(struct usb_fifo *,
107		    struct usb_device_info *);
108static int	ugen_re_enumerate(struct usb_fifo *);
109static int	ugen_iface_ioctl(struct usb_fifo *, u_long, void *, int);
110static uint8_t	ugen_fs_get_complete(struct usb_fifo *, uint8_t *);
111static int	ugen_fs_uninit(struct usb_fifo *f);
112
113/* structures */
114
115struct usb_fifo_methods usb_ugen_methods = {
116	.f_open = &ugen_open,
117	.f_close = &ugen_close,
118	.f_ioctl = &ugen_ioctl,
119	.f_ioctl_post = &ugen_ioctl_post,
120	.f_start_read = &ugen_start_read,
121	.f_stop_read = &ugen_stop_io,
122	.f_start_write = &ugen_start_write,
123	.f_stop_write = &ugen_stop_io,
124};
125
126#ifdef USB_DEBUG
127static int ugen_debug = 0;
128
129SYSCTL_NODE(_hw_usb, OID_AUTO, ugen, CTLFLAG_RW, 0, "USB generic");
130SYSCTL_INT(_hw_usb_ugen, OID_AUTO, debug, CTLFLAG_RW, &ugen_debug,
131    0, "Debug level");
132
133TUNABLE_INT("hw.usb.ugen.debug", &ugen_debug);
134#endif
135
136
137/* prototypes */
138
139static int
140ugen_transfer_setup(struct usb_fifo *f,
141    const struct usb_config *setup, uint8_t n_setup)
142{
143	struct usb_endpoint *ep = usb_fifo_softc(f);
144	struct usb_device *udev = f->udev;
145	uint8_t iface_index = ep->iface_index;
146	int error;
147
148	mtx_unlock(f->priv_mtx);
149
150	/*
151	 * "usbd_transfer_setup()" can sleep so one needs to make a wrapper,
152	 * exiting the mutex and checking things
153	 */
154	error = usbd_transfer_setup(udev, &iface_index, f->xfer,
155	    setup, n_setup, f, f->priv_mtx);
156	if (error == 0) {
157
158		if (f->xfer[0]->nframes == 1) {
159			error = usb_fifo_alloc_buffer(f,
160			    f->xfer[0]->max_data_length, 2);
161		} else {
162			error = usb_fifo_alloc_buffer(f,
163			    f->xfer[0]->max_frame_size,
164			    2 * f->xfer[0]->nframes);
165		}
166		if (error) {
167			usbd_transfer_unsetup(f->xfer, n_setup);
168		}
169	}
170	mtx_lock(f->priv_mtx);
171
172	return (error);
173}
174
175static int
176ugen_open(struct usb_fifo *f, int fflags)
177{
178	struct usb_endpoint *ep = usb_fifo_softc(f);
179	struct usb_endpoint_descriptor *ed = ep->edesc;
180	uint8_t type;
181
182	DPRINTFN(6, "flag=0x%x\n", fflags);
183
184	mtx_lock(f->priv_mtx);
185	switch (usbd_get_speed(f->udev)) {
186	case USB_SPEED_LOW:
187	case USB_SPEED_FULL:
188		f->nframes = UGEN_HW_FRAMES;
189		f->bufsize = UGEN_BULK_FS_BUFFER_SIZE;
190		break;
191	default:
192		f->nframes = UGEN_HW_FRAMES * 8;
193		f->bufsize = UGEN_BULK_HS_BUFFER_SIZE;
194		break;
195	}
196
197	type = ed->bmAttributes & UE_XFERTYPE;
198	if (type == UE_INTERRUPT) {
199		f->bufsize = 0;		/* use "wMaxPacketSize" */
200	}
201	f->timeout = USB_NO_TIMEOUT;
202	f->flag_short = 0;
203	f->fifo_zlp = 0;
204	mtx_unlock(f->priv_mtx);
205
206	return (0);
207}
208
209static void
210ugen_close(struct usb_fifo *f, int fflags)
211{
212	DPRINTFN(6, "flag=0x%x\n", fflags);
213
214	/* cleanup */
215
216	mtx_lock(f->priv_mtx);
217	usbd_transfer_stop(f->xfer[0]);
218	usbd_transfer_stop(f->xfer[1]);
219	mtx_unlock(f->priv_mtx);
220
221	usbd_transfer_unsetup(f->xfer, 2);
222	usb_fifo_free_buffer(f);
223
224	if (ugen_fs_uninit(f)) {
225		/* ignore any errors - we are closing */
226		DPRINTFN(6, "no FIFOs\n");
227	}
228}
229
230static int
231ugen_open_pipe_write(struct usb_fifo *f)
232{
233	struct usb_config usb_config[2];
234	struct usb_endpoint *ep = usb_fifo_softc(f);
235	struct usb_endpoint_descriptor *ed = ep->edesc;
236
237	mtx_assert(f->priv_mtx, MA_OWNED);
238
239	if (f->xfer[0] || f->xfer[1]) {
240		/* transfers are already opened */
241		return (0);
242	}
243	bzero(usb_config, sizeof(usb_config));
244
245	usb_config[1].type = UE_CONTROL;
246	usb_config[1].endpoint = 0;
247	usb_config[1].direction = UE_DIR_ANY;
248	usb_config[1].timeout = 1000;	/* 1 second */
249	usb_config[1].interval = 50;/* 50 milliseconds */
250	usb_config[1].bufsize = sizeof(struct usb_device_request);
251	usb_config[1].callback = &ugen_write_clear_stall_callback;
252	usb_config[1].usb_mode = USB_MODE_HOST;
253
254	usb_config[0].type = ed->bmAttributes & UE_XFERTYPE;
255	usb_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
256	usb_config[0].direction = UE_DIR_TX;
257	usb_config[0].interval = USB_DEFAULT_INTERVAL;
258	usb_config[0].flags.proxy_buffer = 1;
259	usb_config[0].usb_mode = USB_MODE_DUAL;	/* both modes */
260
261	switch (ed->bmAttributes & UE_XFERTYPE) {
262	case UE_INTERRUPT:
263	case UE_BULK:
264		if (f->flag_short) {
265			usb_config[0].flags.force_short_xfer = 1;
266		}
267		usb_config[0].callback = &ugen_ctrl_write_callback;
268		usb_config[0].timeout = f->timeout;
269		usb_config[0].frames = 1;
270		usb_config[0].bufsize = f->bufsize;
271		if (ugen_transfer_setup(f, usb_config, 2)) {
272			return (EIO);
273		}
274		/* first transfer does not clear stall */
275		f->flag_stall = 0;
276		break;
277
278	case UE_ISOCHRONOUS:
279		usb_config[0].flags.short_xfer_ok = 1;
280		usb_config[0].bufsize = 0;	/* use default */
281		usb_config[0].frames = f->nframes;
282		usb_config[0].callback = &ugen_isoc_write_callback;
283		usb_config[0].timeout = 0;
284
285		/* clone configuration */
286		usb_config[1] = usb_config[0];
287
288		if (ugen_transfer_setup(f, usb_config, 2)) {
289			return (EIO);
290		}
291		break;
292	default:
293		return (EINVAL);
294	}
295	return (0);
296}
297
298static int
299ugen_open_pipe_read(struct usb_fifo *f)
300{
301	struct usb_config usb_config[2];
302	struct usb_endpoint *ep = usb_fifo_softc(f);
303	struct usb_endpoint_descriptor *ed = ep->edesc;
304
305	mtx_assert(f->priv_mtx, MA_OWNED);
306
307	if (f->xfer[0] || f->xfer[1]) {
308		/* transfers are already opened */
309		return (0);
310	}
311	bzero(usb_config, sizeof(usb_config));
312
313	usb_config[1].type = UE_CONTROL;
314	usb_config[1].endpoint = 0;
315	usb_config[1].direction = UE_DIR_ANY;
316	usb_config[1].timeout = 1000;	/* 1 second */
317	usb_config[1].interval = 50;/* 50 milliseconds */
318	usb_config[1].bufsize = sizeof(struct usb_device_request);
319	usb_config[1].callback = &ugen_read_clear_stall_callback;
320	usb_config[1].usb_mode = USB_MODE_HOST;
321
322	usb_config[0].type = ed->bmAttributes & UE_XFERTYPE;
323	usb_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
324	usb_config[0].direction = UE_DIR_RX;
325	usb_config[0].interval = USB_DEFAULT_INTERVAL;
326	usb_config[0].flags.proxy_buffer = 1;
327	usb_config[0].usb_mode = USB_MODE_DUAL;	/* both modes */
328
329	switch (ed->bmAttributes & UE_XFERTYPE) {
330	case UE_INTERRUPT:
331	case UE_BULK:
332		if (f->flag_short) {
333			usb_config[0].flags.short_xfer_ok = 1;
334		}
335		usb_config[0].timeout = f->timeout;
336		usb_config[0].frames = 1;
337		usb_config[0].callback = &ugen_ctrl_read_callback;
338		usb_config[0].bufsize = f->bufsize;
339
340		if (ugen_transfer_setup(f, usb_config, 2)) {
341			return (EIO);
342		}
343		/* first transfer does not clear stall */
344		f->flag_stall = 0;
345		break;
346
347	case UE_ISOCHRONOUS:
348		usb_config[0].flags.short_xfer_ok = 1;
349		usb_config[0].bufsize = 0;	/* use default */
350		usb_config[0].frames = f->nframes;
351		usb_config[0].callback = &ugen_isoc_read_callback;
352		usb_config[0].timeout = 0;
353
354		/* clone configuration */
355		usb_config[1] = usb_config[0];
356
357		if (ugen_transfer_setup(f, usb_config, 2)) {
358			return (EIO);
359		}
360		break;
361
362	default:
363		return (EINVAL);
364	}
365	return (0);
366}
367
368static void
369ugen_start_read(struct usb_fifo *f)
370{
371	/* check that pipes are open */
372	if (ugen_open_pipe_read(f)) {
373		/* signal error */
374		usb_fifo_put_data_error(f);
375	}
376	/* start transfers */
377	usbd_transfer_start(f->xfer[0]);
378	usbd_transfer_start(f->xfer[1]);
379}
380
381static void
382ugen_start_write(struct usb_fifo *f)
383{
384	/* check that pipes are open */
385	if (ugen_open_pipe_write(f)) {
386		/* signal error */
387		usb_fifo_get_data_error(f);
388	}
389	/* start transfers */
390	usbd_transfer_start(f->xfer[0]);
391	usbd_transfer_start(f->xfer[1]);
392}
393
394static void
395ugen_stop_io(struct usb_fifo *f)
396{
397	/* stop transfers */
398	usbd_transfer_stop(f->xfer[0]);
399	usbd_transfer_stop(f->xfer[1]);
400}
401
402static void
403ugen_ctrl_read_callback(struct usb_xfer *xfer, usb_error_t error)
404{
405	struct usb_fifo *f = usbd_xfer_softc(xfer);
406	struct usb_mbuf *m;
407
408	DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer->actlen, xfer->aframes);
409
410	switch (USB_GET_STATE(xfer)) {
411	case USB_ST_TRANSFERRED:
412		if (xfer->actlen == 0) {
413			if (f->fifo_zlp != 4) {
414				f->fifo_zlp++;
415			} else {
416				/*
417				 * Throttle a little bit we have multiple ZLPs
418				 * in a row!
419				 */
420				xfer->interval = 64;	/* ms */
421			}
422		} else {
423			/* clear throttle */
424			xfer->interval = 0;
425			f->fifo_zlp = 0;
426		}
427		usb_fifo_put_data(f, xfer->frbuffers, 0,
428		    xfer->actlen, 1);
429
430	case USB_ST_SETUP:
431		if (f->flag_stall) {
432			usbd_transfer_start(f->xfer[1]);
433			break;
434		}
435		USB_IF_POLL(&f->free_q, m);
436		if (m) {
437			usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
438			usbd_transfer_submit(xfer);
439		}
440		break;
441
442	default:			/* Error */
443		if (xfer->error != USB_ERR_CANCELLED) {
444			/* send a zero length packet to userland */
445			usb_fifo_put_data(f, xfer->frbuffers, 0, 0, 1);
446			f->flag_stall = 1;
447			f->fifo_zlp = 0;
448			usbd_transfer_start(f->xfer[1]);
449		}
450		break;
451	}
452}
453
454static void
455ugen_ctrl_write_callback(struct usb_xfer *xfer, usb_error_t error)
456{
457	struct usb_fifo *f = usbd_xfer_softc(xfer);
458	usb_frlength_t actlen;
459
460	DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer->actlen, xfer->aframes);
461
462	switch (USB_GET_STATE(xfer)) {
463	case USB_ST_SETUP:
464	case USB_ST_TRANSFERRED:
465		/*
466		 * If writing is in stall, just jump to clear stall
467		 * callback and solve the situation.
468		 */
469		if (f->flag_stall) {
470			usbd_transfer_start(f->xfer[1]);
471			break;
472		}
473		/*
474		 * Write data, setup and perform hardware transfer.
475		 */
476		if (usb_fifo_get_data(f, xfer->frbuffers, 0,
477		    xfer->max_data_length, &actlen, 0)) {
478			usbd_xfer_set_frame_len(xfer, 0, actlen);
479			usbd_transfer_submit(xfer);
480		}
481		break;
482
483	default:			/* Error */
484		if (xfer->error != USB_ERR_CANCELLED) {
485			f->flag_stall = 1;
486			usbd_transfer_start(f->xfer[1]);
487		}
488		break;
489	}
490}
491
492static void
493ugen_read_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error)
494{
495	struct usb_fifo *f = usbd_xfer_softc(xfer);
496	struct usb_xfer *xfer_other = f->xfer[0];
497
498	if (f->flag_stall == 0) {
499		/* nothing to do */
500		return;
501	}
502	if (usbd_clear_stall_callback(xfer, xfer_other)) {
503		DPRINTFN(5, "f=%p: stall cleared\n", f);
504		f->flag_stall = 0;
505		usbd_transfer_start(xfer_other);
506	}
507}
508
509static void
510ugen_write_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error)
511{
512	struct usb_fifo *f = usbd_xfer_softc(xfer);
513	struct usb_xfer *xfer_other = f->xfer[0];
514
515	if (f->flag_stall == 0) {
516		/* nothing to do */
517		return;
518	}
519	if (usbd_clear_stall_callback(xfer, xfer_other)) {
520		DPRINTFN(5, "f=%p: stall cleared\n", f);
521		f->flag_stall = 0;
522		usbd_transfer_start(xfer_other);
523	}
524}
525
526static void
527ugen_isoc_read_callback(struct usb_xfer *xfer, usb_error_t error)
528{
529	struct usb_fifo *f = usbd_xfer_softc(xfer);
530	usb_frlength_t offset;
531	usb_frcount_t n;
532
533	DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer->actlen, xfer->aframes);
534
535	switch (USB_GET_STATE(xfer)) {
536	case USB_ST_TRANSFERRED:
537
538		DPRINTFN(6, "actlen=%d\n", xfer->actlen);
539
540		offset = 0;
541
542		for (n = 0; n != xfer->aframes; n++) {
543			usb_fifo_put_data(f, xfer->frbuffers, offset,
544			    xfer->frlengths[n], 1);
545			offset += xfer->max_frame_size;
546		}
547
548	case USB_ST_SETUP:
549tr_setup:
550		for (n = 0; n != xfer->nframes; n++) {
551			/* setup size for next transfer */
552			usbd_xfer_set_frame_len(xfer, n, xfer->max_frame_size);
553		}
554		usbd_transfer_submit(xfer);
555		break;
556
557	default:			/* Error */
558		if (xfer->error == USB_ERR_CANCELLED) {
559			break;
560		}
561		goto tr_setup;
562	}
563}
564
565static void
566ugen_isoc_write_callback(struct usb_xfer *xfer, usb_error_t error)
567{
568	struct usb_fifo *f = usbd_xfer_softc(xfer);
569	usb_frlength_t actlen;
570	usb_frlength_t offset;
571	usb_frcount_t n;
572
573	DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer->actlen, xfer->aframes);
574
575	switch (USB_GET_STATE(xfer)) {
576	case USB_ST_TRANSFERRED:
577	case USB_ST_SETUP:
578tr_setup:
579		offset = 0;
580		for (n = 0; n != xfer->nframes; n++) {
581			if (usb_fifo_get_data(f, xfer->frbuffers, offset,
582			    xfer->max_frame_size, &actlen, 1)) {
583				usbd_xfer_set_frame_len(xfer, n, actlen);
584				offset += actlen;
585			} else {
586				break;
587			}
588		}
589
590		for (; n != xfer->nframes; n++) {
591			/* fill in zero frames */
592			usbd_xfer_set_frame_len(xfer, n, 0);
593		}
594		usbd_transfer_submit(xfer);
595		break;
596
597	default:			/* Error */
598		if (xfer->error == USB_ERR_CANCELLED) {
599			break;
600		}
601		goto tr_setup;
602	}
603}
604
605static int
606ugen_set_config(struct usb_fifo *f, uint8_t index)
607{
608	DPRINTFN(2, "index %u\n", index);
609
610	if (f->udev->flags.usb_mode != USB_MODE_HOST) {
611		/* not possible in device side mode */
612		return (ENOTTY);
613	}
614	if (f->udev->curr_config_index == index) {
615		/* no change needed */
616		return (0);
617	}
618	/* make sure all FIFO's are gone */
619	/* else there can be a deadlock */
620	if (ugen_fs_uninit(f)) {
621		/* ignore any errors */
622		DPRINTFN(6, "no FIFOs\n");
623	}
624	/* change setting - will free generic FIFOs, if any */
625	if (usbd_set_config_index(f->udev, index)) {
626		return (EIO);
627	}
628	/* probe and attach */
629	if (usb_probe_and_attach(f->udev, USB_IFACE_INDEX_ANY)) {
630		return (EIO);
631	}
632	return (0);
633}
634
635static int
636ugen_set_interface(struct usb_fifo *f,
637    uint8_t iface_index, uint8_t alt_index)
638{
639	DPRINTFN(2, "%u, %u\n", iface_index, alt_index);
640
641	if (f->udev->flags.usb_mode != USB_MODE_HOST) {
642		/* not possible in device side mode */
643		return (ENOTTY);
644	}
645	/* make sure all FIFO's are gone */
646	/* else there can be a deadlock */
647	if (ugen_fs_uninit(f)) {
648		/* ignore any errors */
649		DPRINTFN(6, "no FIFOs\n");
650	}
651	/* change setting - will free generic FIFOs, if any */
652	if (usbd_set_alt_interface_index(f->udev, iface_index, alt_index)) {
653		return (EIO);
654	}
655	/* probe and attach */
656	if (usb_probe_and_attach(f->udev, iface_index)) {
657		return (EIO);
658	}
659	return (0);
660}
661
662/*------------------------------------------------------------------------*
663 *	ugen_get_cdesc
664 *
665 * This function will retrieve the complete configuration descriptor
666 * at the given index.
667 *------------------------------------------------------------------------*/
668static int
669ugen_get_cdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
670{
671	struct usb_config_descriptor *cdesc;
672	struct usb_device *udev = f->udev;
673	int error;
674	uint16_t len;
675	uint8_t free_data;
676
677	DPRINTFN(6, "\n");
678
679	if (ugd->ugd_data == NULL) {
680		/* userland pointer should not be zero */
681		return (EINVAL);
682	}
683	if ((ugd->ugd_config_index == USB_UNCONFIG_INDEX) ||
684	    (ugd->ugd_config_index == udev->curr_config_index)) {
685		cdesc = usbd_get_config_descriptor(udev);
686		if (cdesc == NULL) {
687			return (ENXIO);
688		}
689		free_data = 0;
690
691	} else {
692		if (usbd_req_get_config_desc_full(udev,
693		    NULL, &cdesc, M_USBDEV,
694		    ugd->ugd_config_index)) {
695			return (ENXIO);
696		}
697		free_data = 1;
698	}
699
700	len = UGETW(cdesc->wTotalLength);
701	if (len > ugd->ugd_maxlen) {
702		len = ugd->ugd_maxlen;
703	}
704	DPRINTFN(6, "len=%u\n", len);
705
706	ugd->ugd_actlen = len;
707	ugd->ugd_offset = 0;
708
709	error = copyout(cdesc, ugd->ugd_data, len);
710
711	if (free_data) {
712		free(cdesc, M_USBDEV);
713	}
714	return (error);
715}
716
717static int
718ugen_get_sdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
719{
720	void *ptr = f->udev->bus->scratch[0].data;
721	uint16_t size = sizeof(f->udev->bus->scratch[0].data);
722	int error;
723
724	if (usbd_req_get_string_desc(f->udev, NULL, ptr,
725	    size, ugd->ugd_lang_id, ugd->ugd_string_index)) {
726		error = EINVAL;
727	} else {
728
729		if (size > ((uint8_t *)ptr)[0]) {
730			size = ((uint8_t *)ptr)[0];
731		}
732		if (size > ugd->ugd_maxlen) {
733			size = ugd->ugd_maxlen;
734		}
735		ugd->ugd_actlen = size;
736		ugd->ugd_offset = 0;
737
738		error = copyout(ptr, ugd->ugd_data, size);
739	}
740	return (error);
741}
742
743/*------------------------------------------------------------------------*
744 *	ugen_get_iface_driver
745 *
746 * This function generates an USB interface description for userland.
747 *
748 * Returns:
749 *    0: Success
750 * Else: Failure
751 *------------------------------------------------------------------------*/
752static int
753ugen_get_iface_driver(struct usb_fifo *f, struct usb_gen_descriptor *ugd)
754{
755	struct usb_device *udev = f->udev;
756	struct usb_interface *iface;
757	const char *ptr;
758	const char *desc;
759	unsigned int len;
760	unsigned int maxlen;
761	char buf[128];
762	int error;
763
764	DPRINTFN(6, "\n");
765
766	if ((ugd->ugd_data == NULL) || (ugd->ugd_maxlen == 0)) {
767		/* userland pointer should not be zero */
768		return (EINVAL);
769	}
770
771	iface = usbd_get_iface(udev, ugd->ugd_iface_index);
772	if ((iface == NULL) || (iface->idesc == NULL)) {
773		/* invalid interface index */
774		return (EINVAL);
775	}
776
777	/* read out device nameunit string, if any */
778	if ((iface->subdev != NULL) &&
779	    device_is_attached(iface->subdev) &&
780	    (ptr = device_get_nameunit(iface->subdev)) &&
781	    (desc = device_get_desc(iface->subdev))) {
782
783		/* print description */
784		snprintf(buf, sizeof(buf), "%s: <%s>", ptr, desc);
785
786		/* range checks */
787		maxlen = ugd->ugd_maxlen - 1;
788		len = strlen(buf);
789		if (len > maxlen)
790			len = maxlen;
791
792		/* update actual length, including terminating zero */
793		ugd->ugd_actlen = len + 1;
794
795		/* copy out interface description */
796		error = copyout(buf, ugd->ugd_data, ugd->ugd_actlen);
797	} else {
798		/* zero length string is default */
799		error = copyout("", ugd->ugd_data, 1);
800	}
801	return (error);
802}
803
804/*------------------------------------------------------------------------*
805 *	usb_gen_fill_deviceinfo
806 *
807 * This function dumps information about an USB device to the
808 * structure pointed to by the "di" argument.
809 *
810 * Returns:
811 *    0: Success
812 * Else: Failure
813 *------------------------------------------------------------------------*/
814static int
815usb_gen_fill_deviceinfo(struct usb_fifo *f, struct usb_device_info *di)
816{
817	struct usb_device *udev;
818	struct usb_device *hub;
819
820	udev = f->udev;
821
822	bzero(di, sizeof(di[0]));
823
824	di->udi_bus = device_get_unit(udev->bus->bdev);
825	di->udi_addr = udev->address;
826	di->udi_index = udev->device_index;
827	strlcpy(di->udi_serial, usb_get_serial(udev), sizeof(di->udi_serial));
828	strlcpy(di->udi_vendor, usb_get_manufacturer(udev), sizeof(di->udi_vendor));
829	strlcpy(di->udi_product, usb_get_product(udev), sizeof(di->udi_product));
830	usb_printbcd(di->udi_release, sizeof(di->udi_release),
831	    UGETW(udev->ddesc.bcdDevice));
832	di->udi_vendorNo = UGETW(udev->ddesc.idVendor);
833	di->udi_productNo = UGETW(udev->ddesc.idProduct);
834	di->udi_releaseNo = UGETW(udev->ddesc.bcdDevice);
835	di->udi_class = udev->ddesc.bDeviceClass;
836	di->udi_subclass = udev->ddesc.bDeviceSubClass;
837	di->udi_protocol = udev->ddesc.bDeviceProtocol;
838	di->udi_config_no = udev->curr_config_no;
839	di->udi_config_index = udev->curr_config_index;
840	di->udi_power = udev->flags.self_powered ? 0 : udev->power;
841	di->udi_speed = udev->speed;
842	di->udi_mode = udev->flags.usb_mode;
843	di->udi_power_mode = udev->power_mode;
844	di->udi_suspended = udev->flags.peer_suspended;
845
846	hub = udev->parent_hub;
847	if (hub) {
848		di->udi_hubaddr = hub->address;
849		di->udi_hubindex = hub->device_index;
850		di->udi_hubport = udev->port_no;
851	}
852	return (0);
853}
854
855/*------------------------------------------------------------------------*
856 *	ugen_check_request
857 *
858 * Return values:
859 * 0: Access allowed
860 * Else: No access
861 *------------------------------------------------------------------------*/
862static int
863ugen_check_request(struct usb_device *udev, struct usb_device_request *req)
864{
865	struct usb_endpoint *ep;
866	int error;
867
868	/*
869	 * Avoid requests that would damage the bus integrity:
870	 */
871	if (((req->bmRequestType == UT_WRITE_DEVICE) &&
872	    (req->bRequest == UR_SET_ADDRESS)) ||
873	    ((req->bmRequestType == UT_WRITE_DEVICE) &&
874	    (req->bRequest == UR_SET_CONFIG)) ||
875	    ((req->bmRequestType == UT_WRITE_INTERFACE) &&
876	    (req->bRequest == UR_SET_INTERFACE))) {
877		/*
878		 * These requests can be useful for testing USB drivers.
879		 */
880		error = priv_check(curthread, PRIV_DRIVER);
881		if (error) {
882			return (error);
883		}
884	}
885	/*
886	 * Special case - handle clearing of stall
887	 */
888	if (req->bmRequestType == UT_WRITE_ENDPOINT) {
889
890		ep = usbd_get_ep_by_addr(udev, req->wIndex[0]);
891		if (ep == NULL) {
892			return (EINVAL);
893		}
894		if ((req->bRequest == UR_CLEAR_FEATURE) &&
895		    (UGETW(req->wValue) == UF_ENDPOINT_HALT)) {
896			usbd_clear_data_toggle(udev, ep);
897		}
898	}
899	/* TODO: add more checks to verify the interface index */
900
901	return (0);
902}
903
904int
905ugen_do_request(struct usb_fifo *f, struct usb_ctl_request *ur)
906{
907	int error;
908	uint16_t len;
909	uint16_t actlen;
910
911	if (ugen_check_request(f->udev, &ur->ucr_request)) {
912		return (EPERM);
913	}
914	len = UGETW(ur->ucr_request.wLength);
915
916	/* check if "ucr_data" is valid */
917	if (len != 0) {
918		if (ur->ucr_data == NULL) {
919			return (EFAULT);
920		}
921	}
922	/* do the USB request */
923	error = usbd_do_request_flags
924	    (f->udev, NULL, &ur->ucr_request, ur->ucr_data,
925	    (ur->ucr_flags & USB_SHORT_XFER_OK) |
926	    USB_USER_DATA_PTR, &actlen,
927	    USB_DEFAULT_TIMEOUT);
928
929	ur->ucr_actlen = actlen;
930
931	if (error) {
932		error = EIO;
933	}
934	return (error);
935}
936
937/*------------------------------------------------------------------------
938 *	ugen_re_enumerate
939 *------------------------------------------------------------------------*/
940static int
941ugen_re_enumerate(struct usb_fifo *f)
942{
943	struct usb_device *udev = f->udev;
944	int error;
945
946	/*
947	 * This request can be useful for testing USB drivers:
948	 */
949	error = priv_check(curthread, PRIV_DRIVER);
950	if (error) {
951		return (error);
952	}
953	if (udev->flags.usb_mode != USB_MODE_HOST) {
954		/* not possible in device side mode */
955		DPRINTFN(6, "device mode\n");
956		return (ENOTTY);
957	}
958	if (udev->parent_hub == NULL) {
959		/* the root HUB cannot be re-enumerated */
960		DPRINTFN(6, "cannot reset root HUB\n");
961		return (EINVAL);
962	}
963	/* make sure all FIFO's are gone */
964	/* else there can be a deadlock */
965	if (ugen_fs_uninit(f)) {
966		/* ignore any errors */
967		DPRINTFN(6, "no FIFOs\n");
968	}
969	/* start re-enumeration of device */
970	usbd_start_re_enumerate(udev);
971	return (0);
972}
973
974int
975ugen_fs_uninit(struct usb_fifo *f)
976{
977	if (f->fs_xfer == NULL) {
978		return (EINVAL);
979	}
980	usbd_transfer_unsetup(f->fs_xfer, f->fs_ep_max);
981	free(f->fs_xfer, M_USB);
982	f->fs_xfer = NULL;
983	f->fs_ep_max = 0;
984	f->fs_ep_ptr = NULL;
985	f->flag_iscomplete = 0;
986	usb_fifo_free_buffer(f);
987	return (0);
988}
989
990static uint8_t
991ugen_fs_get_complete(struct usb_fifo *f, uint8_t *pindex)
992{
993	struct usb_mbuf *m;
994
995	USB_IF_DEQUEUE(&f->used_q, m);
996
997	if (m) {
998		*pindex = *((uint8_t *)(m->cur_data_ptr));
999
1000		USB_IF_ENQUEUE(&f->free_q, m);
1001
1002		return (0);		/* success */
1003	} else {
1004
1005		*pindex = 0;		/* fix compiler warning */
1006
1007		f->flag_iscomplete = 0;
1008	}
1009	return (1);			/* failure */
1010}
1011
1012static void
1013ugen_fs_set_complete(struct usb_fifo *f, uint8_t index)
1014{
1015	struct usb_mbuf *m;
1016
1017	USB_IF_DEQUEUE(&f->free_q, m);
1018
1019	if (m == NULL) {
1020		/* can happen during close */
1021		DPRINTF("out of buffers\n");
1022		return;
1023	}
1024	USB_MBUF_RESET(m);
1025
1026	*((uint8_t *)(m->cur_data_ptr)) = index;
1027
1028	USB_IF_ENQUEUE(&f->used_q, m);
1029
1030	f->flag_iscomplete = 1;
1031
1032	usb_fifo_wakeup(f);
1033}
1034
1035static int
1036ugen_fs_copy_in(struct usb_fifo *f, uint8_t ep_index)
1037{
1038	struct usb_device_request *req;
1039	struct usb_xfer *xfer;
1040	struct usb_fs_endpoint fs_ep;
1041	void *uaddr;			/* userland pointer */
1042	void *kaddr;
1043	usb_frlength_t offset;
1044	usb_frlength_t rem;
1045	usb_frcount_t n;
1046	uint32_t length;
1047	int error;
1048	uint8_t isread;
1049
1050	if (ep_index >= f->fs_ep_max) {
1051		return (EINVAL);
1052	}
1053	xfer = f->fs_xfer[ep_index];
1054	if (xfer == NULL) {
1055		return (EINVAL);
1056	}
1057	mtx_lock(f->priv_mtx);
1058	if (usbd_transfer_pending(xfer)) {
1059		mtx_unlock(f->priv_mtx);
1060		return (EBUSY);		/* should not happen */
1061	}
1062	mtx_unlock(f->priv_mtx);
1063
1064	error = copyin(f->fs_ep_ptr +
1065	    ep_index, &fs_ep, sizeof(fs_ep));
1066	if (error) {
1067		return (error);
1068	}
1069	/* security checks */
1070
1071	if (fs_ep.nFrames > xfer->max_frame_count) {
1072		xfer->error = USB_ERR_INVAL;
1073		goto complete;
1074	}
1075	if (fs_ep.nFrames == 0) {
1076		xfer->error = USB_ERR_INVAL;
1077		goto complete;
1078	}
1079	error = copyin(fs_ep.ppBuffer,
1080	    &uaddr, sizeof(uaddr));
1081	if (error) {
1082		return (error);
1083	}
1084	/* reset first frame */
1085	usbd_xfer_set_frame_offset(xfer, 0, 0);
1086
1087	if (xfer->flags_int.control_xfr) {
1088
1089		req = xfer->frbuffers[0].buffer;
1090
1091		error = copyin(fs_ep.pLength,
1092		    &length, sizeof(length));
1093		if (error) {
1094			return (error);
1095		}
1096		if (length != sizeof(*req)) {
1097			xfer->error = USB_ERR_INVAL;
1098			goto complete;
1099		}
1100		if (length != 0) {
1101			error = copyin(uaddr, req, length);
1102			if (error) {
1103				return (error);
1104			}
1105		}
1106		if (ugen_check_request(f->udev, req)) {
1107			xfer->error = USB_ERR_INVAL;
1108			goto complete;
1109		}
1110		usbd_xfer_set_frame_len(xfer, 0, length);
1111
1112		/* Host mode only ! */
1113		if ((req->bmRequestType &
1114		    (UT_READ | UT_WRITE)) == UT_READ) {
1115			isread = 1;
1116		} else {
1117			isread = 0;
1118		}
1119		n = 1;
1120		offset = sizeof(*req);
1121
1122	} else {
1123		/* Device and Host mode */
1124		if (USB_GET_DATA_ISREAD(xfer)) {
1125			isread = 1;
1126		} else {
1127			isread = 0;
1128		}
1129		n = 0;
1130		offset = 0;
1131	}
1132
1133	rem = usbd_xfer_max_len(xfer);
1134	xfer->nframes = fs_ep.nFrames;
1135	xfer->timeout = fs_ep.timeout;
1136	if (xfer->timeout > 65535) {
1137		xfer->timeout = 65535;
1138	}
1139	if (fs_ep.flags & USB_FS_FLAG_SINGLE_SHORT_OK)
1140		xfer->flags.short_xfer_ok = 1;
1141	else
1142		xfer->flags.short_xfer_ok = 0;
1143
1144	if (fs_ep.flags & USB_FS_FLAG_MULTI_SHORT_OK)
1145		xfer->flags.short_frames_ok = 1;
1146	else
1147		xfer->flags.short_frames_ok = 0;
1148
1149	if (fs_ep.flags & USB_FS_FLAG_FORCE_SHORT)
1150		xfer->flags.force_short_xfer = 1;
1151	else
1152		xfer->flags.force_short_xfer = 0;
1153
1154	if (fs_ep.flags & USB_FS_FLAG_CLEAR_STALL)
1155		usbd_xfer_set_stall(xfer);
1156	else
1157		xfer->flags.stall_pipe = 0;
1158
1159	for (; n != xfer->nframes; n++) {
1160
1161		error = copyin(fs_ep.pLength + n,
1162		    &length, sizeof(length));
1163		if (error) {
1164			break;
1165		}
1166		usbd_xfer_set_frame_len(xfer, n, length);
1167
1168		if (length > rem) {
1169			xfer->error = USB_ERR_INVAL;
1170			goto complete;
1171		}
1172		rem -= length;
1173
1174		if (!isread) {
1175
1176			/* we need to know the source buffer */
1177			error = copyin(fs_ep.ppBuffer + n,
1178			    &uaddr, sizeof(uaddr));
1179			if (error) {
1180				break;
1181			}
1182			if (xfer->flags_int.isochronous_xfr) {
1183				/* get kernel buffer address */
1184				kaddr = xfer->frbuffers[0].buffer;
1185				kaddr = USB_ADD_BYTES(kaddr, offset);
1186			} else {
1187				/* set current frame offset */
1188				usbd_xfer_set_frame_offset(xfer, offset, n);
1189
1190				/* get kernel buffer address */
1191				kaddr = xfer->frbuffers[n].buffer;
1192			}
1193
1194			/* move data */
1195			error = copyin(uaddr, kaddr, length);
1196			if (error) {
1197				break;
1198			}
1199		}
1200		offset += length;
1201	}
1202	return (error);
1203
1204complete:
1205	mtx_lock(f->priv_mtx);
1206	ugen_fs_set_complete(f, ep_index);
1207	mtx_unlock(f->priv_mtx);
1208	return (0);
1209}
1210
1211static int
1212ugen_fs_copy_out(struct usb_fifo *f, uint8_t ep_index)
1213{
1214	struct usb_device_request *req;
1215	struct usb_xfer *xfer;
1216	struct usb_fs_endpoint fs_ep;
1217	struct usb_fs_endpoint *fs_ep_uptr;	/* userland ptr */
1218	void *uaddr;			/* userland ptr */
1219	void *kaddr;
1220	usb_frlength_t offset;
1221	usb_frlength_t rem;
1222	usb_frcount_t n;
1223	uint32_t length;
1224	uint32_t temp;
1225	int error;
1226	uint8_t isread;
1227
1228	if (ep_index >= f->fs_ep_max)
1229		return (EINVAL);
1230
1231	xfer = f->fs_xfer[ep_index];
1232	if (xfer == NULL)
1233		return (EINVAL);
1234
1235	mtx_lock(f->priv_mtx);
1236	if (usbd_transfer_pending(xfer)) {
1237		mtx_unlock(f->priv_mtx);
1238		return (EBUSY);		/* should not happen */
1239	}
1240	mtx_unlock(f->priv_mtx);
1241
1242	fs_ep_uptr = f->fs_ep_ptr + ep_index;
1243	error = copyin(fs_ep_uptr, &fs_ep, sizeof(fs_ep));
1244	if (error) {
1245		return (error);
1246	}
1247	fs_ep.status = xfer->error;
1248	fs_ep.aFrames = xfer->aframes;
1249	fs_ep.isoc_time_complete = xfer->isoc_time_complete;
1250	if (xfer->error) {
1251		goto complete;
1252	}
1253	if (xfer->flags_int.control_xfr) {
1254		req = xfer->frbuffers[0].buffer;
1255
1256		/* Host mode only ! */
1257		if ((req->bmRequestType & (UT_READ | UT_WRITE)) == UT_READ) {
1258			isread = 1;
1259		} else {
1260			isread = 0;
1261		}
1262		if (xfer->nframes == 0)
1263			n = 0;		/* should never happen */
1264		else
1265			n = 1;
1266	} else {
1267		/* Device and Host mode */
1268		if (USB_GET_DATA_ISREAD(xfer)) {
1269			isread = 1;
1270		} else {
1271			isread = 0;
1272		}
1273		n = 0;
1274	}
1275
1276	/* Update lengths and copy out data */
1277
1278	rem = usbd_xfer_max_len(xfer);
1279	offset = 0;
1280
1281	for (; n != xfer->nframes; n++) {
1282
1283		/* get initial length into "temp" */
1284		error = copyin(fs_ep.pLength + n,
1285		    &temp, sizeof(temp));
1286		if (error) {
1287			return (error);
1288		}
1289		if (temp > rem) {
1290			/* the userland length has been corrupted */
1291			DPRINTF("corrupt userland length "
1292			    "%u > %u\n", temp, rem);
1293			fs_ep.status = USB_ERR_INVAL;
1294			goto complete;
1295		}
1296		rem -= temp;
1297
1298		/* get actual transfer length */
1299		length = xfer->frlengths[n];
1300		if (length > temp) {
1301			/* data overflow */
1302			fs_ep.status = USB_ERR_INVAL;
1303			DPRINTF("data overflow %u > %u\n",
1304			    length, temp);
1305			goto complete;
1306		}
1307		if (isread) {
1308
1309			/* we need to know the destination buffer */
1310			error = copyin(fs_ep.ppBuffer + n,
1311			    &uaddr, sizeof(uaddr));
1312			if (error) {
1313				return (error);
1314			}
1315			if (xfer->flags_int.isochronous_xfr) {
1316				/* only one frame buffer */
1317				kaddr = USB_ADD_BYTES(
1318				    xfer->frbuffers[0].buffer, offset);
1319			} else {
1320				/* multiple frame buffers */
1321				kaddr = xfer->frbuffers[n].buffer;
1322			}
1323
1324			/* move data */
1325			error = copyout(kaddr, uaddr, length);
1326			if (error) {
1327				return (error);
1328			}
1329		}
1330		/*
1331		 * Update offset according to initial length, which is
1332		 * needed by isochronous transfers!
1333		 */
1334		offset += temp;
1335
1336		/* update length */
1337		error = copyout(&length,
1338		    fs_ep.pLength + n, sizeof(length));
1339		if (error) {
1340			return (error);
1341		}
1342	}
1343
1344complete:
1345	/* update "aFrames" */
1346	error = copyout(&fs_ep.aFrames, &fs_ep_uptr->aFrames,
1347	    sizeof(fs_ep.aFrames));
1348	if (error)
1349		goto done;
1350
1351	/* update "isoc_time_complete" */
1352	error = copyout(&fs_ep.isoc_time_complete,
1353	    &fs_ep_uptr->isoc_time_complete,
1354	    sizeof(fs_ep.isoc_time_complete));
1355	if (error)
1356		goto done;
1357	/* update "status" */
1358	error = copyout(&fs_ep.status, &fs_ep_uptr->status,
1359	    sizeof(fs_ep.status));
1360done:
1361	return (error);
1362}
1363
1364static uint8_t
1365ugen_fifo_in_use(struct usb_fifo *f, int fflags)
1366{
1367	struct usb_fifo *f_rx;
1368	struct usb_fifo *f_tx;
1369
1370	f_rx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_RX];
1371	f_tx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_TX];
1372
1373	if ((fflags & FREAD) && f_rx &&
1374	    (f_rx->xfer[0] || f_rx->xfer[1])) {
1375		return (1);		/* RX FIFO in use */
1376	}
1377	if ((fflags & FWRITE) && f_tx &&
1378	    (f_tx->xfer[0] || f_tx->xfer[1])) {
1379		return (1);		/* TX FIFO in use */
1380	}
1381	return (0);			/* not in use */
1382}
1383
1384static int
1385ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
1386{
1387	struct usb_config usb_config[1];
1388	struct usb_device_request req;
1389	union {
1390		struct usb_fs_complete *pcomp;
1391		struct usb_fs_start *pstart;
1392		struct usb_fs_stop *pstop;
1393		struct usb_fs_open *popen;
1394		struct usb_fs_close *pclose;
1395		struct usb_fs_clear_stall_sync *pstall;
1396		void   *addr;
1397	}     u;
1398	struct usb_endpoint *ep;
1399	struct usb_endpoint_descriptor *ed;
1400	struct usb_xfer *xfer;
1401	int error = 0;
1402	uint8_t iface_index;
1403	uint8_t isread;
1404	uint8_t ep_index;
1405	uint8_t pre_scale;
1406
1407	u.addr = addr;
1408
1409	DPRINTFN(6, "cmd=0x%08lx\n", cmd);
1410
1411	switch (cmd) {
1412	case USB_FS_COMPLETE:
1413		mtx_lock(f->priv_mtx);
1414		error = ugen_fs_get_complete(f, &ep_index);
1415		mtx_unlock(f->priv_mtx);
1416
1417		if (error) {
1418			error = EBUSY;
1419			break;
1420		}
1421		u.pcomp->ep_index = ep_index;
1422		error = ugen_fs_copy_out(f, u.pcomp->ep_index);
1423		break;
1424
1425	case USB_FS_START:
1426		error = ugen_fs_copy_in(f, u.pstart->ep_index);
1427		if (error)
1428			break;
1429		mtx_lock(f->priv_mtx);
1430		xfer = f->fs_xfer[u.pstart->ep_index];
1431		usbd_transfer_start(xfer);
1432		mtx_unlock(f->priv_mtx);
1433		break;
1434
1435	case USB_FS_STOP:
1436		if (u.pstop->ep_index >= f->fs_ep_max) {
1437			error = EINVAL;
1438			break;
1439		}
1440		mtx_lock(f->priv_mtx);
1441		xfer = f->fs_xfer[u.pstart->ep_index];
1442		if (usbd_transfer_pending(xfer)) {
1443			usbd_transfer_stop(xfer);
1444			/*
1445			 * Check if the USB transfer was stopped
1446			 * before it was even started. Else a cancel
1447			 * callback will be pending.
1448			 */
1449			if (!xfer->flags_int.transferring) {
1450				ugen_fs_set_complete(xfer->priv_sc,
1451				    USB_P2U(xfer->priv_fifo));
1452			}
1453		}
1454		mtx_unlock(f->priv_mtx);
1455		break;
1456
1457	case USB_FS_OPEN:
1458		if (u.popen->ep_index >= f->fs_ep_max) {
1459			error = EINVAL;
1460			break;
1461		}
1462		if (f->fs_xfer[u.popen->ep_index] != NULL) {
1463			error = EBUSY;
1464			break;
1465		}
1466		if (u.popen->max_bufsize > USB_FS_MAX_BUFSIZE) {
1467			u.popen->max_bufsize = USB_FS_MAX_BUFSIZE;
1468		}
1469		if (u.popen->max_frames & USB_FS_MAX_FRAMES_PRE_SCALE) {
1470			pre_scale = 1;
1471			u.popen->max_frames &= ~USB_FS_MAX_FRAMES_PRE_SCALE;
1472		} else {
1473			pre_scale = 0;
1474		}
1475		if (u.popen->max_frames > USB_FS_MAX_FRAMES) {
1476			u.popen->max_frames = USB_FS_MAX_FRAMES;
1477			break;
1478		}
1479		if (u.popen->max_frames == 0) {
1480			error = EINVAL;
1481			break;
1482		}
1483		ep = usbd_get_ep_by_addr(f->udev, u.popen->ep_no);
1484		if (ep == NULL) {
1485			error = EINVAL;
1486			break;
1487		}
1488		ed = ep->edesc;
1489		if (ed == NULL) {
1490			error = ENXIO;
1491			break;
1492		}
1493		iface_index = ep->iface_index;
1494
1495		memset(usb_config, 0, sizeof(usb_config));
1496
1497		usb_config[0].type = ed->bmAttributes & UE_XFERTYPE;
1498		usb_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
1499		usb_config[0].direction = ed->bEndpointAddress & (UE_DIR_OUT | UE_DIR_IN);
1500		usb_config[0].interval = USB_DEFAULT_INTERVAL;
1501		usb_config[0].flags.proxy_buffer = 1;
1502		if (pre_scale != 0)
1503			usb_config[0].flags.pre_scale_frames = 1;
1504		usb_config[0].callback = &ugen_ctrl_fs_callback;
1505		usb_config[0].timeout = 0;	/* no timeout */
1506		usb_config[0].frames = u.popen->max_frames;
1507		usb_config[0].bufsize = u.popen->max_bufsize;
1508		usb_config[0].usb_mode = USB_MODE_DUAL;	/* both modes */
1509
1510		if (usb_config[0].type == UE_CONTROL) {
1511			if (f->udev->flags.usb_mode != USB_MODE_HOST) {
1512				error = EINVAL;
1513				break;
1514			}
1515		} else {
1516
1517			isread = ((usb_config[0].endpoint &
1518			    (UE_DIR_IN | UE_DIR_OUT)) == UE_DIR_IN);
1519
1520			if (f->udev->flags.usb_mode != USB_MODE_HOST) {
1521				isread = !isread;
1522			}
1523			/* check permissions */
1524			if (isread) {
1525				if (!(fflags & FREAD)) {
1526					error = EPERM;
1527					break;
1528				}
1529			} else {
1530				if (!(fflags & FWRITE)) {
1531					error = EPERM;
1532					break;
1533				}
1534			}
1535		}
1536		error = usbd_transfer_setup(f->udev, &iface_index,
1537		    f->fs_xfer + u.popen->ep_index, usb_config, 1,
1538		    f, f->priv_mtx);
1539		if (error == 0) {
1540			/* update maximums */
1541			u.popen->max_packet_length =
1542			    f->fs_xfer[u.popen->ep_index]->max_frame_size;
1543			u.popen->max_bufsize =
1544			    f->fs_xfer[u.popen->ep_index]->max_data_length;
1545			/* update number of frames */
1546			u.popen->max_frames =
1547			    f->fs_xfer[u.popen->ep_index]->nframes;
1548			/* store index of endpoint */
1549			f->fs_xfer[u.popen->ep_index]->priv_fifo =
1550			    ((uint8_t *)0) + u.popen->ep_index;
1551		} else {
1552			error = ENOMEM;
1553		}
1554		break;
1555
1556	case USB_FS_CLOSE:
1557		if (u.pclose->ep_index >= f->fs_ep_max) {
1558			error = EINVAL;
1559			break;
1560		}
1561		if (f->fs_xfer[u.pclose->ep_index] == NULL) {
1562			error = EINVAL;
1563			break;
1564		}
1565		usbd_transfer_unsetup(f->fs_xfer + u.pclose->ep_index, 1);
1566		break;
1567
1568	case USB_FS_CLEAR_STALL_SYNC:
1569		if (u.pstall->ep_index >= f->fs_ep_max) {
1570			error = EINVAL;
1571			break;
1572		}
1573		if (f->fs_xfer[u.pstall->ep_index] == NULL) {
1574			error = EINVAL;
1575			break;
1576		}
1577		if (f->udev->flags.usb_mode != USB_MODE_HOST) {
1578			error = EINVAL;
1579			break;
1580		}
1581		mtx_lock(f->priv_mtx);
1582		error = usbd_transfer_pending(f->fs_xfer[u.pstall->ep_index]);
1583		mtx_unlock(f->priv_mtx);
1584
1585		if (error) {
1586			return (EBUSY);
1587		}
1588		ep = f->fs_xfer[u.pstall->ep_index]->endpoint;
1589
1590		/* setup a clear-stall packet */
1591		req.bmRequestType = UT_WRITE_ENDPOINT;
1592		req.bRequest = UR_CLEAR_FEATURE;
1593		USETW(req.wValue, UF_ENDPOINT_HALT);
1594		req.wIndex[0] = ep->edesc->bEndpointAddress;
1595		req.wIndex[1] = 0;
1596		USETW(req.wLength, 0);
1597
1598		error = usbd_do_request(f->udev, NULL, &req, NULL);
1599		if (error == 0) {
1600			usbd_clear_data_toggle(f->udev, ep);
1601		} else {
1602			error = ENXIO;
1603		}
1604		break;
1605
1606	default:
1607		error = ENOIOCTL;
1608		break;
1609	}
1610
1611	DPRINTFN(6, "error=%d\n", error);
1612
1613	return (error);
1614}
1615
1616static int
1617ugen_set_short_xfer(struct usb_fifo *f, void *addr)
1618{
1619	uint8_t t;
1620
1621	if (*(int *)addr)
1622		t = 1;
1623	else
1624		t = 0;
1625
1626	if (f->flag_short == t) {
1627		/* same value like before - accept */
1628		return (0);
1629	}
1630	if (f->xfer[0] || f->xfer[1]) {
1631		/* cannot change this during transfer */
1632		return (EBUSY);
1633	}
1634	f->flag_short = t;
1635	return (0);
1636}
1637
1638static int
1639ugen_set_timeout(struct usb_fifo *f, void *addr)
1640{
1641	f->timeout = *(int *)addr;
1642	if (f->timeout > 65535) {
1643		/* limit user input */
1644		f->timeout = 65535;
1645	}
1646	return (0);
1647}
1648
1649static int
1650ugen_get_frame_size(struct usb_fifo *f, void *addr)
1651{
1652	if (f->xfer[0]) {
1653		*(int *)addr = f->xfer[0]->max_frame_size;
1654	} else {
1655		return (EINVAL);
1656	}
1657	return (0);
1658}
1659
1660static int
1661ugen_set_buffer_size(struct usb_fifo *f, void *addr)
1662{
1663	usb_frlength_t t;
1664
1665	if (*(int *)addr < 0)
1666		t = 0;		/* use "wMaxPacketSize" */
1667	else if (*(int *)addr < (256 * 1024))
1668		t = *(int *)addr;
1669	else
1670		t = 256 * 1024;
1671
1672	if (f->bufsize == t) {
1673		/* same value like before - accept */
1674		return (0);
1675	}
1676	if (f->xfer[0] || f->xfer[1]) {
1677		/* cannot change this during transfer */
1678		return (EBUSY);
1679	}
1680	f->bufsize = t;
1681	return (0);
1682}
1683
1684static int
1685ugen_get_buffer_size(struct usb_fifo *f, void *addr)
1686{
1687	*(int *)addr = f->bufsize;
1688	return (0);
1689}
1690
1691static int
1692ugen_get_iface_desc(struct usb_fifo *f,
1693    struct usb_interface_descriptor *idesc)
1694{
1695	struct usb_interface *iface;
1696
1697	iface = usbd_get_iface(f->udev, f->iface_index);
1698	if (iface && iface->idesc) {
1699		*idesc = *(iface->idesc);
1700	} else {
1701		return (EIO);
1702	}
1703	return (0);
1704}
1705
1706static int
1707ugen_get_endpoint_desc(struct usb_fifo *f,
1708    struct usb_endpoint_descriptor *ed)
1709{
1710	struct usb_endpoint *ep;
1711
1712	ep = usb_fifo_softc(f);
1713
1714	if (ep && ep->edesc) {
1715		*ed = *ep->edesc;
1716	} else {
1717		return (EINVAL);
1718	}
1719	return (0);
1720}
1721
1722static int
1723ugen_set_power_mode(struct usb_fifo *f, int mode)
1724{
1725	struct usb_device *udev = f->udev;
1726	int err;
1727	uint8_t old_mode;
1728
1729	if ((udev == NULL) ||
1730	    (udev->parent_hub == NULL)) {
1731		return (EINVAL);
1732	}
1733	err = priv_check(curthread, PRIV_DRIVER);
1734	if (err)
1735		return (err);
1736
1737	/* get old power mode */
1738	old_mode = udev->power_mode;
1739
1740	/* if no change, then just return */
1741	if (old_mode == mode)
1742		return (0);
1743
1744	switch (mode) {
1745	case USB_POWER_MODE_OFF:
1746		/* get the device unconfigured */
1747		err = ugen_set_config(f, USB_UNCONFIG_INDEX);
1748		if (err) {
1749			DPRINTFN(0, "Could not unconfigure "
1750			    "device (ignored)\n");
1751		}
1752
1753		/* clear port enable */
1754		err = usbd_req_clear_port_feature(udev->parent_hub,
1755		    NULL, udev->port_no, UHF_PORT_ENABLE);
1756		break;
1757
1758	case USB_POWER_MODE_ON:
1759	case USB_POWER_MODE_SAVE:
1760		break;
1761
1762	case USB_POWER_MODE_RESUME:
1763#if USB_HAVE_POWERD
1764		/* let USB-powerd handle resume */
1765		USB_BUS_LOCK(udev->bus);
1766		udev->pwr_save.write_refs++;
1767		udev->pwr_save.last_xfer_time = ticks;
1768		USB_BUS_UNLOCK(udev->bus);
1769
1770		/* set new power mode */
1771		usbd_set_power_mode(udev, USB_POWER_MODE_SAVE);
1772
1773		/* wait for resume to complete */
1774		usb_pause_mtx(NULL, hz / 4);
1775
1776		/* clear write reference */
1777		USB_BUS_LOCK(udev->bus);
1778		udev->pwr_save.write_refs--;
1779		USB_BUS_UNLOCK(udev->bus);
1780#endif
1781		mode = USB_POWER_MODE_SAVE;
1782		break;
1783
1784	case USB_POWER_MODE_SUSPEND:
1785#if USB_HAVE_POWERD
1786		/* let USB-powerd handle suspend */
1787		USB_BUS_LOCK(udev->bus);
1788		udev->pwr_save.last_xfer_time = ticks - (256 * hz);
1789		USB_BUS_UNLOCK(udev->bus);
1790#endif
1791		mode = USB_POWER_MODE_SAVE;
1792		break;
1793
1794	default:
1795		return (EINVAL);
1796	}
1797
1798	if (err)
1799		return (ENXIO);		/* I/O failure */
1800
1801	/* if we are powered off we need to re-enumerate first */
1802	if (old_mode == USB_POWER_MODE_OFF) {
1803		if (udev->flags.usb_mode == USB_MODE_HOST) {
1804			if (udev->re_enumerate_wait == 0)
1805				udev->re_enumerate_wait = 1;
1806		}
1807		/* set power mode will wake up the explore thread */
1808	}
1809
1810	/* set new power mode */
1811	usbd_set_power_mode(udev, mode);
1812
1813	return (0);			/* success */
1814}
1815
1816static int
1817ugen_get_power_mode(struct usb_fifo *f)
1818{
1819	struct usb_device *udev = f->udev;
1820
1821	if (udev == NULL)
1822		return (USB_POWER_MODE_ON);
1823
1824	return (udev->power_mode);
1825}
1826
1827static int
1828ugen_do_port_feature(struct usb_fifo *f, uint8_t port_no,
1829    uint8_t set, uint16_t feature)
1830{
1831	struct usb_device *udev = f->udev;
1832	struct usb_hub *hub;
1833	int err;
1834
1835	err = priv_check(curthread, PRIV_DRIVER);
1836	if (err) {
1837		return (err);
1838	}
1839	if (port_no == 0) {
1840		return (EINVAL);
1841	}
1842	if ((udev == NULL) ||
1843	    (udev->hub == NULL)) {
1844		return (EINVAL);
1845	}
1846	hub = udev->hub;
1847
1848	if (port_no > hub->nports) {
1849		return (EINVAL);
1850	}
1851	if (set)
1852		err = usbd_req_set_port_feature(udev,
1853		    NULL, port_no, feature);
1854	else
1855		err = usbd_req_clear_port_feature(udev,
1856		    NULL, port_no, feature);
1857
1858	if (err)
1859		return (ENXIO);		/* failure */
1860
1861	return (0);			/* success */
1862}
1863
1864static int
1865ugen_iface_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
1866{
1867	struct usb_fifo *f_rx;
1868	struct usb_fifo *f_tx;
1869	int error = 0;
1870
1871	f_rx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_RX];
1872	f_tx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_TX];
1873
1874	switch (cmd) {
1875	case USB_SET_RX_SHORT_XFER:
1876		if (fflags & FREAD) {
1877			error = ugen_set_short_xfer(f_rx, addr);
1878		} else {
1879			error = EINVAL;
1880		}
1881		break;
1882
1883	case USB_SET_TX_FORCE_SHORT:
1884		if (fflags & FWRITE) {
1885			error = ugen_set_short_xfer(f_tx, addr);
1886		} else {
1887			error = EINVAL;
1888		}
1889		break;
1890
1891	case USB_SET_RX_TIMEOUT:
1892		if (fflags & FREAD) {
1893			error = ugen_set_timeout(f_rx, addr);
1894		} else {
1895			error = EINVAL;
1896		}
1897		break;
1898
1899	case USB_SET_TX_TIMEOUT:
1900		if (fflags & FWRITE) {
1901			error = ugen_set_timeout(f_tx, addr);
1902		} else {
1903			error = EINVAL;
1904		}
1905		break;
1906
1907	case USB_GET_RX_FRAME_SIZE:
1908		if (fflags & FREAD) {
1909			error = ugen_get_frame_size(f_rx, addr);
1910		} else {
1911			error = EINVAL;
1912		}
1913		break;
1914
1915	case USB_GET_TX_FRAME_SIZE:
1916		if (fflags & FWRITE) {
1917			error = ugen_get_frame_size(f_tx, addr);
1918		} else {
1919			error = EINVAL;
1920		}
1921		break;
1922
1923	case USB_SET_RX_BUFFER_SIZE:
1924		if (fflags & FREAD) {
1925			error = ugen_set_buffer_size(f_rx, addr);
1926		} else {
1927			error = EINVAL;
1928		}
1929		break;
1930
1931	case USB_SET_TX_BUFFER_SIZE:
1932		if (fflags & FWRITE) {
1933			error = ugen_set_buffer_size(f_tx, addr);
1934		} else {
1935			error = EINVAL;
1936		}
1937		break;
1938
1939	case USB_GET_RX_BUFFER_SIZE:
1940		if (fflags & FREAD) {
1941			error = ugen_get_buffer_size(f_rx, addr);
1942		} else {
1943			error = EINVAL;
1944		}
1945		break;
1946
1947	case USB_GET_TX_BUFFER_SIZE:
1948		if (fflags & FWRITE) {
1949			error = ugen_get_buffer_size(f_tx, addr);
1950		} else {
1951			error = EINVAL;
1952		}
1953		break;
1954
1955	case USB_GET_RX_INTERFACE_DESC:
1956		if (fflags & FREAD) {
1957			error = ugen_get_iface_desc(f_rx, addr);
1958		} else {
1959			error = EINVAL;
1960		}
1961		break;
1962
1963	case USB_GET_TX_INTERFACE_DESC:
1964		if (fflags & FWRITE) {
1965			error = ugen_get_iface_desc(f_tx, addr);
1966		} else {
1967			error = EINVAL;
1968		}
1969		break;
1970
1971	case USB_GET_RX_ENDPOINT_DESC:
1972		if (fflags & FREAD) {
1973			error = ugen_get_endpoint_desc(f_rx, addr);
1974		} else {
1975			error = EINVAL;
1976		}
1977		break;
1978
1979	case USB_GET_TX_ENDPOINT_DESC:
1980		if (fflags & FWRITE) {
1981			error = ugen_get_endpoint_desc(f_tx, addr);
1982		} else {
1983			error = EINVAL;
1984		}
1985		break;
1986
1987	case USB_SET_RX_STALL_FLAG:
1988		if ((fflags & FREAD) && (*(int *)addr)) {
1989			f_rx->flag_stall = 1;
1990		}
1991		break;
1992
1993	case USB_SET_TX_STALL_FLAG:
1994		if ((fflags & FWRITE) && (*(int *)addr)) {
1995			f_tx->flag_stall = 1;
1996		}
1997		break;
1998
1999	default:
2000		error = ENOIOCTL;
2001		break;
2002	}
2003	return (error);
2004}
2005
2006static int
2007ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
2008{
2009	union {
2010		struct usb_interface_descriptor *idesc;
2011		struct usb_alt_interface *ai;
2012		struct usb_device_descriptor *ddesc;
2013		struct usb_config_descriptor *cdesc;
2014		struct usb_device_stats *stat;
2015		struct usb_fs_init *pinit;
2016		struct usb_fs_uninit *puninit;
2017		uint32_t *ptime;
2018		void   *addr;
2019		int    *pint;
2020	}     u;
2021	struct usb_device_descriptor *dtemp;
2022	struct usb_config_descriptor *ctemp;
2023	struct usb_interface *iface;
2024	int error = 0;
2025	uint8_t n;
2026
2027	u.addr = addr;
2028
2029	DPRINTFN(6, "cmd=0x%08lx\n", cmd);
2030
2031	switch (cmd) {
2032	case USB_DISCOVER:
2033		usb_needs_explore_all();
2034		break;
2035
2036	case USB_SETDEBUG:
2037		if (!(fflags & FWRITE)) {
2038			error = EPERM;
2039			break;
2040		}
2041		usb_debug = *(int *)addr;
2042		break;
2043
2044	case USB_GET_CONFIG:
2045		*(int *)addr = f->udev->curr_config_index;
2046		break;
2047
2048	case USB_SET_CONFIG:
2049		if (!(fflags & FWRITE)) {
2050			error = EPERM;
2051			break;
2052		}
2053		error = ugen_set_config(f, *(int *)addr);
2054		break;
2055
2056	case USB_GET_ALTINTERFACE:
2057		iface = usbd_get_iface(f->udev,
2058		    u.ai->uai_interface_index);
2059		if (iface && iface->idesc) {
2060			u.ai->uai_alt_index = iface->alt_index;
2061		} else {
2062			error = EINVAL;
2063		}
2064		break;
2065
2066	case USB_SET_ALTINTERFACE:
2067		if (!(fflags & FWRITE)) {
2068			error = EPERM;
2069			break;
2070		}
2071		error = ugen_set_interface(f,
2072		    u.ai->uai_interface_index, u.ai->uai_alt_index);
2073		break;
2074
2075	case USB_GET_DEVICE_DESC:
2076		dtemp = usbd_get_device_descriptor(f->udev);
2077		if (!dtemp) {
2078			error = EIO;
2079			break;
2080		}
2081		*u.ddesc = *dtemp;
2082		break;
2083
2084	case USB_GET_CONFIG_DESC:
2085		ctemp = usbd_get_config_descriptor(f->udev);
2086		if (!ctemp) {
2087			error = EIO;
2088			break;
2089		}
2090		*u.cdesc = *ctemp;
2091		break;
2092
2093	case USB_GET_FULL_DESC:
2094		error = ugen_get_cdesc(f, addr);
2095		break;
2096
2097	case USB_GET_STRING_DESC:
2098		error = ugen_get_sdesc(f, addr);
2099		break;
2100
2101	case USB_GET_IFACE_DRIVER:
2102		error = ugen_get_iface_driver(f, addr);
2103		break;
2104
2105	case USB_REQUEST:
2106	case USB_DO_REQUEST:
2107		if (!(fflags & FWRITE)) {
2108			error = EPERM;
2109			break;
2110		}
2111		error = ugen_do_request(f, addr);
2112		break;
2113
2114	case USB_DEVICEINFO:
2115	case USB_GET_DEVICEINFO:
2116		error = usb_gen_fill_deviceinfo(f, addr);
2117		break;
2118
2119	case USB_DEVICESTATS:
2120		for (n = 0; n != 4; n++) {
2121
2122			u.stat->uds_requests_fail[n] =
2123			    f->udev->bus->stats_err.uds_requests[n];
2124
2125			u.stat->uds_requests_ok[n] =
2126			    f->udev->bus->stats_ok.uds_requests[n];
2127		}
2128		break;
2129
2130	case USB_DEVICEENUMERATE:
2131		error = ugen_re_enumerate(f);
2132		break;
2133
2134	case USB_GET_PLUGTIME:
2135		*u.ptime = f->udev->plugtime;
2136		break;
2137
2138	case USB_CLAIM_INTERFACE:
2139	case USB_RELEASE_INTERFACE:
2140		/* TODO */
2141		break;
2142
2143	case USB_IFACE_DRIVER_ACTIVE:
2144
2145		n = *u.pint & 0xFF;
2146
2147		iface = usbd_get_iface(f->udev, n);
2148
2149		if (iface && iface->subdev)
2150			error = 0;
2151		else
2152			error = ENXIO;
2153		break;
2154
2155	case USB_IFACE_DRIVER_DETACH:
2156
2157		error = priv_check(curthread, PRIV_DRIVER);
2158
2159		if (error)
2160			break;
2161
2162		n = *u.pint & 0xFF;
2163
2164		if (n == USB_IFACE_INDEX_ANY) {
2165			error = EINVAL;
2166			break;
2167		}
2168
2169		usb_detach_device(f->udev, n, 0);
2170		break;
2171
2172	case USB_SET_POWER_MODE:
2173		error = ugen_set_power_mode(f, *u.pint);
2174		break;
2175
2176	case USB_GET_POWER_MODE:
2177		*u.pint = ugen_get_power_mode(f);
2178		break;
2179
2180	case USB_SET_PORT_ENABLE:
2181		error = ugen_do_port_feature(f,
2182		    *u.pint, 1, UHF_PORT_ENABLE);
2183		break;
2184
2185	case USB_SET_PORT_DISABLE:
2186		error = ugen_do_port_feature(f,
2187		    *u.pint, 0, UHF_PORT_ENABLE);
2188		break;
2189
2190	case USB_FS_INIT:
2191		/* verify input parameters */
2192		if (u.pinit->pEndpoints == NULL) {
2193			error = EINVAL;
2194			break;
2195		}
2196		if (u.pinit->ep_index_max > 127) {
2197			error = EINVAL;
2198			break;
2199		}
2200		if (u.pinit->ep_index_max == 0) {
2201			error = EINVAL;
2202			break;
2203		}
2204		if (f->fs_xfer != NULL) {
2205			error = EBUSY;
2206			break;
2207		}
2208		if (f->dev_ep_index != 0) {
2209			error = EINVAL;
2210			break;
2211		}
2212		if (ugen_fifo_in_use(f, fflags)) {
2213			error = EBUSY;
2214			break;
2215		}
2216		error = usb_fifo_alloc_buffer(f, 1, u.pinit->ep_index_max);
2217		if (error) {
2218			break;
2219		}
2220		f->fs_xfer = malloc(sizeof(f->fs_xfer[0]) *
2221		    u.pinit->ep_index_max, M_USB, M_WAITOK | M_ZERO);
2222		if (f->fs_xfer == NULL) {
2223			usb_fifo_free_buffer(f);
2224			error = ENOMEM;
2225			break;
2226		}
2227		f->fs_ep_max = u.pinit->ep_index_max;
2228		f->fs_ep_ptr = u.pinit->pEndpoints;
2229		break;
2230
2231	case USB_FS_UNINIT:
2232		if (u.puninit->dummy != 0) {
2233			error = EINVAL;
2234			break;
2235		}
2236		error = ugen_fs_uninit(f);
2237		break;
2238
2239	default:
2240		mtx_lock(f->priv_mtx);
2241		error = ugen_iface_ioctl(f, cmd, addr, fflags);
2242		mtx_unlock(f->priv_mtx);
2243		break;
2244	}
2245	DPRINTFN(6, "error=%d\n", error);
2246	return (error);
2247}
2248
2249static void
2250ugen_ctrl_fs_callback(struct usb_xfer *xfer, usb_error_t error)
2251{
2252	;				/* workaround for a bug in "indent" */
2253
2254	DPRINTF("st=%u alen=%u aframes=%u\n",
2255	    USB_GET_STATE(xfer), xfer->actlen, xfer->aframes);
2256
2257	switch (USB_GET_STATE(xfer)) {
2258	case USB_ST_SETUP:
2259		usbd_transfer_submit(xfer);
2260		break;
2261	default:
2262		ugen_fs_set_complete(xfer->priv_sc, USB_P2U(xfer->priv_fifo));
2263		break;
2264	}
2265}
2266#endif	/* USB_HAVE_UGEN */
2267