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