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