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