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