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