xref: /openbsd-src/sys/dev/usb/ugen.c (revision 850e275390052b330d93020bf619a739a3c277ac)
1 /*	$OpenBSD: ugen.c,v 1.55 2008/09/08 19:35:25 martynas 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 			DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
508 			if (sc->sc_dying)
509 				error = EIO;
510 			if (error == EWOULDBLOCK) {	/* timeout, return 0 */
511 				error = 0;
512 				break;
513 			}
514 			if (error) {
515 				sce->state &= ~UGEN_ASLP;
516 				break;
517 			}
518 		}
519 		splx(s);
520 
521 		/* Transfer as many chunks as possible. */
522 		while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) {
523 			n = min(sce->q.c_cc, uio->uio_resid);
524 			if (n > sizeof(buffer))
525 				n = sizeof(buffer);
526 
527 			/* Remove a small chunk from the input queue. */
528 			q_to_b(&sce->q, buffer, n);
529 			DPRINTFN(5, ("ugenread: got %d chars\n", n));
530 
531 			/* Copy the data to the user process. */
532 			error = uiomove(buffer, n, uio);
533 			if (error)
534 				break;
535 		}
536 		break;
537 	case UE_BULK:
538 		xfer = usbd_alloc_xfer(sc->sc_udev);
539 		if (xfer == 0)
540 			return (ENOMEM);
541 		while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
542 			DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
543 			tn = n;
544 			err = usbd_bulk_transfer(
545 				  xfer, sce->pipeh,
546 				  sce->state & UGEN_SHORT_OK ?
547 				      USBD_SHORT_XFER_OK : 0,
548 				  sce->timeout, buf, &tn, "ugenrb");
549 			if (err) {
550 				if (err == USBD_INTERRUPTED)
551 					error = EINTR;
552 				else if (err == USBD_TIMEOUT)
553 					error = ETIMEDOUT;
554 				else
555 					error = EIO;
556 				break;
557 			}
558 			DPRINTFN(1, ("ugenread: got %d bytes\n", tn));
559 			error = uiomove(buf, tn, uio);
560 			if (error || tn < n)
561 				break;
562 		}
563 		usbd_free_xfer(xfer);
564 		break;
565 	case UE_ISOCHRONOUS:
566 		s = splusb();
567 		while (sce->cur == sce->fill) {
568 			if (flag & IO_NDELAY) {
569 				splx(s);
570 				return (EWOULDBLOCK);
571 			}
572 			sce->state |= UGEN_ASLP;
573 			DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
574 			error = tsleep(sce, PZERO | PCATCH, "ugenri", 0);
575 			DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
576 			if (sc->sc_dying)
577 				error = EIO;
578 			if (error) {
579 				sce->state &= ~UGEN_ASLP;
580 				break;
581 			}
582 		}
583 
584 		while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) {
585 			if(sce->fill > sce->cur)
586 				n = min(sce->fill - sce->cur, uio->uio_resid);
587 			else
588 				n = min(sce->limit - sce->cur, uio->uio_resid);
589 
590 			DPRINTFN(5, ("ugenread: isoc got %d chars\n", n));
591 
592 			/* Copy the data to the user process. */
593 			error = uiomove(sce->cur, n, uio);
594 			if (error)
595 				break;
596 			sce->cur += n;
597 			if(sce->cur >= sce->limit)
598 				sce->cur = sce->ibuf;
599 		}
600 		splx(s);
601 		break;
602 
603 
604 	default:
605 		return (ENXIO);
606 	}
607 	return (error);
608 }
609 
610 int
611 ugenread(dev_t dev, struct uio *uio, int flag)
612 {
613 	int endpt = UGENENDPOINT(dev);
614 	struct ugen_softc *sc;
615 	int error;
616 
617 	sc = ugen_cd.cd_devs[UGENUNIT(dev)];
618 
619 	sc->sc_refcnt++;
620 	error = ugen_do_read(sc, endpt, uio, flag);
621 	if (--sc->sc_refcnt < 0)
622 		usb_detach_wakeup(&sc->sc_dev);
623 	return (error);
624 }
625 
626 int
627 ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
628 {
629 	struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
630 	u_int32_t n;
631 	int error = 0;
632 	char buf[UGEN_BBSIZE];
633 	usbd_xfer_handle xfer;
634 	usbd_status err;
635 
636 	DPRINTFN(5, ("%s: ugenwrite: %d\n", sc->sc_dev.dv_xname, endpt));
637 
638 	if (sc->sc_dying)
639 		return (EIO);
640 
641 	if (endpt == USB_CONTROL_ENDPOINT)
642 		return (ENODEV);
643 
644 #ifdef DIAGNOSTIC
645 	if (sce->edesc == NULL) {
646 		printf("ugenwrite: no edesc\n");
647 		return (EIO);
648 	}
649 	if (sce->pipeh == NULL) {
650 		printf("ugenwrite: no pipe\n");
651 		return (EIO);
652 	}
653 #endif
654 
655 	switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
656 	case UE_BULK:
657 		xfer = usbd_alloc_xfer(sc->sc_udev);
658 		if (xfer == 0)
659 			return (EIO);
660 		while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
661 			error = uiomove(buf, n, uio);
662 			if (error)
663 				break;
664 			DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
665 			err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
666 				  sce->timeout, buf, &n,"ugenwb");
667 			if (err) {
668 				if (err == USBD_INTERRUPTED)
669 					error = EINTR;
670 				else if (err == USBD_TIMEOUT)
671 					error = ETIMEDOUT;
672 				else
673 					error = EIO;
674 				break;
675 			}
676 		}
677 		usbd_free_xfer(xfer);
678 		break;
679 	case UE_INTERRUPT:
680 		xfer = usbd_alloc_xfer(sc->sc_udev);
681 		if (xfer == 0)
682 			return (EIO);
683 		while ((n = min(UGETW(sce->edesc->wMaxPacketSize),
684 		    uio->uio_resid)) != 0) {
685 			error = uiomove(buf, n, uio);
686 			if (error)
687 				break;
688 			DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
689 			err = usbd_intr_transfer(xfer, sce->pipeh, 0,
690 			    sce->timeout, buf, &n, "ugenwi");
691 			if (err) {
692 				if (err == USBD_INTERRUPTED)
693 					error = EINTR;
694 				else if (err == USBD_TIMEOUT)
695 					error = ETIMEDOUT;
696 				else
697 					error = EIO;
698 				break;
699 			}
700 		}
701 		usbd_free_xfer(xfer);
702 		break;
703 	default:
704 		return (ENXIO);
705 	}
706 	return (error);
707 }
708 
709 int
710 ugenwrite(dev_t dev, struct uio *uio, int flag)
711 {
712 	int endpt = UGENENDPOINT(dev);
713 	struct ugen_softc *sc;
714 	int error;
715 
716 	sc = ugen_cd.cd_devs[UGENUNIT(dev)];
717 
718 	sc->sc_refcnt++;
719 	error = ugen_do_write(sc, endpt, uio, flag);
720 	if (--sc->sc_refcnt < 0)
721 		usb_detach_wakeup(&sc->sc_dev);
722 	return (error);
723 }
724 
725 int
726 ugen_activate(struct device *self, enum devact act)
727 {
728 	struct ugen_softc *sc = (struct ugen_softc *)self;
729 
730 	switch (act) {
731 	case DVACT_ACTIVATE:
732 		break;
733 
734 	case DVACT_DEACTIVATE:
735 		sc->sc_dying = 1;
736 		break;
737 	}
738 	return (0);
739 }
740 
741 int
742 ugen_detach(struct device *self, int flags)
743 {
744 	struct ugen_softc *sc = (struct ugen_softc *)self;
745 	struct ugen_endpoint *sce;
746 	int i, dir;
747 	int s;
748 	int maj, mn;
749 
750 	DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags));
751 
752 	sc->sc_dying = 1;
753 	/* Abort all pipes.  Causes processes waiting for transfer to wake. */
754 	for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
755 		for (dir = OUT; dir <= IN; dir++) {
756 			sce = &sc->sc_endpoints[i][dir];
757 			if (sce && sce->pipeh)
758 				usbd_abort_pipe(sce->pipeh);
759 		}
760 	}
761 
762 	s = splusb();
763 	if (--sc->sc_refcnt >= 0) {
764 		/* Wake everyone */
765 		for (i = 0; i < USB_MAX_ENDPOINTS; i++)
766 			wakeup(&sc->sc_endpoints[i][IN]);
767 		/* Wait for processes to go away. */
768 		usb_detach_wait(&sc->sc_dev);
769 	}
770 	splx(s);
771 
772 	/* locate the major number */
773 	for (maj = 0; maj < nchrdev; maj++)
774 		if (cdevsw[maj].d_open == ugenopen)
775 			break;
776 
777 	/* Nuke the vnodes for any open instances (calls close). */
778 	mn = self->dv_unit * USB_MAX_ENDPOINTS;
779 	vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR);
780 
781 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
782 			   &sc->sc_dev);
783 
784 	return (0);
785 }
786 
787 void
788 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
789 {
790 	struct ugen_endpoint *sce = addr;
791 	/*struct ugen_softc *sc = sce->sc;*/
792 	u_int32_t count;
793 	u_char *ibuf;
794 
795 	if (status == USBD_CANCELLED)
796 		return;
797 
798 	if (status != USBD_NORMAL_COMPLETION) {
799 		DPRINTF(("ugenintr: status=%d\n", status));
800 		if (status == USBD_STALLED)
801 			usbd_clear_endpoint_stall_async(sce->pipeh);
802 		return;
803 	}
804 
805 	usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
806 	ibuf = sce->ibuf;
807 
808 	DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
809 		     xfer, status, count));
810 	DPRINTFN(5, ("          data = %02x %02x %02x\n",
811 		     ibuf[0], ibuf[1], ibuf[2]));
812 
813 	(void)b_to_q(ibuf, count, &sce->q);
814 
815 	if (sce->state & UGEN_ASLP) {
816 		sce->state &= ~UGEN_ASLP;
817 		DPRINTFN(5, ("ugen_intr: waking %p\n", sce));
818 		wakeup(sce);
819 	}
820 	selwakeup(&sce->rsel);
821 }
822 
823 void
824 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
825 		usbd_status status)
826 {
827 	struct isoreq *req = addr;
828 	struct ugen_endpoint *sce = req->sce;
829 	u_int32_t count, n;
830 	int i, isize;
831 
832 	/* Return if we are aborting. */
833 	if (status == USBD_CANCELLED)
834 		return;
835 
836 	usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
837 	DPRINTFN(5,("ugen_isoc_rintr: xfer %d, count=%d\n", req - sce->isoreqs,
838 		    count));
839 
840 	/* throw away oldest input if the buffer is full */
841 	if(sce->fill < sce->cur && sce->cur <= sce->fill + count) {
842 		sce->cur += count;
843 		if(sce->cur >= sce->limit)
844 			sce->cur = sce->ibuf + (sce->limit - sce->cur);
845 		DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n",
846 			     count));
847 	}
848 
849 	isize = UGETW(sce->edesc->wMaxPacketSize);
850 	for (i = 0; i < UGEN_NISORFRMS; i++) {
851 		u_int32_t actlen = req->sizes[i];
852 		char const *buf = (char const *)req->dmabuf + isize * i;
853 
854 		/* copy data to buffer */
855 		while (actlen > 0) {
856 			n = min(actlen, sce->limit - sce->fill);
857 			memcpy(sce->fill, buf, n);
858 
859 			buf += n;
860 			actlen -= n;
861 			sce->fill += n;
862 			if(sce->fill == sce->limit)
863 				sce->fill = sce->ibuf;
864 		}
865 
866 		/* setup size for next transfer */
867 		req->sizes[i] = isize;
868 	}
869 
870 	usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS,
871 			     USBD_NO_COPY, ugen_isoc_rintr);
872 	(void)usbd_transfer(xfer);
873 
874 	if (sce->state & UGEN_ASLP) {
875 		sce->state &= ~UGEN_ASLP;
876 		DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce));
877 		wakeup(sce);
878 	}
879 	selwakeup(&sce->rsel);
880 }
881 
882 usbd_status
883 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno)
884 {
885 	usbd_interface_handle iface;
886 	usb_endpoint_descriptor_t *ed;
887 	usbd_status err;
888 	struct ugen_endpoint *sce;
889 	u_int8_t niface, nendpt, endptno, endpt;
890 	int dir;
891 
892 	DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
893 
894 	err = usbd_interface_count(sc->sc_udev, &niface);
895 	if (err)
896 		return (err);
897 	if (ifaceidx < 0 || ifaceidx >= niface)
898 		return (USBD_INVAL);
899 
900 	err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
901 	if (err)
902 		return (err);
903 	err = usbd_endpoint_count(iface, &nendpt);
904 	if (err)
905 		return (err);
906 	for (endptno = 0; endptno < nendpt; endptno++) {
907 		ed = usbd_interface2endpoint_descriptor(iface,endptno);
908 		endpt = ed->bEndpointAddress;
909 		dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
910 		sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
911 		sce->sc = 0;
912 		sce->edesc = 0;
913 		sce->iface = 0;
914 	}
915 
916 	/* change setting */
917 	err = usbd_set_interface(iface, altno);
918 	if (err)
919 		goto out;
920 
921 	err = usbd_endpoint_count(iface, &nendpt);
922 	if (err)
923 		goto out;
924 
925 out:
926 	for (endptno = 0; endptno < nendpt; endptno++) {
927 		ed = usbd_interface2endpoint_descriptor(iface,endptno);
928 		endpt = ed->bEndpointAddress;
929 		dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
930 		sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
931 		sce->sc = sc;
932 		sce->edesc = ed;
933 		sce->iface = iface;
934 	}
935 	return (err);
936 }
937 
938 /* Retrieve a complete descriptor for a certain device and index. */
939 usb_config_descriptor_t *
940 ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp)
941 {
942 	usb_config_descriptor_t *cdesc, *tdesc, cdescr;
943 	int len;
944 	usbd_status err;
945 
946 	if (index == USB_CURRENT_CONFIG_INDEX) {
947 		tdesc = usbd_get_config_descriptor(sc->sc_udev);
948 		len = UGETW(tdesc->wTotalLength);
949 		if (lenp)
950 			*lenp = len;
951 		cdesc = malloc(len, M_TEMP, M_WAITOK);
952 		memcpy(cdesc, tdesc, len);
953 		DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
954 	} else {
955 		err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
956 		if (err)
957 			return (0);
958 		len = UGETW(cdescr.wTotalLength);
959 		DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
960 		if (lenp)
961 			*lenp = len;
962 		cdesc = malloc(len, M_TEMP, M_WAITOK);
963 		err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc,
964 						len);
965 		if (err) {
966 			free(cdesc, M_TEMP);
967 			return (0);
968 		}
969 	}
970 	return (cdesc);
971 }
972 
973 int
974 ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx)
975 {
976 	usbd_interface_handle iface;
977 	usbd_status err;
978 
979 	err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
980 	if (err)
981 		return (-1);
982 	return (usbd_get_interface_altindex(iface));
983 }
984 
985 int
986 ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
987 	      caddr_t addr, int flag, struct proc *p)
988 {
989 	struct ugen_endpoint *sce;
990 	usbd_status err;
991 	usbd_interface_handle iface;
992 	struct usb_config_desc *cd;
993 	usb_config_descriptor_t *cdesc;
994 	struct usb_interface_desc *id;
995 	usb_interface_descriptor_t *idesc;
996 	struct usb_endpoint_desc *ed;
997 	usb_endpoint_descriptor_t *edesc;
998 	struct usb_alt_interface *ai;
999 	struct usb_string_desc *si;
1000 	u_int8_t conf, alt;
1001 
1002 	DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd));
1003 	if (sc->sc_dying)
1004 		return (EIO);
1005 
1006 	switch (cmd) {
1007 	case FIONBIO:
1008 		/* All handled in the upper FS layer. */
1009 		return (0);
1010 	case USB_SET_SHORT_XFER:
1011 		if (endpt == USB_CONTROL_ENDPOINT)
1012 			return (EINVAL);
1013 		/* This flag only affects read */
1014 		sce = &sc->sc_endpoints[endpt][IN];
1015 		if (sce == NULL || sce->pipeh == NULL)
1016 			return (EINVAL);
1017 		if (*(int *)addr)
1018 			sce->state |= UGEN_SHORT_OK;
1019 		else
1020 			sce->state &= ~UGEN_SHORT_OK;
1021 		return (0);
1022 	case USB_SET_TIMEOUT:
1023 		sce = &sc->sc_endpoints[endpt][IN];
1024 		if (sce == NULL
1025 		    /* XXX this shouldn't happen, but the distinction between
1026 		       input and output pipes isn't clear enough.
1027 		       || sce->pipeh == NULL */
1028 			)
1029 			return (EINVAL);
1030 		sce->timeout = *(int *)addr;
1031 		return (0);
1032 	default:
1033 		break;
1034 	}
1035 
1036 	if (endpt != USB_CONTROL_ENDPOINT)
1037 		return (EINVAL);
1038 
1039 	switch (cmd) {
1040 #ifdef UGEN_DEBUG
1041 	case USB_SETDEBUG:
1042 		ugendebug = *(int *)addr;
1043 		break;
1044 #endif
1045 	case USB_GET_CONFIG:
1046 		err = usbd_get_config(sc->sc_udev, &conf);
1047 		if (err)
1048 			return (EIO);
1049 		*(int *)addr = conf;
1050 		break;
1051 	case USB_SET_CONFIG:
1052 		if (!(flag & FWRITE))
1053 			return (EPERM);
1054 		err = ugen_set_config(sc, *(int *)addr);
1055 		switch (err) {
1056 		case USBD_NORMAL_COMPLETION:
1057 			break;
1058 		case USBD_IN_USE:
1059 			return (EBUSY);
1060 		default:
1061 			return (EIO);
1062 		}
1063 		break;
1064 	case USB_GET_ALTINTERFACE:
1065 		ai = (struct usb_alt_interface *)addr;
1066 		err = usbd_device2interface_handle(sc->sc_udev,
1067 			  ai->uai_interface_index, &iface);
1068 		if (err)
1069 			return (EINVAL);
1070 		idesc = usbd_get_interface_descriptor(iface);
1071 		if (idesc == NULL)
1072 			return (EIO);
1073 		ai->uai_alt_no = idesc->bAlternateSetting;
1074 		break;
1075 	case USB_SET_ALTINTERFACE:
1076 		if (!(flag & FWRITE))
1077 			return (EPERM);
1078 		ai = (struct usb_alt_interface *)addr;
1079 		err = usbd_device2interface_handle(sc->sc_udev,
1080 			  ai->uai_interface_index, &iface);
1081 		if (err)
1082 			return (EINVAL);
1083 		err = ugen_set_interface(sc, ai->uai_interface_index,
1084 		    ai->uai_alt_no);
1085 		if (err)
1086 			return (EINVAL);
1087 		break;
1088 	case USB_GET_NO_ALT:
1089 		ai = (struct usb_alt_interface *)addr;
1090 		cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0);
1091 		if (cdesc == NULL)
1092 			return (EINVAL);
1093 		idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0);
1094 		if (idesc == NULL) {
1095 			free(cdesc, M_TEMP);
1096 			return (EINVAL);
1097 		}
1098 		ai->uai_alt_no = usbd_get_no_alts(cdesc,
1099 		    idesc->bInterfaceNumber);
1100 		free(cdesc, M_TEMP);
1101 		break;
1102 	case USB_GET_DEVICE_DESC:
1103 		*(usb_device_descriptor_t *)addr =
1104 			*usbd_get_device_descriptor(sc->sc_udev);
1105 		break;
1106 	case USB_GET_CONFIG_DESC:
1107 		cd = (struct usb_config_desc *)addr;
1108 		cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0);
1109 		if (cdesc == NULL)
1110 			return (EINVAL);
1111 		cd->ucd_desc = *cdesc;
1112 		free(cdesc, M_TEMP);
1113 		break;
1114 	case USB_GET_INTERFACE_DESC:
1115 		id = (struct usb_interface_desc *)addr;
1116 		cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0);
1117 		if (cdesc == NULL)
1118 			return (EINVAL);
1119 		if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX &&
1120 		    id->uid_alt_index == USB_CURRENT_ALT_INDEX)
1121 			alt = ugen_get_alt_index(sc, id->uid_interface_index);
1122 		else
1123 			alt = id->uid_alt_index;
1124 		idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt);
1125 		if (idesc == NULL) {
1126 			free(cdesc, M_TEMP);
1127 			return (EINVAL);
1128 		}
1129 		id->uid_desc = *idesc;
1130 		free(cdesc, M_TEMP);
1131 		break;
1132 	case USB_GET_ENDPOINT_DESC:
1133 		ed = (struct usb_endpoint_desc *)addr;
1134 		cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0);
1135 		if (cdesc == NULL)
1136 			return (EINVAL);
1137 		if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX &&
1138 		    ed->ued_alt_index == USB_CURRENT_ALT_INDEX)
1139 			alt = ugen_get_alt_index(sc, ed->ued_interface_index);
1140 		else
1141 			alt = ed->ued_alt_index;
1142 		edesc = usbd_find_edesc(cdesc, ed->ued_interface_index,
1143 					alt, ed->ued_endpoint_index);
1144 		if (edesc == NULL) {
1145 			free(cdesc, M_TEMP);
1146 			return (EINVAL);
1147 		}
1148 		ed->ued_desc = *edesc;
1149 		free(cdesc, M_TEMP);
1150 		break;
1151 	case USB_GET_FULL_DESC:
1152 	{
1153 		int len;
1154 		struct iovec iov;
1155 		struct uio uio;
1156 		struct usb_full_desc *fd = (struct usb_full_desc *)addr;
1157 		int error;
1158 
1159 		cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len);
1160 		if (len > fd->ufd_size)
1161 			len = fd->ufd_size;
1162 		iov.iov_base = (caddr_t)fd->ufd_data;
1163 		iov.iov_len = len;
1164 		uio.uio_iov = &iov;
1165 		uio.uio_iovcnt = 1;
1166 		uio.uio_resid = len;
1167 		uio.uio_offset = 0;
1168 		uio.uio_segflg = UIO_USERSPACE;
1169 		uio.uio_rw = UIO_READ;
1170 		uio.uio_procp = p;
1171 		error = uiomove((void *)cdesc, len, &uio);
1172 		free(cdesc, M_TEMP);
1173 		return (error);
1174 	}
1175 	case USB_GET_STRING_DESC:
1176 	{
1177 		int len;
1178 		si = (struct usb_string_desc *)addr;
1179 		err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
1180 			si->usd_language_id, &si->usd_desc, &len);
1181 		if (err)
1182 			return (EINVAL);
1183 		break;
1184 	}
1185 	case USB_DO_REQUEST:
1186 	{
1187 		struct usb_ctl_request *ur = (void *)addr;
1188 		int len = UGETW(ur->ucr_request.wLength);
1189 		struct iovec iov;
1190 		struct uio uio;
1191 		void *ptr = 0;
1192 		int error = 0;
1193 
1194 		if (!(flag & FWRITE))
1195 			return (EPERM);
1196 		/* Avoid requests that would damage the bus integrity. */
1197 		if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1198 		     ur->ucr_request.bRequest == UR_SET_ADDRESS) ||
1199 		    (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
1200 		     ur->ucr_request.bRequest == UR_SET_CONFIG) ||
1201 		    (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE &&
1202 		     ur->ucr_request.bRequest == UR_SET_INTERFACE))
1203 			return (EINVAL);
1204 
1205 		if (len < 0 || len > 32767)
1206 			return (EINVAL);
1207 		if (len != 0) {
1208 			iov.iov_base = (caddr_t)ur->ucr_data;
1209 			iov.iov_len = len;
1210 			uio.uio_iov = &iov;
1211 			uio.uio_iovcnt = 1;
1212 			uio.uio_resid = len;
1213 			uio.uio_offset = 0;
1214 			uio.uio_segflg = UIO_USERSPACE;
1215 			uio.uio_rw =
1216 				ur->ucr_request.bmRequestType & UT_READ ?
1217 				UIO_READ : UIO_WRITE;
1218 			uio.uio_procp = p;
1219 			ptr = malloc(len, M_TEMP, M_WAITOK);
1220 			if (uio.uio_rw == UIO_WRITE) {
1221 				error = uiomove(ptr, len, &uio);
1222 				if (error)
1223 					goto ret;
1224 			}
1225 		}
1226 		sce = &sc->sc_endpoints[endpt][IN];
1227 		err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request,
1228 			  ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout);
1229 		if (err) {
1230 			error = EIO;
1231 			goto ret;
1232 		}
1233 		if (len != 0) {
1234 			if (uio.uio_rw == UIO_READ) {
1235 				error = uiomove(ptr, len, &uio);
1236 				if (error)
1237 					goto ret;
1238 			}
1239 		}
1240 	ret:
1241 		if (ptr)
1242 			free(ptr, M_TEMP);
1243 		return (error);
1244 	}
1245 	case USB_GET_DEVICEINFO:
1246 		usbd_fill_deviceinfo(sc->sc_udev,
1247 				     (struct usb_device_info *)addr, 1);
1248 		break;
1249 	default:
1250 		return (EINVAL);
1251 	}
1252 	return (0);
1253 }
1254 
1255 int
1256 ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
1257 {
1258 	int endpt = UGENENDPOINT(dev);
1259 	struct ugen_softc *sc;
1260 	int error;
1261 
1262 	sc = ugen_cd.cd_devs[UGENUNIT(dev)];
1263 
1264 	sc->sc_refcnt++;
1265 	error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
1266 	if (--sc->sc_refcnt < 0)
1267 		usb_detach_wakeup(&sc->sc_dev);
1268 	return (error);
1269 }
1270 
1271 int
1272 ugenpoll(dev_t dev, int events, struct proc *p)
1273 {
1274 	struct ugen_softc *sc;
1275 	struct ugen_endpoint *sce;
1276 	int revents = 0;
1277 	int s;
1278 
1279 	sc = ugen_cd.cd_devs[UGENUNIT(dev)];
1280 
1281 	if (sc->sc_dying)
1282 		return (POLLERR);
1283 
1284 	/* XXX always IN */
1285 	sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1286 	if (sce == NULL)
1287 		return (POLLERR);
1288 #ifdef DIAGNOSTIC
1289 	if (!sce->edesc) {
1290 		printf("ugenpoll: no edesc\n");
1291 		return (POLLERR);
1292 	}
1293 	if (!sce->pipeh) {
1294 		printf("ugenpoll: no pipe\n");
1295 		return (POLLERR);
1296 	}
1297 #endif
1298 	s = splusb();
1299 	switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
1300 	case UE_INTERRUPT:
1301 		if (events & (POLLIN | POLLRDNORM)) {
1302 			if (sce->q.c_cc > 0)
1303 				revents |= events & (POLLIN | POLLRDNORM);
1304 			else
1305 				selrecord(p, &sce->rsel);
1306 		}
1307 		break;
1308 	case UE_ISOCHRONOUS:
1309 		if (events & (POLLIN | POLLRDNORM)) {
1310 			if (sce->cur != sce->fill)
1311 				revents |= events & (POLLIN | POLLRDNORM);
1312 			else
1313 				selrecord(p, &sce->rsel);
1314 		}
1315 		break;
1316 	case UE_BULK:
1317 		/*
1318 		 * We have no easy way of determining if a read will
1319 		 * yield any data or a write will happen.
1320 		 * Pretend they will.
1321 		 */
1322 		revents |= events &
1323 			   (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
1324 		break;
1325 	default:
1326 		break;
1327 	}
1328 	splx(s);
1329 	return (revents);
1330 }
1331 
1332 void filt_ugenrdetach(struct knote *);
1333 int filt_ugenread_intr(struct knote *, long);
1334 int filt_ugenread_isoc(struct knote *, long);
1335 int ugenkqfilter(dev_t, struct knote *);
1336 
1337 void
1338 filt_ugenrdetach(struct knote *kn)
1339 {
1340 	struct ugen_endpoint *sce = (void *)kn->kn_hook;
1341 	int s;
1342 
1343 	s = splusb();
1344 	SLIST_REMOVE(&sce->rsel.si_note, kn, knote, kn_selnext);
1345 	splx(s);
1346 }
1347 
1348 int
1349 filt_ugenread_intr(struct knote *kn, long hint)
1350 {
1351 	struct ugen_endpoint *sce = (void *)kn->kn_hook;
1352 
1353 	kn->kn_data = sce->q.c_cc;
1354 	return (kn->kn_data > 0);
1355 }
1356 
1357 int
1358 filt_ugenread_isoc(struct knote *kn, long hint)
1359 {
1360 	struct ugen_endpoint *sce = (void *)kn->kn_hook;
1361 
1362 	if (sce->cur == sce->fill)
1363 		return (0);
1364 
1365 	if (sce->cur < sce->fill)
1366 		kn->kn_data = sce->fill - sce->cur;
1367 	else
1368 		kn->kn_data = (sce->limit - sce->cur) +
1369 		    (sce->fill - sce->ibuf);
1370 
1371 	return (1);
1372 }
1373 
1374 struct filterops ugenread_intr_filtops =
1375 	{ 1, NULL, filt_ugenrdetach, filt_ugenread_intr };
1376 
1377 struct filterops ugenread_isoc_filtops =
1378 	{ 1, NULL, filt_ugenrdetach, filt_ugenread_isoc };
1379 
1380 struct filterops ugen_seltrue_filtops =
1381 	{ 1, NULL, filt_ugenrdetach, filt_seltrue };
1382 
1383 int
1384 ugenkqfilter(dev_t dev, struct knote *kn)
1385 {
1386 	struct ugen_softc *sc;
1387 	struct ugen_endpoint *sce;
1388 	struct klist *klist;
1389 	int s;
1390 
1391 	sc = ugen_cd.cd_devs[UGENUNIT(dev)];
1392 
1393 	if (sc->sc_dying)
1394 		return (1);
1395 
1396 	/* XXX always IN */
1397 	sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
1398 	if (sce == NULL)
1399 		return (1);
1400 
1401 	switch (kn->kn_filter) {
1402 	case EVFILT_READ:
1403 		klist = &sce->rsel.si_note;
1404 		switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
1405 		case UE_INTERRUPT:
1406 			kn->kn_fop = &ugenread_intr_filtops;
1407 			break;
1408 		case UE_ISOCHRONOUS:
1409 			kn->kn_fop = &ugenread_isoc_filtops;
1410 			break;
1411 		case UE_BULK:
1412 			/*
1413 			 * We have no easy way of determining if a read will
1414 			 * yield any data or a write will happen.
1415 			 * So, emulate "seltrue".
1416 			 */
1417 			kn->kn_fop = &ugen_seltrue_filtops;
1418 			break;
1419 		default:
1420 			return (1);
1421 		}
1422 		break;
1423 
1424 	case EVFILT_WRITE:
1425 		klist = &sce->rsel.si_note;
1426 		switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
1427 		case UE_INTERRUPT:
1428 		case UE_ISOCHRONOUS:
1429 			/* XXX poll doesn't support this */
1430 			return (1);
1431 
1432 		case UE_BULK:
1433 			/*
1434 			 * We have no easy way of determining if a read will
1435 			 * yield any data or a write will happen.
1436 			 * So, emulate "seltrue".
1437 			 */
1438 			kn->kn_fop = &ugen_seltrue_filtops;
1439 			break;
1440 		default:
1441 			return (1);
1442 		}
1443 		break;
1444 
1445 	default:
1446 		return (1);
1447 	}
1448 
1449 	kn->kn_hook = (void *)sce;
1450 
1451 	s = splusb();
1452 	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
1453 	splx(s);
1454 
1455 	return (0);
1456 }
1457