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