1 /* $NetBSD: ugen.c,v 1.78 2005/12/11 12:24:01 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.78 2005/12/11 12:24:01 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 endpt = ed->bEndpointAddress; 298 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 299 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 300 DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x" 301 "(%d,%d), sce=%p\n", 302 endptno, endpt, UE_GET_ADDR(endpt), 303 UE_GET_DIR(endpt), sce)); 304 sce->sc = sc; 305 sce->edesc = ed; 306 sce->iface = iface; 307 } 308 } 309 return (USBD_NORMAL_COMPLETION); 310 } 311 312 int 313 ugenopen(dev_t dev, int flag, int mode, struct lwp *l) 314 { 315 struct ugen_softc *sc; 316 int unit = UGENUNIT(dev); 317 int endpt = UGENENDPOINT(dev); 318 usb_endpoint_descriptor_t *edesc; 319 struct ugen_endpoint *sce; 320 int dir, isize; 321 usbd_status err; 322 usbd_xfer_handle xfer; 323 void *tbuf; 324 int i, j; 325 326 USB_GET_SC_OPEN(ugen, unit, sc); 327 328 DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n", 329 flag, mode, unit, endpt)); 330 331 if (sc == NULL || sc->sc_dying) 332 return (ENXIO); 333 334 /* The control endpoint allows multiple opens. */ 335 if (endpt == USB_CONTROL_ENDPOINT) { 336 sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1; 337 return (0); 338 } 339 340 if (sc->sc_is_open[endpt]) 341 return (EBUSY); 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 if (dir == OUT) { 366 err = usbd_open_pipe(sce->iface, 367 edesc->bEndpointAddress, 0, &sce->pipeh); 368 if (err) 369 return (EIO); 370 break; 371 } 372 isize = UGETW(edesc->wMaxPacketSize); 373 if (isize == 0) /* shouldn't happen */ 374 return (EINVAL); 375 sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK); 376 DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n", 377 endpt, isize)); 378 if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1) 379 return (ENOMEM); 380 err = usbd_open_pipe_intr(sce->iface, 381 edesc->bEndpointAddress, 382 USBD_SHORT_XFER_OK, &sce->pipeh, sce, 383 sce->ibuf, isize, ugenintr, 384 USBD_DEFAULT_INTERVAL); 385 if (err) { 386 free(sce->ibuf, M_USBDEV); 387 clfree(&sce->q); 388 return (EIO); 389 } 390 DPRINTFN(5, ("ugenopen: interrupt open done\n")); 391 break; 392 case UE_BULK: 393 err = usbd_open_pipe(sce->iface, 394 edesc->bEndpointAddress, 0, &sce->pipeh); 395 if (err) 396 return (EIO); 397 break; 398 case UE_ISOCHRONOUS: 399 if (dir == OUT) 400 return (EINVAL); 401 isize = UGETW(edesc->wMaxPacketSize); 402 if (isize == 0) /* shouldn't happen */ 403 return (EINVAL); 404 sce->ibuf = malloc(isize * UGEN_NISOFRAMES, 405 M_USBDEV, M_WAITOK); 406 sce->cur = sce->fill = sce->ibuf; 407 sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES; 408 DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n", 409 endpt, isize)); 410 err = usbd_open_pipe(sce->iface, 411 edesc->bEndpointAddress, 0, &sce->pipeh); 412 if (err) { 413 free(sce->ibuf, M_USBDEV); 414 return (EIO); 415 } 416 for(i = 0; i < UGEN_NISOREQS; ++i) { 417 sce->isoreqs[i].sce = sce; 418 xfer = usbd_alloc_xfer(sc->sc_udev); 419 if (xfer == 0) 420 goto bad; 421 sce->isoreqs[i].xfer = xfer; 422 tbuf = usbd_alloc_buffer 423 (xfer, isize * UGEN_NISORFRMS); 424 if (tbuf == 0) { 425 i++; 426 goto bad; 427 } 428 sce->isoreqs[i].dmabuf = tbuf; 429 for(j = 0; j < UGEN_NISORFRMS; ++j) 430 sce->isoreqs[i].sizes[j] = isize; 431 usbd_setup_isoc_xfer 432 (xfer, sce->pipeh, &sce->isoreqs[i], 433 sce->isoreqs[i].sizes, 434 UGEN_NISORFRMS, USBD_NO_COPY, 435 ugen_isoc_rintr); 436 (void)usbd_transfer(xfer); 437 } 438 DPRINTFN(5, ("ugenopen: isoc open done\n")); 439 break; 440 bad: 441 while (--i >= 0) /* implicit buffer free */ 442 usbd_free_xfer(sce->isoreqs[i].xfer); 443 return (ENOMEM); 444 case UE_CONTROL: 445 sce->timeout = USBD_DEFAULT_TIMEOUT; 446 return (EINVAL); 447 } 448 } 449 sc->sc_is_open[endpt] = 1; 450 return (0); 451 } 452 453 int 454 ugenclose(dev_t dev, int flag, int mode, struct lwp *l) 455 { 456 int endpt = UGENENDPOINT(dev); 457 struct ugen_softc *sc; 458 struct ugen_endpoint *sce; 459 int dir; 460 int i; 461 462 USB_GET_SC(ugen, UGENUNIT(dev), sc); 463 464 DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n", 465 flag, mode, UGENUNIT(dev), endpt)); 466 467 #ifdef DIAGNOSTIC 468 if (!sc->sc_is_open[endpt]) { 469 printf("ugenclose: not open\n"); 470 return (EINVAL); 471 } 472 #endif 473 474 if (endpt == USB_CONTROL_ENDPOINT) { 475 DPRINTFN(5, ("ugenclose: close control\n")); 476 sc->sc_is_open[endpt] = 0; 477 return (0); 478 } 479 480 for (dir = OUT; dir <= IN; dir++) { 481 if (!(flag & (dir == OUT ? FWRITE : FREAD))) 482 continue; 483 sce = &sc->sc_endpoints[endpt][dir]; 484 if (sce == NULL || sce->pipeh == NULL) 485 continue; 486 DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n", 487 endpt, dir, sce)); 488 489 usbd_abort_pipe(sce->pipeh); 490 usbd_close_pipe(sce->pipeh); 491 sce->pipeh = NULL; 492 493 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 494 case UE_INTERRUPT: 495 ndflush(&sce->q, sce->q.c_cc); 496 clfree(&sce->q); 497 break; 498 case UE_ISOCHRONOUS: 499 for (i = 0; i < UGEN_NISOREQS; ++i) 500 usbd_free_xfer(sce->isoreqs[i].xfer); 501 502 default: 503 break; 504 } 505 506 if (sce->ibuf != NULL) { 507 free(sce->ibuf, M_USBDEV); 508 sce->ibuf = NULL; 509 clfree(&sce->q); 510 } 511 } 512 sc->sc_is_open[endpt] = 0; 513 514 return (0); 515 } 516 517 Static int 518 ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) 519 { 520 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN]; 521 u_int32_t n, tn; 522 char tbuf[UGEN_BBSIZE]; 523 usbd_xfer_handle xfer; 524 usbd_status err; 525 int s; 526 int error = 0; 527 u_char buffer[UGEN_CHUNK]; 528 529 DPRINTFN(5, ("%s: ugenread: %d\n", USBDEVNAME(sc->sc_dev), endpt)); 530 531 if (sc->sc_dying) 532 return (EIO); 533 534 if (endpt == USB_CONTROL_ENDPOINT) 535 return (ENODEV); 536 537 #ifdef DIAGNOSTIC 538 if (sce->edesc == NULL) { 539 printf("ugenread: no edesc\n"); 540 return (EIO); 541 } 542 if (sce->pipeh == NULL) { 543 printf("ugenread: no pipe\n"); 544 return (EIO); 545 } 546 #endif 547 548 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 549 case UE_INTERRUPT: 550 /* Block until activity occurred. */ 551 s = splusb(); 552 while (sce->q.c_cc == 0) { 553 if (flag & IO_NDELAY) { 554 splx(s); 555 return (EWOULDBLOCK); 556 } 557 sce->state |= UGEN_ASLP; 558 DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); 559 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0); 560 DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); 561 if (sc->sc_dying) 562 error = EIO; 563 if (error) { 564 sce->state &= ~UGEN_ASLP; 565 break; 566 } 567 } 568 splx(s); 569 570 /* Transfer as many chunks as possible. */ 571 while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) { 572 n = min(sce->q.c_cc, uio->uio_resid); 573 if (n > sizeof(buffer)) 574 n = sizeof(buffer); 575 576 /* Remove a small chunk from the input queue. */ 577 q_to_b(&sce->q, buffer, n); 578 DPRINTFN(5, ("ugenread: got %d chars\n", n)); 579 580 /* Copy the data to the user process. */ 581 error = uiomove(buffer, n, uio); 582 if (error) 583 break; 584 } 585 break; 586 case UE_BULK: 587 xfer = usbd_alloc_xfer(sc->sc_udev); 588 if (xfer == 0) 589 return (ENOMEM); 590 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { 591 DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n)); 592 tn = n; 593 err = usbd_bulk_transfer( 594 xfer, sce->pipeh, 595 sce->state & UGEN_SHORT_OK ? 596 USBD_SHORT_XFER_OK : 0, 597 sce->timeout, tbuf, &tn, "ugenrb"); 598 if (err) { 599 if (err == USBD_INTERRUPTED) 600 error = EINTR; 601 else if (err == USBD_TIMEOUT) 602 error = ETIMEDOUT; 603 else 604 error = EIO; 605 break; 606 } 607 DPRINTFN(1, ("ugenread: got %d bytes\n", tn)); 608 error = uiomove(tbuf, tn, uio); 609 if (error || tn < n) 610 break; 611 } 612 usbd_free_xfer(xfer); 613 break; 614 case UE_ISOCHRONOUS: 615 s = splusb(); 616 while (sce->cur == sce->fill) { 617 if (flag & IO_NDELAY) { 618 splx(s); 619 return (EWOULDBLOCK); 620 } 621 sce->state |= UGEN_ASLP; 622 DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); 623 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0); 624 DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); 625 if (sc->sc_dying) 626 error = EIO; 627 if (error) { 628 sce->state &= ~UGEN_ASLP; 629 break; 630 } 631 } 632 633 while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) { 634 if(sce->fill > sce->cur) 635 n = min(sce->fill - sce->cur, uio->uio_resid); 636 else 637 n = min(sce->limit - sce->cur, uio->uio_resid); 638 639 DPRINTFN(5, ("ugenread: isoc got %d chars\n", n)); 640 641 /* Copy the data to the user process. */ 642 error = uiomove(sce->cur, n, uio); 643 if (error) 644 break; 645 sce->cur += n; 646 if(sce->cur >= sce->limit) 647 sce->cur = sce->ibuf; 648 } 649 splx(s); 650 break; 651 652 653 default: 654 return (ENXIO); 655 } 656 return (error); 657 } 658 659 int 660 ugenread(dev_t dev, struct uio *uio, int flag) 661 { 662 int endpt = UGENENDPOINT(dev); 663 struct ugen_softc *sc; 664 int error; 665 666 USB_GET_SC(ugen, UGENUNIT(dev), sc); 667 668 sc->sc_refcnt++; 669 error = ugen_do_read(sc, endpt, uio, flag); 670 if (--sc->sc_refcnt < 0) 671 usb_detach_wakeup(USBDEV(sc->sc_dev)); 672 return (error); 673 } 674 675 Static int 676 ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) 677 { 678 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT]; 679 u_int32_t n; 680 int error = 0; 681 char tbuf[UGEN_BBSIZE]; 682 usbd_xfer_handle xfer; 683 usbd_status err; 684 685 DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc->sc_dev), endpt)); 686 687 if (sc->sc_dying) 688 return (EIO); 689 690 if (endpt == USB_CONTROL_ENDPOINT) 691 return (ENODEV); 692 693 #ifdef DIAGNOSTIC 694 if (sce->edesc == NULL) { 695 printf("ugenwrite: no edesc\n"); 696 return (EIO); 697 } 698 if (sce->pipeh == NULL) { 699 printf("ugenwrite: no pipe\n"); 700 return (EIO); 701 } 702 #endif 703 704 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 705 case UE_BULK: 706 xfer = usbd_alloc_xfer(sc->sc_udev); 707 if (xfer == 0) 708 return (EIO); 709 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { 710 error = uiomove(tbuf, n, uio); 711 if (error) 712 break; 713 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); 714 err = usbd_bulk_transfer(xfer, sce->pipeh, 0, 715 sce->timeout, tbuf, &n,"ugenwb"); 716 if (err) { 717 if (err == USBD_INTERRUPTED) 718 error = EINTR; 719 else if (err == USBD_TIMEOUT) 720 error = ETIMEDOUT; 721 else 722 error = EIO; 723 break; 724 } 725 } 726 usbd_free_xfer(xfer); 727 break; 728 case UE_INTERRUPT: 729 xfer = usbd_alloc_xfer(sc->sc_udev); 730 if (xfer == 0) 731 return (EIO); 732 while ((n = min(UGETW(sce->edesc->wMaxPacketSize), 733 uio->uio_resid)) != 0) { 734 error = uiomove(tbuf, n, uio); 735 if (error) 736 break; 737 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); 738 err = usbd_intr_transfer(xfer, sce->pipeh, 0, 739 sce->timeout, tbuf, &n, "ugenwi"); 740 if (err) { 741 if (err == USBD_INTERRUPTED) 742 error = EINTR; 743 else if (err == USBD_TIMEOUT) 744 error = ETIMEDOUT; 745 else 746 error = EIO; 747 break; 748 } 749 } 750 usbd_free_xfer(xfer); 751 break; 752 default: 753 return (ENXIO); 754 } 755 return (error); 756 } 757 758 int 759 ugenwrite(dev_t dev, struct uio *uio, int flag) 760 { 761 int endpt = UGENENDPOINT(dev); 762 struct ugen_softc *sc; 763 int error; 764 765 USB_GET_SC(ugen, UGENUNIT(dev), sc); 766 767 sc->sc_refcnt++; 768 error = ugen_do_write(sc, endpt, uio, flag); 769 if (--sc->sc_refcnt < 0) 770 usb_detach_wakeup(USBDEV(sc->sc_dev)); 771 return (error); 772 } 773 774 #if defined(__NetBSD__) || defined(__OpenBSD__) 775 int 776 ugen_activate(device_ptr_t self, enum devact act) 777 { 778 struct ugen_softc *sc = (struct ugen_softc *)self; 779 780 switch (act) { 781 case DVACT_ACTIVATE: 782 return (EOPNOTSUPP); 783 784 case DVACT_DEACTIVATE: 785 sc->sc_dying = 1; 786 break; 787 } 788 return (0); 789 } 790 #endif 791 792 USB_DETACH(ugen) 793 { 794 USB_DETACH_START(ugen, sc); 795 struct ugen_endpoint *sce; 796 int i, dir; 797 int s; 798 #if defined(__NetBSD__) || defined(__OpenBSD__) 799 int maj, mn; 800 801 DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags)); 802 #elif defined(__FreeBSD__) 803 DPRINTF(("ugen_detach: sc=%p\n", sc)); 804 #endif 805 806 sc->sc_dying = 1; 807 /* Abort all pipes. Causes processes waiting for transfer to wake. */ 808 for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 809 for (dir = OUT; dir <= IN; dir++) { 810 sce = &sc->sc_endpoints[i][dir]; 811 if (sce && sce->pipeh) 812 usbd_abort_pipe(sce->pipeh); 813 } 814 } 815 816 s = splusb(); 817 if (--sc->sc_refcnt >= 0) { 818 /* Wake everyone */ 819 for (i = 0; i < USB_MAX_ENDPOINTS; i++) 820 wakeup(&sc->sc_endpoints[i][IN]); 821 /* Wait for processes to go away. */ 822 usb_detach_wait(USBDEV(sc->sc_dev)); 823 } 824 splx(s); 825 826 #if defined(__NetBSD__) || defined(__OpenBSD__) 827 /* locate the major number */ 828 #if defined(__NetBSD__) 829 maj = cdevsw_lookup_major(&ugen_cdevsw); 830 #elif defined(__OpenBSD__) 831 for (maj = 0; maj < nchrdev; maj++) 832 if (cdevsw[maj].d_open == ugenopen) 833 break; 834 #endif 835 836 /* Nuke the vnodes for any open instances (calls close). */ 837 mn = self->dv_unit * USB_MAX_ENDPOINTS; 838 vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR); 839 #elif defined(__FreeBSD__) 840 /* XXX not implemented yet */ 841 #endif 842 843 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 844 USBDEV(sc->sc_dev)); 845 846 return (0); 847 } 848 849 Static void 850 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) 851 { 852 struct ugen_endpoint *sce = addr; 853 /*struct ugen_softc *sc = sce->sc;*/ 854 u_int32_t count; 855 u_char *ibuf; 856 857 if (status == USBD_CANCELLED) 858 return; 859 860 if (status != USBD_NORMAL_COMPLETION) { 861 DPRINTF(("ugenintr: status=%d\n", status)); 862 if (status == USBD_STALLED) 863 usbd_clear_endpoint_stall_async(sce->pipeh); 864 return; 865 } 866 867 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 868 ibuf = sce->ibuf; 869 870 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n", 871 xfer, status, count)); 872 DPRINTFN(5, (" data = %02x %02x %02x\n", 873 ibuf[0], ibuf[1], ibuf[2])); 874 875 (void)b_to_q(ibuf, count, &sce->q); 876 877 if (sce->state & UGEN_ASLP) { 878 sce->state &= ~UGEN_ASLP; 879 DPRINTFN(5, ("ugen_intr: waking %p\n", sce)); 880 wakeup(sce); 881 } 882 selnotify(&sce->rsel, 0); 883 } 884 885 Static void 886 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, 887 usbd_status status) 888 { 889 struct isoreq *req = addr; 890 struct ugen_endpoint *sce = req->sce; 891 u_int32_t count, n; 892 int i, isize; 893 894 /* Return if we are aborting. */ 895 if (status == USBD_CANCELLED) 896 return; 897 898 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 899 DPRINTFN(5,("ugen_isoc_rintr: xfer %ld, count=%d\n", 900 (long)(req - sce->isoreqs), count)); 901 902 /* throw away oldest input if the buffer is full */ 903 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) { 904 sce->cur += count; 905 if(sce->cur >= sce->limit) 906 sce->cur = sce->ibuf + (sce->limit - sce->cur); 907 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n", 908 count)); 909 } 910 911 isize = UGETW(sce->edesc->wMaxPacketSize); 912 for (i = 0; i < UGEN_NISORFRMS; i++) { 913 u_int32_t actlen = req->sizes[i]; 914 char const *tbuf = (char const *)req->dmabuf + isize * i; 915 916 /* copy data to buffer */ 917 while (actlen > 0) { 918 n = min(actlen, sce->limit - sce->fill); 919 memcpy(sce->fill, tbuf, n); 920 921 tbuf += n; 922 actlen -= n; 923 sce->fill += n; 924 if(sce->fill == sce->limit) 925 sce->fill = sce->ibuf; 926 } 927 928 /* setup size for next transfer */ 929 req->sizes[i] = isize; 930 } 931 932 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS, 933 USBD_NO_COPY, ugen_isoc_rintr); 934 (void)usbd_transfer(xfer); 935 936 if (sce->state & UGEN_ASLP) { 937 sce->state &= ~UGEN_ASLP; 938 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce)); 939 wakeup(sce); 940 } 941 selnotify(&sce->rsel, 0); 942 } 943 944 Static usbd_status 945 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) 946 { 947 usbd_interface_handle iface; 948 usb_endpoint_descriptor_t *ed; 949 usbd_status err; 950 struct ugen_endpoint *sce; 951 u_int8_t niface, nendpt, endptno, endpt; 952 int dir; 953 954 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); 955 956 err = usbd_interface_count(sc->sc_udev, &niface); 957 if (err) 958 return (err); 959 if (ifaceidx < 0 || ifaceidx >= niface) 960 return (USBD_INVAL); 961 962 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); 963 if (err) 964 return (err); 965 err = usbd_endpoint_count(iface, &nendpt); 966 if (err) 967 return (err); 968 /* XXX should only do this after setting new altno has succeeded */ 969 for (endptno = 0; endptno < nendpt; endptno++) { 970 ed = usbd_interface2endpoint_descriptor(iface,endptno); 971 endpt = ed->bEndpointAddress; 972 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 973 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 974 sce->sc = 0; 975 sce->edesc = 0; 976 sce->iface = 0; 977 } 978 979 /* change setting */ 980 err = usbd_set_interface(iface, altno); 981 if (err) 982 return (err); 983 984 err = usbd_endpoint_count(iface, &nendpt); 985 if (err) 986 return (err); 987 for (endptno = 0; endptno < nendpt; endptno++) { 988 ed = usbd_interface2endpoint_descriptor(iface,endptno); 989 endpt = ed->bEndpointAddress; 990 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 991 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 992 sce->sc = sc; 993 sce->edesc = ed; 994 sce->iface = iface; 995 } 996 return (0); 997 } 998 999 /* Retrieve a complete descriptor for a certain device and index. */ 1000 Static usb_config_descriptor_t * 1001 ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp) 1002 { 1003 usb_config_descriptor_t *cdesc, *tdesc, cdescr; 1004 int len; 1005 usbd_status err; 1006 1007 if (index == USB_CURRENT_CONFIG_INDEX) { 1008 tdesc = usbd_get_config_descriptor(sc->sc_udev); 1009 len = UGETW(tdesc->wTotalLength); 1010 if (lenp) 1011 *lenp = len; 1012 cdesc = malloc(len, M_TEMP, M_WAITOK); 1013 memcpy(cdesc, tdesc, len); 1014 DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len)); 1015 } else { 1016 err = usbd_get_config_desc(sc->sc_udev, index, &cdescr); 1017 if (err) 1018 return (0); 1019 len = UGETW(cdescr.wTotalLength); 1020 DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len)); 1021 if (lenp) 1022 *lenp = len; 1023 cdesc = malloc(len, M_TEMP, M_WAITOK); 1024 err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len); 1025 if (err) { 1026 free(cdesc, M_TEMP); 1027 return (0); 1028 } 1029 } 1030 return (cdesc); 1031 } 1032 1033 Static int 1034 ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx) 1035 { 1036 usbd_interface_handle iface; 1037 usbd_status err; 1038 1039 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); 1040 if (err) 1041 return (-1); 1042 return (usbd_get_interface_altindex(iface)); 1043 } 1044 1045 Static int 1046 ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, 1047 caddr_t addr, int flag, struct lwp *l) 1048 { 1049 struct ugen_endpoint *sce; 1050 usbd_status err; 1051 usbd_interface_handle iface; 1052 struct usb_config_desc *cd; 1053 usb_config_descriptor_t *cdesc; 1054 struct usb_interface_desc *id; 1055 usb_interface_descriptor_t *idesc; 1056 struct usb_endpoint_desc *ed; 1057 usb_endpoint_descriptor_t *edesc; 1058 struct usb_alt_interface *ai; 1059 struct usb_string_desc *si; 1060 u_int8_t conf, alt; 1061 1062 DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd)); 1063 if (sc->sc_dying) 1064 return (EIO); 1065 1066 switch (cmd) { 1067 case FIONBIO: 1068 /* All handled in the upper FS layer. */ 1069 return (0); 1070 case USB_SET_SHORT_XFER: 1071 if (endpt == USB_CONTROL_ENDPOINT) 1072 return (EINVAL); 1073 /* This flag only affects read */ 1074 sce = &sc->sc_endpoints[endpt][IN]; 1075 if (sce == NULL || sce->pipeh == NULL) 1076 return (EINVAL); 1077 if (*(int *)addr) 1078 sce->state |= UGEN_SHORT_OK; 1079 else 1080 sce->state &= ~UGEN_SHORT_OK; 1081 return (0); 1082 case USB_SET_TIMEOUT: 1083 sce = &sc->sc_endpoints[endpt][IN]; 1084 if (sce == NULL 1085 /* XXX this shouldn't happen, but the distinction between 1086 input and output pipes isn't clear enough. 1087 || sce->pipeh == NULL */ 1088 ) 1089 return (EINVAL); 1090 sce->timeout = *(int *)addr; 1091 return (0); 1092 default: 1093 break; 1094 } 1095 1096 if (endpt != USB_CONTROL_ENDPOINT) 1097 return (EINVAL); 1098 1099 switch (cmd) { 1100 #ifdef UGEN_DEBUG 1101 case USB_SETDEBUG: 1102 ugendebug = *(int *)addr; 1103 break; 1104 #endif 1105 case USB_GET_CONFIG: 1106 err = usbd_get_config(sc->sc_udev, &conf); 1107 if (err) 1108 return (EIO); 1109 *(int *)addr = conf; 1110 break; 1111 case USB_SET_CONFIG: 1112 if (!(flag & FWRITE)) 1113 return (EPERM); 1114 err = ugen_set_config(sc, *(int *)addr); 1115 switch (err) { 1116 case USBD_NORMAL_COMPLETION: 1117 break; 1118 case USBD_IN_USE: 1119 return (EBUSY); 1120 default: 1121 return (EIO); 1122 } 1123 break; 1124 case USB_GET_ALTINTERFACE: 1125 ai = (struct usb_alt_interface *)addr; 1126 err = usbd_device2interface_handle(sc->sc_udev, 1127 ai->uai_interface_index, &iface); 1128 if (err) 1129 return (EINVAL); 1130 idesc = usbd_get_interface_descriptor(iface); 1131 if (idesc == NULL) 1132 return (EIO); 1133 ai->uai_alt_no = idesc->bAlternateSetting; 1134 break; 1135 case USB_SET_ALTINTERFACE: 1136 if (!(flag & FWRITE)) 1137 return (EPERM); 1138 ai = (struct usb_alt_interface *)addr; 1139 err = usbd_device2interface_handle(sc->sc_udev, 1140 ai->uai_interface_index, &iface); 1141 if (err) 1142 return (EINVAL); 1143 err = ugen_set_interface(sc, ai->uai_interface_index, 1144 ai->uai_alt_no); 1145 if (err) 1146 return (EINVAL); 1147 break; 1148 case USB_GET_NO_ALT: 1149 ai = (struct usb_alt_interface *)addr; 1150 cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0); 1151 if (cdesc == NULL) 1152 return (EINVAL); 1153 idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0); 1154 if (idesc == NULL) { 1155 free(cdesc, M_TEMP); 1156 return (EINVAL); 1157 } 1158 ai->uai_alt_no = usbd_get_no_alts(cdesc, 1159 idesc->bInterfaceNumber); 1160 free(cdesc, M_TEMP); 1161 break; 1162 case USB_GET_DEVICE_DESC: 1163 *(usb_device_descriptor_t *)addr = 1164 *usbd_get_device_descriptor(sc->sc_udev); 1165 break; 1166 case USB_GET_CONFIG_DESC: 1167 cd = (struct usb_config_desc *)addr; 1168 cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0); 1169 if (cdesc == NULL) 1170 return (EINVAL); 1171 cd->ucd_desc = *cdesc; 1172 free(cdesc, M_TEMP); 1173 break; 1174 case USB_GET_INTERFACE_DESC: 1175 id = (struct usb_interface_desc *)addr; 1176 cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0); 1177 if (cdesc == NULL) 1178 return (EINVAL); 1179 if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX && 1180 id->uid_alt_index == USB_CURRENT_ALT_INDEX) 1181 alt = ugen_get_alt_index(sc, id->uid_interface_index); 1182 else 1183 alt = id->uid_alt_index; 1184 idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt); 1185 if (idesc == NULL) { 1186 free(cdesc, M_TEMP); 1187 return (EINVAL); 1188 } 1189 id->uid_desc = *idesc; 1190 free(cdesc, M_TEMP); 1191 break; 1192 case USB_GET_ENDPOINT_DESC: 1193 ed = (struct usb_endpoint_desc *)addr; 1194 cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0); 1195 if (cdesc == NULL) 1196 return (EINVAL); 1197 if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX && 1198 ed->ued_alt_index == USB_CURRENT_ALT_INDEX) 1199 alt = ugen_get_alt_index(sc, ed->ued_interface_index); 1200 else 1201 alt = ed->ued_alt_index; 1202 edesc = usbd_find_edesc(cdesc, ed->ued_interface_index, 1203 alt, ed->ued_endpoint_index); 1204 if (edesc == NULL) { 1205 free(cdesc, M_TEMP); 1206 return (EINVAL); 1207 } 1208 ed->ued_desc = *edesc; 1209 free(cdesc, M_TEMP); 1210 break; 1211 case USB_GET_FULL_DESC: 1212 { 1213 int len; 1214 struct iovec iov; 1215 struct uio uio; 1216 struct usb_full_desc *fd = (struct usb_full_desc *)addr; 1217 int error; 1218 1219 cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len); 1220 if (len > fd->ufd_size) 1221 len = fd->ufd_size; 1222 iov.iov_base = (caddr_t)fd->ufd_data; 1223 iov.iov_len = len; 1224 uio.uio_iov = &iov; 1225 uio.uio_iovcnt = 1; 1226 uio.uio_resid = len; 1227 uio.uio_offset = 0; 1228 uio.uio_segflg = UIO_USERSPACE; 1229 uio.uio_rw = UIO_READ; 1230 uio.uio_lwp = l; 1231 error = uiomove((void *)cdesc, len, &uio); 1232 free(cdesc, M_TEMP); 1233 return (error); 1234 } 1235 case USB_GET_STRING_DESC: { 1236 int len; 1237 si = (struct usb_string_desc *)addr; 1238 err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index, 1239 si->usd_language_id, &si->usd_desc, &len); 1240 if (err) 1241 return (EINVAL); 1242 break; 1243 } 1244 case USB_DO_REQUEST: 1245 { 1246 struct usb_ctl_request *ur = (void *)addr; 1247 int len = UGETW(ur->ucr_request.wLength); 1248 struct iovec iov; 1249 struct uio uio; 1250 void *ptr = 0; 1251 usbd_status xerr; 1252 int error = 0; 1253 1254 if (!(flag & FWRITE)) 1255 return (EPERM); 1256 /* Avoid requests that would damage the bus integrity. */ 1257 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 1258 ur->ucr_request.bRequest == UR_SET_ADDRESS) || 1259 (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 1260 ur->ucr_request.bRequest == UR_SET_CONFIG) || 1261 (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE && 1262 ur->ucr_request.bRequest == UR_SET_INTERFACE)) 1263 return (EINVAL); 1264 1265 if (len < 0 || len > 32767) 1266 return (EINVAL); 1267 if (len != 0) { 1268 iov.iov_base = (caddr_t)ur->ucr_data; 1269 iov.iov_len = len; 1270 uio.uio_iov = &iov; 1271 uio.uio_iovcnt = 1; 1272 uio.uio_resid = len; 1273 uio.uio_offset = 0; 1274 uio.uio_segflg = UIO_USERSPACE; 1275 uio.uio_rw = 1276 ur->ucr_request.bmRequestType & UT_READ ? 1277 UIO_READ : UIO_WRITE; 1278 uio.uio_lwp = l; 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