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