1 /* $NetBSD: ugen.c,v 1.79 2006/03/01 12:38:13 yamt Exp $ */
3 /* Also already merged from NetBSD:
4 * $NetBSD: ugen.c,v 1.61 2002/09/23 05:51:20 simonb Exp $
5 * $NetBSD: ugen.c,v 1.64 2003/06/28 14:21:46 darrenr Exp $
6 * $NetBSD: ugen.c,v 1.65 2003/06/29 22:30:56 fvdl Exp $
7 * $NetBSD: ugen.c,v 1.68 2004/06/23 02:30:52 mycroft Exp $
10 #include <sys/cdefs.h>
11 __FBSDID("$FreeBSD$");
14 * Copyright (c) 1998 The NetBSD Foundation, Inc.
15 * All rights reserved.
17 * This code is derived from software contributed to The NetBSD Foundation
18 * by Lennart Augustsson (lennart@augustsson.net) at
19 * Carlstedt Research & Technology.
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * 3. All advertising materials mentioning features or use of this software
30 * must display the following acknowledgement:
31 * This product includes software developed by the NetBSD
32 * Foundation, Inc. and its contributors.
33 * 4. Neither the name of The NetBSD Foundation nor the names of its
34 * contributors may be used to endorse or promote products derived
35 * from this software without specific prior written permission.
37 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
38 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
39 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
41 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47 * POSSIBILITY OF SUCH DAMAGE.
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/kernel.h>
54 #include <sys/malloc.h>
55 #if defined(__NetBSD__) || defined(__OpenBSD__)
56 #include <sys/device.h>
57 #include <sys/ioctl.h>
58 #elif defined(__FreeBSD__)
59 #include <sys/module.h>
61 #include <sys/ioccom.h>
63 #include <sys/fcntl.h>
64 #include <sys/filio.h>
68 #if __FreeBSD_version >= 500014
69 #include <sys/selinfo.h>
71 #include <sys/select.h>
74 #include <sys/sysctl.h>
77 #include <dev/usb/usb.h>
78 #include <dev/usb/usbdi.h>
79 #include <dev/usb/usbdi_util.h>
82 #define DPRINTF(x) if (ugendebug) logprintf x
83 #define DPRINTFN(n,x) if (ugendebug>(n)) logprintf x
85 SYSCTL_NODE(_hw_usb, OID_AUTO, ugen, CTLFLAG_RW, 0, "USB ugen");
86 SYSCTL_INT(_hw_usb_ugen, OID_AUTO, debug, CTLFLAG_RW,
87 &ugendebug, 0, "ugen debug level");
93 #define UGEN_CHUNK 128 /* chunk size for read */
94 #define UGEN_IBSIZE 1020 /* buffer size */
95 #define UGEN_BBSIZE 1024
97 #define UGEN_NISOFRAMES 500 /* 0.5 seconds worth */
98 #define UGEN_NISOREQS 6 /* number of outstanding xfer requests */
99 #define UGEN_NISORFRMS 4 /* number of frames (miliseconds) per req */
101 struct ugen_endpoint {
102 struct ugen_softc *sc;
103 #if defined(__FreeBSD__)
106 usb_endpoint_descriptor_t *edesc;
107 usbd_interface_handle iface;
109 #define UGEN_ASLP 0x02 /* waiting for data */
110 #define UGEN_SHORT_OK 0x04 /* short xfers are OK */
111 usbd_pipe_handle pipeh;
114 u_char *ibuf; /* start of buffer (circular for isoc) */
115 u_char *fill; /* location for input (isoc) */
116 u_char *limit; /* end of circular buffer (isoc) */
117 u_char *cur; /* current read location (isoc) */
120 struct ugen_endpoint *sce;
121 usbd_xfer_handle xfer;
123 u_int16_t sizes[UGEN_NISORFRMS];
124 } isoreqs[UGEN_NISOREQS];
128 USBBASEDEVICE sc_dev; /* base device */
129 usbd_device_handle sc_udev;
130 #if defined(__FreeBSD__)
134 char sc_is_open[USB_MAX_ENDPOINTS];
135 struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2];
140 #define UGEN_DEV_REF(dev, sc) \
141 if ((sc)->sc_dying || dev_refthread(dev) == NULL) \
143 #define UGEN_DEV_RELE(dev, sc) \
145 #define UGEN_DEV_OPEN(dev, sc) \
146 /* handled by dev layer */
147 #define UGEN_DEV_CLOSE(dev, sc) \
148 /* handled by dev layer */
151 #define UGEN_DEV_REF(dev, sc) \
152 if ((sc)->sc_dying) \
155 #define UGEN_DEV_RELE(dev, sc) \
156 if (--(sc)->sc_refcnt < 0) \
157 usb_detach_wakeup(USBDEV((sc)->sc_dev))
158 #define UGEN_DEV_OPEN(dev, sc) \
160 #define UGEN_DEV_CLOSE(dev, sc) \
161 UGEN_DEV_RELE(dev, sc)
166 #if defined(__NetBSD__) || defined(__OpenBSD__)
168 #elif defined(__FreeBSD__)
177 Static struct cdevsw ugenctl_cdevsw = {
178 .d_version = D_VERSION,
179 .d_flags = D_NEEDGIANT,
181 .d_close = ugenclose,
182 .d_ioctl = ugenioctl,
183 .d_purge = ugenpurge,
185 #if __FreeBSD_version < 500014
190 Static struct cdevsw ugen_cdevsw = {
191 .d_version = D_VERSION,
192 .d_flags = D_NEEDGIANT,
194 .d_close = ugenclose,
196 .d_write = ugenwrite,
197 .d_ioctl = ugenioctl,
199 .d_purge = ugenpurge,
201 #if __FreeBSD_version < 500014
207 Static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr,
209 Static void ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
211 Static int ugen_do_read(struct ugen_softc *, int, struct uio *, int);
212 Static int ugen_do_write(struct ugen_softc *, int, struct uio *, int);
213 Static int ugen_do_ioctl(struct ugen_softc *, int, u_long,
214 caddr_t, int, usb_proc_ptr);
215 #if defined(__FreeBSD__)
216 Static void ugen_make_devnodes(struct ugen_softc *sc);
217 Static void ugen_destroy_devnodes(struct ugen_softc *sc);
219 Static int ugen_set_config(struct ugen_softc *sc, int configno);
220 Static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc,
221 int index, int *lenp);
222 Static usbd_status ugen_set_interface(struct ugen_softc *, int, int);
223 Static int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx);
225 #define UGENUNIT(n) ((minor(n) >> 4) & 0xf)
226 #define UGENENDPOINT(n) (minor(n) & 0xf)
227 #define UGENMINOR(u, e) (((u) << 4) | (e))
229 USB_DECLARE_DRIVER(ugen);
233 USB_MATCH_START(ugen, uaa);
237 return (uaa->matchlvl);
240 return (UMATCH_GENERIC);
242 return (UMATCH_NONE);
247 USB_ATTACH_START(ugen, sc, uaa);
248 usbd_device_handle udev;
253 usbd_devinfo(uaa->device, 0, devinfo);
256 sc->sc_udev = udev = uaa->device;
258 memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
260 /* First set configuration index 0, the default one for ugen. */
261 err = usbd_set_config_index(udev, 0, 0);
263 printf("%s: setting configuration index 0 failed\n",
264 USBDEVNAME(sc->sc_dev));
266 USB_ATTACH_ERROR_RETURN;
268 conf = usbd_get_config_descriptor(udev)->bConfigurationValue;
270 /* Set up all the local state for this configuration. */
271 err = ugen_set_config(sc, conf);
273 printf("%s: setting configuration %d failed\n",
274 USBDEVNAME(sc->sc_dev), conf);
276 USB_ATTACH_ERROR_RETURN;
279 #if defined(__FreeBSD__)
280 /* the main device, ctrl endpoint */
281 sc->dev = make_dev(&ugenctl_cdevsw,
282 UGENMINOR(USBDEVUNIT(sc->sc_dev), 0), UID_ROOT, GID_OPERATOR, 0644,
283 "%s", USBDEVNAME(sc->sc_dev));
284 ugen_make_devnodes(sc);
287 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
290 USB_ATTACH_SUCCESS_RETURN;
293 #if defined(__FreeBSD__)
295 ugen_make_devnodes(struct ugen_softc *sc)
300 for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
301 if (sc->sc_endpoints[endptno][IN].sc != NULL ||
302 sc->sc_endpoints[endptno][OUT].sc != NULL ) {
303 /* endpt can be 0x81 and 0x01, representing
304 * endpoint address 0x01 and IN/OUT directions.
305 * We map both endpts to the same device,
306 * IN is reading from it, OUT is writing to it.
308 * In the if clause above we check whether one
309 * of the structs is populated.
311 dev = make_dev(&ugen_cdevsw,
312 UGENMINOR(USBDEVUNIT(sc->sc_dev), endptno),
313 UID_ROOT, GID_OPERATOR, 0644,
315 USBDEVNAME(sc->sc_dev), endptno);
316 dev_depends(sc->dev, dev);
317 if (sc->sc_endpoints[endptno][IN].sc != NULL)
318 sc->sc_endpoints[endptno][IN].dev = dev;
319 if (sc->sc_endpoints[endptno][OUT].sc != NULL)
320 sc->sc_endpoints[endptno][OUT].dev = dev;
326 ugen_destroy_devnodes(struct ugen_softc *sc)
328 int endptno, prev_sc_dying;
331 prev_sc_dying = sc->sc_dying;
333 /* destroy all devices for the other (existing) endpoints as well */
334 for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
335 if (sc->sc_endpoints[endptno][IN].sc != NULL ||
336 sc->sc_endpoints[endptno][OUT].sc != NULL ) {
337 /* endpt can be 0x81 and 0x01, representing
338 * endpoint address 0x01 and IN/OUT directions.
339 * We map both endpoint addresses to the same device,
340 * IN is reading from it, OUT is writing to it.
342 * In the if clause above we check whether one
343 * of the structs is populated.
345 if (sc->sc_endpoints[endptno][IN].sc != NULL)
346 dev = sc->sc_endpoints[endptno][IN].dev;
348 dev = sc->sc_endpoints[endptno][OUT].dev;
351 ("ugen_destroy_devnodes: NULL dev"));
355 sc->sc_endpoints[endptno][IN].sc = NULL;
356 sc->sc_endpoints[endptno][OUT].sc = NULL;
359 sc->sc_dying = prev_sc_dying;
364 ugen_set_config(struct ugen_softc *sc, int configno)
366 usbd_device_handle dev = sc->sc_udev;
367 usbd_interface_handle iface;
368 usb_endpoint_descriptor_t *ed;
369 struct ugen_endpoint *sce, **sce_cache, ***sce_cache_arr;
370 u_int8_t niface, niface_cache, nendpt, *nendpt_cache;
371 int ifaceno, endptno, endpt;
375 DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
376 USBDEVNAME(sc->sc_dev), configno, sc));
378 /* We start at 1, not 0, because we don't care whether the
379 * control endpoint is open or not. It is always present.
381 for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++)
382 if (sc->sc_is_open[endptno]) {
384 ("ugen_set_config: %s - endpoint %d is open\n",
385 USBDEVNAME(sc->sc_dev), endptno));
386 return (USBD_IN_USE);
389 err = usbd_interface_count(dev, &niface);
392 /* store an array of endpoint descriptors to clear if the configuration
393 * change succeeds - these aren't available afterwards */
394 nendpt_cache = malloc(sizeof(u_int8_t) * niface, M_TEMP, M_WAITOK |
396 sce_cache_arr = malloc(sizeof(struct ugen_endpoint **) * niface, M_TEMP,
398 niface_cache = niface;
400 for (ifaceno = 0; ifaceno < niface; ifaceno++) {
401 DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
402 err = usbd_device2interface_handle(dev, ifaceno, &iface);
404 panic("ugen_set_config: can't obtain interface handle");
405 err = usbd_endpoint_count(iface, &nendpt);
407 panic("ugen_set_config: endpoint count failed");
409 /* store endpoint descriptors for each interface */
410 nendpt_cache[ifaceno] = nendpt;
411 sce_cache = malloc(sizeof(struct ugen_endpoint *) * nendpt, M_TEMP,
413 sce_cache_arr[ifaceno] = sce_cache;
415 for (endptno = 0; endptno < nendpt; endptno++) {
416 ed = usbd_interface2endpoint_descriptor(iface,endptno);
417 endpt = ed->bEndpointAddress;
418 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
419 sce_cache[endptno] = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
423 /* Avoid setting the current value. */
424 if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) {
425 /* attempt to perform the configuration change */
426 err = usbd_set_config_no(dev, configno, 1);
428 for(ifaceno = 0; ifaceno < niface_cache; ifaceno++)
429 free(sce_cache_arr[ifaceno], M_TEMP);
430 free(sce_cache_arr, M_TEMP);
431 free(nendpt_cache, M_TEMP);
436 #if defined(__FreeBSD__)
437 ugen_destroy_devnodes(sc);
440 /* now we can clear the old interface's ugen_endpoints */
441 for(ifaceno = 0; ifaceno < niface_cache; ifaceno++) {
442 sce_cache = sce_cache_arr[ifaceno];
443 for(endptno = 0; endptno < nendpt_cache[ifaceno]; endptno++) {
444 sce = sce_cache[endptno];
451 /* and free the cache storing them */
452 for(ifaceno = 0; ifaceno < niface_cache; ifaceno++)
453 free(sce_cache_arr[ifaceno], M_TEMP);
454 free(sce_cache_arr, M_TEMP);
455 free(nendpt_cache, M_TEMP);
457 /* no endpoints if the device is in the unconfigured state */
458 if (configno != USB_UNCONFIG_NO)
460 /* set the new configuration's ugen_endpoints */
461 err = usbd_interface_count(dev, &niface);
463 panic("ugen_set_config: interface count failed");
465 memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
466 for (ifaceno = 0; ifaceno < niface; ifaceno++) {
467 DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
468 err = usbd_device2interface_handle(dev, ifaceno, &iface);
470 panic("ugen_set_config: can't obtain interface handle");
471 err = usbd_endpoint_count(iface, &nendpt);
473 panic("ugen_set_config: endpoint count failed");
474 for (endptno = 0; endptno < nendpt; endptno++) {
475 ed = usbd_interface2endpoint_descriptor(iface,endptno);
476 endpt = ed->bEndpointAddress;
477 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
478 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
479 DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x"
481 endptno, endpt, UE_GET_ADDR(endpt),
482 UE_GET_DIR(endpt), sce));
490 return (USBD_NORMAL_COMPLETION);
494 ugenopen(struct cdev *dev, int flag, int mode, usb_proc_ptr p)
496 struct ugen_softc *sc;
497 int unit = UGENUNIT(dev);
498 int endpt = UGENENDPOINT(dev);
499 usb_endpoint_descriptor_t *edesc;
500 struct ugen_endpoint *sce;
503 usbd_xfer_handle xfer;
507 USB_GET_SC_OPEN(ugen, unit, sc);
509 DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
510 flag, mode, unit, endpt));
512 if (sc == NULL || sc->sc_dying)
515 if (sc->sc_is_open[endpt])
518 if (endpt == USB_CONTROL_ENDPOINT) {
519 sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
520 UGEN_DEV_OPEN(dev, sc);
524 /* Make sure there are pipes for all directions. */
525 for (dir = OUT; dir <= IN; dir++) {
526 if (flag & (dir == OUT ? FWRITE : FREAD)) {
527 sce = &sc->sc_endpoints[endpt][dir];
533 /* Actually open the pipes. */
534 /* XXX Should back out properly if it fails. */
535 for (dir = OUT; dir <= IN; dir++) {
536 if (!(flag & (dir == OUT ? FWRITE : FREAD)))
538 sce = &sc->sc_endpoints[endpt][dir];
540 sce->timeout = USBD_NO_TIMEOUT;
541 DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
542 sc, endpt, dir, sce));
544 switch (edesc->bmAttributes & UE_XFERTYPE) {
547 err = usbd_open_pipe(sce->iface,
548 edesc->bEndpointAddress, 0, &sce->pipeh);
553 isize = UGETW(edesc->wMaxPacketSize);
554 if (isize == 0) /* shouldn't happen */
556 sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
557 DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
559 if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
561 err = usbd_open_pipe_intr(sce->iface,
562 edesc->bEndpointAddress,
563 USBD_SHORT_XFER_OK, &sce->pipeh, sce,
564 sce->ibuf, isize, ugenintr,
565 USBD_DEFAULT_INTERVAL);
567 free(sce->ibuf, M_USBDEV);
571 DPRINTFN(5, ("ugenopen: interrupt open done\n"));
574 err = usbd_open_pipe(sce->iface,
575 edesc->bEndpointAddress, 0, &sce->pipeh);
582 isize = UGETW(edesc->wMaxPacketSize);
583 if (isize == 0) /* shouldn't happen */
585 sce->ibuf = malloc(isize * UGEN_NISOFRAMES,
587 sce->cur = sce->fill = sce->ibuf;
588 sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES;
589 DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n",
591 err = usbd_open_pipe(sce->iface,
592 edesc->bEndpointAddress, 0, &sce->pipeh);
594 free(sce->ibuf, M_USBDEV);
597 for(i = 0; i < UGEN_NISOREQS; ++i) {
598 sce->isoreqs[i].sce = sce;
599 xfer = usbd_alloc_xfer(sc->sc_udev);
602 sce->isoreqs[i].xfer = xfer;
603 buf = usbd_alloc_buffer
604 (xfer, isize * UGEN_NISORFRMS);
609 sce->isoreqs[i].dmabuf = buf;
610 for(j = 0; j < UGEN_NISORFRMS; ++j)
611 sce->isoreqs[i].sizes[j] = isize;
613 (xfer, sce->pipeh, &sce->isoreqs[i],
614 sce->isoreqs[i].sizes,
615 UGEN_NISORFRMS, USBD_NO_COPY,
617 (void)usbd_transfer(xfer);
619 DPRINTFN(5, ("ugenopen: isoc open done\n"));
622 while (--i >= 0) /* implicit buffer free */
623 usbd_free_xfer(sce->isoreqs[i].xfer);
626 sce->timeout = USBD_DEFAULT_TIMEOUT;
630 sc->sc_is_open[endpt] = 1;
631 UGEN_DEV_OPEN(dev, sc);
636 ugenclose(struct cdev *dev, int flag, int mode, usb_proc_ptr p)
638 int endpt = UGENENDPOINT(dev);
639 struct ugen_softc *sc;
640 struct ugen_endpoint *sce;
644 USB_GET_SC(ugen, UGENUNIT(dev), sc);
646 DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
647 flag, mode, UGENUNIT(dev), endpt));
650 if (!sc->sc_is_open[endpt]) {
651 printf("ugenclose: not open\n");
656 if (endpt == USB_CONTROL_ENDPOINT) {
657 DPRINTFN(5, ("ugenclose: close control\n"));
658 sc->sc_is_open[endpt] = 0;
659 UGEN_DEV_CLOSE(dev, sc);
663 for (dir = OUT; dir <= IN; dir++) {
664 if (!(flag & (dir == OUT ? FWRITE : FREAD)))
666 sce = &sc->sc_endpoints[endpt][dir];
667 if (sce->pipeh == NULL)
669 DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
672 usbd_abort_pipe(sce->pipeh);
673 usbd_close_pipe(sce->pipeh);
676 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
678 ndflush(&sce->q, sce->q.c_cc);
682 for (i = 0; i < UGEN_NISOREQS; ++i)
683 usbd_free_xfer(sce->isoreqs[i].xfer);
689 if (sce->ibuf != NULL) {
690 free(sce->ibuf, M_USBDEV);
695 sc->sc_is_open[endpt] = 0;
696 UGEN_DEV_CLOSE(dev, sc);
702 ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
704 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
706 char buf[UGEN_BBSIZE];
707 usbd_xfer_handle xfer;
711 u_char buffer[UGEN_CHUNK];
713 DPRINTFN(5, ("%s: ugenread: %d\n", USBDEVNAME(sc->sc_dev), endpt));
718 if (endpt == USB_CONTROL_ENDPOINT)
722 if (sce->edesc == NULL) {
723 printf("ugenread: no edesc\n");
726 if (sce->pipeh == NULL) {
727 printf("ugenread: no pipe\n");
732 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
734 /* Block until activity occurred. */
736 while (sce->q.c_cc == 0) {
737 if (flag & O_NONBLOCK) {
739 return (EWOULDBLOCK);
741 sce->state |= UGEN_ASLP;
742 DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
743 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0);
744 sce->state &= ~UGEN_ASLP;
745 DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
753 /* Transfer as many chunks as possible. */
754 while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) {
755 n = min(sce->q.c_cc, uio->uio_resid);
756 if (n > sizeof(buffer))
759 /* Remove a small chunk from the input queue. */
760 q_to_b(&sce->q, buffer, n);
761 DPRINTFN(5, ("ugenread: got %d chars\n", n));
763 /* Copy the data to the user process. */
764 error = uiomove(buffer, n, uio);
770 xfer = usbd_alloc_xfer(sc->sc_udev);
773 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
774 DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
776 err = usbd_bulk_transfer(
778 sce->state & UGEN_SHORT_OK ?
779 USBD_SHORT_XFER_OK : 0,
780 sce->timeout, buf, &tn, "ugenrb");
782 if (err == USBD_INTERRUPTED)
784 else if (err == USBD_TIMEOUT)
790 DPRINTFN(1, ("ugenread: got %d bytes\n", tn));
791 error = uiomove(buf, tn, uio);
795 usbd_free_xfer(xfer);
799 while (sce->cur == sce->fill) {
800 if (flag & O_NONBLOCK) {
802 return (EWOULDBLOCK);
804 sce->state |= UGEN_ASLP;
805 DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
806 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0);
807 sce->state &= ~UGEN_ASLP;
808 DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
815 while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) {
816 if(sce->fill > sce->cur)
817 n = min(sce->fill - sce->cur, uio->uio_resid);
819 n = min(sce->limit - sce->cur, uio->uio_resid);
821 DPRINTFN(5, ("ugenread: isoc got %d chars\n", n));
823 /* Copy the data to the user process. */
824 error = uiomove(sce->cur, n, uio);
828 if(sce->cur >= sce->limit)
829 sce->cur = sce->ibuf;
842 ugenread(struct cdev *dev, struct uio *uio, int flag)
844 int endpt = UGENENDPOINT(dev);
845 struct ugen_softc *sc;
848 USB_GET_SC(ugen, UGENUNIT(dev), sc);
853 UGEN_DEV_REF(dev, sc);
854 error = ugen_do_read(sc, endpt, uio, flag);
855 UGEN_DEV_RELE(dev, sc);
860 ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
862 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
865 char buf[UGEN_BBSIZE];
866 usbd_xfer_handle xfer;
869 DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc->sc_dev), endpt));
874 if (endpt == USB_CONTROL_ENDPOINT)
878 if (sce->edesc == NULL) {
879 printf("ugenwrite: no edesc\n");
882 if (sce->pipeh == NULL) {
883 printf("ugenwrite: no pipe\n");
888 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
890 xfer = usbd_alloc_xfer(sc->sc_udev);
893 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
894 error = uiomove(buf, n, uio);
897 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
898 err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
899 sce->timeout, buf, &n,"ugenwb");
901 if (err == USBD_INTERRUPTED)
903 else if (err == USBD_TIMEOUT)
910 usbd_free_xfer(xfer);
913 xfer = usbd_alloc_xfer(sc->sc_udev);
916 while ((n = min(UGETW(sce->edesc->wMaxPacketSize),
917 uio->uio_resid)) != 0) {
918 error = uiomove(buf, n, uio);
921 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
922 err = usbd_intr_transfer(xfer, sce->pipeh, 0,
923 sce->timeout, buf, &n, "ugenwi");
925 if (err == USBD_INTERRUPTED)
927 else if (err == USBD_TIMEOUT)
934 usbd_free_xfer(xfer);
943 ugenwrite(struct cdev *dev, struct uio *uio, int flag)
945 int endpt = UGENENDPOINT(dev);
946 struct ugen_softc *sc;
949 USB_GET_SC(ugen, UGENUNIT(dev), sc);
954 UGEN_DEV_REF(dev, sc);
955 error = ugen_do_write(sc, endpt, uio, flag);
956 UGEN_DEV_RELE(dev, sc);
960 #if defined(__NetBSD__) || defined(__OpenBSD__)
962 ugen_activate(device_ptr_t self, enum devact act)
964 struct ugen_softc *sc = (struct ugen_softc *)self;
970 case DVACT_DEACTIVATE:
980 ugenpurge(struct cdev *dev)
982 int endpt = UGENENDPOINT(dev);
983 struct ugen_endpoint *sce;
984 struct ugen_softc *sc;
986 if (endpt == USB_CONTROL_ENDPOINT)
988 USB_GET_SC(ugen, UGENUNIT(dev), sc);
989 sce = &sc->sc_endpoints[endpt][IN];
991 usbd_abort_pipe(sce->pipeh);
992 if (sce->state & UGEN_ASLP) {
993 DPRINTFN(5, ("ugenpurge: waking %p\n", sce));
996 selwakeuppri(&sce->rsel, PZERO);
998 sce = &sc->sc_endpoints[endpt][OUT];
1000 usbd_abort_pipe(sce->pipeh);
1001 if (sce->state & UGEN_ASLP) {
1002 DPRINTFN(5, ("ugenpurge: waking %p\n", sce));
1005 selwakeuppri(&sce->rsel, PZERO);
1011 USB_DETACH_START(ugen, sc);
1012 struct ugen_endpoint *sce;
1014 #if defined(__NetBSD__) || defined(__OpenBSD__)
1018 #if defined(__NetBSD__) || defined(__OpenBSD__)
1019 DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags));
1020 #elif defined(__FreeBSD__)
1021 DPRINTF(("ugen_detach: sc=%p\n", sc));
1025 /* Abort all pipes. Causes processes waiting for transfer to wake. */
1026 for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
1027 for (dir = OUT; dir <= IN; dir++) {
1028 sce = &sc->sc_endpoints[i][dir];
1030 usbd_abort_pipe(sce->pipeh);
1031 selwakeuppri(&sce->rsel, PZERO);
1035 #if defined(__NetBSD__) || defined(__OpenBSD__)
1037 if (sc->sc_refcnt > 0) {
1039 for (i = 0; i < USB_MAX_ENDPOINTS; i++)
1040 wakeup(&sc->sc_endpoints[i][IN]);
1041 /* Wait for processes to go away. */
1042 while (sc->sc_refcnt > 0)
1043 usb_detach_wait(USBDEV(sc->sc_dev));
1047 /* Wait for opens to go away. */
1050 for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
1051 if (sc->sc_is_open[i])
1055 tsleep(&sc->sc_dying, PZERO, "ugendr", hz);
1058 /* locate the major number */
1059 for (maj = 0; maj < nchrdev; maj++)
1060 if (cdevsw[maj].d_open == ugenopen)
1063 /* Nuke the vnodes for any open instances (calls close). */
1064 mn = self->dv_unit * USB_MAX_ENDPOINTS;
1065 vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR);
1066 #elif defined(__FreeBSD__)
1067 /* destroy the device for the control endpoint */
1068 destroy_dev(sc->dev);
1071 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
1072 USBDEV(sc->sc_dev));
1078 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
1080 struct ugen_endpoint *sce = addr;
1081 /*struct ugen_softc *sc = sce->sc;*/
1085 if (status == USBD_CANCELLED)
1088 if (status != USBD_NORMAL_COMPLETION) {
1089 DPRINTF(("ugenintr: status=%d\n", status));
1090 if (status == USBD_STALLED)
1091 usbd_clear_endpoint_stall_async(sce->pipeh);
1095 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1098 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
1099 xfer, status, count));
1100 DPRINTFN(5, (" data = %02x %02x %02x\n",
1101 ibuf[0], ibuf[1], ibuf[2]));
1103 (void)b_to_q(ibuf, count, &sce->q);
1105 if (sce->state & UGEN_ASLP) {
1106 sce->state &= ~UGEN_ASLP;
1107 DPRINTFN(5, ("ugen_intr: waking %p\n", sce));
1110 selwakeuppri(&sce->rsel, PZERO);
1114 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
1117 struct isoreq *req = addr;
1118 struct ugen_endpoint *sce = req->sce;
1122 /* Return if we are aborting. */
1123 if (status == USBD_CANCELLED)
1126 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1127 DPRINTFN(5,("ugen_isoc_rintr: xfer %d, count=%d\n",
1128 (int)(req - sce->isoreqs),
1131 /* throw away oldest input if the buffer is full */
1132 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) {
1134 if(sce->cur >= sce->limit)
1135 sce->cur = sce->ibuf + (sce->limit - sce->cur);
1136 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n",
1140 isize = UGETW(sce->edesc->wMaxPacketSize);
1141 for (i = 0; i < UGEN_NISORFRMS; i++) {
1142 u_int32_t actlen = req->sizes[i];
1143 char const *buf = (char const *)req->dmabuf + isize * i;
1145 /* copy data to buffer */
1146 while (actlen > 0) {
1147 n = min(actlen, sce->limit - sce->fill);
1148 memcpy(sce->fill, buf, n);
1153 if(sce->fill == sce->limit)
1154 sce->fill = sce->ibuf;
1157 /* setup size for next transfer */
1158 req->sizes[i] = isize;
1161 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS,
1162 USBD_NO_COPY, ugen_isoc_rintr);
1163 (void)usbd_transfer(xfer);
1165 if (sce->state & UGEN_ASLP) {
1166 sce->state &= ~UGEN_ASLP;
1167 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce));
1170 selwakeuppri(&sce->rsel, PZERO);
1174 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno)
1176 usbd_interface_handle iface;
1177 usb_endpoint_descriptor_t *ed;
1179 struct ugen_endpoint *sce, **sce_cache;
1180 u_int8_t niface, nendpt, nendpt_cache, endptno, endpt;
1183 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
1185 err = usbd_interface_count(sc->sc_udev, &niface);
1188 if (ifaceidx < 0 || ifaceidx >= niface)
1189 return (USBD_INVAL);
1191 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
1194 err = usbd_endpoint_count(iface, &nendpt);
1198 /* store an array of endpoint descriptors to clear if the interface
1199 * change succeeds - these aren't available afterwards */
1200 sce_cache = malloc(sizeof(struct ugen_endpoint *) * nendpt, M_TEMP,
1202 nendpt_cache = nendpt;
1204 for (endptno = 0; endptno < nendpt; endptno++) {
1205 ed = usbd_interface2endpoint_descriptor(iface,endptno);
1206 endpt = ed->bEndpointAddress;
1207 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
1208 sce_cache[endptno] = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
1211 /* change setting */
1212 err = usbd_set_interface(iface, altno);
1214 free(sce_cache, M_TEMP);
1217 err = usbd_endpoint_count(iface, &nendpt);
1219 panic("ugen_set_interface: endpoint count failed");
1221 #if defined(__FreeBSD__)
1222 /* destroy the existing devices, we remake the new ones in a moment */
1223 ugen_destroy_devnodes(sc);
1226 /* now we can clear the old interface's ugen_endpoints */
1227 for (endptno = 0; endptno < nendpt_cache; endptno++) {
1228 sce = sce_cache[endptno];
1233 free(sce_cache, M_TEMP);
1235 /* set the new interface's ugen_endpoints */
1236 for (endptno = 0; endptno < nendpt; endptno++) {
1237 ed = usbd_interface2endpoint_descriptor(iface,endptno);
1238 endpt = ed->bEndpointAddress;
1239 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
1240 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
1246 #if defined(__FreeBSD__)
1247 /* make the new devices */
1248 ugen_make_devnodes(sc);
1254 /* Retrieve a complete descriptor for a certain device and index. */
1255 Static usb_config_descriptor_t *
1256 ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp)
1258 usb_config_descriptor_t *cdesc, *tdesc, cdescr;
1262 if (index == USB_CURRENT_CONFIG_INDEX) {
1263 tdesc = usbd_get_config_descriptor(sc->sc_udev);
1264 len = UGETW(tdesc->wTotalLength);
1267 cdesc = malloc(len, M_TEMP, M_WAITOK);
1268 memcpy(cdesc, tdesc, len);
1269 DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
1271 err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
1274 len = UGETW(cdescr.wTotalLength);
1275 DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
1278 cdesc = malloc(len, M_TEMP, M_WAITOK);
1279 err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
1281 free(cdesc, M_TEMP);
1289 ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx)
1291 usbd_interface_handle iface;
1294 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
1297 return (usbd_get_interface_altindex(iface));
1301 ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
1302 caddr_t addr, int flag, usb_proc_ptr p)
1304 struct ugen_endpoint *sce;
1306 usbd_interface_handle iface;
1307 struct usb_config_desc *cd;
1308 usb_config_descriptor_t *cdesc;
1309 struct usb_interface_desc *id;
1310 usb_interface_descriptor_t *idesc;
1311 struct usb_endpoint_desc *ed;
1312 usb_endpoint_descriptor_t *edesc;
1313 struct usb_alt_interface *ai;
1314 struct usb_string_desc *si;
1317 DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd));
1324 /* All handled in the upper FS layer. */
1326 case USB_SET_SHORT_XFER:
1327 if (endpt == USB_CONTROL_ENDPOINT)
1329 /* This flag only affects read */
1330 sce = &sc->sc_endpoints[endpt][IN];
1332 if (sce->pipeh == NULL) {
1333 printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n");
1338 sce->state |= UGEN_SHORT_OK;
1340 sce->state &= ~UGEN_SHORT_OK;
1342 case USB_SET_TIMEOUT:
1343 sce = &sc->sc_endpoints[endpt][IN];
1344 sce->timeout = *(int *)addr;
1350 if (endpt != USB_CONTROL_ENDPOINT)
1356 ugendebug = *(int *)addr;
1359 case USB_GET_CONFIG:
1360 err = usbd_get_config(sc->sc_udev, &conf);
1363 *(int *)addr = conf;
1365 case USB_SET_CONFIG:
1366 if (!(flag & FWRITE))
1368 err = ugen_set_config(sc, *(int *)addr);
1370 case USBD_NORMAL_COMPLETION:
1371 #if defined(__FreeBSD__)
1372 ugen_make_devnodes(sc);
1381 case USB_GET_ALTINTERFACE:
1382 ai = (struct usb_alt_interface *)addr;
1383 err = usbd_device2interface_handle(sc->sc_udev,
1384 ai->uai_interface_index, &iface);
1387 idesc = usbd_get_interface_descriptor(iface);
1390 ai->uai_alt_no = idesc->bAlternateSetting;
1392 case USB_SET_ALTINTERFACE:
1393 if (!(flag & FWRITE))
1395 ai = (struct usb_alt_interface *)addr;
1396 err = usbd_device2interface_handle(sc->sc_udev,
1397 ai->uai_interface_index, &iface);
1400 err = ugen_set_interface(sc, ai->uai_interface_index,
1405 case USB_GET_NO_ALT:
1406 ai = (struct usb_alt_interface *)addr;
1407 cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0);
1410 idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0);
1411 if (idesc == NULL) {
1412 free(cdesc, M_TEMP);
1415 ai->uai_alt_no = usbd_get_no_alts(cdesc,
1416 idesc->bInterfaceNumber);
1417 free(cdesc, M_TEMP);
1419 case USB_GET_DEVICE_DESC:
1420 *(usb_device_descriptor_t *)addr =
1421 *usbd_get_device_descriptor(sc->sc_udev);
1423 case USB_GET_CONFIG_DESC:
1424 cd = (struct usb_config_desc *)addr;
1425 cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0);
1428 cd->ucd_desc = *cdesc;
1429 free(cdesc, M_TEMP);
1431 case USB_GET_INTERFACE_DESC:
1432 id = (struct usb_interface_desc *)addr;
1433 cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0);
1436 if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX &&
1437 id->uid_alt_index == USB_CURRENT_ALT_INDEX)
1438 alt = ugen_get_alt_index(sc, id->uid_interface_index);
1440 alt = id->uid_alt_index;
1441 idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt);
1442 if (idesc == NULL) {
1443 free(cdesc, M_TEMP);
1446 id->uid_desc = *idesc;
1447 free(cdesc, M_TEMP);
1449 case USB_GET_ENDPOINT_DESC:
1450 ed = (struct usb_endpoint_desc *)addr;
1451 cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0);
1454 if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX &&
1455 ed->ued_alt_index == USB_CURRENT_ALT_INDEX)
1456 alt = ugen_get_alt_index(sc, ed->ued_interface_index);
1458 alt = ed->ued_alt_index;
1459 edesc = usbd_find_edesc(cdesc, ed->ued_interface_index,
1460 alt, ed->ued_endpoint_index);
1461 if (edesc == NULL) {
1462 free(cdesc, M_TEMP);
1465 ed->ued_desc = *edesc;
1466 free(cdesc, M_TEMP);
1468 case USB_GET_FULL_DESC:
1473 struct usb_full_desc *fd = (struct usb_full_desc *)addr;
1476 cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len);
1477 if (len > fd->ufd_size)
1479 iov.iov_base = (caddr_t)fd->ufd_data;
1483 uio.uio_resid = len;
1485 uio.uio_segflg = UIO_USERSPACE;
1486 uio.uio_rw = UIO_READ;
1488 error = uiomove((void *)cdesc, len, &uio);
1489 free(cdesc, M_TEMP);
1492 case USB_GET_STRING_DESC: {
1494 si = (struct usb_string_desc *)addr;
1495 err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
1496 si->usd_language_id, &si->usd_desc, &len);
1501 case USB_DO_REQUEST:
1503 struct usb_ctl_request *ur = (void *)addr;
1504 int len = UGETW(ur->ucr_request.wLength);
1511 if (!(flag & FWRITE))
1513 /* Avoid requests that would damage the bus integrity. */
1514 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1515 ur->ucr_request.bRequest == UR_SET_ADDRESS) ||
1516 (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1517 ur->ucr_request.bRequest == UR_SET_CONFIG) ||
1518 (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE &&
1519 ur->ucr_request.bRequest == UR_SET_INTERFACE))
1522 if (len < 0 || len > 32767)
1525 iov.iov_base = (caddr_t)ur->ucr_data;
1529 uio.uio_resid = len;
1531 uio.uio_segflg = UIO_USERSPACE;
1533 ur->ucr_request.bmRequestType & UT_READ ?
1534 UIO_READ : UIO_WRITE;
1536 ptr = malloc(len, M_TEMP, M_WAITOK);
1537 if (uio.uio_rw == UIO_WRITE) {
1538 error = uiomove(ptr, len, &uio);
1543 sce = &sc->sc_endpoints[endpt][IN];
1544 err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request,
1545 ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout);
1551 if (uio.uio_rw == UIO_READ) {
1552 error = uiomove(ptr, len, &uio);
1562 case USB_GET_DEVICEINFO:
1563 usbd_fill_deviceinfo(sc->sc_udev,
1564 (struct usb_device_info *)addr, 1);
1573 ugenioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
1575 int endpt = UGENENDPOINT(dev);
1576 struct ugen_softc *sc;
1579 USB_GET_SC(ugen, UGENUNIT(dev), sc);
1584 UGEN_DEV_REF(dev, sc);
1585 error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
1586 UGEN_DEV_RELE(dev, sc);
1591 ugenpoll(struct cdev *dev, int events, usb_proc_ptr p)
1593 struct ugen_softc *sc;
1594 struct ugen_endpoint *sce_in, *sce_out;
1595 usb_endpoint_descriptor_t *edesc;
1599 USB_GET_SC(ugen, UGENUNIT(dev), sc);
1602 return ((events & (POLLIN | POLLOUT | POLLRDNORM |
1603 POLLWRNORM)) | POLLHUP);
1604 /* Do not allow to poll a control endpoint */
1605 if (UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT)
1606 return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1608 sce_in = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1609 sce_out = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT];
1610 edesc = (sce_in->edesc != NULL) ? sce_in->edesc : sce_out->edesc;
1611 KASSERT(edesc != NULL, ("ugenpoll: NULL edesc"));
1612 if (sce_in->edesc == NULL || sce_in->pipeh == NULL)
1614 if (sce_out->edesc == NULL || sce_out->pipeh == NULL)
1618 switch (edesc->bmAttributes & UE_XFERTYPE) {
1620 if (sce_in != NULL && (events & (POLLIN | POLLRDNORM))) {
1621 if (sce_in->q.c_cc > 0)
1622 revents |= events & (POLLIN | POLLRDNORM);
1624 selrecord(p, &sce_in->rsel);
1626 if (sce_out != NULL && (events & (POLLOUT | POLLWRNORM))) {
1627 if (sce_out->q.c_cc > 0)
1628 revents |= events & (POLLOUT | POLLWRNORM);
1630 selrecord(p, &sce_out->rsel);
1633 case UE_ISOCHRONOUS:
1634 if (sce_in != NULL && (events & (POLLIN | POLLRDNORM))) {
1635 if (sce_in->cur != sce_in->fill)
1636 revents |= events & (POLLIN | POLLRDNORM);
1638 selrecord(p, &sce_in->rsel);
1640 if (sce_out != NULL && (events & (POLLOUT | POLLWRNORM))) {
1641 if (sce_out->cur != sce_out->fill)
1642 revents |= events & (POLLOUT | POLLWRNORM);
1644 selrecord(p, &sce_out->rsel);
1649 * We have no easy way of determining if a read will
1650 * yield any data or a write will happen.
1651 * Pretend they will.
1654 (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
1663 #if defined(__FreeBSD__)
1664 DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, usbd_driver_load, 0);