1 /* $NetBSD: ugen.c,v 1.107 2009/12/23 01:04:45 pooka Exp $ */
4 * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology.
11 * Copyright (c) 2006 BBN Technologies Corp. All rights reserved.
12 * Effort sponsored in part by the Defense Advanced Research Projects
13 * Agency (DARPA) and the Department of the Interior National Business
14 * Center under agreement number NBCHC050166.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
25 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.107 2009/12/23 01:04:45 pooka Exp $");
42 #include "opt_compat_netbsd.h"
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/malloc.h>
48 #if defined(__NetBSD__) || defined(__OpenBSD__)
49 #include <sys/device.h>
50 #include <sys/ioctl.h>
51 #elif defined(__FreeBSD__)
52 #include <sys/module.h>
54 #include <sys/ioccom.h>
56 #include <sys/fcntl.h>
57 #include <sys/filio.h>
62 #include <sys/select.h>
64 #include <sys/vnode.h>
67 #include <dev/usb/usb.h>
68 #include <dev/usb/usbdi.h>
69 #include <dev/usb/usbdi_util.h>
72 #define DPRINTF(x) if (ugendebug) logprintf x
73 #define DPRINTFN(n,x) if (ugendebug>(n)) logprintf x
80 #define UGEN_CHUNK 128 /* chunk size for read */
81 #define UGEN_IBSIZE 1020 /* buffer size */
82 #define UGEN_BBSIZE 1024
84 #define UGEN_NISOFRAMES 500 /* 0.5 seconds worth */
85 #define UGEN_NISOREQS 6 /* number of outstanding xfer requests */
86 #define UGEN_NISORFRMS 4 /* number of frames (miliseconds) per req */
88 #define UGEN_BULK_RA_WB_BUFSIZE 16384 /* default buffer size */
89 #define UGEN_BULK_RA_WB_BUFMAX (1 << 20) /* maximum allowed buffer */
91 struct ugen_endpoint
{
92 struct ugen_softc
*sc
;
93 usb_endpoint_descriptor_t
*edesc
;
94 usbd_interface_handle iface
;
96 #define UGEN_ASLP 0x02 /* waiting for data */
97 #define UGEN_SHORT_OK 0x04 /* short xfers are OK */
98 #define UGEN_BULK_RA 0x08 /* in bulk read-ahead mode */
99 #define UGEN_BULK_WB 0x10 /* in bulk write-behind mode */
100 #define UGEN_RA_WB_STOP 0x20 /* RA/WB xfer is stopped (buffer full/empty) */
101 usbd_pipe_handle pipeh
;
104 u_char
*ibuf
; /* start of buffer (circular for isoc) */
105 u_char
*fill
; /* location for input (isoc) */
106 u_char
*limit
; /* end of circular buffer (isoc) */
107 u_char
*cur
; /* current read location (isoc) */
109 u_int32_t ra_wb_bufsize
; /* requested size for RA/WB buffer */
110 u_int32_t ra_wb_reqsize
; /* requested xfer length for RA/WB */
111 u_int32_t ra_wb_used
; /* how much is in buffer */
112 u_int32_t ra_wb_xferlen
; /* current xfer length for RA/WB */
113 usbd_xfer_handle ra_wb_xfer
;
115 struct ugen_endpoint
*sce
;
116 usbd_xfer_handle xfer
;
118 u_int16_t sizes
[UGEN_NISORFRMS
];
119 } isoreqs
[UGEN_NISOREQS
];
123 USBBASEDEVICE sc_dev
; /* base device */
124 usbd_device_handle sc_udev
;
126 char sc_is_open
[USB_MAX_ENDPOINTS
];
127 struct ugen_endpoint sc_endpoints
[USB_MAX_ENDPOINTS
][2];
132 char sc_buffer
[UGEN_BBSIZE
];
136 #if defined(__NetBSD__)
137 dev_type_open(ugenopen
);
138 dev_type_close(ugenclose
);
139 dev_type_read(ugenread
);
140 dev_type_write(ugenwrite
);
141 dev_type_ioctl(ugenioctl
);
142 dev_type_poll(ugenpoll
);
143 dev_type_kqfilter(ugenkqfilter
);
145 const struct cdevsw ugen_cdevsw
= {
146 ugenopen
, ugenclose
, ugenread
, ugenwrite
, ugenioctl
,
147 nostop
, notty
, ugenpoll
, nommap
, ugenkqfilter
, D_OTHER
,
149 #elif defined(__OpenBSD__)
151 #elif defined(__FreeBSD__)
159 #define UGEN_CDEV_MAJOR 114
161 Static
struct cdevsw ugen_cdevsw
= {
163 /* close */ ugenclose
,
165 /* write */ ugenwrite
,
166 /* ioctl */ ugenioctl
,
169 /* strategy */ nostrategy
,
171 /* maj */ UGEN_CDEV_MAJOR
,
179 Static
void ugenintr(usbd_xfer_handle xfer
, usbd_private_handle addr
,
181 Static
void ugen_isoc_rintr(usbd_xfer_handle xfer
, usbd_private_handle addr
,
183 Static
void ugen_bulkra_intr(usbd_xfer_handle xfer
, usbd_private_handle addr
,
185 Static
void ugen_bulkwb_intr(usbd_xfer_handle xfer
, usbd_private_handle addr
,
187 Static
int ugen_do_read(struct ugen_softc
*, int, struct uio
*, int);
188 Static
int ugen_do_write(struct ugen_softc
*, int, struct uio
*, int);
189 Static
int ugen_do_ioctl(struct ugen_softc
*, int, u_long
,
190 void *, int, struct lwp
*);
191 Static
int ugen_set_config(struct ugen_softc
*sc
, int configno
);
192 Static usb_config_descriptor_t
*ugen_get_cdesc(struct ugen_softc
*sc
,
193 int index
, int *lenp
);
194 Static usbd_status
ugen_set_interface(struct ugen_softc
*, int, int);
195 Static
int ugen_get_alt_index(struct ugen_softc
*sc
, int ifaceidx
);
197 #define UGENUNIT(n) ((minor(n) >> 4) & 0xf)
198 #define UGENENDPOINT(n) (minor(n) & 0xf)
199 #define UGENDEV(u, e) (makedev(0, ((u) << 4) | (e)))
201 USB_DECLARE_DRIVER(ugen
);
203 /* toggle to control attach priority. -1 means "let autoconf decide" */
204 int ugen_override
= -1;
208 USB_MATCH_START(ugen
, uaa
);
211 if (ugen_override
!= -1)
212 override
= ugen_override
;
214 override
= match
->cf_flags
& 1;
217 return (UMATCH_HIGHEST
);
218 else if (uaa
->usegeneric
)
219 return (UMATCH_GENERIC
);
221 return (UMATCH_NONE
);
226 USB_ATTACH_START(ugen
, sc
, uaa
);
227 usbd_device_handle udev
;
235 devinfop
= usbd_devinfo_alloc(uaa
->device
, 0);
236 aprint_normal_dev(self
, "%s\n", devinfop
);
237 usbd_devinfo_free(devinfop
);
240 sc
->sc_udev
= udev
= uaa
->device
;
242 /* First set configuration index 0, the default one for ugen. */
243 err
= usbd_set_config_index(udev
, 0, 0);
245 aprint_error_dev(self
,
246 "setting configuration index 0 failed\n");
248 USB_ATTACH_ERROR_RETURN
;
250 conf
= usbd_get_config_descriptor(udev
)->bConfigurationValue
;
252 /* Set up all the local state for this configuration. */
253 err
= ugen_set_config(sc
, conf
);
255 aprint_error_dev(self
, "setting configuration %d failed\n",
258 USB_ATTACH_ERROR_RETURN
;
263 static int global_init_done
= 0;
264 if (!global_init_done
) {
265 cdevsw_add(&ugen_cdevsw
);
266 global_init_done
= 1;
270 for (i
= 0; i
< USB_MAX_ENDPOINTS
; i
++) {
271 for (dir
= OUT
; dir
<= IN
; dir
++) {
272 struct ugen_endpoint
*sce
;
274 sce
= &sc
->sc_endpoints
[i
][dir
];
279 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH
, sc
->sc_udev
,
282 if (!pmf_device_register(self
, NULL
, NULL
))
283 aprint_error_dev(self
, "couldn't establish power handler\n");
285 USB_ATTACH_SUCCESS_RETURN
;
289 ugen_set_config(struct ugen_softc
*sc
, int configno
)
291 usbd_device_handle dev
= sc
->sc_udev
;
292 usb_config_descriptor_t
*cdesc
;
293 usbd_interface_handle iface
;
294 usb_endpoint_descriptor_t
*ed
;
295 struct ugen_endpoint
*sce
;
296 u_int8_t niface
, nendpt
;
297 int ifaceno
, endptno
, endpt
;
301 DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
302 USBDEVNAME(sc
->sc_dev
), configno
, sc
));
305 * We start at 1, not 0, because we don't care whether the
306 * control endpoint is open or not. It is always present.
308 for (endptno
= 1; endptno
< USB_MAX_ENDPOINTS
; endptno
++)
309 if (sc
->sc_is_open
[endptno
]) {
311 ("ugen_set_config: %s - endpoint %d is open\n",
312 USBDEVNAME(sc
->sc_dev
), endptno
));
313 return (USBD_IN_USE
);
316 /* Avoid setting the current value. */
317 cdesc
= usbd_get_config_descriptor(dev
);
318 if (!cdesc
|| cdesc
->bConfigurationValue
!= configno
) {
319 err
= usbd_set_config_no(dev
, configno
, 1);
324 err
= usbd_interface_count(dev
, &niface
);
327 memset(sc
->sc_endpoints
, 0, sizeof sc
->sc_endpoints
);
328 for (ifaceno
= 0; ifaceno
< niface
; ifaceno
++) {
329 DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno
));
330 err
= usbd_device2interface_handle(dev
, ifaceno
, &iface
);
333 err
= usbd_endpoint_count(iface
, &nendpt
);
336 for (endptno
= 0; endptno
< nendpt
; endptno
++) {
337 ed
= usbd_interface2endpoint_descriptor(iface
,endptno
);
339 endpt
= ed
->bEndpointAddress
;
340 dir
= UE_GET_DIR(endpt
) == UE_DIR_IN
? IN
: OUT
;
341 sce
= &sc
->sc_endpoints
[UE_GET_ADDR(endpt
)][dir
];
342 DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x"
344 endptno
, endpt
, UE_GET_ADDR(endpt
),
345 UE_GET_DIR(endpt
), sce
));
351 return (USBD_NORMAL_COMPLETION
);
355 ugenopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
357 struct ugen_softc
*sc
;
358 int unit
= UGENUNIT(dev
);
359 int endpt
= UGENENDPOINT(dev
);
360 usb_endpoint_descriptor_t
*edesc
;
361 struct ugen_endpoint
*sce
;
364 usbd_xfer_handle xfer
;
368 USB_GET_SC_OPEN(ugen
, unit
, sc
);
370 DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
371 flag
, mode
, unit
, endpt
));
373 if (sc
== NULL
|| sc
->sc_dying
)
376 /* The control endpoint allows multiple opens. */
377 if (endpt
== USB_CONTROL_ENDPOINT
) {
378 sc
->sc_is_open
[USB_CONTROL_ENDPOINT
] = 1;
382 if (sc
->sc_is_open
[endpt
])
385 /* Make sure there are pipes for all directions. */
386 for (dir
= OUT
; dir
<= IN
; dir
++) {
387 if (flag
& (dir
== OUT
? FWRITE
: FREAD
)) {
388 sce
= &sc
->sc_endpoints
[endpt
][dir
];
389 if (sce
== 0 || sce
->edesc
== 0)
394 /* Actually open the pipes. */
395 /* XXX Should back out properly if it fails. */
396 for (dir
= OUT
; dir
<= IN
; dir
++) {
397 if (!(flag
& (dir
== OUT
? FWRITE
: FREAD
)))
399 sce
= &sc
->sc_endpoints
[endpt
][dir
];
401 sce
->timeout
= USBD_NO_TIMEOUT
;
402 DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
403 sc
, endpt
, dir
, sce
));
405 switch (edesc
->bmAttributes
& UE_XFERTYPE
) {
408 err
= usbd_open_pipe(sce
->iface
,
409 edesc
->bEndpointAddress
, 0, &sce
->pipeh
);
414 isize
= UGETW(edesc
->wMaxPacketSize
);
415 if (isize
== 0) /* shouldn't happen */
417 sce
->ibuf
= malloc(isize
, M_USBDEV
, M_WAITOK
);
418 DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
420 if (clalloc(&sce
->q
, UGEN_IBSIZE
, 0) == -1)
422 err
= usbd_open_pipe_intr(sce
->iface
,
423 edesc
->bEndpointAddress
,
424 USBD_SHORT_XFER_OK
, &sce
->pipeh
, sce
,
425 sce
->ibuf
, isize
, ugenintr
,
426 USBD_DEFAULT_INTERVAL
);
428 free(sce
->ibuf
, M_USBDEV
);
432 DPRINTFN(5, ("ugenopen: interrupt open done\n"));
435 err
= usbd_open_pipe(sce
->iface
,
436 edesc
->bEndpointAddress
, 0, &sce
->pipeh
);
439 sce
->ra_wb_bufsize
= UGEN_BULK_RA_WB_BUFSIZE
;
441 * Use request size for non-RA/WB transfers
444 sce
->ra_wb_reqsize
= UGEN_BBSIZE
;
449 isize
= UGETW(edesc
->wMaxPacketSize
);
450 if (isize
== 0) /* shouldn't happen */
452 sce
->ibuf
= malloc(isize
* UGEN_NISOFRAMES
,
454 sce
->cur
= sce
->fill
= sce
->ibuf
;
455 sce
->limit
= sce
->ibuf
+ isize
* UGEN_NISOFRAMES
;
456 DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n",
458 err
= usbd_open_pipe(sce
->iface
,
459 edesc
->bEndpointAddress
, 0, &sce
->pipeh
);
461 free(sce
->ibuf
, M_USBDEV
);
464 for(i
= 0; i
< UGEN_NISOREQS
; ++i
) {
465 sce
->isoreqs
[i
].sce
= sce
;
466 xfer
= usbd_alloc_xfer(sc
->sc_udev
);
469 sce
->isoreqs
[i
].xfer
= xfer
;
470 tbuf
= usbd_alloc_buffer
471 (xfer
, isize
* UGEN_NISORFRMS
);
476 sce
->isoreqs
[i
].dmabuf
= tbuf
;
477 for(j
= 0; j
< UGEN_NISORFRMS
; ++j
)
478 sce
->isoreqs
[i
].sizes
[j
] = isize
;
480 (xfer
, sce
->pipeh
, &sce
->isoreqs
[i
],
481 sce
->isoreqs
[i
].sizes
,
482 UGEN_NISORFRMS
, USBD_NO_COPY
,
484 (void)usbd_transfer(xfer
);
486 DPRINTFN(5, ("ugenopen: isoc open done\n"));
489 while (--i
>= 0) /* implicit buffer free */
490 usbd_free_xfer(sce
->isoreqs
[i
].xfer
);
493 sce
->timeout
= USBD_DEFAULT_TIMEOUT
;
497 sc
->sc_is_open
[endpt
] = 1;
502 ugenclose(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
504 int endpt
= UGENENDPOINT(dev
);
505 struct ugen_softc
*sc
;
506 struct ugen_endpoint
*sce
;
510 USB_GET_SC(ugen
, UGENUNIT(dev
), sc
);
512 DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
513 flag
, mode
, UGENUNIT(dev
), endpt
));
516 if (!sc
->sc_is_open
[endpt
]) {
517 printf("ugenclose: not open\n");
522 if (endpt
== USB_CONTROL_ENDPOINT
) {
523 DPRINTFN(5, ("ugenclose: close control\n"));
524 sc
->sc_is_open
[endpt
] = 0;
528 for (dir
= OUT
; dir
<= IN
; dir
++) {
529 if (!(flag
& (dir
== OUT
? FWRITE
: FREAD
)))
531 sce
= &sc
->sc_endpoints
[endpt
][dir
];
532 if (sce
== NULL
|| sce
->pipeh
== NULL
)
534 DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
537 usbd_abort_pipe(sce
->pipeh
);
538 usbd_close_pipe(sce
->pipeh
);
541 switch (sce
->edesc
->bmAttributes
& UE_XFERTYPE
) {
543 ndflush(&sce
->q
, sce
->q
.c_cc
);
547 for (i
= 0; i
< UGEN_NISOREQS
; ++i
)
548 usbd_free_xfer(sce
->isoreqs
[i
].xfer
);
551 if (sce
->state
& (UGEN_BULK_RA
| UGEN_BULK_WB
))
552 /* ibuf freed below */
553 usbd_free_xfer(sce
->ra_wb_xfer
);
559 if (sce
->ibuf
!= NULL
) {
560 free(sce
->ibuf
, M_USBDEV
);
565 sc
->sc_is_open
[endpt
] = 0;
571 ugen_do_read(struct ugen_softc
*sc
, int endpt
, struct uio
*uio
, int flag
)
573 struct ugen_endpoint
*sce
= &sc
->sc_endpoints
[endpt
][IN
];
575 usbd_xfer_handle xfer
;
580 DPRINTFN(5, ("%s: ugenread: %d\n", USBDEVNAME(sc
->sc_dev
), endpt
));
585 if (endpt
== USB_CONTROL_ENDPOINT
)
589 if (sce
->edesc
== NULL
) {
590 printf("ugenread: no edesc\n");
593 if (sce
->pipeh
== NULL
) {
594 printf("ugenread: no pipe\n");
599 switch (sce
->edesc
->bmAttributes
& UE_XFERTYPE
) {
601 /* Block until activity occurred. */
603 while (sce
->q
.c_cc
== 0) {
604 if (flag
& IO_NDELAY
) {
606 return (EWOULDBLOCK
);
608 sce
->state
|= UGEN_ASLP
;
609 DPRINTFN(5, ("ugenread: sleep on %p\n", sce
));
610 error
= tsleep(sce
, PZERO
| PCATCH
, "ugenri", 0);
611 DPRINTFN(5, ("ugenread: woke, error=%d\n", error
));
615 sce
->state
&= ~UGEN_ASLP
;
621 /* Transfer as many chunks as possible. */
622 while (sce
->q
.c_cc
> 0 && uio
->uio_resid
> 0 && !error
) {
623 n
= min(sce
->q
.c_cc
, uio
->uio_resid
);
624 if (n
> sizeof(sc
->sc_buffer
))
625 n
= sizeof(sc
->sc_buffer
);
627 /* Remove a small chunk from the input queue. */
628 q_to_b(&sce
->q
, sc
->sc_buffer
, n
);
629 DPRINTFN(5, ("ugenread: got %d chars\n", n
));
631 /* Copy the data to the user process. */
632 error
= uiomove(sc
->sc_buffer
, n
, uio
);
638 if (sce
->state
& UGEN_BULK_RA
) {
639 DPRINTFN(5, ("ugenread: BULK_RA req: %zd used: %d\n",
640 uio
->uio_resid
, sce
->ra_wb_used
));
641 xfer
= sce
->ra_wb_xfer
;
644 if (sce
->ra_wb_used
== 0 && flag
& IO_NDELAY
) {
646 return (EWOULDBLOCK
);
648 while (uio
->uio_resid
> 0 && !error
) {
649 while (sce
->ra_wb_used
== 0) {
650 sce
->state
|= UGEN_ASLP
;
652 ("ugenread: sleep on %p\n",
654 error
= tsleep(sce
, PZERO
| PCATCH
,
657 ("ugenread: woke, error=%d\n",
662 sce
->state
&= ~UGEN_ASLP
;
667 /* Copy data to the process. */
668 while (uio
->uio_resid
> 0
669 && sce
->ra_wb_used
> 0) {
670 n
= min(uio
->uio_resid
,
672 n
= min(n
, sce
->limit
- sce
->cur
);
673 error
= uiomove(sce
->cur
, n
, uio
);
677 sce
->ra_wb_used
-= n
;
678 if (sce
->cur
== sce
->limit
)
679 sce
->cur
= sce
->ibuf
;
683 * If the transfers stopped because the
684 * buffer was full, restart them.
686 if (sce
->state
& UGEN_RA_WB_STOP
&&
687 sce
->ra_wb_used
< sce
->limit
- sce
->ibuf
) {
688 n
= (sce
->limit
- sce
->ibuf
)
690 usbd_setup_xfer(xfer
,
691 sce
->pipeh
, sce
, NULL
,
692 min(n
, sce
->ra_wb_xferlen
),
693 USBD_NO_COPY
, USBD_NO_TIMEOUT
,
695 sce
->state
&= ~UGEN_RA_WB_STOP
;
696 err
= usbd_transfer(xfer
);
697 if (err
!= USBD_IN_PROGRESS
)
699 * The transfer has not been
700 * queued. Setting STOP
702 * again at the next read.
704 sce
->state
|= UGEN_RA_WB_STOP
;
710 xfer
= usbd_alloc_xfer(sc
->sc_udev
);
713 while ((n
= min(UGEN_BBSIZE
, uio
->uio_resid
)) != 0) {
714 DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n
));
716 err
= usbd_bulk_transfer(
718 sce
->state
& UGEN_SHORT_OK
?
719 USBD_SHORT_XFER_OK
: 0,
720 sce
->timeout
, sc
->sc_buffer
, &tn
, "ugenrb");
722 if (err
== USBD_INTERRUPTED
)
724 else if (err
== USBD_TIMEOUT
)
730 DPRINTFN(1, ("ugenread: got %d bytes\n", tn
));
731 error
= uiomove(sc
->sc_buffer
, tn
, uio
);
735 usbd_free_xfer(xfer
);
739 while (sce
->cur
== sce
->fill
) {
740 if (flag
& IO_NDELAY
) {
742 return (EWOULDBLOCK
);
744 sce
->state
|= UGEN_ASLP
;
745 DPRINTFN(5, ("ugenread: sleep on %p\n", sce
));
746 error
= tsleep(sce
, PZERO
| PCATCH
, "ugenri", 0);
747 DPRINTFN(5, ("ugenread: woke, error=%d\n", error
));
751 sce
->state
&= ~UGEN_ASLP
;
756 while (sce
->cur
!= sce
->fill
&& uio
->uio_resid
> 0 && !error
) {
757 if(sce
->fill
> sce
->cur
)
758 n
= min(sce
->fill
- sce
->cur
, uio
->uio_resid
);
760 n
= min(sce
->limit
- sce
->cur
, uio
->uio_resid
);
762 DPRINTFN(5, ("ugenread: isoc got %d chars\n", n
));
764 /* Copy the data to the user process. */
765 error
= uiomove(sce
->cur
, n
, uio
);
769 if(sce
->cur
>= sce
->limit
)
770 sce
->cur
= sce
->ibuf
;
783 ugenread(dev_t dev
, struct uio
*uio
, int flag
)
785 int endpt
= UGENENDPOINT(dev
);
786 struct ugen_softc
*sc
;
789 USB_GET_SC(ugen
, UGENUNIT(dev
), sc
);
792 error
= ugen_do_read(sc
, endpt
, uio
, flag
);
793 if (--sc
->sc_refcnt
< 0)
794 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
799 ugen_do_write(struct ugen_softc
*sc
, int endpt
, struct uio
*uio
,
802 struct ugen_endpoint
*sce
= &sc
->sc_endpoints
[endpt
][OUT
];
808 usbd_xfer_handle xfer
;
811 DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc
->sc_dev
), endpt
));
816 if (endpt
== USB_CONTROL_ENDPOINT
)
820 if (sce
->edesc
== NULL
) {
821 printf("ugenwrite: no edesc\n");
824 if (sce
->pipeh
== NULL
) {
825 printf("ugenwrite: no pipe\n");
830 switch (sce
->edesc
->bmAttributes
& UE_XFERTYPE
) {
832 if (sce
->state
& UGEN_BULK_WB
) {
833 DPRINTFN(5, ("ugenwrite: BULK_WB req: %zd used: %d\n",
834 uio
->uio_resid
, sce
->ra_wb_used
));
835 xfer
= sce
->ra_wb_xfer
;
838 if (sce
->ra_wb_used
== sce
->limit
- sce
->ibuf
&&
841 return (EWOULDBLOCK
);
843 while (uio
->uio_resid
> 0 && !error
) {
844 while (sce
->ra_wb_used
==
845 sce
->limit
- sce
->ibuf
) {
846 sce
->state
|= UGEN_ASLP
;
848 ("ugenwrite: sleep on %p\n",
850 error
= tsleep(sce
, PZERO
| PCATCH
,
853 ("ugenwrite: woke, error=%d\n",
858 sce
->state
&= ~UGEN_ASLP
;
863 /* Copy data from the process. */
864 while (uio
->uio_resid
> 0 &&
865 sce
->ra_wb_used
< sce
->limit
- sce
->ibuf
) {
866 n
= min(uio
->uio_resid
,
867 (sce
->limit
- sce
->ibuf
)
869 n
= min(n
, sce
->limit
- sce
->fill
);
870 error
= uiomove(sce
->fill
, n
, uio
);
874 sce
->ra_wb_used
+= n
;
875 if (sce
->fill
== sce
->limit
)
876 sce
->fill
= sce
->ibuf
;
880 * If the transfers stopped because the
881 * buffer was empty, restart them.
883 if (sce
->state
& UGEN_RA_WB_STOP
&&
884 sce
->ra_wb_used
> 0) {
885 dbuf
= (char *)usbd_get_buffer(xfer
);
886 n
= min(sce
->ra_wb_used
,
888 tn
= min(n
, sce
->limit
- sce
->cur
);
889 memcpy(dbuf
, sce
->cur
, tn
);
892 memcpy(dbuf
, sce
->ibuf
,
894 usbd_setup_xfer(xfer
,
895 sce
->pipeh
, sce
, NULL
, n
,
896 USBD_NO_COPY
, USBD_NO_TIMEOUT
,
898 sce
->state
&= ~UGEN_RA_WB_STOP
;
899 err
= usbd_transfer(xfer
);
900 if (err
!= USBD_IN_PROGRESS
)
902 * The transfer has not been
903 * queued. Setting STOP
904 * will make us try again
907 sce
->state
|= UGEN_RA_WB_STOP
;
913 xfer
= usbd_alloc_xfer(sc
->sc_udev
);
916 while ((n
= min(UGEN_BBSIZE
, uio
->uio_resid
)) != 0) {
917 error
= uiomove(sc
->sc_buffer
, n
, uio
);
920 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n
));
921 err
= usbd_bulk_transfer(xfer
, sce
->pipeh
, 0,
922 sce
->timeout
, sc
->sc_buffer
, &n
,"ugenwb");
924 if (err
== USBD_INTERRUPTED
)
926 else if (err
== USBD_TIMEOUT
)
933 usbd_free_xfer(xfer
);
936 xfer
= usbd_alloc_xfer(sc
->sc_udev
);
939 while ((n
= min(UGETW(sce
->edesc
->wMaxPacketSize
),
940 uio
->uio_resid
)) != 0) {
941 error
= uiomove(sc
->sc_buffer
, n
, uio
);
944 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n
));
945 err
= usbd_intr_transfer(xfer
, sce
->pipeh
, 0,
946 sce
->timeout
, sc
->sc_buffer
, &n
, "ugenwi");
948 if (err
== USBD_INTERRUPTED
)
950 else if (err
== USBD_TIMEOUT
)
957 usbd_free_xfer(xfer
);
966 ugenwrite(dev_t dev
, struct uio
*uio
, int flag
)
968 int endpt
= UGENENDPOINT(dev
);
969 struct ugen_softc
*sc
;
972 USB_GET_SC(ugen
, UGENUNIT(dev
), sc
);
975 error
= ugen_do_write(sc
, endpt
, uio
, flag
);
976 if (--sc
->sc_refcnt
< 0)
977 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
981 #if defined(__NetBSD__) || defined(__OpenBSD__)
983 ugen_activate(device_ptr_t self
, enum devact act
)
985 struct ugen_softc
*sc
= device_private(self
);
988 case DVACT_DEACTIVATE
:
999 USB_DETACH_START(ugen
, sc
);
1000 struct ugen_endpoint
*sce
;
1003 #if defined(__NetBSD__) || defined(__OpenBSD__)
1006 DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc
, flags
));
1007 #elif defined(__FreeBSD__)
1008 DPRINTF(("ugen_detach: sc=%p\n", sc
));
1012 pmf_device_deregister(self
);
1013 /* Abort all pipes. Causes processes waiting for transfer to wake. */
1014 for (i
= 0; i
< USB_MAX_ENDPOINTS
; i
++) {
1015 for (dir
= OUT
; dir
<= IN
; dir
++) {
1016 sce
= &sc
->sc_endpoints
[i
][dir
];
1017 if (sce
&& sce
->pipeh
)
1018 usbd_abort_pipe(sce
->pipeh
);
1023 if (--sc
->sc_refcnt
>= 0) {
1025 for (i
= 0; i
< USB_MAX_ENDPOINTS
; i
++)
1026 wakeup(&sc
->sc_endpoints
[i
][IN
]);
1027 /* Wait for processes to go away. */
1028 usb_detach_wait(USBDEV(sc
->sc_dev
));
1032 #if defined(__NetBSD__) || defined(__OpenBSD__)
1033 /* locate the major number */
1034 #if defined(__NetBSD__)
1035 maj
= cdevsw_lookup_major(&ugen_cdevsw
);
1036 #elif defined(__OpenBSD__)
1037 for (maj
= 0; maj
< nchrdev
; maj
++)
1038 if (cdevsw
[maj
].d_open
== ugenopen
)
1042 /* Nuke the vnodes for any open instances (calls close). */
1043 mn
= device_unit(self
) * USB_MAX_ENDPOINTS
;
1044 vdevgone(maj
, mn
, mn
+ USB_MAX_ENDPOINTS
- 1, VCHR
);
1045 #elif defined(__FreeBSD__)
1046 /* XXX not implemented yet */
1049 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH
, sc
->sc_udev
,
1050 USBDEV(sc
->sc_dev
));
1052 for (i
= 0; i
< USB_MAX_ENDPOINTS
; i
++) {
1053 for (dir
= OUT
; dir
<= IN
; dir
++) {
1054 sce
= &sc
->sc_endpoints
[i
][dir
];
1055 seldestroy(&sce
->rsel
);
1063 ugenintr(usbd_xfer_handle xfer
, usbd_private_handle addr
, usbd_status status
)
1065 struct ugen_endpoint
*sce
= addr
;
1066 /*struct ugen_softc *sc = sce->sc;*/
1070 if (status
== USBD_CANCELLED
)
1073 if (status
!= USBD_NORMAL_COMPLETION
) {
1074 DPRINTF(("ugenintr: status=%d\n", status
));
1075 if (status
== USBD_STALLED
)
1076 usbd_clear_endpoint_stall_async(sce
->pipeh
);
1080 usbd_get_xfer_status(xfer
, NULL
, NULL
, &count
, NULL
);
1083 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
1084 xfer
, status
, count
));
1085 DPRINTFN(5, (" data = %02x %02x %02x\n",
1086 ibuf
[0], ibuf
[1], ibuf
[2]));
1088 (void)b_to_q(ibuf
, count
, &sce
->q
);
1090 if (sce
->state
& UGEN_ASLP
) {
1091 sce
->state
&= ~UGEN_ASLP
;
1092 DPRINTFN(5, ("ugen_intr: waking %p\n", sce
));
1095 selnotify(&sce
->rsel
, 0, 0);
1099 ugen_isoc_rintr(usbd_xfer_handle xfer
, usbd_private_handle addr
,
1102 struct isoreq
*req
= addr
;
1103 struct ugen_endpoint
*sce
= req
->sce
;
1107 /* Return if we are aborting. */
1108 if (status
== USBD_CANCELLED
)
1111 usbd_get_xfer_status(xfer
, NULL
, NULL
, &count
, NULL
);
1112 DPRINTFN(5,("ugen_isoc_rintr: xfer %ld, count=%d\n",
1113 (long)(req
- sce
->isoreqs
), count
));
1115 /* throw away oldest input if the buffer is full */
1116 if(sce
->fill
< sce
->cur
&& sce
->cur
<= sce
->fill
+ count
) {
1118 if(sce
->cur
>= sce
->limit
)
1119 sce
->cur
= sce
->ibuf
+ (sce
->limit
- sce
->cur
);
1120 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n",
1124 isize
= UGETW(sce
->edesc
->wMaxPacketSize
);
1125 for (i
= 0; i
< UGEN_NISORFRMS
; i
++) {
1126 u_int32_t actlen
= req
->sizes
[i
];
1127 char const *tbuf
= (char const *)req
->dmabuf
+ isize
* i
;
1129 /* copy data to buffer */
1130 while (actlen
> 0) {
1131 n
= min(actlen
, sce
->limit
- sce
->fill
);
1132 memcpy(sce
->fill
, tbuf
, n
);
1137 if(sce
->fill
== sce
->limit
)
1138 sce
->fill
= sce
->ibuf
;
1141 /* setup size for next transfer */
1142 req
->sizes
[i
] = isize
;
1145 usbd_setup_isoc_xfer(xfer
, sce
->pipeh
, req
, req
->sizes
, UGEN_NISORFRMS
,
1146 USBD_NO_COPY
, ugen_isoc_rintr
);
1147 (void)usbd_transfer(xfer
);
1149 if (sce
->state
& UGEN_ASLP
) {
1150 sce
->state
&= ~UGEN_ASLP
;
1151 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce
));
1154 selnotify(&sce
->rsel
, 0, 0);
1158 ugen_bulkra_intr(usbd_xfer_handle xfer
, usbd_private_handle addr
,
1161 struct ugen_endpoint
*sce
= addr
;
1166 /* Return if we are aborting. */
1167 if (status
== USBD_CANCELLED
)
1170 if (status
!= USBD_NORMAL_COMPLETION
) {
1171 DPRINTF(("ugen_bulkra_intr: status=%d\n", status
));
1172 sce
->state
|= UGEN_RA_WB_STOP
;
1173 if (status
== USBD_STALLED
)
1174 usbd_clear_endpoint_stall_async(sce
->pipeh
);
1178 usbd_get_xfer_status(xfer
, NULL
, NULL
, &count
, NULL
);
1180 /* Keep track of how much is in the buffer. */
1181 sce
->ra_wb_used
+= count
;
1183 /* Copy data to buffer. */
1184 tbuf
= (char const *)usbd_get_buffer(sce
->ra_wb_xfer
);
1185 n
= min(count
, sce
->limit
- sce
->fill
);
1186 memcpy(sce
->fill
, tbuf
, n
);
1190 if (sce
->fill
== sce
->limit
)
1191 sce
->fill
= sce
->ibuf
;
1193 memcpy(sce
->fill
, tbuf
, count
);
1197 /* Set up the next request if necessary. */
1198 n
= (sce
->limit
- sce
->ibuf
) - sce
->ra_wb_used
;
1200 usbd_setup_xfer(xfer
, sce
->pipeh
, sce
, NULL
,
1201 min(n
, sce
->ra_wb_xferlen
), USBD_NO_COPY
,
1202 USBD_NO_TIMEOUT
, ugen_bulkra_intr
);
1203 err
= usbd_transfer(xfer
);
1204 if (err
!= USBD_IN_PROGRESS
) {
1205 printf("usbd_bulkra_intr: error=%d\n", err
);
1207 * The transfer has not been queued. Setting STOP
1208 * will make us try again at the next read.
1210 sce
->state
|= UGEN_RA_WB_STOP
;
1214 sce
->state
|= UGEN_RA_WB_STOP
;
1216 if (sce
->state
& UGEN_ASLP
) {
1217 sce
->state
&= ~UGEN_ASLP
;
1218 DPRINTFN(5, ("ugen_bulkra_intr: waking %p\n", sce
));
1221 selnotify(&sce
->rsel
, 0, 0);
1225 ugen_bulkwb_intr(usbd_xfer_handle xfer
, usbd_private_handle addr
,
1228 struct ugen_endpoint
*sce
= addr
;
1233 /* Return if we are aborting. */
1234 if (status
== USBD_CANCELLED
)
1237 if (status
!= USBD_NORMAL_COMPLETION
) {
1238 DPRINTF(("ugen_bulkwb_intr: status=%d\n", status
));
1239 sce
->state
|= UGEN_RA_WB_STOP
;
1240 if (status
== USBD_STALLED
)
1241 usbd_clear_endpoint_stall_async(sce
->pipeh
);
1245 usbd_get_xfer_status(xfer
, NULL
, NULL
, &count
, NULL
);
1247 /* Keep track of how much is in the buffer. */
1248 sce
->ra_wb_used
-= count
;
1250 /* Update buffer pointers. */
1252 if (sce
->cur
>= sce
->limit
)
1253 sce
->cur
= sce
->ibuf
+ (sce
->cur
- sce
->limit
);
1255 /* Set up next request if necessary. */
1256 if (sce
->ra_wb_used
> 0) {
1257 /* copy data from buffer */
1258 tbuf
= (char *)usbd_get_buffer(sce
->ra_wb_xfer
);
1259 count
= min(sce
->ra_wb_used
, sce
->ra_wb_xferlen
);
1260 n
= min(count
, sce
->limit
- sce
->cur
);
1261 memcpy(tbuf
, sce
->cur
, n
);
1264 memcpy(tbuf
, sce
->ibuf
, count
- n
);
1266 usbd_setup_xfer(xfer
, sce
->pipeh
, sce
, NULL
,
1267 count
, USBD_NO_COPY
, USBD_NO_TIMEOUT
, ugen_bulkwb_intr
);
1268 err
= usbd_transfer(xfer
);
1269 if (err
!= USBD_IN_PROGRESS
) {
1270 printf("usbd_bulkwb_intr: error=%d\n", err
);
1272 * The transfer has not been queued. Setting STOP
1273 * will make us try again at the next write.
1275 sce
->state
|= UGEN_RA_WB_STOP
;
1279 sce
->state
|= UGEN_RA_WB_STOP
;
1281 if (sce
->state
& UGEN_ASLP
) {
1282 sce
->state
&= ~UGEN_ASLP
;
1283 DPRINTFN(5, ("ugen_bulkwb_intr: waking %p\n", sce
));
1286 selnotify(&sce
->rsel
, 0, 0);
1290 ugen_set_interface(struct ugen_softc
*sc
, int ifaceidx
, int altno
)
1292 usbd_interface_handle iface
;
1293 usb_endpoint_descriptor_t
*ed
;
1295 struct ugen_endpoint
*sce
;
1296 u_int8_t niface
, nendpt
, endptno
, endpt
;
1299 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx
, altno
));
1301 err
= usbd_interface_count(sc
->sc_udev
, &niface
);
1304 if (ifaceidx
< 0 || ifaceidx
>= niface
)
1305 return (USBD_INVAL
);
1307 err
= usbd_device2interface_handle(sc
->sc_udev
, ifaceidx
, &iface
);
1310 err
= usbd_endpoint_count(iface
, &nendpt
);
1313 /* XXX should only do this after setting new altno has succeeded */
1314 for (endptno
= 0; endptno
< nendpt
; endptno
++) {
1315 ed
= usbd_interface2endpoint_descriptor(iface
,endptno
);
1316 endpt
= ed
->bEndpointAddress
;
1317 dir
= UE_GET_DIR(endpt
) == UE_DIR_IN
? IN
: OUT
;
1318 sce
= &sc
->sc_endpoints
[UE_GET_ADDR(endpt
)][dir
];
1324 /* change setting */
1325 err
= usbd_set_interface(iface
, altno
);
1329 err
= usbd_endpoint_count(iface
, &nendpt
);
1332 for (endptno
= 0; endptno
< nendpt
; endptno
++) {
1333 ed
= usbd_interface2endpoint_descriptor(iface
,endptno
);
1334 KASSERT(ed
!= NULL
);
1335 endpt
= ed
->bEndpointAddress
;
1336 dir
= UE_GET_DIR(endpt
) == UE_DIR_IN
? IN
: OUT
;
1337 sce
= &sc
->sc_endpoints
[UE_GET_ADDR(endpt
)][dir
];
1345 /* Retrieve a complete descriptor for a certain device and index. */
1346 Static usb_config_descriptor_t
*
1347 ugen_get_cdesc(struct ugen_softc
*sc
, int index
, int *lenp
)
1349 usb_config_descriptor_t
*cdesc
, *tdesc
, cdescr
;
1353 if (index
== USB_CURRENT_CONFIG_INDEX
) {
1354 tdesc
= usbd_get_config_descriptor(sc
->sc_udev
);
1355 len
= UGETW(tdesc
->wTotalLength
);
1358 cdesc
= malloc(len
, M_TEMP
, M_WAITOK
);
1359 memcpy(cdesc
, tdesc
, len
);
1360 DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len
));
1362 err
= usbd_get_config_desc(sc
->sc_udev
, index
, &cdescr
);
1365 len
= UGETW(cdescr
.wTotalLength
);
1366 DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index
, len
));
1369 cdesc
= malloc(len
, M_TEMP
, M_WAITOK
);
1370 err
= usbd_get_config_desc_full(sc
->sc_udev
, index
, cdesc
, len
);
1372 free(cdesc
, M_TEMP
);
1380 ugen_get_alt_index(struct ugen_softc
*sc
, int ifaceidx
)
1382 usbd_interface_handle iface
;
1385 err
= usbd_device2interface_handle(sc
->sc_udev
, ifaceidx
, &iface
);
1388 return (usbd_get_interface_altindex(iface
));
1392 ugen_do_ioctl(struct ugen_softc
*sc
, int endpt
, u_long cmd
,
1393 void *addr
, int flag
, struct lwp
*l
)
1395 struct ugen_endpoint
*sce
;
1397 usbd_interface_handle iface
;
1398 struct usb_config_desc
*cd
;
1399 usb_config_descriptor_t
*cdesc
;
1400 struct usb_interface_desc
*id
;
1401 usb_interface_descriptor_t
*idesc
;
1402 struct usb_endpoint_desc
*ed
;
1403 usb_endpoint_descriptor_t
*edesc
;
1404 struct usb_alt_interface
*ai
;
1405 struct usb_string_desc
*si
;
1408 DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd
));
1414 /* All handled in the upper FS layer. */
1416 case USB_SET_SHORT_XFER
:
1417 if (endpt
== USB_CONTROL_ENDPOINT
)
1419 /* This flag only affects read */
1420 sce
= &sc
->sc_endpoints
[endpt
][IN
];
1421 if (sce
== NULL
|| sce
->pipeh
== NULL
)
1424 sce
->state
|= UGEN_SHORT_OK
;
1426 sce
->state
&= ~UGEN_SHORT_OK
;
1428 case USB_SET_TIMEOUT
:
1429 sce
= &sc
->sc_endpoints
[endpt
][IN
];
1431 /* XXX this shouldn't happen, but the distinction between
1432 input and output pipes isn't clear enough.
1433 || sce->pipeh == NULL */
1436 sce
->timeout
= *(int *)addr
;
1438 case USB_SET_BULK_RA
:
1439 if (endpt
== USB_CONTROL_ENDPOINT
)
1441 sce
= &sc
->sc_endpoints
[endpt
][IN
];
1442 if (sce
== NULL
|| sce
->pipeh
== NULL
)
1445 if ((edesc
->bmAttributes
& UE_XFERTYPE
) != UE_BULK
)
1449 /* Only turn RA on if it's currently off. */
1450 if (sce
->state
& UGEN_BULK_RA
)
1453 if (sce
->ra_wb_bufsize
== 0 || sce
->ra_wb_reqsize
== 0)
1454 /* shouldn't happen */
1456 sce
->ra_wb_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
1457 if (sce
->ra_wb_xfer
== NULL
)
1459 sce
->ra_wb_xferlen
= sce
->ra_wb_reqsize
;
1461 * Set up a dmabuf because we reuse the xfer with
1462 * the same (max) request length like isoc.
1464 if (usbd_alloc_buffer(sce
->ra_wb_xfer
,
1465 sce
->ra_wb_xferlen
) == 0) {
1466 usbd_free_xfer(sce
->ra_wb_xfer
);
1469 sce
->ibuf
= malloc(sce
->ra_wb_bufsize
,
1470 M_USBDEV
, M_WAITOK
);
1471 sce
->fill
= sce
->cur
= sce
->ibuf
;
1472 sce
->limit
= sce
->ibuf
+ sce
->ra_wb_bufsize
;
1473 sce
->ra_wb_used
= 0;
1474 sce
->state
|= UGEN_BULK_RA
;
1475 sce
->state
&= ~UGEN_RA_WB_STOP
;
1476 /* Now start reading. */
1477 usbd_setup_xfer(sce
->ra_wb_xfer
, sce
->pipeh
, sce
,
1479 min(sce
->ra_wb_xferlen
, sce
->ra_wb_bufsize
),
1480 USBD_NO_COPY
, USBD_NO_TIMEOUT
,
1482 err
= usbd_transfer(sce
->ra_wb_xfer
);
1483 if (err
!= USBD_IN_PROGRESS
) {
1484 sce
->state
&= ~UGEN_BULK_RA
;
1485 free(sce
->ibuf
, M_USBDEV
);
1487 usbd_free_xfer(sce
->ra_wb_xfer
);
1491 /* Only turn RA off if it's currently on. */
1492 if (!(sce
->state
& UGEN_BULK_RA
))
1495 sce
->state
&= ~UGEN_BULK_RA
;
1496 usbd_abort_pipe(sce
->pipeh
);
1497 usbd_free_xfer(sce
->ra_wb_xfer
);
1499 * XXX Discard whatever's in the buffer, but we
1500 * should keep it around and drain the buffer
1503 free(sce
->ibuf
, M_USBDEV
);
1507 case USB_SET_BULK_WB
:
1508 if (endpt
== USB_CONTROL_ENDPOINT
)
1510 sce
= &sc
->sc_endpoints
[endpt
][OUT
];
1511 if (sce
== NULL
|| sce
->pipeh
== NULL
)
1514 if ((edesc
->bmAttributes
& UE_XFERTYPE
) != UE_BULK
)
1518 /* Only turn WB on if it's currently off. */
1519 if (sce
->state
& UGEN_BULK_WB
)
1522 if (sce
->ra_wb_bufsize
== 0 || sce
->ra_wb_reqsize
== 0)
1523 /* shouldn't happen */
1525 sce
->ra_wb_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
1526 if (sce
->ra_wb_xfer
== NULL
)
1528 sce
->ra_wb_xferlen
= sce
->ra_wb_reqsize
;
1530 * Set up a dmabuf because we reuse the xfer with
1531 * the same (max) request length like isoc.
1533 if (usbd_alloc_buffer(sce
->ra_wb_xfer
,
1534 sce
->ra_wb_xferlen
) == 0) {
1535 usbd_free_xfer(sce
->ra_wb_xfer
);
1538 sce
->ibuf
= malloc(sce
->ra_wb_bufsize
,
1539 M_USBDEV
, M_WAITOK
);
1540 sce
->fill
= sce
->cur
= sce
->ibuf
;
1541 sce
->limit
= sce
->ibuf
+ sce
->ra_wb_bufsize
;
1542 sce
->ra_wb_used
= 0;
1543 sce
->state
|= UGEN_BULK_WB
| UGEN_RA_WB_STOP
;
1545 /* Only turn WB off if it's currently on. */
1546 if (!(sce
->state
& UGEN_BULK_WB
))
1549 sce
->state
&= ~UGEN_BULK_WB
;
1551 * XXX Discard whatever's in the buffer, but we
1552 * should keep it around and keep writing to
1553 * drain the buffer instead.
1555 usbd_abort_pipe(sce
->pipeh
);
1556 usbd_free_xfer(sce
->ra_wb_xfer
);
1557 free(sce
->ibuf
, M_USBDEV
);
1561 case USB_SET_BULK_RA_OPT
:
1562 case USB_SET_BULK_WB_OPT
:
1564 struct usb_bulk_ra_wb_opt
*opt
;
1566 if (endpt
== USB_CONTROL_ENDPOINT
)
1568 opt
= (struct usb_bulk_ra_wb_opt
*)addr
;
1569 if (cmd
== USB_SET_BULK_RA_OPT
)
1570 sce
= &sc
->sc_endpoints
[endpt
][IN
];
1572 sce
= &sc
->sc_endpoints
[endpt
][OUT
];
1573 if (sce
== NULL
|| sce
->pipeh
== NULL
)
1575 if (opt
->ra_wb_buffer_size
< 1 ||
1576 opt
->ra_wb_buffer_size
> UGEN_BULK_RA_WB_BUFMAX
||
1577 opt
->ra_wb_request_size
< 1 ||
1578 opt
->ra_wb_request_size
> opt
->ra_wb_buffer_size
)
1581 * XXX These changes do not take effect until the
1582 * next time RA/WB mode is enabled but they ought to
1583 * take effect immediately.
1585 sce
->ra_wb_bufsize
= opt
->ra_wb_buffer_size
;
1586 sce
->ra_wb_reqsize
= opt
->ra_wb_request_size
;
1593 if (endpt
!= USB_CONTROL_ENDPOINT
)
1599 ugendebug
= *(int *)addr
;
1602 case USB_GET_CONFIG
:
1603 err
= usbd_get_config(sc
->sc_udev
, &conf
);
1606 *(int *)addr
= conf
;
1608 case USB_SET_CONFIG
:
1609 if (!(flag
& FWRITE
))
1611 err
= ugen_set_config(sc
, *(int *)addr
);
1613 case USBD_NORMAL_COMPLETION
:
1621 case USB_GET_ALTINTERFACE
:
1622 ai
= (struct usb_alt_interface
*)addr
;
1623 err
= usbd_device2interface_handle(sc
->sc_udev
,
1624 ai
->uai_interface_index
, &iface
);
1627 idesc
= usbd_get_interface_descriptor(iface
);
1630 ai
->uai_alt_no
= idesc
->bAlternateSetting
;
1632 case USB_SET_ALTINTERFACE
:
1633 if (!(flag
& FWRITE
))
1635 ai
= (struct usb_alt_interface
*)addr
;
1636 err
= usbd_device2interface_handle(sc
->sc_udev
,
1637 ai
->uai_interface_index
, &iface
);
1640 err
= ugen_set_interface(sc
, ai
->uai_interface_index
,
1645 case USB_GET_NO_ALT
:
1646 ai
= (struct usb_alt_interface
*)addr
;
1647 cdesc
= ugen_get_cdesc(sc
, ai
->uai_config_index
, 0);
1650 idesc
= usbd_find_idesc(cdesc
, ai
->uai_interface_index
, 0);
1651 if (idesc
== NULL
) {
1652 free(cdesc
, M_TEMP
);
1655 ai
->uai_alt_no
= usbd_get_no_alts(cdesc
,
1656 idesc
->bInterfaceNumber
);
1657 free(cdesc
, M_TEMP
);
1659 case USB_GET_DEVICE_DESC
:
1660 *(usb_device_descriptor_t
*)addr
=
1661 *usbd_get_device_descriptor(sc
->sc_udev
);
1663 case USB_GET_CONFIG_DESC
:
1664 cd
= (struct usb_config_desc
*)addr
;
1665 cdesc
= ugen_get_cdesc(sc
, cd
->ucd_config_index
, 0);
1668 cd
->ucd_desc
= *cdesc
;
1669 free(cdesc
, M_TEMP
);
1671 case USB_GET_INTERFACE_DESC
:
1672 id
= (struct usb_interface_desc
*)addr
;
1673 cdesc
= ugen_get_cdesc(sc
, id
->uid_config_index
, 0);
1676 if (id
->uid_config_index
== USB_CURRENT_CONFIG_INDEX
&&
1677 id
->uid_alt_index
== USB_CURRENT_ALT_INDEX
)
1678 alt
= ugen_get_alt_index(sc
, id
->uid_interface_index
);
1680 alt
= id
->uid_alt_index
;
1681 idesc
= usbd_find_idesc(cdesc
, id
->uid_interface_index
, alt
);
1682 if (idesc
== NULL
) {
1683 free(cdesc
, M_TEMP
);
1686 id
->uid_desc
= *idesc
;
1687 free(cdesc
, M_TEMP
);
1689 case USB_GET_ENDPOINT_DESC
:
1690 ed
= (struct usb_endpoint_desc
*)addr
;
1691 cdesc
= ugen_get_cdesc(sc
, ed
->ued_config_index
, 0);
1694 if (ed
->ued_config_index
== USB_CURRENT_CONFIG_INDEX
&&
1695 ed
->ued_alt_index
== USB_CURRENT_ALT_INDEX
)
1696 alt
= ugen_get_alt_index(sc
, ed
->ued_interface_index
);
1698 alt
= ed
->ued_alt_index
;
1699 edesc
= usbd_find_edesc(cdesc
, ed
->ued_interface_index
,
1700 alt
, ed
->ued_endpoint_index
);
1701 if (edesc
== NULL
) {
1702 free(cdesc
, M_TEMP
);
1705 ed
->ued_desc
= *edesc
;
1706 free(cdesc
, M_TEMP
);
1708 case USB_GET_FULL_DESC
:
1713 struct usb_full_desc
*fd
= (struct usb_full_desc
*)addr
;
1716 cdesc
= ugen_get_cdesc(sc
, fd
->ufd_config_index
, &len
);
1719 if (len
> fd
->ufd_size
)
1721 iov
.iov_base
= (void *)fd
->ufd_data
;
1725 uio
.uio_resid
= len
;
1727 uio
.uio_rw
= UIO_READ
;
1728 uio
.uio_vmspace
= l
->l_proc
->p_vmspace
;
1729 error
= uiomove((void *)cdesc
, len
, &uio
);
1730 free(cdesc
, M_TEMP
);
1733 case USB_GET_STRING_DESC
: {
1735 si
= (struct usb_string_desc
*)addr
;
1736 err
= usbd_get_string_desc(sc
->sc_udev
, si
->usd_string_index
,
1737 si
->usd_language_id
, &si
->usd_desc
, &len
);
1742 case USB_DO_REQUEST
:
1744 struct usb_ctl_request
*ur
= (void *)addr
;
1745 int len
= UGETW(ur
->ucr_request
.wLength
);
1752 if (!(flag
& FWRITE
))
1754 /* Avoid requests that would damage the bus integrity. */
1755 if ((ur
->ucr_request
.bmRequestType
== UT_WRITE_DEVICE
&&
1756 ur
->ucr_request
.bRequest
== UR_SET_ADDRESS
) ||
1757 (ur
->ucr_request
.bmRequestType
== UT_WRITE_DEVICE
&&
1758 ur
->ucr_request
.bRequest
== UR_SET_CONFIG
) ||
1759 (ur
->ucr_request
.bmRequestType
== UT_WRITE_INTERFACE
&&
1760 ur
->ucr_request
.bRequest
== UR_SET_INTERFACE
))
1763 if (len
< 0 || len
> 32767)
1766 iov
.iov_base
= (void *)ur
->ucr_data
;
1770 uio
.uio_resid
= len
;
1773 ur
->ucr_request
.bmRequestType
& UT_READ
?
1774 UIO_READ
: UIO_WRITE
;
1775 uio
.uio_vmspace
= l
->l_proc
->p_vmspace
;
1776 ptr
= malloc(len
, M_TEMP
, M_WAITOK
);
1777 if (uio
.uio_rw
== UIO_WRITE
) {
1778 error
= uiomove(ptr
, len
, &uio
);
1783 sce
= &sc
->sc_endpoints
[endpt
][IN
];
1784 xerr
= usbd_do_request_flags(sc
->sc_udev
, &ur
->ucr_request
,
1785 ptr
, ur
->ucr_flags
, &ur
->ucr_actlen
, sce
->timeout
);
1791 if (uio
.uio_rw
== UIO_READ
) {
1792 error
= uiomove(ptr
, len
, &uio
);
1802 case USB_GET_DEVICEINFO
:
1803 usbd_fill_deviceinfo(sc
->sc_udev
,
1804 (struct usb_device_info
*)addr
, 0);
1807 case USB_GET_DEVICEINFO_OLD
:
1808 usbd_fill_deviceinfo_old(sc
->sc_udev
,
1809 (struct usb_device_info_old
*)addr
, 0);
1820 ugenioctl(dev_t dev
, u_long cmd
, void *addr
, int flag
, struct lwp
*l
)
1822 int endpt
= UGENENDPOINT(dev
);
1823 struct ugen_softc
*sc
;
1826 USB_GET_SC(ugen
, UGENUNIT(dev
), sc
);
1829 error
= ugen_do_ioctl(sc
, endpt
, cmd
, addr
, flag
, l
);
1830 if (--sc
->sc_refcnt
< 0)
1831 usb_detach_wakeup(USBDEV(sc
->sc_dev
));
1836 ugenpoll(dev_t dev
, int events
, struct lwp
*l
)
1838 struct ugen_softc
*sc
;
1839 struct ugen_endpoint
*sce_in
, *sce_out
;
1843 USB_GET_SC(ugen
, UGENUNIT(dev
), sc
);
1848 sce_in
= &sc
->sc_endpoints
[UGENENDPOINT(dev
)][IN
];
1849 sce_out
= &sc
->sc_endpoints
[UGENENDPOINT(dev
)][OUT
];
1850 if (sce_in
== NULL
&& sce_out
== NULL
)
1853 if (!sce_in
->edesc
&& !sce_out
->edesc
) {
1854 printf("ugenpoll: no edesc\n");
1857 /* It's possible to have only one pipe open. */
1858 if (!sce_in
->pipeh
&& !sce_out
->pipeh
) {
1859 printf("ugenpoll: no pipe\n");
1864 if (sce_in
&& sce_in
->pipeh
&& (events
& (POLLIN
| POLLRDNORM
)))
1865 switch (sce_in
->edesc
->bmAttributes
& UE_XFERTYPE
) {
1867 if (sce_in
->q
.c_cc
> 0)
1868 revents
|= events
& (POLLIN
| POLLRDNORM
);
1870 selrecord(l
, &sce_in
->rsel
);
1872 case UE_ISOCHRONOUS
:
1873 if (sce_in
->cur
!= sce_in
->fill
)
1874 revents
|= events
& (POLLIN
| POLLRDNORM
);
1876 selrecord(l
, &sce_in
->rsel
);
1879 if (sce_in
->state
& UGEN_BULK_RA
) {
1880 if (sce_in
->ra_wb_used
> 0)
1882 (POLLIN
| POLLRDNORM
);
1884 selrecord(l
, &sce_in
->rsel
);
1888 * We have no easy way of determining if a read will
1889 * yield any data or a write will happen.
1890 * Pretend they will.
1892 revents
|= events
& (POLLIN
| POLLRDNORM
);
1897 if (sce_out
&& sce_out
->pipeh
&& (events
& (POLLOUT
| POLLWRNORM
)))
1898 switch (sce_out
->edesc
->bmAttributes
& UE_XFERTYPE
) {
1900 case UE_ISOCHRONOUS
:
1901 /* XXX unimplemented */
1904 if (sce_out
->state
& UGEN_BULK_WB
) {
1905 if (sce_out
->ra_wb_used
<
1906 sce_out
->limit
- sce_out
->ibuf
)
1908 (POLLOUT
| POLLWRNORM
);
1910 selrecord(l
, &sce_out
->rsel
);
1914 * We have no easy way of determining if a read will
1915 * yield any data or a write will happen.
1916 * Pretend they will.
1918 revents
|= events
& (POLLOUT
| POLLWRNORM
);
1930 filt_ugenrdetach(struct knote
*kn
)
1932 struct ugen_endpoint
*sce
= kn
->kn_hook
;
1936 SLIST_REMOVE(&sce
->rsel
.sel_klist
, kn
, knote
, kn_selnext
);
1941 filt_ugenread_intr(struct knote
*kn
, long hint
)
1943 struct ugen_endpoint
*sce
= kn
->kn_hook
;
1945 kn
->kn_data
= sce
->q
.c_cc
;
1946 return (kn
->kn_data
> 0);
1950 filt_ugenread_isoc(struct knote
*kn
, long hint
)
1952 struct ugen_endpoint
*sce
= kn
->kn_hook
;
1954 if (sce
->cur
== sce
->fill
)
1957 if (sce
->cur
< sce
->fill
)
1958 kn
->kn_data
= sce
->fill
- sce
->cur
;
1960 kn
->kn_data
= (sce
->limit
- sce
->cur
) +
1961 (sce
->fill
- sce
->ibuf
);
1967 filt_ugenread_bulk(struct knote
*kn
, long hint
)
1969 struct ugen_endpoint
*sce
= kn
->kn_hook
;
1971 if (!(sce
->state
& UGEN_BULK_RA
))
1973 * We have no easy way of determining if a read will
1974 * yield any data or a write will happen.
1975 * So, emulate "seltrue".
1977 return (filt_seltrue(kn
, hint
));
1979 if (sce
->ra_wb_used
== 0)
1982 kn
->kn_data
= sce
->ra_wb_used
;
1988 filt_ugenwrite_bulk(struct knote
*kn
, long hint
)
1990 struct ugen_endpoint
*sce
= kn
->kn_hook
;
1992 if (!(sce
->state
& UGEN_BULK_WB
))
1994 * We have no easy way of determining if a read will
1995 * yield any data or a write will happen.
1996 * So, emulate "seltrue".
1998 return (filt_seltrue(kn
, hint
));
2000 if (sce
->ra_wb_used
== sce
->limit
- sce
->ibuf
)
2003 kn
->kn_data
= (sce
->limit
- sce
->ibuf
) - sce
->ra_wb_used
;
2008 static const struct filterops ugenread_intr_filtops
=
2009 { 1, NULL
, filt_ugenrdetach
, filt_ugenread_intr
};
2011 static const struct filterops ugenread_isoc_filtops
=
2012 { 1, NULL
, filt_ugenrdetach
, filt_ugenread_isoc
};
2014 static const struct filterops ugenread_bulk_filtops
=
2015 { 1, NULL
, filt_ugenrdetach
, filt_ugenread_bulk
};
2017 static const struct filterops ugenwrite_bulk_filtops
=
2018 { 1, NULL
, filt_ugenrdetach
, filt_ugenwrite_bulk
};
2021 ugenkqfilter(dev_t dev
, struct knote
*kn
)
2023 struct ugen_softc
*sc
;
2024 struct ugen_endpoint
*sce
;
2025 struct klist
*klist
;
2028 USB_GET_SC(ugen
, UGENUNIT(dev
), sc
);
2033 switch (kn
->kn_filter
) {
2035 sce
= &sc
->sc_endpoints
[UGENENDPOINT(dev
)][IN
];
2039 klist
= &sce
->rsel
.sel_klist
;
2040 switch (sce
->edesc
->bmAttributes
& UE_XFERTYPE
) {
2042 kn
->kn_fop
= &ugenread_intr_filtops
;
2044 case UE_ISOCHRONOUS
:
2045 kn
->kn_fop
= &ugenread_isoc_filtops
;
2048 kn
->kn_fop
= &ugenread_bulk_filtops
;
2057 sce
= &sc
->sc_endpoints
[UGENENDPOINT(dev
)][OUT
];
2061 klist
= &sce
->rsel
.sel_klist
;
2062 switch (sce
->edesc
->bmAttributes
& UE_XFERTYPE
) {
2064 case UE_ISOCHRONOUS
:
2065 /* XXX poll doesn't support this */
2069 kn
->kn_fop
= &ugenwrite_bulk_filtops
;
2083 SLIST_INSERT_HEAD(klist
, kn
, kn_selnext
);
2089 #if defined(__FreeBSD__)
2090 DRIVER_MODULE(ugen
, uhub
, ugen_driver
, ugen_devclass
, usbd_driver_load
, 0);