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