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