ugen.c revision 1.96 1 /* $NetBSD: ugen.c,v 1.96 2007/12/24 14:41:19 smb Exp $ */
2
3 /*
4 * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart (at) augustsson.net) at
9 * Carlstedt Research & Technology.
10 *
11 * Copyright (c) 2006 BBN Technologies Corp. All rights reserved.
12 * Effort sponsored in part by the Defense Advanced Research Projects
13 * Agency (DARPA) and the Department of the Interior National Business
14 * Center under agreement number NBCHC050166.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. All advertising materials mentioning features or use of this software
25 * must display the following acknowledgement:
26 * This product includes software developed by the NetBSD
27 * Foundation, Inc. and its contributors.
28 * 4. Neither the name of The NetBSD Foundation nor the names of its
29 * contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
33 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
34 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
35 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
36 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGE.
43 */
44
45
46 #include <sys/cdefs.h>
47 __KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.96 2007/12/24 14:41:19 smb Exp $");
48
49 #include "opt_ugen_bulk_ra_wb.h"
50 #include "opt_compat_netbsd.h"
51
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/kernel.h>
55 #include <sys/malloc.h>
56 #if defined(__NetBSD__) || defined(__OpenBSD__)
57 #include <sys/device.h>
58 #include <sys/ioctl.h>
59 #elif defined(__FreeBSD__)
60 #include <sys/module.h>
61 #include <sys/bus.h>
62 #include <sys/ioccom.h>
63 #include <sys/conf.h>
64 #include <sys/fcntl.h>
65 #include <sys/filio.h>
66 #endif
67 #include <sys/conf.h>
68 #include <sys/tty.h>
69 #include <sys/file.h>
70 #include <sys/select.h>
71 #include <sys/proc.h>
72 #include <sys/vnode.h>
73 #include <sys/poll.h>
74
75 #include <dev/usb/usb.h>
76 #include <dev/usb/usbdi.h>
77 #include <dev/usb/usbdi_util.h>
78
79 #ifdef UGEN_DEBUG
80 #define DPRINTF(x) if (ugendebug) logprintf x
81 #define DPRINTFN(n,x) if (ugendebug>(n)) logprintf x
82 int ugendebug = 0;
83 #else
84 #define DPRINTF(x)
85 #define DPRINTFN(n,x)
86 #endif
87
88 #define UGEN_CHUNK 128 /* chunk size for read */
89 #define UGEN_IBSIZE 1020 /* buffer size */
90 #define UGEN_BBSIZE 1024
91
92 #define UGEN_NISOFRAMES 500 /* 0.5 seconds worth */
93 #define UGEN_NISOREQS 6 /* number of outstanding xfer requests */
94 #define UGEN_NISORFRMS 4 /* number of frames (miliseconds) per req */
95
96 #define UGEN_BULK_RA_WB_BUFSIZE 16384 /* default buffer size */
97 #define UGEN_BULK_RA_WB_BUFMAX (1 << 20) /* maximum allowed buffer */
98
99 struct ugen_endpoint {
100 struct ugen_softc *sc;
101 usb_endpoint_descriptor_t *edesc;
102 usbd_interface_handle iface;
103 int state;
104 #define UGEN_ASLP 0x02 /* waiting for data */
105 #define UGEN_SHORT_OK 0x04 /* short xfers are OK */
106 #define UGEN_BULK_RA 0x08 /* in bulk read-ahead mode */
107 #define UGEN_BULK_WB 0x10 /* in bulk write-behind mode */
108 #define UGEN_RA_WB_STOP 0x20 /* RA/WB xfer is stopped (buffer full/empty) */
109 usbd_pipe_handle pipeh;
110 struct clist q;
111 struct selinfo rsel;
112 u_char *ibuf; /* start of buffer (circular for isoc) */
113 u_char *fill; /* location for input (isoc) */
114 u_char *limit; /* end of circular buffer (isoc) */
115 u_char *cur; /* current read location (isoc) */
116 u_int32_t timeout;
117 #ifdef UGEN_BULK_RA_WB
118 u_int32_t ra_wb_bufsize; /* requested size for RA/WB buffer */
119 u_int32_t ra_wb_reqsize; /* requested xfer length for RA/WB */
120 u_int32_t ra_wb_used; /* how much is in buffer */
121 u_int32_t ra_wb_xferlen; /* current xfer length for RA/WB */
122 usbd_xfer_handle ra_wb_xfer;
123 #endif
124 struct isoreq {
125 struct ugen_endpoint *sce;
126 usbd_xfer_handle xfer;
127 void *dmabuf;
128 u_int16_t sizes[UGEN_NISORFRMS];
129 } isoreqs[UGEN_NISOREQS];
130 };
131
132 struct ugen_softc {
133 USBBASEDEVICE sc_dev; /* base device */
134 usbd_device_handle sc_udev;
135
136 char sc_is_open[USB_MAX_ENDPOINTS];
137 struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2];
138 #define OUT 0
139 #define IN 1
140
141 int sc_refcnt;
142 char sc_buffer[UGEN_BBSIZE];
143 u_char sc_dying;
144 };
145
146 #if defined(__NetBSD__)
147 dev_type_open(ugenopen);
148 dev_type_close(ugenclose);
149 dev_type_read(ugenread);
150 dev_type_write(ugenwrite);
151 dev_type_ioctl(ugenioctl);
152 dev_type_poll(ugenpoll);
153 dev_type_kqfilter(ugenkqfilter);
154
155 const struct cdevsw ugen_cdevsw = {
156 ugenopen, ugenclose, ugenread, ugenwrite, ugenioctl,
157 nostop, notty, ugenpoll, nommap, ugenkqfilter, D_OTHER,
158 };
159 #elif defined(__OpenBSD__)
160 cdev_decl(ugen);
161 #elif defined(__FreeBSD__)
162 d_open_t ugenopen;
163 d_close_t ugenclose;
164 d_read_t ugenread;
165 d_write_t ugenwrite;
166 d_ioctl_t ugenioctl;
167 d_poll_t ugenpoll;
168
169 #define UGEN_CDEV_MAJOR 114
170
171 Static struct cdevsw ugen_cdevsw = {
172 /* open */ ugenopen,
173 /* close */ ugenclose,
174 /* read */ ugenread,
175 /* write */ ugenwrite,
176 /* ioctl */ ugenioctl,
177 /* poll */ ugenpoll,
178 /* mmap */ nommap,
179 /* strategy */ nostrategy,
180 /* name */ "ugen",
181 /* maj */ UGEN_CDEV_MAJOR,
182 /* dump */ nodump,
183 /* psize */ nopsize,
184 /* flags */ 0,
185 /* bmaj */ -1
186 };
187 #endif
188
189 Static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr,
190 usbd_status status);
191 Static void ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
192 usbd_status status);
193 #ifdef UGEN_BULK_RA_WB
194 Static void ugen_bulkra_intr(usbd_xfer_handle xfer, usbd_private_handle addr,
195 usbd_status status);
196 Static void ugen_bulkwb_intr(usbd_xfer_handle xfer, usbd_private_handle addr,
197 usbd_status status);
198 #endif
199 Static int ugen_do_read(struct ugen_softc *, int, struct uio *, int);
200 Static int ugen_do_write(struct ugen_softc *, int, struct uio *, int);
201 Static int ugen_do_ioctl(struct ugen_softc *, int, u_long,
202 void *, int, struct lwp *);
203 Static int ugen_set_config(struct ugen_softc *sc, int configno);
204 Static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc,
205 int index, int *lenp);
206 Static usbd_status ugen_set_interface(struct ugen_softc *, int, int);
207 Static int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx);
208
209 #define UGENUNIT(n) ((minor(n) >> 4) & 0xf)
210 #define UGENENDPOINT(n) (minor(n) & 0xf)
211 #define UGENDEV(u, e) (makedev(0, ((u) << 4) | (e)))
212
213 USB_DECLARE_DRIVER(ugen);
214
215 USB_MATCH(ugen)
216 {
217 USB_MATCH_START(ugen, uaa);
218
219 if (match->cf_flags & 1)
220 return (UMATCH_HIGHEST);
221 else if (uaa->usegeneric)
222 return (UMATCH_GENERIC);
223 else
224 return (UMATCH_NONE);
225 }
226
227 USB_ATTACH(ugen)
228 {
229 USB_ATTACH_START(ugen, sc, uaa);
230 usbd_device_handle udev;
231 char *devinfop;
232 usbd_status err;
233 int conf;
234
235 devinfop = usbd_devinfo_alloc(uaa->device, 0);
236 USB_ATTACH_SETUP;
237 aprint_normal("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfop);
238 usbd_devinfo_free(devinfop);
239
240 sc->sc_udev = udev = uaa->device;
241
242 /* First set configuration index 0, the default one for ugen. */
243 err = usbd_set_config_index(udev, 0, 0);
244 if (err) {
245 aprint_error("%s: setting configuration index 0 failed\n",
246 USBDEVNAME(sc->sc_dev));
247 sc->sc_dying = 1;
248 USB_ATTACH_ERROR_RETURN;
249 }
250 conf = usbd_get_config_descriptor(udev)->bConfigurationValue;
251
252 /* Set up all the local state for this configuration. */
253 err = ugen_set_config(sc, conf);
254 if (err) {
255 aprint_error("%s: setting configuration %d failed\n",
256 USBDEVNAME(sc->sc_dev), conf);
257 sc->sc_dying = 1;
258 USB_ATTACH_ERROR_RETURN;
259 }
260
261 #ifdef __FreeBSD__
262 {
263 static int global_init_done = 0;
264 if (!global_init_done) {
265 cdevsw_add(&ugen_cdevsw);
266 global_init_done = 1;
267 }
268 }
269 #endif
270
271 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
272 USBDEV(sc->sc_dev));
273
274 if (!pmf_device_register(self, NULL, NULL))
275 aprint_error_dev(self, "couldn't establish power handler\n");
276
277 USB_ATTACH_SUCCESS_RETURN;
278 }
279
280 Static int
281 ugen_set_config(struct ugen_softc *sc, int configno)
282 {
283 usbd_device_handle dev = sc->sc_udev;
284 usbd_interface_handle iface;
285 usb_endpoint_descriptor_t *ed;
286 struct ugen_endpoint *sce;
287 u_int8_t niface, nendpt;
288 int ifaceno, endptno, endpt;
289 usbd_status err;
290 int dir;
291
292 DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
293 USBDEVNAME(sc->sc_dev), configno, sc));
294
295 /*
296 * We start at 1, not 0, because we don't care whether the
297 * control endpoint is open or not. It is always present.
298 */
299 for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++)
300 if (sc->sc_is_open[endptno]) {
301 DPRINTFN(1,
302 ("ugen_set_config: %s - endpoint %d is open\n",
303 USBDEVNAME(sc->sc_dev), endptno));
304 return (USBD_IN_USE);
305 }
306
307 /* Avoid setting the current value. */
308 if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) {
309 err = usbd_set_config_no(dev, configno, 1);
310 if (err)
311 return (err);
312 }
313
314 err = usbd_interface_count(dev, &niface);
315 if (err)
316 return (err);
317 memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
318 for (ifaceno = 0; ifaceno < niface; ifaceno++) {
319 DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
320 err = usbd_device2interface_handle(dev, ifaceno, &iface);
321 if (err)
322 return (err);
323 err = usbd_endpoint_count(iface, &nendpt);
324 if (err)
325 return (err);
326 for (endptno = 0; endptno < nendpt; endptno++) {
327 ed = usbd_interface2endpoint_descriptor(iface,endptno);
328 KASSERT(ed != NULL);
329 endpt = ed->bEndpointAddress;
330 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
331 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
332 DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x"
333 "(%d,%d), sce=%p\n",
334 endptno, endpt, UE_GET_ADDR(endpt),
335 UE_GET_DIR(endpt), sce));
336 sce->sc = sc;
337 sce->edesc = ed;
338 sce->iface = iface;
339 }
340 }
341 return (USBD_NORMAL_COMPLETION);
342 }
343
344 int
345 ugenopen(dev_t dev, int flag, int mode, struct lwp *l)
346 {
347 struct ugen_softc *sc;
348 int unit = UGENUNIT(dev);
349 int endpt = UGENENDPOINT(dev);
350 usb_endpoint_descriptor_t *edesc;
351 struct ugen_endpoint *sce;
352 int dir, isize;
353 usbd_status err;
354 usbd_xfer_handle xfer;
355 void *tbuf;
356 int i, j;
357
358 USB_GET_SC_OPEN(ugen, unit, sc);
359
360 DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
361 flag, mode, unit, endpt));
362
363 if (sc == NULL || sc->sc_dying)
364 return (ENXIO);
365
366 /* The control endpoint allows multiple opens. */
367 if (endpt == USB_CONTROL_ENDPOINT) {
368 sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
369 return (0);
370 }
371
372 if (sc->sc_is_open[endpt])
373 return (EBUSY);
374
375 /* Make sure there are pipes for all directions. */
376 for (dir = OUT; dir <= IN; dir++) {
377 if (flag & (dir == OUT ? FWRITE : FREAD)) {
378 sce = &sc->sc_endpoints[endpt][dir];
379 if (sce == 0 || sce->edesc == 0)
380 return (ENXIO);
381 }
382 }
383
384 /* Actually open the pipes. */
385 /* XXX Should back out properly if it fails. */
386 for (dir = OUT; dir <= IN; dir++) {
387 if (!(flag & (dir == OUT ? FWRITE : FREAD)))
388 continue;
389 sce = &sc->sc_endpoints[endpt][dir];
390 sce->state = 0;
391 sce->timeout = USBD_NO_TIMEOUT;
392 DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
393 sc, endpt, dir, sce));
394 edesc = sce->edesc;
395 switch (edesc->bmAttributes & UE_XFERTYPE) {
396 case UE_INTERRUPT:
397 if (dir == OUT) {
398 err = usbd_open_pipe(sce->iface,
399 edesc->bEndpointAddress, 0, &sce->pipeh);
400 if (err)
401 return (EIO);
402 break;
403 }
404 isize = UGETW(edesc->wMaxPacketSize);
405 if (isize == 0) /* shouldn't happen */
406 return (EINVAL);
407 sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
408 DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
409 endpt, isize));
410 if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
411 return (ENOMEM);
412 err = usbd_open_pipe_intr(sce->iface,
413 edesc->bEndpointAddress,
414 USBD_SHORT_XFER_OK, &sce->pipeh, sce,
415 sce->ibuf, isize, ugenintr,
416 USBD_DEFAULT_INTERVAL);
417 if (err) {
418 free(sce->ibuf, M_USBDEV);
419 clfree(&sce->q);
420 return (EIO);
421 }
422 DPRINTFN(5, ("ugenopen: interrupt open done\n"));
423 break;
424 case UE_BULK:
425 err = usbd_open_pipe(sce->iface,
426 edesc->bEndpointAddress, 0, &sce->pipeh);
427 if (err)
428 return (EIO);
429 #ifdef UGEN_BULK_RA_WB
430 sce->ra_wb_bufsize = UGEN_BULK_RA_WB_BUFSIZE;
431 /*
432 * Use request size for non-RA/WB transfers
433 * as the default.
434 */
435 sce->ra_wb_reqsize = UGEN_BBSIZE;
436 #endif
437 break;
438 case UE_ISOCHRONOUS:
439 if (dir == OUT)
440 return (EINVAL);
441 isize = UGETW(edesc->wMaxPacketSize);
442 if (isize == 0) /* shouldn't happen */
443 return (EINVAL);
444 sce->ibuf = malloc(isize * UGEN_NISOFRAMES,
445 M_USBDEV, M_WAITOK);
446 sce->cur = sce->fill = sce->ibuf;
447 sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES;
448 DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n",
449 endpt, isize));
450 err = usbd_open_pipe(sce->iface,
451 edesc->bEndpointAddress, 0, &sce->pipeh);
452 if (err) {
453 free(sce->ibuf, M_USBDEV);
454 return (EIO);
455 }
456 for(i = 0; i < UGEN_NISOREQS; ++i) {
457 sce->isoreqs[i].sce = sce;
458 xfer = usbd_alloc_xfer(sc->sc_udev);
459 if (xfer == 0)
460 goto bad;
461 sce->isoreqs[i].xfer = xfer;
462 tbuf = usbd_alloc_buffer
463 (xfer, isize * UGEN_NISORFRMS);
464 if (tbuf == 0) {
465 i++;
466 goto bad;
467 }
468 sce->isoreqs[i].dmabuf = tbuf;
469 for(j = 0; j < UGEN_NISORFRMS; ++j)
470 sce->isoreqs[i].sizes[j] = isize;
471 usbd_setup_isoc_xfer
472 (xfer, sce->pipeh, &sce->isoreqs[i],
473 sce->isoreqs[i].sizes,
474 UGEN_NISORFRMS, USBD_NO_COPY,
475 ugen_isoc_rintr);
476 (void)usbd_transfer(xfer);
477 }
478 DPRINTFN(5, ("ugenopen: isoc open done\n"));
479 break;
480 bad:
481 while (--i >= 0) /* implicit buffer free */
482 usbd_free_xfer(sce->isoreqs[i].xfer);
483 return (ENOMEM);
484 case UE_CONTROL:
485 sce->timeout = USBD_DEFAULT_TIMEOUT;
486 return (EINVAL);
487 }
488 }
489 sc->sc_is_open[endpt] = 1;
490 return (0);
491 }
492
493 int
494 ugenclose(dev_t dev, int flag, int mode, struct lwp *l)
495 {
496 int endpt = UGENENDPOINT(dev);
497 struct ugen_softc *sc;
498 struct ugen_endpoint *sce;
499 int dir;
500 int i;
501
502 USB_GET_SC(ugen, UGENUNIT(dev), sc);
503
504 DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
505 flag, mode, UGENUNIT(dev), endpt));
506
507 #ifdef DIAGNOSTIC
508 if (!sc->sc_is_open[endpt]) {
509 printf("ugenclose: not open\n");
510 return (EINVAL);
511 }
512 #endif
513
514 if (endpt == USB_CONTROL_ENDPOINT) {
515 DPRINTFN(5, ("ugenclose: close control\n"));
516 sc->sc_is_open[endpt] = 0;
517 return (0);
518 }
519
520 for (dir = OUT; dir <= IN; dir++) {
521 if (!(flag & (dir == OUT ? FWRITE : FREAD)))
522 continue;
523 sce = &sc->sc_endpoints[endpt][dir];
524 if (sce == NULL || sce->pipeh == NULL)
525 continue;
526 DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
527 endpt, dir, sce));
528
529 usbd_abort_pipe(sce->pipeh);
530 usbd_close_pipe(sce->pipeh);
531 sce->pipeh = NULL;
532
533 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
534 case UE_INTERRUPT:
535 ndflush(&sce->q, sce->q.c_cc);
536 clfree(&sce->q);
537 break;
538 case UE_ISOCHRONOUS:
539 for (i = 0; i < UGEN_NISOREQS; ++i)
540 usbd_free_xfer(sce->isoreqs[i].xfer);
541 break;
542 #ifdef UGEN_BULK_RA_WB
543 case UE_BULK:
544 if (sce->state & (UGEN_BULK_RA | UGEN_BULK_WB))
545 /* ibuf freed below */
546 usbd_free_xfer(sce->ra_wb_xfer);
547 break;
548 #endif
549 default:
550 break;
551 }
552
553 if (sce->ibuf != NULL) {
554 free(sce->ibuf, M_USBDEV);
555 sce->ibuf = NULL;
556 clfree(&sce->q);
557 }
558 }
559 sc->sc_is_open[endpt] = 0;
560
561 return (0);
562 }
563
564 Static int
565 ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
566 {
567 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
568 u_int32_t n, tn;
569 usbd_xfer_handle xfer;
570 usbd_status err;
571 int s;
572 int error = 0;
573
574 DPRINTFN(5, ("%s: ugenread: %d\n", USBDEVNAME(sc->sc_dev), endpt));
575
576 if (sc->sc_dying)
577 return (EIO);
578
579 if (endpt == USB_CONTROL_ENDPOINT)
580 return (ENODEV);
581
582 #ifdef DIAGNOSTIC
583 if (sce->edesc == NULL) {
584 printf("ugenread: no edesc\n");
585 return (EIO);
586 }
587 if (sce->pipeh == NULL) {
588 printf("ugenread: no pipe\n");
589 return (EIO);
590 }
591 #endif
592
593 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
594 case UE_INTERRUPT:
595 /* Block until activity occurred. */
596 s = splusb();
597 while (sce->q.c_cc == 0) {
598 if (flag & IO_NDELAY) {
599 splx(s);
600 return (EWOULDBLOCK);
601 }
602 sce->state |= UGEN_ASLP;
603 DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
604 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0);
605 DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
606 if (sc->sc_dying)
607 error = EIO;
608 if (error) {
609 sce->state &= ~UGEN_ASLP;
610 break;
611 }
612 }
613 splx(s);
614
615 /* Transfer as many chunks as possible. */
616 while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) {
617 n = min(sce->q.c_cc, uio->uio_resid);
618 if (n > sizeof(sc->sc_buffer))
619 n = sizeof(sc->sc_buffer);
620
621 /* Remove a small chunk from the input queue. */
622 q_to_b(&sce->q, sc->sc_buffer, n);
623 DPRINTFN(5, ("ugenread: got %d chars\n", n));
624
625 /* Copy the data to the user process. */
626 error = uiomove(sc->sc_buffer, n, uio);
627 if (error)
628 break;
629 }
630 break;
631 case UE_BULK:
632 #ifdef UGEN_BULK_RA_WB
633 if (sce->state & UGEN_BULK_RA) {
634 DPRINTFN(5, ("ugenread: BULK_RA req: %zd used: %d\n",
635 uio->uio_resid, sce->ra_wb_used));
636 xfer = sce->ra_wb_xfer;
637
638 s = splusb();
639 if (sce->ra_wb_used == 0 && flag & IO_NDELAY) {
640 splx(s);
641 return (EWOULDBLOCK);
642 }
643 while (uio->uio_resid > 0 && !error) {
644 while (sce->ra_wb_used == 0) {
645 sce->state |= UGEN_ASLP;
646 DPRINTFN(5,
647 ("ugenread: sleep on %p\n",
648 sce));
649 error = tsleep(sce, PZERO | PCATCH,
650 "ugenrb", 0);
651 DPRINTFN(5,
652 ("ugenread: woke, error=%d\n",
653 error));
654 if (sc->sc_dying)
655 error = EIO;
656 if (error) {
657 sce->state &= ~UGEN_ASLP;
658 break;
659 }
660 }
661
662 /* Copy data to the process. */
663 while (uio->uio_resid > 0
664 && sce->ra_wb_used > 0) {
665 n = min(uio->uio_resid,
666 sce->ra_wb_used);
667 n = min(n, sce->limit - sce->cur);
668 error = uiomove(sce->cur, n, uio);
669 if (error)
670 break;
671 sce->cur += n;
672 sce->ra_wb_used -= n;
673 if (sce->cur == sce->limit)
674 sce->cur = sce->ibuf;
675 }
676
677 /*
678 * If the transfers stopped because the
679 * buffer was full, restart them.
680 */
681 if (sce->state & UGEN_RA_WB_STOP &&
682 sce->ra_wb_used < sce->limit - sce->ibuf) {
683 n = (sce->limit - sce->ibuf)
684 - sce->ra_wb_used;
685 usbd_setup_xfer(xfer,
686 sce->pipeh, sce, NULL,
687 min(n, sce->ra_wb_xferlen),
688 USBD_NO_COPY, USBD_NO_TIMEOUT,
689 ugen_bulkra_intr);
690 sce->state &= ~UGEN_RA_WB_STOP;
691 err = usbd_transfer(xfer);
692 if (err != USBD_IN_PROGRESS)
693 /*
694 * The transfer has not been
695 * queued. Setting STOP
696 * will make us try
697 * again at the next read.
698 */
699 sce->state |= UGEN_RA_WB_STOP;
700 }
701 }
702 splx(s);
703 break;
704 }
705 #endif
706 xfer = usbd_alloc_xfer(sc->sc_udev);
707 if (xfer == 0)
708 return (ENOMEM);
709 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
710 DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
711 tn = n;
712 err = usbd_bulk_transfer(
713 xfer, sce->pipeh,
714 sce->state & UGEN_SHORT_OK ?
715 USBD_SHORT_XFER_OK : 0,
716 sce->timeout, sc->sc_buffer, &tn, "ugenrb");
717 if (err) {
718 if (err == USBD_INTERRUPTED)
719 error = EINTR;
720 else if (err == USBD_TIMEOUT)
721 error = ETIMEDOUT;
722 else
723 error = EIO;
724 break;
725 }
726 DPRINTFN(1, ("ugenread: got %d bytes\n", tn));
727 error = uiomove(sc->sc_buffer, tn, uio);
728 if (error || tn < n)
729 break;
730 }
731 usbd_free_xfer(xfer);
732 break;
733 case UE_ISOCHRONOUS:
734 s = splusb();
735 while (sce->cur == sce->fill) {
736 if (flag & IO_NDELAY) {
737 splx(s);
738 return (EWOULDBLOCK);
739 }
740 sce->state |= UGEN_ASLP;
741 DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
742 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0);
743 DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
744 if (sc->sc_dying)
745 error = EIO;
746 if (error) {
747 sce->state &= ~UGEN_ASLP;
748 break;
749 }
750 }
751
752 while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) {
753 if(sce->fill > sce->cur)
754 n = min(sce->fill - sce->cur, uio->uio_resid);
755 else
756 n = min(sce->limit - sce->cur, uio->uio_resid);
757
758 DPRINTFN(5, ("ugenread: isoc got %d chars\n", n));
759
760 /* Copy the data to the user process. */
761 error = uiomove(sce->cur, n, uio);
762 if (error)
763 break;
764 sce->cur += n;
765 if(sce->cur >= sce->limit)
766 sce->cur = sce->ibuf;
767 }
768 splx(s);
769 break;
770
771
772 default:
773 return (ENXIO);
774 }
775 return (error);
776 }
777
778 int
779 ugenread(dev_t dev, struct uio *uio, int flag)
780 {
781 int endpt = UGENENDPOINT(dev);
782 struct ugen_softc *sc;
783 int error;
784
785 USB_GET_SC(ugen, UGENUNIT(dev), sc);
786
787 sc->sc_refcnt++;
788 error = ugen_do_read(sc, endpt, uio, flag);
789 if (--sc->sc_refcnt < 0)
790 usb_detach_wakeup(USBDEV(sc->sc_dev));
791 return (error);
792 }
793
794 Static int
795 ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio,
796 int flag)
797 {
798 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
799 u_int32_t n;
800 int error = 0;
801 #ifdef UGEN_BULK_RA_WB
802 int s;
803 u_int32_t tn;
804 char *dbuf;
805 #endif
806 usbd_xfer_handle xfer;
807 usbd_status err;
808
809 DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc->sc_dev), endpt));
810
811 if (sc->sc_dying)
812 return (EIO);
813
814 if (endpt == USB_CONTROL_ENDPOINT)
815 return (ENODEV);
816
817 #ifdef DIAGNOSTIC
818 if (sce->edesc == NULL) {
819 printf("ugenwrite: no edesc\n");
820 return (EIO);
821 }
822 if (sce->pipeh == NULL) {
823 printf("ugenwrite: no pipe\n");
824 return (EIO);
825 }
826 #endif
827
828 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
829 case UE_BULK:
830 #ifdef UGEN_BULK_RA_WB
831 if (sce->state & UGEN_BULK_WB) {
832 DPRINTFN(5, ("ugenwrite: BULK_WB req: %zd used: %d\n",
833 uio->uio_resid, sce->ra_wb_used));
834 xfer = sce->ra_wb_xfer;
835
836 s = splusb();
837 if (sce->ra_wb_used == sce->limit - sce->ibuf &&
838 flag & IO_NDELAY) {
839 splx(s);
840 return (EWOULDBLOCK);
841 }
842 while (uio->uio_resid > 0 && !error) {
843 while (sce->ra_wb_used ==
844 sce->limit - sce->ibuf) {
845 sce->state |= UGEN_ASLP;
846 DPRINTFN(5,
847 ("ugenwrite: sleep on %p\n",
848 sce));
849 error = tsleep(sce, PZERO | PCATCH,
850 "ugenwb", 0);
851 DPRINTFN(5,
852 ("ugenwrite: woke, error=%d\n",
853 error));
854 if (sc->sc_dying)
855 error = EIO;
856 if (error) {
857 sce->state &= ~UGEN_ASLP;
858 break;
859 }
860 }
861
862 /* Copy data from the process. */
863 while (uio->uio_resid > 0 &&
864 sce->ra_wb_used < sce->limit - sce->ibuf) {
865 n = min(uio->uio_resid,
866 (sce->limit - sce->ibuf)
867 - sce->ra_wb_used);
868 n = min(n, sce->limit - sce->fill);
869 error = uiomove(sce->fill, n, uio);
870 if (error)
871 break;
872 sce->fill += n;
873 sce->ra_wb_used += n;
874 if (sce->fill == sce->limit)
875 sce->fill = sce->ibuf;
876 }
877
878 /*
879 * If the transfers stopped because the
880 * buffer was empty, restart them.
881 */
882 if (sce->state & UGEN_RA_WB_STOP &&
883 sce->ra_wb_used > 0) {
884 dbuf = (char *)usbd_get_buffer(xfer);
885 n = min(sce->ra_wb_used,
886 sce->ra_wb_xferlen);
887 tn = min(n, sce->limit - sce->cur);
888 memcpy(dbuf, sce->cur, tn);
889 dbuf += tn;
890 if (n - tn > 0)
891 memcpy(dbuf, sce->ibuf,
892 n - tn);
893 usbd_setup_xfer(xfer,
894 sce->pipeh, sce, NULL, n,
895 USBD_NO_COPY, USBD_NO_TIMEOUT,
896 ugen_bulkwb_intr);
897 sce->state &= ~UGEN_RA_WB_STOP;
898 err = usbd_transfer(xfer);
899 if (err != USBD_IN_PROGRESS)
900 /*
901 * The transfer has not been
902 * queued. Setting STOP
903 * will make us try again
904 * at the next read.
905 */
906 sce->state |= UGEN_RA_WB_STOP;
907 }
908 }
909 splx(s);
910 break;
911 }
912 #endif
913 xfer = usbd_alloc_xfer(sc->sc_udev);
914 if (xfer == 0)
915 return (EIO);
916 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
917 error = uiomove(sc->sc_buffer, n, uio);
918 if (error)
919 break;
920 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
921 err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
922 sce->timeout, sc->sc_buffer, &n,"ugenwb");
923 if (err) {
924 if (err == USBD_INTERRUPTED)
925 error = EINTR;
926 else if (err == USBD_TIMEOUT)
927 error = ETIMEDOUT;
928 else
929 error = EIO;
930 break;
931 }
932 }
933 usbd_free_xfer(xfer);
934 break;
935 case UE_INTERRUPT:
936 xfer = usbd_alloc_xfer(sc->sc_udev);
937 if (xfer == 0)
938 return (EIO);
939 while ((n = min(UGETW(sce->edesc->wMaxPacketSize),
940 uio->uio_resid)) != 0) {
941 error = uiomove(sc->sc_buffer, n, uio);
942 if (error)
943 break;
944 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
945 err = usbd_intr_transfer(xfer, sce->pipeh, 0,
946 sce->timeout, sc->sc_buffer, &n, "ugenwi");
947 if (err) {
948 if (err == USBD_INTERRUPTED)
949 error = EINTR;
950 else if (err == USBD_TIMEOUT)
951 error = ETIMEDOUT;
952 else
953 error = EIO;
954 break;
955 }
956 }
957 usbd_free_xfer(xfer);
958 break;
959 default:
960 return (ENXIO);
961 }
962 return (error);
963 }
964
965 int
966 ugenwrite(dev_t dev, struct uio *uio, int flag)
967 {
968 int endpt = UGENENDPOINT(dev);
969 struct ugen_softc *sc;
970 int error;
971
972 USB_GET_SC(ugen, UGENUNIT(dev), sc);
973
974 sc->sc_refcnt++;
975 error = ugen_do_write(sc, endpt, uio, flag);
976 if (--sc->sc_refcnt < 0)
977 usb_detach_wakeup(USBDEV(sc->sc_dev));
978 return (error);
979 }
980
981 #if defined(__NetBSD__) || defined(__OpenBSD__)
982 int
983 ugen_activate(device_ptr_t self, enum devact act)
984 {
985 struct ugen_softc *sc = (struct ugen_softc *)self;
986
987 switch (act) {
988 case DVACT_ACTIVATE:
989 return (EOPNOTSUPP);
990
991 case DVACT_DEACTIVATE:
992 sc->sc_dying = 1;
993 break;
994 }
995 return (0);
996 }
997 #endif
998
999 USB_DETACH(ugen)
1000 {
1001 USB_DETACH_START(ugen, sc);
1002 struct ugen_endpoint *sce;
1003 int i, dir;
1004 int s;
1005 #if defined(__NetBSD__) || defined(__OpenBSD__)
1006 int maj, mn;
1007
1008 DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags));
1009 #elif defined(__FreeBSD__)
1010 DPRINTF(("ugen_detach: sc=%p\n", sc));
1011 #endif
1012
1013 sc->sc_dying = 1;
1014 pmf_device_deregister(self);
1015 /* Abort all pipes. Causes processes waiting for transfer to wake. */
1016 for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
1017 for (dir = OUT; dir <= IN; dir++) {
1018 sce = &sc->sc_endpoints[i][dir];
1019 if (sce && sce->pipeh)
1020 usbd_abort_pipe(sce->pipeh);
1021 }
1022 }
1023
1024 s = splusb();
1025 if (--sc->sc_refcnt >= 0) {
1026 /* Wake everyone */
1027 for (i = 0; i < USB_MAX_ENDPOINTS; i++)
1028 wakeup(&sc->sc_endpoints[i][IN]);
1029 /* Wait for processes to go away. */
1030 usb_detach_wait(USBDEV(sc->sc_dev));
1031 }
1032 splx(s);
1033
1034 #if defined(__NetBSD__) || defined(__OpenBSD__)
1035 /* locate the major number */
1036 #if defined(__NetBSD__)
1037 maj = cdevsw_lookup_major(&ugen_cdevsw);
1038 #elif defined(__OpenBSD__)
1039 for (maj = 0; maj < nchrdev; maj++)
1040 if (cdevsw[maj].d_open == ugenopen)
1041 break;
1042 #endif
1043
1044 /* Nuke the vnodes for any open instances (calls close). */
1045 mn = device_unit(self) * USB_MAX_ENDPOINTS;
1046 vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR);
1047 #elif defined(__FreeBSD__)
1048 /* XXX not implemented yet */
1049 #endif
1050
1051 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
1052 USBDEV(sc->sc_dev));
1053
1054 return (0);
1055 }
1056
1057 Static void
1058 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
1059 {
1060 struct ugen_endpoint *sce = addr;
1061 /*struct ugen_softc *sc = sce->sc;*/
1062 u_int32_t count;
1063 u_char *ibuf;
1064
1065 if (status == USBD_CANCELLED)
1066 return;
1067
1068 if (status != USBD_NORMAL_COMPLETION) {
1069 DPRINTF(("ugenintr: status=%d\n", status));
1070 if (status == USBD_STALLED)
1071 usbd_clear_endpoint_stall_async(sce->pipeh);
1072 return;
1073 }
1074
1075 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1076 ibuf = sce->ibuf;
1077
1078 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
1079 xfer, status, count));
1080 DPRINTFN(5, (" data = %02x %02x %02x\n",
1081 ibuf[0], ibuf[1], ibuf[2]));
1082
1083 (void)b_to_q(ibuf, count, &sce->q);
1084
1085 if (sce->state & UGEN_ASLP) {
1086 sce->state &= ~UGEN_ASLP;
1087 DPRINTFN(5, ("ugen_intr: waking %p\n", sce));
1088 wakeup(sce);
1089 }
1090 selnotify(&sce->rsel, 0);
1091 }
1092
1093 Static void
1094 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
1095 usbd_status status)
1096 {
1097 struct isoreq *req = addr;
1098 struct ugen_endpoint *sce = req->sce;
1099 u_int32_t count, n;
1100 int i, isize;
1101
1102 /* Return if we are aborting. */
1103 if (status == USBD_CANCELLED)
1104 return;
1105
1106 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1107 DPRINTFN(5,("ugen_isoc_rintr: xfer %ld, count=%d\n",
1108 (long)(req - sce->isoreqs), count));
1109
1110 /* throw away oldest input if the buffer is full */
1111 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) {
1112 sce->cur += count;
1113 if(sce->cur >= sce->limit)
1114 sce->cur = sce->ibuf + (sce->limit - sce->cur);
1115 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n",
1116 count));
1117 }
1118
1119 isize = UGETW(sce->edesc->wMaxPacketSize);
1120 for (i = 0; i < UGEN_NISORFRMS; i++) {
1121 u_int32_t actlen = req->sizes[i];
1122 char const *tbuf = (char const *)req->dmabuf + isize * i;
1123
1124 /* copy data to buffer */
1125 while (actlen > 0) {
1126 n = min(actlen, sce->limit - sce->fill);
1127 memcpy(sce->fill, tbuf, n);
1128
1129 tbuf += n;
1130 actlen -= n;
1131 sce->fill += n;
1132 if(sce->fill == sce->limit)
1133 sce->fill = sce->ibuf;
1134 }
1135
1136 /* setup size for next transfer */
1137 req->sizes[i] = isize;
1138 }
1139
1140 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS,
1141 USBD_NO_COPY, ugen_isoc_rintr);
1142 (void)usbd_transfer(xfer);
1143
1144 if (sce->state & UGEN_ASLP) {
1145 sce->state &= ~UGEN_ASLP;
1146 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce));
1147 wakeup(sce);
1148 }
1149 selnotify(&sce->rsel, 0);
1150 }
1151
1152 #ifdef UGEN_BULK_RA_WB
1153 Static void
1154 ugen_bulkra_intr(usbd_xfer_handle xfer, usbd_private_handle addr,
1155 usbd_status status)
1156 {
1157 struct ugen_endpoint *sce = addr;
1158 u_int32_t count, n;
1159 char const *tbuf;
1160 usbd_status err;
1161
1162 /* Return if we are aborting. */
1163 if (status == USBD_CANCELLED)
1164 return;
1165
1166 if (status != USBD_NORMAL_COMPLETION) {
1167 DPRINTF(("ugen_bulkra_intr: status=%d\n", status));
1168 sce->state |= UGEN_RA_WB_STOP;
1169 if (status == USBD_STALLED)
1170 usbd_clear_endpoint_stall_async(sce->pipeh);
1171 return;
1172 }
1173
1174 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1175
1176 /* Keep track of how much is in the buffer. */
1177 sce->ra_wb_used += count;
1178
1179 /* Copy data to buffer. */
1180 tbuf = (char const *)usbd_get_buffer(sce->ra_wb_xfer);
1181 n = min(count, sce->limit - sce->fill);
1182 memcpy(sce->fill, tbuf, n);
1183 tbuf += n;
1184 count -= n;
1185 sce->fill += n;
1186 if (sce->fill == sce->limit)
1187 sce->fill = sce->ibuf;
1188 if (count > 0) {
1189 memcpy(sce->fill, tbuf, count);
1190 sce->fill += count;
1191 }
1192
1193 /* Set up the next request if necessary. */
1194 n = (sce->limit - sce->ibuf) - sce->ra_wb_used;
1195 if (n > 0) {
1196 usbd_setup_xfer(xfer, sce->pipeh, sce, NULL,
1197 min(n, sce->ra_wb_xferlen), USBD_NO_COPY,
1198 USBD_NO_TIMEOUT, ugen_bulkra_intr);
1199 err = usbd_transfer(xfer);
1200 if (err != USBD_IN_PROGRESS) {
1201 printf("usbd_bulkra_intr: error=%d\n", err);
1202 /*
1203 * The transfer has not been queued. Setting STOP
1204 * will make us try again at the next read.
1205 */
1206 sce->state |= UGEN_RA_WB_STOP;
1207 }
1208 }
1209 else
1210 sce->state |= UGEN_RA_WB_STOP;
1211
1212 if (sce->state & UGEN_ASLP) {
1213 sce->state &= ~UGEN_ASLP;
1214 DPRINTFN(5, ("ugen_bulkra_intr: waking %p\n", sce));
1215 wakeup(sce);
1216 }
1217 selnotify(&sce->rsel, 0);
1218 }
1219
1220 Static void
1221 ugen_bulkwb_intr(usbd_xfer_handle xfer, usbd_private_handle addr,
1222 usbd_status status)
1223 {
1224 struct ugen_endpoint *sce = addr;
1225 u_int32_t count, n;
1226 char *tbuf;
1227 usbd_status err;
1228
1229 /* Return if we are aborting. */
1230 if (status == USBD_CANCELLED)
1231 return;
1232
1233 if (status != USBD_NORMAL_COMPLETION) {
1234 DPRINTF(("ugen_bulkwb_intr: status=%d\n", status));
1235 sce->state |= UGEN_RA_WB_STOP;
1236 if (status == USBD_STALLED)
1237 usbd_clear_endpoint_stall_async(sce->pipeh);
1238 return;
1239 }
1240
1241 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1242
1243 /* Keep track of how much is in the buffer. */
1244 sce->ra_wb_used -= count;
1245
1246 /* Update buffer pointers. */
1247 sce->cur += count;
1248 if (sce->cur >= sce->limit)
1249 sce->cur = sce->ibuf + (sce->cur - sce->limit);
1250
1251 /* Set up next request if necessary. */
1252 if (sce->ra_wb_used > 0) {
1253 /* copy data from buffer */
1254 tbuf = (char *)usbd_get_buffer(sce->ra_wb_xfer);
1255 count = min(sce->ra_wb_used, sce->ra_wb_xferlen);
1256 n = min(count, sce->limit - sce->cur);
1257 memcpy(tbuf, sce->cur, n);
1258 tbuf += n;
1259 if (count - n > 0)
1260 memcpy(tbuf, sce->ibuf, count - n);
1261
1262 usbd_setup_xfer(xfer, sce->pipeh, sce, NULL,
1263 count, USBD_NO_COPY, USBD_NO_TIMEOUT, ugen_bulkwb_intr);
1264 err = usbd_transfer(xfer);
1265 if (err != USBD_IN_PROGRESS) {
1266 printf("usbd_bulkwb_intr: error=%d\n", err);
1267 /*
1268 * The transfer has not been queued. Setting STOP
1269 * will make us try again at the next write.
1270 */
1271 sce->state |= UGEN_RA_WB_STOP;
1272 }
1273 }
1274 else
1275 sce->state |= UGEN_RA_WB_STOP;
1276
1277 if (sce->state & UGEN_ASLP) {
1278 sce->state &= ~UGEN_ASLP;
1279 DPRINTFN(5, ("ugen_bulkwb_intr: waking %p\n", sce));
1280 wakeup(sce);
1281 }
1282 selnotify(&sce->rsel, 0);
1283 }
1284 #endif
1285
1286 Static usbd_status
1287 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno)
1288 {
1289 usbd_interface_handle iface;
1290 usb_endpoint_descriptor_t *ed;
1291 usbd_status err;
1292 struct ugen_endpoint *sce;
1293 u_int8_t niface, nendpt, endptno, endpt;
1294 int dir;
1295
1296 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
1297
1298 err = usbd_interface_count(sc->sc_udev, &niface);
1299 if (err)
1300 return (err);
1301 if (ifaceidx < 0 || ifaceidx >= niface)
1302 return (USBD_INVAL);
1303
1304 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
1305 if (err)
1306 return (err);
1307 err = usbd_endpoint_count(iface, &nendpt);
1308 if (err)
1309 return (err);
1310 /* XXX should only do this after setting new altno has succeeded */
1311 for (endptno = 0; endptno < nendpt; endptno++) {
1312 ed = usbd_interface2endpoint_descriptor(iface,endptno);
1313 endpt = ed->bEndpointAddress;
1314 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
1315 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
1316 sce->sc = 0;
1317 sce->edesc = 0;
1318 sce->iface = 0;
1319 }
1320
1321 /* change setting */
1322 err = usbd_set_interface(iface, altno);
1323 if (err)
1324 return (err);
1325
1326 err = usbd_endpoint_count(iface, &nendpt);
1327 if (err)
1328 return (err);
1329 for (endptno = 0; endptno < nendpt; endptno++) {
1330 ed = usbd_interface2endpoint_descriptor(iface,endptno);
1331 KASSERT(ed != NULL);
1332 endpt = ed->bEndpointAddress;
1333 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
1334 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
1335 sce->sc = sc;
1336 sce->edesc = ed;
1337 sce->iface = iface;
1338 }
1339 return (0);
1340 }
1341
1342 /* Retrieve a complete descriptor for a certain device and index. */
1343 Static usb_config_descriptor_t *
1344 ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp)
1345 {
1346 usb_config_descriptor_t *cdesc, *tdesc, cdescr;
1347 int len;
1348 usbd_status err;
1349
1350 if (index == USB_CURRENT_CONFIG_INDEX) {
1351 tdesc = usbd_get_config_descriptor(sc->sc_udev);
1352 len = UGETW(tdesc->wTotalLength);
1353 if (lenp)
1354 *lenp = len;
1355 cdesc = malloc(len, M_TEMP, M_WAITOK);
1356 memcpy(cdesc, tdesc, len);
1357 DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
1358 } else {
1359 err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
1360 if (err)
1361 return (0);
1362 len = UGETW(cdescr.wTotalLength);
1363 DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
1364 if (lenp)
1365 *lenp = len;
1366 cdesc = malloc(len, M_TEMP, M_WAITOK);
1367 err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
1368 if (err) {
1369 free(cdesc, M_TEMP);
1370 return (0);
1371 }
1372 }
1373 return (cdesc);
1374 }
1375
1376 Static int
1377 ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx)
1378 {
1379 usbd_interface_handle iface;
1380 usbd_status err;
1381
1382 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
1383 if (err)
1384 return (-1);
1385 return (usbd_get_interface_altindex(iface));
1386 }
1387
1388 Static int
1389 ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
1390 void *addr, int flag, struct lwp *l)
1391 {
1392 struct ugen_endpoint *sce;
1393 usbd_status err;
1394 usbd_interface_handle iface;
1395 struct usb_config_desc *cd;
1396 usb_config_descriptor_t *cdesc;
1397 struct usb_interface_desc *id;
1398 usb_interface_descriptor_t *idesc;
1399 struct usb_endpoint_desc *ed;
1400 usb_endpoint_descriptor_t *edesc;
1401 struct usb_alt_interface *ai;
1402 struct usb_string_desc *si;
1403 u_int8_t conf, alt;
1404
1405 DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd));
1406 if (sc->sc_dying)
1407 return (EIO);
1408
1409 switch (cmd) {
1410 case FIONBIO:
1411 /* All handled in the upper FS layer. */
1412 return (0);
1413 case USB_SET_SHORT_XFER:
1414 if (endpt == USB_CONTROL_ENDPOINT)
1415 return (EINVAL);
1416 /* This flag only affects read */
1417 sce = &sc->sc_endpoints[endpt][IN];
1418 if (sce == NULL || sce->pipeh == NULL)
1419 return (EINVAL);
1420 if (*(int *)addr)
1421 sce->state |= UGEN_SHORT_OK;
1422 else
1423 sce->state &= ~UGEN_SHORT_OK;
1424 return (0);
1425 case USB_SET_TIMEOUT:
1426 sce = &sc->sc_endpoints[endpt][IN];
1427 if (sce == NULL
1428 /* XXX this shouldn't happen, but the distinction between
1429 input and output pipes isn't clear enough.
1430 || sce->pipeh == NULL */
1431 )
1432 return (EINVAL);
1433 sce->timeout = *(int *)addr;
1434 return (0);
1435 case USB_SET_BULK_RA:
1436 #ifdef UGEN_BULK_RA_WB
1437 if (endpt == USB_CONTROL_ENDPOINT)
1438 return (EINVAL);
1439 sce = &sc->sc_endpoints[endpt][IN];
1440 if (sce == NULL || sce->pipeh == NULL)
1441 return (EINVAL);
1442 edesc = sce->edesc;
1443 if ((edesc->bmAttributes & UE_XFERTYPE) != UE_BULK)
1444 return (EINVAL);
1445
1446 if (*(int *)addr) {
1447 /* Only turn RA on if it's currently off. */
1448 if (sce->state & UGEN_BULK_RA)
1449 return (0);
1450
1451 if (sce->ra_wb_bufsize == 0 || sce->ra_wb_reqsize == 0)
1452 /* shouldn't happen */
1453 return (EINVAL);
1454 sce->ra_wb_xfer = usbd_alloc_xfer(sc->sc_udev);
1455 if (sce->ra_wb_xfer == NULL)
1456 return (ENOMEM);
1457 sce->ra_wb_xferlen = sce->ra_wb_reqsize;
1458 /*
1459 * Set up a dmabuf because we reuse the xfer with
1460 * the same (max) request length like isoc.
1461 */
1462 if (usbd_alloc_buffer(sce->ra_wb_xfer,
1463 sce->ra_wb_xferlen) == 0) {
1464 usbd_free_xfer(sce->ra_wb_xfer);
1465 return (ENOMEM);
1466 }
1467 sce->ibuf = malloc(sce->ra_wb_bufsize,
1468 M_USBDEV, M_WAITOK);
1469 sce->fill = sce->cur = sce->ibuf;
1470 sce->limit = sce->ibuf + sce->ra_wb_bufsize;
1471 sce->ra_wb_used = 0;
1472 sce->state |= UGEN_BULK_RA;
1473 sce->state &= ~UGEN_RA_WB_STOP;
1474 /* Now start reading. */
1475 usbd_setup_xfer(sce->ra_wb_xfer, sce->pipeh, sce,
1476 NULL,
1477 min(sce->ra_wb_xferlen, sce->ra_wb_bufsize),
1478 USBD_NO_COPY, USBD_NO_TIMEOUT,
1479 ugen_bulkra_intr);
1480 err = usbd_transfer(sce->ra_wb_xfer);
1481 if (err != USBD_IN_PROGRESS) {
1482 sce->state &= ~UGEN_BULK_RA;
1483 free(sce->ibuf, M_USBDEV);
1484 sce->ibuf = NULL;
1485 usbd_free_xfer(sce->ra_wb_xfer);
1486 return (EIO);
1487 }
1488 } else {
1489 /* Only turn RA off if it's currently on. */
1490 if (!(sce->state & UGEN_BULK_RA))
1491 return (0);
1492
1493 sce->state &= ~UGEN_BULK_RA;
1494 usbd_abort_pipe(sce->pipeh);
1495 usbd_free_xfer(sce->ra_wb_xfer);
1496 /*
1497 * XXX Discard whatever's in the buffer, but we
1498 * should keep it around and drain the buffer
1499 * instead.
1500 */
1501 free(sce->ibuf, M_USBDEV);
1502 sce->ibuf = NULL;
1503 }
1504 return (0);
1505 #else
1506 return (EOPNOTSUPP);
1507 #endif
1508 case USB_SET_BULK_WB:
1509 #ifdef UGEN_BULK_RA_WB
1510 if (endpt == USB_CONTROL_ENDPOINT)
1511 return (EINVAL);
1512 sce = &sc->sc_endpoints[endpt][OUT];
1513 if (sce == NULL || sce->pipeh == NULL)
1514 return (EINVAL);
1515 edesc = sce->edesc;
1516 if ((edesc->bmAttributes & UE_XFERTYPE) != UE_BULK)
1517 return (EINVAL);
1518
1519 if (*(int *)addr) {
1520 /* Only turn WB on if it's currently off. */
1521 if (sce->state & UGEN_BULK_WB)
1522 return (0);
1523
1524 if (sce->ra_wb_bufsize == 0 || sce->ra_wb_reqsize == 0)
1525 /* shouldn't happen */
1526 return (EINVAL);
1527 sce->ra_wb_xfer = usbd_alloc_xfer(sc->sc_udev);
1528 if (sce->ra_wb_xfer == NULL)
1529 return (ENOMEM);
1530 sce->ra_wb_xferlen = sce->ra_wb_reqsize;
1531 /*
1532 * Set up a dmabuf because we reuse the xfer with
1533 * the same (max) request length like isoc.
1534 */
1535 if (usbd_alloc_buffer(sce->ra_wb_xfer,
1536 sce->ra_wb_xferlen) == 0) {
1537 usbd_free_xfer(sce->ra_wb_xfer);
1538 return (ENOMEM);
1539 }
1540 sce->ibuf = malloc(sce->ra_wb_bufsize,
1541 M_USBDEV, M_WAITOK);
1542 sce->fill = sce->cur = sce->ibuf;
1543 sce->limit = sce->ibuf + sce->ra_wb_bufsize;
1544 sce->ra_wb_used = 0;
1545 sce->state |= UGEN_BULK_WB | UGEN_RA_WB_STOP;
1546 } else {
1547 /* Only turn WB off if it's currently on. */
1548 if (!(sce->state & UGEN_BULK_WB))
1549 return (0);
1550
1551 sce->state &= ~UGEN_BULK_WB;
1552 /*
1553 * XXX Discard whatever's in the buffer, but we
1554 * should keep it around and keep writing to
1555 * drain the buffer instead.
1556 */
1557 usbd_abort_pipe(sce->pipeh);
1558 usbd_free_xfer(sce->ra_wb_xfer);
1559 free(sce->ibuf, M_USBDEV);
1560 sce->ibuf = NULL;
1561 }
1562 return (0);
1563 #else
1564 return (EOPNOTSUPP);
1565 #endif
1566 case USB_SET_BULK_RA_OPT:
1567 case USB_SET_BULK_WB_OPT:
1568 #ifdef UGEN_BULK_RA_WB
1569 {
1570 struct usb_bulk_ra_wb_opt *opt;
1571
1572 if (endpt == USB_CONTROL_ENDPOINT)
1573 return (EINVAL);
1574 opt = (struct usb_bulk_ra_wb_opt *)addr;
1575 if (cmd == USB_SET_BULK_RA_OPT)
1576 sce = &sc->sc_endpoints[endpt][IN];
1577 else
1578 sce = &sc->sc_endpoints[endpt][OUT];
1579 if (sce == NULL || sce->pipeh == NULL)
1580 return (EINVAL);
1581 if (opt->ra_wb_buffer_size < 1 ||
1582 opt->ra_wb_buffer_size > UGEN_BULK_RA_WB_BUFMAX ||
1583 opt->ra_wb_request_size < 1 ||
1584 opt->ra_wb_request_size > opt->ra_wb_buffer_size)
1585 return (EINVAL);
1586 /*
1587 * XXX These changes do not take effect until the
1588 * next time RA/WB mode is enabled but they ought to
1589 * take effect immediately.
1590 */
1591 sce->ra_wb_bufsize = opt->ra_wb_buffer_size;
1592 sce->ra_wb_reqsize = opt->ra_wb_request_size;
1593 return (0);
1594 }
1595 #else
1596 return (EOPNOTSUPP);
1597 #endif
1598 default:
1599 break;
1600 }
1601
1602 if (endpt != USB_CONTROL_ENDPOINT)
1603 return (EINVAL);
1604
1605 switch (cmd) {
1606 #ifdef UGEN_DEBUG
1607 case USB_SETDEBUG:
1608 ugendebug = *(int *)addr;
1609 break;
1610 #endif
1611 case USB_GET_CONFIG:
1612 err = usbd_get_config(sc->sc_udev, &conf);
1613 if (err)
1614 return (EIO);
1615 *(int *)addr = conf;
1616 break;
1617 case USB_SET_CONFIG:
1618 if (!(flag & FWRITE))
1619 return (EPERM);
1620 err = ugen_set_config(sc, *(int *)addr);
1621 switch (err) {
1622 case USBD_NORMAL_COMPLETION:
1623 break;
1624 case USBD_IN_USE:
1625 return (EBUSY);
1626 default:
1627 return (EIO);
1628 }
1629 break;
1630 case USB_GET_ALTINTERFACE:
1631 ai = (struct usb_alt_interface *)addr;
1632 err = usbd_device2interface_handle(sc->sc_udev,
1633 ai->uai_interface_index, &iface);
1634 if (err)
1635 return (EINVAL);
1636 idesc = usbd_get_interface_descriptor(iface);
1637 if (idesc == NULL)
1638 return (EIO);
1639 ai->uai_alt_no = idesc->bAlternateSetting;
1640 break;
1641 case USB_SET_ALTINTERFACE:
1642 if (!(flag & FWRITE))
1643 return (EPERM);
1644 ai = (struct usb_alt_interface *)addr;
1645 err = usbd_device2interface_handle(sc->sc_udev,
1646 ai->uai_interface_index, &iface);
1647 if (err)
1648 return (EINVAL);
1649 err = ugen_set_interface(sc, ai->uai_interface_index,
1650 ai->uai_alt_no);
1651 if (err)
1652 return (EINVAL);
1653 break;
1654 case USB_GET_NO_ALT:
1655 ai = (struct usb_alt_interface *)addr;
1656 cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0);
1657 if (cdesc == NULL)
1658 return (EINVAL);
1659 idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0);
1660 if (idesc == NULL) {
1661 free(cdesc, M_TEMP);
1662 return (EINVAL);
1663 }
1664 ai->uai_alt_no = usbd_get_no_alts(cdesc,
1665 idesc->bInterfaceNumber);
1666 free(cdesc, M_TEMP);
1667 break;
1668 case USB_GET_DEVICE_DESC:
1669 *(usb_device_descriptor_t *)addr =
1670 *usbd_get_device_descriptor(sc->sc_udev);
1671 break;
1672 case USB_GET_CONFIG_DESC:
1673 cd = (struct usb_config_desc *)addr;
1674 cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0);
1675 if (cdesc == NULL)
1676 return (EINVAL);
1677 cd->ucd_desc = *cdesc;
1678 free(cdesc, M_TEMP);
1679 break;
1680 case USB_GET_INTERFACE_DESC:
1681 id = (struct usb_interface_desc *)addr;
1682 cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0);
1683 if (cdesc == NULL)
1684 return (EINVAL);
1685 if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX &&
1686 id->uid_alt_index == USB_CURRENT_ALT_INDEX)
1687 alt = ugen_get_alt_index(sc, id->uid_interface_index);
1688 else
1689 alt = id->uid_alt_index;
1690 idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt);
1691 if (idesc == NULL) {
1692 free(cdesc, M_TEMP);
1693 return (EINVAL);
1694 }
1695 id->uid_desc = *idesc;
1696 free(cdesc, M_TEMP);
1697 break;
1698 case USB_GET_ENDPOINT_DESC:
1699 ed = (struct usb_endpoint_desc *)addr;
1700 cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0);
1701 if (cdesc == NULL)
1702 return (EINVAL);
1703 if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX &&
1704 ed->ued_alt_index == USB_CURRENT_ALT_INDEX)
1705 alt = ugen_get_alt_index(sc, ed->ued_interface_index);
1706 else
1707 alt = ed->ued_alt_index;
1708 edesc = usbd_find_edesc(cdesc, ed->ued_interface_index,
1709 alt, ed->ued_endpoint_index);
1710 if (edesc == NULL) {
1711 free(cdesc, M_TEMP);
1712 return (EINVAL);
1713 }
1714 ed->ued_desc = *edesc;
1715 free(cdesc, M_TEMP);
1716 break;
1717 case USB_GET_FULL_DESC:
1718 {
1719 int len;
1720 struct iovec iov;
1721 struct uio uio;
1722 struct usb_full_desc *fd = (struct usb_full_desc *)addr;
1723 int error;
1724
1725 cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len);
1726 if (len > fd->ufd_size)
1727 len = fd->ufd_size;
1728 iov.iov_base = (void *)fd->ufd_data;
1729 iov.iov_len = len;
1730 uio.uio_iov = &iov;
1731 uio.uio_iovcnt = 1;
1732 uio.uio_resid = len;
1733 uio.uio_offset = 0;
1734 uio.uio_rw = UIO_READ;
1735 uio.uio_vmspace = l->l_proc->p_vmspace;
1736 error = uiomove((void *)cdesc, len, &uio);
1737 free(cdesc, M_TEMP);
1738 return (error);
1739 }
1740 case USB_GET_STRING_DESC: {
1741 int len;
1742 si = (struct usb_string_desc *)addr;
1743 err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
1744 si->usd_language_id, &si->usd_desc, &len);
1745 if (err)
1746 return (EINVAL);
1747 break;
1748 }
1749 case USB_DO_REQUEST:
1750 {
1751 struct usb_ctl_request *ur = (void *)addr;
1752 int len = UGETW(ur->ucr_request.wLength);
1753 struct iovec iov;
1754 struct uio uio;
1755 void *ptr = 0;
1756 usbd_status xerr;
1757 int error = 0;
1758
1759 if (!(flag & FWRITE))
1760 return (EPERM);
1761 /* Avoid requests that would damage the bus integrity. */
1762 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1763 ur->ucr_request.bRequest == UR_SET_ADDRESS) ||
1764 (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1765 ur->ucr_request.bRequest == UR_SET_CONFIG) ||
1766 (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE &&
1767 ur->ucr_request.bRequest == UR_SET_INTERFACE))
1768 return (EINVAL);
1769
1770 if (len < 0 || len > 32767)
1771 return (EINVAL);
1772 if (len != 0) {
1773 iov.iov_base = (void *)ur->ucr_data;
1774 iov.iov_len = len;
1775 uio.uio_iov = &iov;
1776 uio.uio_iovcnt = 1;
1777 uio.uio_resid = len;
1778 uio.uio_offset = 0;
1779 uio.uio_rw =
1780 ur->ucr_request.bmRequestType & UT_READ ?
1781 UIO_READ : UIO_WRITE;
1782 uio.uio_vmspace = l->l_proc->p_vmspace;
1783 ptr = malloc(len, M_TEMP, M_WAITOK);
1784 if (uio.uio_rw == UIO_WRITE) {
1785 error = uiomove(ptr, len, &uio);
1786 if (error)
1787 goto ret;
1788 }
1789 }
1790 sce = &sc->sc_endpoints[endpt][IN];
1791 xerr = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request,
1792 ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout);
1793 if (xerr) {
1794 error = EIO;
1795 goto ret;
1796 }
1797 if (len != 0) {
1798 if (uio.uio_rw == UIO_READ) {
1799 error = uiomove(ptr, len, &uio);
1800 if (error)
1801 goto ret;
1802 }
1803 }
1804 ret:
1805 if (ptr)
1806 free(ptr, M_TEMP);
1807 return (error);
1808 }
1809 case USB_GET_DEVICEINFO:
1810 usbd_fill_deviceinfo(sc->sc_udev,
1811 (struct usb_device_info *)addr, 0);
1812 break;
1813 #ifdef COMPAT_30
1814 case USB_GET_DEVICEINFO_OLD:
1815 usbd_fill_deviceinfo_old(sc->sc_udev,
1816 (struct usb_device_info_old *)addr, 0);
1817
1818 break;
1819 #endif
1820 default:
1821 return (EINVAL);
1822 }
1823 return (0);
1824 }
1825
1826 int
1827 ugenioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
1828 {
1829 int endpt = UGENENDPOINT(dev);
1830 struct ugen_softc *sc;
1831 int error;
1832
1833 USB_GET_SC(ugen, UGENUNIT(dev), sc);
1834
1835 sc->sc_refcnt++;
1836 error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, l);
1837 if (--sc->sc_refcnt < 0)
1838 usb_detach_wakeup(USBDEV(sc->sc_dev));
1839 return (error);
1840 }
1841
1842 int
1843 ugenpoll(dev_t dev, int events, struct lwp *l)
1844 {
1845 struct ugen_softc *sc;
1846 struct ugen_endpoint *sce_in, *sce_out;
1847 int revents = 0;
1848 int s;
1849
1850 USB_GET_SC(ugen, UGENUNIT(dev), sc);
1851
1852 if (sc->sc_dying)
1853 return (POLLHUP);
1854
1855 sce_in = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1856 sce_out = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT];
1857 if (sce_in == NULL && sce_out == NULL)
1858 return (POLLERR);
1859 #ifdef DIAGNOSTIC
1860 if (!sce_in->edesc && !sce_out->edesc) {
1861 printf("ugenpoll: no edesc\n");
1862 return (POLLERR);
1863 }
1864 /* It's possible to have only one pipe open. */
1865 if (!sce_in->pipeh && !sce_out->pipeh) {
1866 printf("ugenpoll: no pipe\n");
1867 return (POLLERR);
1868 }
1869 #endif
1870 s = splusb();
1871 if (sce_in && sce_in->pipeh && (events & (POLLIN | POLLRDNORM)))
1872 switch (sce_in->edesc->bmAttributes & UE_XFERTYPE) {
1873 case UE_INTERRUPT:
1874 if (sce_in->q.c_cc > 0)
1875 revents |= events & (POLLIN | POLLRDNORM);
1876 else
1877 selrecord(l, &sce_in->rsel);
1878 break;
1879 case UE_ISOCHRONOUS:
1880 if (sce_in->cur != sce_in->fill)
1881 revents |= events & (POLLIN | POLLRDNORM);
1882 else
1883 selrecord(l, &sce_in->rsel);
1884 break;
1885 case UE_BULK:
1886 #ifdef UGEN_BULK_RA_WB
1887 if (sce_in->state & UGEN_BULK_RA) {
1888 if (sce_in->ra_wb_used > 0)
1889 revents |= events &
1890 (POLLIN | POLLRDNORM);
1891 else
1892 selrecord(l, &sce_in->rsel);
1893 break;
1894 }
1895 #endif
1896 /*
1897 * We have no easy way of determining if a read will
1898 * yield any data or a write will happen.
1899 * Pretend they will.
1900 */
1901 revents |= events & (POLLIN | POLLRDNORM);
1902 break;
1903 default:
1904 break;
1905 }
1906 if (sce_out && sce_out->pipeh && (events & (POLLOUT | POLLWRNORM)))
1907 switch (sce_out->edesc->bmAttributes & UE_XFERTYPE) {
1908 case UE_INTERRUPT:
1909 case UE_ISOCHRONOUS:
1910 /* XXX unimplemented */
1911 break;
1912 case UE_BULK:
1913 #ifdef UGEN_BULK_RA_WB
1914 if (sce_out->state & UGEN_BULK_WB) {
1915 if (sce_out->ra_wb_used <
1916 sce_out->limit - sce_out->ibuf)
1917 revents |= events &
1918 (POLLOUT | POLLWRNORM);
1919 else
1920 selrecord(l, &sce_out->rsel);
1921 break;
1922 }
1923 #endif
1924 /*
1925 * We have no easy way of determining if a read will
1926 * yield any data or a write will happen.
1927 * Pretend they will.
1928 */
1929 revents |= events & (POLLOUT | POLLWRNORM);
1930 break;
1931 default:
1932 break;
1933 }
1934
1935
1936 splx(s);
1937 return (revents);
1938 }
1939
1940 static void
1941 filt_ugenrdetach(struct knote *kn)
1942 {
1943 struct ugen_endpoint *sce = kn->kn_hook;
1944 int s;
1945
1946 s = splusb();
1947 SLIST_REMOVE(&sce->rsel.sel_klist, kn, knote, kn_selnext);
1948 splx(s);
1949 }
1950
1951 static int
1952 filt_ugenread_intr(struct knote *kn, long hint)
1953 {
1954 struct ugen_endpoint *sce = kn->kn_hook;
1955
1956 kn->kn_data = sce->q.c_cc;
1957 return (kn->kn_data > 0);
1958 }
1959
1960 static int
1961 filt_ugenread_isoc(struct knote *kn, long hint)
1962 {
1963 struct ugen_endpoint *sce = kn->kn_hook;
1964
1965 if (sce->cur == sce->fill)
1966 return (0);
1967
1968 if (sce->cur < sce->fill)
1969 kn->kn_data = sce->fill - sce->cur;
1970 else
1971 kn->kn_data = (sce->limit - sce->cur) +
1972 (sce->fill - sce->ibuf);
1973
1974 return (1);
1975 }
1976
1977 #ifdef UGEN_BULK_RA_WB
1978 static int
1979 filt_ugenread_bulk(struct knote *kn, long hint)
1980 {
1981 struct ugen_endpoint *sce = kn->kn_hook;
1982
1983 if (!(sce->state & UGEN_BULK_RA))
1984 /*
1985 * We have no easy way of determining if a read will
1986 * yield any data or a write will happen.
1987 * So, emulate "seltrue".
1988 */
1989 return (filt_seltrue(kn, hint));
1990
1991 if (sce->ra_wb_used == 0)
1992 return (0);
1993
1994 kn->kn_data = sce->ra_wb_used;
1995
1996 return (1);
1997 }
1998
1999 static int
2000 filt_ugenwrite_bulk(struct knote *kn, long hint)
2001 {
2002 struct ugen_endpoint *sce = kn->kn_hook;
2003
2004 if (!(sce->state & UGEN_BULK_WB))
2005 /*
2006 * We have no easy way of determining if a read will
2007 * yield any data or a write will happen.
2008 * So, emulate "seltrue".
2009 */
2010 return (filt_seltrue(kn, hint));
2011
2012 if (sce->ra_wb_used == sce->limit - sce->ibuf)
2013 return (0);
2014
2015 kn->kn_data = (sce->limit - sce->ibuf) - sce->ra_wb_used;
2016
2017 return (1);
2018 }
2019 #endif
2020
2021 static const struct filterops ugenread_intr_filtops =
2022 { 1, NULL, filt_ugenrdetach, filt_ugenread_intr };
2023
2024 static const struct filterops ugenread_isoc_filtops =
2025 { 1, NULL, filt_ugenrdetach, filt_ugenread_isoc };
2026
2027 #ifdef UGEN_BULK_RA_WB
2028 static const struct filterops ugenread_bulk_filtops =
2029 { 1, NULL, filt_ugenrdetach, filt_ugenread_bulk };
2030
2031 static const struct filterops ugenwrite_bulk_filtops =
2032 { 1, NULL, filt_ugenrdetach, filt_ugenwrite_bulk };
2033 #else
2034 static const struct filterops ugen_seltrue_filtops =
2035 { 1, NULL, filt_ugenrdetach, filt_seltrue };
2036 #endif
2037
2038 int
2039 ugenkqfilter(dev_t dev, struct knote *kn)
2040 {
2041 struct ugen_softc *sc;
2042 struct ugen_endpoint *sce;
2043 struct klist *klist;
2044 int s;
2045
2046 USB_GET_SC(ugen, UGENUNIT(dev), sc);
2047
2048 if (sc->sc_dying)
2049 return (ENXIO);
2050
2051 switch (kn->kn_filter) {
2052 case EVFILT_READ:
2053 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
2054 if (sce == NULL)
2055 return (EINVAL);
2056
2057 klist = &sce->rsel.sel_klist;
2058 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
2059 case UE_INTERRUPT:
2060 kn->kn_fop = &ugenread_intr_filtops;
2061 break;
2062 case UE_ISOCHRONOUS:
2063 kn->kn_fop = &ugenread_isoc_filtops;
2064 break;
2065 case UE_BULK:
2066 #ifdef UGEN_BULK_RA_WB
2067 kn->kn_fop = &ugenread_bulk_filtops;
2068 break;
2069 #else
2070 /*
2071 * We have no easy way of determining if a read will
2072 * yield any data or a write will happen.
2073 * So, emulate "seltrue".
2074 */
2075 kn->kn_fop = &ugen_seltrue_filtops;
2076 #endif
2077 break;
2078 default:
2079 return (EINVAL);
2080 }
2081 break;
2082
2083 case EVFILT_WRITE:
2084 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT];
2085 if (sce == NULL)
2086 return (EINVAL);
2087
2088 klist = &sce->rsel.sel_klist;
2089 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
2090 case UE_INTERRUPT:
2091 case UE_ISOCHRONOUS:
2092 /* XXX poll doesn't support this */
2093 return (EINVAL);
2094
2095 case UE_BULK:
2096 #ifdef UGEN_BULK_RA_WB
2097 kn->kn_fop = &ugenwrite_bulk_filtops;
2098 #else
2099 /*
2100 * We have no easy way of determining if a read will
2101 * yield any data or a write will happen.
2102 * So, emulate "seltrue".
2103 */
2104 kn->kn_fop = &ugen_seltrue_filtops;
2105 #endif
2106 break;
2107 default:
2108 return (EINVAL);
2109 }
2110 break;
2111
2112 default:
2113 return (EINVAL);
2114 }
2115
2116 kn->kn_hook = sce;
2117
2118 s = splusb();
2119 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
2120 splx(s);
2121
2122 return (0);
2123 }
2124
2125 #if defined(__FreeBSD__)
2126 DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, usbd_driver_load, 0);
2127 #endif
2128