1 /* $OpenBSD: ugen.c,v 1.64 2011/01/25 20:03:36 jakemsr 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_ACTIVATE: 750 break; 751 752 case DVACT_DEACTIVATE: 753 sc->sc_dying = 1; 754 break; 755 } 756 return (0); 757 } 758 759 int 760 ugen_detach(struct device *self, int flags) 761 { 762 struct ugen_softc *sc = (struct ugen_softc *)self; 763 struct ugen_endpoint *sce; 764 int i, dir; 765 int s; 766 int maj, mn; 767 768 DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags)); 769 770 /* Abort all pipes. Causes processes waiting for transfer to wake. */ 771 for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 772 for (dir = OUT; dir <= IN; dir++) { 773 sce = &sc->sc_endpoints[i][dir]; 774 if (sce && sce->pipeh) 775 usbd_abort_pipe(sce->pipeh); 776 } 777 } 778 779 s = splusb(); 780 if (--sc->sc_refcnt >= 0) { 781 /* Wake everyone */ 782 for (i = 0; i < USB_MAX_ENDPOINTS; i++) 783 wakeup(&sc->sc_endpoints[i][IN]); 784 /* Wait for processes to go away. */ 785 usb_detach_wait(&sc->sc_dev); 786 } 787 splx(s); 788 789 /* locate the major number */ 790 for (maj = 0; maj < nchrdev; maj++) 791 if (cdevsw[maj].d_open == ugenopen) 792 break; 793 794 /* Nuke the vnodes for any open instances (calls close). */ 795 mn = self->dv_unit * USB_MAX_ENDPOINTS; 796 vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR); 797 798 return (0); 799 } 800 801 void 802 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) 803 { 804 struct ugen_endpoint *sce = addr; 805 /*struct ugen_softc *sc = sce->sc;*/ 806 u_int32_t count; 807 u_char *ibuf; 808 809 if (status == USBD_CANCELLED) 810 return; 811 812 if (status != USBD_NORMAL_COMPLETION) { 813 DPRINTF(("ugenintr: status=%d\n", status)); 814 if (status == USBD_STALLED) 815 usbd_clear_endpoint_stall_async(sce->pipeh); 816 return; 817 } 818 819 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 820 ibuf = sce->ibuf; 821 822 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n", 823 xfer, status, count)); 824 DPRINTFN(5, (" data = %02x %02x %02x\n", 825 ibuf[0], ibuf[1], ibuf[2])); 826 827 (void)b_to_q(ibuf, count, &sce->q); 828 829 if (sce->state & UGEN_ASLP) { 830 sce->state &= ~UGEN_ASLP; 831 DPRINTFN(5, ("ugen_intr: waking %p\n", sce)); 832 wakeup(sce); 833 } 834 selwakeup(&sce->rsel); 835 } 836 837 void 838 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, 839 usbd_status status) 840 { 841 struct isoreq *req = addr; 842 struct ugen_endpoint *sce = req->sce; 843 u_int32_t count, n; 844 int i, isize; 845 846 /* Return if we are aborting. */ 847 if (status == USBD_CANCELLED) 848 return; 849 850 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 851 DPRINTFN(5,("ugen_isoc_rintr: xfer %d, count=%d\n", req - sce->isoreqs, 852 count)); 853 854 /* throw away oldest input if the buffer is full */ 855 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) { 856 sce->cur += count; 857 if(sce->cur >= sce->limit) 858 sce->cur = sce->ibuf + (sce->limit - sce->cur); 859 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n", 860 count)); 861 } 862 863 isize = UGETW(sce->edesc->wMaxPacketSize); 864 for (i = 0; i < UGEN_NISORFRMS; i++) { 865 u_int32_t actlen = req->sizes[i]; 866 char const *buf = (char const *)req->dmabuf + isize * i; 867 868 /* copy data to buffer */ 869 while (actlen > 0) { 870 n = min(actlen, sce->limit - sce->fill); 871 memcpy(sce->fill, buf, n); 872 873 buf += n; 874 actlen -= n; 875 sce->fill += n; 876 if(sce->fill == sce->limit) 877 sce->fill = sce->ibuf; 878 } 879 880 /* setup size for next transfer */ 881 req->sizes[i] = isize; 882 } 883 884 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS, 885 USBD_NO_COPY, ugen_isoc_rintr); 886 (void)usbd_transfer(xfer); 887 888 if (sce->state & UGEN_ASLP) { 889 sce->state &= ~UGEN_ASLP; 890 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce)); 891 wakeup(sce); 892 } 893 selwakeup(&sce->rsel); 894 } 895 896 usbd_status 897 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) 898 { 899 usbd_interface_handle iface; 900 usb_endpoint_descriptor_t *ed; 901 usbd_status err; 902 struct ugen_endpoint *sce; 903 u_int8_t niface, nendpt, endptno, endpt; 904 int dir; 905 906 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); 907 908 err = usbd_interface_count(sc->sc_udev, &niface); 909 if (err) 910 return (err); 911 if (ifaceidx < 0 || ifaceidx >= niface || 912 usbd_iface_claimed(sc->sc_udev, ifaceidx)) 913 return (USBD_INVAL); 914 915 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); 916 if (err) 917 return (err); 918 err = usbd_endpoint_count(iface, &nendpt); 919 if (err) 920 return (err); 921 for (endptno = 0; endptno < nendpt; endptno++) { 922 ed = usbd_interface2endpoint_descriptor(iface,endptno); 923 endpt = ed->bEndpointAddress; 924 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 925 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 926 sce->sc = 0; 927 sce->edesc = 0; 928 sce->iface = 0; 929 } 930 931 /* change setting */ 932 err = usbd_set_interface(iface, altno); 933 if (err) 934 goto out; 935 936 err = usbd_endpoint_count(iface, &nendpt); 937 if (err) 938 goto out; 939 940 out: 941 for (endptno = 0; endptno < nendpt; endptno++) { 942 ed = usbd_interface2endpoint_descriptor(iface,endptno); 943 endpt = ed->bEndpointAddress; 944 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 945 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 946 sce->sc = sc; 947 sce->edesc = ed; 948 sce->iface = iface; 949 } 950 return (err); 951 } 952 953 /* Retrieve a complete descriptor for a certain device and index. */ 954 usb_config_descriptor_t * 955 ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp) 956 { 957 usb_config_descriptor_t *cdesc, *tdesc, cdescr; 958 int len; 959 usbd_status err; 960 961 if (index == USB_CURRENT_CONFIG_INDEX) { 962 tdesc = usbd_get_config_descriptor(sc->sc_udev); 963 len = UGETW(tdesc->wTotalLength); 964 if (lenp) 965 *lenp = len; 966 cdesc = malloc(len, M_TEMP, M_WAITOK); 967 memcpy(cdesc, tdesc, len); 968 DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len)); 969 } else { 970 err = usbd_get_config_desc(sc->sc_udev, index, &cdescr); 971 if (err) 972 return (0); 973 len = UGETW(cdescr.wTotalLength); 974 DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len)); 975 if (lenp) 976 *lenp = len; 977 cdesc = malloc(len, M_TEMP, M_WAITOK); 978 err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, 979 len); 980 if (err) { 981 free(cdesc, M_TEMP); 982 return (0); 983 } 984 } 985 return (cdesc); 986 } 987 988 int 989 ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx) 990 { 991 usbd_interface_handle iface; 992 usbd_status err; 993 994 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); 995 if (err) 996 return (-1); 997 return (usbd_get_interface_altindex(iface)); 998 } 999 1000 int 1001 ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, 1002 caddr_t addr, int flag, struct proc *p) 1003 { 1004 struct ugen_endpoint *sce; 1005 usbd_status err; 1006 usbd_interface_handle iface; 1007 struct usb_config_desc *cd; 1008 usb_config_descriptor_t *cdesc; 1009 struct usb_interface_desc *id; 1010 usb_interface_descriptor_t *idesc; 1011 struct usb_endpoint_desc *ed; 1012 usb_endpoint_descriptor_t *edesc; 1013 struct usb_alt_interface *ai; 1014 struct usb_string_desc *si; 1015 u_int8_t conf, alt; 1016 1017 DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd)); 1018 if (sc->sc_dying) 1019 return (EIO); 1020 1021 switch (cmd) { 1022 case FIONBIO: 1023 /* All handled in the upper FS layer. */ 1024 return (0); 1025 case USB_SET_SHORT_XFER: 1026 if (endpt == USB_CONTROL_ENDPOINT) 1027 return (EINVAL); 1028 /* This flag only affects read */ 1029 sce = &sc->sc_endpoints[endpt][IN]; 1030 if (sce == NULL || sce->pipeh == NULL) 1031 return (EINVAL); 1032 if (*(int *)addr) 1033 sce->state |= UGEN_SHORT_OK; 1034 else 1035 sce->state &= ~UGEN_SHORT_OK; 1036 return (0); 1037 case USB_SET_TIMEOUT: 1038 sce = &sc->sc_endpoints[endpt][IN]; 1039 if (sce == NULL) 1040 return (EINVAL); 1041 sce->timeout = *(int *)addr; 1042 sce = &sc->sc_endpoints[endpt][OUT]; 1043 if (sce == NULL) 1044 return (EINVAL); 1045 sce->timeout = *(int *)addr; 1046 return (0); 1047 default: 1048 break; 1049 } 1050 1051 if (endpt != USB_CONTROL_ENDPOINT) 1052 return (EINVAL); 1053 1054 switch (cmd) { 1055 #ifdef UGEN_DEBUG 1056 case USB_SETDEBUG: 1057 ugendebug = *(int *)addr; 1058 break; 1059 #endif 1060 case USB_GET_CONFIG: 1061 err = usbd_get_config(sc->sc_udev, &conf); 1062 if (err) 1063 return (EIO); 1064 *(int *)addr = conf; 1065 break; 1066 case USB_SET_CONFIG: 1067 if (!(flag & FWRITE)) 1068 return (EPERM); 1069 err = ugen_set_config(sc, *(int *)addr); 1070 switch (err) { 1071 case USBD_NORMAL_COMPLETION: 1072 break; 1073 case USBD_IN_USE: 1074 return (EBUSY); 1075 default: 1076 return (EIO); 1077 } 1078 break; 1079 case USB_GET_ALTINTERFACE: 1080 ai = (struct usb_alt_interface *)addr; 1081 err = usbd_device2interface_handle(sc->sc_udev, 1082 ai->uai_interface_index, &iface); 1083 if (err) 1084 return (EINVAL); 1085 idesc = usbd_get_interface_descriptor(iface); 1086 if (idesc == NULL) 1087 return (EIO); 1088 ai->uai_alt_no = idesc->bAlternateSetting; 1089 break; 1090 case USB_SET_ALTINTERFACE: 1091 if (!(flag & FWRITE)) 1092 return (EPERM); 1093 ai = (struct usb_alt_interface *)addr; 1094 err = usbd_device2interface_handle(sc->sc_udev, 1095 ai->uai_interface_index, &iface); 1096 if (err) 1097 return (EINVAL); 1098 err = ugen_set_interface(sc, ai->uai_interface_index, 1099 ai->uai_alt_no); 1100 if (err) 1101 return (EINVAL); 1102 break; 1103 case USB_GET_NO_ALT: 1104 ai = (struct usb_alt_interface *)addr; 1105 cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0); 1106 if (cdesc == NULL) 1107 return (EINVAL); 1108 idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0); 1109 if (idesc == NULL) { 1110 free(cdesc, M_TEMP); 1111 return (EINVAL); 1112 } 1113 ai->uai_alt_no = usbd_get_no_alts(cdesc, 1114 idesc->bInterfaceNumber); 1115 free(cdesc, M_TEMP); 1116 break; 1117 case USB_GET_DEVICE_DESC: 1118 *(usb_device_descriptor_t *)addr = 1119 *usbd_get_device_descriptor(sc->sc_udev); 1120 break; 1121 case USB_GET_CONFIG_DESC: 1122 cd = (struct usb_config_desc *)addr; 1123 cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0); 1124 if (cdesc == NULL) 1125 return (EINVAL); 1126 cd->ucd_desc = *cdesc; 1127 free(cdesc, M_TEMP); 1128 break; 1129 case USB_GET_INTERFACE_DESC: 1130 id = (struct usb_interface_desc *)addr; 1131 cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0); 1132 if (cdesc == NULL) 1133 return (EINVAL); 1134 if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX && 1135 id->uid_alt_index == USB_CURRENT_ALT_INDEX) 1136 alt = ugen_get_alt_index(sc, id->uid_interface_index); 1137 else 1138 alt = id->uid_alt_index; 1139 idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt); 1140 if (idesc == NULL) { 1141 free(cdesc, M_TEMP); 1142 return (EINVAL); 1143 } 1144 id->uid_desc = *idesc; 1145 free(cdesc, M_TEMP); 1146 break; 1147 case USB_GET_ENDPOINT_DESC: 1148 ed = (struct usb_endpoint_desc *)addr; 1149 cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0); 1150 if (cdesc == NULL) 1151 return (EINVAL); 1152 if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX && 1153 ed->ued_alt_index == USB_CURRENT_ALT_INDEX) 1154 alt = ugen_get_alt_index(sc, ed->ued_interface_index); 1155 else 1156 alt = ed->ued_alt_index; 1157 edesc = usbd_find_edesc(cdesc, ed->ued_interface_index, 1158 alt, ed->ued_endpoint_index); 1159 if (edesc == NULL) { 1160 free(cdesc, M_TEMP); 1161 return (EINVAL); 1162 } 1163 ed->ued_desc = *edesc; 1164 free(cdesc, M_TEMP); 1165 break; 1166 case USB_GET_FULL_DESC: 1167 { 1168 int len; 1169 struct iovec iov; 1170 struct uio uio; 1171 struct usb_full_desc *fd = (struct usb_full_desc *)addr; 1172 int error; 1173 1174 cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len); 1175 if (len > fd->ufd_size) 1176 len = fd->ufd_size; 1177 iov.iov_base = (caddr_t)fd->ufd_data; 1178 iov.iov_len = len; 1179 uio.uio_iov = &iov; 1180 uio.uio_iovcnt = 1; 1181 uio.uio_resid = len; 1182 uio.uio_offset = 0; 1183 uio.uio_segflg = UIO_USERSPACE; 1184 uio.uio_rw = UIO_READ; 1185 uio.uio_procp = p; 1186 error = uiomove((void *)cdesc, len, &uio); 1187 free(cdesc, M_TEMP); 1188 return (error); 1189 } 1190 case USB_GET_STRING_DESC: 1191 { 1192 int len; 1193 si = (struct usb_string_desc *)addr; 1194 err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index, 1195 si->usd_language_id, &si->usd_desc, &len); 1196 if (err) 1197 return (EINVAL); 1198 break; 1199 } 1200 case USB_DO_REQUEST: 1201 { 1202 struct usb_ctl_request *ur = (void *)addr; 1203 int len = UGETW(ur->ucr_request.wLength); 1204 struct iovec iov; 1205 struct uio uio; 1206 void *ptr = 0; 1207 int error = 0; 1208 1209 if (!(flag & FWRITE)) 1210 return (EPERM); 1211 /* Avoid requests that would damage the bus integrity. */ 1212 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 1213 ur->ucr_request.bRequest == UR_SET_ADDRESS) || 1214 (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 1215 ur->ucr_request.bRequest == UR_SET_CONFIG) || 1216 (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE && 1217 ur->ucr_request.bRequest == UR_SET_INTERFACE)) 1218 return (EINVAL); 1219 1220 if (len < 0 || len > 32767) 1221 return (EINVAL); 1222 if (len != 0) { 1223 iov.iov_base = (caddr_t)ur->ucr_data; 1224 iov.iov_len = len; 1225 uio.uio_iov = &iov; 1226 uio.uio_iovcnt = 1; 1227 uio.uio_resid = len; 1228 uio.uio_offset = 0; 1229 uio.uio_segflg = UIO_USERSPACE; 1230 uio.uio_rw = 1231 ur->ucr_request.bmRequestType & UT_READ ? 1232 UIO_READ : UIO_WRITE; 1233 uio.uio_procp = p; 1234 ptr = malloc(len, M_TEMP, M_WAITOK); 1235 if (uio.uio_rw == UIO_WRITE) { 1236 error = uiomove(ptr, len, &uio); 1237 if (error) 1238 goto ret; 1239 } 1240 } 1241 sce = &sc->sc_endpoints[endpt][IN]; 1242 err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request, 1243 ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout); 1244 if (err) { 1245 error = EIO; 1246 goto ret; 1247 } 1248 if (len != 0) { 1249 if (uio.uio_rw == UIO_READ) { 1250 error = uiomove(ptr, len, &uio); 1251 if (error) 1252 goto ret; 1253 } 1254 } 1255 ret: 1256 if (ptr) 1257 free(ptr, M_TEMP); 1258 return (error); 1259 } 1260 case USB_GET_DEVICEINFO: 1261 usbd_fill_deviceinfo(sc->sc_udev, 1262 (struct usb_device_info *)addr, 1); 1263 break; 1264 default: 1265 return (EINVAL); 1266 } 1267 return (0); 1268 } 1269 1270 int 1271 ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 1272 { 1273 int endpt = UGENENDPOINT(dev); 1274 struct ugen_softc *sc; 1275 int error; 1276 1277 sc = ugen_cd.cd_devs[UGENUNIT(dev)]; 1278 1279 sc->sc_refcnt++; 1280 error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p); 1281 if (--sc->sc_refcnt < 0) 1282 usb_detach_wakeup(&sc->sc_dev); 1283 return (error); 1284 } 1285 1286 int 1287 ugenpoll(dev_t dev, int events, struct proc *p) 1288 { 1289 struct ugen_softc *sc; 1290 struct ugen_endpoint *sce; 1291 int revents = 0; 1292 int s; 1293 1294 sc = ugen_cd.cd_devs[UGENUNIT(dev)]; 1295 1296 if (sc->sc_dying) 1297 return (POLLERR); 1298 1299 /* XXX always IN */ 1300 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; 1301 if (sce == NULL) 1302 return (POLLERR); 1303 #ifdef DIAGNOSTIC 1304 if (!sce->edesc) { 1305 printf("ugenpoll: no edesc\n"); 1306 return (POLLERR); 1307 } 1308 if (!sce->pipeh) { 1309 printf("ugenpoll: no pipe\n"); 1310 return (POLLERR); 1311 } 1312 #endif 1313 s = splusb(); 1314 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1315 case UE_INTERRUPT: 1316 if (events & (POLLIN | POLLRDNORM)) { 1317 if (sce->q.c_cc > 0) 1318 revents |= events & (POLLIN | POLLRDNORM); 1319 else 1320 selrecord(p, &sce->rsel); 1321 } 1322 break; 1323 case UE_ISOCHRONOUS: 1324 if (events & (POLLIN | POLLRDNORM)) { 1325 if (sce->cur != sce->fill) 1326 revents |= events & (POLLIN | POLLRDNORM); 1327 else 1328 selrecord(p, &sce->rsel); 1329 } 1330 break; 1331 case UE_BULK: 1332 /* 1333 * We have no easy way of determining if a read will 1334 * yield any data or a write will happen. 1335 * Pretend they will. 1336 */ 1337 revents |= events & 1338 (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM); 1339 break; 1340 default: 1341 break; 1342 } 1343 splx(s); 1344 return (revents); 1345 } 1346 1347 void filt_ugenrdetach(struct knote *); 1348 int filt_ugenread_intr(struct knote *, long); 1349 int filt_ugenread_isoc(struct knote *, long); 1350 int ugenkqfilter(dev_t, struct knote *); 1351 1352 void 1353 filt_ugenrdetach(struct knote *kn) 1354 { 1355 struct ugen_endpoint *sce = (void *)kn->kn_hook; 1356 int s; 1357 1358 s = splusb(); 1359 SLIST_REMOVE(&sce->rsel.si_note, kn, knote, kn_selnext); 1360 splx(s); 1361 } 1362 1363 int 1364 filt_ugenread_intr(struct knote *kn, long hint) 1365 { 1366 struct ugen_endpoint *sce = (void *)kn->kn_hook; 1367 1368 kn->kn_data = sce->q.c_cc; 1369 return (kn->kn_data > 0); 1370 } 1371 1372 int 1373 filt_ugenread_isoc(struct knote *kn, long hint) 1374 { 1375 struct ugen_endpoint *sce = (void *)kn->kn_hook; 1376 1377 if (sce->cur == sce->fill) 1378 return (0); 1379 1380 if (sce->cur < sce->fill) 1381 kn->kn_data = sce->fill - sce->cur; 1382 else 1383 kn->kn_data = (sce->limit - sce->cur) + 1384 (sce->fill - sce->ibuf); 1385 1386 return (1); 1387 } 1388 1389 struct filterops ugenread_intr_filtops = 1390 { 1, NULL, filt_ugenrdetach, filt_ugenread_intr }; 1391 1392 struct filterops ugenread_isoc_filtops = 1393 { 1, NULL, filt_ugenrdetach, filt_ugenread_isoc }; 1394 1395 struct filterops ugen_seltrue_filtops = 1396 { 1, NULL, filt_ugenrdetach, filt_seltrue }; 1397 1398 int 1399 ugenkqfilter(dev_t dev, struct knote *kn) 1400 { 1401 struct ugen_softc *sc; 1402 struct ugen_endpoint *sce; 1403 struct klist *klist; 1404 int s; 1405 1406 sc = ugen_cd.cd_devs[UGENUNIT(dev)]; 1407 1408 if (sc->sc_dying) 1409 return (1); 1410 1411 /* XXX always IN */ 1412 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; 1413 if (sce == NULL) 1414 return (1); 1415 1416 switch (kn->kn_filter) { 1417 case EVFILT_READ: 1418 klist = &sce->rsel.si_note; 1419 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1420 case UE_INTERRUPT: 1421 kn->kn_fop = &ugenread_intr_filtops; 1422 break; 1423 case UE_ISOCHRONOUS: 1424 kn->kn_fop = &ugenread_isoc_filtops; 1425 break; 1426 case UE_BULK: 1427 /* 1428 * We have no easy way of determining if a read will 1429 * yield any data or a write will happen. 1430 * So, emulate "seltrue". 1431 */ 1432 kn->kn_fop = &ugen_seltrue_filtops; 1433 break; 1434 default: 1435 return (1); 1436 } 1437 break; 1438 1439 case EVFILT_WRITE: 1440 klist = &sce->rsel.si_note; 1441 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1442 case UE_INTERRUPT: 1443 case UE_ISOCHRONOUS: 1444 /* XXX poll doesn't support this */ 1445 return (1); 1446 1447 case UE_BULK: 1448 /* 1449 * We have no easy way of determining if a read will 1450 * yield any data or a write will happen. 1451 * So, emulate "seltrue". 1452 */ 1453 kn->kn_fop = &ugen_seltrue_filtops; 1454 break; 1455 default: 1456 return (1); 1457 } 1458 break; 1459 1460 default: 1461 return (1); 1462 } 1463 1464 kn->kn_hook = (void *)sce; 1465 1466 s = splusb(); 1467 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 1468 splx(s); 1469 1470 return (0); 1471 } 1472