58f2d0ec03878f6be7500d2267f489200d1b4a8d
[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/event.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_kqfilter_t ugenkqfilter;
143
144 static void ugen_filt_detach(struct knote *);
145 static int ugen_filt_read(struct knote *, long);
146 static int ugen_filt_write(struct knote *, long);
147
148 #define UGEN_CDEV_MAJOR 114
149
150 static struct dev_ops ugen_ops = {
151         { "ugen", UGEN_CDEV_MAJOR, D_KQFILTER },
152         .d_open =       ugenopen,
153         .d_close =      ugenclose,
154         .d_read =       ugenread,
155         .d_write =      ugenwrite,
156         .d_ioctl =      ugenioctl,
157         .d_kqfilter =   ugenkqfilter
158 };
159
160 static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr,
161                             usbd_status status);
162 static void ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
163                             usbd_status status);
164 static int ugen_do_read(struct ugen_softc *, int, struct uio *, int);
165 static int ugen_do_write(struct ugen_softc *, int, struct uio *, int);
166 static int ugen_do_ioctl(struct ugen_softc *, int, u_long,
167                             caddr_t, int);
168 static void ugen_make_devnodes(struct ugen_softc *sc);
169 static void ugen_destroy_devnodes(struct ugen_softc *sc);
170 static int ugen_set_config(struct ugen_softc *sc, int configno);
171 static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc,
172                                                 int index, int *lenp);
173 static usbd_status ugen_set_interface(struct ugen_softc *, int, int);
174 static int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx);
175
176 #define UGENUNIT(n) ((lminor(n) >> 4) & 0xff)
177 #define UGENENDPOINT(n) (minor(n) & 0xf)
178 #define UGENMINOR(u, e) (((u & 0xf) << 4) | ((u & 0xf0) << 12) | (e))
179 #define UGENUNITMASK    0xffff00f0
180
181 static device_probe_t ugen_match;
182 static device_attach_t ugen_attach;
183 static device_detach_t ugen_detach;
184
185 static devclass_t ugen_devclass;
186
187 static kobj_method_t ugen_methods[] = {
188         DEVMETHOD(device_probe, ugen_match),
189         DEVMETHOD(device_attach, ugen_attach),
190         DEVMETHOD(device_detach, ugen_detach),
191         {0,0}
192 };
193
194 static driver_t ugen_driver = {
195         "ugen",
196         ugen_methods,
197         sizeof(struct ugen_softc)
198 };
199
200 MODULE_DEPEND(ugen, usb, 1, 1, 1);
201
202 static int
203 ugen_match(device_t self)
204 {
205         struct usb_attach_arg *uaa = device_get_ivars(self);
206
207 #if 0
208         if (uaa->matchlvl)
209                 return (uaa->matchlvl);
210 #endif
211         if (uaa->usegeneric)
212                 return (UMATCH_GENERIC);
213         else
214                 return (UMATCH_NONE);
215 }
216
217 static int
218 ugen_attach(device_t self)
219 {
220         struct ugen_softc *sc = device_get_softc(self);
221         struct usb_attach_arg *uaa = device_get_ivars(self);
222         usbd_device_handle udev;
223         usbd_status err;
224         int conf;
225
226         sc->sc_dev = self;
227         sc->sc_udev = udev = uaa->device;
228
229         memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
230
231         /* First set configuration index 0, the default one for ugen. */
232         err = usbd_set_config_index(udev, 0, 0);
233         if (err) {
234                 kprintf("%s: setting configuration index 0 failed\n",
235                        device_get_nameunit(sc->sc_dev));
236                 sc->sc_dying = 1;
237                 return ENXIO;
238         }
239         conf = usbd_get_config_descriptor(udev)->bConfigurationValue;
240
241         /* Set up all the local state for this configuration. */
242         err = ugen_set_config(sc, conf);
243         if (err) {
244                 kprintf("%s: setting configuration %d failed\n",
245                        device_get_nameunit(sc->sc_dev), conf);
246                 sc->sc_dying = 1;
247                 return ENXIO;
248         }
249
250         /* the main device, ctrl endpoint */
251         make_dev(&ugen_ops, UGENMINOR(device_get_unit(sc->sc_dev), 0),
252                  UID_ROOT, GID_OPERATOR, 0644,
253                  "%s", device_get_nameunit(sc->sc_dev));
254
255         usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
256         return 0;
257 }
258
259 static void
260 ugen_make_devnodes(struct ugen_softc *sc)
261 {
262         int endptno;
263         cdev_t dev;
264
265         for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
266                 if (sc->sc_endpoints[endptno][IN].sc != NULL ||
267                     sc->sc_endpoints[endptno][OUT].sc != NULL ) {
268                         /* endpt can be 0x81 and 0x01, representing
269                          * endpoint address 0x01 and IN/OUT directions.
270                          * We map both endpts to the same device,
271                          * IN is reading from it, OUT is writing to it.
272                          *
273                          * In the if clause above we check whether one
274                          * of the structs is populated.
275                          */
276                         dev = make_dev(&ugen_ops,
277                                 UGENMINOR(device_get_unit(sc->sc_dev), endptno),
278                                 UID_ROOT, GID_OPERATOR, 0644,
279                                 "%s.%d",
280                                 device_get_nameunit(sc->sc_dev), endptno);
281                         if (sc->sc_endpoints[endptno][IN].sc != NULL) {
282                                 reference_dev(dev);
283                                 if (sc->sc_endpoints[endptno][IN].dev)
284                                         release_dev(sc->sc_endpoints[endptno][IN].dev);
285                                 sc->sc_endpoints[endptno][IN].dev = dev;
286                         }
287                         if (sc->sc_endpoints[endptno][OUT].sc != NULL) {
288                                 reference_dev(dev);
289                                 if (sc->sc_endpoints[endptno][OUT].dev)
290                                         release_dev(sc->sc_endpoints[endptno][OUT].dev);
291                                 sc->sc_endpoints[endptno][OUT].dev = dev;
292                         }
293                 }
294         }
295 }
296
297 static void
298 ugen_destroy_devnodes(struct ugen_softc *sc)
299 {
300         int endptno, prev_sc_dying;
301         cdev_t dev;
302
303         prev_sc_dying = sc->sc_dying;
304         sc->sc_dying = 1;
305
306         /* destroy all devices for the other (existing) endpoints as well */
307         for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
308                 if (sc->sc_endpoints[endptno][IN].sc != NULL ||
309                     sc->sc_endpoints[endptno][OUT].sc != NULL ) {
310                         /* endpt can be 0x81 and 0x01, representing
311                          * endpoint address 0x01 and IN/OUT directions.
312                          * We map both endpoint addresses to the same device,
313                          * IN is reading from it, OUT is writing to it.
314                          *
315                          * In the if clause above we check whether one
316                          * of the structs is populated.
317                          */
318                         dev = sc->sc_endpoints[endptno][IN].dev;
319                         if (dev != NULL) {
320                                 destroy_dev(dev);
321                                 sc->sc_endpoints[endptno][IN].dev = NULL;
322                         }
323                         dev = sc->sc_endpoints[endptno][OUT].dev;
324                         if (dev != NULL) {
325                                 destroy_dev(dev);
326                                 sc->sc_endpoints[endptno][OUT].dev = NULL;
327                         }
328                 }
329         }
330         sc->sc_dying = prev_sc_dying;
331 }
332
333 static int
334 ugen_set_config(struct ugen_softc *sc, int configno)
335 {
336         usbd_device_handle dev = sc->sc_udev;
337         usbd_interface_handle iface;
338         usb_endpoint_descriptor_t *ed;
339         struct ugen_endpoint *sce;
340         u_int8_t niface, nendpt;
341         int ifaceno, endptno, endpt;
342         usbd_status err;
343         int dir;
344
345         DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
346                     device_get_nameunit(sc->sc_dev), configno, sc));
347
348         ugen_destroy_devnodes(sc);
349
350         /* We start at 1, not 0, because we don't care whether the
351          * control endpoint is open or not. It is always present.
352          */
353         for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
354                 if (sc->sc_is_open[endptno]) {
355                         DPRINTFN(1,
356                              ("ugen_set_config: %s - endpoint %d is open\n",
357                               device_get_nameunit(sc->sc_dev), endptno));
358                         return (USBD_IN_USE);
359                 }
360         }
361
362         /* Avoid setting the current value. */
363         if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) {
364                 err = usbd_set_config_no(dev, configno, 1);
365                 if (err)
366                         return (err);
367         }
368
369         err = usbd_interface_count(dev, &niface);
370         if (err)
371                 return (err);
372         memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
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);
376                 if (err)
377                         return (err);
378                 err = usbd_endpoint_count(iface, &nendpt);
379                 if (err)
380                         return (err);
381                 for (endptno = 0; endptno < nendpt; endptno++) {
382                         ed = usbd_interface2endpoint_descriptor(iface,endptno);
383                         endpt = ed->bEndpointAddress;
384                         dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
385                         sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
386                         DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x"
387                                     "(%d,%d), sce=%p\n",
388                                     endptno, endpt, UE_GET_ADDR(endpt),
389                                     UE_GET_DIR(endpt), sce));
390                         sce->sc = sc;
391                         sce->edesc = ed;
392                         sce->iface = iface;
393                 }
394         }
395
396         ugen_make_devnodes(sc);
397
398         return (USBD_NORMAL_COMPLETION);
399 }
400
401 int
402 ugenopen(struct dev_open_args *ap)
403 {
404         cdev_t dev = ap->a_head.a_dev;
405         struct ugen_softc *sc;
406         int unit = UGENUNIT(dev);
407         int endpt = UGENENDPOINT(dev);
408         usb_endpoint_descriptor_t *edesc;
409         struct ugen_endpoint *sce;
410         int dir, isize;
411         usbd_status err;
412         usbd_xfer_handle xfer;
413         void *buf;
414         int i, j;
415
416         sc = devclass_get_softc(ugen_devclass, unit);
417         if (sc == NULL)
418                 return (ENXIO);
419
420         DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
421                      ap->a_oflags, ap->a_devtype, unit, endpt));
422
423         if (sc->sc_dying)
424                 return (ENXIO);
425
426         if (sc->sc_is_open[endpt])
427                 return (EBUSY);
428
429         if (endpt == USB_CONTROL_ENDPOINT) {
430                 sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
431                 return (0);
432         }
433
434         /* Make sure there are pipes for all directions. */
435         for (dir = OUT; dir <= IN; dir++) {
436                 if (ap->a_oflags & (dir == OUT ? FWRITE : FREAD)) {
437                         sce = &sc->sc_endpoints[endpt][dir];
438                         if (sce == 0 || sce->edesc == 0)
439                                 return (ENXIO);
440                 }
441         }
442
443         /* Actually open the pipes. */
444         /* XXX Should back out properly if it fails. */
445         for (dir = OUT; dir <= IN; dir++) {
446                 if (!(ap->a_oflags & (dir == OUT ? FWRITE : FREAD)))
447                         continue;
448                 sce = &sc->sc_endpoints[endpt][dir];
449                 sce->state = 0;
450                 sce->timeout = USBD_NO_TIMEOUT;
451                 DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
452                              sc, endpt, dir, sce));
453                 edesc = sce->edesc;
454                 switch (edesc->bmAttributes & UE_XFERTYPE) {
455                 case UE_INTERRUPT:
456                         if (dir == OUT) {
457                                 err = usbd_open_pipe(sce->iface,
458                                     edesc->bEndpointAddress, 0, &sce->pipeh);
459                                 if (err)
460                                         return (EIO);
461                                 break;
462                         }
463                         isize = UGETW(edesc->wMaxPacketSize);
464                         if (isize == 0) /* shouldn't happen */
465                                 return (EINVAL);
466                         sce->ibuf = kmalloc(isize, M_USBDEV, M_WAITOK);
467                         DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
468                                      endpt, isize));
469                         if ((clist_alloc_cblocks(&sce->q, UGEN_IBSIZE,
470                                                  UGEN_IBSIZE), 0) == -1)
471                                 return (ENOMEM);
472                         err = usbd_open_pipe_intr(sce->iface,
473                                 edesc->bEndpointAddress,
474                                 USBD_SHORT_XFER_OK, &sce->pipeh, sce,
475                                 sce->ibuf, isize, ugenintr,
476                                 USBD_DEFAULT_INTERVAL);
477                         if (err) {
478                                 kfree(sce->ibuf, M_USBDEV);
479                                 clist_free_cblocks(&sce->q);
480                                 return (EIO);
481                         }
482                         DPRINTFN(5, ("ugenopen: interrupt open done\n"));
483                         break;
484                 case UE_BULK:
485                         err = usbd_open_pipe(sce->iface,
486                                   edesc->bEndpointAddress, 0, &sce->pipeh);
487                         if (err)
488                                 return (EIO);
489                         break;
490                 case UE_ISOCHRONOUS:
491                         if (dir == OUT)
492                                 return (EINVAL);
493                         isize = UGETW(edesc->wMaxPacketSize);
494                         if (isize == 0) /* shouldn't happen */
495                                 return (EINVAL);
496                         sce->ibuf = kmalloc(isize * UGEN_NISOFRAMES,
497                                 M_USBDEV, M_WAITOK);
498                         sce->cur = sce->fill = sce->ibuf;
499                         sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES;
500                         DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n",
501                                      endpt, isize));
502                         err = usbd_open_pipe(sce->iface,
503                                   edesc->bEndpointAddress, 0, &sce->pipeh);
504                         if (err) {
505                                 kfree(sce->ibuf, M_USBDEV);
506                                 return (EIO);
507                         }
508                         for(i = 0; i < UGEN_NISOREQS; ++i) {
509                                 sce->isoreqs[i].sce = sce;
510                                 xfer = usbd_alloc_xfer(sc->sc_udev);
511                                 if (xfer == 0)
512                                         goto bad;
513                                 sce->isoreqs[i].xfer = xfer;
514                                 buf = usbd_alloc_buffer
515                                         (xfer, isize * UGEN_NISORFRMS);
516                                 if (buf == 0) {
517                                         i++;
518                                         goto bad;
519                                 }
520                                 sce->isoreqs[i].dmabuf = buf;
521                                 for(j = 0; j < UGEN_NISORFRMS; ++j)
522                                         sce->isoreqs[i].sizes[j] = isize;
523                                 usbd_setup_isoc_xfer
524                                         (xfer, sce->pipeh, &sce->isoreqs[i],
525                                          sce->isoreqs[i].sizes,
526                                          UGEN_NISORFRMS, USBD_NO_COPY,
527                                          ugen_isoc_rintr);
528                                 (void)usbd_transfer(xfer);
529                         }
530                         DPRINTFN(5, ("ugenopen: isoc open done\n"));
531                         break;
532                 bad:
533                         while (--i >= 0) /* implicit buffer free */
534                                 usbd_free_xfer(sce->isoreqs[i].xfer);
535                         return (ENOMEM);
536                 case UE_CONTROL:
537                         sce->timeout = USBD_DEFAULT_TIMEOUT;
538                         return (EINVAL);
539                 }
540         }
541         sc->sc_is_open[endpt] = 1;
542         return (0);
543 }
544
545 int
546 ugenclose(struct dev_close_args *ap)
547 {
548         cdev_t dev = ap->a_head.a_dev;
549         int endpt = UGENENDPOINT(dev);
550         struct ugen_softc *sc;
551         struct ugen_endpoint *sce;
552         int dir;
553         int i;
554
555         sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
556
557         DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
558                      ap->a_fflag, ap->a_devtype, UGENUNIT(dev), endpt));
559
560 #ifdef DIAGNOSTIC
561         if (!sc->sc_is_open[endpt]) {
562                 kprintf("ugenclose: not open\n");
563                 return (EINVAL);
564         }
565 #endif
566
567         if (endpt == USB_CONTROL_ENDPOINT) {
568                 DPRINTFN(5, ("ugenclose: close control\n"));
569                 sc->sc_is_open[endpt] = 0;
570                 return (0);
571         }
572
573         for (dir = OUT; dir <= IN; dir++) {
574                 if (!(ap->a_fflag & (dir == OUT ? FWRITE : FREAD)))
575                         continue;
576                 sce = &sc->sc_endpoints[endpt][dir];
577                 if (sce->pipeh == NULL)
578                         continue;
579                 DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
580                              endpt, dir, sce));
581
582                 usbd_abort_pipe(sce->pipeh);
583                 usbd_close_pipe(sce->pipeh);
584                 sce->pipeh = NULL;
585
586                 switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
587                 case UE_INTERRUPT:
588                         ndflush(&sce->q, sce->q.c_cc);
589                         clist_free_cblocks(&sce->q);
590                         break;
591                 case UE_ISOCHRONOUS:
592                         for (i = 0; i < UGEN_NISOREQS; ++i)
593                                 usbd_free_xfer(sce->isoreqs[i].xfer);
594                 default:
595                         break;
596                 }
597
598                 if (sce->ibuf != NULL) {
599                         kfree(sce->ibuf, M_USBDEV);
600                         sce->ibuf = NULL;
601                         clist_free_cblocks(&sce->q);
602                 }
603         }
604         sc->sc_is_open[endpt] = 0;
605
606         return (0);
607 }
608
609 static int
610 ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
611 {
612         struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
613         u_int32_t n, tn;
614         char *buf;
615         usbd_xfer_handle xfer;
616         usbd_status err;
617         int error = 0;
618         int ugen_bbsize;
619         u_char buffer[UGEN_CHUNK];
620
621         DPRINTFN(5, ("%s: ugenread: %d\n", device_get_nameunit(sc->sc_dev), endpt));
622
623         if (sc->sc_dying)
624                 return (EIO);
625
626         if (endpt == USB_CONTROL_ENDPOINT)
627                 return (ENODEV);
628
629 #ifdef DIAGNOSTIC
630         if (sce->edesc == NULL) {
631                 kprintf("ugenread: no edesc\n");
632                 return (EIO);
633         }
634         if (sce->pipeh == NULL) {
635                 kprintf("ugenread: no pipe\n");
636                 return (EIO);
637         }
638 #endif
639
640         buf = getugenbuf(ugen_bufsize, &ugen_bbsize);
641
642         switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
643         case UE_INTERRUPT:
644                 /* Block until activity occurred. */
645                 crit_enter();
646                 while (sce->q.c_cc == 0) {
647                         if (flag & IO_NDELAY) {
648                                 crit_exit();
649                                 error = EWOULDBLOCK;
650                                 goto done;
651                         }
652                         sce->state |= UGEN_ASLP;
653                         DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
654                         error = tsleep(sce, PCATCH, "ugenri",
655                             (sce->timeout * hz + 999) / 1000);
656                         sce->state &= ~UGEN_ASLP;
657                         DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
658                         if (sc->sc_dying)
659                                 error = EIO;
660                         if (error == EAGAIN) {
661                                 error = 0;      /* timeout, return 0 bytes */
662                                 break;
663                         }
664                         if (error)
665                                 break;
666                 }
667                 crit_exit();
668
669                 /* Transfer as many chunks as possible. */
670                 while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) {
671                         n = szmin(sce->q.c_cc, uio->uio_resid);
672                         if (n > sizeof(buffer))
673                                 n = sizeof(buffer);
674
675                         /* Remove a small chunk from the input queue. */
676                         q_to_b(&sce->q, buffer, n);
677                         DPRINTFN(5, ("ugenread: got %d chars\n", n));
678
679                         /* Copy the data to the user process. */
680                         error = uiomove(buffer, n, uio);
681                         if (error)
682                                 break;
683                 }
684                 break;
685         case UE_BULK:
686                 xfer = usbd_alloc_xfer(sc->sc_udev);
687                 if (xfer == 0) {
688                         error = ENOMEM;
689                         goto done;
690                 }
691                 while ((n = szmin(ugen_bbsize, uio->uio_resid)) != 0) {
692                         DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
693                         tn = n;
694                         err = usbd_bulk_transfer(
695                                 xfer, sce->pipeh,
696                                 sce->state & UGEN_SHORT_OK ?
697                                     USBD_SHORT_XFER_OK : 0,
698                                 sce->timeout, buf, &tn, "ugenrb");
699                         if (err) {
700                                 if (err == USBD_INTERRUPTED)
701                                         error = EINTR;
702                                 else if (err == USBD_TIMEOUT)
703                                         error = ETIMEDOUT;
704                                 else
705                                         error = EIO;
706                                 break;
707                         }
708                         DPRINTFN(1, ("ugenread: got %d bytes\n", tn));
709                         error = uiomove(buf, tn, uio);
710                         if (error || tn < n)
711                                 break;
712                 }
713                 usbd_free_xfer(xfer);
714                 break;
715         case UE_ISOCHRONOUS:
716                 crit_enter();
717                 while (sce->cur == sce->fill) {
718                         if (flag & IO_NDELAY) {
719                                 crit_exit();
720                                 error = EWOULDBLOCK;
721                                 goto done;
722                         }
723                         sce->state |= UGEN_ASLP;
724                         DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
725                         error = tsleep(sce, PCATCH, "ugenri",
726                             (sce->timeout * hz + 999) / 1000);
727                         sce->state &= ~UGEN_ASLP;
728                         DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
729                         if (sc->sc_dying)
730                                 error = EIO;
731                         if (error == EAGAIN) {
732                                 error = 0;      /* timeout, return 0 bytes */
733                                 break;
734                         }
735                         if (error)
736                                 break;
737                 }
738
739                 while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) {
740                         if (sce->fill > sce->cur)
741                                 n = szmin(sce->fill - sce->cur, uio->uio_resid);
742                         else
743                                 n = szmin(sce->limit- sce->cur, uio->uio_resid);
744
745                         DPRINTFN(5, ("ugenread: isoc got %d chars\n", n));
746
747                         /* Copy the data to the user process. */
748                         error = uiomove(sce->cur, n, uio);
749                         if (error)
750                                 break;
751                         sce->cur += n;
752                         if(sce->cur >= sce->limit)
753                                 sce->cur = sce->ibuf;
754                 }
755                 crit_exit();
756                 break;
757
758
759         default:
760                 error = ENXIO;
761                 break;
762         }
763 done:
764         relugenbuf(buf, ugen_bbsize);
765         return (error);
766 }
767
768 int
769 ugenread(struct dev_read_args *ap)
770 {
771         cdev_t dev = ap->a_head.a_dev;
772         int endpt = UGENENDPOINT(dev);
773         struct ugen_softc *sc;
774         int error;
775
776         sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
777
778         if (sc->sc_dying)
779                 return (EIO);
780
781         sc->sc_refcnt++;
782         error = ugen_do_read(sc, endpt, ap->a_uio, ap->a_ioflag);
783         if (--sc->sc_refcnt < 0)
784                 usb_detach_wakeup(sc->sc_dev);
785         return (error);
786 }
787
788 static int
789 ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
790 {
791         struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
792         u_int32_t n;
793         int error = 0;
794         int ugen_bbsize;
795         char *buf;
796         usbd_xfer_handle xfer;
797         usbd_status err;
798
799         DPRINTFN(5, ("%s: ugenwrite: %d\n", device_get_nameunit(sc->sc_dev), endpt));
800
801         if (sc->sc_dying)
802                 return (EIO);
803
804         if (endpt == USB_CONTROL_ENDPOINT)
805                 return (ENODEV);
806
807 #ifdef DIAGNOSTIC
808         if (sce->edesc == NULL) {
809                 kprintf("ugenwrite: no edesc\n");
810                 return (EIO);
811         }
812         if (sce->pipeh == NULL) {
813                 kprintf("ugenwrite: no pipe\n");
814                 return (EIO);
815         }
816 #endif
817
818         buf = getugenbuf(ugen_bufsize, &ugen_bbsize);
819
820         switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
821         case UE_BULK:
822                 xfer = usbd_alloc_xfer(sc->sc_udev);
823                 if (xfer == 0) {
824                         error = EIO;
825                         goto done;
826                 }
827                 while ((n = szmin(ugen_bbsize, uio->uio_resid)) != 0) {
828                         error = uiomove(buf, n, uio);
829                         if (error)
830                                 break;
831                         DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
832                         err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
833                                   sce->timeout, buf, &n,"ugenwb");
834                         if (err) {
835                                 if (err == USBD_INTERRUPTED)
836                                         error = EINTR;
837                                 else if (err == USBD_TIMEOUT)
838                                         error = ETIMEDOUT;
839                                 else
840                                         error = EIO;
841                                 break;
842                         }
843                 }
844                 usbd_free_xfer(xfer);
845                 break;
846         case UE_INTERRUPT:
847                 xfer = usbd_alloc_xfer(sc->sc_udev);
848                 if (xfer == 0) {
849                         error = EIO;
850                         goto done;
851                 }
852                 while ((n = szmin(UGETW(sce->edesc->wMaxPacketSize),
853                                 uio->uio_resid)) != 0) {
854                         error = uiomove(buf, n, uio);
855                         if (error)
856                                 break;
857                         DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
858                         err = usbd_intr_transfer(xfer, sce->pipeh, 0,
859                                   sce->timeout, buf, &n,"ugenwi");
860                         if (err) {
861                                 if (err == USBD_INTERRUPTED)
862                                         error = EINTR;
863                                 else if (err == USBD_TIMEOUT)
864                                         error = ETIMEDOUT;
865                                 else
866                                         error = EIO;
867                                 break;
868                         }
869                 }
870                 usbd_free_xfer(xfer);
871                 break;
872         default:
873                 error = ENXIO;
874                 break;
875         }
876 done:
877         relugenbuf(buf, ugen_bbsize);
878         return (error);
879 }
880
881 int
882 ugenwrite(struct dev_write_args *ap)
883 {
884         cdev_t dev = ap->a_head.a_dev;
885         int endpt = UGENENDPOINT(dev);
886         struct ugen_softc *sc;
887         int error;
888
889         sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
890
891         if (sc->sc_dying)
892                 return (EIO);
893
894         sc->sc_refcnt++;
895         error = ugen_do_write(sc, endpt, ap->a_uio, ap->a_ioflag);
896         if (--sc->sc_refcnt < 0)
897                 usb_detach_wakeup(sc->sc_dev);
898         return (error);
899 }
900
901 static int
902 ugen_detach(device_t self)
903 {
904         struct ugen_softc *sc = device_get_softc(self);
905         struct ugen_endpoint *sce;
906         int i, dir;
907
908         DPRINTF(("ugen_detach: sc=%p\n", sc));
909
910         sc->sc_dying = 1;
911         /* Abort all pipes.  Causes processes waiting for transfer to wake. */
912         for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
913                 for (dir = OUT; dir <= IN; dir++) {
914                         sce = &sc->sc_endpoints[i][dir];
915                         if (sce && sce->pipeh)
916                                 usbd_abort_pipe(sce->pipeh);
917                         selwakeup(&sce->rsel);
918                 }
919         }
920         crit_enter();
921         if (--sc->sc_refcnt >= 0) {
922                 /* Wake everyone */
923                 for (i = 0; i < USB_MAX_ENDPOINTS; i++)
924                         wakeup(&sc->sc_endpoints[i][IN]);
925                 /* Wait for processes to go away. */
926                 usb_detach_wait(sc->sc_dev);
927         }
928         crit_exit();
929
930         /* destroy the device for the control endpoint */
931         ugen_destroy_devnodes(sc);
932         dev_ops_remove_minor(&ugen_ops,
933                     /*UGENUNITMASK,*/ UGENMINOR(device_get_unit(sc->sc_dev), 0));
934         usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
935         return (0);
936 }
937
938 static void
939 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
940 {
941         struct ugen_endpoint *sce = addr;
942         /*struct ugen_softc *sc = sce->sc;*/
943         u_int32_t count;
944         u_char *ibuf;
945
946         if (status == USBD_CANCELLED)
947                 return;
948
949         if (status != USBD_NORMAL_COMPLETION) {
950                 DPRINTF(("ugenintr: status=%d\n", status));
951                 if (status == USBD_STALLED)
952                     usbd_clear_endpoint_stall_async(sce->pipeh);
953                 return;
954         }
955
956         usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
957         ibuf = sce->ibuf;
958
959         DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
960                      xfer, status, count));
961         DPRINTFN(5, ("          data = %02x %02x %02x\n",
962                      ibuf[0], ibuf[1], ibuf[2]));
963
964         (void)b_to_q(ibuf, count, &sce->q);
965
966         if (sce->state & UGEN_ASLP) {
967                 sce->state &= ~UGEN_ASLP;
968                 DPRINTFN(5, ("ugen_intr: waking %p\n", sce));
969                 wakeup(sce);
970         }
971         selwakeup(&sce->rsel);
972 }
973
974 static void
975 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
976                 usbd_status status)
977 {
978         struct isoreq *req = addr;
979         struct ugen_endpoint *sce = req->sce;
980         u_int32_t count, n;
981         int i, isize;
982
983         /* Return if we are aborting. */
984         if (status == USBD_CANCELLED)
985                 return;
986
987         usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
988         DPRINTFN(5,("ugen_isoc_rintr: xfer %d, count=%d\n",
989                     (int)(req - sce->isoreqs),
990                     count));
991
992         /* throw away oldest input if the buffer is full */
993         if(sce->fill < sce->cur && sce->cur <= sce->fill + count) {
994                 sce->cur += count;
995                 if(sce->cur >= sce->limit)
996                         sce->cur = sce->ibuf + (sce->limit - sce->cur);
997                 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n",
998                              count));
999         }
1000
1001         isize = UGETW(sce->edesc->wMaxPacketSize);
1002         for (i = 0; i < UGEN_NISORFRMS; i++) {
1003                 u_int32_t actlen = req->sizes[i];
1004                 char const *buf = (char const *)req->dmabuf + isize * i;
1005
1006                 /* copy data to buffer */
1007                 while (actlen > 0) {
1008                         n = min(actlen, sce->limit - sce->fill);
1009                         memcpy(sce->fill, buf, n);
1010
1011                         buf += n;
1012                         actlen -= n;
1013                         sce->fill += n;
1014                         if(sce->fill == sce->limit)
1015                                 sce->fill = sce->ibuf;
1016                 }
1017
1018                 /* setup size for next transfer */
1019                 req->sizes[i] = isize;
1020         }
1021
1022         usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS,
1023                              USBD_NO_COPY, ugen_isoc_rintr);
1024         (void)usbd_transfer(xfer);
1025
1026         if (sce->state & UGEN_ASLP) {
1027                 sce->state &= ~UGEN_ASLP;
1028                 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce));
1029                 wakeup(sce);
1030         }
1031         selwakeup(&sce->rsel);
1032 }
1033
1034 static usbd_status
1035 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno)
1036 {
1037         usbd_interface_handle iface;
1038         usb_endpoint_descriptor_t *ed;
1039         usbd_status err;
1040         struct ugen_endpoint *sce;
1041         u_int8_t niface, nendpt, endptno, endpt;
1042         int dir;
1043
1044         DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
1045
1046         err = usbd_interface_count(sc->sc_udev, &niface);
1047         if (err)
1048                 return (err);
1049         if (ifaceidx < 0 || ifaceidx >= niface)
1050                 return (USBD_INVAL);
1051
1052         err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
1053         if (err)
1054                 return (err);
1055         err = usbd_endpoint_count(iface, &nendpt);
1056         if (err)
1057                 return (err);
1058
1059         /* destroy the existing devices, we remake the new ones in a moment */
1060         ugen_destroy_devnodes(sc);
1061
1062         /* XXX should only do this after setting new altno has succeeded */
1063         for (endptno = 0; endptno < nendpt; endptno++) {
1064                 ed = usbd_interface2endpoint_descriptor(iface,endptno);
1065                 endpt = ed->bEndpointAddress;
1066                 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
1067                 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
1068                 sce->sc = 0;
1069                 sce->edesc = 0;
1070                 sce->iface = 0;
1071         }
1072
1073         /* change setting */
1074         err = usbd_set_interface(iface, altno);
1075         if (err)
1076                 return (err);
1077
1078         err = usbd_endpoint_count(iface, &nendpt);
1079         if (err)
1080                 return (err);
1081         for (endptno = 0; endptno < nendpt; endptno++) {
1082                 ed = usbd_interface2endpoint_descriptor(iface,endptno);
1083                 endpt = ed->bEndpointAddress;
1084                 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
1085                 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
1086                 sce->sc = sc;
1087                 sce->edesc = ed;
1088                 sce->iface = iface;
1089         }
1090
1091         /* make the new devices */
1092         ugen_make_devnodes(sc);
1093
1094         return (0);
1095 }
1096
1097 /* Retrieve a complete descriptor for a certain device and index. */
1098 static usb_config_descriptor_t *
1099 ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp)
1100 {
1101         usb_config_descriptor_t *cdesc, *tdesc, cdescr;
1102         int len;
1103         usbd_status err;
1104
1105         if (index == USB_CURRENT_CONFIG_INDEX) {
1106                 tdesc = usbd_get_config_descriptor(sc->sc_udev);
1107                 len = UGETW(tdesc->wTotalLength);
1108                 if (lenp)
1109                         *lenp = len;
1110                 cdesc = kmalloc(len, M_TEMP, M_INTWAIT);
1111                 memcpy(cdesc, tdesc, len);
1112                 DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
1113         } else {
1114                 err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
1115                 if (err)
1116                         return (0);
1117                 len = UGETW(cdescr.wTotalLength);
1118                 DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
1119                 if (lenp)
1120                         *lenp = len;
1121                 cdesc = kmalloc(len, M_TEMP, M_INTWAIT);
1122                 err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
1123                 if (err) {
1124                         kfree(cdesc, M_TEMP);
1125                         return (0);
1126                 }
1127         }
1128         return (cdesc);
1129 }
1130
1131 static int
1132 ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx)
1133 {
1134         usbd_interface_handle iface;
1135         usbd_status err;
1136
1137         err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
1138         if (err)
1139                 return (-1);
1140         return (usbd_get_interface_altindex(iface));
1141 }
1142
1143 static int
1144 ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
1145               caddr_t addr, int flag)
1146 {
1147         struct ugen_endpoint *sce;
1148         usbd_status err;
1149         usbd_interface_handle iface;
1150         struct usb_config_desc *cd;
1151         usb_config_descriptor_t *cdesc;
1152         struct usb_interface_desc *id;
1153         usb_interface_descriptor_t *idesc;
1154         struct usb_endpoint_desc *ed;
1155         usb_endpoint_descriptor_t *edesc;
1156         struct usb_alt_interface *ai;
1157         struct usb_string_desc *si;
1158         u_int8_t conf, alt;
1159
1160         DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd));
1161         if (sc->sc_dying)
1162                 return (EIO);
1163
1164         switch (cmd) {
1165         case USB_SET_SHORT_XFER:
1166                 /* This flag only affects read */
1167                 if (endpt == USB_CONTROL_ENDPOINT)
1168                         return (EINVAL);
1169                 sce = &sc->sc_endpoints[endpt][IN];
1170
1171                 if (sce->pipeh == NULL) {
1172                         kprintf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n");
1173                         return (EIO);
1174                 }
1175
1176                 if (*(int *)addr)
1177                         sce->state |= UGEN_SHORT_OK;
1178                 else
1179                         sce->state &= ~UGEN_SHORT_OK;
1180                 return (0);
1181         case USB_SET_TIMEOUT:
1182                 sce = &sc->sc_endpoints[endpt][IN];
1183                 sce->timeout = *(int *)addr;
1184                 sce = &sc->sc_endpoints[endpt][OUT];
1185                 sce->timeout = *(int *)addr;
1186                 return (0);
1187         default:
1188                 break;
1189         }
1190
1191         if (endpt != USB_CONTROL_ENDPOINT)
1192                 return (EINVAL);
1193
1194         switch (cmd) {
1195 #ifdef USB_DEBUG
1196         case USB_SETDEBUG:
1197                 ugendebug = *(int *)addr;
1198                 break;
1199 #endif
1200         case USB_GET_CONFIG:
1201                 err = usbd_get_config(sc->sc_udev, &conf);
1202                 if (err)
1203                         return (EIO);
1204                 *(int *)addr = conf;
1205                 break;
1206         case USB_SET_CONFIG:
1207                 if (!(flag & FWRITE))
1208                         return (EPERM);
1209                 err = ugen_set_config(sc, *(int *)addr);
1210                 switch (err) {
1211                 case USBD_NORMAL_COMPLETION:
1212                         break;
1213                 case USBD_IN_USE:
1214                         return (EBUSY);
1215                 default:
1216                         return (EIO);
1217                 }
1218                 break;
1219         case USB_GET_ALTINTERFACE:
1220                 ai = (struct usb_alt_interface *)addr;
1221                 err = usbd_device2interface_handle(sc->sc_udev,
1222                           ai->uai_interface_index, &iface);
1223                 if (err)
1224                         return (EINVAL);
1225                 idesc = usbd_get_interface_descriptor(iface);
1226                 if (idesc == NULL)
1227                         return (EIO);
1228                 ai->uai_alt_no = idesc->bAlternateSetting;
1229                 break;
1230         case USB_SET_ALTINTERFACE:
1231                 if (!(flag & FWRITE))
1232                         return (EPERM);
1233                 ai = (struct usb_alt_interface *)addr;
1234                 err = usbd_device2interface_handle(sc->sc_udev,
1235                           ai->uai_interface_index, &iface);
1236                 if (err)
1237                         return (EINVAL);
1238                 err = ugen_set_interface(sc, ai->uai_interface_index, ai->uai_alt_no);
1239                 if (err)
1240                         return (EINVAL);
1241                 break;
1242         case USB_GET_NO_ALT:
1243                 ai = (struct usb_alt_interface *)addr;
1244                 cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0);
1245                 if (cdesc == NULL)
1246                         return (EINVAL);
1247                 idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0);
1248                 if (idesc == NULL) {
1249                         kfree(cdesc, M_TEMP);
1250                         return (EINVAL);
1251                 }
1252                 ai->uai_alt_no = usbd_get_no_alts(cdesc, idesc->bInterfaceNumber);
1253                 kfree(cdesc, M_TEMP);
1254                 break;
1255         case USB_GET_DEVICE_DESC:
1256                 *(usb_device_descriptor_t *)addr =
1257                         *usbd_get_device_descriptor(sc->sc_udev);
1258                 break;
1259         case USB_GET_CONFIG_DESC:
1260                 cd = (struct usb_config_desc *)addr;
1261                 cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0);
1262                 if (cdesc == NULL)
1263                         return (EINVAL);
1264                 cd->ucd_desc = *cdesc;
1265                 kfree(cdesc, M_TEMP);
1266                 break;
1267         case USB_GET_INTERFACE_DESC:
1268                 id = (struct usb_interface_desc *)addr;
1269                 cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0);
1270                 if (cdesc == NULL)
1271                         return (EINVAL);
1272                 if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX &&
1273                     id->uid_alt_index == USB_CURRENT_ALT_INDEX)
1274                         alt = ugen_get_alt_index(sc, id->uid_interface_index);
1275                 else
1276                         alt = id->uid_alt_index;
1277                 idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt);
1278                 if (idesc == NULL) {
1279                         kfree(cdesc, M_TEMP);
1280                         return (EINVAL);
1281                 }
1282                 id->uid_desc = *idesc;
1283                 kfree(cdesc, M_TEMP);
1284                 break;
1285         case USB_GET_ENDPOINT_DESC:
1286                 ed = (struct usb_endpoint_desc *)addr;
1287                 cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0);
1288                 if (cdesc == NULL)
1289                         return (EINVAL);
1290                 if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX &&
1291                     ed->ued_alt_index == USB_CURRENT_ALT_INDEX)
1292                         alt = ugen_get_alt_index(sc, ed->ued_interface_index);
1293                 else
1294                         alt = ed->ued_alt_index;
1295                 edesc = usbd_find_edesc(cdesc, ed->ued_interface_index,
1296                                         alt, ed->ued_endpoint_index);
1297                 if (edesc == NULL) {
1298                         kfree(cdesc, M_TEMP);
1299                         return (EINVAL);
1300                 }
1301                 ed->ued_desc = *edesc;
1302                 kfree(cdesc, M_TEMP);
1303                 break;
1304         case USB_GET_FULL_DESC:
1305         {
1306                 int len;
1307                 struct iovec iov;
1308                 struct uio uio;
1309                 struct usb_full_desc *fd = (struct usb_full_desc *)addr;
1310                 int error;
1311
1312                 cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len);
1313                 if (len > fd->ufd_size)
1314                         len = fd->ufd_size;
1315                 iov.iov_base = (caddr_t)fd->ufd_data;
1316                 iov.iov_len = len;
1317                 uio.uio_iov = &iov;
1318                 uio.uio_iovcnt = 1;
1319                 uio.uio_resid = len;
1320                 uio.uio_offset = 0;
1321                 uio.uio_segflg = UIO_USERSPACE;
1322                 uio.uio_rw = UIO_READ;
1323                 uio.uio_td = curthread;
1324                 error = uiomove((void *)cdesc, len, &uio);
1325                 kfree(cdesc, M_TEMP);
1326                 return (error);
1327         }
1328         case USB_GET_STRING_DESC:
1329         {
1330                 int size;
1331
1332                 si = (struct usb_string_desc *)addr;
1333                 err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
1334                           si->usd_language_id, &si->usd_desc, &size);
1335                 if (err)
1336                         return (EINVAL);
1337                 break;
1338         }
1339         case USB_DO_REQUEST:
1340         {
1341                 struct usb_ctl_request *ur = (void *)addr;
1342                 int len = UGETW(ur->ucr_request.wLength);
1343                 struct iovec iov;
1344                 struct uio uio;
1345                 void *ptr = 0;
1346                 usbd_status err;
1347                 int error = 0;
1348
1349                 if (!(flag & FWRITE))
1350                         return (EPERM);
1351                 /* Avoid requests that would damage the bus integrity. */
1352                 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1353                      ur->ucr_request.bRequest == UR_SET_ADDRESS) ||
1354                     (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1355                      ur->ucr_request.bRequest == UR_SET_CONFIG) ||
1356                     (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE &&
1357                      ur->ucr_request.bRequest == UR_SET_INTERFACE))
1358                         return (EINVAL);
1359
1360                 if (len < 0 || len > 32767)
1361                         return (EINVAL);
1362                 if (len != 0) {
1363                         iov.iov_base = (caddr_t)ur->ucr_data;
1364                         iov.iov_len = len;
1365                         uio.uio_iov = &iov;
1366                         uio.uio_iovcnt = 1;
1367                         uio.uio_resid = len;
1368                         uio.uio_offset = 0;
1369                         uio.uio_segflg = UIO_USERSPACE;
1370                         uio.uio_rw =
1371                                 ur->ucr_request.bmRequestType & UT_READ ?
1372                                 UIO_READ : UIO_WRITE;
1373                         uio.uio_td = curthread;
1374                         ptr = kmalloc(len, M_TEMP, M_WAITOK);
1375                         if (uio.uio_rw == UIO_WRITE) {
1376                                 error = uiomove(ptr, len, &uio);
1377                                 if (error)
1378                                         goto ret;
1379                         }
1380                 }
1381                 sce = &sc->sc_endpoints[endpt][IN];
1382                 err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request,
1383                           ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout);
1384                 if (err) {
1385                         error = EIO;
1386                         goto ret;
1387                 }
1388                 if (len != 0) {
1389                         if (uio.uio_rw == UIO_READ) {
1390                                 error = uiomove(ptr, len, &uio);
1391                                 if (error)
1392                                         goto ret;
1393                         }
1394                 }
1395         ret:
1396                 if (ptr)
1397                         kfree(ptr, M_TEMP);
1398                 return (error);
1399         }
1400         case USB_GET_DEVICEINFO:
1401                 usbd_fill_deviceinfo(sc->sc_udev,
1402                     (struct usb_device_info *)addr, 1);
1403                 break;
1404         default:
1405                 return (EINVAL);
1406         }
1407         return (0);
1408 }
1409
1410 int
1411 ugenioctl(struct dev_ioctl_args *ap)
1412 {
1413         cdev_t dev = ap->a_head.a_dev;
1414         int endpt = UGENENDPOINT(dev);
1415         struct ugen_softc *sc;
1416         int error;
1417
1418         sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
1419         if (sc->sc_dying)
1420                 return (EIO);
1421
1422         sc->sc_refcnt++;
1423         error = ugen_do_ioctl(sc, endpt, ap->a_cmd, ap->a_data, ap->a_fflag);
1424         if (--sc->sc_refcnt < 0)
1425                 usb_detach_wakeup(sc->sc_dev);
1426         return (error);
1427 }
1428
1429 static struct filterops ugen_filtops_read =
1430         { 1, NULL, ugen_filt_detach, ugen_filt_read };
1431 static struct filterops ugen_filtops_write =
1432         { 1, NULL, ugen_filt_detach, ugen_filt_write };
1433
1434 int
1435 ugenkqfilter(struct dev_kqfilter_args *ap)
1436 {
1437         cdev_t dev = ap->a_head.a_dev;
1438         struct knote *kn = ap->a_kn;
1439         struct klist *klist;
1440         struct ugen_softc *sc;
1441         struct ugen_endpoint *sce;
1442
1443         sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
1444
1445         ap->a_result = 1;
1446
1447         if (sc->sc_dying)
1448                 return (0);
1449
1450         /* Do not allow filter on a control endpoint */
1451         if (UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT)
1452                 return (0);
1453
1454         ap->a_result = 0;
1455
1456         switch (kn->kn_filter) {
1457         case EVFILT_READ:
1458                 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1459                 kn->kn_fop = &ugen_filtops_read;
1460                 kn->kn_hook = (caddr_t)dev;
1461                 break;
1462         case EVFILT_WRITE:
1463                 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT];
1464                 kn->kn_fop = &ugen_filtops_write;
1465                 kn->kn_hook = (caddr_t)dev;
1466                 break;
1467         default:
1468                 ap->a_result = EOPNOTSUPP;
1469                 return (0);
1470         }
1471
1472         if (sce->edesc != NULL || sce->pipeh != NULL) {
1473                 crit_enter();
1474                 klist = &sce->rsel.si_note;
1475                 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
1476                 crit_exit();
1477         }
1478
1479         return (0);
1480 }
1481
1482 static void
1483 ugen_filt_detach(struct knote *kn)
1484 {
1485         cdev_t dev = (cdev_t)kn->kn_hook;
1486         struct ugen_softc *sc;
1487         struct ugen_endpoint *sce;
1488         struct klist *klist;
1489
1490         sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
1491
1492         switch (kn->kn_filter) {
1493         case EVFILT_READ:
1494                 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1495                 break;
1496         case EVFILT_WRITE:
1497                 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT];
1498                 break;
1499         default:
1500                 return;
1501         }
1502
1503         if (sce->edesc != NULL || sce->pipeh != NULL) {
1504                 crit_enter();
1505                 klist = &sce->rsel.si_note;
1506                 SLIST_REMOVE(klist, kn, knote, kn_selnext);
1507                 crit_exit();
1508         }
1509 }
1510
1511 static int
1512 ugen_filt_read(struct knote *kn, long hint)
1513 {
1514         cdev_t dev = (cdev_t)kn->kn_hook;
1515         struct ugen_softc *sc;
1516         struct ugen_endpoint *sce;
1517         int ready = 0;
1518
1519         sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
1520         sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1521
1522         switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
1523         case UE_INTERRUPT:
1524                 if (sce->q.c_cc > 0)
1525                         ready = 1;
1526                 break;
1527         case UE_ISOCHRONOUS:
1528                 if (sce->cur != sce->fill)
1529                         ready = 1;
1530                 break;
1531         case UE_BULK:
1532                 ready = 1;
1533                 break;
1534         default:
1535                 break;
1536         }
1537
1538         return (ready);
1539 }
1540
1541 static int
1542 ugen_filt_write(struct knote *kn, long hint)
1543 {
1544         cdev_t dev = (cdev_t)kn->kn_hook;
1545         struct ugen_softc *sc;
1546         struct ugen_endpoint *sce;
1547         int ready = 0;
1548
1549         sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
1550         sce = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT];
1551
1552         switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
1553         case UE_INTERRUPT:
1554                 if (sce->q.c_cc > 0)
1555                         ready = 1;
1556                 break;
1557         case UE_ISOCHRONOUS:
1558                 if (sce->cur != sce->fill)
1559                         ready = 1;
1560                 break;
1561         case UE_BULK:
1562                 ready = 1;
1563                 break;
1564         default:
1565                 break;
1566         }
1567
1568         return (ready);
1569 }
1570
1571 DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, usbd_driver_load, 0);
1572