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