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