1 /* $OpenBSD: ugen.c,v 1.68 2011/12/07 06:23:18 mglocker 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 } 471 } 472 sc->sc_is_open[endpt] = 0; 473 474 return (0); 475 } 476 477 int 478 ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) 479 { 480 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN]; 481 u_int32_t n, tn; 482 char buf[UGEN_BBSIZE]; 483 usbd_xfer_handle xfer; 484 usbd_status err; 485 int s; 486 int error = 0; 487 u_char buffer[UGEN_CHUNK]; 488 489 DPRINTFN(5, ("%s: ugenread: %d\n", sc->sc_dev.dv_xname, endpt)); 490 491 if (sc->sc_dying) 492 return (EIO); 493 494 if (endpt == USB_CONTROL_ENDPOINT) 495 return (ENODEV); 496 497 #ifdef DIAGNOSTIC 498 if (sce->edesc == NULL) { 499 printf("ugenread: no edesc\n"); 500 return (EIO); 501 } 502 if (sce->pipeh == NULL) { 503 printf("ugenread: no pipe\n"); 504 return (EIO); 505 } 506 #endif 507 508 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 509 case UE_INTERRUPT: 510 /* Block until activity occurred. */ 511 s = splusb(); 512 while (sce->q.c_cc == 0) { 513 if (flag & IO_NDELAY) { 514 splx(s); 515 return (EWOULDBLOCK); 516 } 517 sce->state |= UGEN_ASLP; 518 DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); 519 error = tsleep(sce, PZERO | PCATCH, "ugenri", 520 (sce->timeout * hz) / 1000); 521 sce->state &= ~UGEN_ASLP; 522 DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); 523 if (sc->sc_dying) 524 error = EIO; 525 if (error == EWOULDBLOCK) { /* timeout, return 0 */ 526 error = 0; 527 break; 528 } 529 if (error) 530 break; 531 } 532 splx(s); 533 534 /* Transfer as many chunks as possible. */ 535 while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) { 536 n = min(sce->q.c_cc, uio->uio_resid); 537 if (n > sizeof(buffer)) 538 n = sizeof(buffer); 539 540 /* Remove a small chunk from the input queue. */ 541 q_to_b(&sce->q, buffer, n); 542 DPRINTFN(5, ("ugenread: got %d chars\n", n)); 543 544 /* Copy the data to the user process. */ 545 error = uiomove(buffer, n, uio); 546 if (error) 547 break; 548 } 549 break; 550 case UE_BULK: 551 xfer = usbd_alloc_xfer(sc->sc_udev); 552 if (xfer == 0) 553 return (ENOMEM); 554 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { 555 DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n)); 556 tn = n; 557 err = usbd_bulk_transfer( 558 xfer, sce->pipeh, 559 sce->state & UGEN_SHORT_OK ? 560 USBD_SHORT_XFER_OK : 0, 561 sce->timeout, buf, &tn, "ugenrb"); 562 if (err) { 563 if (err == USBD_INTERRUPTED) 564 error = EINTR; 565 else if (err == USBD_TIMEOUT) 566 error = ETIMEDOUT; 567 else 568 error = EIO; 569 break; 570 } 571 DPRINTFN(1, ("ugenread: got %d bytes\n", tn)); 572 error = uiomove(buf, tn, uio); 573 if (error || tn < n) 574 break; 575 } 576 usbd_free_xfer(xfer); 577 break; 578 case UE_ISOCHRONOUS: 579 s = splusb(); 580 while (sce->cur == sce->fill) { 581 if (flag & IO_NDELAY) { 582 splx(s); 583 return (EWOULDBLOCK); 584 } 585 sce->state |= UGEN_ASLP; 586 DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); 587 error = tsleep(sce, PZERO | PCATCH, "ugenri", 588 (sce->timeout * hz) / 1000); 589 sce->state &= ~UGEN_ASLP; 590 DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); 591 if (sc->sc_dying) 592 error = EIO; 593 if (error == EWOULDBLOCK) { /* timeout, return 0 */ 594 error = 0; 595 break; 596 } 597 if (error) 598 break; 599 } 600 601 while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) { 602 if(sce->fill > sce->cur) 603 n = min(sce->fill - sce->cur, uio->uio_resid); 604 else 605 n = min(sce->limit - sce->cur, uio->uio_resid); 606 607 DPRINTFN(5, ("ugenread: isoc got %d chars\n", n)); 608 609 /* Copy the data to the user process. */ 610 error = uiomove(sce->cur, n, uio); 611 if (error) 612 break; 613 sce->cur += n; 614 if(sce->cur >= sce->limit) 615 sce->cur = sce->ibuf; 616 } 617 splx(s); 618 break; 619 620 621 default: 622 return (ENXIO); 623 } 624 return (error); 625 } 626 627 int 628 ugenread(dev_t dev, struct uio *uio, int flag) 629 { 630 int endpt = UGENENDPOINT(dev); 631 struct ugen_softc *sc; 632 int error; 633 634 sc = ugen_cd.cd_devs[UGENUNIT(dev)]; 635 636 sc->sc_refcnt++; 637 error = ugen_do_read(sc, endpt, uio, flag); 638 if (--sc->sc_refcnt < 0) 639 usb_detach_wakeup(&sc->sc_dev); 640 return (error); 641 } 642 643 int 644 ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) 645 { 646 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT]; 647 u_int32_t n; 648 int error = 0; 649 char buf[UGEN_BBSIZE]; 650 usbd_xfer_handle xfer; 651 usbd_status err; 652 653 DPRINTFN(5, ("%s: ugenwrite: %d\n", sc->sc_dev.dv_xname, endpt)); 654 655 if (sc->sc_dying) 656 return (EIO); 657 658 if (endpt == USB_CONTROL_ENDPOINT) 659 return (ENODEV); 660 661 #ifdef DIAGNOSTIC 662 if (sce->edesc == NULL) { 663 printf("ugenwrite: no edesc\n"); 664 return (EIO); 665 } 666 if (sce->pipeh == NULL) { 667 printf("ugenwrite: no pipe\n"); 668 return (EIO); 669 } 670 #endif 671 672 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 673 case UE_BULK: 674 xfer = usbd_alloc_xfer(sc->sc_udev); 675 if (xfer == 0) 676 return (EIO); 677 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { 678 error = uiomove(buf, n, uio); 679 if (error) 680 break; 681 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); 682 err = usbd_bulk_transfer(xfer, sce->pipeh, 0, 683 sce->timeout, buf, &n,"ugenwb"); 684 if (err) { 685 if (err == USBD_INTERRUPTED) 686 error = EINTR; 687 else if (err == USBD_TIMEOUT) 688 error = ETIMEDOUT; 689 else 690 error = EIO; 691 break; 692 } 693 } 694 usbd_free_xfer(xfer); 695 break; 696 case UE_INTERRUPT: 697 xfer = usbd_alloc_xfer(sc->sc_udev); 698 if (xfer == 0) 699 return (EIO); 700 while ((n = min(UGETW(sce->edesc->wMaxPacketSize), 701 uio->uio_resid)) != 0) { 702 error = uiomove(buf, n, uio); 703 if (error) 704 break; 705 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); 706 err = usbd_intr_transfer(xfer, sce->pipeh, 0, 707 sce->timeout, buf, &n, "ugenwi"); 708 if (err) { 709 if (err == USBD_INTERRUPTED) 710 error = EINTR; 711 else if (err == USBD_TIMEOUT) 712 error = ETIMEDOUT; 713 else 714 error = EIO; 715 break; 716 } 717 } 718 usbd_free_xfer(xfer); 719 break; 720 default: 721 return (ENXIO); 722 } 723 return (error); 724 } 725 726 int 727 ugenwrite(dev_t dev, struct uio *uio, int flag) 728 { 729 int endpt = UGENENDPOINT(dev); 730 struct ugen_softc *sc; 731 int error; 732 733 sc = ugen_cd.cd_devs[UGENUNIT(dev)]; 734 735 sc->sc_refcnt++; 736 error = ugen_do_write(sc, endpt, uio, flag); 737 if (--sc->sc_refcnt < 0) 738 usb_detach_wakeup(&sc->sc_dev); 739 return (error); 740 } 741 742 int 743 ugen_activate(struct device *self, int act) 744 { 745 struct ugen_softc *sc = (struct ugen_softc *)self; 746 747 switch (act) { 748 case DVACT_DEACTIVATE: 749 sc->sc_dying = 1; 750 break; 751 } 752 return (0); 753 } 754 755 int 756 ugen_detach(struct device *self, int flags) 757 { 758 struct ugen_softc *sc = (struct ugen_softc *)self; 759 struct ugen_endpoint *sce; 760 int i, dir; 761 int s; 762 int maj, mn; 763 764 DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags)); 765 766 /* Abort all pipes. Causes processes waiting for transfer to wake. */ 767 for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 768 for (dir = OUT; dir <= IN; dir++) { 769 sce = &sc->sc_endpoints[i][dir]; 770 if (sce && sce->pipeh) 771 usbd_abort_pipe(sce->pipeh); 772 } 773 } 774 775 s = splusb(); 776 if (--sc->sc_refcnt >= 0) { 777 /* Wake everyone */ 778 for (i = 0; i < USB_MAX_ENDPOINTS; i++) 779 wakeup(&sc->sc_endpoints[i][IN]); 780 /* Wait for processes to go away. */ 781 usb_detach_wait(&sc->sc_dev); 782 } 783 splx(s); 784 785 /* locate the major number */ 786 for (maj = 0; maj < nchrdev; maj++) 787 if (cdevsw[maj].d_open == ugenopen) 788 break; 789 790 /* Nuke the vnodes for any open instances (calls close). */ 791 mn = self->dv_unit * USB_MAX_ENDPOINTS; 792 vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR); 793 794 return (0); 795 } 796 797 void 798 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) 799 { 800 struct ugen_endpoint *sce = addr; 801 /*struct ugen_softc *sc = sce->sc;*/ 802 u_int32_t count; 803 u_char *ibuf; 804 805 if (status == USBD_CANCELLED) 806 return; 807 808 if (status != USBD_NORMAL_COMPLETION) { 809 DPRINTF(("ugenintr: status=%d\n", status)); 810 if (status == USBD_STALLED) 811 usbd_clear_endpoint_stall_async(sce->pipeh); 812 return; 813 } 814 815 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 816 ibuf = sce->ibuf; 817 818 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n", 819 xfer, status, count)); 820 DPRINTFN(5, (" data = %02x %02x %02x\n", 821 ibuf[0], ibuf[1], ibuf[2])); 822 823 (void)b_to_q(ibuf, count, &sce->q); 824 825 if (sce->state & UGEN_ASLP) { 826 sce->state &= ~UGEN_ASLP; 827 DPRINTFN(5, ("ugen_intr: waking %p\n", sce)); 828 wakeup(sce); 829 } 830 selwakeup(&sce->rsel); 831 } 832 833 void 834 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, 835 usbd_status status) 836 { 837 struct isoreq *req = addr; 838 struct ugen_endpoint *sce = req->sce; 839 u_int32_t count, n; 840 int i, isize; 841 842 /* Return if we are aborting. */ 843 if (status == USBD_CANCELLED) 844 return; 845 846 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 847 DPRINTFN(5,("ugen_isoc_rintr: xfer %d, count=%d\n", req - sce->isoreqs, 848 count)); 849 850 /* throw away oldest input if the buffer is full */ 851 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) { 852 sce->cur += count; 853 if(sce->cur >= sce->limit) 854 sce->cur = sce->ibuf + (sce->limit - sce->cur); 855 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n", 856 count)); 857 } 858 859 isize = UGETW(sce->edesc->wMaxPacketSize); 860 for (i = 0; i < UGEN_NISORFRMS; i++) { 861 u_int32_t actlen = req->sizes[i]; 862 char const *buf = (char const *)req->dmabuf + isize * i; 863 864 /* copy data to buffer */ 865 while (actlen > 0) { 866 n = min(actlen, sce->limit - sce->fill); 867 memcpy(sce->fill, buf, n); 868 869 buf += n; 870 actlen -= n; 871 sce->fill += n; 872 if(sce->fill == sce->limit) 873 sce->fill = sce->ibuf; 874 } 875 876 /* setup size for next transfer */ 877 req->sizes[i] = isize; 878 } 879 880 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS, 881 USBD_NO_COPY, ugen_isoc_rintr); 882 (void)usbd_transfer(xfer); 883 884 if (sce->state & UGEN_ASLP) { 885 sce->state &= ~UGEN_ASLP; 886 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce)); 887 wakeup(sce); 888 } 889 selwakeup(&sce->rsel); 890 } 891 892 usbd_status 893 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) 894 { 895 usbd_interface_handle iface; 896 usb_endpoint_descriptor_t *ed; 897 usbd_status err; 898 struct ugen_endpoint *sce; 899 u_int8_t niface, nendpt, endptno, endpt; 900 int dir; 901 902 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); 903 904 err = usbd_interface_count(sc->sc_udev, &niface); 905 if (err) 906 return (err); 907 if (ifaceidx < 0 || ifaceidx >= niface || 908 usbd_iface_claimed(sc->sc_udev, ifaceidx)) 909 return (USBD_INVAL); 910 911 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); 912 if (err) 913 return (err); 914 err = usbd_endpoint_count(iface, &nendpt); 915 if (err) 916 return (err); 917 for (endptno = 0; endptno < nendpt; endptno++) { 918 ed = usbd_interface2endpoint_descriptor(iface,endptno); 919 endpt = ed->bEndpointAddress; 920 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 921 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 922 sce->sc = 0; 923 sce->edesc = 0; 924 sce->iface = 0; 925 } 926 927 /* change setting */ 928 err = usbd_set_interface(iface, altno); 929 if (err) 930 goto out; 931 932 err = usbd_endpoint_count(iface, &nendpt); 933 if (err) 934 goto out; 935 936 out: 937 for (endptno = 0; endptno < nendpt; endptno++) { 938 ed = usbd_interface2endpoint_descriptor(iface,endptno); 939 endpt = ed->bEndpointAddress; 940 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 941 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 942 sce->sc = sc; 943 sce->edesc = ed; 944 sce->iface = iface; 945 } 946 return (err); 947 } 948 949 /* Retrieve a complete descriptor for a certain device and index. */ 950 usb_config_descriptor_t * 951 ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp) 952 { 953 usb_config_descriptor_t *cdesc, *tdesc, cdescr; 954 int len; 955 usbd_status err; 956 957 if (index == USB_CURRENT_CONFIG_INDEX) { 958 tdesc = usbd_get_config_descriptor(sc->sc_udev); 959 len = UGETW(tdesc->wTotalLength); 960 if (lenp) 961 *lenp = len; 962 cdesc = malloc(len, M_TEMP, M_WAITOK); 963 memcpy(cdesc, tdesc, len); 964 DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len)); 965 } else { 966 err = usbd_get_config_desc(sc->sc_udev, index, &cdescr); 967 if (err) 968 return (0); 969 len = UGETW(cdescr.wTotalLength); 970 DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len)); 971 if (lenp) 972 *lenp = len; 973 cdesc = malloc(len, M_TEMP, M_WAITOK); 974 err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, 975 len); 976 if (err) { 977 free(cdesc, M_TEMP); 978 return (0); 979 } 980 } 981 return (cdesc); 982 } 983 984 int 985 ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx) 986 { 987 usbd_interface_handle iface; 988 usbd_status err; 989 990 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); 991 if (err) 992 return (-1); 993 return (usbd_get_interface_altindex(iface)); 994 } 995 996 int 997 ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, 998 caddr_t addr, int flag, struct proc *p) 999 { 1000 struct ugen_endpoint *sce; 1001 usbd_status err; 1002 usbd_interface_handle iface; 1003 struct usb_config_desc *cd; 1004 usb_config_descriptor_t *cdesc; 1005 struct usb_interface_desc *id; 1006 usb_interface_descriptor_t *idesc; 1007 struct usb_endpoint_desc *ed; 1008 usb_endpoint_descriptor_t *edesc; 1009 struct usb_alt_interface *ai; 1010 struct usb_string_desc *si; 1011 u_int8_t conf, alt; 1012 1013 DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd)); 1014 if (sc->sc_dying) 1015 return (EIO); 1016 1017 switch (cmd) { 1018 case FIONBIO: 1019 /* All handled in the upper FS layer. */ 1020 return (0); 1021 case USB_SET_SHORT_XFER: 1022 if (endpt == USB_CONTROL_ENDPOINT) 1023 return (EINVAL); 1024 /* This flag only affects read */ 1025 sce = &sc->sc_endpoints[endpt][IN]; 1026 if (sce == NULL || sce->pipeh == NULL) 1027 return (EINVAL); 1028 if (*(int *)addr) 1029 sce->state |= UGEN_SHORT_OK; 1030 else 1031 sce->state &= ~UGEN_SHORT_OK; 1032 return (0); 1033 case USB_SET_TIMEOUT: 1034 sce = &sc->sc_endpoints[endpt][IN]; 1035 if (sce == NULL) 1036 return (EINVAL); 1037 sce->timeout = *(int *)addr; 1038 sce = &sc->sc_endpoints[endpt][OUT]; 1039 if (sce == NULL) 1040 return (EINVAL); 1041 sce->timeout = *(int *)addr; 1042 return (0); 1043 default: 1044 break; 1045 } 1046 1047 if (endpt != USB_CONTROL_ENDPOINT) 1048 return (EINVAL); 1049 1050 switch (cmd) { 1051 #ifdef UGEN_DEBUG 1052 case USB_SETDEBUG: 1053 ugendebug = *(int *)addr; 1054 break; 1055 #endif 1056 case USB_GET_CONFIG: 1057 err = usbd_get_config(sc->sc_udev, &conf); 1058 if (err) 1059 return (EIO); 1060 *(int *)addr = conf; 1061 break; 1062 case USB_SET_CONFIG: 1063 if (!(flag & FWRITE)) 1064 return (EPERM); 1065 err = ugen_set_config(sc, *(int *)addr); 1066 switch (err) { 1067 case USBD_NORMAL_COMPLETION: 1068 break; 1069 case USBD_IN_USE: 1070 return (EBUSY); 1071 default: 1072 return (EIO); 1073 } 1074 break; 1075 case USB_GET_ALTINTERFACE: 1076 ai = (struct usb_alt_interface *)addr; 1077 err = usbd_device2interface_handle(sc->sc_udev, 1078 ai->uai_interface_index, &iface); 1079 if (err) 1080 return (EINVAL); 1081 idesc = usbd_get_interface_descriptor(iface); 1082 if (idesc == NULL) 1083 return (EIO); 1084 ai->uai_alt_no = idesc->bAlternateSetting; 1085 break; 1086 case USB_SET_ALTINTERFACE: 1087 if (!(flag & FWRITE)) 1088 return (EPERM); 1089 ai = (struct usb_alt_interface *)addr; 1090 err = usbd_device2interface_handle(sc->sc_udev, 1091 ai->uai_interface_index, &iface); 1092 if (err) 1093 return (EINVAL); 1094 err = ugen_set_interface(sc, ai->uai_interface_index, 1095 ai->uai_alt_no); 1096 if (err) 1097 return (EINVAL); 1098 break; 1099 case USB_GET_NO_ALT: 1100 ai = (struct usb_alt_interface *)addr; 1101 cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0); 1102 if (cdesc == NULL) 1103 return (EINVAL); 1104 idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0); 1105 if (idesc == NULL) { 1106 free(cdesc, M_TEMP); 1107 return (EINVAL); 1108 } 1109 ai->uai_alt_no = usbd_get_no_alts(cdesc, 1110 idesc->bInterfaceNumber); 1111 free(cdesc, M_TEMP); 1112 break; 1113 case USB_GET_DEVICE_DESC: 1114 *(usb_device_descriptor_t *)addr = 1115 *usbd_get_device_descriptor(sc->sc_udev); 1116 break; 1117 case USB_GET_CONFIG_DESC: 1118 cd = (struct usb_config_desc *)addr; 1119 cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0); 1120 if (cdesc == NULL) 1121 return (EINVAL); 1122 cd->ucd_desc = *cdesc; 1123 free(cdesc, M_TEMP); 1124 break; 1125 case USB_GET_INTERFACE_DESC: 1126 id = (struct usb_interface_desc *)addr; 1127 cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0); 1128 if (cdesc == NULL) 1129 return (EINVAL); 1130 if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX && 1131 id->uid_alt_index == USB_CURRENT_ALT_INDEX) 1132 alt = ugen_get_alt_index(sc, id->uid_interface_index); 1133 else 1134 alt = id->uid_alt_index; 1135 idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt); 1136 if (idesc == NULL) { 1137 free(cdesc, M_TEMP); 1138 return (EINVAL); 1139 } 1140 id->uid_desc = *idesc; 1141 free(cdesc, M_TEMP); 1142 break; 1143 case USB_GET_ENDPOINT_DESC: 1144 ed = (struct usb_endpoint_desc *)addr; 1145 cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0); 1146 if (cdesc == NULL) 1147 return (EINVAL); 1148 if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX && 1149 ed->ued_alt_index == USB_CURRENT_ALT_INDEX) 1150 alt = ugen_get_alt_index(sc, ed->ued_interface_index); 1151 else 1152 alt = ed->ued_alt_index; 1153 edesc = usbd_find_edesc(cdesc, ed->ued_interface_index, 1154 alt, ed->ued_endpoint_index); 1155 if (edesc == NULL) { 1156 free(cdesc, M_TEMP); 1157 return (EINVAL); 1158 } 1159 ed->ued_desc = *edesc; 1160 free(cdesc, M_TEMP); 1161 break; 1162 case USB_GET_FULL_DESC: 1163 { 1164 int len; 1165 struct iovec iov; 1166 struct uio uio; 1167 struct usb_full_desc *fd = (struct usb_full_desc *)addr; 1168 int error; 1169 1170 cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len); 1171 if (cdesc == NULL) 1172 return (EINVAL); 1173 if (len > fd->ufd_size) 1174 len = fd->ufd_size; 1175 iov.iov_base = (caddr_t)fd->ufd_data; 1176 iov.iov_len = len; 1177 uio.uio_iov = &iov; 1178 uio.uio_iovcnt = 1; 1179 uio.uio_resid = len; 1180 uio.uio_offset = 0; 1181 uio.uio_segflg = UIO_USERSPACE; 1182 uio.uio_rw = UIO_READ; 1183 uio.uio_procp = p; 1184 error = uiomove((void *)cdesc, len, &uio); 1185 free(cdesc, M_TEMP); 1186 return (error); 1187 } 1188 case USB_GET_STRING_DESC: 1189 { 1190 int len; 1191 si = (struct usb_string_desc *)addr; 1192 err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index, 1193 si->usd_language_id, &si->usd_desc, &len); 1194 if (err) 1195 return (EINVAL); 1196 break; 1197 } 1198 case USB_DO_REQUEST: 1199 { 1200 struct usb_ctl_request *ur = (void *)addr; 1201 int len = UGETW(ur->ucr_request.wLength); 1202 struct iovec iov; 1203 struct uio uio; 1204 void *ptr = 0; 1205 int error = 0; 1206 1207 if (!(flag & FWRITE)) 1208 return (EPERM); 1209 /* Avoid requests that would damage the bus integrity. */ 1210 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 1211 ur->ucr_request.bRequest == UR_SET_ADDRESS) || 1212 (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 1213 ur->ucr_request.bRequest == UR_SET_CONFIG) || 1214 (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE && 1215 ur->ucr_request.bRequest == UR_SET_INTERFACE)) 1216 return (EINVAL); 1217 1218 if (len < 0 || len > 32767) 1219 return (EINVAL); 1220 if (len != 0) { 1221 iov.iov_base = (caddr_t)ur->ucr_data; 1222 iov.iov_len = len; 1223 uio.uio_iov = &iov; 1224 uio.uio_iovcnt = 1; 1225 uio.uio_resid = len; 1226 uio.uio_offset = 0; 1227 uio.uio_segflg = UIO_USERSPACE; 1228 uio.uio_rw = 1229 ur->ucr_request.bmRequestType & UT_READ ? 1230 UIO_READ : UIO_WRITE; 1231 uio.uio_procp = p; 1232 ptr = malloc(len, M_TEMP, M_WAITOK); 1233 if (uio.uio_rw == UIO_WRITE) { 1234 error = uiomove(ptr, len, &uio); 1235 if (error) 1236 goto ret; 1237 } 1238 } 1239 sce = &sc->sc_endpoints[endpt][IN]; 1240 err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request, 1241 ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout); 1242 if (err) { 1243 error = EIO; 1244 goto ret; 1245 } 1246 if (len != 0) { 1247 if (uio.uio_rw == UIO_READ) { 1248 error = uiomove(ptr, len, &uio); 1249 if (error) 1250 goto ret; 1251 } 1252 } 1253 ret: 1254 if (ptr) 1255 free(ptr, M_TEMP); 1256 return (error); 1257 } 1258 case USB_GET_DEVICEINFO: 1259 usbd_fill_deviceinfo(sc->sc_udev, 1260 (struct usb_device_info *)addr, 1); 1261 break; 1262 default: 1263 return (EINVAL); 1264 } 1265 return (0); 1266 } 1267 1268 int 1269 ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 1270 { 1271 int endpt = UGENENDPOINT(dev); 1272 struct ugen_softc *sc; 1273 int error; 1274 1275 sc = ugen_cd.cd_devs[UGENUNIT(dev)]; 1276 1277 sc->sc_refcnt++; 1278 error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p); 1279 if (--sc->sc_refcnt < 0) 1280 usb_detach_wakeup(&sc->sc_dev); 1281 return (error); 1282 } 1283 1284 int 1285 ugenpoll(dev_t dev, int events, struct proc *p) 1286 { 1287 struct ugen_softc *sc; 1288 struct ugen_endpoint *sce; 1289 int revents = 0; 1290 int s; 1291 1292 sc = ugen_cd.cd_devs[UGENUNIT(dev)]; 1293 1294 if (sc->sc_dying) 1295 return (POLLERR); 1296 1297 /* XXX always IN */ 1298 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; 1299 if (sce == NULL) 1300 return (POLLERR); 1301 #ifdef DIAGNOSTIC 1302 if (!sce->edesc) { 1303 printf("ugenpoll: no edesc\n"); 1304 return (POLLERR); 1305 } 1306 if (!sce->pipeh) { 1307 printf("ugenpoll: no pipe\n"); 1308 return (POLLERR); 1309 } 1310 #endif 1311 s = splusb(); 1312 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1313 case UE_INTERRUPT: 1314 if (events & (POLLIN | POLLRDNORM)) { 1315 if (sce->q.c_cc > 0) 1316 revents |= events & (POLLIN | POLLRDNORM); 1317 else 1318 selrecord(p, &sce->rsel); 1319 } 1320 break; 1321 case UE_ISOCHRONOUS: 1322 if (events & (POLLIN | POLLRDNORM)) { 1323 if (sce->cur != sce->fill) 1324 revents |= events & (POLLIN | POLLRDNORM); 1325 else 1326 selrecord(p, &sce->rsel); 1327 } 1328 break; 1329 case UE_BULK: 1330 /* 1331 * We have no easy way of determining if a read will 1332 * yield any data or a write will happen. 1333 * Pretend they will. 1334 */ 1335 revents |= events & 1336 (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM); 1337 break; 1338 default: 1339 break; 1340 } 1341 splx(s); 1342 return (revents); 1343 } 1344 1345 void filt_ugenrdetach(struct knote *); 1346 int filt_ugenread_intr(struct knote *, long); 1347 int filt_ugenread_isoc(struct knote *, long); 1348 int ugenkqfilter(dev_t, struct knote *); 1349 1350 void 1351 filt_ugenrdetach(struct knote *kn) 1352 { 1353 struct ugen_endpoint *sce = (void *)kn->kn_hook; 1354 int s; 1355 1356 s = splusb(); 1357 SLIST_REMOVE(&sce->rsel.si_note, kn, knote, kn_selnext); 1358 splx(s); 1359 } 1360 1361 int 1362 filt_ugenread_intr(struct knote *kn, long hint) 1363 { 1364 struct ugen_endpoint *sce = (void *)kn->kn_hook; 1365 1366 kn->kn_data = sce->q.c_cc; 1367 return (kn->kn_data > 0); 1368 } 1369 1370 int 1371 filt_ugenread_isoc(struct knote *kn, long hint) 1372 { 1373 struct ugen_endpoint *sce = (void *)kn->kn_hook; 1374 1375 if (sce->cur == sce->fill) 1376 return (0); 1377 1378 if (sce->cur < sce->fill) 1379 kn->kn_data = sce->fill - sce->cur; 1380 else 1381 kn->kn_data = (sce->limit - sce->cur) + 1382 (sce->fill - sce->ibuf); 1383 1384 return (1); 1385 } 1386 1387 struct filterops ugenread_intr_filtops = 1388 { 1, NULL, filt_ugenrdetach, filt_ugenread_intr }; 1389 1390 struct filterops ugenread_isoc_filtops = 1391 { 1, NULL, filt_ugenrdetach, filt_ugenread_isoc }; 1392 1393 struct filterops ugen_seltrue_filtops = 1394 { 1, NULL, filt_ugenrdetach, filt_seltrue }; 1395 1396 int 1397 ugenkqfilter(dev_t dev, struct knote *kn) 1398 { 1399 struct ugen_softc *sc; 1400 struct ugen_endpoint *sce; 1401 struct klist *klist; 1402 int s; 1403 1404 sc = ugen_cd.cd_devs[UGENUNIT(dev)]; 1405 1406 if (sc->sc_dying) 1407 return (ENXIO); 1408 1409 /* XXX always IN */ 1410 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; 1411 if (sce == NULL) 1412 return (EINVAL); 1413 1414 switch (kn->kn_filter) { 1415 case EVFILT_READ: 1416 klist = &sce->rsel.si_note; 1417 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1418 case UE_INTERRUPT: 1419 kn->kn_fop = &ugenread_intr_filtops; 1420 break; 1421 case UE_ISOCHRONOUS: 1422 kn->kn_fop = &ugenread_isoc_filtops; 1423 break; 1424 case UE_BULK: 1425 /* 1426 * We have no easy way of determining if a read will 1427 * yield any data or a write will happen. 1428 * So, emulate "seltrue". 1429 */ 1430 kn->kn_fop = &ugen_seltrue_filtops; 1431 break; 1432 default: 1433 return (EINVAL); 1434 } 1435 break; 1436 1437 case EVFILT_WRITE: 1438 klist = &sce->rsel.si_note; 1439 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1440 case UE_INTERRUPT: 1441 case UE_ISOCHRONOUS: 1442 /* XXX poll doesn't support this */ 1443 return (EINVAL); 1444 1445 case UE_BULK: 1446 /* 1447 * We have no easy way of determining if a read will 1448 * yield any data or a write will happen. 1449 * So, emulate "seltrue". 1450 */ 1451 kn->kn_fop = &ugen_seltrue_filtops; 1452 break; 1453 default: 1454 return (EINVAL); 1455 } 1456 break; 1457 1458 default: 1459 return (EINVAL); 1460 } 1461 1462 kn->kn_hook = (void *)sce; 1463 1464 s = splusb(); 1465 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 1466 splx(s); 1467 1468 return (0); 1469 } 1470