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