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