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