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