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