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