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