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