1 /* $NetBSD: ugen.c,v 1.83 2006/06/09 21:34:19 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.83 2006/06/09 21:34:19 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 char sc_buffer[UGEN_BBSIZE]; 122 u_char sc_dying; 123 }; 124 125 #if defined(__NetBSD__) 126 dev_type_open(ugenopen); 127 dev_type_close(ugenclose); 128 dev_type_read(ugenread); 129 dev_type_write(ugenwrite); 130 dev_type_ioctl(ugenioctl); 131 dev_type_poll(ugenpoll); 132 dev_type_kqfilter(ugenkqfilter); 133 134 const struct cdevsw ugen_cdevsw = { 135 ugenopen, ugenclose, ugenread, ugenwrite, ugenioctl, 136 nostop, notty, ugenpoll, nommap, ugenkqfilter, 137 }; 138 #elif defined(__OpenBSD__) 139 cdev_decl(ugen); 140 #elif defined(__FreeBSD__) 141 d_open_t ugenopen; 142 d_close_t ugenclose; 143 d_read_t ugenread; 144 d_write_t ugenwrite; 145 d_ioctl_t ugenioctl; 146 d_poll_t ugenpoll; 147 148 #define UGEN_CDEV_MAJOR 114 149 150 Static struct cdevsw ugen_cdevsw = { 151 /* open */ ugenopen, 152 /* close */ ugenclose, 153 /* read */ ugenread, 154 /* write */ ugenwrite, 155 /* ioctl */ ugenioctl, 156 /* poll */ ugenpoll, 157 /* mmap */ nommap, 158 /* strategy */ nostrategy, 159 /* name */ "ugen", 160 /* maj */ UGEN_CDEV_MAJOR, 161 /* dump */ nodump, 162 /* psize */ nopsize, 163 /* flags */ 0, 164 /* bmaj */ -1 165 }; 166 #endif 167 168 Static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, 169 usbd_status status); 170 Static void ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, 171 usbd_status status); 172 Static int ugen_do_read(struct ugen_softc *, int, struct uio *, int); 173 Static int ugen_do_write(struct ugen_softc *, int, struct uio *, int); 174 Static int ugen_do_ioctl(struct ugen_softc *, int, u_long, 175 caddr_t, int, struct lwp *); 176 Static int ugen_set_config(struct ugen_softc *sc, int configno); 177 Static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc, 178 int index, int *lenp); 179 Static usbd_status ugen_set_interface(struct ugen_softc *, int, int); 180 Static int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx); 181 182 #define UGENUNIT(n) ((minor(n) >> 4) & 0xf) 183 #define UGENENDPOINT(n) (minor(n) & 0xf) 184 #define UGENDEV(u, e) (makedev(0, ((u) << 4) | (e))) 185 186 USB_DECLARE_DRIVER(ugen); 187 188 USB_MATCH(ugen) 189 { 190 USB_MATCH_START(ugen, uaa); 191 192 if (match->cf_flags & 1) 193 return (UMATCH_HIGHEST); 194 else if (uaa->usegeneric) 195 return (UMATCH_GENERIC); 196 else 197 return (UMATCH_NONE); 198 } 199 200 USB_ATTACH(ugen) 201 { 202 USB_ATTACH_START(ugen, sc, uaa); 203 usbd_device_handle udev; 204 char *devinfop; 205 usbd_status err; 206 int conf; 207 208 devinfop = usbd_devinfo_alloc(uaa->device, 0); 209 USB_ATTACH_SETUP; 210 printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfop); 211 usbd_devinfo_free(devinfop); 212 213 sc->sc_udev = udev = uaa->device; 214 215 /* First set configuration index 0, the default one for ugen. */ 216 err = usbd_set_config_index(udev, 0, 0); 217 if (err) { 218 printf("%s: setting configuration index 0 failed\n", 219 USBDEVNAME(sc->sc_dev)); 220 sc->sc_dying = 1; 221 USB_ATTACH_ERROR_RETURN; 222 } 223 conf = usbd_get_config_descriptor(udev)->bConfigurationValue; 224 225 /* Set up all the local state for this configuration. */ 226 err = ugen_set_config(sc, conf); 227 if (err) { 228 printf("%s: setting configuration %d failed\n", 229 USBDEVNAME(sc->sc_dev), conf); 230 sc->sc_dying = 1; 231 USB_ATTACH_ERROR_RETURN; 232 } 233 234 #ifdef __FreeBSD__ 235 { 236 static int global_init_done = 0; 237 if (!global_init_done) { 238 cdevsw_add(&ugen_cdevsw); 239 global_init_done = 1; 240 } 241 } 242 #endif 243 244 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 245 USBDEV(sc->sc_dev)); 246 247 USB_ATTACH_SUCCESS_RETURN; 248 } 249 250 Static int 251 ugen_set_config(struct ugen_softc *sc, int configno) 252 { 253 usbd_device_handle dev = sc->sc_udev; 254 usbd_interface_handle iface; 255 usb_endpoint_descriptor_t *ed; 256 struct ugen_endpoint *sce; 257 u_int8_t niface, nendpt; 258 int ifaceno, endptno, endpt; 259 usbd_status err; 260 int dir; 261 262 DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n", 263 USBDEVNAME(sc->sc_dev), configno, sc)); 264 265 /* 266 * We start at 1, not 0, because we don't care whether the 267 * control endpoint is open or not. It is always present. 268 */ 269 for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) 270 if (sc->sc_is_open[endptno]) { 271 DPRINTFN(1, 272 ("ugen_set_config: %s - endpoint %d is open\n", 273 USBDEVNAME(sc->sc_dev), endptno)); 274 return (USBD_IN_USE); 275 } 276 277 /* Avoid setting the current value. */ 278 if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) { 279 err = usbd_set_config_no(dev, configno, 1); 280 if (err) 281 return (err); 282 } 283 284 err = usbd_interface_count(dev, &niface); 285 if (err) 286 return (err); 287 memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints); 288 for (ifaceno = 0; ifaceno < niface; ifaceno++) { 289 DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno)); 290 err = usbd_device2interface_handle(dev, ifaceno, &iface); 291 if (err) 292 return (err); 293 err = usbd_endpoint_count(iface, &nendpt); 294 if (err) 295 return (err); 296 for (endptno = 0; endptno < nendpt; endptno++) { 297 ed = usbd_interface2endpoint_descriptor(iface,endptno); 298 KASSERT(ed != NULL); 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, struct lwp *l) 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, struct lwp *l) 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 usbd_xfer_handle xfer; 525 usbd_status err; 526 int s; 527 int error = 0; 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(sc->sc_buffer)) 574 n = sizeof(sc->sc_buffer); 575 576 /* Remove a small chunk from the input queue. */ 577 q_to_b(&sce->q, sc->sc_buffer, n); 578 DPRINTFN(5, ("ugenread: got %d chars\n", n)); 579 580 /* Copy the data to the user process. */ 581 error = uiomove(sc->sc_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, sc->sc_buffer, &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(sc->sc_buffer, 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 usbd_xfer_handle xfer; 682 usbd_status err; 683 684 DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc->sc_dev), endpt)); 685 686 if (sc->sc_dying) 687 return (EIO); 688 689 if (endpt == USB_CONTROL_ENDPOINT) 690 return (ENODEV); 691 692 #ifdef DIAGNOSTIC 693 if (sce->edesc == NULL) { 694 printf("ugenwrite: no edesc\n"); 695 return (EIO); 696 } 697 if (sce->pipeh == NULL) { 698 printf("ugenwrite: no pipe\n"); 699 return (EIO); 700 } 701 #endif 702 703 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 704 case UE_BULK: 705 xfer = usbd_alloc_xfer(sc->sc_udev); 706 if (xfer == 0) 707 return (EIO); 708 while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { 709 error = uiomove(sc->sc_buffer, n, uio); 710 if (error) 711 break; 712 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); 713 err = usbd_bulk_transfer(xfer, sce->pipeh, 0, 714 sce->timeout, sc->sc_buffer, &n,"ugenwb"); 715 if (err) { 716 if (err == USBD_INTERRUPTED) 717 error = EINTR; 718 else if (err == USBD_TIMEOUT) 719 error = ETIMEDOUT; 720 else 721 error = EIO; 722 break; 723 } 724 } 725 usbd_free_xfer(xfer); 726 break; 727 case UE_INTERRUPT: 728 xfer = usbd_alloc_xfer(sc->sc_udev); 729 if (xfer == 0) 730 return (EIO); 731 while ((n = min(UGETW(sce->edesc->wMaxPacketSize), 732 uio->uio_resid)) != 0) { 733 error = uiomove(sc->sc_buffer, n, uio); 734 if (error) 735 break; 736 DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); 737 err = usbd_intr_transfer(xfer, sce->pipeh, 0, 738 sce->timeout, sc->sc_buffer, &n, "ugenwi"); 739 if (err) { 740 if (err == USBD_INTERRUPTED) 741 error = EINTR; 742 else if (err == USBD_TIMEOUT) 743 error = ETIMEDOUT; 744 else 745 error = EIO; 746 break; 747 } 748 } 749 usbd_free_xfer(xfer); 750 break; 751 default: 752 return (ENXIO); 753 } 754 return (error); 755 } 756 757 int 758 ugenwrite(dev_t dev, struct uio *uio, int flag) 759 { 760 int endpt = UGENENDPOINT(dev); 761 struct ugen_softc *sc; 762 int error; 763 764 USB_GET_SC(ugen, UGENUNIT(dev), sc); 765 766 sc->sc_refcnt++; 767 error = ugen_do_write(sc, endpt, uio, flag); 768 if (--sc->sc_refcnt < 0) 769 usb_detach_wakeup(USBDEV(sc->sc_dev)); 770 return (error); 771 } 772 773 #if defined(__NetBSD__) || defined(__OpenBSD__) 774 int 775 ugen_activate(device_ptr_t self, enum devact act) 776 { 777 struct ugen_softc *sc = (struct ugen_softc *)self; 778 779 switch (act) { 780 case DVACT_ACTIVATE: 781 return (EOPNOTSUPP); 782 783 case DVACT_DEACTIVATE: 784 sc->sc_dying = 1; 785 break; 786 } 787 return (0); 788 } 789 #endif 790 791 USB_DETACH(ugen) 792 { 793 USB_DETACH_START(ugen, sc); 794 struct ugen_endpoint *sce; 795 int i, dir; 796 int s; 797 #if defined(__NetBSD__) || defined(__OpenBSD__) 798 int maj, mn; 799 800 DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags)); 801 #elif defined(__FreeBSD__) 802 DPRINTF(("ugen_detach: sc=%p\n", sc)); 803 #endif 804 805 sc->sc_dying = 1; 806 /* Abort all pipes. Causes processes waiting for transfer to wake. */ 807 for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 808 for (dir = OUT; dir <= IN; dir++) { 809 sce = &sc->sc_endpoints[i][dir]; 810 if (sce && sce->pipeh) 811 usbd_abort_pipe(sce->pipeh); 812 } 813 } 814 815 s = splusb(); 816 if (--sc->sc_refcnt >= 0) { 817 /* Wake everyone */ 818 for (i = 0; i < USB_MAX_ENDPOINTS; i++) 819 wakeup(&sc->sc_endpoints[i][IN]); 820 /* Wait for processes to go away. */ 821 usb_detach_wait(USBDEV(sc->sc_dev)); 822 } 823 splx(s); 824 825 #if defined(__NetBSD__) || defined(__OpenBSD__) 826 /* locate the major number */ 827 #if defined(__NetBSD__) 828 maj = cdevsw_lookup_major(&ugen_cdevsw); 829 #elif defined(__OpenBSD__) 830 for (maj = 0; maj < nchrdev; maj++) 831 if (cdevsw[maj].d_open == ugenopen) 832 break; 833 #endif 834 835 /* Nuke the vnodes for any open instances (calls close). */ 836 mn = device_unit(self) * USB_MAX_ENDPOINTS; 837 vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR); 838 #elif defined(__FreeBSD__) 839 /* XXX not implemented yet */ 840 #endif 841 842 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 843 USBDEV(sc->sc_dev)); 844 845 return (0); 846 } 847 848 Static void 849 ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) 850 { 851 struct ugen_endpoint *sce = addr; 852 /*struct ugen_softc *sc = sce->sc;*/ 853 u_int32_t count; 854 u_char *ibuf; 855 856 if (status == USBD_CANCELLED) 857 return; 858 859 if (status != USBD_NORMAL_COMPLETION) { 860 DPRINTF(("ugenintr: status=%d\n", status)); 861 if (status == USBD_STALLED) 862 usbd_clear_endpoint_stall_async(sce->pipeh); 863 return; 864 } 865 866 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 867 ibuf = sce->ibuf; 868 869 DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n", 870 xfer, status, count)); 871 DPRINTFN(5, (" data = %02x %02x %02x\n", 872 ibuf[0], ibuf[1], ibuf[2])); 873 874 (void)b_to_q(ibuf, count, &sce->q); 875 876 if (sce->state & UGEN_ASLP) { 877 sce->state &= ~UGEN_ASLP; 878 DPRINTFN(5, ("ugen_intr: waking %p\n", sce)); 879 wakeup(sce); 880 } 881 selnotify(&sce->rsel, 0); 882 } 883 884 Static void 885 ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, 886 usbd_status status) 887 { 888 struct isoreq *req = addr; 889 struct ugen_endpoint *sce = req->sce; 890 u_int32_t count, n; 891 int i, isize; 892 893 /* Return if we are aborting. */ 894 if (status == USBD_CANCELLED) 895 return; 896 897 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 898 DPRINTFN(5,("ugen_isoc_rintr: xfer %ld, count=%d\n", 899 (long)(req - sce->isoreqs), count)); 900 901 /* throw away oldest input if the buffer is full */ 902 if(sce->fill < sce->cur && sce->cur <= sce->fill + count) { 903 sce->cur += count; 904 if(sce->cur >= sce->limit) 905 sce->cur = sce->ibuf + (sce->limit - sce->cur); 906 DPRINTFN(5, ("ugen_isoc_rintr: throwing away %d bytes\n", 907 count)); 908 } 909 910 isize = UGETW(sce->edesc->wMaxPacketSize); 911 for (i = 0; i < UGEN_NISORFRMS; i++) { 912 u_int32_t actlen = req->sizes[i]; 913 char const *tbuf = (char const *)req->dmabuf + isize * i; 914 915 /* copy data to buffer */ 916 while (actlen > 0) { 917 n = min(actlen, sce->limit - sce->fill); 918 memcpy(sce->fill, tbuf, n); 919 920 tbuf += n; 921 actlen -= n; 922 sce->fill += n; 923 if(sce->fill == sce->limit) 924 sce->fill = sce->ibuf; 925 } 926 927 /* setup size for next transfer */ 928 req->sizes[i] = isize; 929 } 930 931 usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS, 932 USBD_NO_COPY, ugen_isoc_rintr); 933 (void)usbd_transfer(xfer); 934 935 if (sce->state & UGEN_ASLP) { 936 sce->state &= ~UGEN_ASLP; 937 DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce)); 938 wakeup(sce); 939 } 940 selnotify(&sce->rsel, 0); 941 } 942 943 Static usbd_status 944 ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) 945 { 946 usbd_interface_handle iface; 947 usb_endpoint_descriptor_t *ed; 948 usbd_status err; 949 struct ugen_endpoint *sce; 950 u_int8_t niface, nendpt, endptno, endpt; 951 int dir; 952 953 DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); 954 955 err = usbd_interface_count(sc->sc_udev, &niface); 956 if (err) 957 return (err); 958 if (ifaceidx < 0 || ifaceidx >= niface) 959 return (USBD_INVAL); 960 961 err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); 962 if (err) 963 return (err); 964 err = usbd_endpoint_count(iface, &nendpt); 965 if (err) 966 return (err); 967 /* XXX should only do this after setting new altno has succeeded */ 968 for (endptno = 0; endptno < nendpt; endptno++) { 969 ed = usbd_interface2endpoint_descriptor(iface,endptno); 970 endpt = ed->bEndpointAddress; 971 dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 972 sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 973 sce->sc = 0; 974 sce->edesc = 0; 975 sce->iface = 0; 976 } 977 978 /* change setting */ 979 err = usbd_set_interface(iface, altno); 980 if (err) 981 return (err); 982 983 err = usbd_endpoint_count(iface, &nendpt); 984 if (err) 985 return (err); 986 for (endptno = 0; endptno < nendpt; endptno++) { 987 ed = usbd_interface2endpoint_descriptor(iface,endptno); 988 KASSERT(ed != NULL); 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_rw = UIO_READ; 1229 uio.uio_vmspace = l->l_proc->p_vmspace; 1230 error = uiomove((void *)cdesc, len, &uio); 1231 free(cdesc, M_TEMP); 1232 return (error); 1233 } 1234 case USB_GET_STRING_DESC: { 1235 int len; 1236 si = (struct usb_string_desc *)addr; 1237 err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index, 1238 si->usd_language_id, &si->usd_desc, &len); 1239 if (err) 1240 return (EINVAL); 1241 break; 1242 } 1243 case USB_DO_REQUEST: 1244 { 1245 struct usb_ctl_request *ur = (void *)addr; 1246 int len = UGETW(ur->ucr_request.wLength); 1247 struct iovec iov; 1248 struct uio uio; 1249 void *ptr = 0; 1250 usbd_status xerr; 1251 int error = 0; 1252 1253 if (!(flag & FWRITE)) 1254 return (EPERM); 1255 /* Avoid requests that would damage the bus integrity. */ 1256 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 1257 ur->ucr_request.bRequest == UR_SET_ADDRESS) || 1258 (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 1259 ur->ucr_request.bRequest == UR_SET_CONFIG) || 1260 (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE && 1261 ur->ucr_request.bRequest == UR_SET_INTERFACE)) 1262 return (EINVAL); 1263 1264 if (len < 0 || len > 32767) 1265 return (EINVAL); 1266 if (len != 0) { 1267 iov.iov_base = (caddr_t)ur->ucr_data; 1268 iov.iov_len = len; 1269 uio.uio_iov = &iov; 1270 uio.uio_iovcnt = 1; 1271 uio.uio_resid = len; 1272 uio.uio_offset = 0; 1273 uio.uio_rw = 1274 ur->ucr_request.bmRequestType & UT_READ ? 1275 UIO_READ : UIO_WRITE; 1276 uio.uio_vmspace = l->l_proc->p_vmspace; 1277 ptr = malloc(len, M_TEMP, M_WAITOK); 1278 if (uio.uio_rw == UIO_WRITE) { 1279 error = uiomove(ptr, len, &uio); 1280 if (error) 1281 goto ret; 1282 } 1283 } 1284 sce = &sc->sc_endpoints[endpt][IN]; 1285 xerr = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request, 1286 ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout); 1287 if (xerr) { 1288 error = EIO; 1289 goto ret; 1290 } 1291 if (len != 0) { 1292 if (uio.uio_rw == UIO_READ) { 1293 error = uiomove(ptr, len, &uio); 1294 if (error) 1295 goto ret; 1296 } 1297 } 1298 ret: 1299 if (ptr) 1300 free(ptr, M_TEMP); 1301 return (error); 1302 } 1303 case USB_GET_DEVICEINFO: 1304 usbd_fill_deviceinfo(sc->sc_udev, 1305 (struct usb_device_info *)addr, 1); 1306 break; 1307 default: 1308 return (EINVAL); 1309 } 1310 return (0); 1311 } 1312 1313 int 1314 ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct lwp *l) 1315 { 1316 int endpt = UGENENDPOINT(dev); 1317 struct ugen_softc *sc; 1318 int error; 1319 1320 USB_GET_SC(ugen, UGENUNIT(dev), sc); 1321 1322 sc->sc_refcnt++; 1323 error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, l); 1324 if (--sc->sc_refcnt < 0) 1325 usb_detach_wakeup(USBDEV(sc->sc_dev)); 1326 return (error); 1327 } 1328 1329 int 1330 ugenpoll(dev_t dev, int events, struct lwp *l) 1331 { 1332 struct ugen_softc *sc; 1333 struct ugen_endpoint *sce; 1334 int revents = 0; 1335 int s; 1336 1337 USB_GET_SC(ugen, UGENUNIT(dev), sc); 1338 1339 if (sc->sc_dying) 1340 return (POLLHUP); 1341 1342 /* XXX always IN */ 1343 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; 1344 if (sce == NULL) 1345 return (POLLERR); 1346 #ifdef DIAGNOSTIC 1347 if (!sce->edesc) { 1348 printf("ugenpoll: no edesc\n"); 1349 return (POLLERR); 1350 } 1351 if (!sce->pipeh) { 1352 printf("ugenpoll: no pipe\n"); 1353 return (POLLERR); 1354 } 1355 #endif 1356 s = splusb(); 1357 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1358 case UE_INTERRUPT: 1359 if (events & (POLLIN | POLLRDNORM)) { 1360 if (sce->q.c_cc > 0) 1361 revents |= events & (POLLIN | POLLRDNORM); 1362 else 1363 selrecord(l, &sce->rsel); 1364 } 1365 break; 1366 case UE_ISOCHRONOUS: 1367 if (events & (POLLIN | POLLRDNORM)) { 1368 if (sce->cur != sce->fill) 1369 revents |= events & (POLLIN | POLLRDNORM); 1370 else 1371 selrecord(l, &sce->rsel); 1372 } 1373 break; 1374 case UE_BULK: 1375 /* 1376 * We have no easy way of determining if a read will 1377 * yield any data or a write will happen. 1378 * Pretend they will. 1379 */ 1380 revents |= events & 1381 (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM); 1382 break; 1383 default: 1384 break; 1385 } 1386 splx(s); 1387 return (revents); 1388 } 1389 1390 static void 1391 filt_ugenrdetach(struct knote *kn) 1392 { 1393 struct ugen_endpoint *sce = kn->kn_hook; 1394 int s; 1395 1396 s = splusb(); 1397 SLIST_REMOVE(&sce->rsel.sel_klist, kn, knote, kn_selnext); 1398 splx(s); 1399 } 1400 1401 static int 1402 filt_ugenread_intr(struct knote *kn, long hint) 1403 { 1404 struct ugen_endpoint *sce = kn->kn_hook; 1405 1406 kn->kn_data = sce->q.c_cc; 1407 return (kn->kn_data > 0); 1408 } 1409 1410 static int 1411 filt_ugenread_isoc(struct knote *kn, long hint) 1412 { 1413 struct ugen_endpoint *sce = kn->kn_hook; 1414 1415 if (sce->cur == sce->fill) 1416 return (0); 1417 1418 if (sce->cur < sce->fill) 1419 kn->kn_data = sce->fill - sce->cur; 1420 else 1421 kn->kn_data = (sce->limit - sce->cur) + 1422 (sce->fill - sce->ibuf); 1423 1424 return (1); 1425 } 1426 1427 static const struct filterops ugenread_intr_filtops = 1428 { 1, NULL, filt_ugenrdetach, filt_ugenread_intr }; 1429 1430 static const struct filterops ugenread_isoc_filtops = 1431 { 1, NULL, filt_ugenrdetach, filt_ugenread_isoc }; 1432 1433 static const struct filterops ugen_seltrue_filtops = 1434 { 1, NULL, filt_ugenrdetach, filt_seltrue }; 1435 1436 int 1437 ugenkqfilter(dev_t dev, struct knote *kn) 1438 { 1439 struct ugen_softc *sc; 1440 struct ugen_endpoint *sce; 1441 struct klist *klist; 1442 int s; 1443 1444 USB_GET_SC(ugen, UGENUNIT(dev), sc); 1445 1446 if (sc->sc_dying) 1447 return (1); 1448 1449 /* XXX always IN */ 1450 sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; 1451 if (sce == NULL) 1452 return (1); 1453 1454 switch (kn->kn_filter) { 1455 case EVFILT_READ: 1456 klist = &sce->rsel.sel_klist; 1457 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1458 case UE_INTERRUPT: 1459 kn->kn_fop = &ugenread_intr_filtops; 1460 break; 1461 case UE_ISOCHRONOUS: 1462 kn->kn_fop = &ugenread_isoc_filtops; 1463 break; 1464 case UE_BULK: 1465 /* 1466 * We have no easy way of determining if a read will 1467 * yield any data or a write will happen. 1468 * So, emulate "seltrue". 1469 */ 1470 kn->kn_fop = &ugen_seltrue_filtops; 1471 break; 1472 default: 1473 return (1); 1474 } 1475 break; 1476 1477 case EVFILT_WRITE: 1478 klist = &sce->rsel.sel_klist; 1479 switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1480 case UE_INTERRUPT: 1481 case UE_ISOCHRONOUS: 1482 /* XXX poll doesn't support this */ 1483 return (1); 1484 1485 case UE_BULK: 1486 /* 1487 * We have no easy way of determining if a read will 1488 * yield any data or a write will happen. 1489 * So, emulate "seltrue". 1490 */ 1491 kn->kn_fop = &ugen_seltrue_filtops; 1492 break; 1493 default: 1494 return (1); 1495 } 1496 break; 1497 1498 default: 1499 return (1); 1500 } 1501 1502 kn->kn_hook = sce; 1503 1504 s = splusb(); 1505 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 1506 splx(s); 1507 1508 return (0); 1509 } 1510 1511 #if defined(__FreeBSD__) 1512 DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, usbd_driver_load, 0); 1513 #endif 1514