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