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