1 /* $NetBSD: ugen.c,v 1.75 2005/06/21 14:01:12 ws 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.75 2005/06/21 14:01:12 ws 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, 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 *devinfop; 206 usbd_status err; 207 int conf; 208 209 devinfop = usbd_devinfo_alloc(uaa->device, 0); 210 USB_ATTACH_SETUP; 211 printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfop); 212 usbd_devinfo_free(devinfop); 213 214 sc->sc_udev = udev = uaa->device; 215 216 /* First set configuration index 0, the default one for ugen. */ 217 err = usbd_set_config_index(udev, 0, 0); 218 if (err) { 219 printf("%s: setting configuration index 0 failed\n", 220 USBDEVNAME(sc->sc_dev)); 221 sc->sc_dying = 1; 222 USB_ATTACH_ERROR_RETURN; 223 } 224 conf = usbd_get_config_descriptor(udev)->bConfigurationValue; 225 226 /* Set up all the local state for this configuration. */ 227 err = ugen_set_config(sc, conf); 228 if (err) { 229 printf("%s: setting configuration %d failed\n", 230 USBDEVNAME(sc->sc_dev), conf); 231 sc->sc_dying = 1; 232 USB_ATTACH_ERROR_RETURN; 233 } 234 235 #ifdef __FreeBSD__ 236 { 237 static int global_init_done = 0; 238 if (!global_init_done) { 239 cdevsw_add(&ugen_cdevsw); 240 global_init_done = 1; 241 } 242 } 243 #endif 244 245 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 246 USBDEV(sc->sc_dev)); 247 248 USB_ATTACH_SUCCESS_RETURN; 249 } 250 251 Static int 252 ugen_set_config(struct ugen_softc *sc, int configno) 253 { 254 usbd_device_handle dev = sc->sc_udev; 255 usbd_interface_handle iface; 256 usb_endpoint_descriptor_t *ed; 257 struct ugen_endpoint *sce; 258 u_int8_t niface, nendpt; 259 int ifaceno, endptno, endpt; 260 usbd_status err; 261 int dir; 262 263 DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n", 264 USBDEVNAME(sc->sc_dev), configno, sc)); 265 266 /* 267 * We start at 1, not 0, because we don't care whether the 268 * control endpoint is open or not. It is always present. 269 */ 270 for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) 271 if (sc->sc_is_open[endptno]) { 272 DPRINTFN(1, 273 ("ugen_set_config: %s - endpoint %d is open\n", 274 USBDEVNAME(sc->sc_dev), endptno)); 275 return (USBD_IN_USE); 276 } 277 278 /* Avoid setting the current value. */ 279 if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) { 280 err = usbd_set_config_no(dev, configno, 1); 281 if (err) 282 return (err); 283 } 284 285 err = usbd_interface_count(dev, &niface); 286 if (err) 287 return (err); 288 memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints); 289 for (ifaceno = 0; ifaceno < niface; ifaceno++) { 290 DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno)); 291 err = usbd_device2interface_handle(dev, ifaceno, &iface); 292 if (err) 293 return (err); 294 err = usbd_endpoint_count(iface, &nendpt); 295 if (err) 296 return (err); 297 for (endptno = 0; endptno < nendpt; endptno++) { 298 ed = usbd_interface2endpoint_descriptor(iface,endptno); 299 endpt = ed->bEndpointAddress; 300 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 301 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 302 DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x" 303 "(%d,%d), sce=%p\n", 304 endptno, endpt, UE_GET_ADDR(endpt), 305 UE_GET_DIR(endpt), sce)); 306 sce->sc = sc; 307 sce->edesc = ed; 308 sce->iface = iface; 309 } 310 } 311 return (USBD_NORMAL_COMPLETION); 312 } 313 314 int 315 ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p) 316 { 317 struct ugen_softc *sc; 318 int unit = UGENUNIT(dev); 319 int endpt = UGENENDPOINT(dev); 320 usb_endpoint_descriptor_t *edesc; 321 struct ugen_endpoint *sce; 322 int dir, isize; 323 usbd_status err; 324 usbd_xfer_handle xfer; 325 void *tbuf; 326 int i, j; 327 328 USB_GET_SC_OPEN(ugen, unit, sc); 329 330 DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n", 331 flag, mode, unit, endpt)); 332 333 if (sc == NULL || sc->sc_dying) 334 return (ENXIO); 335 336 /* The control endpoint allows multiple opens. */ 337 if (endpt == USB_CONTROL_ENDPOINT) { 338 sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1; 339 return (0); 340 } 341 342 if (sc->sc_is_open[endpt]) 343 return (EBUSY); 344 345 /* Make sure there are pipes for all directions. */ 346 for (dir = OUT; dir <= IN; dir++) { 347 if (flag & (dir == OUT ? FWRITE : FREAD)) { 348 sce = &sc->sc_endpoints[endpt][dir]; 349 if (sce == 0 || sce->edesc == 0) 350 return (ENXIO); 351 } 352 } 353 354 /* Actually open the pipes. */ 355 /* XXX Should back out properly if it fails. */ 356 for (dir = OUT; dir <= IN; dir++) { 357 if (!(flag & (dir == OUT ? FWRITE : FREAD))) 358 continue; 359 sce = &sc->sc_endpoints[endpt][dir]; 360 sce->state = 0; 361 sce->timeout = USBD_NO_TIMEOUT; 362 DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n", 363 sc, endpt, dir, sce)); 364 edesc = sce->edesc; 365 switch (edesc->bmAttributes & UE_XFERTYPE) { 366 case UE_INTERRUPT: 367 if (dir == OUT) { 368 err = usbd_open_pipe(sce->iface, 369 edesc->bEndpointAddress, 0, &sce->pipeh); 370 if (err) 371 return (EIO); 372 break; 373 } 374 isize = UGETW(edesc->wMaxPacketSize); 375 if (isize == 0) /* shouldn't happen */ 376 return (EINVAL); 377 sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK); 378 DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n", 379 endpt, isize)); 380 if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1) 381 return (ENOMEM); 382 err = usbd_open_pipe_intr(sce->iface, 383 edesc->bEndpointAddress, 384 USBD_SHORT_XFER_OK, &sce->pipeh, sce, 385 sce->ibuf, isize, ugenintr, 386 USBD_DEFAULT_INTERVAL); 387 if (err) { 388 free(sce->ibuf, M_USBDEV); 389 clfree(&sce->q); 390 return (EIO); 391 } 392 DPRINTFN(5, ("ugenopen: interrupt open done\n")); 393 break; 394 case UE_BULK: 395 err = usbd_open_pipe(sce->iface, 396 edesc->bEndpointAddress, 0, &sce->pipeh); 397 if (err) 398 return (EIO); 399 break; 400 case UE_ISOCHRONOUS: 401 if (dir == OUT) 402 return (EINVAL); 403 isize = UGETW(edesc->wMaxPacketSize); 404 if (isize == 0) /* shouldn't happen */ 405 return (EINVAL); 406 sce->ibuf = malloc(isize * UGEN_NISOFRAMES, 407 M_USBDEV, M_WAITOK); 408 sce->cur = sce->fill = sce->ibuf; 409 sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES; 410 DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n", 411 endpt, isize)); 412 err = usbd_open_pipe(sce->iface, 413 edesc->bEndpointAddress, 0, &sce->pipeh); 414 if (err) { 415 free(sce->ibuf, M_USBDEV); 416 return (EIO); 417 } 418 for(i = 0; i < UGEN_NISOREQS; ++i) { 419 sce->isoreqs[i].sce = sce; 420 xfer = usbd_alloc_xfer(sc->sc_udev); 421 if (xfer == 0) 422 goto bad; 423 sce->isoreqs[i].xfer = xfer; 424 tbuf = usbd_alloc_buffer 425 (xfer, isize * UGEN_NISORFRMS); 426 if (tbuf == 0) { 427 i++; 428 goto bad; 429 } 430 sce->isoreqs[i].dmabuf = tbuf; 431 for(j = 0; j < UGEN_NISORFRMS; ++j) 432 sce->isoreqs[i].sizes[j] = isize; 433 usbd_setup_isoc_xfer 434 (xfer, sce->pipeh, &sce->isoreqs[i], 435 sce->isoreqs[i].sizes, 436 UGEN_NISORFRMS, USBD_NO_COPY, 437 ugen_isoc_rintr); 438 (void)usbd_transfer(xfer); 439 } 440 DPRINTFN(5, ("ugenopen: isoc open done\n")); 441 break; 442 bad: 443 while (--i >= 0) /* implicit buffer free */ 444 usbd_free_xfer(sce->isoreqs[i].xfer); 445 return (ENOMEM); 446 case UE_CONTROL: 447 sce->timeout = USBD_DEFAULT_TIMEOUT; 448 return (EINVAL); 449 } 450 } 451 sc->sc_is_open[endpt] = 1; 452 return (0); 453 } 454 455 int 456 ugenclose(dev_t dev, int flag, int mode, usb_proc_ptr p) 457 { 458 int endpt = UGENENDPOINT(dev); 459 struct ugen_softc *sc; 460 struct ugen_endpoint *sce; 461 int dir; 462 int i; 463 464 USB_GET_SC(ugen, UGENUNIT(dev), sc); 465 466 DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n", 467 flag, mode, UGENUNIT(dev), endpt)); 468 469 #ifdef DIAGNOSTIC 470 if (!sc->sc_is_open[endpt]) { 471 printf("ugenclose: not open\n"); 472 return (EINVAL); 473 } 474 #endif 475 476 if (endpt == USB_CONTROL_ENDPOINT) { 477 DPRINTFN(5, ("ugenclose: close control\n")); 478 sc->sc_is_open[endpt] = 0; 479 return (0); 480 } 481 482 for (dir = OUT; dir <= IN; dir++) { 483 if (!(flag & (dir == OUT ? FWRITE : FREAD))) 484 continue; 485 sce = &sc->sc_endpoints[endpt][dir]; 486 if (sce == NULL || sce->pipeh == NULL) 487 continue; 488 DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n", 489 endpt, dir, sce)); 490 491 usbd_abort_pipe(sce->pipeh); 492 usbd_close_pipe(sce->pipeh); 493 sce->pipeh = NULL; 494 495 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 496 case UE_INTERRUPT: 497 ndflush(&sce->q, sce->q.c_cc); 498 clfree(&sce->q); 499 break; 500 case UE_ISOCHRONOUS: 501 for (i = 0; i < UGEN_NISOREQS; ++i) 502 usbd_free_xfer(sce->isoreqs[i].xfer); 503 504 default: 505 break; 506 } 507 508 if (sce->ibuf != NULL) { 509 free(sce->ibuf, M_USBDEV); 510 sce->ibuf = NULL; 511 clfree(&sce->q); 512 } 513 } 514 sc->sc_is_open[endpt] = 0; 515 516 return (0); 517 } 518 519 Static int 520 ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) 521 { 522 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN]; 523 u_int32_t n, tn; 524 char tbuf[UGEN_BBSIZE]; 525 usbd_xfer_handle xfer; 526 usbd_status err; 527 int s; 528 int error = 0; 529 u_char buffer[UGEN_CHUNK]; 530 531 DPRINTFN(5, ("%s: ugenread: %d\n", USBDEVNAME(sc->sc_dev), endpt)); 532 533 if (sc->sc_dying) 534 return (EIO); 535 536 if (endpt == USB_CONTROL_ENDPOINT) 537 return (ENODEV); 538 539 #ifdef DIAGNOSTIC 540 if (sce->edesc == NULL) { 541 printf("ugenread: no edesc\n"); 542 return (EIO); 543 } 544 if (sce->pipeh == NULL) { 545 printf("ugenread: no pipe\n"); 546 return (EIO); 547 } 548 #endif 549 550 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 551 case UE_INTERRUPT: 552 /* Block until activity occurred. */ 553 s = splusb(); 554 while (sce->q.c_cc == 0) { 555 if (flag & IO_NDELAY) { 556 splx(s); 557 return (EWOULDBLOCK); 558 } 559 sce->state |= UGEN_ASLP; 560 DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); 561 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0); 562 DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); 563 if (sc->sc_dying) 564 error = EIO; 565 if (error) { 566 sce->state &= ~UGEN_ASLP; 567 break; 568 } 569 } 570 splx(s); 571 572 /* Transfer as many chunks as possible. */ 573 while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) { 574 n = min(sce->q.c_cc, uio->uio_resid); 575 if (n > sizeof(buffer)) 576 n = sizeof(buffer); 577 578 /* Remove a small chunk from the input queue. */ 579 q_to_b(&sce->q, buffer, n); 580 DPRINTFN(5, ("ugenread: got %d chars\n", n)); 581 582 /* Copy the data to the user process. */ 583 error = uiomove(buffer, n, uio); 584 if (error) 585 break; 586 } 587 break; 588 case UE_BULK: 589 xfer = usbd_alloc_xfer(sc->sc_udev); 590 if (xfer == 0) 591 return (ENOMEM); 592 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { 593 DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n)); 594 tn = n; 595 err = usbd_bulk_transfer( 596 xfer, sce->pipeh, 597 sce->state & UGEN_SHORT_OK ? 598 USBD_SHORT_XFER_OK : 0, 599 sce->timeout, tbuf, &tn, "ugenrb"); 600 if (err) { 601 if (err == USBD_INTERRUPTED) 602 error = EINTR; 603 else if (err == USBD_TIMEOUT) 604 error = ETIMEDOUT; 605 else 606 error = EIO; 607 break; 608 } 609 DPRINTFN(1, ("ugenread: got %d bytes\n", tn)); 610 error = uiomove(tbuf, tn, uio); 611 if (error || tn < n) 612 break; 613 } 614 usbd_free_xfer(xfer); 615 break; 616 case UE_ISOCHRONOUS: 617 s = splusb(); 618 while (sce->cur == sce->fill) { 619 if (flag & IO_NDELAY) { 620 splx(s); 621 return (EWOULDBLOCK); 622 } 623 sce->state |= UGEN_ASLP; 624 DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); 625 error = tsleep(sce, PZERO | PCATCH, "ugenri", 0); 626 DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); 627 if (sc->sc_dying) 628 error = EIO; 629 if (error) { 630 sce->state &= ~UGEN_ASLP; 631 break; 632 } 633 } 634 635 while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) { 636 if(sce->fill > sce->cur) 637 n = min(sce->fill - sce->cur, uio->uio_resid); 638 else 639 n = min(sce->limit - sce->cur, uio->uio_resid); 640 641 DPRINTFN(5, ("ugenread: isoc got %d chars\n", n)); 642 643 /* Copy the data to the user process. */ 644 error = uiomove(sce->cur, n, uio); 645 if (error) 646 break; 647 sce->cur += n; 648 if(sce->cur >= sce->limit) 649 sce->cur = sce->ibuf; 650 } 651 splx(s); 652 break; 653 654 655 default: 656 return (ENXIO); 657 } 658 return (error); 659 } 660 661 int 662 ugenread(dev_t dev, struct uio *uio, int flag) 663 { 664 int endpt = UGENENDPOINT(dev); 665 struct ugen_softc *sc; 666 int error; 667 668 USB_GET_SC(ugen, UGENUNIT(dev), sc); 669 670 sc->sc_refcnt++; 671 error = ugen_do_read(sc, endpt, uio, flag); 672 if (--sc->sc_refcnt < 0) 673 usb_detach_wakeup(USBDEV(sc->sc_dev)); 674 return (error); 675 } 676 677 Static int 678 ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) 679 { 680 struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT]; 681 u_int32_t n; 682 int error = 0; 683 char tbuf[UGEN_BBSIZE]; 684 usbd_xfer_handle xfer; 685 usbd_status err; 686 687 DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc->sc_dev), endpt)); 688 689 if (sc->sc_dying) 690 return (EIO); 691 692 if (endpt == USB_CONTROL_ENDPOINT) 693 return (ENODEV); 694 695 #ifdef DIAGNOSTIC 696 if (sce->edesc == NULL) { 697 printf("ugenwrite: no edesc\n"); 698 return (EIO); 699 } 700 if (sce->pipeh == NULL) { 701 printf("ugenwrite: no pipe\n"); 702 return (EIO); 703 } 704 #endif 705 706 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 707 case UE_BULK: 708 xfer = usbd_alloc_xfer(sc->sc_udev); 709 if (xfer == 0) 710 return (EIO); 711 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { 712 error = uiomove(tbuf, n, uio); 713 if (error) 714 break; 715 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); 716 err = usbd_bulk_transfer(xfer, sce->pipeh, 0, 717 sce->timeout, tbuf, &n,"ugenwb"); 718 if (err) { 719 if (err == USBD_INTERRUPTED) 720 error = EINTR; 721 else if (err == USBD_TIMEOUT) 722 error = ETIMEDOUT; 723 else 724 error = EIO; 725 break; 726 } 727 } 728 usbd_free_xfer(xfer); 729 break; 730 case UE_INTERRUPT: 731 xfer = usbd_alloc_xfer(sc->sc_udev); 732 if (xfer == 0) 733 return (EIO); 734 while ((n = min(UGETW(sce->edesc->wMaxPacketSize), 735 uio->uio_resid)) != 0) { 736 error = uiomove(tbuf, n, uio); 737 if (error) 738 break; 739 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); 740 err = usbd_intr_transfer(xfer, sce->pipeh, 0, 741 sce->timeout, tbuf, &n, "ugenwi"); 742 if (err) { 743 if (err == USBD_INTERRUPTED) 744 error = EINTR; 745 else if (err == USBD_TIMEOUT) 746 error = ETIMEDOUT; 747 else 748 error = EIO; 749 break; 750 } 751 } 752 usbd_free_xfer(xfer); 753 break; 754 default: 755 return (ENXIO); 756 } 757 return (error); 758 } 759 760 int 761 ugenwrite(dev_t dev, struct uio *uio, int flag) 762 { 763 int endpt = UGENENDPOINT(dev); 764 struct ugen_softc *sc; 765 int error; 766 767 USB_GET_SC(ugen, UGENUNIT(dev), sc); 768 769 sc->sc_refcnt++; 770 error = ugen_do_write(sc, endpt, uio, flag); 771 if (--sc->sc_refcnt < 0) 772 usb_detach_wakeup(USBDEV(sc->sc_dev)); 773 return (error); 774 } 775 776 #if defined(__NetBSD__) || defined(__OpenBSD__) 777 int 778 ugen_activate(device_ptr_t self, enum devact act) 779 { 780 struct ugen_softc *sc = (struct ugen_softc *)self; 781 782 switch (act) { 783 case DVACT_ACTIVATE: 784 return (EOPNOTSUPP); 785 786 case DVACT_DEACTIVATE: 787 sc->sc_dying = 1; 788 break; 789 } 790 return (0); 791 } 792 #endif 793 794 USB_DETACH(ugen) 795 { 796 USB_DETACH_START(ugen, sc); 797 struct ugen_endpoint *sce; 798 int i, dir; 799 int s; 800 #if defined(__NetBSD__) || defined(__OpenBSD__) 801 int maj, mn; 802 803 DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags)); 804 #elif defined(__FreeBSD__) 805 DPRINTF(("ugen_detach: sc=%p\n", sc)); 806 #endif 807 808 sc->sc_dying = 1; 809 /* Abort all pipes. Causes processes waiting for transfer to wake. */ 810 for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 811 for (dir = OUT; dir <= IN; dir++) { 812 sce = &sc->sc_endpoints[i][dir]; 813 if (sce && sce->pipeh) 814 usbd_abort_pipe(sce->pipeh); 815 } 816 } 817 818 s = splusb(); 819 if (--sc->sc_refcnt >= 0) { 820 /* Wake everyone */ 821 for (i = 0; i < USB_MAX_ENDPOINTS; i++) 822 wakeup(&sc->sc_endpoints[i][IN]); 823 /* Wait for processes to go away. */ 824 usb_detach_wait(USBDEV(sc->sc_dev)); 825 } 826 splx(s); 827 828 #if defined(__NetBSD__) || defined(__OpenBSD__) 829 /* locate the major number */ 830 #if defined(__NetBSD__) 831 maj = cdevsw_lookup_major(&ugen_cdevsw); 832 #elif defined(__OpenBSD__) 833 for (maj = 0; maj < nchrdev; maj++) 834 if (cdevsw[maj].d_open == ugenopen) 835 break; 836 #endif 837 838 /* Nuke the vnodes for any open instances (calls close). */ 839 mn = self->dv_unit * USB_MAX_ENDPOINTS; 840 vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR); 841 #elif defined(__FreeBSD__) 842 /* XXX not implemented yet */ 843 #endif 844 845 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 846 USBDEV(sc->sc_dev)); 847 848 return (0); 849 } 850 851 Static void 852 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) 853 { 854 struct ugen_endpoint *sce = addr; 855 /*struct ugen_softc *sc = sce->sc;*/ 856 u_int32_t count; 857 u_char *ibuf; 858 859 if (status == USBD_CANCELLED) 860 return; 861 862 if (status != USBD_NORMAL_COMPLETION) { 863 DPRINTF(("ugenintr: status=%d\n", status)); 864 if (status == USBD_STALLED) 865 usbd_clear_endpoint_stall_async(sce->pipeh); 866 return; 867 } 868 869 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 870 ibuf = sce->ibuf; 871 872 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n", 873 xfer, status, count)); 874 DPRINTFN(5, (" data = %02x %02x %02x\n", 875 ibuf[0], ibuf[1], ibuf[2])); 876 877 (void)b_to_q(ibuf, count, &sce->q); 878 879 if (sce->state & UGEN_ASLP) { 880 sce->state &= ~UGEN_ASLP; 881 DPRINTFN(5, ("ugen_intr: waking %p\n", sce)); 882 wakeup(sce); 883 } 884 selnotify(&sce->rsel, 0); 885 } 886 887 Static void 888 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, 889 usbd_status status) 890 { 891 struct isoreq *req = addr; 892 struct ugen_endpoint *sce = req->sce; 893 u_int32_t count, n; 894 int i, isize; 895 896 /* Return if we are aborting. */ 897 if (status == USBD_CANCELLED) 898 return; 899 900 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 901 DPRINTFN(5,("ugen_isoc_rintr: xfer %ld, count=%d\n", 902 (long)(req - sce->isoreqs), count)); 903 904 /* throw away oldest input if the buffer is full */ 905 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) { 906 sce->cur += count; 907 if(sce->cur >= sce->limit) 908 sce->cur = sce->ibuf + (sce->limit - sce->cur); 909 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n", 910 count)); 911 } 912 913 isize = UGETW(sce->edesc->wMaxPacketSize); 914 for (i = 0; i < UGEN_NISORFRMS; i++) { 915 u_int32_t actlen = req->sizes[i]; 916 char const *tbuf = (char const *)req->dmabuf + isize * i; 917 918 /* copy data to buffer */ 919 while (actlen > 0) { 920 n = min(actlen, sce->limit - sce->fill); 921 memcpy(sce->fill, tbuf, n); 922 923 tbuf += n; 924 actlen -= n; 925 sce->fill += n; 926 if(sce->fill == sce->limit) 927 sce->fill = sce->ibuf; 928 } 929 930 /* setup size for next transfer */ 931 req->sizes[i] = isize; 932 } 933 934 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS, 935 USBD_NO_COPY, ugen_isoc_rintr); 936 (void)usbd_transfer(xfer); 937 938 if (sce->state & UGEN_ASLP) { 939 sce->state &= ~UGEN_ASLP; 940 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce)); 941 wakeup(sce); 942 } 943 selnotify(&sce->rsel, 0); 944 } 945 946 Static usbd_status 947 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) 948 { 949 usbd_interface_handle iface; 950 usb_endpoint_descriptor_t *ed; 951 usbd_status err; 952 struct ugen_endpoint *sce; 953 u_int8_t niface, nendpt, endptno, endpt; 954 int dir; 955 956 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); 957 958 err = usbd_interface_count(sc->sc_udev, &niface); 959 if (err) 960 return (err); 961 if (ifaceidx < 0 || ifaceidx >= niface) 962 return (USBD_INVAL); 963 964 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); 965 if (err) 966 return (err); 967 err = usbd_endpoint_count(iface, &nendpt); 968 if (err) 969 return (err); 970 /* XXX should only do this after setting new altno has succeeded */ 971 for (endptno = 0; endptno < nendpt; endptno++) { 972 ed = usbd_interface2endpoint_descriptor(iface,endptno); 973 endpt = ed->bEndpointAddress; 974 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 975 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 976 sce->sc = 0; 977 sce->edesc = 0; 978 sce->iface = 0; 979 } 980 981 /* change setting */ 982 err = usbd_set_interface(iface, altno); 983 if (err) 984 return (err); 985 986 err = usbd_endpoint_count(iface, &nendpt); 987 if (err) 988 return (err); 989 for (endptno = 0; endptno < nendpt; endptno++) { 990 ed = usbd_interface2endpoint_descriptor(iface,endptno); 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, usb_proc_ptr p) 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_segflg = UIO_USERSPACE; 1231 uio.uio_rw = UIO_READ; 1232 uio.uio_procp = p; 1233 error = uiomove((void *)cdesc, len, &uio); 1234 free(cdesc, M_TEMP); 1235 return (error); 1236 } 1237 case USB_GET_STRING_DESC: { 1238 int len; 1239 si = (struct usb_string_desc *)addr; 1240 err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index, 1241 si->usd_language_id, &si->usd_desc, &len); 1242 if (err) 1243 return (EINVAL); 1244 break; 1245 } 1246 case USB_DO_REQUEST: 1247 { 1248 struct usb_ctl_request *ur = (void *)addr; 1249 int len = UGETW(ur->ucr_request.wLength); 1250 struct iovec iov; 1251 struct uio uio; 1252 void *ptr = 0; 1253 usbd_status xerr; 1254 int error = 0; 1255 1256 if (!(flag & FWRITE)) 1257 return (EPERM); 1258 /* Avoid requests that would damage the bus integrity. */ 1259 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 1260 ur->ucr_request.bRequest == UR_SET_ADDRESS) || 1261 (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 1262 ur->ucr_request.bRequest == UR_SET_CONFIG) || 1263 (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE && 1264 ur->ucr_request.bRequest == UR_SET_INTERFACE)) 1265 return (EINVAL); 1266 1267 if (len < 0 || len > 32767) 1268 return (EINVAL); 1269 if (len != 0) { 1270 iov.iov_base = (caddr_t)ur->ucr_data; 1271 iov.iov_len = len; 1272 uio.uio_iov = &iov; 1273 uio.uio_iovcnt = 1; 1274 uio.uio_resid = len; 1275 uio.uio_offset = 0; 1276 uio.uio_segflg = UIO_USERSPACE; 1277 uio.uio_rw = 1278 ur->ucr_request.bmRequestType & UT_READ ? 1279 UIO_READ : UIO_WRITE; 1280 uio.uio_procp = p; 1281 ptr = malloc(len, M_TEMP, M_WAITOK); 1282 if (uio.uio_rw == UIO_WRITE) { 1283 error = uiomove(ptr, len, &uio); 1284 if (error) 1285 goto ret; 1286 } 1287 } 1288 sce = &sc->sc_endpoints[endpt][IN]; 1289 xerr = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request, 1290 ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout); 1291 if (xerr) { 1292 error = EIO; 1293 goto ret; 1294 } 1295 if (len != 0) { 1296 if (uio.uio_rw == UIO_READ) { 1297 error = uiomove(ptr, len, &uio); 1298 if (error) 1299 goto ret; 1300 } 1301 } 1302 ret: 1303 if (ptr) 1304 free(ptr, M_TEMP); 1305 return (error); 1306 } 1307 case USB_GET_DEVICEINFO: 1308 usbd_fill_deviceinfo(sc->sc_udev, 1309 (struct usb_device_info *)addr, 1); 1310 break; 1311 default: 1312 return (EINVAL); 1313 } 1314 return (0); 1315 } 1316 1317 int 1318 ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p) 1319 { 1320 int endpt = UGENENDPOINT(dev); 1321 struct ugen_softc *sc; 1322 int error; 1323 1324 USB_GET_SC(ugen, UGENUNIT(dev), sc); 1325 1326 sc->sc_refcnt++; 1327 error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p); 1328 if (--sc->sc_refcnt < 0) 1329 usb_detach_wakeup(USBDEV(sc->sc_dev)); 1330 return (error); 1331 } 1332 1333 int 1334 ugenpoll(dev_t dev, int events, usb_proc_ptr p) 1335 { 1336 struct ugen_softc *sc; 1337 struct ugen_endpoint *sce; 1338 int revents = 0; 1339 int s; 1340 1341 USB_GET_SC(ugen, UGENUNIT(dev), sc); 1342 1343 if (sc->sc_dying) 1344 return (POLLHUP); 1345 1346 /* XXX always IN */ 1347 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; 1348 if (sce == NULL) 1349 return (POLLERR); 1350 #ifdef DIAGNOSTIC 1351 if (!sce->edesc) { 1352 printf("ugenpoll: no edesc\n"); 1353 return (POLLERR); 1354 } 1355 if (!sce->pipeh) { 1356 printf("ugenpoll: no pipe\n"); 1357 return (POLLERR); 1358 } 1359 #endif 1360 s = splusb(); 1361 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1362 case UE_INTERRUPT: 1363 if (events & (POLLIN | POLLRDNORM)) { 1364 if (sce->q.c_cc > 0) 1365 revents |= events & (POLLIN | POLLRDNORM); 1366 else 1367 selrecord(p, &sce->rsel); 1368 } 1369 break; 1370 case UE_ISOCHRONOUS: 1371 if (events & (POLLIN | POLLRDNORM)) { 1372 if (sce->cur != sce->fill) 1373 revents |= events & (POLLIN | POLLRDNORM); 1374 else 1375 selrecord(p, &sce->rsel); 1376 } 1377 break; 1378 case UE_BULK: 1379 /* 1380 * We have no easy way of determining if a read will 1381 * yield any data or a write will happen. 1382 * Pretend they will. 1383 */ 1384 revents |= events & 1385 (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM); 1386 break; 1387 default: 1388 break; 1389 } 1390 splx(s); 1391 return (revents); 1392 } 1393 1394 static void 1395 filt_ugenrdetach(struct knote *kn) 1396 { 1397 struct ugen_endpoint *sce = kn->kn_hook; 1398 int s; 1399 1400 s = splusb(); 1401 SLIST_REMOVE(&sce->rsel.sel_klist, kn, knote, kn_selnext); 1402 splx(s); 1403 } 1404 1405 static int 1406 filt_ugenread_intr(struct knote *kn, long hint) 1407 { 1408 struct ugen_endpoint *sce = kn->kn_hook; 1409 1410 kn->kn_data = sce->q.c_cc; 1411 return (kn->kn_data > 0); 1412 } 1413 1414 static int 1415 filt_ugenread_isoc(struct knote *kn, long hint) 1416 { 1417 struct ugen_endpoint *sce = kn->kn_hook; 1418 1419 if (sce->cur == sce->fill) 1420 return (0); 1421 1422 if (sce->cur < sce->fill) 1423 kn->kn_data = sce->fill - sce->cur; 1424 else 1425 kn->kn_data = (sce->limit - sce->cur) + 1426 (sce->fill - sce->ibuf); 1427 1428 return (1); 1429 } 1430 1431 static const struct filterops ugenread_intr_filtops = 1432 { 1, NULL, filt_ugenrdetach, filt_ugenread_intr }; 1433 1434 static const struct filterops ugenread_isoc_filtops = 1435 { 1, NULL, filt_ugenrdetach, filt_ugenread_isoc }; 1436 1437 static const struct filterops ugen_seltrue_filtops = 1438 { 1, NULL, filt_ugenrdetach, filt_seltrue }; 1439 1440 int 1441 ugenkqfilter(dev_t dev, struct knote *kn) 1442 { 1443 struct ugen_softc *sc; 1444 struct ugen_endpoint *sce; 1445 struct klist *klist; 1446 int s; 1447 1448 USB_GET_SC(ugen, UGENUNIT(dev), sc); 1449 1450 if (sc->sc_dying) 1451 return (1); 1452 1453 /* XXX always IN */ 1454 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; 1455 if (sce == NULL) 1456 return (1); 1457 1458 switch (kn->kn_filter) { 1459 case EVFILT_READ: 1460 klist = &sce->rsel.sel_klist; 1461 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1462 case UE_INTERRUPT: 1463 kn->kn_fop = &ugenread_intr_filtops; 1464 break; 1465 case UE_ISOCHRONOUS: 1466 kn->kn_fop = &ugenread_isoc_filtops; 1467 break; 1468 case UE_BULK: 1469 /* 1470 * We have no easy way of determining if a read will 1471 * yield any data or a write will happen. 1472 * So, emulate "seltrue". 1473 */ 1474 kn->kn_fop = &ugen_seltrue_filtops; 1475 break; 1476 default: 1477 return (1); 1478 } 1479 break; 1480 1481 case EVFILT_WRITE: 1482 klist = &sce->rsel.sel_klist; 1483 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1484 case UE_INTERRUPT: 1485 case UE_ISOCHRONOUS: 1486 /* XXX poll doesn't support this */ 1487 return (1); 1488 1489 case UE_BULK: 1490 /* 1491 * We have no easy way of determining if a read will 1492 * yield any data or a write will happen. 1493 * So, emulate "seltrue". 1494 */ 1495 kn->kn_fop = &ugen_seltrue_filtops; 1496 break; 1497 default: 1498 return (1); 1499 } 1500 break; 1501 1502 default: 1503 return (1); 1504 } 1505 1506 kn->kn_hook = sce; 1507 1508 s = splusb(); 1509 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 1510 splx(s); 1511 1512 return (0); 1513 } 1514 1515 #if defined(__FreeBSD__) 1516 DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, usbd_driver_load, 0); 1517 #endif 1518