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