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