1 /* $OpenBSD: ugen.c,v 1.116 2022/07/02 08:50:42 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 return (0); 803 } 804 805 void 806 ugenintr(struct usbd_xfer *xfer, void *addr, usbd_status status) 807 { 808 struct ugen_endpoint *sce = addr; 809 /*struct ugen_softc *sc = sce->sc;*/ 810 u_int32_t count; 811 u_char *ibuf; 812 813 if (status == USBD_CANCELLED) 814 return; 815 816 if (status != USBD_NORMAL_COMPLETION) { 817 DPRINTF(("ugenintr: status=%d\n", status)); 818 if (status == USBD_STALLED) 819 usbd_clear_endpoint_stall_async(sce->pipeh); 820 return; 821 } 822 823 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 824 ibuf = sce->ibuf; 825 826 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n", 827 xfer, status, count)); 828 DPRINTFN(5, (" data = %02x %02x %02x\n", 829 ibuf[0], ibuf[1], ibuf[2])); 830 831 (void)b_to_q(ibuf, count, &sce->q); 832 833 if (sce->state & UGEN_ASLP) { 834 sce->state &= ~UGEN_ASLP; 835 DPRINTFN(5, ("ugen_intr: waking %p\n", sce)); 836 wakeup(sce); 837 } 838 selwakeup(&sce->rsel); 839 } 840 841 void 842 ugen_isoc_rintr(struct usbd_xfer *xfer, void *addr, usbd_status status) 843 { 844 struct isoreq *req = addr; 845 struct ugen_endpoint *sce = req->sce; 846 u_int32_t count, n; 847 int i, isize; 848 849 /* Return if we are aborting. */ 850 if (status == USBD_CANCELLED) 851 return; 852 853 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 854 DPRINTFN(5,("%s: xfer %ld, count=%d\n", __func__, req - sce->isoreqs, 855 count)); 856 857 /* throw away oldest input if the buffer is full */ 858 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) { 859 sce->cur += count; 860 if(sce->cur >= sce->limit) 861 sce->cur = sce->ibuf + (sce->limit - sce->cur); 862 DPRINTFN(5, ("%s: throwing away %d bytes\n", __func__, count)); 863 } 864 865 isize = UGETW(sce->edesc->wMaxPacketSize); 866 for (i = 0; i < UGEN_NISORFRMS; i++) { 867 u_int32_t actlen = req->sizes[i]; 868 char const *buf = (char const *)req->dmabuf + isize * i; 869 870 /* copy data to buffer */ 871 while (actlen > 0) { 872 n = min(actlen, sce->limit - sce->fill); 873 memcpy(sce->fill, buf, n); 874 875 buf += n; 876 actlen -= n; 877 sce->fill += n; 878 if(sce->fill == sce->limit) 879 sce->fill = sce->ibuf; 880 } 881 882 /* setup size for next transfer */ 883 req->sizes[i] = isize; 884 } 885 886 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS, 887 USBD_NO_COPY | USBD_SHORT_XFER_OK, ugen_isoc_rintr); 888 (void)usbd_transfer(xfer); 889 890 if (sce->state & UGEN_ASLP) { 891 sce->state &= ~UGEN_ASLP; 892 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce)); 893 wakeup(sce); 894 } 895 selwakeup(&sce->rsel); 896 } 897 898 int 899 ugen_set_interface(struct ugen_softc *sc, int ifaceno, int altno) 900 { 901 struct usbd_interface *iface; 902 usb_config_descriptor_t *cdesc; 903 usb_interface_descriptor_t *id; 904 usb_endpoint_descriptor_t *ed; 905 struct ugen_endpoint *sce; 906 uint8_t endptno, endpt; 907 int dir, err; 908 909 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceno, altno)); 910 911 cdesc = usbd_get_config_descriptor(sc->sc_udev); 912 if (ifaceno < 0 || ifaceno >= cdesc->bNumInterfaces || 913 usbd_iface_claimed(sc->sc_udev, ifaceno)) 914 return (USBD_INVAL); 915 916 err = usbd_device2interface_handle(sc->sc_udev, ifaceno, &iface); 917 if (err) 918 return (err); 919 id = usbd_get_interface_descriptor(iface); 920 for (endptno = 0; endptno < id->bNumEndpoints; endptno++) { 921 ed = usbd_interface2endpoint_descriptor(iface,endptno); 922 endpt = ed->bEndpointAddress; 923 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 924 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 925 sce->sc = 0; 926 sce->edesc = 0; 927 sce->iface = 0; 928 } 929 930 /* Try to change setting, if this fails put back the descriptors. */ 931 err = usbd_set_interface(iface, altno); 932 933 id = usbd_get_interface_descriptor(iface); 934 for (endptno = 0; endptno < id->bNumEndpoints; endptno++) { 935 ed = usbd_interface2endpoint_descriptor(iface,endptno); 936 endpt = ed->bEndpointAddress; 937 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 938 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 939 sce->sc = sc; 940 sce->edesc = ed; 941 sce->iface = iface; 942 } 943 return (err); 944 } 945 946 int 947 ugen_get_alt_index(struct ugen_softc *sc, int ifaceno) 948 { 949 struct usbd_interface *iface; 950 usbd_status err; 951 952 err = usbd_device2interface_handle(sc->sc_udev, ifaceno, &iface); 953 if (err) 954 return (-1); 955 return (usbd_get_interface_altindex(iface)); 956 } 957 958 int 959 ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, caddr_t addr, 960 int flag, struct proc *p) 961 { 962 struct ugen_endpoint *sce; 963 int err, cdesc_len; 964 struct usbd_interface *iface; 965 struct usb_config_desc *cd; 966 usb_config_descriptor_t *cdesc; 967 struct usb_interface_desc *id; 968 usb_interface_descriptor_t *idesc; 969 struct usb_endpoint_desc *ed; 970 usb_endpoint_descriptor_t *edesc; 971 struct usb_alt_interface *ai; 972 u_int8_t conf, alt; 973 974 DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd)); 975 if (usbd_is_dying(sc->sc_udev)) 976 return (EIO); 977 978 switch (cmd) { 979 case FIONBIO: 980 /* All handled in the upper FS layer. */ 981 return (0); 982 case USB_SET_SHORT_XFER: 983 if (endpt == USB_CONTROL_ENDPOINT) 984 return (EINVAL); 985 /* This flag only affects read */ 986 sce = &sc->sc_endpoints[endpt][IN]; 987 if (sce == NULL || sce->pipeh == NULL) 988 return (EINVAL); 989 if (*(int *)addr) 990 sce->state |= UGEN_SHORT_OK; 991 else 992 sce->state &= ~UGEN_SHORT_OK; 993 return (0); 994 case USB_SET_TIMEOUT: 995 sce = &sc->sc_endpoints[endpt][IN]; 996 if (sce == NULL) 997 return (EINVAL); 998 sce->timeout = *(int *)addr; 999 sce = &sc->sc_endpoints[endpt][OUT]; 1000 if (sce == NULL) 1001 return (EINVAL); 1002 sce->timeout = *(int *)addr; 1003 return (0); 1004 default: 1005 break; 1006 } 1007 1008 if (endpt != USB_CONTROL_ENDPOINT) 1009 return (EINVAL); 1010 1011 switch (cmd) { 1012 #ifdef UGEN_DEBUG 1013 case USB_SETDEBUG: 1014 ugendebug = *(int *)addr; 1015 break; 1016 #endif 1017 case USB_GET_CONFIG: 1018 err = usbd_get_config(sc->sc_udev, &conf); 1019 if (err) 1020 return (EIO); 1021 *(int *)addr = conf; 1022 break; 1023 case USB_SET_CONFIG: 1024 if (!(flag & FWRITE)) 1025 return (EPERM); 1026 err = ugen_set_config(sc, *(int *)addr); 1027 switch (err) { 1028 case USBD_NORMAL_COMPLETION: 1029 break; 1030 case USBD_IN_USE: 1031 return (EBUSY); 1032 default: 1033 return (EIO); 1034 } 1035 break; 1036 case USB_GET_ALTINTERFACE: 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 idesc = usbd_get_interface_descriptor(iface); 1043 if (idesc == NULL) 1044 return (EIO); 1045 ai->uai_alt_no = idesc->bAlternateSetting; 1046 break; 1047 case USB_SET_ALTINTERFACE: 1048 if (!(flag & FWRITE)) 1049 return (EPERM); 1050 ai = (struct usb_alt_interface *)addr; 1051 err = usbd_device2interface_handle(sc->sc_udev, 1052 ai->uai_interface_index, &iface); 1053 if (err) 1054 return (EINVAL); 1055 err = ugen_set_interface(sc, ai->uai_interface_index, 1056 ai->uai_alt_no); 1057 if (err) 1058 return (EINVAL); 1059 break; 1060 case USB_GET_NO_ALT: 1061 ai = (struct usb_alt_interface *)addr; 1062 cdesc = usbd_get_cdesc(sc->sc_udev, ai->uai_config_index, 1063 &cdesc_len); 1064 if (cdesc == NULL) 1065 return (EINVAL); 1066 idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0); 1067 if (idesc == NULL) { 1068 free(cdesc, M_TEMP, UGETW(cdesc->wTotalLength)); 1069 return (EINVAL); 1070 } 1071 ai->uai_alt_no = usbd_get_no_alts(cdesc, 1072 idesc->bInterfaceNumber); 1073 free(cdesc, M_TEMP, cdesc_len); 1074 break; 1075 case USB_GET_DEVICE_DESC: 1076 *(usb_device_descriptor_t *)addr = 1077 *usbd_get_device_descriptor(sc->sc_udev); 1078 break; 1079 case USB_GET_CONFIG_DESC: 1080 cd = (struct usb_config_desc *)addr; 1081 cdesc = usbd_get_cdesc(sc->sc_udev, cd->ucd_config_index, 1082 &cdesc_len); 1083 if (cdesc == NULL) 1084 return (EINVAL); 1085 cd->ucd_desc = *cdesc; 1086 free(cdesc, M_TEMP, cdesc_len); 1087 break; 1088 case USB_GET_INTERFACE_DESC: 1089 id = (struct usb_interface_desc *)addr; 1090 cdesc = usbd_get_cdesc(sc->sc_udev, id->uid_config_index, 1091 &cdesc_len); 1092 if (cdesc == NULL) 1093 return (EINVAL); 1094 if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX && 1095 id->uid_alt_index == USB_CURRENT_ALT_INDEX) 1096 alt = ugen_get_alt_index(sc, id->uid_interface_index); 1097 else 1098 alt = id->uid_alt_index; 1099 idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt); 1100 if (idesc == NULL) { 1101 free(cdesc, M_TEMP, UGETW(cdesc->wTotalLength)); 1102 return (EINVAL); 1103 } 1104 id->uid_desc = *idesc; 1105 free(cdesc, M_TEMP, cdesc_len); 1106 break; 1107 case USB_GET_ENDPOINT_DESC: 1108 ed = (struct usb_endpoint_desc *)addr; 1109 cdesc = usbd_get_cdesc(sc->sc_udev, ed->ued_config_index, 1110 &cdesc_len); 1111 if (cdesc == NULL) 1112 return (EINVAL); 1113 if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX && 1114 ed->ued_alt_index == USB_CURRENT_ALT_INDEX) 1115 alt = ugen_get_alt_index(sc, ed->ued_interface_index); 1116 else 1117 alt = ed->ued_alt_index; 1118 edesc = usbd_find_edesc(cdesc, ed->ued_interface_index, 1119 alt, ed->ued_endpoint_index); 1120 if (edesc == NULL) { 1121 free(cdesc, M_TEMP, UGETW(cdesc->wTotalLength)); 1122 return (EINVAL); 1123 } 1124 ed->ued_desc = *edesc; 1125 free(cdesc, M_TEMP, cdesc_len); 1126 break; 1127 case USB_GET_FULL_DESC: 1128 { 1129 u_int len; 1130 struct iovec iov; 1131 struct uio uio; 1132 struct usb_full_desc *fd = (struct usb_full_desc *)addr; 1133 int error; 1134 1135 cdesc = usbd_get_cdesc(sc->sc_udev, fd->ufd_config_index, 1136 &cdesc_len); 1137 if (cdesc == NULL) 1138 return (EINVAL); 1139 len = cdesc_len; 1140 if (len > fd->ufd_size) 1141 len = fd->ufd_size; 1142 iov.iov_base = (caddr_t)fd->ufd_data; 1143 iov.iov_len = len; 1144 uio.uio_iov = &iov; 1145 uio.uio_iovcnt = 1; 1146 uio.uio_resid = len; 1147 uio.uio_offset = 0; 1148 uio.uio_segflg = UIO_USERSPACE; 1149 uio.uio_rw = UIO_READ; 1150 uio.uio_procp = p; 1151 error = uiomove((void *)cdesc, len, &uio); 1152 free(cdesc, M_TEMP, cdesc_len); 1153 return (error); 1154 } 1155 case USB_DO_REQUEST: 1156 { 1157 struct usb_ctl_request *ur = (void *)addr; 1158 size_t len = UGETW(ur->ucr_request.wLength), mlen; 1159 struct iovec iov; 1160 struct uio uio; 1161 void *ptr = NULL; 1162 int error = 0; 1163 1164 if (!(flag & FWRITE)) 1165 return (EPERM); 1166 /* Avoid requests that would damage the bus integrity. */ 1167 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 1168 ur->ucr_request.bRequest == UR_SET_ADDRESS) || 1169 (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 1170 ur->ucr_request.bRequest == UR_SET_CONFIG) || 1171 (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE && 1172 ur->ucr_request.bRequest == UR_SET_INTERFACE)) 1173 return (EINVAL); 1174 1175 if (len > 32767) 1176 return (EINVAL); 1177 if (len != 0) { 1178 iov.iov_base = (caddr_t)ur->ucr_data; 1179 iov.iov_len = len; 1180 uio.uio_iov = &iov; 1181 uio.uio_iovcnt = 1; 1182 uio.uio_resid = len; 1183 uio.uio_offset = 0; 1184 uio.uio_segflg = UIO_USERSPACE; 1185 uio.uio_rw = 1186 ur->ucr_request.bmRequestType & UT_READ ? 1187 UIO_READ : UIO_WRITE; 1188 uio.uio_procp = p; 1189 if ((ptr = malloc(len, M_TEMP, M_NOWAIT)) == NULL) { 1190 error = ENOMEM; 1191 goto ret; 1192 } 1193 if (uio.uio_rw == UIO_WRITE) { 1194 error = uiomove(ptr, len, &uio); 1195 if (error) 1196 goto ret; 1197 } 1198 } 1199 sce = &sc->sc_endpoints[endpt][IN]; 1200 err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request, 1201 ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout); 1202 if (err) { 1203 error = EIO; 1204 goto ret; 1205 } 1206 /* Only if USBD_SHORT_XFER_OK is set. */ 1207 mlen = len; 1208 if (mlen > ur->ucr_actlen) 1209 mlen = ur->ucr_actlen; 1210 if (mlen != 0) { 1211 if (uio.uio_rw == UIO_READ) { 1212 error = uiomove(ptr, mlen, &uio); 1213 if (error) 1214 goto ret; 1215 } 1216 } 1217 ret: 1218 free(ptr, M_TEMP, len); 1219 return (error); 1220 } 1221 case USB_GET_DEVICEINFO: 1222 usbd_fill_deviceinfo(sc->sc_udev, 1223 (struct usb_device_info *)addr); 1224 break; 1225 default: 1226 return (EINVAL); 1227 } 1228 return (0); 1229 } 1230 1231 int 1232 ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 1233 { 1234 int endpt = UGENENDPOINT(dev); 1235 struct ugen_softc *sc; 1236 int error; 1237 1238 sc = ugen_cd.cd_devs[UGENUNIT(dev)]; 1239 1240 sc->sc_refcnt++; 1241 error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p); 1242 if (--sc->sc_refcnt < 0) 1243 usb_detach_wakeup(&sc->sc_dev); 1244 return (error); 1245 } 1246 1247 void filt_ugenrdetach(struct knote *); 1248 int filt_ugenread_intr(struct knote *, long); 1249 int filt_ugenread_isoc(struct knote *, long); 1250 int ugenkqfilter(dev_t, struct knote *); 1251 1252 void 1253 filt_ugenrdetach(struct knote *kn) 1254 { 1255 struct ugen_endpoint *sce = (void *)kn->kn_hook; 1256 int s; 1257 1258 s = splusb(); 1259 klist_remove_locked(&sce->rsel.si_note, kn); 1260 splx(s); 1261 } 1262 1263 int 1264 filt_ugenread_intr(struct knote *kn, long hint) 1265 { 1266 struct ugen_endpoint *sce = (void *)kn->kn_hook; 1267 1268 kn->kn_data = sce->q.c_cc; 1269 return (kn->kn_data > 0); 1270 } 1271 1272 int 1273 filt_ugenread_isoc(struct knote *kn, long hint) 1274 { 1275 struct ugen_endpoint *sce = (void *)kn->kn_hook; 1276 1277 if (sce->cur == sce->fill) 1278 return (0); 1279 1280 if (sce->cur < sce->fill) 1281 kn->kn_data = sce->fill - sce->cur; 1282 else 1283 kn->kn_data = (sce->limit - sce->cur) + 1284 (sce->fill - sce->ibuf); 1285 1286 return (1); 1287 } 1288 1289 const struct filterops ugenread_intr_filtops = { 1290 .f_flags = FILTEROP_ISFD, 1291 .f_attach = NULL, 1292 .f_detach = filt_ugenrdetach, 1293 .f_event = filt_ugenread_intr, 1294 }; 1295 1296 const struct filterops ugenread_isoc_filtops = { 1297 .f_flags = FILTEROP_ISFD, 1298 .f_attach = NULL, 1299 .f_detach = filt_ugenrdetach, 1300 .f_event = filt_ugenread_isoc, 1301 }; 1302 1303 int 1304 ugenkqfilter(dev_t dev, struct knote *kn) 1305 { 1306 struct ugen_softc *sc; 1307 struct ugen_endpoint *sce; 1308 struct klist *klist; 1309 int s; 1310 1311 sc = ugen_cd.cd_devs[UGENUNIT(dev)]; 1312 1313 if (usbd_is_dying(sc->sc_udev)) 1314 return (ENXIO); 1315 1316 /* XXX always IN */ 1317 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; 1318 if (sce == NULL) 1319 return (ENXIO); 1320 1321 switch (kn->kn_filter) { 1322 case EVFILT_READ: 1323 klist = &sce->rsel.si_note; 1324 switch (UE_GET_XFERTYPE(sce->edesc->bmAttributes)) { 1325 case UE_INTERRUPT: 1326 kn->kn_fop = &ugenread_intr_filtops; 1327 break; 1328 case UE_ISOCHRONOUS: 1329 kn->kn_fop = &ugenread_isoc_filtops; 1330 break; 1331 case UE_BULK: 1332 /* 1333 * We have no easy way of determining if a read will 1334 * yield any data or a write will happen. 1335 */ 1336 return (seltrue_kqfilter(dev, kn)); 1337 default: 1338 return (EINVAL); 1339 } 1340 break; 1341 1342 case EVFILT_WRITE: 1343 klist = &sce->rsel.si_note; 1344 switch (UE_GET_XFERTYPE(sce->edesc->bmAttributes)) { 1345 case UE_INTERRUPT: 1346 case UE_ISOCHRONOUS: 1347 /* XXX poll doesn't support this */ 1348 return (EINVAL); 1349 1350 case UE_BULK: 1351 /* 1352 * We have no easy way of determining if a read will 1353 * yield any data or a write will happen. 1354 */ 1355 return (seltrue_kqfilter(dev, kn)); 1356 default: 1357 return (EINVAL); 1358 } 1359 break; 1360 1361 default: 1362 return (EINVAL); 1363 } 1364 1365 kn->kn_hook = (void *)sce; 1366 1367 s = splusb(); 1368 klist_insert_locked(klist, kn); 1369 splx(s); 1370 1371 return (0); 1372 } 1373 1374 void 1375 ugen_clear_iface_eps(struct ugen_softc *sc, struct usbd_interface *iface) 1376 { 1377 usb_interface_descriptor_t *id; 1378 usb_endpoint_descriptor_t *ed; 1379 uint8_t xfertype; 1380 int i; 1381 1382 /* Only clear interface endpoints when none are in use. */ 1383 for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 1384 if (i == USB_CONTROL_ENDPOINT) 1385 continue; 1386 if (sc->sc_is_open[i] != 0) 1387 return; 1388 } 1389 DPRINTFN(1,("%s: clear interface eps\n", __func__)); 1390 1391 id = usbd_get_interface_descriptor(iface); 1392 if (id == NULL) 1393 goto bad; 1394 1395 for (i = 0; i < id->bNumEndpoints; i++) { 1396 ed = usbd_interface2endpoint_descriptor(iface, i); 1397 if (ed == NULL) 1398 goto bad; 1399 1400 xfertype = UE_GET_XFERTYPE(ed->bmAttributes); 1401 if (xfertype == UE_BULK || xfertype == UE_INTERRUPT) { 1402 if (usbd_clear_endpoint_feature(sc->sc_udev, 1403 ed->bEndpointAddress, UF_ENDPOINT_HALT)) 1404 goto bad; 1405 } 1406 } 1407 return; 1408 bad: 1409 printf("%s: clear endpoints failed!\n", __func__); 1410 } 1411