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