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