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