ugen.c revision 1.82 1 /* $NetBSD: ugen.c,v 1.82 2006/04/14 16:41:53 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.82 2006/04/14 16:41:53 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 KASSERT(ed != NULL);
298 endpt = ed->bEndpointAddress;
299 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
300 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
301 DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x"
302 "(%d,%d), sce=%p\n",
303 endptno, endpt, UE_GET_ADDR(endpt),
304 UE_GET_DIR(endpt), sce));
305 sce->sc = sc;
306 sce->edesc = ed;
307 sce->iface = iface;
308 }
309 }
310 return (USBD_NORMAL_COMPLETION);
311 }
312
313 int
314 ugenopen(dev_t dev, int flag, int mode, struct lwp *l)
315 {
316 struct ugen_softc *sc;
317 int unit = UGENUNIT(dev);
318 int endpt = UGENENDPOINT(dev);
319 usb_endpoint_descriptor_t *edesc;
320 struct ugen_endpoint *sce;
321 int dir, isize;
322 usbd_status err;
323 usbd_xfer_handle xfer;
324 void *tbuf;
325 int i, j;
326
327 USB_GET_SC_OPEN(ugen, unit, sc);
328
329 DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
330 flag, mode, unit, endpt));
331
332 if (sc == NULL || sc->sc_dying)
333 return (ENXIO);
334
335 /* The control endpoint allows multiple opens. */
336 if (endpt == USB_CONTROL_ENDPOINT) {
337 sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
338 return (0);
339 }
340
341 if (sc->sc_is_open[endpt])
342 return (EBUSY);
343
344 /* Make sure there are pipes for all directions. */
345 for (dir = OUT; dir <= IN; dir++) {
346 if (flag & (dir == OUT ? FWRITE : FREAD)) {
347 sce = &sc->sc_endpoints[endpt][dir];
348 if (sce == 0 || sce->edesc == 0)
349 return (ENXIO);
350 }
351 }
352
353 /* Actually open the pipes. */
354 /* XXX Should back out properly if it fails. */
355 for (dir = OUT; dir <= IN; dir++) {
356 if (!(flag & (dir == OUT ? FWRITE : FREAD)))
357 continue;
358 sce = &sc->sc_endpoints[endpt][dir];
359 sce->state = 0;
360 sce->timeout = USBD_NO_TIMEOUT;
361 DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
362 sc, endpt, dir, sce));
363 edesc = sce->edesc;
364 switch (edesc->bmAttributes & UE_XFERTYPE) {
365 case UE_INTERRUPT:
366 if (dir == OUT) {
367 err = usbd_open_pipe(sce->iface,
368 edesc->bEndpointAddress, 0, &sce->pipeh);
369 if (err)
370 return (EIO);
371 break;
372 }
373 isize = UGETW(edesc->wMaxPacketSize);
374 if (isize == 0) /* shouldn't happen */
375 return (EINVAL);
376 sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
377 DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
378 endpt, isize));
379 if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
380 return (ENOMEM);
381 err = usbd_open_pipe_intr(sce->iface,
382 edesc->bEndpointAddress,
383 USBD_SHORT_XFER_OK, &sce->pipeh, sce,
384 sce->ibuf, isize, ugenintr,
385 USBD_DEFAULT_INTERVAL);
386 if (err) {
387 free(sce->ibuf, M_USBDEV);
388 clfree(&sce->q);
389 return (EIO);
390 }
391 DPRINTFN(5, ("ugenopen: interrupt open done\n"));
392 break;
393 case UE_BULK:
394 err = usbd_open_pipe(sce->iface,
395 edesc->bEndpointAddress, 0, &sce->pipeh);
396 if (err)
397 return (EIO);
398 break;
399 case UE_ISOCHRONOUS:
400 if (dir == OUT)
401 return (EINVAL);
402 isize = UGETW(edesc->wMaxPacketSize);
403 if (isize == 0) /* shouldn't happen */
404 return (EINVAL);
405 sce->ibuf = malloc(isize * UGEN_NISOFRAMES,
406 M_USBDEV, M_WAITOK);
407 sce->cur = sce->fill = sce->ibuf;
408 sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES;
409 DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n",
410 endpt, isize));
411 err = usbd_open_pipe(sce->iface,
412 edesc->bEndpointAddress, 0, &sce->pipeh);
413 if (err) {
414 free(sce->ibuf, M_USBDEV);
415 return (EIO);
416 }
417 for(i = 0; i < UGEN_NISOREQS; ++i) {
418 sce->isoreqs[i].sce = sce;
419 xfer = usbd_alloc_xfer(sc->sc_udev);
420 if (xfer == 0)
421 goto bad;
422 sce->isoreqs[i].xfer = xfer;
423 tbuf = usbd_alloc_buffer
424 (xfer, isize * UGEN_NISORFRMS);
425 if (tbuf == 0) {
426 i++;
427 goto bad;
428 }
429 sce->isoreqs[i].dmabuf = tbuf;
430 for(j = 0; j < UGEN_NISORFRMS; ++j)
431 sce->isoreqs[i].sizes[j] = isize;
432 usbd_setup_isoc_xfer
433 (xfer, sce->pipeh, &sce->isoreqs[i],
434 sce->isoreqs[i].sizes,
435 UGEN_NISORFRMS, USBD_NO_COPY,
436 ugen_isoc_rintr);
437 (void)usbd_transfer(xfer);
438 }
439 DPRINTFN(5, ("ugenopen: isoc open done\n"));
440 break;
441 bad:
442 while (--i >= 0) /* implicit buffer free */
443 usbd_free_xfer(sce->isoreqs[i].xfer);
444 return (ENOMEM);
445 case UE_CONTROL:
446 sce->timeout = USBD_DEFAULT_TIMEOUT;
447 return (EINVAL);
448 }
449 }
450 sc->sc_is_open[endpt] = 1;
451 return (0);
452 }
453
454 int
455 ugenclose(dev_t dev, int flag, int mode, struct lwp *l)
456 {
457 int endpt = UGENENDPOINT(dev);
458 struct ugen_softc *sc;
459 struct ugen_endpoint *sce;
460 int dir;
461 int i;
462
463 USB_GET_SC(ugen, UGENUNIT(dev), sc);
464
465 DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
466 flag, mode, UGENUNIT(dev), endpt));
467
468 #ifdef DIAGNOSTIC
469 if (!sc->sc_is_open[endpt]) {
470 printf("ugenclose: not open\n");
471 return (EINVAL);
472 }
473 #endif
474
475 if (endpt == USB_CONTROL_ENDPOINT) {
476 DPRINTFN(5, ("ugenclose: close control\n"));
477 sc->sc_is_open[endpt] = 0;
478 return (0);
479 }
480
481 for (dir = OUT; dir <= IN; dir++) {
482 if (!(flag & (dir == OUT ? FWRITE : FREAD)))
483 continue;
484 sce = &sc->sc_endpoints[endpt][dir];
485 if (sce == NULL || sce->pipeh == NULL)
486 continue;
487 DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
488 endpt, dir, sce));
489
490 usbd_abort_pipe(sce->pipeh);
491 usbd_close_pipe(sce->pipeh);
492 sce->pipeh = NULL;
493
494 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
495 case UE_INTERRUPT:
496 ndflush(&sce->q, sce->q.c_cc);
497 clfree(&sce->q);
498 break;
499 case UE_ISOCHRONOUS:
500 for (i = 0; i < UGEN_NISOREQS; ++i)
501 usbd_free_xfer(sce->isoreqs[i].xfer);
502
503 default:
504 break;
505 }
506
507 if (sce->ibuf != NULL) {
508 free(sce->ibuf, M_USBDEV);
509 sce->ibuf = NULL;
510 clfree(&sce->q);
511 }
512 }
513 sc->sc_is_open[endpt] = 0;
514
515 return (0);
516 }
517
518 Static int
519 ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
520 {
521 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
522 u_int32_t n, tn;
523 char tbuf[UGEN_BBSIZE];
524 usbd_xfer_handle xfer;
525 usbd_status err;
526 int s;
527 int error = 0;
528 u_char buffer[UGEN_CHUNK];
529
530 DPRINTFN(5, ("%s: ugenread: %d\n", USBDEVNAME(sc->sc_dev), endpt));
531
532 if (sc->sc_dying)
533 return (EIO);
534
535 if (endpt == USB_CONTROL_ENDPOINT)
536 return (ENODEV);
537
538 #ifdef DIAGNOSTIC
539 if (sce->edesc == NULL) {
540 printf("ugenread: no edesc\n");
541 return (EIO);
542 }
543 if (sce->pipeh == NULL) {
544 printf("ugenread: no pipe\n");
545 return (EIO);
546 }
547 #endif
548
549 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
550 case UE_INTERRUPT:
551 /* Block until activity occurred. */
552 s = splusb();
553 while (sce->q.c_cc == 0) {
554 if (flag & IO_NDELAY) {
555 splx(s);
556 return (EWOULDBLOCK);
557 }
558 sce->state |= UGEN_ASLP;
559 DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
560 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0);
561 DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
562 if (sc->sc_dying)
563 error = EIO;
564 if (error) {
565 sce->state &= ~UGEN_ASLP;
566 break;
567 }
568 }
569 splx(s);
570
571 /* Transfer as many chunks as possible. */
572 while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) {
573 n = min(sce->q.c_cc, uio->uio_resid);
574 if (n > sizeof(buffer))
575 n = sizeof(buffer);
576
577 /* Remove a small chunk from the input queue. */
578 q_to_b(&sce->q, buffer, n);
579 DPRINTFN(5, ("ugenread: got %d chars\n", n));
580
581 /* Copy the data to the user process. */
582 error = uiomove(buffer, n, uio);
583 if (error)
584 break;
585 }
586 break;
587 case UE_BULK:
588 xfer = usbd_alloc_xfer(sc->sc_udev);
589 if (xfer == 0)
590 return (ENOMEM);
591 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
592 DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
593 tn = n;
594 err = usbd_bulk_transfer(
595 xfer, sce->pipeh,
596 sce->state & UGEN_SHORT_OK ?
597 USBD_SHORT_XFER_OK : 0,
598 sce->timeout, tbuf, &tn, "ugenrb");
599 if (err) {
600 if (err == USBD_INTERRUPTED)
601 error = EINTR;
602 else if (err == USBD_TIMEOUT)
603 error = ETIMEDOUT;
604 else
605 error = EIO;
606 break;
607 }
608 DPRINTFN(1, ("ugenread: got %d bytes\n", tn));
609 error = uiomove(tbuf, tn, uio);
610 if (error || tn < n)
611 break;
612 }
613 usbd_free_xfer(xfer);
614 break;
615 case UE_ISOCHRONOUS:
616 s = splusb();
617 while (sce->cur == sce->fill) {
618 if (flag & IO_NDELAY) {
619 splx(s);
620 return (EWOULDBLOCK);
621 }
622 sce->state |= UGEN_ASLP;
623 DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
624 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0);
625 DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
626 if (sc->sc_dying)
627 error = EIO;
628 if (error) {
629 sce->state &= ~UGEN_ASLP;
630 break;
631 }
632 }
633
634 while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) {
635 if(sce->fill > sce->cur)
636 n = min(sce->fill - sce->cur, uio->uio_resid);
637 else
638 n = min(sce->limit - sce->cur, uio->uio_resid);
639
640 DPRINTFN(5, ("ugenread: isoc got %d chars\n", n));
641
642 /* Copy the data to the user process. */
643 error = uiomove(sce->cur, n, uio);
644 if (error)
645 break;
646 sce->cur += n;
647 if(sce->cur >= sce->limit)
648 sce->cur = sce->ibuf;
649 }
650 splx(s);
651 break;
652
653
654 default:
655 return (ENXIO);
656 }
657 return (error);
658 }
659
660 int
661 ugenread(dev_t dev, struct uio *uio, int flag)
662 {
663 int endpt = UGENENDPOINT(dev);
664 struct ugen_softc *sc;
665 int error;
666
667 USB_GET_SC(ugen, UGENUNIT(dev), sc);
668
669 sc->sc_refcnt++;
670 error = ugen_do_read(sc, endpt, uio, flag);
671 if (--sc->sc_refcnt < 0)
672 usb_detach_wakeup(USBDEV(sc->sc_dev));
673 return (error);
674 }
675
676 Static int
677 ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
678 {
679 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
680 u_int32_t n;
681 int error = 0;
682 char tbuf[UGEN_BBSIZE];
683 usbd_xfer_handle xfer;
684 usbd_status err;
685
686 DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc->sc_dev), endpt));
687
688 if (sc->sc_dying)
689 return (EIO);
690
691 if (endpt == USB_CONTROL_ENDPOINT)
692 return (ENODEV);
693
694 #ifdef DIAGNOSTIC
695 if (sce->edesc == NULL) {
696 printf("ugenwrite: no edesc\n");
697 return (EIO);
698 }
699 if (sce->pipeh == NULL) {
700 printf("ugenwrite: no pipe\n");
701 return (EIO);
702 }
703 #endif
704
705 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
706 case UE_BULK:
707 xfer = usbd_alloc_xfer(sc->sc_udev);
708 if (xfer == 0)
709 return (EIO);
710 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
711 error = uiomove(tbuf, n, uio);
712 if (error)
713 break;
714 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
715 err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
716 sce->timeout, tbuf, &n,"ugenwb");
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 }
727 usbd_free_xfer(xfer);
728 break;
729 case UE_INTERRUPT:
730 xfer = usbd_alloc_xfer(sc->sc_udev);
731 if (xfer == 0)
732 return (EIO);
733 while ((n = min(UGETW(sce->edesc->wMaxPacketSize),
734 uio->uio_resid)) != 0) {
735 error = uiomove(tbuf, n, uio);
736 if (error)
737 break;
738 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
739 err = usbd_intr_transfer(xfer, sce->pipeh, 0,
740 sce->timeout, tbuf, &n, "ugenwi");
741 if (err) {
742 if (err == USBD_INTERRUPTED)
743 error = EINTR;
744 else if (err == USBD_TIMEOUT)
745 error = ETIMEDOUT;
746 else
747 error = EIO;
748 break;
749 }
750 }
751 usbd_free_xfer(xfer);
752 break;
753 default:
754 return (ENXIO);
755 }
756 return (error);
757 }
758
759 int
760 ugenwrite(dev_t dev, struct uio *uio, int flag)
761 {
762 int endpt = UGENENDPOINT(dev);
763 struct ugen_softc *sc;
764 int error;
765
766 USB_GET_SC(ugen, UGENUNIT(dev), sc);
767
768 sc->sc_refcnt++;
769 error = ugen_do_write(sc, endpt, uio, flag);
770 if (--sc->sc_refcnt < 0)
771 usb_detach_wakeup(USBDEV(sc->sc_dev));
772 return (error);
773 }
774
775 #if defined(__NetBSD__) || defined(__OpenBSD__)
776 int
777 ugen_activate(device_ptr_t self, enum devact act)
778 {
779 struct ugen_softc *sc = (struct ugen_softc *)self;
780
781 switch (act) {
782 case DVACT_ACTIVATE:
783 return (EOPNOTSUPP);
784
785 case DVACT_DEACTIVATE:
786 sc->sc_dying = 1;
787 break;
788 }
789 return (0);
790 }
791 #endif
792
793 USB_DETACH(ugen)
794 {
795 USB_DETACH_START(ugen, sc);
796 struct ugen_endpoint *sce;
797 int i, dir;
798 int s;
799 #if defined(__NetBSD__) || defined(__OpenBSD__)
800 int maj, mn;
801
802 DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags));
803 #elif defined(__FreeBSD__)
804 DPRINTF(("ugen_detach: sc=%p\n", sc));
805 #endif
806
807 sc->sc_dying = 1;
808 /* Abort all pipes. Causes processes waiting for transfer to wake. */
809 for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
810 for (dir = OUT; dir <= IN; dir++) {
811 sce = &sc->sc_endpoints[i][dir];
812 if (sce && sce->pipeh)
813 usbd_abort_pipe(sce->pipeh);
814 }
815 }
816
817 s = splusb();
818 if (--sc->sc_refcnt >= 0) {
819 /* Wake everyone */
820 for (i = 0; i < USB_MAX_ENDPOINTS; i++)
821 wakeup(&sc->sc_endpoints[i][IN]);
822 /* Wait for processes to go away. */
823 usb_detach_wait(USBDEV(sc->sc_dev));
824 }
825 splx(s);
826
827 #if defined(__NetBSD__) || defined(__OpenBSD__)
828 /* locate the major number */
829 #if defined(__NetBSD__)
830 maj = cdevsw_lookup_major(&ugen_cdevsw);
831 #elif defined(__OpenBSD__)
832 for (maj = 0; maj < nchrdev; maj++)
833 if (cdevsw[maj].d_open == ugenopen)
834 break;
835 #endif
836
837 /* Nuke the vnodes for any open instances (calls close). */
838 mn = device_unit(self) * USB_MAX_ENDPOINTS;
839 vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR);
840 #elif defined(__FreeBSD__)
841 /* XXX not implemented yet */
842 #endif
843
844 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
845 USBDEV(sc->sc_dev));
846
847 return (0);
848 }
849
850 Static void
851 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
852 {
853 struct ugen_endpoint *sce = addr;
854 /*struct ugen_softc *sc = sce->sc;*/
855 u_int32_t count;
856 u_char *ibuf;
857
858 if (status == USBD_CANCELLED)
859 return;
860
861 if (status != USBD_NORMAL_COMPLETION) {
862 DPRINTF(("ugenintr: status=%d\n", status));
863 if (status == USBD_STALLED)
864 usbd_clear_endpoint_stall_async(sce->pipeh);
865 return;
866 }
867
868 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
869 ibuf = sce->ibuf;
870
871 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
872 xfer, status, count));
873 DPRINTFN(5, (" data = %02x %02x %02x\n",
874 ibuf[0], ibuf[1], ibuf[2]));
875
876 (void)b_to_q(ibuf, count, &sce->q);
877
878 if (sce->state & UGEN_ASLP) {
879 sce->state &= ~UGEN_ASLP;
880 DPRINTFN(5, ("ugen_intr: waking %p\n", sce));
881 wakeup(sce);
882 }
883 selnotify(&sce->rsel, 0);
884 }
885
886 Static void
887 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
888 usbd_status status)
889 {
890 struct isoreq *req = addr;
891 struct ugen_endpoint *sce = req->sce;
892 u_int32_t count, n;
893 int i, isize;
894
895 /* Return if we are aborting. */
896 if (status == USBD_CANCELLED)
897 return;
898
899 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
900 DPRINTFN(5,("ugen_isoc_rintr: xfer %ld, count=%d\n",
901 (long)(req - sce->isoreqs), count));
902
903 /* throw away oldest input if the buffer is full */
904 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) {
905 sce->cur += count;
906 if(sce->cur >= sce->limit)
907 sce->cur = sce->ibuf + (sce->limit - sce->cur);
908 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n",
909 count));
910 }
911
912 isize = UGETW(sce->edesc->wMaxPacketSize);
913 for (i = 0; i < UGEN_NISORFRMS; i++) {
914 u_int32_t actlen = req->sizes[i];
915 char const *tbuf = (char const *)req->dmabuf + isize * i;
916
917 /* copy data to buffer */
918 while (actlen > 0) {
919 n = min(actlen, sce->limit - sce->fill);
920 memcpy(sce->fill, tbuf, n);
921
922 tbuf += n;
923 actlen -= n;
924 sce->fill += n;
925 if(sce->fill == sce->limit)
926 sce->fill = sce->ibuf;
927 }
928
929 /* setup size for next transfer */
930 req->sizes[i] = isize;
931 }
932
933 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS,
934 USBD_NO_COPY, ugen_isoc_rintr);
935 (void)usbd_transfer(xfer);
936
937 if (sce->state & UGEN_ASLP) {
938 sce->state &= ~UGEN_ASLP;
939 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce));
940 wakeup(sce);
941 }
942 selnotify(&sce->rsel, 0);
943 }
944
945 Static usbd_status
946 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno)
947 {
948 usbd_interface_handle iface;
949 usb_endpoint_descriptor_t *ed;
950 usbd_status err;
951 struct ugen_endpoint *sce;
952 u_int8_t niface, nendpt, endptno, endpt;
953 int dir;
954
955 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
956
957 err = usbd_interface_count(sc->sc_udev, &niface);
958 if (err)
959 return (err);
960 if (ifaceidx < 0 || ifaceidx >= niface)
961 return (USBD_INVAL);
962
963 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
964 if (err)
965 return (err);
966 err = usbd_endpoint_count(iface, &nendpt);
967 if (err)
968 return (err);
969 /* XXX should only do this after setting new altno has succeeded */
970 for (endptno = 0; endptno < nendpt; endptno++) {
971 ed = usbd_interface2endpoint_descriptor(iface,endptno);
972 endpt = ed->bEndpointAddress;
973 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
974 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
975 sce->sc = 0;
976 sce->edesc = 0;
977 sce->iface = 0;
978 }
979
980 /* change setting */
981 err = usbd_set_interface(iface, altno);
982 if (err)
983 return (err);
984
985 err = usbd_endpoint_count(iface, &nendpt);
986 if (err)
987 return (err);
988 for (endptno = 0; endptno < nendpt; endptno++) {
989 ed = usbd_interface2endpoint_descriptor(iface,endptno);
990 KASSERT(ed != NULL);
991 endpt = ed->bEndpointAddress;
992 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
993 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
994 sce->sc = sc;
995 sce->edesc = ed;
996 sce->iface = iface;
997 }
998 return (0);
999 }
1000
1001 /* Retrieve a complete descriptor for a certain device and index. */
1002 Static usb_config_descriptor_t *
1003 ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp)
1004 {
1005 usb_config_descriptor_t *cdesc, *tdesc, cdescr;
1006 int len;
1007 usbd_status err;
1008
1009 if (index == USB_CURRENT_CONFIG_INDEX) {
1010 tdesc = usbd_get_config_descriptor(sc->sc_udev);
1011 len = UGETW(tdesc->wTotalLength);
1012 if (lenp)
1013 *lenp = len;
1014 cdesc = malloc(len, M_TEMP, M_WAITOK);
1015 memcpy(cdesc, tdesc, len);
1016 DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
1017 } else {
1018 err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
1019 if (err)
1020 return (0);
1021 len = UGETW(cdescr.wTotalLength);
1022 DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
1023 if (lenp)
1024 *lenp = len;
1025 cdesc = malloc(len, M_TEMP, M_WAITOK);
1026 err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
1027 if (err) {
1028 free(cdesc, M_TEMP);
1029 return (0);
1030 }
1031 }
1032 return (cdesc);
1033 }
1034
1035 Static int
1036 ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx)
1037 {
1038 usbd_interface_handle iface;
1039 usbd_status err;
1040
1041 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
1042 if (err)
1043 return (-1);
1044 return (usbd_get_interface_altindex(iface));
1045 }
1046
1047 Static int
1048 ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
1049 caddr_t addr, int flag, struct lwp *l)
1050 {
1051 struct ugen_endpoint *sce;
1052 usbd_status err;
1053 usbd_interface_handle iface;
1054 struct usb_config_desc *cd;
1055 usb_config_descriptor_t *cdesc;
1056 struct usb_interface_desc *id;
1057 usb_interface_descriptor_t *idesc;
1058 struct usb_endpoint_desc *ed;
1059 usb_endpoint_descriptor_t *edesc;
1060 struct usb_alt_interface *ai;
1061 struct usb_string_desc *si;
1062 u_int8_t conf, alt;
1063
1064 DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd));
1065 if (sc->sc_dying)
1066 return (EIO);
1067
1068 switch (cmd) {
1069 case FIONBIO:
1070 /* All handled in the upper FS layer. */
1071 return (0);
1072 case USB_SET_SHORT_XFER:
1073 if (endpt == USB_CONTROL_ENDPOINT)
1074 return (EINVAL);
1075 /* This flag only affects read */
1076 sce = &sc->sc_endpoints[endpt][IN];
1077 if (sce == NULL || sce->pipeh == NULL)
1078 return (EINVAL);
1079 if (*(int *)addr)
1080 sce->state |= UGEN_SHORT_OK;
1081 else
1082 sce->state &= ~UGEN_SHORT_OK;
1083 return (0);
1084 case USB_SET_TIMEOUT:
1085 sce = &sc->sc_endpoints[endpt][IN];
1086 if (sce == NULL
1087 /* XXX this shouldn't happen, but the distinction between
1088 input and output pipes isn't clear enough.
1089 || sce->pipeh == NULL */
1090 )
1091 return (EINVAL);
1092 sce->timeout = *(int *)addr;
1093 return (0);
1094 default:
1095 break;
1096 }
1097
1098 if (endpt != USB_CONTROL_ENDPOINT)
1099 return (EINVAL);
1100
1101 switch (cmd) {
1102 #ifdef UGEN_DEBUG
1103 case USB_SETDEBUG:
1104 ugendebug = *(int *)addr;
1105 break;
1106 #endif
1107 case USB_GET_CONFIG:
1108 err = usbd_get_config(sc->sc_udev, &conf);
1109 if (err)
1110 return (EIO);
1111 *(int *)addr = conf;
1112 break;
1113 case USB_SET_CONFIG:
1114 if (!(flag & FWRITE))
1115 return (EPERM);
1116 err = ugen_set_config(sc, *(int *)addr);
1117 switch (err) {
1118 case USBD_NORMAL_COMPLETION:
1119 break;
1120 case USBD_IN_USE:
1121 return (EBUSY);
1122 default:
1123 return (EIO);
1124 }
1125 break;
1126 case USB_GET_ALTINTERFACE:
1127 ai = (struct usb_alt_interface *)addr;
1128 err = usbd_device2interface_handle(sc->sc_udev,
1129 ai->uai_interface_index, &iface);
1130 if (err)
1131 return (EINVAL);
1132 idesc = usbd_get_interface_descriptor(iface);
1133 if (idesc == NULL)
1134 return (EIO);
1135 ai->uai_alt_no = idesc->bAlternateSetting;
1136 break;
1137 case USB_SET_ALTINTERFACE:
1138 if (!(flag & FWRITE))
1139 return (EPERM);
1140 ai = (struct usb_alt_interface *)addr;
1141 err = usbd_device2interface_handle(sc->sc_udev,
1142 ai->uai_interface_index, &iface);
1143 if (err)
1144 return (EINVAL);
1145 err = ugen_set_interface(sc, ai->uai_interface_index,
1146 ai->uai_alt_no);
1147 if (err)
1148 return (EINVAL);
1149 break;
1150 case USB_GET_NO_ALT:
1151 ai = (struct usb_alt_interface *)addr;
1152 cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0);
1153 if (cdesc == NULL)
1154 return (EINVAL);
1155 idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0);
1156 if (idesc == NULL) {
1157 free(cdesc, M_TEMP);
1158 return (EINVAL);
1159 }
1160 ai->uai_alt_no = usbd_get_no_alts(cdesc,
1161 idesc->bInterfaceNumber);
1162 free(cdesc, M_TEMP);
1163 break;
1164 case USB_GET_DEVICE_DESC:
1165 *(usb_device_descriptor_t *)addr =
1166 *usbd_get_device_descriptor(sc->sc_udev);
1167 break;
1168 case USB_GET_CONFIG_DESC:
1169 cd = (struct usb_config_desc *)addr;
1170 cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0);
1171 if (cdesc == NULL)
1172 return (EINVAL);
1173 cd->ucd_desc = *cdesc;
1174 free(cdesc, M_TEMP);
1175 break;
1176 case USB_GET_INTERFACE_DESC:
1177 id = (struct usb_interface_desc *)addr;
1178 cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0);
1179 if (cdesc == NULL)
1180 return (EINVAL);
1181 if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX &&
1182 id->uid_alt_index == USB_CURRENT_ALT_INDEX)
1183 alt = ugen_get_alt_index(sc, id->uid_interface_index);
1184 else
1185 alt = id->uid_alt_index;
1186 idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt);
1187 if (idesc == NULL) {
1188 free(cdesc, M_TEMP);
1189 return (EINVAL);
1190 }
1191 id->uid_desc = *idesc;
1192 free(cdesc, M_TEMP);
1193 break;
1194 case USB_GET_ENDPOINT_DESC:
1195 ed = (struct usb_endpoint_desc *)addr;
1196 cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0);
1197 if (cdesc == NULL)
1198 return (EINVAL);
1199 if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX &&
1200 ed->ued_alt_index == USB_CURRENT_ALT_INDEX)
1201 alt = ugen_get_alt_index(sc, ed->ued_interface_index);
1202 else
1203 alt = ed->ued_alt_index;
1204 edesc = usbd_find_edesc(cdesc, ed->ued_interface_index,
1205 alt, ed->ued_endpoint_index);
1206 if (edesc == NULL) {
1207 free(cdesc, M_TEMP);
1208 return (EINVAL);
1209 }
1210 ed->ued_desc = *edesc;
1211 free(cdesc, M_TEMP);
1212 break;
1213 case USB_GET_FULL_DESC:
1214 {
1215 int len;
1216 struct iovec iov;
1217 struct uio uio;
1218 struct usb_full_desc *fd = (struct usb_full_desc *)addr;
1219 int error;
1220
1221 cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len);
1222 if (len > fd->ufd_size)
1223 len = fd->ufd_size;
1224 iov.iov_base = (caddr_t)fd->ufd_data;
1225 iov.iov_len = len;
1226 uio.uio_iov = &iov;
1227 uio.uio_iovcnt = 1;
1228 uio.uio_resid = len;
1229 uio.uio_offset = 0;
1230 uio.uio_rw = UIO_READ;
1231 uio.uio_vmspace = l->l_proc->p_vmspace;
1232 error = uiomove((void *)cdesc, len, &uio);
1233 free(cdesc, M_TEMP);
1234 return (error);
1235 }
1236 case USB_GET_STRING_DESC: {
1237 int len;
1238 si = (struct usb_string_desc *)addr;
1239 err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
1240 si->usd_language_id, &si->usd_desc, &len);
1241 if (err)
1242 return (EINVAL);
1243 break;
1244 }
1245 case USB_DO_REQUEST:
1246 {
1247 struct usb_ctl_request *ur = (void *)addr;
1248 int len = UGETW(ur->ucr_request.wLength);
1249 struct iovec iov;
1250 struct uio uio;
1251 void *ptr = 0;
1252 usbd_status xerr;
1253 int error = 0;
1254
1255 if (!(flag & FWRITE))
1256 return (EPERM);
1257 /* Avoid requests that would damage the bus integrity. */
1258 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1259 ur->ucr_request.bRequest == UR_SET_ADDRESS) ||
1260 (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1261 ur->ucr_request.bRequest == UR_SET_CONFIG) ||
1262 (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE &&
1263 ur->ucr_request.bRequest == UR_SET_INTERFACE))
1264 return (EINVAL);
1265
1266 if (len < 0 || len > 32767)
1267 return (EINVAL);
1268 if (len != 0) {
1269 iov.iov_base = (caddr_t)ur->ucr_data;
1270 iov.iov_len = len;
1271 uio.uio_iov = &iov;
1272 uio.uio_iovcnt = 1;
1273 uio.uio_resid = len;
1274 uio.uio_offset = 0;
1275 uio.uio_rw =
1276 ur->ucr_request.bmRequestType & UT_READ ?
1277 UIO_READ : UIO_WRITE;
1278 uio.uio_vmspace = l->l_proc->p_vmspace;
1279 ptr = malloc(len, M_TEMP, M_WAITOK);
1280 if (uio.uio_rw == UIO_WRITE) {
1281 error = uiomove(ptr, len, &uio);
1282 if (error)
1283 goto ret;
1284 }
1285 }
1286 sce = &sc->sc_endpoints[endpt][IN];
1287 xerr = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request,
1288 ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout);
1289 if (xerr) {
1290 error = EIO;
1291 goto ret;
1292 }
1293 if (len != 0) {
1294 if (uio.uio_rw == UIO_READ) {
1295 error = uiomove(ptr, len, &uio);
1296 if (error)
1297 goto ret;
1298 }
1299 }
1300 ret:
1301 if (ptr)
1302 free(ptr, M_TEMP);
1303 return (error);
1304 }
1305 case USB_GET_DEVICEINFO:
1306 usbd_fill_deviceinfo(sc->sc_udev,
1307 (struct usb_device_info *)addr, 1);
1308 break;
1309 default:
1310 return (EINVAL);
1311 }
1312 return (0);
1313 }
1314
1315 int
1316 ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct lwp *l)
1317 {
1318 int endpt = UGENENDPOINT(dev);
1319 struct ugen_softc *sc;
1320 int error;
1321
1322 USB_GET_SC(ugen, UGENUNIT(dev), sc);
1323
1324 sc->sc_refcnt++;
1325 error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, l);
1326 if (--sc->sc_refcnt < 0)
1327 usb_detach_wakeup(USBDEV(sc->sc_dev));
1328 return (error);
1329 }
1330
1331 int
1332 ugenpoll(dev_t dev, int events, struct lwp *l)
1333 {
1334 struct ugen_softc *sc;
1335 struct ugen_endpoint *sce;
1336 int revents = 0;
1337 int s;
1338
1339 USB_GET_SC(ugen, UGENUNIT(dev), sc);
1340
1341 if (sc->sc_dying)
1342 return (POLLHUP);
1343
1344 /* XXX always IN */
1345 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1346 if (sce == NULL)
1347 return (POLLERR);
1348 #ifdef DIAGNOSTIC
1349 if (!sce->edesc) {
1350 printf("ugenpoll: no edesc\n");
1351 return (POLLERR);
1352 }
1353 if (!sce->pipeh) {
1354 printf("ugenpoll: no pipe\n");
1355 return (POLLERR);
1356 }
1357 #endif
1358 s = splusb();
1359 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
1360 case UE_INTERRUPT:
1361 if (events & (POLLIN | POLLRDNORM)) {
1362 if (sce->q.c_cc > 0)
1363 revents |= events & (POLLIN | POLLRDNORM);
1364 else
1365 selrecord(l, &sce->rsel);
1366 }
1367 break;
1368 case UE_ISOCHRONOUS:
1369 if (events & (POLLIN | POLLRDNORM)) {
1370 if (sce->cur != sce->fill)
1371 revents |= events & (POLLIN | POLLRDNORM);
1372 else
1373 selrecord(l, &sce->rsel);
1374 }
1375 break;
1376 case UE_BULK:
1377 /*
1378 * We have no easy way of determining if a read will
1379 * yield any data or a write will happen.
1380 * Pretend they will.
1381 */
1382 revents |= events &
1383 (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
1384 break;
1385 default:
1386 break;
1387 }
1388 splx(s);
1389 return (revents);
1390 }
1391
1392 static void
1393 filt_ugenrdetach(struct knote *kn)
1394 {
1395 struct ugen_endpoint *sce = kn->kn_hook;
1396 int s;
1397
1398 s = splusb();
1399 SLIST_REMOVE(&sce->rsel.sel_klist, kn, knote, kn_selnext);
1400 splx(s);
1401 }
1402
1403 static int
1404 filt_ugenread_intr(struct knote *kn, long hint)
1405 {
1406 struct ugen_endpoint *sce = kn->kn_hook;
1407
1408 kn->kn_data = sce->q.c_cc;
1409 return (kn->kn_data > 0);
1410 }
1411
1412 static int
1413 filt_ugenread_isoc(struct knote *kn, long hint)
1414 {
1415 struct ugen_endpoint *sce = kn->kn_hook;
1416
1417 if (sce->cur == sce->fill)
1418 return (0);
1419
1420 if (sce->cur < sce->fill)
1421 kn->kn_data = sce->fill - sce->cur;
1422 else
1423 kn->kn_data = (sce->limit - sce->cur) +
1424 (sce->fill - sce->ibuf);
1425
1426 return (1);
1427 }
1428
1429 static const struct filterops ugenread_intr_filtops =
1430 { 1, NULL, filt_ugenrdetach, filt_ugenread_intr };
1431
1432 static const struct filterops ugenread_isoc_filtops =
1433 { 1, NULL, filt_ugenrdetach, filt_ugenread_isoc };
1434
1435 static const struct filterops ugen_seltrue_filtops =
1436 { 1, NULL, filt_ugenrdetach, filt_seltrue };
1437
1438 int
1439 ugenkqfilter(dev_t dev, struct knote *kn)
1440 {
1441 struct ugen_softc *sc;
1442 struct ugen_endpoint *sce;
1443 struct klist *klist;
1444 int s;
1445
1446 USB_GET_SC(ugen, UGENUNIT(dev), sc);
1447
1448 if (sc->sc_dying)
1449 return (1);
1450
1451 /* XXX always IN */
1452 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1453 if (sce == NULL)
1454 return (1);
1455
1456 switch (kn->kn_filter) {
1457 case EVFILT_READ:
1458 klist = &sce->rsel.sel_klist;
1459 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
1460 case UE_INTERRUPT:
1461 kn->kn_fop = &ugenread_intr_filtops;
1462 break;
1463 case UE_ISOCHRONOUS:
1464 kn->kn_fop = &ugenread_isoc_filtops;
1465 break;
1466 case UE_BULK:
1467 /*
1468 * We have no easy way of determining if a read will
1469 * yield any data or a write will happen.
1470 * So, emulate "seltrue".
1471 */
1472 kn->kn_fop = &ugen_seltrue_filtops;
1473 break;
1474 default:
1475 return (1);
1476 }
1477 break;
1478
1479 case EVFILT_WRITE:
1480 klist = &sce->rsel.sel_klist;
1481 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
1482 case UE_INTERRUPT:
1483 case UE_ISOCHRONOUS:
1484 /* XXX poll doesn't support this */
1485 return (1);
1486
1487 case UE_BULK:
1488 /*
1489 * We have no easy way of determining if a read will
1490 * yield any data or a write will happen.
1491 * So, emulate "seltrue".
1492 */
1493 kn->kn_fop = &ugen_seltrue_filtops;
1494 break;
1495 default:
1496 return (1);
1497 }
1498 break;
1499
1500 default:
1501 return (1);
1502 }
1503
1504 kn->kn_hook = sce;
1505
1506 s = splusb();
1507 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
1508 splx(s);
1509
1510 return (0);
1511 }
1512
1513 #if defined(__FreeBSD__)
1514 DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, usbd_driver_load, 0);
1515 #endif
1516