1 /* $NetBSD: ugen.c,v 1.79 2006/03/01 12:38:13 yamt Exp $ */
3 /* Also already merged from NetBSD:
4 * $NetBSD: ugen.c,v 1.61 2002/09/23 05:51:20 simonb Exp $
5 * $NetBSD: ugen.c,v 1.64 2003/06/28 14:21:46 darrenr Exp $
6 * $NetBSD: ugen.c,v 1.65 2003/06/29 22:30:56 fvdl Exp $
7 * $NetBSD: ugen.c,v 1.68 2004/06/23 02:30:52 mycroft Exp $
10 #include <sys/cdefs.h>
11 __FBSDID("$FreeBSD$");
14 * Copyright (c) 1998 The NetBSD Foundation, Inc.
15 * All rights reserved.
17 * This code is derived from software contributed to The NetBSD Foundation
18 * by Lennart Augustsson (lennart@augustsson.net) at
19 * Carlstedt Research & Technology.
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * 3. All advertising materials mentioning features or use of this software
30 * must display the following acknowledgement:
31 * This product includes software developed by the NetBSD
32 * Foundation, Inc. and its contributors.
33 * 4. Neither the name of The NetBSD Foundation nor the names of its
34 * contributors may be used to endorse or promote products derived
35 * from this software without specific prior written permission.
37 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
38 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
39 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
41 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47 * POSSIBILITY OF SUCH DAMAGE.
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/kernel.h>
54 #include <sys/malloc.h>
55 #include <sys/module.h>
57 #include <sys/ioccom.h>
59 #include <sys/fcntl.h>
60 #include <sys/filio.h>
63 #include <sys/selinfo.h>
65 #include <sys/sysctl.h>
68 #include <dev/usb/usb.h>
69 #include <dev/usb/usbdi.h>
70 #include <dev/usb/usbdi_util.h>
73 #define DPRINTF(x) if (ugendebug) printf x
74 #define DPRINTFN(n,x) if (ugendebug>(n)) printf x
76 SYSCTL_NODE(_hw_usb, OID_AUTO, ugen, CTLFLAG_RW, 0, "USB ugen");
77 SYSCTL_INT(_hw_usb_ugen, OID_AUTO, debug, CTLFLAG_RW,
78 &ugendebug, 0, "ugen debug level");
84 #define UGEN_CHUNK 128 /* chunk size for read */
85 #define UGEN_IBSIZE 1020 /* buffer size */
86 #define UGEN_BBSIZE 1024
88 #define UGEN_NISOFRAMES 500 /* 0.5 seconds worth */
89 #define UGEN_NISOREQS 6 /* number of outstanding xfer requests */
90 #define UGEN_NISORFRMS 4 /* number of frames (miliseconds) per req */
92 struct ugen_endpoint {
93 struct ugen_softc *sc;
95 usb_endpoint_descriptor_t *edesc;
96 usbd_interface_handle iface;
98 #define UGEN_ASLP 0x02 /* waiting for data */
99 #define UGEN_SHORT_OK 0x04 /* short xfers are OK */
100 usbd_pipe_handle pipeh;
103 u_char *ibuf; /* start of buffer (circular for isoc) */
104 u_char *fill; /* location for input (isoc) */
105 u_char *limit; /* end of circular buffer (isoc) */
106 u_char *cur; /* current read location (isoc) */
109 struct ugen_endpoint *sce;
110 usbd_xfer_handle xfer;
112 u_int16_t sizes[UGEN_NISORFRMS];
113 } isoreqs[UGEN_NISOREQS];
117 device_t sc_dev; /* base device */
118 usbd_device_handle sc_udev;
121 char sc_is_open[USB_MAX_ENDPOINTS];
122 struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2];
126 #define UGEN_DEV_REF(dev, sc) \
127 if ((sc)->sc_dying || dev_refthread(dev) == NULL) \
129 #define UGEN_DEV_RELE(dev, sc) \
131 #define UGEN_DEV_OPEN(dev, sc) \
132 /* handled by dev layer */
133 #define UGEN_DEV_CLOSE(dev, sc) \
134 /* handled by dev layer */
146 static struct cdevsw ugenctl_cdevsw = {
147 .d_version = D_VERSION,
148 .d_flags = D_NEEDGIANT,
150 .d_close = ugenclose,
151 .d_ioctl = ugenioctl,
152 .d_purge = ugenpurge,
156 static struct cdevsw ugen_cdevsw = {
157 .d_version = D_VERSION,
158 .d_flags = D_NEEDGIANT,
160 .d_close = ugenclose,
162 .d_write = ugenwrite,
163 .d_ioctl = ugenioctl,
165 .d_purge = ugenpurge,
169 static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr,
171 static void ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
173 static int ugen_do_read(struct ugen_softc *, int, struct uio *, int);
174 static int ugen_do_write(struct ugen_softc *, int, struct uio *, int);
175 static int ugen_do_ioctl(struct ugen_softc *, int, u_long,
176 caddr_t, int, struct thread *);
177 static void ugen_make_devnodes(struct ugen_softc *sc);
178 static void ugen_destroy_devnodes(struct ugen_softc *sc);
179 static int ugen_set_config(struct ugen_softc *sc, int configno);
180 static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc,
181 int index, int *lenp);
182 static usbd_status ugen_set_interface(struct ugen_softc *, int, int);
183 static int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx);
185 #define UGENUNIT(n) ((minor(n) >> 4) & 0xf)
186 #define UGENENDPOINT(n) (minor(n) & 0xf)
187 #define UGENMINOR(u, e) (((u) << 4) | (e))
189 static device_probe_t ugen_match;
190 static device_attach_t ugen_attach;
191 static device_detach_t ugen_detach;
193 static devclass_t ugen_devclass;
195 static device_method_t ugen_methods[] = {
196 DEVMETHOD(device_probe, ugen_match),
197 DEVMETHOD(device_attach, ugen_attach),
198 DEVMETHOD(device_detach, ugen_detach),
203 static driver_t ugen_driver = {
206 sizeof(struct ugen_softc)
209 MODULE_DEPEND(ugen, usb, 1, 1, 1);
212 ugen_match(device_t self)
214 struct usb_attach_arg *uaa = device_get_ivars(self);
218 return (uaa->matchlvl);
221 return (UMATCH_GENERIC);
223 return (UMATCH_NONE);
227 ugen_attach(device_t self)
229 struct ugen_softc *sc = device_get_softc(self);
230 struct usb_attach_arg *uaa = device_get_ivars(self);
231 usbd_device_handle udev;
236 sc->sc_udev = udev = uaa->device;
238 memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
240 /* First set configuration index 0, the default one for ugen. */
241 err = usbd_set_config_index(udev, 0, 0);
243 printf("%s: setting configuration index 0 failed\n",
244 device_get_nameunit(sc->sc_dev));
248 conf = usbd_get_config_descriptor(udev)->bConfigurationValue;
250 /* Set up all the local state for this configuration. */
251 err = ugen_set_config(sc, conf);
253 printf("%s: setting configuration %d failed\n",
254 device_get_nameunit(sc->sc_dev), conf);
259 /* the main device, ctrl endpoint */
260 sc->dev = make_dev(&ugenctl_cdevsw,
261 UGENMINOR(device_get_unit(sc->sc_dev), 0), UID_ROOT, GID_OPERATOR, 0644,
262 "%s", device_get_nameunit(sc->sc_dev));
263 ugen_make_devnodes(sc);
264 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
269 ugen_make_devnodes(struct ugen_softc *sc)
274 for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
275 if (sc->sc_endpoints[endptno][IN].sc != NULL ||
276 sc->sc_endpoints[endptno][OUT].sc != NULL ) {
277 /* endpt can be 0x81 and 0x01, representing
278 * endpoint address 0x01 and IN/OUT directions.
279 * We map both endpts to the same device,
280 * IN is reading from it, OUT is writing to it.
282 * In the if clause above we check whether one
283 * of the structs is populated.
285 dev = make_dev(&ugen_cdevsw,
286 UGENMINOR(device_get_unit(sc->sc_dev), endptno),
287 UID_ROOT, GID_OPERATOR, 0644,
289 device_get_nameunit(sc->sc_dev), endptno);
290 dev_depends(sc->dev, dev);
291 if (sc->sc_endpoints[endptno][IN].sc != NULL)
292 sc->sc_endpoints[endptno][IN].dev = dev;
293 if (sc->sc_endpoints[endptno][OUT].sc != NULL)
294 sc->sc_endpoints[endptno][OUT].dev = dev;
300 ugen_destroy_devnodes(struct ugen_softc *sc)
302 int endptno, prev_sc_dying;
305 prev_sc_dying = sc->sc_dying;
307 /* destroy all devices for the other (existing) endpoints as well */
308 for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
309 if (sc->sc_endpoints[endptno][IN].sc != NULL ||
310 sc->sc_endpoints[endptno][OUT].sc != NULL ) {
311 /* endpt can be 0x81 and 0x01, representing
312 * endpoint address 0x01 and IN/OUT directions.
313 * We map both endpoint addresses to the same device,
314 * IN is reading from it, OUT is writing to it.
316 * In the if clause above we check whether one
317 * of the structs is populated.
319 if (sc->sc_endpoints[endptno][IN].sc != NULL)
320 dev = sc->sc_endpoints[endptno][IN].dev;
322 dev = sc->sc_endpoints[endptno][OUT].dev;
325 ("ugen_destroy_devnodes: NULL dev"));
329 sc->sc_endpoints[endptno][IN].sc = NULL;
330 sc->sc_endpoints[endptno][OUT].sc = NULL;
333 sc->sc_dying = prev_sc_dying;
337 ugen_set_config(struct ugen_softc *sc, int configno)
339 usbd_device_handle dev = sc->sc_udev;
340 usbd_interface_handle iface;
341 usb_endpoint_descriptor_t *ed;
342 struct ugen_endpoint *sce, **sce_cache, ***sce_cache_arr;
343 u_int8_t niface, niface_cache, nendpt, *nendpt_cache;
344 int ifaceno, endptno, endpt;
348 DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
349 device_get_nameunit(sc->sc_dev), configno, sc));
351 /* We start at 1, not 0, because we don't care whether the
352 * control endpoint is open or not. It is always present.
354 for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++)
355 if (sc->sc_is_open[endptno]) {
357 ("ugen_set_config: %s - endpoint %d is open\n",
358 device_get_nameunit(sc->sc_dev), endptno));
359 return (USBD_IN_USE);
362 err = usbd_interface_count(dev, &niface);
365 /* store an array of endpoint descriptors to clear if the configuration
366 * change succeeds - these aren't available afterwards */
367 nendpt_cache = malloc(sizeof(u_int8_t) * niface, M_TEMP, M_WAITOK |
369 sce_cache_arr = malloc(sizeof(struct ugen_endpoint **) * niface, M_TEMP,
371 niface_cache = niface;
373 for (ifaceno = 0; ifaceno < niface; ifaceno++) {
374 DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
375 err = usbd_device2interface_handle(dev, ifaceno, &iface);
377 panic("ugen_set_config: can't obtain interface handle");
378 err = usbd_endpoint_count(iface, &nendpt);
380 panic("ugen_set_config: endpoint count failed");
382 /* store endpoint descriptors for each interface */
383 nendpt_cache[ifaceno] = nendpt;
384 sce_cache = malloc(sizeof(struct ugen_endpoint *) * nendpt, M_TEMP,
386 sce_cache_arr[ifaceno] = sce_cache;
388 for (endptno = 0; endptno < nendpt; endptno++) {
389 ed = usbd_interface2endpoint_descriptor(iface,endptno);
390 endpt = ed->bEndpointAddress;
391 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
392 sce_cache[endptno] = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
396 /* Avoid setting the current value. */
397 if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) {
398 /* attempt to perform the configuration change */
399 err = usbd_set_config_no(dev, configno, 1);
401 for(ifaceno = 0; ifaceno < niface_cache; ifaceno++)
402 free(sce_cache_arr[ifaceno], M_TEMP);
403 free(sce_cache_arr, M_TEMP);
404 free(nendpt_cache, M_TEMP);
409 ugen_destroy_devnodes(sc);
411 /* now we can clear the old interface's ugen_endpoints */
412 for(ifaceno = 0; ifaceno < niface_cache; ifaceno++) {
413 sce_cache = sce_cache_arr[ifaceno];
414 for(endptno = 0; endptno < nendpt_cache[ifaceno]; endptno++) {
415 sce = sce_cache[endptno];
422 /* and free the cache storing them */
423 for(ifaceno = 0; ifaceno < niface_cache; ifaceno++)
424 free(sce_cache_arr[ifaceno], M_TEMP);
425 free(sce_cache_arr, M_TEMP);
426 free(nendpt_cache, M_TEMP);
428 /* no endpoints if the device is in the unconfigured state */
429 if (configno != USB_UNCONFIG_NO)
431 /* set the new configuration's ugen_endpoints */
432 err = usbd_interface_count(dev, &niface);
434 panic("ugen_set_config: interface count failed");
436 memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
437 for (ifaceno = 0; ifaceno < niface; ifaceno++) {
438 DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
439 err = usbd_device2interface_handle(dev, ifaceno, &iface);
441 panic("ugen_set_config: can't obtain interface handle");
442 err = usbd_endpoint_count(iface, &nendpt);
444 panic("ugen_set_config: endpoint count failed");
445 for (endptno = 0; endptno < nendpt; endptno++) {
446 ed = usbd_interface2endpoint_descriptor(iface,endptno);
447 endpt = ed->bEndpointAddress;
448 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
449 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
450 DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x"
452 endptno, endpt, UE_GET_ADDR(endpt),
453 UE_GET_DIR(endpt), sce));
461 return (USBD_NORMAL_COMPLETION);
465 ugenopen(struct cdev *dev, int flag, int mode, struct thread *p)
467 struct ugen_softc *sc;
468 int unit = UGENUNIT(dev);
469 int endpt = UGENENDPOINT(dev);
470 usb_endpoint_descriptor_t *edesc;
471 struct ugen_endpoint *sce;
474 usbd_xfer_handle xfer;
478 sc = devclass_get_softc(ugen_devclass, unit);
482 DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
483 flag, mode, unit, endpt));
485 if (sc == NULL || sc->sc_dying)
488 if (sc->sc_is_open[endpt])
491 if (endpt == USB_CONTROL_ENDPOINT) {
492 sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
493 UGEN_DEV_OPEN(dev, sc);
497 /* Make sure there are pipes for all directions. */
498 for (dir = OUT; dir <= IN; dir++) {
499 if (flag & (dir == OUT ? FWRITE : FREAD)) {
500 sce = &sc->sc_endpoints[endpt][dir];
506 /* Actually open the pipes. */
507 /* XXX Should back out properly if it fails. */
508 for (dir = OUT; dir <= IN; dir++) {
509 if (!(flag & (dir == OUT ? FWRITE : FREAD)))
511 sce = &sc->sc_endpoints[endpt][dir];
513 sce->timeout = USBD_NO_TIMEOUT;
514 DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
515 sc, endpt, dir, sce));
517 switch (edesc->bmAttributes & UE_XFERTYPE) {
520 err = usbd_open_pipe(sce->iface,
521 edesc->bEndpointAddress, 0, &sce->pipeh);
526 isize = UGETW(edesc->wMaxPacketSize);
527 if (isize == 0) /* shouldn't happen */
529 sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
530 DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
532 if ((clist_alloc_cblocks(&sce->q, UGEN_IBSIZE,
533 UGEN_IBSIZE), 0) == -1)
535 err = usbd_open_pipe_intr(sce->iface,
536 edesc->bEndpointAddress,
537 USBD_SHORT_XFER_OK, &sce->pipeh, sce,
538 sce->ibuf, isize, ugenintr,
539 USBD_DEFAULT_INTERVAL);
541 free(sce->ibuf, M_USBDEV);
542 clist_free_cblocks(&sce->q);
545 DPRINTFN(5, ("ugenopen: interrupt open done\n"));
548 err = usbd_open_pipe(sce->iface,
549 edesc->bEndpointAddress, 0, &sce->pipeh);
556 isize = UGETW(edesc->wMaxPacketSize);
557 if (isize == 0) /* shouldn't happen */
559 sce->ibuf = malloc(isize * UGEN_NISOFRAMES,
561 sce->cur = sce->fill = sce->ibuf;
562 sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES;
563 DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n",
565 err = usbd_open_pipe(sce->iface,
566 edesc->bEndpointAddress, 0, &sce->pipeh);
568 free(sce->ibuf, M_USBDEV);
571 for(i = 0; i < UGEN_NISOREQS; ++i) {
572 sce->isoreqs[i].sce = sce;
573 xfer = usbd_alloc_xfer(sc->sc_udev);
576 sce->isoreqs[i].xfer = xfer;
577 buf = usbd_alloc_buffer
578 (xfer, isize * UGEN_NISORFRMS);
583 sce->isoreqs[i].dmabuf = buf;
584 for(j = 0; j < UGEN_NISORFRMS; ++j)
585 sce->isoreqs[i].sizes[j] = isize;
587 (xfer, sce->pipeh, &sce->isoreqs[i],
588 sce->isoreqs[i].sizes,
589 UGEN_NISORFRMS, USBD_NO_COPY,
591 (void)usbd_transfer(xfer);
593 DPRINTFN(5, ("ugenopen: isoc open done\n"));
596 while (--i >= 0) /* implicit buffer free */
597 usbd_free_xfer(sce->isoreqs[i].xfer);
600 sce->timeout = USBD_DEFAULT_TIMEOUT;
604 sc->sc_is_open[endpt] = 1;
605 UGEN_DEV_OPEN(dev, sc);
610 ugenclose(struct cdev *dev, int flag, int mode, struct thread *p)
612 int endpt = UGENENDPOINT(dev);
613 struct ugen_softc *sc;
614 struct ugen_endpoint *sce;
618 sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
620 DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
621 flag, mode, UGENUNIT(dev), endpt));
624 if (!sc->sc_is_open[endpt]) {
625 printf("ugenclose: not open\n");
630 if (endpt == USB_CONTROL_ENDPOINT) {
631 DPRINTFN(5, ("ugenclose: close control\n"));
632 sc->sc_is_open[endpt] = 0;
633 UGEN_DEV_CLOSE(dev, sc);
637 for (dir = OUT; dir <= IN; dir++) {
638 if (!(flag & (dir == OUT ? FWRITE : FREAD)))
640 sce = &sc->sc_endpoints[endpt][dir];
641 if (sce->pipeh == NULL)
643 DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
646 usbd_abort_pipe(sce->pipeh);
647 usbd_close_pipe(sce->pipeh);
650 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
652 ndflush(&sce->q, sce->q.c_cc);
653 clist_free_cblocks(&sce->q);
656 for (i = 0; i < UGEN_NISOREQS; ++i)
657 usbd_free_xfer(sce->isoreqs[i].xfer);
663 if (sce->ibuf != NULL) {
664 free(sce->ibuf, M_USBDEV);
666 clist_free_cblocks(&sce->q);
669 sc->sc_is_open[endpt] = 0;
670 UGEN_DEV_CLOSE(dev, sc);
676 ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
678 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
680 char buf[UGEN_BBSIZE];
681 usbd_xfer_handle xfer;
684 int error = 0, doneone = 0;
685 u_char buffer[UGEN_CHUNK];
687 DPRINTFN(5, ("%s: ugenread: %d\n", device_get_nameunit(sc->sc_dev), endpt));
692 if (endpt == USB_CONTROL_ENDPOINT)
696 if (sce->edesc == NULL) {
697 printf("ugenread: no edesc\n");
700 if (sce->pipeh == NULL) {
701 printf("ugenread: no pipe\n");
706 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
708 /* Block until activity occurred. */
710 while (sce->q.c_cc == 0) {
711 if (flag & O_NONBLOCK) {
713 return (EWOULDBLOCK);
715 sce->state |= UGEN_ASLP;
716 DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
717 error = tsleep(sce, PZERO | PCATCH, "ugenri",
718 (sce->timeout * hz + 999) / 1000);
719 sce->state &= ~UGEN_ASLP;
720 DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
723 if (error == EAGAIN) {
724 error = 0; /* timeout, return 0 bytes */
732 /* Transfer as many chunks as possible. */
733 while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) {
734 n = min(sce->q.c_cc, uio->uio_resid);
735 if (n > sizeof(buffer))
738 /* Remove a small chunk from the input queue. */
739 q_to_b(&sce->q, buffer, n);
740 DPRINTFN(5, ("ugenread: got %d chars\n", n));
742 /* Copy the data to the user process. */
743 error = uiomove(buffer, n, uio);
749 xfer = usbd_alloc_xfer(sc->sc_udev);
752 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0 ||
754 DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
757 err = usbd_bulk_transfer(
759 sce->state & UGEN_SHORT_OK ?
760 USBD_SHORT_XFER_OK : 0,
761 sce->timeout, buf, &tn, "ugenrb");
763 if (err == USBD_INTERRUPTED)
765 else if (err == USBD_TIMEOUT)
771 DPRINTFN(1, ("ugenread: got %d bytes\n", tn));
772 error = uiomove(buf, tn, uio);
776 usbd_free_xfer(xfer);
780 while (sce->cur == sce->fill) {
781 if (flag & O_NONBLOCK) {
783 return (EWOULDBLOCK);
785 sce->state |= UGEN_ASLP;
786 DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
787 error = tsleep(sce, PZERO | PCATCH, "ugenri",
788 (sce->timeout * hz + 999) / 1000);
789 sce->state &= ~UGEN_ASLP;
790 DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
793 if (error == EAGAIN) {
794 error = 0; /* timeout, return 0 bytes */
801 while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) {
802 if (sce->fill > sce->cur)
803 n = min(sce->fill - sce->cur, uio->uio_resid);
805 n = min(sce->limit - sce->cur, uio->uio_resid);
807 DPRINTFN(5, ("ugenread: isoc got %d chars\n", n));
809 /* Copy the data to the user process. */
810 error = uiomove(sce->cur, n, uio);
814 if(sce->cur >= sce->limit)
815 sce->cur = sce->ibuf;
828 ugenread(struct cdev *dev, struct uio *uio, int flag)
830 int endpt = UGENENDPOINT(dev);
831 struct ugen_softc *sc;
834 sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
839 UGEN_DEV_REF(dev, sc);
840 error = ugen_do_read(sc, endpt, uio, flag);
841 UGEN_DEV_RELE(dev, sc);
846 ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
848 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
850 int error = 0, doneone = 0;
851 char buf[UGEN_BBSIZE];
852 usbd_xfer_handle xfer;
855 DPRINTFN(5, ("%s: ugenwrite: %d\n", device_get_nameunit(sc->sc_dev), endpt));
860 if (endpt == USB_CONTROL_ENDPOINT)
864 if (sce->edesc == NULL) {
865 printf("ugenwrite: no edesc\n");
868 if (sce->pipeh == NULL) {
869 printf("ugenwrite: no pipe\n");
874 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
876 xfer = usbd_alloc_xfer(sc->sc_udev);
879 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0 ||
882 error = uiomove(buf, n, uio);
885 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
886 err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
887 sce->timeout, buf, &n,"ugenwb");
889 if (err == USBD_INTERRUPTED)
891 else if (err == USBD_TIMEOUT)
898 usbd_free_xfer(xfer);
901 xfer = usbd_alloc_xfer(sc->sc_udev);
904 while ((n = min(UGETW(sce->edesc->wMaxPacketSize),
905 uio->uio_resid)) != 0 || !doneone) {
907 error = uiomove(buf, n, uio);
910 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
911 err = usbd_intr_transfer(xfer, sce->pipeh, 0,
912 sce->timeout, buf, &n, "ugenwi");
914 if (err == USBD_INTERRUPTED)
916 else if (err == USBD_TIMEOUT)
923 usbd_free_xfer(xfer);
932 ugenwrite(struct cdev *dev, struct uio *uio, int flag)
934 int endpt = UGENENDPOINT(dev);
935 struct ugen_softc *sc;
938 sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
943 UGEN_DEV_REF(dev, sc);
944 error = ugen_do_write(sc, endpt, uio, flag);
945 UGEN_DEV_RELE(dev, sc);
950 ugenpurge(struct cdev *dev)
952 int endpt = UGENENDPOINT(dev);
953 struct ugen_endpoint *sce;
954 struct ugen_softc *sc;
956 if (endpt == USB_CONTROL_ENDPOINT)
958 sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
959 sce = &sc->sc_endpoints[endpt][IN];
961 usbd_abort_pipe(sce->pipeh);
962 if (sce->state & UGEN_ASLP) {
963 DPRINTFN(5, ("ugenpurge: waking %p\n", sce));
966 selwakeuppri(&sce->rsel, PZERO);
968 sce = &sc->sc_endpoints[endpt][OUT];
970 usbd_abort_pipe(sce->pipeh);
971 if (sce->state & UGEN_ASLP) {
972 DPRINTFN(5, ("ugenpurge: waking %p\n", sce));
975 selwakeuppri(&sce->rsel, PZERO);
979 ugen_detach(device_t self)
981 struct ugen_softc *sc = device_get_softc(self);
982 struct ugen_endpoint *sce;
985 DPRINTF(("ugen_detach: sc=%p\n", sc));
988 /* Abort all pipes. Causes processes waiting for transfer to wake. */
989 for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
990 for (dir = OUT; dir <= IN; dir++) {
991 sce = &sc->sc_endpoints[i][dir];
993 usbd_abort_pipe(sce->pipeh);
994 selwakeuppri(&sce->rsel, PZERO);
998 /* destroy the device for the control endpoint */
999 destroy_dev(sc->dev);
1000 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
1005 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
1007 struct ugen_endpoint *sce = addr;
1008 /*struct ugen_softc *sc = sce->sc;*/
1012 if (status == USBD_CANCELLED)
1015 if (status != USBD_NORMAL_COMPLETION) {
1016 DPRINTF(("ugenintr: status=%d\n", status));
1017 if (status == USBD_STALLED)
1018 usbd_clear_endpoint_stall_async(sce->pipeh);
1022 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1025 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
1026 xfer, status, count));
1027 DPRINTFN(5, (" data = %02x %02x %02x\n",
1028 ibuf[0], ibuf[1], ibuf[2]));
1030 (void)b_to_q(ibuf, count, &sce->q);
1032 if (sce->state & UGEN_ASLP) {
1033 sce->state &= ~UGEN_ASLP;
1034 DPRINTFN(5, ("ugen_intr: waking %p\n", sce));
1037 selwakeuppri(&sce->rsel, PZERO);
1041 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
1044 struct isoreq *req = addr;
1045 struct ugen_endpoint *sce = req->sce;
1049 /* Return if we are aborting. */
1050 if (status == USBD_CANCELLED)
1053 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1054 DPRINTFN(5,("ugen_isoc_rintr: xfer %td, count=%d\n", req - sce->isoreqs,
1057 /* throw away oldest input if the buffer is full */
1058 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) {
1060 if(sce->cur >= sce->limit)
1061 sce->cur = sce->ibuf + (sce->limit - sce->cur);
1062 DPRINTF(("ugen_isoc_rintr: throwing away %d bytes\n",
1066 isize = UGETW(sce->edesc->wMaxPacketSize);
1067 for (i = 0; i < UGEN_NISORFRMS; i++) {
1068 u_int32_t actlen = req->sizes[i];
1069 char const *buf = (char const *)req->dmabuf + isize * i;
1071 /* copy data to buffer */
1072 while (actlen > 0) {
1073 n = min(actlen, sce->limit - sce->fill);
1074 memcpy(sce->fill, buf, n);
1079 if(sce->fill == sce->limit)
1080 sce->fill = sce->ibuf;
1083 /* setup size for next transfer */
1084 req->sizes[i] = isize;
1087 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS,
1088 USBD_NO_COPY, ugen_isoc_rintr);
1089 (void)usbd_transfer(xfer);
1091 if (sce->state & UGEN_ASLP) {
1092 sce->state &= ~UGEN_ASLP;
1093 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce));
1096 selwakeuppri(&sce->rsel, PZERO);
1100 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno)
1102 usbd_interface_handle iface;
1103 usb_endpoint_descriptor_t *ed;
1105 struct ugen_endpoint *sce, **sce_cache;
1106 u_int8_t niface, nendpt, nendpt_cache, endptno, endpt;
1109 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
1111 err = usbd_interface_count(sc->sc_udev, &niface);
1114 if (ifaceidx < 0 || ifaceidx >= niface)
1115 return (USBD_INVAL);
1117 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
1120 err = usbd_endpoint_count(iface, &nendpt);
1124 /* store an array of endpoint descriptors to clear if the interface
1125 * change succeeds - these aren't available afterwards */
1126 sce_cache = malloc(sizeof(struct ugen_endpoint *) * nendpt, M_TEMP,
1128 nendpt_cache = nendpt;
1130 for (endptno = 0; endptno < nendpt; endptno++) {
1131 ed = usbd_interface2endpoint_descriptor(iface,endptno);
1132 endpt = ed->bEndpointAddress;
1133 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
1134 sce_cache[endptno] = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
1137 /* change setting */
1138 err = usbd_set_interface(iface, altno);
1140 free(sce_cache, M_TEMP);
1143 err = usbd_endpoint_count(iface, &nendpt);
1145 panic("ugen_set_interface: endpoint count failed");
1147 /* destroy the existing devices, we remake the new ones in a moment */
1148 ugen_destroy_devnodes(sc);
1150 /* now we can clear the old interface's ugen_endpoints */
1151 for (endptno = 0; endptno < nendpt_cache; endptno++) {
1152 sce = sce_cache[endptno];
1157 free(sce_cache, M_TEMP);
1159 /* set the new interface's ugen_endpoints */
1160 for (endptno = 0; endptno < nendpt; endptno++) {
1161 ed = usbd_interface2endpoint_descriptor(iface,endptno);
1162 endpt = ed->bEndpointAddress;
1163 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
1164 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
1170 /* make the new devices */
1171 ugen_make_devnodes(sc);
1176 /* Retrieve a complete descriptor for a certain device and index. */
1177 static usb_config_descriptor_t *
1178 ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp)
1180 usb_config_descriptor_t *cdesc, *tdesc, cdescr;
1184 if (index == USB_CURRENT_CONFIG_INDEX) {
1185 tdesc = usbd_get_config_descriptor(sc->sc_udev);
1186 len = UGETW(tdesc->wTotalLength);
1189 cdesc = malloc(len, M_TEMP, M_WAITOK);
1190 memcpy(cdesc, tdesc, len);
1191 DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
1193 err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
1196 len = UGETW(cdescr.wTotalLength);
1197 DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
1200 cdesc = malloc(len, M_TEMP, M_WAITOK);
1201 err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
1203 free(cdesc, M_TEMP);
1211 ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx)
1213 usbd_interface_handle iface;
1216 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
1219 return (usbd_get_interface_altindex(iface));
1223 ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
1224 caddr_t addr, int flag, struct thread *p)
1226 struct ugen_endpoint *sce;
1228 usbd_interface_handle iface;
1229 struct usb_config_desc *cd;
1230 usb_config_descriptor_t *cdesc;
1231 struct usb_interface_desc *id;
1232 usb_interface_descriptor_t *idesc;
1233 struct usb_endpoint_desc *ed;
1234 usb_endpoint_descriptor_t *edesc;
1235 struct usb_alt_interface *ai;
1236 struct usb_string_desc *si;
1239 DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd));
1246 /* All handled in the upper FS layer. */
1248 case USB_SET_SHORT_XFER:
1249 if (endpt == USB_CONTROL_ENDPOINT)
1251 /* This flag only affects read */
1252 sce = &sc->sc_endpoints[endpt][IN];
1254 if (sce->pipeh == NULL) {
1255 printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n");
1260 sce->state |= UGEN_SHORT_OK;
1262 sce->state &= ~UGEN_SHORT_OK;
1264 case USB_SET_TIMEOUT:
1265 sce = &sc->sc_endpoints[endpt][IN];
1266 sce->timeout = *(int *)addr;
1267 sce = &sc->sc_endpoints[endpt][OUT];
1268 sce->timeout = *(int *)addr;
1274 if (endpt != USB_CONTROL_ENDPOINT)
1280 ugendebug = *(int *)addr;
1283 case USB_GET_CONFIG:
1284 err = usbd_get_config(sc->sc_udev, &conf);
1287 *(int *)addr = conf;
1289 case USB_SET_CONFIG:
1290 if (!(flag & FWRITE))
1292 err = ugen_set_config(sc, *(int *)addr);
1294 case USBD_NORMAL_COMPLETION:
1295 ugen_make_devnodes(sc);
1303 case USB_GET_ALTINTERFACE:
1304 ai = (struct usb_alt_interface *)addr;
1305 err = usbd_device2interface_handle(sc->sc_udev,
1306 ai->uai_interface_index, &iface);
1309 idesc = usbd_get_interface_descriptor(iface);
1312 ai->uai_alt_no = idesc->bAlternateSetting;
1314 case USB_SET_ALTINTERFACE:
1315 if (!(flag & FWRITE))
1317 ai = (struct usb_alt_interface *)addr;
1318 err = usbd_device2interface_handle(sc->sc_udev,
1319 ai->uai_interface_index, &iface);
1322 err = ugen_set_interface(sc, ai->uai_interface_index,
1327 case USB_GET_NO_ALT:
1328 ai = (struct usb_alt_interface *)addr;
1329 cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0);
1332 idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0);
1333 if (idesc == NULL) {
1334 free(cdesc, M_TEMP);
1337 ai->uai_alt_no = usbd_get_no_alts(cdesc,
1338 idesc->bInterfaceNumber);
1339 free(cdesc, M_TEMP);
1341 case USB_GET_DEVICE_DESC:
1342 *(usb_device_descriptor_t *)addr =
1343 *usbd_get_device_descriptor(sc->sc_udev);
1345 case USB_GET_CONFIG_DESC:
1346 cd = (struct usb_config_desc *)addr;
1347 cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0);
1350 cd->ucd_desc = *cdesc;
1351 free(cdesc, M_TEMP);
1353 case USB_GET_INTERFACE_DESC:
1354 id = (struct usb_interface_desc *)addr;
1355 cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0);
1358 if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX &&
1359 id->uid_alt_index == USB_CURRENT_ALT_INDEX)
1360 alt = ugen_get_alt_index(sc, id->uid_interface_index);
1362 alt = id->uid_alt_index;
1363 idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt);
1364 if (idesc == NULL) {
1365 free(cdesc, M_TEMP);
1368 id->uid_desc = *idesc;
1369 free(cdesc, M_TEMP);
1371 case USB_GET_ENDPOINT_DESC:
1372 ed = (struct usb_endpoint_desc *)addr;
1373 cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0);
1376 if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX &&
1377 ed->ued_alt_index == USB_CURRENT_ALT_INDEX)
1378 alt = ugen_get_alt_index(sc, ed->ued_interface_index);
1380 alt = ed->ued_alt_index;
1381 edesc = usbd_find_edesc(cdesc, ed->ued_interface_index,
1382 alt, ed->ued_endpoint_index);
1383 if (edesc == NULL) {
1384 free(cdesc, M_TEMP);
1387 ed->ued_desc = *edesc;
1388 free(cdesc, M_TEMP);
1390 case USB_GET_FULL_DESC:
1395 struct usb_full_desc *fd = (struct usb_full_desc *)addr;
1398 cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len);
1399 if (len > fd->ufd_size)
1401 iov.iov_base = (caddr_t)fd->ufd_data;
1405 uio.uio_resid = len;
1407 uio.uio_segflg = UIO_USERSPACE;
1408 uio.uio_rw = UIO_READ;
1410 error = uiomove((void *)cdesc, len, &uio);
1411 free(cdesc, M_TEMP);
1414 case USB_GET_STRING_DESC: {
1416 si = (struct usb_string_desc *)addr;
1417 err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
1418 si->usd_language_id, &si->usd_desc, &len);
1423 case USB_DO_REQUEST:
1425 struct usb_ctl_request *ur = (void *)addr;
1426 int len = UGETW(ur->ucr_request.wLength);
1432 if (!(flag & FWRITE))
1434 /* Avoid requests that would damage the bus integrity. */
1435 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1436 ur->ucr_request.bRequest == UR_SET_ADDRESS) ||
1437 (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1438 ur->ucr_request.bRequest == UR_SET_CONFIG) ||
1439 (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE &&
1440 ur->ucr_request.bRequest == UR_SET_INTERFACE))
1443 if (len < 0 || len > 32767)
1446 iov.iov_base = (caddr_t)ur->ucr_data;
1450 uio.uio_resid = len;
1452 uio.uio_segflg = UIO_USERSPACE;
1454 ur->ucr_request.bmRequestType & UT_READ ?
1455 UIO_READ : UIO_WRITE;
1457 ptr = malloc(len, M_TEMP, M_WAITOK);
1458 if (uio.uio_rw == UIO_WRITE) {
1459 error = uiomove(ptr, len, &uio);
1464 sce = &sc->sc_endpoints[endpt][IN];
1465 err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request,
1466 ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout);
1472 if (uio.uio_rw == UIO_READ) {
1473 error = uiomove(ptr, len, &uio);
1483 case USB_GET_DEVICEINFO:
1484 usbd_fill_deviceinfo(sc->sc_udev,
1485 (struct usb_device_info *)addr, 1);
1487 case USB_RESET_DEVICE:
1488 err = usbd_reset_device(sc->sc_udev);
1499 ugenioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
1502 int endpt = UGENENDPOINT(dev);
1503 struct ugen_softc *sc;
1506 sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
1511 UGEN_DEV_REF(dev, sc);
1512 error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
1513 UGEN_DEV_RELE(dev, sc);
1518 ugenpoll(struct cdev *dev, int events, struct thread *p)
1520 struct ugen_softc *sc;
1521 struct ugen_endpoint *sce_in, *sce_out;
1522 usb_endpoint_descriptor_t *edesc;
1526 sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
1529 return ((events & (POLLIN | POLLOUT | POLLRDNORM |
1530 POLLWRNORM)) | POLLHUP);
1531 /* Do not allow to poll a control endpoint */
1532 if (UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT)
1533 return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1535 sce_in = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1536 sce_out = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT];
1537 edesc = (sce_in->edesc != NULL) ? sce_in->edesc : sce_out->edesc;
1538 KASSERT(edesc != NULL, ("ugenpoll: NULL edesc"));
1539 if (sce_in->edesc == NULL || sce_in->pipeh == NULL)
1541 if (sce_out->edesc == NULL || sce_out->pipeh == NULL)
1545 switch (edesc->bmAttributes & UE_XFERTYPE) {
1547 if (sce_in != NULL && (events & (POLLIN | POLLRDNORM))) {
1548 if (sce_in->q.c_cc > 0)
1549 revents |= events & (POLLIN | POLLRDNORM);
1551 selrecord(p, &sce_in->rsel);
1553 if (sce_out != NULL && (events & (POLLOUT | POLLWRNORM))) {
1554 if (sce_out->q.c_cc > 0)
1555 revents |= events & (POLLOUT | POLLWRNORM);
1557 selrecord(p, &sce_out->rsel);
1560 case UE_ISOCHRONOUS:
1561 if (sce_in != NULL && (events & (POLLIN | POLLRDNORM))) {
1562 if (sce_in->cur != sce_in->fill)
1563 revents |= events & (POLLIN | POLLRDNORM);
1565 selrecord(p, &sce_in->rsel);
1567 if (sce_out != NULL && (events & (POLLOUT | POLLWRNORM))) {
1568 if (sce_out->cur != sce_out->fill)
1569 revents |= events & (POLLOUT | POLLWRNORM);
1571 selrecord(p, &sce_out->rsel);
1576 * We have no easy way of determining if a read will
1577 * yield any data or a write will happen.
1578 * Pretend they will.
1581 (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
1590 DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, usbd_driver_load, 0);