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