This source file includes following definitions.
- ugen_match
- ugen_attach
- ugen_set_config
- ugenopen
- ugenclose
- ugen_do_read
- ugenread
- ugen_do_write
- ugenwrite
- ugen_activate
- ugen_detach
- ugenintr
- ugen_isoc_rintr
- ugen_set_interface
- ugen_get_cdesc
- ugen_get_alt_index
- ugen_do_ioctl
- ugenioctl
- ugenpoll
- filt_ugenrdetach
- filt_ugenread_intr
- filt_ugenread_isoc
- ugenkqfilter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/kernel.h>
46 #include <sys/malloc.h>
47 #include <sys/device.h>
48 #include <sys/ioctl.h>
49 #include <sys/conf.h>
50 #include <sys/tty.h>
51 #include <sys/file.h>
52 #include <sys/selinfo.h>
53 #include <sys/proc.h>
54 #include <sys/vnode.h>
55 #include <sys/poll.h>
56
57 #include <dev/usb/usb.h>
58 #include <dev/usb/usbdi.h>
59 #include <dev/usb/usbdi_util.h>
60 #include <dev/usb/usbdevs.h>
61
62 #ifdef UGEN_DEBUG
63 #define DPRINTF(x) do { if (ugendebug) printf x; } while (0)
64 #define DPRINTFN(n,x) do { if (ugendebug>(n)) printf x; } while (0)
65 int ugendebug = 0;
66 #else
67 #define DPRINTF(x)
68 #define DPRINTFN(n,x)
69 #endif
70
71 #define UGEN_CHUNK 128
72 #define UGEN_IBSIZE 1020
73 #define UGEN_BBSIZE 1024
74
75 #define UGEN_NISOFRAMES 500
76 #define UGEN_NISOREQS 6
77 #define UGEN_NISORFRMS 4
78
79 struct ugen_endpoint {
80 struct ugen_softc *sc;
81 usb_endpoint_descriptor_t *edesc;
82 usbd_interface_handle iface;
83 int state;
84 #define UGEN_ASLP 0x02
85 #define UGEN_SHORT_OK 0x04
86 usbd_pipe_handle pipeh;
87 struct clist q;
88 struct selinfo rsel;
89 u_char *ibuf;
90 u_char *fill;
91 u_char *limit;
92 u_char *cur;
93 u_int32_t timeout;
94 struct isoreq {
95 struct ugen_endpoint *sce;
96 usbd_xfer_handle xfer;
97 void *dmabuf;
98 u_int16_t sizes[UGEN_NISORFRMS];
99 } isoreqs[UGEN_NISOREQS];
100 };
101
102 struct ugen_softc {
103 struct device sc_dev;
104 usbd_device_handle sc_udev;
105
106 char sc_is_open[USB_MAX_ENDPOINTS];
107 struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2];
108 #define OUT 0
109 #define IN 1
110
111 int sc_refcnt;
112 u_char sc_dying;
113 };
114
115 void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr,
116 usbd_status status);
117 void ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
118 usbd_status status);
119 int ugen_do_read(struct ugen_softc *, int, struct uio *, int);
120 int ugen_do_write(struct ugen_softc *, int, struct uio *, int);
121 int ugen_do_ioctl(struct ugen_softc *, int, u_long,
122 caddr_t, int, struct proc *);
123 int ugen_set_config(struct ugen_softc *sc, int configno);
124 usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc,
125 int index, int *lenp);
126 usbd_status ugen_set_interface(struct ugen_softc *, int, int);
127 int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx);
128
129 #define UGENUNIT(n) ((minor(n) >> 4) & 0xf)
130 #define UGENENDPOINT(n) (minor(n) & 0xf)
131 #define UGENDEV(u, e) (makedev(0, ((u) << 4) | (e)))
132
133 int ugen_match(struct device *, void *, void *);
134 void ugen_attach(struct device *, struct device *, void *);
135 int ugen_detach(struct device *, int);
136 int ugen_activate(struct device *, enum devact);
137
138 struct cfdriver ugen_cd = {
139 NULL, "ugen", DV_DULL
140 };
141
142 const struct cfattach ugen_ca = {
143 sizeof(struct ugen_softc),
144 ugen_match,
145 ugen_attach,
146 ugen_detach,
147 ugen_activate,
148 };
149
150 int
151 ugen_match(struct device *parent, void *match, void *aux)
152 {
153 struct usb_attach_arg *uaa = aux;
154
155 #if 0
156 if (uaa->matchlvl)
157 return (uaa->matchlvl);
158 #endif
159 if (uaa->usegeneric) {
160 #ifdef __macppc__
161
162
163
164
165
166
167 if (uaa->vendor == USB_VENDOR_APPLE &&
168 uaa->product == USB_PRODUCT_APPLE_ADB)
169 return (UMATCH_NONE);
170 #endif
171 return (UMATCH_GENERIC);
172 } else
173 return (UMATCH_NONE);
174 }
175
176 void
177 ugen_attach(struct device *parent, struct device *self, void *aux)
178 {
179 struct ugen_softc *sc = (struct ugen_softc *)self;
180 struct usb_attach_arg *uaa = aux;
181 usbd_device_handle udev;
182 char *devinfop;
183 usbd_status err;
184 int conf;
185
186 devinfop = usbd_devinfo_alloc(uaa->device, 0);
187 printf("\n%s: %s\n", sc->sc_dev.dv_xname, devinfop);
188 usbd_devinfo_free(devinfop);
189
190 sc->sc_udev = udev = uaa->device;
191
192
193 err = usbd_set_config_index(udev, 0, 0);
194 if (err) {
195 printf("%s: setting configuration index 0 failed\n",
196 sc->sc_dev.dv_xname);
197 sc->sc_dying = 1;
198 return;
199 }
200 conf = usbd_get_config_descriptor(udev)->bConfigurationValue;
201
202
203 err = ugen_set_config(sc, conf);
204 if (err) {
205 printf("%s: setting configuration %d failed\n",
206 sc->sc_dev.dv_xname, conf);
207 sc->sc_dying = 1;
208 return;
209 }
210
211 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
212 &sc->sc_dev);
213 }
214
215 int
216 ugen_set_config(struct ugen_softc *sc, int configno)
217 {
218 usbd_device_handle dev = sc->sc_udev;
219 usbd_interface_handle iface;
220 usb_endpoint_descriptor_t *ed;
221 struct ugen_endpoint *sce;
222 u_int8_t niface, nendpt;
223 int ifaceno, endptno, endpt;
224 usbd_status err;
225 int dir;
226
227 DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
228 sc->sc_dev.dv_xname, configno, sc));
229
230
231
232
233
234 for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++)
235 if (sc->sc_is_open[endptno]) {
236 DPRINTFN(1,
237 ("ugen_set_config: %s - endpoint %d is open\n",
238 sc->sc_dev.dv_xname, endptno));
239 return (USBD_IN_USE);
240 }
241
242
243 if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) {
244 err = usbd_set_config_no(dev, configno, 1);
245 if (err)
246 return (err);
247 }
248
249 err = usbd_interface_count(dev, &niface);
250 if (err)
251 return (err);
252 memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
253 for (ifaceno = 0; ifaceno < niface; ifaceno++) {
254 DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
255 err = usbd_device2interface_handle(dev, ifaceno, &iface);
256 if (err)
257 return (err);
258 err = usbd_endpoint_count(iface, &nendpt);
259 if (err)
260 return (err);
261 for (endptno = 0; endptno < nendpt; endptno++) {
262 ed = usbd_interface2endpoint_descriptor(iface,endptno);
263 endpt = ed->bEndpointAddress;
264 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
265 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
266 DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x"
267 "(%d,%d), sce=%p\n",
268 endptno, endpt, UE_GET_ADDR(endpt),
269 UE_GET_DIR(endpt), sce));
270 sce->sc = sc;
271 sce->edesc = ed;
272 sce->iface = iface;
273 }
274 }
275 return (USBD_NORMAL_COMPLETION);
276 }
277
278 int
279 ugenopen(dev_t dev, int flag, int mode, struct proc *p)
280 {
281 struct ugen_softc *sc;
282 int unit = UGENUNIT(dev);
283 int endpt = UGENENDPOINT(dev);
284 usb_endpoint_descriptor_t *edesc;
285 struct ugen_endpoint *sce;
286 int dir, isize;
287 usbd_status err;
288 usbd_xfer_handle xfer;
289 void *buf;
290 int i, j;
291
292 if (unit >= ugen_cd.cd_ndevs)
293 return (ENXIO);
294 sc = ugen_cd.cd_devs[unit];
295 if (sc == NULL)
296 return (ENXIO);
297
298 DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
299 flag, mode, unit, endpt));
300
301 if (sc == NULL || sc->sc_dying)
302 return (ENXIO);
303
304 if (sc->sc_is_open[endpt])
305 return (EBUSY);
306
307 if (endpt == USB_CONTROL_ENDPOINT) {
308 sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
309 return (0);
310 }
311
312
313 for (dir = OUT; dir <= IN; dir++) {
314 if (flag & (dir == OUT ? FWRITE : FREAD)) {
315 sce = &sc->sc_endpoints[endpt][dir];
316 if (sce == 0 || sce->edesc == 0)
317 return (ENXIO);
318 }
319 }
320
321
322
323 for (dir = OUT; dir <= IN; dir++) {
324 if (!(flag & (dir == OUT ? FWRITE : FREAD)))
325 continue;
326 sce = &sc->sc_endpoints[endpt][dir];
327 sce->state = 0;
328 sce->timeout = USBD_NO_TIMEOUT;
329 DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
330 sc, endpt, dir, sce));
331 edesc = sce->edesc;
332 switch (edesc->bmAttributes & UE_XFERTYPE) {
333 case UE_INTERRUPT:
334 if (dir == OUT) {
335 err = usbd_open_pipe(sce->iface,
336 edesc->bEndpointAddress, 0, &sce->pipeh);
337 if (err)
338 return (EIO);
339 break;
340 }
341 isize = UGETW(edesc->wMaxPacketSize);
342 if (isize == 0)
343 return (EINVAL);
344 sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
345 DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
346 endpt, isize));
347 if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
348 return (ENOMEM);
349 err = usbd_open_pipe_intr(sce->iface,
350 edesc->bEndpointAddress,
351 USBD_SHORT_XFER_OK, &sce->pipeh, sce,
352 sce->ibuf, isize, ugenintr,
353 USBD_DEFAULT_INTERVAL);
354 if (err) {
355 free(sce->ibuf, M_USBDEV);
356 clfree(&sce->q);
357 return (EIO);
358 }
359 DPRINTFN(5, ("ugenopen: interrupt open done\n"));
360 break;
361 case UE_BULK:
362 err = usbd_open_pipe(sce->iface,
363 edesc->bEndpointAddress, 0, &sce->pipeh);
364 if (err)
365 return (EIO);
366 break;
367 case UE_ISOCHRONOUS:
368 if (dir == OUT)
369 return (EINVAL);
370 isize = UGETW(edesc->wMaxPacketSize);
371 if (isize == 0)
372 return (EINVAL);
373 sce->ibuf = malloc(isize * UGEN_NISOFRAMES,
374 M_USBDEV, M_WAITOK);
375 sce->cur = sce->fill = sce->ibuf;
376 sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES;
377 DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n",
378 endpt, isize));
379 err = usbd_open_pipe(sce->iface,
380 edesc->bEndpointAddress, 0, &sce->pipeh);
381 if (err) {
382 free(sce->ibuf, M_USBDEV);
383 return (EIO);
384 }
385 for(i = 0; i < UGEN_NISOREQS; ++i) {
386 sce->isoreqs[i].sce = sce;
387 xfer = usbd_alloc_xfer(sc->sc_udev);
388 if (xfer == 0)
389 goto bad;
390 sce->isoreqs[i].xfer = xfer;
391 buf = usbd_alloc_buffer
392 (xfer, isize * UGEN_NISORFRMS);
393 if (buf == 0) {
394 i++;
395 goto bad;
396 }
397 sce->isoreqs[i].dmabuf = buf;
398 for(j = 0; j < UGEN_NISORFRMS; ++j)
399 sce->isoreqs[i].sizes[j] = isize;
400 usbd_setup_isoc_xfer
401 (xfer, sce->pipeh, &sce->isoreqs[i],
402 sce->isoreqs[i].sizes,
403 UGEN_NISORFRMS, USBD_NO_COPY,
404 ugen_isoc_rintr);
405 (void)usbd_transfer(xfer);
406 }
407 DPRINTFN(5, ("ugenopen: isoc open done\n"));
408 break;
409 bad:
410 while (--i >= 0)
411 usbd_free_xfer(sce->isoreqs[i].xfer);
412 return (ENOMEM);
413 case UE_CONTROL:
414 sce->timeout = USBD_DEFAULT_TIMEOUT;
415 return (EINVAL);
416 }
417 }
418 sc->sc_is_open[endpt] = 1;
419 return (0);
420 }
421
422 int
423 ugenclose(dev_t dev, int flag, int mode, struct proc *p)
424 {
425 int endpt = UGENENDPOINT(dev);
426 struct ugen_softc *sc;
427 struct ugen_endpoint *sce;
428 int dir;
429 int i;
430
431 sc = ugen_cd.cd_devs[UGENUNIT(dev)];
432
433 DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
434 flag, mode, UGENUNIT(dev), endpt));
435
436 #ifdef DIAGNOSTIC
437 if (!sc->sc_is_open[endpt]) {
438 printf("ugenclose: not open\n");
439 return (EINVAL);
440 }
441 #endif
442
443 if (endpt == USB_CONTROL_ENDPOINT) {
444 DPRINTFN(5, ("ugenclose: close control\n"));
445 sc->sc_is_open[endpt] = 0;
446 return (0);
447 }
448
449 for (dir = OUT; dir <= IN; dir++) {
450 if (!(flag & (dir == OUT ? FWRITE : FREAD)))
451 continue;
452 sce = &sc->sc_endpoints[endpt][dir];
453 if (sce == NULL || sce->pipeh == NULL)
454 continue;
455 DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
456 endpt, dir, sce));
457
458 usbd_abort_pipe(sce->pipeh);
459 usbd_close_pipe(sce->pipeh);
460 sce->pipeh = NULL;
461
462 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
463 case UE_INTERRUPT:
464 ndflush(&sce->q, sce->q.c_cc);
465 clfree(&sce->q);
466 break;
467 case UE_ISOCHRONOUS:
468 for (i = 0; i < UGEN_NISOREQS; ++i)
469 usbd_free_xfer(sce->isoreqs[i].xfer);
470
471 default:
472 break;
473 }
474
475 if (sce->ibuf != NULL) {
476 free(sce->ibuf, M_USBDEV);
477 sce->ibuf = NULL;
478 clfree(&sce->q);
479 }
480 }
481 sc->sc_is_open[endpt] = 0;
482
483 return (0);
484 }
485
486 int
487 ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
488 {
489 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
490 u_int32_t n, tn;
491 char buf[UGEN_BBSIZE];
492 usbd_xfer_handle xfer;
493 usbd_status err;
494 int s;
495 int error = 0;
496 u_char buffer[UGEN_CHUNK];
497
498 DPRINTFN(5, ("%s: ugenread: %d\n", sc->sc_dev.dv_xname, endpt));
499
500 if (sc->sc_dying)
501 return (EIO);
502
503 if (endpt == USB_CONTROL_ENDPOINT)
504 return (ENODEV);
505
506 #ifdef DIAGNOSTIC
507 if (sce->edesc == NULL) {
508 printf("ugenread: no edesc\n");
509 return (EIO);
510 }
511 if (sce->pipeh == NULL) {
512 printf("ugenread: no pipe\n");
513 return (EIO);
514 }
515 #endif
516
517 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
518 case UE_INTERRUPT:
519
520 s = splusb();
521 while (sce->q.c_cc == 0) {
522 if (flag & IO_NDELAY) {
523 splx(s);
524 return (EWOULDBLOCK);
525 }
526 sce->state |= UGEN_ASLP;
527 DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
528 error = tsleep(sce, PZERO | PCATCH, "ugenri",
529 (sce->timeout * hz) / 1000);
530 DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
531 if (sc->sc_dying)
532 error = EIO;
533 if (error == EWOULDBLOCK) {
534 error = 0;
535 break;
536 }
537 if (error) {
538 sce->state &= ~UGEN_ASLP;
539 break;
540 }
541 }
542 splx(s);
543
544
545 while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) {
546 n = min(sce->q.c_cc, uio->uio_resid);
547 if (n > sizeof(buffer))
548 n = sizeof(buffer);
549
550
551 q_to_b(&sce->q, buffer, n);
552 DPRINTFN(5, ("ugenread: got %d chars\n", n));
553
554
555 error = uiomove(buffer, n, uio);
556 if (error)
557 break;
558 }
559 break;
560 case UE_BULK:
561 xfer = usbd_alloc_xfer(sc->sc_udev);
562 if (xfer == 0)
563 return (ENOMEM);
564 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
565 DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
566 tn = n;
567 err = usbd_bulk_transfer(
568 xfer, sce->pipeh,
569 sce->state & UGEN_SHORT_OK ?
570 USBD_SHORT_XFER_OK : 0,
571 sce->timeout, buf, &tn, "ugenrb");
572 if (err) {
573 if (err == USBD_INTERRUPTED)
574 error = EINTR;
575 else if (err == USBD_TIMEOUT)
576 error = ETIMEDOUT;
577 else
578 error = EIO;
579 break;
580 }
581 DPRINTFN(1, ("ugenread: got %d bytes\n", tn));
582 error = uiomove(buf, tn, uio);
583 if (error || tn < n)
584 break;
585 }
586 usbd_free_xfer(xfer);
587 break;
588 case UE_ISOCHRONOUS:
589 s = splusb();
590 while (sce->cur == sce->fill) {
591 if (flag & IO_NDELAY) {
592 splx(s);
593 return (EWOULDBLOCK);
594 }
595 sce->state |= UGEN_ASLP;
596 DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
597 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0);
598 DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
599 if (sc->sc_dying)
600 error = EIO;
601 if (error) {
602 sce->state &= ~UGEN_ASLP;
603 break;
604 }
605 }
606
607 while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) {
608 if(sce->fill > sce->cur)
609 n = min(sce->fill - sce->cur, uio->uio_resid);
610 else
611 n = min(sce->limit - sce->cur, uio->uio_resid);
612
613 DPRINTFN(5, ("ugenread: isoc got %d chars\n", n));
614
615
616 error = uiomove(sce->cur, n, uio);
617 if (error)
618 break;
619 sce->cur += n;
620 if(sce->cur >= sce->limit)
621 sce->cur = sce->ibuf;
622 }
623 splx(s);
624 break;
625
626
627 default:
628 return (ENXIO);
629 }
630 return (error);
631 }
632
633 int
634 ugenread(dev_t dev, struct uio *uio, int flag)
635 {
636 int endpt = UGENENDPOINT(dev);
637 struct ugen_softc *sc;
638 int error;
639
640 sc = ugen_cd.cd_devs[UGENUNIT(dev)];
641
642 sc->sc_refcnt++;
643 error = ugen_do_read(sc, endpt, uio, flag);
644 if (--sc->sc_refcnt < 0)
645 usb_detach_wakeup(&sc->sc_dev);
646 return (error);
647 }
648
649 int
650 ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
651 {
652 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
653 u_int32_t n;
654 int error = 0;
655 char buf[UGEN_BBSIZE];
656 usbd_xfer_handle xfer;
657 usbd_status err;
658
659 DPRINTFN(5, ("%s: ugenwrite: %d\n", sc->sc_dev.dv_xname, endpt));
660
661 if (sc->sc_dying)
662 return (EIO);
663
664 if (endpt == USB_CONTROL_ENDPOINT)
665 return (ENODEV);
666
667 #ifdef DIAGNOSTIC
668 if (sce->edesc == NULL) {
669 printf("ugenwrite: no edesc\n");
670 return (EIO);
671 }
672 if (sce->pipeh == NULL) {
673 printf("ugenwrite: no pipe\n");
674 return (EIO);
675 }
676 #endif
677
678 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
679 case UE_BULK:
680 xfer = usbd_alloc_xfer(sc->sc_udev);
681 if (xfer == 0)
682 return (EIO);
683 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
684 error = uiomove(buf, n, uio);
685 if (error)
686 break;
687 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
688 err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
689 sce->timeout, buf, &n,"ugenwb");
690 if (err) {
691 if (err == USBD_INTERRUPTED)
692 error = EINTR;
693 else if (err == USBD_TIMEOUT)
694 error = ETIMEDOUT;
695 else
696 error = EIO;
697 break;
698 }
699 }
700 usbd_free_xfer(xfer);
701 break;
702 case UE_INTERRUPT:
703 xfer = usbd_alloc_xfer(sc->sc_udev);
704 if (xfer == 0)
705 return (EIO);
706 while ((n = min(UGETW(sce->edesc->wMaxPacketSize),
707 uio->uio_resid)) != 0) {
708 error = uiomove(buf, n, uio);
709 if (error)
710 break;
711 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
712 err = usbd_intr_transfer(xfer, sce->pipeh, 0,
713 sce->timeout, buf, &n, "ugenwi");
714 if (err) {
715 if (err == USBD_INTERRUPTED)
716 error = EINTR;
717 else if (err == USBD_TIMEOUT)
718 error = ETIMEDOUT;
719 else
720 error = EIO;
721 break;
722 }
723 }
724 usbd_free_xfer(xfer);
725 break;
726 default:
727 return (ENXIO);
728 }
729 return (error);
730 }
731
732 int
733 ugenwrite(dev_t dev, struct uio *uio, int flag)
734 {
735 int endpt = UGENENDPOINT(dev);
736 struct ugen_softc *sc;
737 int error;
738
739 sc = ugen_cd.cd_devs[UGENUNIT(dev)];
740
741 sc->sc_refcnt++;
742 error = ugen_do_write(sc, endpt, uio, flag);
743 if (--sc->sc_refcnt < 0)
744 usb_detach_wakeup(&sc->sc_dev);
745 return (error);
746 }
747
748 int
749 ugen_activate(struct device *self, enum devact act)
750 {
751 struct ugen_softc *sc = (struct ugen_softc *)self;
752
753 switch (act) {
754 case DVACT_ACTIVATE:
755 break;
756
757 case DVACT_DEACTIVATE:
758 sc->sc_dying = 1;
759 break;
760 }
761 return (0);
762 }
763
764 int
765 ugen_detach(struct device *self, int flags)
766 {
767 struct ugen_softc *sc = (struct ugen_softc *)self;
768 struct ugen_endpoint *sce;
769 int i, dir;
770 int s;
771 int maj, mn;
772
773 DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags));
774
775 sc->sc_dying = 1;
776
777 for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
778 for (dir = OUT; dir <= IN; dir++) {
779 sce = &sc->sc_endpoints[i][dir];
780 if (sce && sce->pipeh)
781 usbd_abort_pipe(sce->pipeh);
782 }
783 }
784
785 s = splusb();
786 if (--sc->sc_refcnt >= 0) {
787
788 for (i = 0; i < USB_MAX_ENDPOINTS; i++)
789 wakeup(&sc->sc_endpoints[i][IN]);
790
791 usb_detach_wait(&sc->sc_dev);
792 }
793 splx(s);
794
795
796 for (maj = 0; maj < nchrdev; maj++)
797 if (cdevsw[maj].d_open == ugenopen)
798 break;
799
800
801 mn = self->dv_unit * USB_MAX_ENDPOINTS;
802 vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR);
803
804 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
805 &sc->sc_dev);
806
807 return (0);
808 }
809
810 void
811 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
812 {
813 struct ugen_endpoint *sce = addr;
814
815 u_int32_t count;
816 u_char *ibuf;
817
818 if (status == USBD_CANCELLED)
819 return;
820
821 if (status != USBD_NORMAL_COMPLETION) {
822 DPRINTF(("ugenintr: status=%d\n", status));
823 if (status == USBD_STALLED)
824 usbd_clear_endpoint_stall_async(sce->pipeh);
825 return;
826 }
827
828 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
829 ibuf = sce->ibuf;
830
831 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
832 xfer, status, count));
833 DPRINTFN(5, (" data = %02x %02x %02x\n",
834 ibuf[0], ibuf[1], ibuf[2]));
835
836 (void)b_to_q(ibuf, count, &sce->q);
837
838 if (sce->state & UGEN_ASLP) {
839 sce->state &= ~UGEN_ASLP;
840 DPRINTFN(5, ("ugen_intr: waking %p\n", sce));
841 wakeup(sce);
842 }
843 selwakeup(&sce->rsel);
844 }
845
846 void
847 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
848 usbd_status status)
849 {
850 struct isoreq *req = addr;
851 struct ugen_endpoint *sce = req->sce;
852 u_int32_t count, n;
853 int i, isize;
854
855
856 if (status == USBD_CANCELLED)
857 return;
858
859 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
860 DPRINTFN(5,("ugen_isoc_rintr: xfer %d, count=%d\n", req - sce->isoreqs,
861 count));
862
863
864 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) {
865 sce->cur += count;
866 if(sce->cur >= sce->limit)
867 sce->cur = sce->ibuf + (sce->limit - sce->cur);
868 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n",
869 count));
870 }
871
872 isize = UGETW(sce->edesc->wMaxPacketSize);
873 for (i = 0; i < UGEN_NISORFRMS; i++) {
874 u_int32_t actlen = req->sizes[i];
875 char const *buf = (char const *)req->dmabuf + isize * i;
876
877
878 while (actlen > 0) {
879 n = min(actlen, sce->limit - sce->fill);
880 memcpy(sce->fill, buf, n);
881
882 buf += n;
883 actlen -= n;
884 sce->fill += n;
885 if(sce->fill == sce->limit)
886 sce->fill = sce->ibuf;
887 }
888
889
890 req->sizes[i] = isize;
891 }
892
893 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS,
894 USBD_NO_COPY, ugen_isoc_rintr);
895 (void)usbd_transfer(xfer);
896
897 if (sce->state & UGEN_ASLP) {
898 sce->state &= ~UGEN_ASLP;
899 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce));
900 wakeup(sce);
901 }
902 selwakeup(&sce->rsel);
903 }
904
905 usbd_status
906 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno)
907 {
908 usbd_interface_handle iface;
909 usb_endpoint_descriptor_t *ed;
910 usbd_status err;
911 struct ugen_endpoint *sce;
912 u_int8_t niface, nendpt, endptno, endpt;
913 int dir;
914
915 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
916
917 err = usbd_interface_count(sc->sc_udev, &niface);
918 if (err)
919 return (err);
920 if (ifaceidx < 0 || ifaceidx >= niface)
921 return (USBD_INVAL);
922
923 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
924 if (err)
925 return (err);
926 err = usbd_endpoint_count(iface, &nendpt);
927 if (err)
928 return (err);
929
930 for (endptno = 0; endptno < nendpt; endptno++) {
931 ed = usbd_interface2endpoint_descriptor(iface,endptno);
932 endpt = ed->bEndpointAddress;
933 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
934 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
935 sce->sc = 0;
936 sce->edesc = 0;
937 sce->iface = 0;
938 }
939
940
941 err = usbd_set_interface(iface, altno);
942 if (err)
943 return (err);
944
945 err = usbd_endpoint_count(iface, &nendpt);
946 if (err)
947 return (err);
948 for (endptno = 0; endptno < nendpt; endptno++) {
949 ed = usbd_interface2endpoint_descriptor(iface,endptno);
950 endpt = ed->bEndpointAddress;
951 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
952 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
953 sce->sc = sc;
954 sce->edesc = ed;
955 sce->iface = iface;
956 }
957 return (0);
958 }
959
960
961 usb_config_descriptor_t *
962 ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp)
963 {
964 usb_config_descriptor_t *cdesc, *tdesc, cdescr;
965 int len;
966 usbd_status err;
967
968 if (index == USB_CURRENT_CONFIG_INDEX) {
969 tdesc = usbd_get_config_descriptor(sc->sc_udev);
970 len = UGETW(tdesc->wTotalLength);
971 if (lenp)
972 *lenp = len;
973 cdesc = malloc(len, M_TEMP, M_WAITOK);
974 memcpy(cdesc, tdesc, len);
975 DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
976 } else {
977 err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
978 if (err)
979 return (0);
980 len = UGETW(cdescr.wTotalLength);
981 DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
982 if (lenp)
983 *lenp = len;
984 cdesc = malloc(len, M_TEMP, M_WAITOK);
985 err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc,
986 len);
987 if (err) {
988 free(cdesc, M_TEMP);
989 return (0);
990 }
991 }
992 return (cdesc);
993 }
994
995 int
996 ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx)
997 {
998 usbd_interface_handle iface;
999 usbd_status err;
1000
1001 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
1002 if (err)
1003 return (-1);
1004 return (usbd_get_interface_altindex(iface));
1005 }
1006
1007 int
1008 ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
1009 caddr_t addr, int flag, struct proc *p)
1010 {
1011 struct ugen_endpoint *sce;
1012 usbd_status err;
1013 usbd_interface_handle iface;
1014 struct usb_config_desc *cd;
1015 usb_config_descriptor_t *cdesc;
1016 struct usb_interface_desc *id;
1017 usb_interface_descriptor_t *idesc;
1018 struct usb_endpoint_desc *ed;
1019 usb_endpoint_descriptor_t *edesc;
1020 struct usb_alt_interface *ai;
1021 struct usb_string_desc *si;
1022 u_int8_t conf, alt;
1023
1024 DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd));
1025 if (sc->sc_dying)
1026 return (EIO);
1027
1028 switch (cmd) {
1029 case FIONBIO:
1030
1031 return (0);
1032 case USB_SET_SHORT_XFER:
1033 if (endpt == USB_CONTROL_ENDPOINT)
1034 return (EINVAL);
1035
1036 sce = &sc->sc_endpoints[endpt][IN];
1037 if (sce == NULL || sce->pipeh == NULL)
1038 return (EINVAL);
1039 if (*(int *)addr)
1040 sce->state |= UGEN_SHORT_OK;
1041 else
1042 sce->state &= ~UGEN_SHORT_OK;
1043 return (0);
1044 case USB_SET_TIMEOUT:
1045 sce = &sc->sc_endpoints[endpt][IN];
1046 if (sce == NULL
1047
1048
1049
1050 )
1051 return (EINVAL);
1052 sce->timeout = *(int *)addr;
1053 return (0);
1054 default:
1055 break;
1056 }
1057
1058 if (endpt != USB_CONTROL_ENDPOINT)
1059 return (EINVAL);
1060
1061 switch (cmd) {
1062 #ifdef UGEN_DEBUG
1063 case USB_SETDEBUG:
1064 ugendebug = *(int *)addr;
1065 break;
1066 #endif
1067 case USB_GET_CONFIG:
1068 err = usbd_get_config(sc->sc_udev, &conf);
1069 if (err)
1070 return (EIO);
1071 *(int *)addr = conf;
1072 break;
1073 case USB_SET_CONFIG:
1074 if (!(flag & FWRITE))
1075 return (EPERM);
1076 err = ugen_set_config(sc, *(int *)addr);
1077 switch (err) {
1078 case USBD_NORMAL_COMPLETION:
1079 break;
1080 case USBD_IN_USE:
1081 return (EBUSY);
1082 default:
1083 return (EIO);
1084 }
1085 break;
1086 case USB_GET_ALTINTERFACE:
1087 ai = (struct usb_alt_interface *)addr;
1088 err = usbd_device2interface_handle(sc->sc_udev,
1089 ai->uai_interface_index, &iface);
1090 if (err)
1091 return (EINVAL);
1092 idesc = usbd_get_interface_descriptor(iface);
1093 if (idesc == NULL)
1094 return (EIO);
1095 ai->uai_alt_no = idesc->bAlternateSetting;
1096 break;
1097 case USB_SET_ALTINTERFACE:
1098 if (!(flag & FWRITE))
1099 return (EPERM);
1100 ai = (struct usb_alt_interface *)addr;
1101 err = usbd_device2interface_handle(sc->sc_udev,
1102 ai->uai_interface_index, &iface);
1103 if (err)
1104 return (EINVAL);
1105 err = ugen_set_interface(sc, ai->uai_interface_index,
1106 ai->uai_alt_no);
1107 if (err)
1108 return (EINVAL);
1109 break;
1110 case USB_GET_NO_ALT:
1111 ai = (struct usb_alt_interface *)addr;
1112 cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0);
1113 if (cdesc == NULL)
1114 return (EINVAL);
1115 idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0);
1116 if (idesc == NULL) {
1117 free(cdesc, M_TEMP);
1118 return (EINVAL);
1119 }
1120 ai->uai_alt_no = usbd_get_no_alts(cdesc,
1121 idesc->bInterfaceNumber);
1122 free(cdesc, M_TEMP);
1123 break;
1124 case USB_GET_DEVICE_DESC:
1125 *(usb_device_descriptor_t *)addr =
1126 *usbd_get_device_descriptor(sc->sc_udev);
1127 break;
1128 case USB_GET_CONFIG_DESC:
1129 cd = (struct usb_config_desc *)addr;
1130 cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0);
1131 if (cdesc == NULL)
1132 return (EINVAL);
1133 cd->ucd_desc = *cdesc;
1134 free(cdesc, M_TEMP);
1135 break;
1136 case USB_GET_INTERFACE_DESC:
1137 id = (struct usb_interface_desc *)addr;
1138 cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0);
1139 if (cdesc == NULL)
1140 return (EINVAL);
1141 if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX &&
1142 id->uid_alt_index == USB_CURRENT_ALT_INDEX)
1143 alt = ugen_get_alt_index(sc, id->uid_interface_index);
1144 else
1145 alt = id->uid_alt_index;
1146 idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt);
1147 if (idesc == NULL) {
1148 free(cdesc, M_TEMP);
1149 return (EINVAL);
1150 }
1151 id->uid_desc = *idesc;
1152 free(cdesc, M_TEMP);
1153 break;
1154 case USB_GET_ENDPOINT_DESC:
1155 ed = (struct usb_endpoint_desc *)addr;
1156 cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0);
1157 if (cdesc == NULL)
1158 return (EINVAL);
1159 if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX &&
1160 ed->ued_alt_index == USB_CURRENT_ALT_INDEX)
1161 alt = ugen_get_alt_index(sc, ed->ued_interface_index);
1162 else
1163 alt = ed->ued_alt_index;
1164 edesc = usbd_find_edesc(cdesc, ed->ued_interface_index,
1165 alt, ed->ued_endpoint_index);
1166 if (edesc == NULL) {
1167 free(cdesc, M_TEMP);
1168 return (EINVAL);
1169 }
1170 ed->ued_desc = *edesc;
1171 free(cdesc, M_TEMP);
1172 break;
1173 case USB_GET_FULL_DESC:
1174 {
1175 int len;
1176 struct iovec iov;
1177 struct uio uio;
1178 struct usb_full_desc *fd = (struct usb_full_desc *)addr;
1179 int error;
1180
1181 cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len);
1182 if (len > fd->ufd_size)
1183 len = fd->ufd_size;
1184 iov.iov_base = (caddr_t)fd->ufd_data;
1185 iov.iov_len = len;
1186 uio.uio_iov = &iov;
1187 uio.uio_iovcnt = 1;
1188 uio.uio_resid = len;
1189 uio.uio_offset = 0;
1190 uio.uio_segflg = UIO_USERSPACE;
1191 uio.uio_rw = UIO_READ;
1192 uio.uio_procp = p;
1193 error = uiomove((void *)cdesc, len, &uio);
1194 free(cdesc, M_TEMP);
1195 return (error);
1196 }
1197 case USB_GET_STRING_DESC:
1198 {
1199 int len;
1200 si = (struct usb_string_desc *)addr;
1201 err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
1202 si->usd_language_id, &si->usd_desc, &len);
1203 if (err)
1204 return (EINVAL);
1205 break;
1206 }
1207 case USB_DO_REQUEST:
1208 {
1209 struct usb_ctl_request *ur = (void *)addr;
1210 int len = UGETW(ur->ucr_request.wLength);
1211 struct iovec iov;
1212 struct uio uio;
1213 void *ptr = 0;
1214 usbd_status err;
1215 int error = 0;
1216
1217 if (!(flag & FWRITE))
1218 return (EPERM);
1219
1220 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1221 ur->ucr_request.bRequest == UR_SET_ADDRESS) ||
1222 (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1223 ur->ucr_request.bRequest == UR_SET_CONFIG) ||
1224 (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE &&
1225 ur->ucr_request.bRequest == UR_SET_INTERFACE))
1226 return (EINVAL);
1227
1228 if (len < 0 || len > 32767)
1229 return (EINVAL);
1230 if (len != 0) {
1231 iov.iov_base = (caddr_t)ur->ucr_data;
1232 iov.iov_len = len;
1233 uio.uio_iov = &iov;
1234 uio.uio_iovcnt = 1;
1235 uio.uio_resid = len;
1236 uio.uio_offset = 0;
1237 uio.uio_segflg = UIO_USERSPACE;
1238 uio.uio_rw =
1239 ur->ucr_request.bmRequestType & UT_READ ?
1240 UIO_READ : UIO_WRITE;
1241 uio.uio_procp = p;
1242 ptr = malloc(len, M_TEMP, M_WAITOK);
1243 if (uio.uio_rw == UIO_WRITE) {
1244 error = uiomove(ptr, len, &uio);
1245 if (error)
1246 goto ret;
1247 }
1248 }
1249 sce = &sc->sc_endpoints[endpt][IN];
1250 err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request,
1251 ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout);
1252 if (err) {
1253 error = EIO;
1254 goto ret;
1255 }
1256 if (len != 0) {
1257 if (uio.uio_rw == UIO_READ) {
1258 error = uiomove(ptr, len, &uio);
1259 if (error)
1260 goto ret;
1261 }
1262 }
1263 ret:
1264 if (ptr)
1265 free(ptr, M_TEMP);
1266 return (error);
1267 }
1268 case USB_GET_DEVICEINFO:
1269 usbd_fill_deviceinfo(sc->sc_udev,
1270 (struct usb_device_info *)addr, 1);
1271 break;
1272 default:
1273 return (EINVAL);
1274 }
1275 return (0);
1276 }
1277
1278 int
1279 ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
1280 {
1281 int endpt = UGENENDPOINT(dev);
1282 struct ugen_softc *sc;
1283 int error;
1284
1285 sc = ugen_cd.cd_devs[UGENUNIT(dev)];
1286
1287 sc->sc_refcnt++;
1288 error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
1289 if (--sc->sc_refcnt < 0)
1290 usb_detach_wakeup(&sc->sc_dev);
1291 return (error);
1292 }
1293
1294 int
1295 ugenpoll(dev_t dev, int events, struct proc *p)
1296 {
1297 struct ugen_softc *sc;
1298 struct ugen_endpoint *sce;
1299 int revents = 0;
1300 int s;
1301
1302 sc = ugen_cd.cd_devs[UGENUNIT(dev)];
1303
1304 if (sc->sc_dying)
1305 return (POLLERR);
1306
1307
1308 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1309 if (sce == NULL)
1310 return (POLLERR);
1311 #ifdef DIAGNOSTIC
1312 if (!sce->edesc) {
1313 printf("ugenpoll: no edesc\n");
1314 return (POLLERR);
1315 }
1316 if (!sce->pipeh) {
1317 printf("ugenpoll: no pipe\n");
1318 return (POLLERR);
1319 }
1320 #endif
1321 s = splusb();
1322 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
1323 case UE_INTERRUPT:
1324 if (events & (POLLIN | POLLRDNORM)) {
1325 if (sce->q.c_cc > 0)
1326 revents |= events & (POLLIN | POLLRDNORM);
1327 else
1328 selrecord(p, &sce->rsel);
1329 }
1330 break;
1331 case UE_ISOCHRONOUS:
1332 if (events & (POLLIN | POLLRDNORM)) {
1333 if (sce->cur != sce->fill)
1334 revents |= events & (POLLIN | POLLRDNORM);
1335 else
1336 selrecord(p, &sce->rsel);
1337 }
1338 break;
1339 case UE_BULK:
1340
1341
1342
1343
1344
1345 revents |= events &
1346 (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
1347 break;
1348 default:
1349 break;
1350 }
1351 splx(s);
1352 return (revents);
1353 }
1354
1355 void filt_ugenrdetach(struct knote *);
1356 int filt_ugenread_intr(struct knote *, long);
1357 int filt_ugenread_isoc(struct knote *, long);
1358 int ugenkqfilter(dev_t, struct knote *);
1359
1360 void
1361 filt_ugenrdetach(struct knote *kn)
1362 {
1363 struct ugen_endpoint *sce = (void *)kn->kn_hook;
1364 int s;
1365
1366 s = splusb();
1367 SLIST_REMOVE(&sce->rsel.si_note, kn, knote, kn_selnext);
1368 splx(s);
1369 }
1370
1371 int
1372 filt_ugenread_intr(struct knote *kn, long hint)
1373 {
1374 struct ugen_endpoint *sce = (void *)kn->kn_hook;
1375
1376 kn->kn_data = sce->q.c_cc;
1377 return (kn->kn_data > 0);
1378 }
1379
1380 int
1381 filt_ugenread_isoc(struct knote *kn, long hint)
1382 {
1383 struct ugen_endpoint *sce = (void *)kn->kn_hook;
1384
1385 if (sce->cur == sce->fill)
1386 return (0);
1387
1388 if (sce->cur < sce->fill)
1389 kn->kn_data = sce->fill - sce->cur;
1390 else
1391 kn->kn_data = (sce->limit - sce->cur) +
1392 (sce->fill - sce->ibuf);
1393
1394 return (1);
1395 }
1396
1397 struct filterops ugenread_intr_filtops =
1398 { 1, NULL, filt_ugenrdetach, filt_ugenread_intr };
1399
1400 struct filterops ugenread_isoc_filtops =
1401 { 1, NULL, filt_ugenrdetach, filt_ugenread_isoc };
1402
1403 struct filterops ugen_seltrue_filtops =
1404 { 1, NULL, filt_ugenrdetach, filt_seltrue };
1405
1406 int
1407 ugenkqfilter(dev_t dev, struct knote *kn)
1408 {
1409 struct ugen_softc *sc;
1410 struct ugen_endpoint *sce;
1411 struct klist *klist;
1412 int s;
1413
1414 sc = ugen_cd.cd_devs[UGENUNIT(dev)];
1415
1416 if (sc->sc_dying)
1417 return (1);
1418
1419
1420 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1421 if (sce == NULL)
1422 return (1);
1423
1424 switch (kn->kn_filter) {
1425 case EVFILT_READ:
1426 klist = &sce->rsel.si_note;
1427 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
1428 case UE_INTERRUPT:
1429 kn->kn_fop = &ugenread_intr_filtops;
1430 break;
1431 case UE_ISOCHRONOUS:
1432 kn->kn_fop = &ugenread_isoc_filtops;
1433 break;
1434 case UE_BULK:
1435
1436
1437
1438
1439
1440 kn->kn_fop = &ugen_seltrue_filtops;
1441 break;
1442 default:
1443 return (1);
1444 }
1445 break;
1446
1447 case EVFILT_WRITE:
1448 klist = &sce->rsel.si_note;
1449 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
1450 case UE_INTERRUPT:
1451 case UE_ISOCHRONOUS:
1452
1453 return (1);
1454
1455 case UE_BULK:
1456
1457
1458
1459
1460
1461 kn->kn_fop = &ugen_seltrue_filtops;
1462 break;
1463 default:
1464 return (1);
1465 }
1466 break;
1467
1468 default:
1469 return (1);
1470 }
1471
1472 kn->kn_hook = (void *)sce;
1473
1474 s = splusb();
1475 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
1476 splx(s);
1477
1478 return (0);
1479 }