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