1 /* $NetBSD: ugen.c,v 1.51 2001/11/13 07:59:32 augustss Exp $ */ 2 /* $FreeBSD: src/sys/dev/usb/ugen.c,v 1.26 1999/11/17 22:33:41 n_hibma Exp $ */ 3 4 /* 5 * Copyright (c) 1998 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Lennart Augustsson (lennart@augustsson.net) at 10 * Carlstedt Research & Technology. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the NetBSD 23 * Foundation, Inc. and its contributors. 24 * 4. Neither the name of The NetBSD Foundation nor the names of its 25 * contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41 42 #include <sys/cdefs.h> 43 __KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.51 2001/11/13 07:59:32 augustss Exp $"); 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/kernel.h> 48 #include <sys/malloc.h> 49 #if defined(__NetBSD__) || defined(__OpenBSD__) 50 #include <sys/device.h> 51 #include <sys/ioctl.h> 52 #elif defined(__FreeBSD__) 53 #include <sys/module.h> 54 #include <sys/bus.h> 55 #include <sys/ioccom.h> 56 #include <sys/conf.h> 57 #include <sys/fcntl.h> 58 #include <sys/filio.h> 59 #endif 60 #include <sys/conf.h> 61 #include <sys/tty.h> 62 #include <sys/file.h> 63 #include <sys/select.h> 64 #include <sys/proc.h> 65 #include <sys/vnode.h> 66 #include <sys/poll.h> 67 68 #include <dev/usb/usb.h> 69 #include <dev/usb/usbdi.h> 70 #include <dev/usb/usbdi_util.h> 71 72 #ifdef UGEN_DEBUG 73 #define DPRINTF(x) if (ugendebug) logprintf x 74 #define DPRINTFN(n,x) if (ugendebug>(n)) logprintf x 75 int ugendebug = 0; 76 #else 77 #define DPRINTF(x) 78 #define DPRINTFN(n,x) 79 #endif 80 81 #define UGEN_CHUNK 128 /* chunk size for read */ 82 #define UGEN_IBSIZE 1020 /* buffer size */ 83 #define UGEN_BBSIZE 1024 84 85 #define UGEN_NISOFRAMES 500 /* 0.5 seconds worth */ 86 #define UGEN_NISOREQS 6 /* number of outstanding xfer requests */ 87 #define UGEN_NISORFRMS 4 /* number of frames (miliseconds) per req */ 88 89 struct ugen_endpoint { 90 struct ugen_softc *sc; 91 usb_endpoint_descriptor_t *edesc; 92 usbd_interface_handle iface; 93 int state; 94 #define UGEN_ASLP 0x02 /* waiting for data */ 95 #define UGEN_SHORT_OK 0x04 /* short xfers are OK */ 96 usbd_pipe_handle pipeh; 97 struct clist q; 98 struct selinfo rsel; 99 u_char *ibuf; /* start of buffer (circular for isoc) */ 100 u_char *fill; /* location for input (isoc) */ 101 u_char *limit; /* end of circular buffer (isoc) */ 102 u_char *cur; /* current read location (isoc) */ 103 u_int32_t timeout; 104 struct isoreq { 105 struct ugen_endpoint *sce; 106 usbd_xfer_handle xfer; 107 void *dmabuf; 108 u_int16_t sizes[UGEN_NISORFRMS]; 109 } isoreqs[UGEN_NISOREQS]; 110 }; 111 112 struct ugen_softc { 113 USBBASEDEVICE sc_dev; /* base device */ 114 usbd_device_handle sc_udev; 115 116 char sc_is_open[USB_MAX_ENDPOINTS]; 117 struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2]; 118 #define OUT 0 119 #define IN 1 120 121 int sc_refcnt; 122 u_char sc_dying; 123 }; 124 125 #if defined(__NetBSD__) || defined(__OpenBSD__) 126 cdev_decl(ugen); 127 #elif defined(__FreeBSD__) 128 d_open_t ugenopen; 129 d_close_t ugenclose; 130 d_read_t ugenread; 131 d_write_t ugenwrite; 132 d_ioctl_t ugenioctl; 133 d_poll_t ugenpoll; 134 135 #define UGEN_CDEV_MAJOR 114 136 137 Static struct cdevsw ugen_cdevsw = { 138 /* open */ ugenopen, 139 /* close */ ugenclose, 140 /* read */ ugenread, 141 /* write */ ugenwrite, 142 /* ioctl */ ugenioctl, 143 /* poll */ ugenpoll, 144 /* mmap */ nommap, 145 /* strategy */ nostrategy, 146 /* name */ "ugen", 147 /* maj */ UGEN_CDEV_MAJOR, 148 /* dump */ nodump, 149 /* psize */ nopsize, 150 /* flags */ 0, 151 /* bmaj */ -1 152 }; 153 #endif 154 155 Static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, 156 usbd_status status); 157 Static void ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, 158 usbd_status status); 159 Static int ugen_do_read(struct ugen_softc *, int, struct uio *, int); 160 Static int ugen_do_write(struct ugen_softc *, int, struct uio *, int); 161 Static int ugen_do_ioctl(struct ugen_softc *, int, u_long, 162 caddr_t, int, struct proc *); 163 Static int ugen_set_config(struct ugen_softc *sc, int configno); 164 Static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc, 165 int index, int *lenp); 166 Static usbd_status ugen_set_interface(struct ugen_softc *, int, int); 167 Static int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx); 168 169 #define UGENUNIT(n) ((minor(n) >> 4) & 0xf) 170 #define UGENENDPOINT(n) (minor(n) & 0xf) 171 #define UGENDEV(u, e) (makedev(0, ((u) << 4) | (e))) 172 173 USB_DECLARE_DRIVER(ugen); 174 175 USB_MATCH(ugen) 176 { 177 USB_MATCH_START(ugen, uaa); 178 179 #if 0 180 if (uaa->matchlvl) 181 return (uaa->matchlvl); 182 #endif 183 if (uaa->usegeneric) 184 return (UMATCH_GENERIC); 185 else 186 return (UMATCH_NONE); 187 } 188 189 USB_ATTACH(ugen) 190 { 191 USB_ATTACH_START(ugen, sc, uaa); 192 usbd_device_handle udev; 193 char devinfo[1024]; 194 usbd_status err; 195 int conf; 196 197 usbd_devinfo(uaa->device, 0, devinfo); 198 USB_ATTACH_SETUP; 199 printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo); 200 201 sc->sc_udev = udev = uaa->device; 202 203 /* First set configuration index 0, the default one for ugen. */ 204 err = usbd_set_config_index(udev, 0, 0); 205 if (err) { 206 printf("%s: setting configuration index 0 failed\n", 207 USBDEVNAME(sc->sc_dev)); 208 sc->sc_dying = 1; 209 USB_ATTACH_ERROR_RETURN; 210 } 211 conf = usbd_get_config_descriptor(udev)->bConfigurationValue; 212 213 /* Set up all the local state for this configuration. */ 214 err = ugen_set_config(sc, conf); 215 if (err) { 216 printf("%s: setting configuration %d failed\n", 217 USBDEVNAME(sc->sc_dev), conf); 218 sc->sc_dying = 1; 219 USB_ATTACH_ERROR_RETURN; 220 } 221 222 #ifdef __FreeBSD__ 223 { 224 static int global_init_done = 0; 225 if (!global_init_done) { 226 cdevsw_add(&ugen_cdevsw); 227 global_init_done = 1; 228 } 229 } 230 #endif 231 232 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 233 USBDEV(sc->sc_dev)); 234 235 USB_ATTACH_SUCCESS_RETURN; 236 } 237 238 Static int 239 ugen_set_config(struct ugen_softc *sc, int configno) 240 { 241 usbd_device_handle dev = sc->sc_udev; 242 usbd_interface_handle iface; 243 usb_endpoint_descriptor_t *ed; 244 struct ugen_endpoint *sce; 245 u_int8_t niface, nendpt; 246 int ifaceno, endptno, endpt; 247 usbd_status err; 248 int dir; 249 250 DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n", 251 USBDEVNAME(sc->sc_dev), configno, sc)); 252 /* Avoid setting the current value. */ 253 if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) { 254 err = usbd_set_config_no(dev, configno, 1); 255 if (err) 256 return (err); 257 } 258 259 err = usbd_interface_count(dev, &niface); 260 if (err) 261 return (err); 262 memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints); 263 for (ifaceno = 0; ifaceno < niface; ifaceno++) { 264 DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno)); 265 err = usbd_device2interface_handle(dev, ifaceno, &iface); 266 if (err) 267 return (err); 268 err = usbd_endpoint_count(iface, &nendpt); 269 if (err) 270 return (err); 271 for (endptno = 0; endptno < nendpt; endptno++) { 272 ed = usbd_interface2endpoint_descriptor(iface,endptno); 273 endpt = ed->bEndpointAddress; 274 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 275 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 276 DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x" 277 "(%d,%d), sce=%p\n", 278 endptno, endpt, UE_GET_ADDR(endpt), 279 UE_GET_DIR(endpt), sce)); 280 sce->sc = sc; 281 sce->edesc = ed; 282 sce->iface = iface; 283 } 284 } 285 return (USBD_NORMAL_COMPLETION); 286 } 287 288 int 289 ugenopen(dev_t dev, int flag, int mode, struct proc *p) 290 { 291 struct ugen_softc *sc; 292 int unit = UGENUNIT(dev); 293 int endpt = UGENENDPOINT(dev); 294 usb_endpoint_descriptor_t *edesc; 295 struct ugen_endpoint *sce; 296 int dir, isize; 297 usbd_status err; 298 usbd_xfer_handle xfer; 299 void *buf; 300 int i, j; 301 302 USB_GET_SC_OPEN(ugen, unit, sc); 303 304 DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n", 305 flag, mode, unit, endpt)); 306 307 if (sc == NULL || sc->sc_dying) 308 return (ENXIO); 309 310 if (sc->sc_is_open[endpt]) 311 return (EBUSY); 312 313 if (endpt == USB_CONTROL_ENDPOINT) { 314 sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1; 315 return (0); 316 } 317 318 /* Make sure there are pipes for all directions. */ 319 for (dir = OUT; dir <= IN; dir++) { 320 if (flag & (dir == OUT ? FWRITE : FREAD)) { 321 sce = &sc->sc_endpoints[endpt][dir]; 322 if (sce == 0 || sce->edesc == 0) 323 return (ENXIO); 324 } 325 } 326 327 /* Actually open the pipes. */ 328 /* XXX Should back out properly if it fails. */ 329 for (dir = OUT; dir <= IN; dir++) { 330 if (!(flag & (dir == OUT ? FWRITE : FREAD))) 331 continue; 332 sce = &sc->sc_endpoints[endpt][dir]; 333 sce->state = 0; 334 sce->timeout = USBD_NO_TIMEOUT; 335 DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n", 336 sc, endpt, dir, sce)); 337 edesc = sce->edesc; 338 switch (edesc->bmAttributes & UE_XFERTYPE) { 339 case UE_INTERRUPT: 340 isize = UGETW(edesc->wMaxPacketSize); 341 if (isize == 0) /* shouldn't happen */ 342 return (EINVAL); 343 sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK); 344 DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n", 345 endpt, isize)); 346 if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1) 347 return (ENOMEM); 348 err = usbd_open_pipe_intr(sce->iface, 349 edesc->bEndpointAddress, 350 USBD_SHORT_XFER_OK, &sce->pipeh, sce, 351 sce->ibuf, isize, ugenintr, 352 USBD_DEFAULT_INTERVAL); 353 if (err) { 354 free(sce->ibuf, M_USBDEV); 355 clfree(&sce->q); 356 return (EIO); 357 } 358 DPRINTFN(5, ("ugenopen: interrupt open done\n")); 359 break; 360 case UE_BULK: 361 err = usbd_open_pipe(sce->iface, 362 edesc->bEndpointAddress, 0, &sce->pipeh); 363 if (err) 364 return (EIO); 365 break; 366 case UE_ISOCHRONOUS: 367 if (dir == OUT) 368 return (EINVAL); 369 isize = UGETW(edesc->wMaxPacketSize); 370 if (isize == 0) /* shouldn't happen */ 371 return (EINVAL); 372 sce->ibuf = malloc(isize * UGEN_NISOFRAMES, 373 M_USBDEV, M_WAITOK); 374 sce->cur = sce->fill = sce->ibuf; 375 sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES; 376 DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n", 377 endpt, isize)); 378 err = usbd_open_pipe(sce->iface, 379 edesc->bEndpointAddress, 0, &sce->pipeh); 380 if (err) { 381 free(sce->ibuf, M_USBDEV); 382 return (EIO); 383 } 384 for(i = 0; i < UGEN_NISOREQS; ++i) { 385 sce->isoreqs[i].sce = sce; 386 xfer = usbd_alloc_xfer(sc->sc_udev); 387 if (xfer == 0) 388 goto bad; 389 sce->isoreqs[i].xfer = xfer; 390 buf = usbd_alloc_buffer 391 (xfer, isize * UGEN_NISORFRMS); 392 if (buf == 0) { 393 i++; 394 goto bad; 395 } 396 sce->isoreqs[i].dmabuf = buf; 397 for(j = 0; j < UGEN_NISORFRMS; ++j) 398 sce->isoreqs[i].sizes[j] = isize; 399 usbd_setup_isoc_xfer 400 (xfer, sce->pipeh, &sce->isoreqs[i], 401 sce->isoreqs[i].sizes, 402 UGEN_NISORFRMS, USBD_NO_COPY, 403 ugen_isoc_rintr); 404 (void)usbd_transfer(xfer); 405 } 406 DPRINTFN(5, ("ugenopen: isoc open done\n")); 407 break; 408 bad: 409 while (--i >= 0) /* implicit buffer free */ 410 usbd_free_xfer(sce->isoreqs[i].xfer); 411 return (ENOMEM); 412 case UE_CONTROL: 413 return (EINVAL); 414 } 415 } 416 sc->sc_is_open[endpt] = 1; 417 return (0); 418 } 419 420 int 421 ugenclose(dev_t dev, int flag, int mode, struct proc *p) 422 { 423 int endpt = UGENENDPOINT(dev); 424 struct ugen_softc *sc; 425 struct ugen_endpoint *sce; 426 int dir; 427 int i; 428 429 USB_GET_SC(ugen, UGENUNIT(dev), sc); 430 431 DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n", 432 flag, mode, UGENUNIT(dev), endpt)); 433 434 #ifdef DIAGNOSTIC 435 if (!sc->sc_is_open[endpt]) { 436 printf("ugenclose: not open\n"); 437 return (EINVAL); 438 } 439 #endif 440 441 if (endpt == USB_CONTROL_ENDPOINT) { 442 DPRINTFN(5, ("ugenclose: close control\n")); 443 sc->sc_is_open[endpt] = 0; 444 return (0); 445 } 446 447 for (dir = OUT; dir <= IN; dir++) { 448 if (!(flag & (dir == OUT ? FWRITE : FREAD))) 449 continue; 450 sce = &sc->sc_endpoints[endpt][dir]; 451 if (sce == NULL || sce->pipeh == NULL) 452 continue; 453 DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n", 454 endpt, dir, sce)); 455 456 usbd_abort_pipe(sce->pipeh); 457 usbd_close_pipe(sce->pipeh); 458 sce->pipeh = NULL; 459 460 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 461 case UE_INTERRUPT: 462 ndflush(&sce->q, sce->q.c_cc); 463 clfree(&sce->q); 464 break; 465 case UE_ISOCHRONOUS: 466 for (i = 0; i < UGEN_NISOREQS; ++i) 467 usbd_free_xfer(sce->isoreqs[i].xfer); 468 469 default: 470 break; 471 } 472 473 if (sce->ibuf != NULL) { 474 free(sce->ibuf, M_USBDEV); 475 sce->ibuf = NULL; 476 clfree(&sce->q); 477 478 } 479 } 480 sc->sc_is_open[endpt] = 0; 481 482 return (0); 483 } 484 485 Static int 486 ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) 487 { 488 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN]; 489 u_int32_t n, tn; 490 char buf[UGEN_BBSIZE]; 491 usbd_xfer_handle xfer; 492 usbd_status err; 493 int s; 494 int error = 0; 495 u_char buffer[UGEN_CHUNK]; 496 497 DPRINTFN(5, ("%s: ugenread: %d\n", USBDEVNAME(sc->sc_dev), endpt)); 498 499 if (sc->sc_dying) 500 return (EIO); 501 502 if (endpt == USB_CONTROL_ENDPOINT) 503 return (ENODEV); 504 505 #ifdef DIAGNOSTIC 506 if (sce->edesc == NULL) { 507 printf("ugenread: no edesc\n"); 508 return (EIO); 509 } 510 if (sce->pipeh == NULL) { 511 printf("ugenread: no pipe\n"); 512 return (EIO); 513 } 514 #endif 515 516 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 517 case UE_INTERRUPT: 518 /* Block until activity occurred. */ 519 s = splusb(); 520 while (sce->q.c_cc == 0) { 521 if (flag & IO_NDELAY) { 522 splx(s); 523 return (EWOULDBLOCK); 524 } 525 sce->state |= UGEN_ASLP; 526 DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); 527 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0); 528 DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); 529 if (sc->sc_dying) 530 error = EIO; 531 if (error) { 532 sce->state &= ~UGEN_ASLP; 533 break; 534 } 535 } 536 splx(s); 537 538 /* Transfer as many chunks as possible. */ 539 while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) { 540 n = min(sce->q.c_cc, uio->uio_resid); 541 if (n > sizeof(buffer)) 542 n = sizeof(buffer); 543 544 /* Remove a small chunk from the input queue. */ 545 q_to_b(&sce->q, buffer, n); 546 DPRINTFN(5, ("ugenread: got %d chars\n", n)); 547 548 /* Copy the data to the user process. */ 549 error = uiomove(buffer, n, uio); 550 if (error) 551 break; 552 } 553 break; 554 case UE_BULK: 555 xfer = usbd_alloc_xfer(sc->sc_udev); 556 if (xfer == 0) 557 return (ENOMEM); 558 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { 559 DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n)); 560 tn = n; 561 err = usbd_bulk_transfer( 562 xfer, sce->pipeh, 563 sce->state & UGEN_SHORT_OK ? 564 USBD_SHORT_XFER_OK : 0, 565 sce->timeout, buf, &tn, "ugenrb"); 566 if (err) { 567 if (err == USBD_INTERRUPTED) 568 error = EINTR; 569 else if (err == USBD_TIMEOUT) 570 error = ETIMEDOUT; 571 else 572 error = EIO; 573 break; 574 } 575 DPRINTFN(1, ("ugenread: got %d bytes\n", tn)); 576 error = uiomove(buf, tn, uio); 577 if (error || tn < n) 578 break; 579 } 580 usbd_free_xfer(xfer); 581 break; 582 case UE_ISOCHRONOUS: 583 s = splusb(); 584 while (sce->cur == sce->fill) { 585 if (flag & IO_NDELAY) { 586 splx(s); 587 return (EWOULDBLOCK); 588 } 589 sce->state |= UGEN_ASLP; 590 DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); 591 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0); 592 DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); 593 if (sc->sc_dying) 594 error = EIO; 595 if (error) { 596 sce->state &= ~UGEN_ASLP; 597 break; 598 } 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 USB_GET_SC(ugen, UGENUNIT(dev), sc); 635 636 sc->sc_refcnt++; 637 error = ugen_do_read(sc, endpt, uio, flag); 638 if (--sc->sc_refcnt < 0) 639 usb_detach_wakeup(USBDEV(sc->sc_dev)); 640 return (error); 641 } 642 643 Static 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", USBDEVNAME(sc->sc_dev), 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 default: 697 return (ENXIO); 698 } 699 return (error); 700 } 701 702 int 703 ugenwrite(dev_t dev, struct uio *uio, int flag) 704 { 705 int endpt = UGENENDPOINT(dev); 706 struct ugen_softc *sc; 707 int error; 708 709 USB_GET_SC(ugen, UGENUNIT(dev), sc); 710 711 sc->sc_refcnt++; 712 error = ugen_do_write(sc, endpt, uio, flag); 713 if (--sc->sc_refcnt < 0) 714 usb_detach_wakeup(USBDEV(sc->sc_dev)); 715 return (error); 716 } 717 718 #if defined(__NetBSD__) || defined(__OpenBSD__) 719 int 720 ugen_activate(device_ptr_t self, enum devact act) 721 { 722 struct ugen_softc *sc = (struct ugen_softc *)self; 723 724 switch (act) { 725 case DVACT_ACTIVATE: 726 return (EOPNOTSUPP); 727 break; 728 729 case DVACT_DEACTIVATE: 730 sc->sc_dying = 1; 731 break; 732 } 733 return (0); 734 } 735 #endif 736 737 USB_DETACH(ugen) 738 { 739 USB_DETACH_START(ugen, sc); 740 struct ugen_endpoint *sce; 741 int i, dir; 742 int s; 743 #if defined(__NetBSD__) || defined(__OpenBSD__) 744 int maj, mn; 745 746 DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags)); 747 #elif defined(__FreeBSD__) 748 DPRINTF(("ugen_detach: sc=%p\n", sc)); 749 #endif 750 751 sc->sc_dying = 1; 752 /* Abort all pipes. Causes processes waiting for transfer to wake. */ 753 for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 754 for (dir = OUT; dir <= IN; dir++) { 755 sce = &sc->sc_endpoints[i][dir]; 756 if (sce && sce->pipeh) 757 usbd_abort_pipe(sce->pipeh); 758 } 759 } 760 761 s = splusb(); 762 if (--sc->sc_refcnt >= 0) { 763 /* Wake everyone */ 764 for (i = 0; i < USB_MAX_ENDPOINTS; i++) 765 wakeup(&sc->sc_endpoints[i][IN]); 766 /* Wait for processes to go away. */ 767 usb_detach_wait(USBDEV(sc->sc_dev)); 768 } 769 splx(s); 770 771 #if defined(__NetBSD__) || defined(__OpenBSD__) 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 #elif defined(__FreeBSD__) 781 /* XXX not implemented yet */ 782 #endif 783 784 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 785 USBDEV(sc->sc_dev)); 786 787 return (0); 788 } 789 790 Static void 791 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) 792 { 793 struct ugen_endpoint *sce = addr; 794 /*struct ugen_softc *sc = sce->sc;*/ 795 u_int32_t count; 796 u_char *ibuf; 797 798 if (status == USBD_CANCELLED) 799 return; 800 801 if (status != USBD_NORMAL_COMPLETION) { 802 DPRINTF(("ugenintr: status=%d\n", status)); 803 usbd_clear_endpoint_stall_async(sce->pipeh); 804 return; 805 } 806 807 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 808 ibuf = sce->ibuf; 809 810 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n", 811 xfer, status, count)); 812 DPRINTFN(5, (" data = %02x %02x %02x\n", 813 ibuf[0], ibuf[1], ibuf[2])); 814 815 (void)b_to_q(ibuf, count, &sce->q); 816 817 if (sce->state & UGEN_ASLP) { 818 sce->state &= ~UGEN_ASLP; 819 DPRINTFN(5, ("ugen_intr: waking %p\n", sce)); 820 wakeup(sce); 821 } 822 selwakeup(&sce->rsel); 823 } 824 825 Static void 826 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, 827 usbd_status status) 828 { 829 struct isoreq *req = addr; 830 struct ugen_endpoint *sce = req->sce; 831 u_int32_t count, n; 832 int i, isize; 833 834 /* Return if we are aborting. */ 835 if (status == USBD_CANCELLED) 836 return; 837 838 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 839 DPRINTFN(5,("ugen_isoc_rintr: xfer %d, count=%d\n", req - sce->isoreqs, 840 count)); 841 842 /* throw away oldest input if the buffer is full */ 843 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) { 844 sce->cur += count; 845 if(sce->cur >= sce->limit) 846 sce->cur = sce->ibuf + (sce->limit - sce->cur); 847 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n", 848 count)); 849 } 850 851 isize = UGETW(sce->edesc->wMaxPacketSize); 852 for (i = 0; i < UGEN_NISORFRMS; i++) { 853 u_int32_t actlen = req->sizes[i]; 854 char const *buf = (char const *)req->dmabuf + isize * i; 855 856 /* copy data to buffer */ 857 while (actlen > 0) { 858 n = min(actlen, sce->limit - sce->fill); 859 memcpy(sce->fill, buf, n); 860 861 buf += n; 862 actlen -= n; 863 sce->fill += n; 864 if(sce->fill == sce->limit) 865 sce->fill = sce->ibuf; 866 } 867 868 /* setup size for next transfer */ 869 req->sizes[i] = isize; 870 } 871 872 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS, 873 USBD_NO_COPY, ugen_isoc_rintr); 874 (void)usbd_transfer(xfer); 875 876 if (sce->state & UGEN_ASLP) { 877 sce->state &= ~UGEN_ASLP; 878 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce)); 879 wakeup(sce); 880 } 881 selwakeup(&sce->rsel); 882 } 883 884 Static usbd_status 885 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) 886 { 887 usbd_interface_handle iface; 888 usb_endpoint_descriptor_t *ed; 889 usbd_status err; 890 struct ugen_endpoint *sce; 891 u_int8_t niface, nendpt, endptno, endpt; 892 int dir; 893 894 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); 895 896 err = usbd_interface_count(sc->sc_udev, &niface); 897 if (err) 898 return (err); 899 if (ifaceidx < 0 || ifaceidx >= niface) 900 return (USBD_INVAL); 901 902 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); 903 if (err) 904 return (err); 905 err = usbd_endpoint_count(iface, &nendpt); 906 if (err) 907 return (err); 908 /* XXX should only do this after setting new altno has succeeded */ 909 for (endptno = 0; endptno < nendpt; endptno++) { 910 ed = usbd_interface2endpoint_descriptor(iface,endptno); 911 endpt = ed->bEndpointAddress; 912 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 913 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 914 sce->sc = 0; 915 sce->edesc = 0; 916 sce->iface = 0; 917 } 918 919 /* change setting */ 920 err = usbd_set_interface(iface, altno); 921 if (err) 922 return (err); 923 924 err = usbd_endpoint_count(iface, &nendpt); 925 if (err) 926 return (err); 927 for (endptno = 0; endptno < nendpt; endptno++) { 928 ed = usbd_interface2endpoint_descriptor(iface,endptno); 929 endpt = ed->bEndpointAddress; 930 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 931 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 932 sce->sc = sc; 933 sce->edesc = ed; 934 sce->iface = iface; 935 } 936 return (0); 937 } 938 939 /* Retrieve a complete descriptor for a certain device and index. */ 940 Static usb_config_descriptor_t * 941 ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp) 942 { 943 usb_config_descriptor_t *cdesc, *tdesc, cdescr; 944 int len; 945 usbd_status err; 946 947 if (index == USB_CURRENT_CONFIG_INDEX) { 948 tdesc = usbd_get_config_descriptor(sc->sc_udev); 949 len = UGETW(tdesc->wTotalLength); 950 if (lenp) 951 *lenp = len; 952 cdesc = malloc(len, M_TEMP, M_WAITOK); 953 memcpy(cdesc, tdesc, len); 954 DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len)); 955 } else { 956 err = usbd_get_config_desc(sc->sc_udev, index, &cdescr); 957 if (err) 958 return (0); 959 len = UGETW(cdescr.wTotalLength); 960 DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len)); 961 if (lenp) 962 *lenp = len; 963 cdesc = malloc(len, M_TEMP, M_WAITOK); 964 err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc,len); 965 if (err) { 966 free(cdesc, M_TEMP); 967 return (0); 968 } 969 } 970 return (cdesc); 971 } 972 973 Static 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 Static 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 if (endpt == USB_CONTROL_ENDPOINT) { 1024 /* XXX the lower levels don't support this yet. */ 1025 return (EINVAL); 1026 } 1027 sce = &sc->sc_endpoints[endpt][IN]; 1028 if (sce == NULL || sce->pipeh == NULL) 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 if (err) 1056 return (EIO); 1057 break; 1058 case USB_GET_ALTINTERFACE: 1059 ai = (struct usb_alt_interface *)addr; 1060 err = usbd_device2interface_handle(sc->sc_udev, 1061 ai->interface_index, &iface); 1062 if (err) 1063 return (EINVAL); 1064 idesc = usbd_get_interface_descriptor(iface); 1065 if (idesc == NULL) 1066 return (EIO); 1067 ai->alt_no = idesc->bAlternateSetting; 1068 break; 1069 case USB_SET_ALTINTERFACE: 1070 if (!(flag & FWRITE)) 1071 return (EPERM); 1072 ai = (struct usb_alt_interface *)addr; 1073 err = usbd_device2interface_handle(sc->sc_udev, 1074 ai->interface_index, &iface); 1075 if (err) 1076 return (EINVAL); 1077 err = ugen_set_interface(sc, ai->interface_index, ai->alt_no); 1078 if (err) 1079 return (EINVAL); 1080 break; 1081 case USB_GET_NO_ALT: 1082 ai = (struct usb_alt_interface *)addr; 1083 cdesc = ugen_get_cdesc(sc, ai->config_index, 0); 1084 if (cdesc == NULL) 1085 return (EINVAL); 1086 idesc = usbd_find_idesc(cdesc, ai->interface_index, 0); 1087 if (idesc == NULL) { 1088 free(cdesc, M_TEMP); 1089 return (EINVAL); 1090 } 1091 ai->alt_no = usbd_get_no_alts(cdesc, idesc->bInterfaceNumber); 1092 free(cdesc, M_TEMP); 1093 break; 1094 case USB_GET_DEVICE_DESC: 1095 *(usb_device_descriptor_t *)addr = 1096 *usbd_get_device_descriptor(sc->sc_udev); 1097 break; 1098 case USB_GET_CONFIG_DESC: 1099 cd = (struct usb_config_desc *)addr; 1100 cdesc = ugen_get_cdesc(sc, cd->config_index, 0); 1101 if (cdesc == NULL) 1102 return (EINVAL); 1103 cd->desc = *cdesc; 1104 free(cdesc, M_TEMP); 1105 break; 1106 case USB_GET_INTERFACE_DESC: 1107 id = (struct usb_interface_desc *)addr; 1108 cdesc = ugen_get_cdesc(sc, id->config_index, 0); 1109 if (cdesc == NULL) 1110 return (EINVAL); 1111 if (id->config_index == USB_CURRENT_CONFIG_INDEX && 1112 id->alt_index == USB_CURRENT_ALT_INDEX) 1113 alt = ugen_get_alt_index(sc, id->interface_index); 1114 else 1115 alt = id->alt_index; 1116 idesc = usbd_find_idesc(cdesc, id->interface_index, alt); 1117 if (idesc == NULL) { 1118 free(cdesc, M_TEMP); 1119 return (EINVAL); 1120 } 1121 id->desc = *idesc; 1122 free(cdesc, M_TEMP); 1123 break; 1124 case USB_GET_ENDPOINT_DESC: 1125 ed = (struct usb_endpoint_desc *)addr; 1126 cdesc = ugen_get_cdesc(sc, ed->config_index, 0); 1127 if (cdesc == NULL) 1128 return (EINVAL); 1129 if (ed->config_index == USB_CURRENT_CONFIG_INDEX && 1130 ed->alt_index == USB_CURRENT_ALT_INDEX) 1131 alt = ugen_get_alt_index(sc, ed->interface_index); 1132 else 1133 alt = ed->alt_index; 1134 edesc = usbd_find_edesc(cdesc, ed->interface_index, 1135 alt, ed->endpoint_index); 1136 if (edesc == NULL) { 1137 free(cdesc, M_TEMP); 1138 return (EINVAL); 1139 } 1140 ed->desc = *edesc; 1141 free(cdesc, M_TEMP); 1142 break; 1143 case USB_GET_FULL_DESC: 1144 { 1145 int len; 1146 struct iovec iov; 1147 struct uio uio; 1148 struct usb_full_desc *fd = (struct usb_full_desc *)addr; 1149 int error; 1150 1151 cdesc = ugen_get_cdesc(sc, fd->config_index, &len); 1152 if (len > fd->size) 1153 len = fd->size; 1154 iov.iov_base = (caddr_t)fd->data; 1155 iov.iov_len = len; 1156 uio.uio_iov = &iov; 1157 uio.uio_iovcnt = 1; 1158 uio.uio_resid = len; 1159 uio.uio_offset = 0; 1160 uio.uio_segflg = UIO_USERSPACE; 1161 uio.uio_rw = UIO_READ; 1162 uio.uio_procp = p; 1163 error = uiomove((void *)cdesc, len, &uio); 1164 free(cdesc, M_TEMP); 1165 return (error); 1166 } 1167 case USB_GET_STRING_DESC: 1168 si = (struct usb_string_desc *)addr; 1169 err = usbd_get_string_desc(sc->sc_udev, si->string_index, 1170 si->language_id, &si->desc); 1171 if (err) 1172 return (EINVAL); 1173 break; 1174 case USB_DO_REQUEST: 1175 { 1176 struct usb_ctl_request *ur = (void *)addr; 1177 int len = UGETW(ur->request.wLength); 1178 struct iovec iov; 1179 struct uio uio; 1180 void *ptr = 0; 1181 usbd_status err; 1182 int error = 0; 1183 1184 if (!(flag & FWRITE)) 1185 return (EPERM); 1186 /* Avoid requests that would damage the bus integrity. */ 1187 if ((ur->request.bmRequestType == UT_WRITE_DEVICE && 1188 ur->request.bRequest == UR_SET_ADDRESS) || 1189 (ur->request.bmRequestType == UT_WRITE_DEVICE && 1190 ur->request.bRequest == UR_SET_CONFIG) || 1191 (ur->request.bmRequestType == UT_WRITE_INTERFACE && 1192 ur->request.bRequest == UR_SET_INTERFACE)) 1193 return (EINVAL); 1194 1195 if (len < 0 || len > 32767) 1196 return (EINVAL); 1197 if (len != 0) { 1198 iov.iov_base = (caddr_t)ur->data; 1199 iov.iov_len = len; 1200 uio.uio_iov = &iov; 1201 uio.uio_iovcnt = 1; 1202 uio.uio_resid = len; 1203 uio.uio_offset = 0; 1204 uio.uio_segflg = UIO_USERSPACE; 1205 uio.uio_rw = 1206 ur->request.bmRequestType & UT_READ ? 1207 UIO_READ : UIO_WRITE; 1208 uio.uio_procp = p; 1209 ptr = malloc(len, M_TEMP, M_WAITOK); 1210 if (uio.uio_rw == UIO_WRITE) { 1211 error = uiomove(ptr, len, &uio); 1212 if (error) 1213 goto ret; 1214 } 1215 } 1216 err = usbd_do_request_flags(sc->sc_udev, &ur->request, 1217 ptr, ur->flags, &ur->actlen); 1218 if (err) { 1219 error = EIO; 1220 goto ret; 1221 } 1222 if (len != 0) { 1223 if (uio.uio_rw == UIO_READ) { 1224 error = uiomove(ptr, len, &uio); 1225 if (error) 1226 goto ret; 1227 } 1228 } 1229 ret: 1230 if (ptr) 1231 free(ptr, M_TEMP); 1232 return (error); 1233 } 1234 case USB_GET_DEVICEINFO: 1235 usbd_fill_deviceinfo(sc->sc_udev, 1236 (struct usb_device_info *)addr, 1); 1237 break; 1238 default: 1239 return (EINVAL); 1240 } 1241 return (0); 1242 } 1243 1244 int 1245 ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 1246 { 1247 int endpt = UGENENDPOINT(dev); 1248 struct ugen_softc *sc; 1249 int error; 1250 1251 USB_GET_SC(ugen, UGENUNIT(dev), sc); 1252 1253 sc->sc_refcnt++; 1254 error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p); 1255 if (--sc->sc_refcnt < 0) 1256 usb_detach_wakeup(USBDEV(sc->sc_dev)); 1257 return (error); 1258 } 1259 1260 int 1261 ugenpoll(dev_t dev, int events, struct proc *p) 1262 { 1263 struct ugen_softc *sc; 1264 struct ugen_endpoint *sce; 1265 int revents = 0; 1266 int s; 1267 1268 USB_GET_SC(ugen, UGENUNIT(dev), sc); 1269 1270 if (sc->sc_dying) 1271 return (EIO); 1272 1273 /* XXX always IN */ 1274 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; 1275 if (sce == NULL) 1276 return (EINVAL); 1277 #ifdef DIAGNOSTIC 1278 if (!sce->edesc) { 1279 printf("ugenpoll: no edesc\n"); 1280 return (EIO); 1281 } 1282 if (!sce->pipeh) { 1283 printf("ugenpoll: no pipe\n"); 1284 return (EIO); 1285 } 1286 #endif 1287 s = splusb(); 1288 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1289 case UE_INTERRUPT: 1290 if (events & (POLLIN | POLLRDNORM)) { 1291 if (sce->q.c_cc > 0) 1292 revents |= events & (POLLIN | POLLRDNORM); 1293 else 1294 selrecord(p, &sce->rsel); 1295 } 1296 break; 1297 case UE_ISOCHRONOUS: 1298 if (events & (POLLIN | POLLRDNORM)) { 1299 if (sce->cur != sce->fill) 1300 revents |= events & (POLLIN | POLLRDNORM); 1301 else 1302 selrecord(p, &sce->rsel); 1303 } 1304 break; 1305 case UE_BULK: 1306 /* 1307 * We have no easy way of determining if a read will 1308 * yield any data or a write will happen. 1309 * Pretend they will. 1310 */ 1311 revents |= events & 1312 (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM); 1313 break; 1314 default: 1315 break; 1316 } 1317 splx(s); 1318 return (revents); 1319 } 1320 1321 #if defined(__FreeBSD__) 1322 DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, usbd_driver_load, 0); 1323 #endif 1324