ugen.c revision 1.49 1 /* $NetBSD: ugen.c,v 1.49 2001/10/24 22:31:04 augustss Exp $ */
2 /* $FreeBSD: src/sys/dev/usb/ugen.c,v 1.26 1999/11/17 22:33:41 n_hibma Exp $ */
3
4 /*
5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart (at) augustsson.net) at
10 * Carlstedt Research & Technology.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the NetBSD
23 * Foundation, Inc. and its contributors.
24 * 4. Neither the name of The NetBSD Foundation nor the names of its
25 * contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/malloc.h>
46 #if defined(__NetBSD__) || defined(__OpenBSD__)
47 #include <sys/device.h>
48 #include <sys/ioctl.h>
49 #elif defined(__FreeBSD__)
50 #include <sys/module.h>
51 #include <sys/bus.h>
52 #include <sys/ioccom.h>
53 #include <sys/conf.h>
54 #include <sys/fcntl.h>
55 #include <sys/filio.h>
56 #endif
57 #include <sys/conf.h>
58 #include <sys/tty.h>
59 #include <sys/file.h>
60 #include <sys/select.h>
61 #include <sys/proc.h>
62 #include <sys/vnode.h>
63 #include <sys/poll.h>
64
65 #include <dev/usb/usb.h>
66 #include <dev/usb/usbdi.h>
67 #include <dev/usb/usbdi_util.h>
68
69 #ifdef UGEN_DEBUG
70 #define DPRINTF(x) if (ugendebug) logprintf x
71 #define DPRINTFN(n,x) if (ugendebug>(n)) logprintf x
72 int ugendebug = 0;
73 #else
74 #define DPRINTF(x)
75 #define DPRINTFN(n,x)
76 #endif
77
78 #define UGEN_CHUNK 128 /* chunk size for read */
79 #define UGEN_IBSIZE 1020 /* buffer size */
80 #define UGEN_BBSIZE 1024
81
82 #define UGEN_NISOFRAMES 500 /* 0.5 seconds worth */
83 #define UGEN_NISOREQS 6 /* number of outstanding xfer requests */
84 #define UGEN_NISORFRMS 4 /* number of frames (miliseconds) per req */
85
86 struct ugen_endpoint {
87 struct ugen_softc *sc;
88 usb_endpoint_descriptor_t *edesc;
89 usbd_interface_handle iface;
90 int state;
91 #define UGEN_ASLP 0x02 /* waiting for data */
92 #define UGEN_SHORT_OK 0x04 /* short xfers are OK */
93 usbd_pipe_handle pipeh;
94 struct clist q;
95 struct selinfo rsel;
96 u_char *ibuf; /* start of buffer (circular for isoc) */
97 u_char *fill; /* location for input (isoc) */
98 u_char *limit; /* end of circular buffer (isoc) */
99 u_char *cur; /* current read location (isoc) */
100 u_int32_t timeout;
101 struct isoreq {
102 struct ugen_endpoint *sce;
103 usbd_xfer_handle xfer;
104 void *dmabuf;
105 u_int16_t sizes[UGEN_NISORFRMS];
106 } isoreqs[UGEN_NISOREQS];
107 };
108
109 struct ugen_softc {
110 USBBASEDEVICE sc_dev; /* base device */
111 usbd_device_handle sc_udev;
112
113 char sc_is_open[USB_MAX_ENDPOINTS];
114 struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2];
115 #define OUT 0
116 #define IN 1
117
118 int sc_refcnt;
119 u_char sc_dying;
120 };
121
122 #if defined(__NetBSD__) || defined(__OpenBSD__)
123 cdev_decl(ugen);
124 #elif defined(__FreeBSD__)
125 d_open_t ugenopen;
126 d_close_t ugenclose;
127 d_read_t ugenread;
128 d_write_t ugenwrite;
129 d_ioctl_t ugenioctl;
130 d_poll_t ugenpoll;
131
132 #define UGEN_CDEV_MAJOR 114
133
134 Static struct cdevsw ugen_cdevsw = {
135 /* open */ ugenopen,
136 /* close */ ugenclose,
137 /* read */ ugenread,
138 /* write */ ugenwrite,
139 /* ioctl */ ugenioctl,
140 /* poll */ ugenpoll,
141 /* mmap */ nommap,
142 /* strategy */ nostrategy,
143 /* name */ "ugen",
144 /* maj */ UGEN_CDEV_MAJOR,
145 /* dump */ nodump,
146 /* psize */ nopsize,
147 /* flags */ 0,
148 /* bmaj */ -1
149 };
150 #endif
151
152 Static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr,
153 usbd_status status);
154 Static void ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
155 usbd_status status);
156 Static int ugen_do_read(struct ugen_softc *, int, struct uio *, int);
157 Static int ugen_do_write(struct ugen_softc *, int, struct uio *, int);
158 Static int ugen_do_ioctl(struct ugen_softc *, int, u_long,
159 caddr_t, int, struct proc *);
160 Static int ugen_set_config(struct ugen_softc *sc, int configno);
161 Static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc,
162 int index, int *lenp);
163 Static usbd_status ugen_set_interface(struct ugen_softc *, int, int);
164 Static int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx);
165
166 #define UGENUNIT(n) ((minor(n) >> 4) & 0xf)
167 #define UGENENDPOINT(n) (minor(n) & 0xf)
168 #define UGENDEV(u, e) (makedev(0, ((u) << 4) | (e)))
169
170 USB_DECLARE_DRIVER(ugen);
171
172 USB_MATCH(ugen)
173 {
174 USB_MATCH_START(ugen, uaa);
175
176 #if 0
177 if (uaa->matchlvl)
178 return (uaa->matchlvl);
179 #endif
180 if (uaa->usegeneric)
181 return (UMATCH_GENERIC);
182 else
183 return (UMATCH_NONE);
184 }
185
186 USB_ATTACH(ugen)
187 {
188 USB_ATTACH_START(ugen, sc, uaa);
189 usbd_device_handle udev;
190 char devinfo[1024];
191 usbd_status err;
192 int conf;
193
194 usbd_devinfo(uaa->device, 0, devinfo);
195 USB_ATTACH_SETUP;
196 printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
197
198 sc->sc_udev = udev = uaa->device;
199
200 /* First set configuration index 0, the default one for ugen. */
201 err = usbd_set_config_index(udev, 0, 0);
202 if (err) {
203 printf("%s: setting configuration index 0 failed\n",
204 USBDEVNAME(sc->sc_dev));
205 sc->sc_dying = 1;
206 USB_ATTACH_ERROR_RETURN;
207 }
208 conf = usbd_get_config_descriptor(udev)->bConfigurationValue;
209
210 /* Set up all the local state for this configuration. */
211 err = ugen_set_config(sc, conf);
212 if (err) {
213 printf("%s: setting configuration %d failed\n",
214 USBDEVNAME(sc->sc_dev), conf);
215 sc->sc_dying = 1;
216 USB_ATTACH_ERROR_RETURN;
217 }
218
219 #ifdef __FreeBSD__
220 {
221 static int global_init_done = 0;
222 if (!global_init_done) {
223 cdevsw_add(&ugen_cdevsw);
224 global_init_done = 1;
225 }
226 }
227 #endif
228
229 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
230 USBDEV(sc->sc_dev));
231
232 USB_ATTACH_SUCCESS_RETURN;
233 }
234
235 Static int
236 ugen_set_config(struct ugen_softc *sc, int configno)
237 {
238 usbd_device_handle dev = sc->sc_udev;
239 usbd_interface_handle iface;
240 usb_endpoint_descriptor_t *ed;
241 struct ugen_endpoint *sce;
242 u_int8_t niface, nendpt;
243 int ifaceno, endptno, endpt;
244 usbd_status err;
245 int dir;
246
247 DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
248 USBDEVNAME(sc->sc_dev), configno, sc));
249 /* Avoid setting the current value. */
250 if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) {
251 err = usbd_set_config_no(dev, configno, 1);
252 if (err)
253 return (err);
254 }
255
256 err = usbd_interface_count(dev, &niface);
257 if (err)
258 return (err);
259 memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
260 for (ifaceno = 0; ifaceno < niface; ifaceno++) {
261 DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
262 err = usbd_device2interface_handle(dev, ifaceno, &iface);
263 if (err)
264 return (err);
265 err = usbd_endpoint_count(iface, &nendpt);
266 if (err)
267 return (err);
268 for (endptno = 0; endptno < nendpt; endptno++) {
269 ed = usbd_interface2endpoint_descriptor(iface,endptno);
270 endpt = ed->bEndpointAddress;
271 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
272 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
273 DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x"
274 "(%d,%d), sce=%p\n",
275 endptno, endpt, UE_GET_ADDR(endpt),
276 UE_GET_DIR(endpt), sce));
277 sce->sc = sc;
278 sce->edesc = ed;
279 sce->iface = iface;
280 }
281 }
282 return (USBD_NORMAL_COMPLETION);
283 }
284
285 int
286 ugenopen(dev_t dev, int flag, int mode, struct proc *p)
287 {
288 struct ugen_softc *sc;
289 int unit = UGENUNIT(dev);
290 int endpt = UGENENDPOINT(dev);
291 usb_endpoint_descriptor_t *edesc;
292 struct ugen_endpoint *sce;
293 int dir, isize;
294 usbd_status err;
295 usbd_xfer_handle xfer;
296 void *buf;
297 int i, j;
298
299 USB_GET_SC_OPEN(ugen, unit, sc);
300
301 DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
302 flag, mode, unit, endpt));
303
304 if (sc == NULL || sc->sc_dying)
305 return (ENXIO);
306
307 if (sc->sc_is_open[endpt])
308 return (EBUSY);
309
310 if (endpt == USB_CONTROL_ENDPOINT) {
311 sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
312 return (0);
313 }
314
315 /* Make sure there are pipes for all directions. */
316 for (dir = OUT; dir <= IN; dir++) {
317 if (flag & (dir == OUT ? FWRITE : FREAD)) {
318 sce = &sc->sc_endpoints[endpt][dir];
319 if (sce == 0 || sce->edesc == 0)
320 return (ENXIO);
321 }
322 }
323
324 /* Actually open the pipes. */
325 /* XXX Should back out properly if it fails. */
326 for (dir = OUT; dir <= IN; dir++) {
327 if (!(flag & (dir == OUT ? FWRITE : FREAD)))
328 continue;
329 sce = &sc->sc_endpoints[endpt][dir];
330 sce->state = 0;
331 sce->timeout = USBD_NO_TIMEOUT;
332 DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
333 sc, endpt, dir, sce));
334 edesc = sce->edesc;
335 switch (edesc->bmAttributes & UE_XFERTYPE) {
336 case UE_INTERRUPT:
337 isize = UGETW(edesc->wMaxPacketSize);
338 if (isize == 0) /* shouldn't happen */
339 return (EINVAL);
340 sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
341 DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
342 endpt, isize));
343 if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
344 return (ENOMEM);
345 err = usbd_open_pipe_intr(sce->iface,
346 edesc->bEndpointAddress,
347 USBD_SHORT_XFER_OK, &sce->pipeh, sce,
348 sce->ibuf, isize, ugenintr,
349 USBD_DEFAULT_INTERVAL);
350 if (err) {
351 free(sce->ibuf, M_USBDEV);
352 clfree(&sce->q);
353 return (EIO);
354 }
355 DPRINTFN(5, ("ugenopen: interrupt open done\n"));
356 break;
357 case UE_BULK:
358 err = usbd_open_pipe(sce->iface,
359 edesc->bEndpointAddress, 0, &sce->pipeh);
360 if (err)
361 return (EIO);
362 break;
363 case UE_ISOCHRONOUS:
364 if (dir == OUT)
365 return (EINVAL);
366 isize = UGETW(edesc->wMaxPacketSize);
367 if (isize == 0) /* shouldn't happen */
368 return (EINVAL);
369 sce->ibuf = malloc(isize * UGEN_NISOFRAMES,
370 M_USBDEV, M_WAITOK);
371 sce->cur = sce->fill = sce->ibuf;
372 sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES;
373 DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n",
374 endpt, isize));
375 err = usbd_open_pipe(sce->iface,
376 edesc->bEndpointAddress, 0, &sce->pipeh);
377 if (err) {
378 free(sce->ibuf, M_USBDEV);
379 return (EIO);
380 }
381 for(i = 0; i < UGEN_NISOREQS; ++i) {
382 sce->isoreqs[i].sce = sce;
383 xfer = usbd_alloc_xfer(sc->sc_udev);
384 if (xfer == 0)
385 goto bad;
386 sce->isoreqs[i].xfer = xfer;
387 buf = usbd_alloc_buffer
388 (xfer, isize * UGEN_NISORFRMS);
389 if (buf == 0) {
390 i++;
391 goto bad;
392 }
393 sce->isoreqs[i].dmabuf = buf;
394 for(j = 0; j < UGEN_NISORFRMS; ++j)
395 sce->isoreqs[i].sizes[j] = isize;
396 usbd_setup_isoc_xfer
397 (xfer, sce->pipeh, &sce->isoreqs[i],
398 sce->isoreqs[i].sizes,
399 UGEN_NISORFRMS, USBD_NO_COPY,
400 ugen_isoc_rintr);
401 (void)usbd_transfer(xfer);
402 }
403 DPRINTFN(5, ("ugenopen: isoc open done\n"));
404 break;
405 bad:
406 while (--i >= 0) /* implicit buffer free */
407 usbd_free_xfer(sce->isoreqs[i].xfer);
408 return (ENOMEM);
409 case UE_CONTROL:
410 return (EINVAL);
411 }
412 }
413 sc->sc_is_open[endpt] = 1;
414 return (0);
415 }
416
417 int
418 ugenclose(dev_t dev, int flag, int mode, struct proc *p)
419 {
420 int endpt = UGENENDPOINT(dev);
421 struct ugen_softc *sc;
422 struct ugen_endpoint *sce;
423 int dir;
424 int i;
425
426 USB_GET_SC(ugen, UGENUNIT(dev), sc);
427
428 DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
429 flag, mode, UGENUNIT(dev), endpt));
430
431 #ifdef DIAGNOSTIC
432 if (!sc->sc_is_open[endpt]) {
433 printf("ugenclose: not open\n");
434 return (EINVAL);
435 }
436 #endif
437
438 if (endpt == USB_CONTROL_ENDPOINT) {
439 DPRINTFN(5, ("ugenclose: close control\n"));
440 sc->sc_is_open[endpt] = 0;
441 return (0);
442 }
443
444 for (dir = OUT; dir <= IN; dir++) {
445 if (!(flag & (dir == OUT ? FWRITE : FREAD)))
446 continue;
447 sce = &sc->sc_endpoints[endpt][dir];
448 if (sce == NULL || sce->pipeh == NULL)
449 continue;
450 DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
451 endpt, dir, sce));
452
453 usbd_abort_pipe(sce->pipeh);
454 usbd_close_pipe(sce->pipeh);
455 sce->pipeh = NULL;
456
457 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
458 case UE_INTERRUPT:
459 ndflush(&sce->q, sce->q.c_cc);
460 clfree(&sce->q);
461 break;
462 case UE_ISOCHRONOUS:
463 for (i = 0; i < UGEN_NISOREQS; ++i)
464 usbd_free_xfer(sce->isoreqs[i].xfer);
465
466 default:
467 break;
468 }
469
470 if (sce->ibuf != NULL) {
471 free(sce->ibuf, M_USBDEV);
472 sce->ibuf = NULL;
473 clfree(&sce->q);
474
475 }
476 }
477 sc->sc_is_open[endpt] = 0;
478
479 return (0);
480 }
481
482 Static int
483 ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
484 {
485 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
486 u_int32_t n, tn;
487 char buf[UGEN_BBSIZE];
488 usbd_xfer_handle xfer;
489 usbd_status err;
490 int s;
491 int error = 0;
492 u_char buffer[UGEN_CHUNK];
493
494 DPRINTFN(5, ("%s: ugenread: %d\n", USBDEVNAME(sc->sc_dev), endpt));
495
496 if (sc->sc_dying)
497 return (EIO);
498
499 if (endpt == USB_CONTROL_ENDPOINT)
500 return (ENODEV);
501
502 #ifdef DIAGNOSTIC
503 if (sce->edesc == NULL) {
504 printf("ugenread: no edesc\n");
505 return (EIO);
506 }
507 if (sce->pipeh == NULL) {
508 printf("ugenread: no pipe\n");
509 return (EIO);
510 }
511 #endif
512
513 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
514 case UE_INTERRUPT:
515 /* Block until activity occurred. */
516 s = splusb();
517 while (sce->q.c_cc == 0) {
518 if (flag & IO_NDELAY) {
519 splx(s);
520 return (EWOULDBLOCK);
521 }
522 sce->state |= UGEN_ASLP;
523 DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
524 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0);
525 DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
526 if (sc->sc_dying)
527 error = EIO;
528 if (error) {
529 sce->state &= ~UGEN_ASLP;
530 break;
531 }
532 }
533 splx(s);
534
535 /* Transfer as many chunks as possible. */
536 while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) {
537 n = min(sce->q.c_cc, uio->uio_resid);
538 if (n > sizeof(buffer))
539 n = sizeof(buffer);
540
541 /* Remove a small chunk from the input queue. */
542 q_to_b(&sce->q, buffer, n);
543 DPRINTFN(5, ("ugenread: got %d chars\n", n));
544
545 /* Copy the data to the user process. */
546 error = uiomove(buffer, n, uio);
547 if (error)
548 break;
549 }
550 break;
551 case UE_BULK:
552 xfer = usbd_alloc_xfer(sc->sc_udev);
553 if (xfer == 0)
554 return (ENOMEM);
555 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
556 DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
557 tn = n;
558 err = usbd_bulk_transfer(
559 xfer, sce->pipeh,
560 sce->state & UGEN_SHORT_OK ?
561 USBD_SHORT_XFER_OK : 0,
562 sce->timeout, buf, &tn, "ugenrb");
563 if (err) {
564 if (err == USBD_INTERRUPTED)
565 error = EINTR;
566 else if (err == USBD_TIMEOUT)
567 error = ETIMEDOUT;
568 else
569 error = EIO;
570 break;
571 }
572 DPRINTFN(1, ("ugenread: got %d bytes\n", tn));
573 error = uiomove(buf, tn, uio);
574 if (error || tn < n)
575 break;
576 }
577 usbd_free_xfer(xfer);
578 break;
579 case UE_ISOCHRONOUS:
580 s = splusb();
581 while (sce->cur == sce->fill) {
582 if (flag & IO_NDELAY) {
583 splx(s);
584 return (EWOULDBLOCK);
585 }
586 sce->state |= UGEN_ASLP;
587 DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
588 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0);
589 DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
590 if (sc->sc_dying)
591 error = EIO;
592 if (error) {
593 sce->state &= ~UGEN_ASLP;
594 break;
595 }
596 }
597
598 while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) {
599 if(sce->fill > sce->cur)
600 n = min(sce->fill - sce->cur, uio->uio_resid);
601 else
602 n = min(sce->limit - sce->cur, uio->uio_resid);
603
604 DPRINTFN(5, ("ugenread: isoc got %d chars\n", n));
605
606 /* Copy the data to the user process. */
607 error = uiomove(sce->cur, n, uio);
608 if (error)
609 break;
610 sce->cur += n;
611 if(sce->cur >= sce->limit)
612 sce->cur = sce->ibuf;
613 }
614 splx(s);
615 break;
616
617
618 default:
619 return (ENXIO);
620 }
621 return (error);
622 }
623
624 int
625 ugenread(dev_t dev, struct uio *uio, int flag)
626 {
627 int endpt = UGENENDPOINT(dev);
628 struct ugen_softc *sc;
629 int error;
630
631 USB_GET_SC(ugen, UGENUNIT(dev), sc);
632
633 sc->sc_refcnt++;
634 error = ugen_do_read(sc, endpt, uio, flag);
635 if (--sc->sc_refcnt < 0)
636 usb_detach_wakeup(USBDEV(sc->sc_dev));
637 return (error);
638 }
639
640 Static int
641 ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
642 {
643 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
644 u_int32_t n;
645 int error = 0;
646 char buf[UGEN_BBSIZE];
647 usbd_xfer_handle xfer;
648 usbd_status err;
649
650 DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc->sc_dev), endpt));
651
652 if (sc->sc_dying)
653 return (EIO);
654
655 if (endpt == USB_CONTROL_ENDPOINT)
656 return (ENODEV);
657
658 #ifdef DIAGNOSTIC
659 if (sce->edesc == NULL) {
660 printf("ugenwrite: no edesc\n");
661 return (EIO);
662 }
663 if (sce->pipeh == NULL) {
664 printf("ugenwrite: no pipe\n");
665 return (EIO);
666 }
667 #endif
668
669 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
670 case UE_BULK:
671 xfer = usbd_alloc_xfer(sc->sc_udev);
672 if (xfer == 0)
673 return (EIO);
674 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
675 error = uiomove(buf, n, uio);
676 if (error)
677 break;
678 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
679 err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
680 sce->timeout, buf, &n,"ugenwb");
681 if (err) {
682 if (err == USBD_INTERRUPTED)
683 error = EINTR;
684 else if (err == USBD_TIMEOUT)
685 error = ETIMEDOUT;
686 else
687 error = EIO;
688 break;
689 }
690 }
691 usbd_free_xfer(xfer);
692 break;
693 default:
694 return (ENXIO);
695 }
696 return (error);
697 }
698
699 int
700 ugenwrite(dev_t dev, struct uio *uio, int flag)
701 {
702 int endpt = UGENENDPOINT(dev);
703 struct ugen_softc *sc;
704 int error;
705
706 USB_GET_SC(ugen, UGENUNIT(dev), sc);
707
708 sc->sc_refcnt++;
709 error = ugen_do_write(sc, endpt, uio, flag);
710 if (--sc->sc_refcnt < 0)
711 usb_detach_wakeup(USBDEV(sc->sc_dev));
712 return (error);
713 }
714
715 #if defined(__NetBSD__) || defined(__OpenBSD__)
716 int
717 ugen_activate(device_ptr_t self, enum devact act)
718 {
719 struct ugen_softc *sc = (struct ugen_softc *)self;
720
721 switch (act) {
722 case DVACT_ACTIVATE:
723 return (EOPNOTSUPP);
724 break;
725
726 case DVACT_DEACTIVATE:
727 sc->sc_dying = 1;
728 break;
729 }
730 return (0);
731 }
732 #endif
733
734 USB_DETACH(ugen)
735 {
736 USB_DETACH_START(ugen, sc);
737 struct ugen_endpoint *sce;
738 int i, dir;
739 int s;
740 #if defined(__NetBSD__) || defined(__OpenBSD__)
741 int maj, mn;
742
743 DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags));
744 #elif defined(__FreeBSD__)
745 DPRINTF(("ugen_detach: sc=%p\n", sc));
746 #endif
747
748 sc->sc_dying = 1;
749 /* Abort all pipes. Causes processes waiting for transfer to wake. */
750 for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
751 for (dir = OUT; dir <= IN; dir++) {
752 sce = &sc->sc_endpoints[i][dir];
753 if (sce && sce->pipeh)
754 usbd_abort_pipe(sce->pipeh);
755 }
756 }
757
758 s = splusb();
759 if (--sc->sc_refcnt >= 0) {
760 /* Wake everyone */
761 for (i = 0; i < USB_MAX_ENDPOINTS; i++)
762 wakeup(&sc->sc_endpoints[i][IN]);
763 /* Wait for processes to go away. */
764 usb_detach_wait(USBDEV(sc->sc_dev));
765 }
766 splx(s);
767
768 #if defined(__NetBSD__) || defined(__OpenBSD__)
769 /* locate the major number */
770 for (maj = 0; maj < nchrdev; maj++)
771 if (cdevsw[maj].d_open == ugenopen)
772 break;
773
774 /* Nuke the vnodes for any open instances (calls close). */
775 mn = self->dv_unit * USB_MAX_ENDPOINTS;
776 vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR);
777 #elif defined(__FreeBSD__)
778 /* XXX not implemented yet */
779 #endif
780
781 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
782 USBDEV(sc->sc_dev));
783
784 return (0);
785 }
786
787 Static void
788 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
789 {
790 struct ugen_endpoint *sce = addr;
791 /*struct ugen_softc *sc = sce->sc;*/
792 u_int32_t count;
793 u_char *ibuf;
794
795 if (status == USBD_CANCELLED)
796 return;
797
798 if (status != USBD_NORMAL_COMPLETION) {
799 DPRINTF(("ugenintr: status=%d\n", status));
800 usbd_clear_endpoint_stall_async(sce->pipeh);
801 return;
802 }
803
804 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
805 ibuf = sce->ibuf;
806
807 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
808 xfer, status, count));
809 DPRINTFN(5, (" data = %02x %02x %02x\n",
810 ibuf[0], ibuf[1], ibuf[2]));
811
812 (void)b_to_q(ibuf, count, &sce->q);
813
814 if (sce->state & UGEN_ASLP) {
815 sce->state &= ~UGEN_ASLP;
816 DPRINTFN(5, ("ugen_intr: waking %p\n", sce));
817 wakeup(sce);
818 }
819 selwakeup(&sce->rsel);
820 }
821
822 Static void
823 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
824 usbd_status status)
825 {
826 struct isoreq *req = addr;
827 struct ugen_endpoint *sce = req->sce;
828 u_int32_t count, n;
829 int i, isize;
830
831 /* Return if we are aborting. */
832 if (status == USBD_CANCELLED)
833 return;
834
835 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
836 DPRINTFN(5,("ugen_isoc_rintr: xfer %d, count=%d\n", req - sce->isoreqs,
837 count));
838
839 /* throw away oldest input if the buffer is full */
840 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) {
841 sce->cur += count;
842 if(sce->cur >= sce->limit)
843 sce->cur = sce->ibuf + (sce->limit - sce->cur);
844 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n",
845 count));
846 }
847
848 isize = UGETW(sce->edesc->wMaxPacketSize);
849 for (i = 0; i < UGEN_NISORFRMS; i++) {
850 u_int32_t actlen = req->sizes[i];
851 char const *buf = (char const *)req->dmabuf + isize * i;
852
853 /* copy data to buffer */
854 while (actlen > 0) {
855 n = min(actlen, sce->limit - sce->fill);
856 memcpy(sce->fill, buf, n);
857
858 buf += n;
859 actlen -= n;
860 sce->fill += n;
861 if(sce->fill == sce->limit)
862 sce->fill = sce->ibuf;
863 }
864
865 /* setup size for next transfer */
866 req->sizes[i] = isize;
867 }
868
869 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS,
870 USBD_NO_COPY, ugen_isoc_rintr);
871 (void)usbd_transfer(xfer);
872
873 if (sce->state & UGEN_ASLP) {
874 sce->state &= ~UGEN_ASLP;
875 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce));
876 wakeup(sce);
877 }
878 selwakeup(&sce->rsel);
879 }
880
881 Static usbd_status
882 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno)
883 {
884 usbd_interface_handle iface;
885 usb_endpoint_descriptor_t *ed;
886 usbd_status err;
887 struct ugen_endpoint *sce;
888 u_int8_t niface, nendpt, endptno, endpt;
889 int dir;
890
891 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
892
893 err = usbd_interface_count(sc->sc_udev, &niface);
894 if (err)
895 return (err);
896 if (ifaceidx < 0 || ifaceidx >= niface)
897 return (USBD_INVAL);
898
899 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
900 if (err)
901 return (err);
902 err = usbd_endpoint_count(iface, &nendpt);
903 if (err)
904 return (err);
905 /* XXX should only do this after setting new altno has succeeded */
906 for (endptno = 0; endptno < nendpt; endptno++) {
907 ed = usbd_interface2endpoint_descriptor(iface,endptno);
908 endpt = ed->bEndpointAddress;
909 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
910 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
911 sce->sc = 0;
912 sce->edesc = 0;
913 sce->iface = 0;
914 }
915
916 /* change setting */
917 err = usbd_set_interface(iface, altno);
918 if (err)
919 return (err);
920
921 err = usbd_endpoint_count(iface, &nendpt);
922 if (err)
923 return (err);
924 for (endptno = 0; endptno < nendpt; endptno++) {
925 ed = usbd_interface2endpoint_descriptor(iface,endptno);
926 endpt = ed->bEndpointAddress;
927 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
928 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
929 sce->sc = sc;
930 sce->edesc = ed;
931 sce->iface = iface;
932 }
933 return (0);
934 }
935
936 /* Retrieve a complete descriptor for a certain device and index. */
937 Static usb_config_descriptor_t *
938 ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp)
939 {
940 usb_config_descriptor_t *cdesc, *tdesc, cdescr;
941 int len;
942 usbd_status err;
943
944 if (index == USB_CURRENT_CONFIG_INDEX) {
945 tdesc = usbd_get_config_descriptor(sc->sc_udev);
946 len = UGETW(tdesc->wTotalLength);
947 if (lenp)
948 *lenp = len;
949 cdesc = malloc(len, M_TEMP, M_WAITOK);
950 memcpy(cdesc, tdesc, len);
951 DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
952 } else {
953 err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
954 if (err)
955 return (0);
956 len = UGETW(cdescr.wTotalLength);
957 DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
958 if (lenp)
959 *lenp = len;
960 cdesc = malloc(len, M_TEMP, M_WAITOK);
961 err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc,len);
962 if (err) {
963 free(cdesc, M_TEMP);
964 return (0);
965 }
966 }
967 return (cdesc);
968 }
969
970 Static int
971 ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx)
972 {
973 usbd_interface_handle iface;
974 usbd_status err;
975
976 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
977 if (err)
978 return (-1);
979 return (usbd_get_interface_altindex(iface));
980 }
981
982 Static int
983 ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
984 caddr_t addr, int flag, struct proc *p)
985 {
986 struct ugen_endpoint *sce;
987 usbd_status err;
988 usbd_interface_handle iface;
989 struct usb_config_desc *cd;
990 usb_config_descriptor_t *cdesc;
991 struct usb_interface_desc *id;
992 usb_interface_descriptor_t *idesc;
993 struct usb_endpoint_desc *ed;
994 usb_endpoint_descriptor_t *edesc;
995 struct usb_alt_interface *ai;
996 struct usb_string_desc *si;
997 u_int8_t conf, alt;
998
999 DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd));
1000 if (sc->sc_dying)
1001 return (EIO);
1002
1003 switch (cmd) {
1004 case FIONBIO:
1005 /* All handled in the upper FS layer. */
1006 return (0);
1007 case USB_SET_SHORT_XFER:
1008 /* This flag only affects read */
1009 if (endpt == USB_CONTROL_ENDPOINT)
1010 return (EINVAL);
1011 sce = &sc->sc_endpoints[endpt][IN];
1012 if (sce == NULL)
1013 return (EINVAL);
1014 #ifdef DIAGNOSTIC
1015 if (sce->pipeh == NULL) {
1016 printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n");
1017 return (EIO);
1018 }
1019 #endif
1020 if (*(int *)addr)
1021 sce->state |= UGEN_SHORT_OK;
1022 else
1023 sce->state &= ~UGEN_SHORT_OK;
1024 return (0);
1025 case USB_SET_TIMEOUT:
1026 sce = &sc->sc_endpoints[endpt][IN];
1027 if (sce == NULL)
1028 return (EINVAL);
1029 #ifdef DIAGNOSTIC
1030 if (sce->pipeh == NULL) {
1031 printf("ugenioctl: USB_SET_TIMEOUT, no pipe\n");
1032 return (EIO);
1033 }
1034 #endif
1035 sce->timeout = *(int *)addr;
1036 return (0);
1037 default:
1038 break;
1039 }
1040
1041 if (endpt != USB_CONTROL_ENDPOINT)
1042 return (EINVAL);
1043
1044 switch (cmd) {
1045 #ifdef UGEN_DEBUG
1046 case USB_SETDEBUG:
1047 ugendebug = *(int *)addr;
1048 break;
1049 #endif
1050 case USB_GET_CONFIG:
1051 err = usbd_get_config(sc->sc_udev, &conf);
1052 if (err)
1053 return (EIO);
1054 *(int *)addr = conf;
1055 break;
1056 case USB_SET_CONFIG:
1057 if (!(flag & FWRITE))
1058 return (EPERM);
1059 err = ugen_set_config(sc, *(int *)addr);
1060 if (err)
1061 return (EIO);
1062 break;
1063 case USB_GET_ALTINTERFACE:
1064 ai = (struct usb_alt_interface *)addr;
1065 err = usbd_device2interface_handle(sc->sc_udev,
1066 ai->interface_index, &iface);
1067 if (err)
1068 return (EINVAL);
1069 idesc = usbd_get_interface_descriptor(iface);
1070 if (idesc == NULL)
1071 return (EIO);
1072 ai->alt_no = idesc->bAlternateSetting;
1073 break;
1074 case USB_SET_ALTINTERFACE:
1075 if (!(flag & FWRITE))
1076 return (EPERM);
1077 ai = (struct usb_alt_interface *)addr;
1078 err = usbd_device2interface_handle(sc->sc_udev,
1079 ai->interface_index, &iface);
1080 if (err)
1081 return (EINVAL);
1082 err = ugen_set_interface(sc, ai->interface_index, ai->alt_no);
1083 if (err)
1084 return (EINVAL);
1085 break;
1086 case USB_GET_NO_ALT:
1087 ai = (struct usb_alt_interface *)addr;
1088 cdesc = ugen_get_cdesc(sc, ai->config_index, 0);
1089 if (cdesc == NULL)
1090 return (EINVAL);
1091 idesc = usbd_find_idesc(cdesc, ai->interface_index, 0);
1092 if (idesc == NULL) {
1093 free(cdesc, M_TEMP);
1094 return (EINVAL);
1095 }
1096 ai->alt_no = usbd_get_no_alts(cdesc, idesc->bInterfaceNumber);
1097 free(cdesc, M_TEMP);
1098 break;
1099 case USB_GET_DEVICE_DESC:
1100 *(usb_device_descriptor_t *)addr =
1101 *usbd_get_device_descriptor(sc->sc_udev);
1102 break;
1103 case USB_GET_CONFIG_DESC:
1104 cd = (struct usb_config_desc *)addr;
1105 cdesc = ugen_get_cdesc(sc, cd->config_index, 0);
1106 if (cdesc == NULL)
1107 return (EINVAL);
1108 cd->desc = *cdesc;
1109 free(cdesc, M_TEMP);
1110 break;
1111 case USB_GET_INTERFACE_DESC:
1112 id = (struct usb_interface_desc *)addr;
1113 cdesc = ugen_get_cdesc(sc, id->config_index, 0);
1114 if (cdesc == NULL)
1115 return (EINVAL);
1116 if (id->config_index == USB_CURRENT_CONFIG_INDEX &&
1117 id->alt_index == USB_CURRENT_ALT_INDEX)
1118 alt = ugen_get_alt_index(sc, id->interface_index);
1119 else
1120 alt = id->alt_index;
1121 idesc = usbd_find_idesc(cdesc, id->interface_index, alt);
1122 if (idesc == NULL) {
1123 free(cdesc, M_TEMP);
1124 return (EINVAL);
1125 }
1126 id->desc = *idesc;
1127 free(cdesc, M_TEMP);
1128 break;
1129 case USB_GET_ENDPOINT_DESC:
1130 ed = (struct usb_endpoint_desc *)addr;
1131 cdesc = ugen_get_cdesc(sc, ed->config_index, 0);
1132 if (cdesc == NULL)
1133 return (EINVAL);
1134 if (ed->config_index == USB_CURRENT_CONFIG_INDEX &&
1135 ed->alt_index == USB_CURRENT_ALT_INDEX)
1136 alt = ugen_get_alt_index(sc, ed->interface_index);
1137 else
1138 alt = ed->alt_index;
1139 edesc = usbd_find_edesc(cdesc, ed->interface_index,
1140 alt, ed->endpoint_index);
1141 if (edesc == NULL) {
1142 free(cdesc, M_TEMP);
1143 return (EINVAL);
1144 }
1145 ed->desc = *edesc;
1146 free(cdesc, M_TEMP);
1147 break;
1148 case USB_GET_FULL_DESC:
1149 {
1150 int len;
1151 struct iovec iov;
1152 struct uio uio;
1153 struct usb_full_desc *fd = (struct usb_full_desc *)addr;
1154 int error;
1155
1156 cdesc = ugen_get_cdesc(sc, fd->config_index, &len);
1157 if (len > fd->size)
1158 len = fd->size;
1159 iov.iov_base = (caddr_t)fd->data;
1160 iov.iov_len = len;
1161 uio.uio_iov = &iov;
1162 uio.uio_iovcnt = 1;
1163 uio.uio_resid = len;
1164 uio.uio_offset = 0;
1165 uio.uio_segflg = UIO_USERSPACE;
1166 uio.uio_rw = UIO_READ;
1167 uio.uio_procp = p;
1168 error = uiomove((void *)cdesc, len, &uio);
1169 free(cdesc, M_TEMP);
1170 return (error);
1171 }
1172 case USB_GET_STRING_DESC:
1173 si = (struct usb_string_desc *)addr;
1174 err = usbd_get_string_desc(sc->sc_udev, si->string_index,
1175 si->language_id, &si->desc);
1176 if (err)
1177 return (EINVAL);
1178 break;
1179 case USB_DO_REQUEST:
1180 {
1181 struct usb_ctl_request *ur = (void *)addr;
1182 int len = UGETW(ur->request.wLength);
1183 struct iovec iov;
1184 struct uio uio;
1185 void *ptr = 0;
1186 usbd_status err;
1187 int error = 0;
1188
1189 if (!(flag & FWRITE))
1190 return (EPERM);
1191 /* Avoid requests that would damage the bus integrity. */
1192 if ((ur->request.bmRequestType == UT_WRITE_DEVICE &&
1193 ur->request.bRequest == UR_SET_ADDRESS) ||
1194 (ur->request.bmRequestType == UT_WRITE_DEVICE &&
1195 ur->request.bRequest == UR_SET_CONFIG) ||
1196 (ur->request.bmRequestType == UT_WRITE_INTERFACE &&
1197 ur->request.bRequest == UR_SET_INTERFACE))
1198 return (EINVAL);
1199
1200 if (len < 0 || len > 32767)
1201 return (EINVAL);
1202 if (len != 0) {
1203 iov.iov_base = (caddr_t)ur->data;
1204 iov.iov_len = len;
1205 uio.uio_iov = &iov;
1206 uio.uio_iovcnt = 1;
1207 uio.uio_resid = len;
1208 uio.uio_offset = 0;
1209 uio.uio_segflg = UIO_USERSPACE;
1210 uio.uio_rw =
1211 ur->request.bmRequestType & UT_READ ?
1212 UIO_READ : UIO_WRITE;
1213 uio.uio_procp = p;
1214 ptr = malloc(len, M_TEMP, M_WAITOK);
1215 if (uio.uio_rw == UIO_WRITE) {
1216 error = uiomove(ptr, len, &uio);
1217 if (error)
1218 goto ret;
1219 }
1220 }
1221 err = usbd_do_request_flags(sc->sc_udev, &ur->request,
1222 ptr, ur->flags, &ur->actlen);
1223 if (err) {
1224 error = EIO;
1225 goto ret;
1226 }
1227 if (len != 0) {
1228 if (uio.uio_rw == UIO_READ) {
1229 error = uiomove(ptr, len, &uio);
1230 if (error)
1231 goto ret;
1232 }
1233 }
1234 ret:
1235 if (ptr)
1236 free(ptr, M_TEMP);
1237 return (error);
1238 }
1239 case USB_GET_DEVICEINFO:
1240 usbd_fill_deviceinfo(sc->sc_udev,
1241 (struct usb_device_info *)addr, 1);
1242 break;
1243 default:
1244 return (EINVAL);
1245 }
1246 return (0);
1247 }
1248
1249 int
1250 ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
1251 {
1252 int endpt = UGENENDPOINT(dev);
1253 struct ugen_softc *sc;
1254 int error;
1255
1256 USB_GET_SC(ugen, UGENUNIT(dev), sc);
1257
1258 sc->sc_refcnt++;
1259 error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
1260 if (--sc->sc_refcnt < 0)
1261 usb_detach_wakeup(USBDEV(sc->sc_dev));
1262 return (error);
1263 }
1264
1265 int
1266 ugenpoll(dev_t dev, int events, struct proc *p)
1267 {
1268 struct ugen_softc *sc;
1269 struct ugen_endpoint *sce;
1270 int revents = 0;
1271 int s;
1272
1273 USB_GET_SC(ugen, UGENUNIT(dev), sc);
1274
1275 if (sc->sc_dying)
1276 return (EIO);
1277
1278 /* XXX always IN */
1279 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1280 if (sce == NULL)
1281 return (EINVAL);
1282 #ifdef DIAGNOSTIC
1283 if (!sce->edesc) {
1284 printf("ugenpoll: no edesc\n");
1285 return (EIO);
1286 }
1287 if (!sce->pipeh) {
1288 printf("ugenpoll: no pipe\n");
1289 return (EIO);
1290 }
1291 #endif
1292 s = splusb();
1293 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
1294 case UE_INTERRUPT:
1295 if (events & (POLLIN | POLLRDNORM)) {
1296 if (sce->q.c_cc > 0)
1297 revents |= events & (POLLIN | POLLRDNORM);
1298 else
1299 selrecord(p, &sce->rsel);
1300 }
1301 break;
1302 case UE_ISOCHRONOUS:
1303 if (events & (POLLIN | POLLRDNORM)) {
1304 if (sce->cur != sce->fill)
1305 revents |= events & (POLLIN | POLLRDNORM);
1306 else
1307 selrecord(p, &sce->rsel);
1308 }
1309 break;
1310 case UE_BULK:
1311 /*
1312 * We have no easy way of determining if a read will
1313 * yield any data or a write will happen.
1314 * Pretend they will.
1315 */
1316 revents |= events &
1317 (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
1318 break;
1319 default:
1320 break;
1321 }
1322 splx(s);
1323 return (revents);
1324 }
1325
1326 #if defined(__FreeBSD__)
1327 DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, usbd_driver_load, 0);
1328 #endif
1329