1 /* $FreeBSD: head/sys/dev/usb/usb_generic.c 277417 2015-01-20 11:43:16Z hselasky $ */
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/stdint.h>
28 #include <sys/param.h>
29 #include <sys/queue.h>
30 #include <sys/types.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
34 #include <sys/module.h>
36 #include <sys/mutex.h>
37 #include <sys/condvar.h>
38 #include <sys/sysctl.h>
39 #include <sys/unistd.h>
40 #include <sys/callout.h>
41 #include <sys/malloc.h>
44 #include <sys/fcntl.h>
46 #include <bus/u4b/usb.h>
47 #include <bus/u4b/usb_ioctl.h>
48 #include <bus/u4b/usbdi.h>
49 #include <bus/u4b/usbdi_util.h>
51 #define USB_DEBUG_VAR ugen_debug
53 #include <bus/u4b/usb_core.h>
54 #include <bus/u4b/usb_dev.h>
55 #include <bus/u4b/usb_mbuf.h>
56 #include <bus/u4b/usb_process.h>
57 #include <bus/u4b/usb_device.h>
58 #include <bus/u4b/usb_debug.h>
59 #include <bus/u4b/usb_request.h>
60 #include <bus/u4b/usb_busdma.h>
61 #include <bus/u4b/usb_util.h>
62 #include <bus/u4b/usb_hub.h>
63 #include <bus/u4b/usb_generic.h>
64 #include <bus/u4b/usb_transfer.h>
66 #include <bus/u4b/usb_controller.h>
67 #include <bus/u4b/usb_bus.h>
73 #define UGEN_BULK_FS_BUFFER_SIZE (64*32) /* bytes */
74 #define UGEN_BULK_HS_BUFFER_SIZE (1024*32) /* bytes */
75 #define UGEN_HW_FRAMES 50 /* number of milliseconds per transfer */
77 /* function prototypes */
79 static usb_callback_t ugen_read_clear_stall_callback
;
80 static usb_callback_t ugen_write_clear_stall_callback
;
81 static usb_callback_t ugen_ctrl_read_callback
;
82 static usb_callback_t ugen_ctrl_write_callback
;
83 static usb_callback_t ugen_isoc_read_callback
;
84 static usb_callback_t ugen_isoc_write_callback
;
85 static usb_callback_t ugen_ctrl_fs_callback
;
87 static usb_fifo_open_t ugen_open
;
88 static usb_fifo_close_t ugen_close
;
89 static usb_fifo_ioctl_t ugen_ioctl
;
90 static usb_fifo_ioctl_t ugen_ioctl_post
;
91 static usb_fifo_cmd_t ugen_start_read
;
92 static usb_fifo_cmd_t ugen_start_write
;
93 static usb_fifo_cmd_t ugen_stop_io
;
95 static int ugen_transfer_setup(struct usb_fifo
*,
96 const struct usb_config
*, uint8_t);
97 static int ugen_open_pipe_write(struct usb_fifo
*);
98 static int ugen_open_pipe_read(struct usb_fifo
*);
99 static int ugen_set_config(struct usb_fifo
*, uint8_t);
100 static int ugen_set_interface(struct usb_fifo
*, uint8_t, uint8_t);
101 static int ugen_get_cdesc(struct usb_fifo
*, struct usb_gen_descriptor
*);
102 static int ugen_get_sdesc(struct usb_fifo
*, struct usb_gen_descriptor
*);
103 static int ugen_get_iface_driver(struct usb_fifo
*f
, struct usb_gen_descriptor
*ugd
);
104 static int usb_gen_fill_deviceinfo(struct usb_fifo
*,
105 struct usb_device_info
*);
106 static int ugen_re_enumerate(struct usb_fifo
*);
107 static int ugen_iface_ioctl(struct usb_fifo
*, u_long
, void *, int);
108 static uint8_t ugen_fs_get_complete(struct usb_fifo
*, uint8_t *);
109 static int ugen_fs_uninit(struct usb_fifo
*f
);
113 struct usb_fifo_methods usb_ugen_methods
= {
114 .f_open
= &ugen_open
,
115 .f_close
= &ugen_close
,
116 .f_ioctl
= &ugen_ioctl
,
117 .f_ioctl_post
= &ugen_ioctl_post
,
118 .f_start_read
= &ugen_start_read
,
119 .f_stop_read
= &ugen_stop_io
,
120 .f_start_write
= &ugen_start_write
,
121 .f_stop_write
= &ugen_stop_io
,
125 static int ugen_debug
= 0;
127 static SYSCTL_NODE(_hw_usb
, OID_AUTO
, ugen
, CTLFLAG_RW
, 0, "USB generic");
128 SYSCTL_INT(_hw_usb_ugen
, OID_AUTO
, debug
, CTLFLAG_RW
, &ugen_debug
,
131 TUNABLE_INT("hw.usb.ugen.debug", &ugen_debug
);
138 ugen_transfer_setup(struct usb_fifo
*f
,
139 const struct usb_config
*setup
, uint8_t n_setup
)
141 struct usb_endpoint
*ep
= usb_fifo_softc(f
);
142 struct usb_device
*udev
= f
->udev
;
143 uint8_t iface_index
= ep
->iface_index
;
146 lockmgr(f
->priv_lock
, LK_RELEASE
);
149 * "usbd_transfer_setup()" can sleep so one needs to make a wrapper,
150 * exiting the mutex and checking things
152 error
= usbd_transfer_setup(udev
, &iface_index
, f
->xfer
,
153 setup
, n_setup
, f
, f
->priv_lock
);
156 if (f
->xfer
[0]->nframes
== 1) {
157 error
= usb_fifo_alloc_buffer(f
,
158 f
->xfer
[0]->max_data_length
, 2);
160 error
= usb_fifo_alloc_buffer(f
,
161 f
->xfer
[0]->max_frame_size
,
162 2 * f
->xfer
[0]->nframes
);
165 usbd_transfer_unsetup(f
->xfer
, n_setup
);
168 lockmgr(f
->priv_lock
, LK_EXCLUSIVE
);
174 ugen_open(struct usb_fifo
*f
, int fflags
)
176 struct usb_endpoint
*ep
= usb_fifo_softc(f
);
177 struct usb_endpoint_descriptor
*ed
= ep
->edesc
;
180 DPRINTFN(6, "flag=0x%x\n", fflags
);
182 lockmgr(f
->priv_lock
, LK_EXCLUSIVE
);
183 switch (usbd_get_speed(f
->udev
)) {
186 f
->nframes
= UGEN_HW_FRAMES
;
187 f
->bufsize
= UGEN_BULK_FS_BUFFER_SIZE
;
190 f
->nframes
= UGEN_HW_FRAMES
* 8;
191 f
->bufsize
= UGEN_BULK_HS_BUFFER_SIZE
;
195 type
= ed
->bmAttributes
& UE_XFERTYPE
;
196 if (type
== UE_INTERRUPT
) {
197 f
->bufsize
= 0; /* use "wMaxPacketSize" */
199 f
->timeout
= USB_NO_TIMEOUT
;
202 lockmgr(f
->priv_lock
, LK_RELEASE
);
208 ugen_close(struct usb_fifo
*f
, int fflags
)
210 DPRINTFN(6, "flag=0x%x\n", fflags
);
214 lockmgr(f
->priv_lock
, LK_EXCLUSIVE
);
215 usbd_transfer_stop(f
->xfer
[0]);
216 usbd_transfer_stop(f
->xfer
[1]);
217 lockmgr(f
->priv_lock
, LK_RELEASE
);
219 usbd_transfer_unsetup(f
->xfer
, 2);
220 usb_fifo_free_buffer(f
);
222 if (ugen_fs_uninit(f
)) {
223 /* ignore any errors - we are closing */
224 DPRINTFN(6, "no FIFOs\n");
229 ugen_open_pipe_write(struct usb_fifo
*f
)
231 struct usb_config usb_config
[2];
232 struct usb_endpoint
*ep
= usb_fifo_softc(f
);
233 struct usb_endpoint_descriptor
*ed
= ep
->edesc
;
235 KKASSERT(lockowned(f
->priv_lock
));
237 if (f
->xfer
[0] || f
->xfer
[1]) {
238 /* transfers are already opened */
241 memset(usb_config
, 0, sizeof(usb_config
));
243 usb_config
[1].type
= UE_CONTROL
;
244 usb_config
[1].endpoint
= 0;
245 usb_config
[1].direction
= UE_DIR_ANY
;
246 usb_config
[1].timeout
= 1000; /* 1 second */
247 usb_config
[1].interval
= 50;/* 50 milliseconds */
248 usb_config
[1].bufsize
= sizeof(struct usb_device_request
);
249 usb_config
[1].callback
= &ugen_write_clear_stall_callback
;
250 usb_config
[1].usb_mode
= USB_MODE_HOST
;
252 usb_config
[0].type
= ed
->bmAttributes
& UE_XFERTYPE
;
253 usb_config
[0].endpoint
= ed
->bEndpointAddress
& UE_ADDR
;
254 usb_config
[0].stream_id
= 0; /* XXX support more stream ID's */
255 usb_config
[0].direction
= UE_DIR_TX
;
256 usb_config
[0].interval
= USB_DEFAULT_INTERVAL
;
257 usb_config
[0].flags
.proxy_buffer
= 1;
258 usb_config
[0].usb_mode
= USB_MODE_DUAL
; /* both modes */
260 switch (ed
->bmAttributes
& UE_XFERTYPE
) {
264 usb_config
[0].flags
.force_short_xfer
= 1;
266 usb_config
[0].callback
= &ugen_ctrl_write_callback
;
267 usb_config
[0].timeout
= f
->timeout
;
268 usb_config
[0].frames
= 1;
269 usb_config
[0].bufsize
= f
->bufsize
;
270 if (ugen_transfer_setup(f
, usb_config
, 2)) {
273 /* first transfer does not clear stall */
278 usb_config
[0].flags
.short_xfer_ok
= 1;
279 usb_config
[0].bufsize
= 0; /* use default */
280 usb_config
[0].frames
= f
->nframes
;
281 usb_config
[0].callback
= &ugen_isoc_write_callback
;
282 usb_config
[0].timeout
= 0;
284 /* clone configuration */
285 usb_config
[1] = usb_config
[0];
287 if (ugen_transfer_setup(f
, usb_config
, 2)) {
298 ugen_open_pipe_read(struct usb_fifo
*f
)
300 struct usb_config usb_config
[2];
301 struct usb_endpoint
*ep
= usb_fifo_softc(f
);
302 struct usb_endpoint_descriptor
*ed
= ep
->edesc
;
304 KKASSERT(lockowned(f
->priv_lock
));
306 if (f
->xfer
[0] || f
->xfer
[1]) {
307 /* transfers are already opened */
310 memset(usb_config
, 0, sizeof(usb_config
));
312 usb_config
[1].type
= UE_CONTROL
;
313 usb_config
[1].endpoint
= 0;
314 usb_config
[1].direction
= UE_DIR_ANY
;
315 usb_config
[1].timeout
= 1000; /* 1 second */
316 usb_config
[1].interval
= 50;/* 50 milliseconds */
317 usb_config
[1].bufsize
= sizeof(struct usb_device_request
);
318 usb_config
[1].callback
= &ugen_read_clear_stall_callback
;
319 usb_config
[1].usb_mode
= USB_MODE_HOST
;
321 usb_config
[0].type
= ed
->bmAttributes
& UE_XFERTYPE
;
322 usb_config
[0].endpoint
= ed
->bEndpointAddress
& UE_ADDR
;
323 usb_config
[0].stream_id
= 0; /* XXX support more stream ID's */
324 usb_config
[0].direction
= UE_DIR_RX
;
325 usb_config
[0].interval
= USB_DEFAULT_INTERVAL
;
326 usb_config
[0].flags
.proxy_buffer
= 1;
327 usb_config
[0].usb_mode
= USB_MODE_DUAL
; /* both modes */
329 switch (ed
->bmAttributes
& UE_XFERTYPE
) {
333 usb_config
[0].flags
.short_xfer_ok
= 1;
335 usb_config
[0].timeout
= f
->timeout
;
336 usb_config
[0].frames
= 1;
337 usb_config
[0].callback
= &ugen_ctrl_read_callback
;
338 usb_config
[0].bufsize
= f
->bufsize
;
340 if (ugen_transfer_setup(f
, usb_config
, 2)) {
343 /* first transfer does not clear stall */
348 usb_config
[0].flags
.short_xfer_ok
= 1;
349 usb_config
[0].bufsize
= 0; /* use default */
350 usb_config
[0].frames
= f
->nframes
;
351 usb_config
[0].callback
= &ugen_isoc_read_callback
;
352 usb_config
[0].timeout
= 0;
354 /* clone configuration */
355 usb_config
[1] = usb_config
[0];
357 if (ugen_transfer_setup(f
, usb_config
, 2)) {
369 ugen_start_read(struct usb_fifo
*f
)
371 /* check that pipes are open */
372 if (ugen_open_pipe_read(f
)) {
374 usb_fifo_put_data_error(f
);
376 /* start transfers */
377 usbd_transfer_start(f
->xfer
[0]);
378 usbd_transfer_start(f
->xfer
[1]);
382 ugen_start_write(struct usb_fifo
*f
)
384 /* check that pipes are open */
385 if (ugen_open_pipe_write(f
)) {
387 usb_fifo_get_data_error(f
);
389 /* start transfers */
390 usbd_transfer_start(f
->xfer
[0]);
391 usbd_transfer_start(f
->xfer
[1]);
395 ugen_stop_io(struct usb_fifo
*f
)
398 usbd_transfer_stop(f
->xfer
[0]);
399 usbd_transfer_stop(f
->xfer
[1]);
403 ugen_ctrl_read_callback(struct usb_xfer
*xfer
, usb_error_t error
)
405 struct usb_fifo
*f
= usbd_xfer_softc(xfer
);
408 DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer
->actlen
, xfer
->aframes
);
410 switch (USB_GET_STATE(xfer
)) {
411 case USB_ST_TRANSFERRED
:
412 if (xfer
->actlen
== 0) {
413 if (f
->fifo_zlp
!= 4) {
417 * Throttle a little bit we have multiple ZLPs
420 xfer
->interval
= 64; /* ms */
427 usb_fifo_put_data(f
, xfer
->frbuffers
, 0,
432 usbd_transfer_start(f
->xfer
[1]);
435 USB_IF_POLL(&f
->free_q
, m
);
437 usbd_xfer_set_frame_len(xfer
, 0, usbd_xfer_max_len(xfer
));
438 usbd_transfer_submit(xfer
);
443 if (xfer
->error
!= USB_ERR_CANCELLED
) {
444 /* send a zero length packet to userland */
445 usb_fifo_put_data(f
, xfer
->frbuffers
, 0, 0, 1);
448 usbd_transfer_start(f
->xfer
[1]);
455 ugen_ctrl_write_callback(struct usb_xfer
*xfer
, usb_error_t error
)
457 struct usb_fifo
*f
= usbd_xfer_softc(xfer
);
458 usb_frlength_t actlen
;
460 DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer
->actlen
, xfer
->aframes
);
462 switch (USB_GET_STATE(xfer
)) {
464 case USB_ST_TRANSFERRED
:
466 * If writing is in stall, just jump to clear stall
467 * callback and solve the situation.
470 usbd_transfer_start(f
->xfer
[1]);
474 * Write data, setup and perform hardware transfer.
476 if (usb_fifo_get_data(f
, xfer
->frbuffers
, 0,
477 xfer
->max_data_length
, &actlen
, 0)) {
478 usbd_xfer_set_frame_len(xfer
, 0, actlen
);
479 usbd_transfer_submit(xfer
);
484 if (xfer
->error
!= USB_ERR_CANCELLED
) {
486 usbd_transfer_start(f
->xfer
[1]);
493 ugen_read_clear_stall_callback(struct usb_xfer
*xfer
, usb_error_t error
)
495 struct usb_fifo
*f
= usbd_xfer_softc(xfer
);
496 struct usb_xfer
*xfer_other
= f
->xfer
[0];
498 if (f
->flag_stall
== 0) {
502 if (usbd_clear_stall_callback(xfer
, xfer_other
)) {
503 DPRINTFN(5, "f=%p: stall cleared\n", f
);
505 usbd_transfer_start(xfer_other
);
510 ugen_write_clear_stall_callback(struct usb_xfer
*xfer
, usb_error_t error
)
512 struct usb_fifo
*f
= usbd_xfer_softc(xfer
);
513 struct usb_xfer
*xfer_other
= f
->xfer
[0];
515 if (f
->flag_stall
== 0) {
519 if (usbd_clear_stall_callback(xfer
, xfer_other
)) {
520 DPRINTFN(5, "f=%p: stall cleared\n", f
);
522 usbd_transfer_start(xfer_other
);
527 ugen_isoc_read_callback(struct usb_xfer
*xfer
, usb_error_t error
)
529 struct usb_fifo
*f
= usbd_xfer_softc(xfer
);
530 usb_frlength_t offset
;
533 DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer
->actlen
, xfer
->aframes
);
535 switch (USB_GET_STATE(xfer
)) {
536 case USB_ST_TRANSFERRED
:
538 DPRINTFN(6, "actlen=%d\n", xfer
->actlen
);
542 for (n
= 0; n
!= xfer
->aframes
; n
++) {
543 usb_fifo_put_data(f
, xfer
->frbuffers
, offset
,
544 xfer
->frlengths
[n
], 1);
545 offset
+= xfer
->max_frame_size
;
550 for (n
= 0; n
!= xfer
->nframes
; n
++) {
551 /* setup size for next transfer */
552 usbd_xfer_set_frame_len(xfer
, n
, xfer
->max_frame_size
);
554 usbd_transfer_submit(xfer
);
558 if (xfer
->error
== USB_ERR_CANCELLED
) {
566 ugen_isoc_write_callback(struct usb_xfer
*xfer
, usb_error_t error
)
568 struct usb_fifo
*f
= usbd_xfer_softc(xfer
);
569 usb_frlength_t actlen
;
570 usb_frlength_t offset
;
573 DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer
->actlen
, xfer
->aframes
);
575 switch (USB_GET_STATE(xfer
)) {
576 case USB_ST_TRANSFERRED
:
580 for (n
= 0; n
!= xfer
->nframes
; n
++) {
581 if (usb_fifo_get_data(f
, xfer
->frbuffers
, offset
,
582 xfer
->max_frame_size
, &actlen
, 1)) {
583 usbd_xfer_set_frame_len(xfer
, n
, actlen
);
590 for (; n
!= xfer
->nframes
; n
++) {
591 /* fill in zero frames */
592 usbd_xfer_set_frame_len(xfer
, n
, 0);
594 usbd_transfer_submit(xfer
);
598 if (xfer
->error
== USB_ERR_CANCELLED
) {
606 ugen_set_config(struct usb_fifo
*f
, uint8_t index
)
608 DPRINTFN(2, "index %u\n", index
);
610 if (f
->udev
->flags
.usb_mode
!= USB_MODE_HOST
) {
611 /* not possible in device side mode */
615 /* make sure all FIFO's are gone */
616 /* else there can be a deadlock */
617 if (ugen_fs_uninit(f
)) {
618 /* ignore any errors */
619 DPRINTFN(6, "no FIFOs\n");
622 if (usbd_start_set_config(f
->udev
, index
) != 0)
629 ugen_set_interface(struct usb_fifo
*f
,
630 uint8_t iface_index
, uint8_t alt_index
)
632 DPRINTFN(2, "%u, %u\n", iface_index
, alt_index
);
634 if (f
->udev
->flags
.usb_mode
!= USB_MODE_HOST
) {
635 /* not possible in device side mode */
638 /* make sure all FIFO's are gone */
639 /* else there can be a deadlock */
640 if (ugen_fs_uninit(f
)) {
641 /* ignore any errors */
642 DPRINTFN(6, "no FIFOs\n");
644 /* change setting - will free generic FIFOs, if any */
645 if (usbd_set_alt_interface_index(f
->udev
, iface_index
, alt_index
)) {
648 /* probe and attach */
649 if (usb_probe_and_attach(f
->udev
, iface_index
)) {
655 /*------------------------------------------------------------------------*
658 * This function will retrieve the complete configuration descriptor
659 * at the given index.
660 *------------------------------------------------------------------------*/
662 ugen_get_cdesc(struct usb_fifo
*f
, struct usb_gen_descriptor
*ugd
)
664 struct usb_config_descriptor
*cdesc
;
665 struct usb_device
*udev
= f
->udev
;
672 if (ugd
->ugd_data
== NULL
) {
673 /* userland pointer should not be zero */
676 if ((ugd
->ugd_config_index
== USB_UNCONFIG_INDEX
) ||
677 (ugd
->ugd_config_index
== udev
->curr_config_index
)) {
678 cdesc
= usbd_get_config_descriptor(udev
);
685 #if (USB_HAVE_FIXED_CONFIG == 0)
686 if (usbd_req_get_config_desc_full(udev
,
687 NULL
, &cdesc
, ugd
->ugd_config_index
)) {
692 /* configuration descriptor data is shared */
697 len
= UGETW(cdesc
->wTotalLength
);
698 if (len
> ugd
->ugd_maxlen
) {
699 len
= ugd
->ugd_maxlen
;
701 DPRINTFN(6, "len=%u\n", len
);
703 ugd
->ugd_actlen
= len
;
706 error
= copyout(cdesc
, ugd
->ugd_data
, len
);
709 usbd_free_config_desc(udev
, cdesc
);
715 * This function is called having the enumeration SX locked which
716 * protects the scratch area used.
719 ugen_get_sdesc(struct usb_fifo
*f
, struct usb_gen_descriptor
*ugd
)
725 ptr
= f
->udev
->scratch
.data
;
726 size
= sizeof(f
->udev
->scratch
.data
);
728 if (usbd_req_get_string_desc(f
->udev
, NULL
, ptr
,
729 size
, ugd
->ugd_lang_id
, ugd
->ugd_string_index
)) {
733 if (size
> ((uint8_t *)ptr
)[0]) {
734 size
= ((uint8_t *)ptr
)[0];
736 if (size
> ugd
->ugd_maxlen
) {
737 size
= ugd
->ugd_maxlen
;
739 ugd
->ugd_actlen
= size
;
742 error
= copyout(ptr
, ugd
->ugd_data
, size
);
747 /*------------------------------------------------------------------------*
748 * ugen_get_iface_driver
750 * This function generates an USB interface description for userland.
755 *------------------------------------------------------------------------*/
757 ugen_get_iface_driver(struct usb_fifo
*f
, struct usb_gen_descriptor
*ugd
)
759 struct usb_device
*udev
= f
->udev
;
760 struct usb_interface
*iface
;
770 if ((ugd
->ugd_data
== NULL
) || (ugd
->ugd_maxlen
== 0)) {
771 /* userland pointer should not be zero */
775 iface
= usbd_get_iface(udev
, ugd
->ugd_iface_index
);
776 if ((iface
== NULL
) || (iface
->idesc
== NULL
)) {
777 /* invalid interface index */
781 /* read out device nameunit string, if any */
782 if ((iface
->subdev
!= NULL
) &&
783 device_is_attached(iface
->subdev
) &&
784 (ptr
= device_get_nameunit(iface
->subdev
)) &&
785 (desc
= device_get_desc(iface
->subdev
))) {
787 /* print description */
788 ksnprintf(buf
, sizeof(buf
), "%s: <%s>", ptr
, desc
);
791 maxlen
= ugd
->ugd_maxlen
- 1;
796 /* update actual length, including terminating zero */
797 ugd
->ugd_actlen
= len
+ 1;
799 /* copy out interface description */
800 error
= copyout(buf
, ugd
->ugd_data
, ugd
->ugd_actlen
);
802 /* zero length string is default */
803 error
= copyout("", ugd
->ugd_data
, 1);
808 /*------------------------------------------------------------------------*
809 * usb_gen_fill_deviceinfo
811 * This function dumps information about an USB device to the
812 * structure pointed to by the "di" argument.
817 *------------------------------------------------------------------------*/
819 usb_gen_fill_deviceinfo(struct usb_fifo
*f
, struct usb_device_info
*di
)
821 struct usb_device
*udev
;
822 struct usb_device
*hub
;
826 bzero(di
, sizeof(di
[0]));
828 di
->udi_bus
= device_get_unit(udev
->bus
->bdev
);
829 di
->udi_addr
= udev
->address
;
830 di
->udi_index
= udev
->device_index
;
831 strlcpy(di
->udi_serial
, usb_get_serial(udev
), sizeof(di
->udi_serial
));
832 strlcpy(di
->udi_vendor
, usb_get_manufacturer(udev
), sizeof(di
->udi_vendor
));
833 strlcpy(di
->udi_product
, usb_get_product(udev
), sizeof(di
->udi_product
));
834 usb_printbcd(di
->udi_release
, sizeof(di
->udi_release
),
835 UGETW(udev
->ddesc
.bcdDevice
));
836 di
->udi_vendorNo
= UGETW(udev
->ddesc
.idVendor
);
837 di
->udi_productNo
= UGETW(udev
->ddesc
.idProduct
);
838 di
->udi_releaseNo
= UGETW(udev
->ddesc
.bcdDevice
);
839 di
->udi_class
= udev
->ddesc
.bDeviceClass
;
840 di
->udi_subclass
= udev
->ddesc
.bDeviceSubClass
;
841 di
->udi_protocol
= udev
->ddesc
.bDeviceProtocol
;
842 di
->udi_config_no
= udev
->curr_config_no
;
843 di
->udi_config_index
= udev
->curr_config_index
;
844 di
->udi_power
= udev
->flags
.self_powered
? 0 : udev
->power
;
845 di
->udi_speed
= udev
->speed
;
846 di
->udi_mode
= udev
->flags
.usb_mode
;
847 di
->udi_power_mode
= udev
->power_mode
;
848 di
->udi_suspended
= udev
->flags
.peer_suspended
;
850 hub
= udev
->parent_hub
;
852 di
->udi_hubaddr
= hub
->address
;
853 di
->udi_hubindex
= hub
->device_index
;
854 di
->udi_hubport
= udev
->port_no
;
859 /*------------------------------------------------------------------------*
865 *------------------------------------------------------------------------*/
867 ugen_check_request(struct usb_device
*udev
, struct usb_device_request
*req
)
869 struct usb_endpoint
*ep
;
873 * Avoid requests that would damage the bus integrity:
875 if (((req
->bmRequestType
== UT_WRITE_DEVICE
) &&
876 (req
->bRequest
== UR_SET_ADDRESS
)) ||
877 ((req
->bmRequestType
== UT_WRITE_DEVICE
) &&
878 (req
->bRequest
== UR_SET_CONFIG
)) ||
879 ((req
->bmRequestType
== UT_WRITE_INTERFACE
) &&
880 (req
->bRequest
== UR_SET_INTERFACE
))) {
882 * These requests can be useful for testing USB drivers.
884 error
= priv_check(curthread
, PRIV_DRIVER
);
890 * Special case - handle clearing of stall
892 if (req
->bmRequestType
== UT_WRITE_ENDPOINT
) {
894 ep
= usbd_get_ep_by_addr(udev
, req
->wIndex
[0]);
898 if ((req
->bRequest
== UR_CLEAR_FEATURE
) &&
899 (UGETW(req
->wValue
) == UF_ENDPOINT_HALT
)) {
900 usbd_clear_data_toggle(udev
, ep
);
903 /* TODO: add more checks to verify the interface index */
909 ugen_do_request(struct usb_fifo
*f
, struct usb_ctl_request
*ur
)
915 if (ugen_check_request(f
->udev
, &ur
->ucr_request
)) {
918 len
= UGETW(ur
->ucr_request
.wLength
);
920 /* check if "ucr_data" is valid */
922 if (ur
->ucr_data
== NULL
) {
926 /* do the USB request */
927 error
= usbd_do_request_flags
928 (f
->udev
, NULL
, &ur
->ucr_request
, ur
->ucr_data
,
929 (ur
->ucr_flags
& USB_SHORT_XFER_OK
) |
930 USB_USER_DATA_PTR
, &actlen
,
931 USB_DEFAULT_TIMEOUT
);
933 ur
->ucr_actlen
= actlen
;
941 /*------------------------------------------------------------------------
943 *------------------------------------------------------------------------*/
945 ugen_re_enumerate(struct usb_fifo
*f
)
947 struct usb_device
*udev
= f
->udev
;
951 * This request can be useful for testing USB drivers:
953 error
= priv_check(curthread
, PRIV_DRIVER
);
957 if (udev
->flags
.usb_mode
!= USB_MODE_HOST
) {
958 /* not possible in device side mode */
959 DPRINTFN(6, "device mode\n");
962 /* make sure all FIFO's are gone */
963 /* else there can be a deadlock */
964 if (ugen_fs_uninit(f
)) {
965 /* ignore any errors */
966 DPRINTFN(6, "no FIFOs\n");
968 /* start re-enumeration of device */
969 usbd_start_re_enumerate(udev
);
974 ugen_fs_uninit(struct usb_fifo
*f
)
976 if (f
->fs_xfer
== NULL
) {
979 usbd_transfer_unsetup(f
->fs_xfer
, f
->fs_ep_max
);
980 kfree(f
->fs_xfer
, M_USB
);
984 f
->flag_iscomplete
= 0;
985 usb_fifo_free_buffer(f
);
990 ugen_fs_get_complete(struct usb_fifo
*f
, uint8_t *pindex
)
994 USB_IF_DEQUEUE(&f
->used_q
, m
);
997 *pindex
= *((uint8_t *)(m
->cur_data_ptr
));
999 USB_IF_ENQUEUE(&f
->free_q
, m
);
1001 return (0); /* success */
1004 *pindex
= 0; /* fix compiler warning */
1006 f
->flag_iscomplete
= 0;
1008 return (1); /* failure */
1012 ugen_fs_set_complete(struct usb_fifo
*f
, uint8_t index
)
1016 USB_IF_DEQUEUE(&f
->free_q
, m
);
1019 /* can happen during close */
1020 DPRINTF("out of buffers\n");
1025 *((uint8_t *)(m
->cur_data_ptr
)) = index
;
1027 USB_IF_ENQUEUE(&f
->used_q
, m
);
1029 f
->flag_iscomplete
= 1;
1035 ugen_fs_copy_in(struct usb_fifo
*f
, uint8_t ep_index
)
1037 struct usb_device_request
*req
;
1038 struct usb_xfer
*xfer
;
1039 struct usb_fs_endpoint fs_ep
;
1040 void *uaddr
; /* userland pointer */
1042 usb_frlength_t offset
;
1049 if (ep_index
>= f
->fs_ep_max
) {
1052 xfer
= f
->fs_xfer
[ep_index
];
1056 lockmgr(f
->priv_lock
, LK_EXCLUSIVE
);
1057 if (usbd_transfer_pending(xfer
)) {
1058 lockmgr(f
->priv_lock
, LK_RELEASE
);
1059 return (EBUSY
); /* should not happen */
1061 lockmgr(f
->priv_lock
, LK_RELEASE
);
1063 error
= copyin(f
->fs_ep_ptr
+
1064 ep_index
, &fs_ep
, sizeof(fs_ep
));
1068 /* security checks */
1070 if (fs_ep
.nFrames
> xfer
->max_frame_count
) {
1071 xfer
->error
= USB_ERR_INVAL
;
1074 if (fs_ep
.nFrames
== 0) {
1075 xfer
->error
= USB_ERR_INVAL
;
1078 error
= copyin(fs_ep
.ppBuffer
,
1079 &uaddr
, sizeof(uaddr
));
1083 /* reset first frame */
1084 usbd_xfer_set_frame_offset(xfer
, 0, 0);
1086 if (xfer
->flags_int
.control_xfr
) {
1088 req
= xfer
->frbuffers
[0].buffer
;
1090 error
= copyin(fs_ep
.pLength
,
1091 &length
, sizeof(length
));
1095 if (length
!= sizeof(*req
)) {
1096 xfer
->error
= USB_ERR_INVAL
;
1100 error
= copyin(uaddr
, req
, length
);
1105 if (ugen_check_request(f
->udev
, req
)) {
1106 xfer
->error
= USB_ERR_INVAL
;
1109 usbd_xfer_set_frame_len(xfer
, 0, length
);
1111 /* Host mode only ! */
1112 if ((req
->bmRequestType
&
1113 (UT_READ
| UT_WRITE
)) == UT_READ
) {
1119 offset
= sizeof(*req
);
1122 /* Device and Host mode */
1123 if (USB_GET_DATA_ISREAD(xfer
)) {
1132 rem
= usbd_xfer_max_len(xfer
);
1133 xfer
->nframes
= fs_ep
.nFrames
;
1134 xfer
->timeout
= fs_ep
.timeout
;
1135 if (xfer
->timeout
> 65535) {
1136 xfer
->timeout
= 65535;
1138 if (fs_ep
.flags
& USB_FS_FLAG_SINGLE_SHORT_OK
)
1139 xfer
->flags
.short_xfer_ok
= 1;
1141 xfer
->flags
.short_xfer_ok
= 0;
1143 if (fs_ep
.flags
& USB_FS_FLAG_MULTI_SHORT_OK
)
1144 xfer
->flags
.short_frames_ok
= 1;
1146 xfer
->flags
.short_frames_ok
= 0;
1148 if (fs_ep
.flags
& USB_FS_FLAG_FORCE_SHORT
)
1149 xfer
->flags
.force_short_xfer
= 1;
1151 xfer
->flags
.force_short_xfer
= 0;
1153 if (fs_ep
.flags
& USB_FS_FLAG_CLEAR_STALL
)
1154 usbd_xfer_set_stall(xfer
);
1156 xfer
->flags
.stall_pipe
= 0;
1158 for (; n
!= xfer
->nframes
; n
++) {
1160 error
= copyin(fs_ep
.pLength
+ n
,
1161 &length
, sizeof(length
));
1165 usbd_xfer_set_frame_len(xfer
, n
, length
);
1168 xfer
->error
= USB_ERR_INVAL
;
1175 /* we need to know the source buffer */
1176 error
= copyin(fs_ep
.ppBuffer
+ n
,
1177 &uaddr
, sizeof(uaddr
));
1181 if (xfer
->flags_int
.isochronous_xfr
) {
1182 /* get kernel buffer address */
1183 kaddr
= xfer
->frbuffers
[0].buffer
;
1184 kaddr
= USB_ADD_BYTES(kaddr
, offset
);
1186 /* set current frame offset */
1187 usbd_xfer_set_frame_offset(xfer
, offset
, n
);
1189 /* get kernel buffer address */
1190 kaddr
= xfer
->frbuffers
[n
].buffer
;
1194 error
= copyin(uaddr
, kaddr
, length
);
1204 lockmgr(f
->priv_lock
, LK_EXCLUSIVE
);
1205 ugen_fs_set_complete(f
, ep_index
);
1206 lockmgr(f
->priv_lock
, LK_RELEASE
);
1211 ugen_fs_copy_out(struct usb_fifo
*f
, uint8_t ep_index
)
1213 struct usb_device_request
*req
;
1214 struct usb_xfer
*xfer
;
1215 struct usb_fs_endpoint fs_ep
;
1216 struct usb_fs_endpoint
*fs_ep_uptr
; /* userland ptr */
1217 void *uaddr
; /* userland ptr */
1219 usb_frlength_t offset
;
1227 if (ep_index
>= f
->fs_ep_max
)
1230 xfer
= f
->fs_xfer
[ep_index
];
1234 lockmgr(f
->priv_lock
, LK_EXCLUSIVE
);
1235 if (usbd_transfer_pending(xfer
)) {
1236 lockmgr(f
->priv_lock
, LK_RELEASE
);
1237 return (EBUSY
); /* should not happen */
1239 lockmgr(f
->priv_lock
, LK_RELEASE
);
1241 fs_ep_uptr
= f
->fs_ep_ptr
+ ep_index
;
1242 error
= copyin(fs_ep_uptr
, &fs_ep
, sizeof(fs_ep
));
1246 fs_ep
.status
= xfer
->error
;
1247 fs_ep
.aFrames
= xfer
->aframes
;
1248 fs_ep
.isoc_time_complete
= xfer
->isoc_time_complete
;
1252 if (xfer
->flags_int
.control_xfr
) {
1253 req
= xfer
->frbuffers
[0].buffer
;
1255 /* Host mode only ! */
1256 if ((req
->bmRequestType
& (UT_READ
| UT_WRITE
)) == UT_READ
) {
1261 if (xfer
->nframes
== 0)
1262 n
= 0; /* should never happen */
1266 /* Device and Host mode */
1267 if (USB_GET_DATA_ISREAD(xfer
)) {
1275 /* Update lengths and copy out data */
1277 rem
= usbd_xfer_max_len(xfer
);
1280 for (; n
!= xfer
->nframes
; n
++) {
1282 /* get initial length into "temp" */
1283 error
= copyin(fs_ep
.pLength
+ n
,
1284 &temp
, sizeof(temp
));
1289 /* the userland length has been corrupted */
1290 DPRINTF("corrupt userland length "
1291 "%u > %u\n", temp
, rem
);
1292 fs_ep
.status
= USB_ERR_INVAL
;
1297 /* get actual transfer length */
1298 length
= xfer
->frlengths
[n
];
1299 if (length
> temp
) {
1301 fs_ep
.status
= USB_ERR_INVAL
;
1302 DPRINTF("data overflow %u > %u\n",
1308 /* we need to know the destination buffer */
1309 error
= copyin(fs_ep
.ppBuffer
+ n
,
1310 &uaddr
, sizeof(uaddr
));
1314 if (xfer
->flags_int
.isochronous_xfr
) {
1315 /* only one frame buffer */
1316 kaddr
= USB_ADD_BYTES(
1317 xfer
->frbuffers
[0].buffer
, offset
);
1319 /* multiple frame buffers */
1320 kaddr
= xfer
->frbuffers
[n
].buffer
;
1324 error
= copyout(kaddr
, uaddr
, length
);
1330 * Update offset according to initial length, which is
1331 * needed by isochronous transfers!
1336 error
= copyout(&length
,
1337 fs_ep
.pLength
+ n
, sizeof(length
));
1344 /* update "aFrames" */
1345 error
= copyout(&fs_ep
.aFrames
, &fs_ep_uptr
->aFrames
,
1346 sizeof(fs_ep
.aFrames
));
1350 /* update "isoc_time_complete" */
1351 error
= copyout(&fs_ep
.isoc_time_complete
,
1352 &fs_ep_uptr
->isoc_time_complete
,
1353 sizeof(fs_ep
.isoc_time_complete
));
1356 /* update "status" */
1357 error
= copyout(&fs_ep
.status
, &fs_ep_uptr
->status
,
1358 sizeof(fs_ep
.status
));
1364 ugen_fifo_in_use(struct usb_fifo
*f
, int fflags
)
1366 struct usb_fifo
*f_rx
;
1367 struct usb_fifo
*f_tx
;
1369 f_rx
= f
->udev
->fifo
[(f
->fifo_index
& ~1) + USB_FIFO_RX
];
1370 f_tx
= f
->udev
->fifo
[(f
->fifo_index
& ~1) + USB_FIFO_TX
];
1372 if ((fflags
& FREAD
) && f_rx
&&
1373 (f_rx
->xfer
[0] || f_rx
->xfer
[1])) {
1374 return (1); /* RX FIFO in use */
1376 if ((fflags
& FWRITE
) && f_tx
&&
1377 (f_tx
->xfer
[0] || f_tx
->xfer
[1])) {
1378 return (1); /* TX FIFO in use */
1380 return (0); /* not in use */
1384 ugen_ioctl(struct usb_fifo
*f
, u_long cmd
, void *addr
, int fflags
)
1386 struct usb_config usb_config
[1];
1387 struct usb_device_request req
;
1389 struct usb_fs_complete
*pcomp
;
1390 struct usb_fs_start
*pstart
;
1391 struct usb_fs_stop
*pstop
;
1392 struct usb_fs_open
*popen
;
1393 struct usb_fs_open_stream
*popen_stream
;
1394 struct usb_fs_close
*pclose
;
1395 struct usb_fs_clear_stall_sync
*pstall
;
1398 struct usb_endpoint
*ep
;
1399 struct usb_endpoint_descriptor
*ed
;
1400 struct usb_xfer
*xfer
;
1402 uint8_t iface_index
;
1409 DPRINTFN(6, "cmd=0x%08lx\n", cmd
);
1412 case USB_FS_COMPLETE
:
1413 lockmgr(f
->priv_lock
, LK_EXCLUSIVE
);
1414 error
= ugen_fs_get_complete(f
, &ep_index
);
1415 lockmgr(f
->priv_lock
, LK_RELEASE
);
1421 u
.pcomp
->ep_index
= ep_index
;
1422 error
= ugen_fs_copy_out(f
, u
.pcomp
->ep_index
);
1426 error
= ugen_fs_copy_in(f
, u
.pstart
->ep_index
);
1429 lockmgr(f
->priv_lock
, LK_EXCLUSIVE
);
1430 xfer
= f
->fs_xfer
[u
.pstart
->ep_index
];
1431 usbd_transfer_start(xfer
);
1432 lockmgr(f
->priv_lock
, LK_RELEASE
);
1436 if (u
.pstop
->ep_index
>= f
->fs_ep_max
) {
1440 lockmgr(f
->priv_lock
, LK_EXCLUSIVE
);
1441 xfer
= f
->fs_xfer
[u
.pstart
->ep_index
];
1442 if (usbd_transfer_pending(xfer
)) {
1443 usbd_transfer_stop(xfer
);
1445 * Check if the USB transfer was stopped
1446 * before it was even started. Else a cancel
1447 * callback will be pending.
1449 if (!xfer
->flags_int
.transferring
) {
1450 ugen_fs_set_complete(xfer
->priv_sc
,
1451 USB_P2U(xfer
->priv_fifo
));
1454 lockmgr(f
->priv_lock
, LK_RELEASE
);
1458 case USB_FS_OPEN_STREAM
:
1459 if (u
.popen
->ep_index
>= f
->fs_ep_max
) {
1463 if (f
->fs_xfer
[u
.popen
->ep_index
] != NULL
) {
1467 if (u
.popen
->max_bufsize
> USB_FS_MAX_BUFSIZE
) {
1468 u
.popen
->max_bufsize
= USB_FS_MAX_BUFSIZE
;
1470 if (u
.popen
->max_frames
& USB_FS_MAX_FRAMES_PRE_SCALE
) {
1472 u
.popen
->max_frames
&= ~USB_FS_MAX_FRAMES_PRE_SCALE
;
1476 if (u
.popen
->max_frames
> USB_FS_MAX_FRAMES
) {
1477 u
.popen
->max_frames
= USB_FS_MAX_FRAMES
;
1480 if (u
.popen
->max_frames
== 0) {
1484 ep
= usbd_get_ep_by_addr(f
->udev
, u
.popen
->ep_no
);
1494 iface_index
= ep
->iface_index
;
1496 memset(usb_config
, 0, sizeof(usb_config
));
1498 usb_config
[0].type
= ed
->bmAttributes
& UE_XFERTYPE
;
1499 usb_config
[0].endpoint
= ed
->bEndpointAddress
& UE_ADDR
;
1500 usb_config
[0].direction
= ed
->bEndpointAddress
& (UE_DIR_OUT
| UE_DIR_IN
);
1501 usb_config
[0].interval
= USB_DEFAULT_INTERVAL
;
1502 usb_config
[0].flags
.proxy_buffer
= 1;
1504 usb_config
[0].flags
.pre_scale_frames
= 1;
1505 usb_config
[0].callback
= &ugen_ctrl_fs_callback
;
1506 usb_config
[0].timeout
= 0; /* no timeout */
1507 usb_config
[0].frames
= u
.popen
->max_frames
;
1508 usb_config
[0].bufsize
= u
.popen
->max_bufsize
;
1509 usb_config
[0].usb_mode
= USB_MODE_DUAL
; /* both modes */
1510 if (cmd
== USB_FS_OPEN_STREAM
)
1511 usb_config
[0].stream_id
= u
.popen_stream
->stream_id
;
1513 if (usb_config
[0].type
== UE_CONTROL
) {
1514 if (f
->udev
->flags
.usb_mode
!= USB_MODE_HOST
) {
1520 isread
= ((usb_config
[0].endpoint
&
1521 (UE_DIR_IN
| UE_DIR_OUT
)) == UE_DIR_IN
);
1523 if (f
->udev
->flags
.usb_mode
!= USB_MODE_HOST
) {
1526 /* check permissions */
1528 if (!(fflags
& FREAD
)) {
1533 if (!(fflags
& FWRITE
)) {
1539 error
= usbd_transfer_setup(f
->udev
, &iface_index
,
1540 f
->fs_xfer
+ u
.popen
->ep_index
, usb_config
, 1,
1543 /* update maximums */
1544 u
.popen
->max_packet_length
=
1545 f
->fs_xfer
[u
.popen
->ep_index
]->max_frame_size
;
1546 u
.popen
->max_bufsize
=
1547 f
->fs_xfer
[u
.popen
->ep_index
]->max_data_length
;
1548 /* update number of frames */
1549 u
.popen
->max_frames
=
1550 f
->fs_xfer
[u
.popen
->ep_index
]->nframes
;
1551 /* store index of endpoint */
1552 f
->fs_xfer
[u
.popen
->ep_index
]->priv_fifo
=
1553 ((uint8_t *)0) + u
.popen
->ep_index
;
1560 if (u
.pclose
->ep_index
>= f
->fs_ep_max
) {
1564 if (f
->fs_xfer
[u
.pclose
->ep_index
] == NULL
) {
1568 usbd_transfer_unsetup(f
->fs_xfer
+ u
.pclose
->ep_index
, 1);
1571 case USB_FS_CLEAR_STALL_SYNC
:
1572 if (u
.pstall
->ep_index
>= f
->fs_ep_max
) {
1576 if (f
->fs_xfer
[u
.pstall
->ep_index
] == NULL
) {
1580 if (f
->udev
->flags
.usb_mode
!= USB_MODE_HOST
) {
1584 lockmgr(f
->priv_lock
, LK_EXCLUSIVE
);
1585 error
= usbd_transfer_pending(f
->fs_xfer
[u
.pstall
->ep_index
]);
1586 lockmgr(f
->priv_lock
, LK_RELEASE
);
1591 ep
= f
->fs_xfer
[u
.pstall
->ep_index
]->endpoint
;
1593 /* setup a clear-stall packet */
1594 req
.bmRequestType
= UT_WRITE_ENDPOINT
;
1595 req
.bRequest
= UR_CLEAR_FEATURE
;
1596 USETW(req
.wValue
, UF_ENDPOINT_HALT
);
1597 req
.wIndex
[0] = ep
->edesc
->bEndpointAddress
;
1599 USETW(req
.wLength
, 0);
1601 error
= usbd_do_request(f
->udev
, NULL
, &req
, NULL
);
1603 usbd_clear_data_toggle(f
->udev
, ep
);
1614 DPRINTFN(6, "error=%d\n", error
);
1620 ugen_set_short_xfer(struct usb_fifo
*f
, void *addr
)
1629 if (f
->flag_short
== t
) {
1630 /* same value like before - accept */
1633 if (f
->xfer
[0] || f
->xfer
[1]) {
1634 /* cannot change this during transfer */
1642 ugen_set_timeout(struct usb_fifo
*f
, void *addr
)
1644 f
->timeout
= *(int *)addr
;
1645 if (f
->timeout
> 65535) {
1646 /* limit user input */
1653 ugen_get_frame_size(struct usb_fifo
*f
, void *addr
)
1656 *(int *)addr
= f
->xfer
[0]->max_frame_size
;
1664 ugen_set_buffer_size(struct usb_fifo
*f
, void *addr
)
1668 if (*(int *)addr
< 0)
1669 t
= 0; /* use "wMaxPacketSize" */
1670 else if (*(int *)addr
< (256 * 1024))
1675 if (f
->bufsize
== t
) {
1676 /* same value like before - accept */
1679 if (f
->xfer
[0] || f
->xfer
[1]) {
1680 /* cannot change this during transfer */
1688 ugen_get_buffer_size(struct usb_fifo
*f
, void *addr
)
1690 *(int *)addr
= f
->bufsize
;
1695 ugen_get_iface_desc(struct usb_fifo
*f
,
1696 struct usb_interface_descriptor
*idesc
)
1698 struct usb_interface
*iface
;
1700 iface
= usbd_get_iface(f
->udev
, f
->iface_index
);
1701 if (iface
&& iface
->idesc
) {
1702 *idesc
= *(iface
->idesc
);
1710 ugen_get_endpoint_desc(struct usb_fifo
*f
,
1711 struct usb_endpoint_descriptor
*ed
)
1713 struct usb_endpoint
*ep
;
1715 ep
= usb_fifo_softc(f
);
1717 if (ep
&& ep
->edesc
) {
1726 ugen_set_power_mode(struct usb_fifo
*f
, int mode
)
1728 struct usb_device
*udev
= f
->udev
;
1732 if ((udev
== NULL
) ||
1733 (udev
->parent_hub
== NULL
)) {
1736 err
= priv_check(curthread
, PRIV_DRIVER
);
1740 /* get old power mode */
1741 old_mode
= udev
->power_mode
;
1743 /* if no change, then just return */
1744 if (old_mode
== mode
)
1748 case USB_POWER_MODE_OFF
:
1749 if (udev
->flags
.usb_mode
== USB_MODE_HOST
&&
1750 udev
->re_enumerate_wait
== USB_RE_ENUM_DONE
) {
1751 udev
->re_enumerate_wait
= USB_RE_ENUM_PWR_OFF
;
1753 /* set power mode will wake up the explore thread */
1756 case USB_POWER_MODE_ON
:
1757 case USB_POWER_MODE_SAVE
:
1760 case USB_POWER_MODE_RESUME
:
1762 /* let USB-powerd handle resume */
1763 USB_BUS_LOCK(udev
->bus
);
1764 udev
->pwr_save
.write_refs
++;
1765 udev
->pwr_save
.last_xfer_time
= ticks
;
1766 USB_BUS_UNLOCK(udev
->bus
);
1768 /* set new power mode */
1769 usbd_set_power_mode(udev
, USB_POWER_MODE_SAVE
);
1771 /* wait for resume to complete */
1772 usb_pause_mtx(NULL
, hz
/ 4);
1774 /* clear write reference */
1775 USB_BUS_LOCK(udev
->bus
);
1776 udev
->pwr_save
.write_refs
--;
1777 USB_BUS_UNLOCK(udev
->bus
);
1779 mode
= USB_POWER_MODE_SAVE
;
1782 case USB_POWER_MODE_SUSPEND
:
1784 /* let USB-powerd handle suspend */
1785 USB_BUS_LOCK(udev
->bus
);
1786 udev
->pwr_save
.last_xfer_time
= ticks
- (256 * hz
);
1787 USB_BUS_UNLOCK(udev
->bus
);
1789 mode
= USB_POWER_MODE_SAVE
;
1797 return (ENXIO
); /* I/O failure */
1799 /* if we are powered off we need to re-enumerate first */
1800 if (old_mode
== USB_POWER_MODE_OFF
) {
1801 if (udev
->flags
.usb_mode
== USB_MODE_HOST
&&
1802 udev
->re_enumerate_wait
== USB_RE_ENUM_DONE
) {
1803 udev
->re_enumerate_wait
= USB_RE_ENUM_START
;
1805 /* set power mode will wake up the explore thread */
1808 /* set new power mode */
1809 usbd_set_power_mode(udev
, mode
);
1811 return (0); /* success */
1815 ugen_get_power_mode(struct usb_fifo
*f
)
1817 struct usb_device
*udev
= f
->udev
;
1820 return (USB_POWER_MODE_ON
);
1822 return (udev
->power_mode
);
1826 ugen_get_port_path(struct usb_fifo
*f
, struct usb_device_port_path
*dpp
)
1828 struct usb_device
*udev
= f
->udev
;
1829 struct usb_device
*next
;
1830 unsigned int nlevel
= 0;
1835 dpp
->udp_bus
= device_get_unit(udev
->bus
->bdev
);
1836 dpp
->udp_index
= udev
->device_index
;
1838 /* count port levels */
1840 while (next
->parent_hub
!= NULL
) {
1842 next
= next
->parent_hub
;
1845 /* check if too many levels */
1846 if (nlevel
> USB_DEVICE_PORT_PATH_MAX
)
1849 /* store total level of ports */
1850 dpp
->udp_port_level
= nlevel
;
1852 /* store port index array */
1854 while (next
->parent_hub
!= NULL
) {
1855 dpp
->udp_port_no
[--nlevel
] = next
->port_no
;
1856 next
= next
->parent_hub
;
1858 return (0); /* success */
1861 return (EINVAL
); /* failure */
1865 ugen_get_power_usage(struct usb_fifo
*f
)
1867 struct usb_device
*udev
= f
->udev
;
1872 return (udev
->power
);
1876 ugen_do_port_feature(struct usb_fifo
*f
, uint8_t port_no
,
1877 uint8_t set
, uint16_t feature
)
1879 struct usb_device
*udev
= f
->udev
;
1880 struct usb_hub
*hub
;
1883 err
= priv_check(curthread
, PRIV_DRIVER
);
1890 if ((udev
== NULL
) ||
1891 (udev
->hub
== NULL
)) {
1896 if (port_no
> hub
->nports
) {
1900 err
= usbd_req_set_port_feature(udev
,
1901 NULL
, port_no
, feature
);
1903 err
= usbd_req_clear_port_feature(udev
,
1904 NULL
, port_no
, feature
);
1907 return (ENXIO
); /* failure */
1909 return (0); /* success */
1913 ugen_iface_ioctl(struct usb_fifo
*f
, u_long cmd
, void *addr
, int fflags
)
1915 struct usb_fifo
*f_rx
;
1916 struct usb_fifo
*f_tx
;
1919 f_rx
= f
->udev
->fifo
[(f
->fifo_index
& ~1) + USB_FIFO_RX
];
1920 f_tx
= f
->udev
->fifo
[(f
->fifo_index
& ~1) + USB_FIFO_TX
];
1923 case USB_SET_RX_SHORT_XFER
:
1924 if (fflags
& FREAD
) {
1925 error
= ugen_set_short_xfer(f_rx
, addr
);
1931 case USB_SET_TX_FORCE_SHORT
:
1932 if (fflags
& FWRITE
) {
1933 error
= ugen_set_short_xfer(f_tx
, addr
);
1939 case USB_SET_RX_TIMEOUT
:
1940 if (fflags
& FREAD
) {
1941 error
= ugen_set_timeout(f_rx
, addr
);
1947 case USB_SET_TX_TIMEOUT
:
1948 if (fflags
& FWRITE
) {
1949 error
= ugen_set_timeout(f_tx
, addr
);
1955 case USB_GET_RX_FRAME_SIZE
:
1956 if (fflags
& FREAD
) {
1957 error
= ugen_get_frame_size(f_rx
, addr
);
1963 case USB_GET_TX_FRAME_SIZE
:
1964 if (fflags
& FWRITE
) {
1965 error
= ugen_get_frame_size(f_tx
, addr
);
1971 case USB_SET_RX_BUFFER_SIZE
:
1972 if (fflags
& FREAD
) {
1973 error
= ugen_set_buffer_size(f_rx
, addr
);
1979 case USB_SET_TX_BUFFER_SIZE
:
1980 if (fflags
& FWRITE
) {
1981 error
= ugen_set_buffer_size(f_tx
, addr
);
1987 case USB_GET_RX_BUFFER_SIZE
:
1988 if (fflags
& FREAD
) {
1989 error
= ugen_get_buffer_size(f_rx
, addr
);
1995 case USB_GET_TX_BUFFER_SIZE
:
1996 if (fflags
& FWRITE
) {
1997 error
= ugen_get_buffer_size(f_tx
, addr
);
2003 case USB_GET_RX_INTERFACE_DESC
:
2004 if (fflags
& FREAD
) {
2005 error
= ugen_get_iface_desc(f_rx
, addr
);
2011 case USB_GET_TX_INTERFACE_DESC
:
2012 if (fflags
& FWRITE
) {
2013 error
= ugen_get_iface_desc(f_tx
, addr
);
2019 case USB_GET_RX_ENDPOINT_DESC
:
2020 if (fflags
& FREAD
) {
2021 error
= ugen_get_endpoint_desc(f_rx
, addr
);
2027 case USB_GET_TX_ENDPOINT_DESC
:
2028 if (fflags
& FWRITE
) {
2029 error
= ugen_get_endpoint_desc(f_tx
, addr
);
2035 case USB_SET_RX_STALL_FLAG
:
2036 if ((fflags
& FREAD
) && (*(int *)addr
)) {
2037 f_rx
->flag_stall
= 1;
2041 case USB_SET_TX_STALL_FLAG
:
2042 if ((fflags
& FWRITE
) && (*(int *)addr
)) {
2043 f_tx
->flag_stall
= 1;
2055 ugen_ioctl_post(struct usb_fifo
*f
, u_long cmd
, void *addr
, int fflags
)
2058 struct usb_interface_descriptor
*idesc
;
2059 struct usb_alt_interface
*ai
;
2060 struct usb_device_descriptor
*ddesc
;
2061 struct usb_config_descriptor
*cdesc
;
2062 struct usb_device_stats
*stat
;
2063 struct usb_fs_init
*pinit
;
2064 struct usb_fs_uninit
*puninit
;
2065 struct usb_device_port_path
*dpp
;
2070 struct usb_device_descriptor
*dtemp
;
2071 struct usb_config_descriptor
*ctemp
;
2072 struct usb_interface
*iface
;
2078 DPRINTFN(6, "cmd=0x%08lx\n", cmd
);
2082 usb_needs_explore_all();
2086 if (!(fflags
& FWRITE
)) {
2090 usb_debug
= *(int *)addr
;
2093 case USB_GET_CONFIG
:
2094 *(int *)addr
= f
->udev
->curr_config_index
;
2097 case USB_SET_CONFIG
:
2098 if (!(fflags
& FWRITE
)) {
2102 error
= ugen_set_config(f
, *(int *)addr
);
2105 case USB_GET_ALTINTERFACE
:
2106 iface
= usbd_get_iface(f
->udev
,
2107 u
.ai
->uai_interface_index
);
2108 if (iface
&& iface
->idesc
) {
2109 u
.ai
->uai_alt_index
= iface
->alt_index
;
2115 case USB_SET_ALTINTERFACE
:
2116 if (!(fflags
& FWRITE
)) {
2120 error
= ugen_set_interface(f
,
2121 u
.ai
->uai_interface_index
, u
.ai
->uai_alt_index
);
2124 case USB_GET_DEVICE_DESC
:
2125 dtemp
= usbd_get_device_descriptor(f
->udev
);
2133 case USB_GET_CONFIG_DESC
:
2134 ctemp
= usbd_get_config_descriptor(f
->udev
);
2142 case USB_GET_FULL_DESC
:
2143 error
= ugen_get_cdesc(f
, addr
);
2146 case USB_GET_STRING_DESC
:
2147 error
= ugen_get_sdesc(f
, addr
);
2150 case USB_GET_IFACE_DRIVER
:
2151 error
= ugen_get_iface_driver(f
, addr
);
2155 case USB_DO_REQUEST
:
2156 if (!(fflags
& FWRITE
)) {
2160 error
= ugen_do_request(f
, addr
);
2163 case USB_DEVICEINFO
:
2164 case USB_GET_DEVICEINFO
:
2165 error
= usb_gen_fill_deviceinfo(f
, addr
);
2168 case USB_DEVICESTATS
:
2169 for (n
= 0; n
!= 4; n
++) {
2171 u
.stat
->uds_requests_fail
[n
] =
2172 f
->udev
->bus
->stats_err
.uds_requests
[n
];
2174 u
.stat
->uds_requests_ok
[n
] =
2175 f
->udev
->bus
->stats_ok
.uds_requests
[n
];
2179 case USB_DEVICEENUMERATE
:
2180 error
= ugen_re_enumerate(f
);
2183 case USB_GET_PLUGTIME
:
2184 *u
.ptime
= f
->udev
->plugtime
;
2187 case USB_CLAIM_INTERFACE
:
2188 case USB_RELEASE_INTERFACE
:
2192 case USB_IFACE_DRIVER_ACTIVE
:
2196 iface
= usbd_get_iface(f
->udev
, n
);
2198 if (iface
&& iface
->subdev
)
2204 case USB_IFACE_DRIVER_DETACH
:
2206 error
= priv_check(curthread
, PRIV_DRIVER
);
2213 if (n
== USB_IFACE_INDEX_ANY
) {
2219 * Detach the currently attached driver.
2221 usb_detach_device(f
->udev
, n
, 0);
2224 * Set parent to self, this should keep attach away
2225 * until the next set configuration event.
2227 usbd_set_parent_iface(f
->udev
, n
, n
);
2230 case USB_SET_POWER_MODE
:
2231 error
= ugen_set_power_mode(f
, *u
.pint
);
2234 case USB_GET_POWER_MODE
:
2235 *u
.pint
= ugen_get_power_mode(f
);
2238 case USB_GET_DEV_PORT_PATH
:
2239 error
= ugen_get_port_path(f
, u
.dpp
);
2242 case USB_GET_POWER_USAGE
:
2243 *u
.pint
= ugen_get_power_usage(f
);
2246 case USB_SET_PORT_ENABLE
:
2247 error
= ugen_do_port_feature(f
,
2248 *u
.pint
, 1, UHF_PORT_ENABLE
);
2251 case USB_SET_PORT_DISABLE
:
2252 error
= ugen_do_port_feature(f
,
2253 *u
.pint
, 0, UHF_PORT_ENABLE
);
2257 /* verify input parameters */
2258 if (u
.pinit
->pEndpoints
== NULL
) {
2262 if (u
.pinit
->ep_index_max
> 127) {
2266 if (u
.pinit
->ep_index_max
== 0) {
2270 if (f
->fs_xfer
!= NULL
) {
2274 if (f
->dev_ep_index
!= 0) {
2278 if (ugen_fifo_in_use(f
, fflags
)) {
2282 error
= usb_fifo_alloc_buffer(f
, 1, u
.pinit
->ep_index_max
);
2286 f
->fs_xfer
= kmalloc(sizeof(f
->fs_xfer
[0]) *
2287 u
.pinit
->ep_index_max
, M_USB
, M_WAITOK
| M_ZERO
);
2288 if (f
->fs_xfer
== NULL
) {
2289 usb_fifo_free_buffer(f
);
2293 f
->fs_ep_max
= u
.pinit
->ep_index_max
;
2294 f
->fs_ep_ptr
= u
.pinit
->pEndpoints
;
2298 if (u
.puninit
->dummy
!= 0) {
2302 error
= ugen_fs_uninit(f
);
2306 lockmgr(f
->priv_lock
, LK_EXCLUSIVE
);
2307 error
= ugen_iface_ioctl(f
, cmd
, addr
, fflags
);
2308 lockmgr(f
->priv_lock
, LK_RELEASE
);
2311 DPRINTFN(6, "error=%d\n", error
);
2316 ugen_ctrl_fs_callback(struct usb_xfer
*xfer
, usb_error_t error
)
2318 ; /* workaround for a bug in "indent" */
2320 DPRINTF("st=%u alen=%u aframes=%u\n",
2321 USB_GET_STATE(xfer
), xfer
->actlen
, xfer
->aframes
);
2323 switch (USB_GET_STATE(xfer
)) {
2325 usbd_transfer_submit(xfer
);
2328 ugen_fs_set_complete(xfer
->priv_sc
, USB_P2U(xfer
->priv_fifo
));
2332 #endif /* USB_HAVE_UGEN */