1 /* $NetBSD: udsir.c,v 1.1 2013/05/28 12:03:26 kiyohara Exp $ */ 2 3 /* 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by David Sainty <David.Sainty@dtsp.co.nz> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: udsir.c,v 1.1 2013/05/28 12:03:26 kiyohara Exp $"); 34 35 #include <sys/param.h> 36 #include <sys/device.h> 37 #include <sys/errno.h> 38 #include <sys/systm.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/conf.h> 42 #include <sys/file.h> 43 #include <sys/poll.h> 44 #include <sys/select.h> 45 #include <sys/proc.h> 46 #include <sys/kthread.h> 47 48 #include <dev/usb/usb.h> 49 #include <dev/usb/usbdevs.h> 50 #include <dev/usb/usbdi.h> 51 #include <dev/usb/usbdi_util.h> 52 53 #include <dev/ir/ir.h> 54 #include <dev/ir/irdaio.h> 55 #include <dev/ir/irframevar.h> 56 #include <dev/ir/sir.h> 57 58 #ifdef UDSIR_DEBUG 59 #define DPRINTFN(n,x) if (udsirdebug > (n)) printf x 60 int udsirdebug = 0; 61 #else 62 #define DPRINTFN(n,x) 63 #endif 64 65 /* Max size with framing. */ 66 #define MAX_UDSIR_OUTPUT_FRAME (2 * IRDA_MAX_FRAME_SIZE + IRDA_MAX_EBOFS + 4) 67 68 struct udsir_softc { 69 device_t sc_dev; 70 usbd_device_handle sc_udev; 71 usbd_interface_handle sc_iface; 72 73 uint8_t *sc_ur_buf; /* Unencapsulated frame */ 74 u_int sc_ur_framelen; 75 76 uint8_t *sc_rd_buf; /* Raw incoming data stream */ 77 int sc_rd_maxpsz; 78 size_t sc_rd_index; 79 int sc_rd_addr; 80 usbd_pipe_handle sc_rd_pipe; 81 usbd_xfer_handle sc_rd_xfer; 82 u_int sc_rd_count; 83 int sc_rd_readinprogress; 84 int sc_rd_expectdataticks; 85 u_char sc_rd_err; 86 struct framestate sc_framestate; 87 struct lwp *sc_thread; 88 struct selinfo sc_rd_sel; 89 90 uint8_t *sc_wr_buf; 91 int sc_wr_maxpsz; 92 int sc_wr_addr; 93 int sc_wr_stalewrite; 94 usbd_xfer_handle sc_wr_xfer; 95 usbd_pipe_handle sc_wr_pipe; 96 struct selinfo sc_wr_sel; 97 98 enum { 99 udir_input, /* Receiving data */ 100 udir_output, /* Transmitting data */ 101 udir_stalled, /* Error preventing data flow */ 102 udir_idle /* Neither receiving nor transmitting */ 103 } sc_direction; 104 105 device_t sc_child; 106 struct irda_params sc_params; 107 108 int sc_refcnt; 109 char sc_closing; 110 char sc_dying; 111 }; 112 113 /* True if we cannot safely read data from the device */ 114 #define UDSIR_BLOCK_RX_DATA(sc) ((sc)->sc_ur_framelen != 0) 115 116 #define UDSIR_WR_TIMEOUT 200 117 118 static int udsir_match(device_t, cfdata_t, void *); 119 static void udsir_attach(device_t, device_t, void *); 120 static int udsir_detach(device_t, int); 121 static void udsir_childdet(device_t, device_t); 122 static int udsir_activate(device_t, enum devact); 123 124 static int udsir_open(void *, int, int, struct lwp *); 125 static int udsir_close(void *, int, int, struct lwp *); 126 static int udsir_read(void *, struct uio *, int); 127 static int udsir_write(void *, struct uio *, int); 128 static int udsir_poll(void *, int, struct lwp *); 129 static int udsir_kqfilter(void *, struct knote *); 130 static int udsir_set_params(void *, struct irda_params *); 131 static int udsir_get_speeds(void *, int *); 132 static int udsir_get_turnarounds(void *, int *); 133 134 static void filt_udsirrdetach(struct knote *); 135 static int filt_udsirread(struct knote *, long); 136 static void filt_udsirwdetach(struct knote *); 137 static int filt_udsirwrite(struct knote *, long); 138 139 static void udsir_thread(void *); 140 141 #ifdef UDSIR_DEBUG 142 static void udsir_dumpdata(uint8_t const *, size_t, char const *); 143 #endif 144 static int deframe_rd_ur(struct udsir_softc *); 145 static void udsir_periodic(struct udsir_softc *); 146 static void udsir_rd_cb(usbd_xfer_handle, usbd_private_handle, usbd_status); 147 static usbd_status udsir_start_read(struct udsir_softc *); 148 149 CFATTACH_DECL2_NEW(udsir, sizeof(struct udsir_softc), 150 udsir_match, udsir_attach, udsir_detach, 151 udsir_activate, NULL, udsir_childdet); 152 153 static struct irframe_methods const udsir_methods = { 154 udsir_open, udsir_close, udsir_read, udsir_write, udsir_poll, 155 udsir_kqfilter, udsir_set_params, udsir_get_speeds, udsir_get_turnarounds, 156 }; 157 158 static int 159 udsir_match(device_t parent, cfdata_t match, void *aux) 160 { 161 struct usbif_attach_arg *uaa = aux; 162 163 DPRINTFN(50, ("udsir_match\n")); 164 165 if (uaa->vendor == USB_VENDOR_KINGSUN && 166 uaa->product == USB_PRODUCT_KINGSUN_IRDA) 167 return UMATCH_VENDOR_PRODUCT; 168 169 return UMATCH_NONE; 170 } 171 172 static void 173 udsir_attach(device_t parent, device_t self, void *aux) 174 { 175 struct udsir_softc *sc = device_private(self); 176 struct usbif_attach_arg *uaa = aux; 177 usbd_device_handle dev = uaa->device; 178 usbd_interface_handle iface = uaa->iface; 179 char *devinfop; 180 usb_endpoint_descriptor_t *ed; 181 uint8_t epcount; 182 int i; 183 struct ir_attach_args ia; 184 185 DPRINTFN(10, ("udsir_attach: sc=%p\n", sc)); 186 187 sc->sc_dev = self; 188 189 aprint_naive("\n"); 190 aprint_normal("\n"); 191 192 devinfop = usbd_devinfo_alloc(dev, 0); 193 aprint_normal_dev(self, "%s\n", devinfop); 194 usbd_devinfo_free(devinfop); 195 196 sc->sc_udev = dev; 197 sc->sc_iface = iface; 198 199 epcount = 0; 200 (void)usbd_endpoint_count(iface, &epcount); 201 202 sc->sc_rd_addr = -1; 203 sc->sc_wr_addr = -1; 204 for (i = 0; i < epcount; i++) { 205 ed = usbd_interface2endpoint_descriptor(iface, i); 206 if (ed == NULL) { 207 aprint_error_dev(self, "couldn't get ep %d\n", i); 208 return; 209 } 210 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 211 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 212 sc->sc_rd_addr = ed->bEndpointAddress; 213 sc->sc_rd_maxpsz = UGETW(ed->wMaxPacketSize); 214 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 215 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 216 sc->sc_wr_addr = ed->bEndpointAddress; 217 sc->sc_wr_maxpsz = UGETW(ed->wMaxPacketSize); 218 } 219 } 220 if (sc->sc_rd_addr == -1 || sc->sc_wr_addr == -1) { 221 aprint_error_dev(self, "missing endpoint\n"); 222 return; 223 } 224 225 DPRINTFN(10, ("udsir_attach: %p\n", sc->sc_udev)); 226 227 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 228 sc->sc_dev); 229 230 ia.ia_type = IR_TYPE_IRFRAME; 231 ia.ia_methods = &udsir_methods; 232 ia.ia_handle = sc; 233 234 sc->sc_child = config_found(self, &ia, ir_print); 235 selinit(&sc->sc_rd_sel); 236 selinit(&sc->sc_wr_sel); 237 238 return; 239 } 240 241 static int 242 udsir_detach(device_t self, int flags) 243 { 244 struct udsir_softc *sc = device_private(self); 245 int s; 246 int rv = 0; 247 248 DPRINTFN(0, ("udsir_detach: sc=%p flags=%d\n", sc, flags)); 249 250 sc->sc_closing = sc->sc_dying = 1; 251 252 wakeup(&sc->sc_thread); 253 254 while (sc->sc_thread != NULL) 255 tsleep(&sc->sc_closing, PWAIT, "usircl", 0); 256 257 /* Abort all pipes. Causes processes waiting for transfer to wake. */ 258 if (sc->sc_rd_pipe != NULL) { 259 usbd_abort_pipe(sc->sc_rd_pipe); 260 usbd_close_pipe(sc->sc_rd_pipe); 261 sc->sc_rd_pipe = NULL; 262 } 263 if (sc->sc_wr_pipe != NULL) { 264 usbd_abort_pipe(sc->sc_wr_pipe); 265 usbd_close_pipe(sc->sc_wr_pipe); 266 sc->sc_wr_pipe = NULL; 267 } 268 wakeup(&sc->sc_ur_framelen); 269 wakeup(&sc->sc_wr_buf); 270 271 s = splusb(); 272 if (--sc->sc_refcnt >= 0) { 273 /* Wait for processes to go away. */ 274 usb_detach_waitold(sc->sc_dev); 275 } 276 splx(s); 277 278 if (sc->sc_child != NULL) 279 rv = config_detach(sc->sc_child, flags); 280 281 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); 282 283 seldestroy(&sc->sc_rd_sel); 284 seldestroy(&sc->sc_wr_sel); 285 286 return rv; 287 } 288 289 static void 290 udsir_childdet(device_t self, device_t child) 291 { 292 struct udsir_softc *sc = device_private(self); 293 294 KASSERT(sc->sc_child == child); 295 sc->sc_child = NULL; 296 } 297 298 static int 299 udsir_activate(device_t self, enum devact act) 300 { 301 struct udsir_softc *sc = device_private(self); 302 303 switch (act) { 304 case DVACT_DEACTIVATE: 305 sc->sc_dying = 1; 306 return 0; 307 default: 308 return EOPNOTSUPP; 309 } 310 } 311 312 /* ARGSUSED */ 313 static int 314 udsir_open(void *h, int flag, int mode, struct lwp *l) 315 { 316 struct udsir_softc *sc = h; 317 int error; 318 usbd_status err; 319 320 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 321 322 err = usbd_open_pipe(sc->sc_iface, sc->sc_rd_addr, 0, &sc->sc_rd_pipe); 323 if (err != USBD_NORMAL_COMPLETION) { 324 error = EIO; 325 goto bad1; 326 } 327 err = usbd_open_pipe(sc->sc_iface, sc->sc_wr_addr, 0, &sc->sc_wr_pipe); 328 if (err != USBD_NORMAL_COMPLETION) { 329 error = EIO; 330 goto bad2; 331 } 332 sc->sc_rd_xfer = usbd_alloc_xfer(sc->sc_udev); 333 if (sc->sc_rd_xfer == NULL) { 334 error = ENOMEM; 335 goto bad3; 336 } 337 sc->sc_wr_xfer = usbd_alloc_xfer(sc->sc_udev); 338 if (sc->sc_wr_xfer == NULL) { 339 error = ENOMEM; 340 goto bad4; 341 } 342 sc->sc_rd_buf = usbd_alloc_buffer(sc->sc_rd_xfer, sc->sc_rd_maxpsz); 343 if (sc->sc_rd_buf == NULL) { 344 error = ENOMEM; 345 goto bad5; 346 } 347 sc->sc_wr_buf = usbd_alloc_buffer(sc->sc_wr_xfer, IRDA_MAX_FRAME_SIZE); 348 if (sc->sc_wr_buf == NULL) { 349 error = ENOMEM; 350 goto bad5; 351 } 352 sc->sc_ur_buf = malloc(IRDA_MAX_FRAME_SIZE, M_USBDEV, M_NOWAIT); 353 if (sc->sc_ur_buf == NULL) { 354 error = ENOMEM; 355 goto bad5; 356 } 357 358 sc->sc_rd_index = sc->sc_rd_count = 0; 359 sc->sc_closing = 0; 360 sc->sc_rd_readinprogress = 0; 361 sc->sc_rd_expectdataticks = 0; 362 sc->sc_ur_framelen = 0; 363 sc->sc_rd_err = 0; 364 sc->sc_wr_stalewrite = 0; 365 sc->sc_direction = udir_idle; 366 sc->sc_params.speed = 0; 367 sc->sc_params.ebofs = 0; 368 sc->sc_params.maxsize = min(sc->sc_rd_maxpsz, sc->sc_wr_maxpsz); 369 370 deframe_init(&sc->sc_framestate, sc->sc_ur_buf, IRDA_MAX_FRAME_SIZE); 371 372 /* Increment reference for thread */ 373 sc->sc_refcnt++; 374 375 error = kthread_create(PRI_NONE, 0, NULL, udsir_thread, sc, 376 &sc->sc_thread, "%s", device_xname(sc->sc_dev)); 377 if (error) { 378 sc->sc_refcnt--; 379 goto bad5; 380 } 381 382 return 0; 383 384 bad5: 385 usbd_free_xfer(sc->sc_wr_xfer); 386 sc->sc_wr_xfer = NULL; 387 bad4: 388 usbd_free_xfer(sc->sc_rd_xfer); 389 sc->sc_rd_xfer = NULL; 390 bad3: 391 usbd_close_pipe(sc->sc_wr_pipe); 392 sc->sc_wr_pipe = NULL; 393 bad2: 394 usbd_close_pipe(sc->sc_rd_pipe); 395 sc->sc_rd_pipe = NULL; 396 bad1: 397 return error; 398 } 399 400 /* ARGSUSED */ 401 static int 402 udsir_close(void *h, int flag, int mode, struct lwp *l) 403 { 404 struct udsir_softc *sc = h; 405 406 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 407 408 sc->sc_refcnt++; 409 410 sc->sc_rd_readinprogress = 1; 411 sc->sc_closing = 1; 412 413 wakeup(&sc->sc_thread); 414 415 while (sc->sc_thread != NULL) 416 tsleep(&sc->sc_closing, PWAIT, "usircl", 0); 417 418 if (sc->sc_rd_pipe != NULL) { 419 usbd_abort_pipe(sc->sc_rd_pipe); 420 usbd_close_pipe(sc->sc_rd_pipe); 421 sc->sc_rd_pipe = NULL; 422 } 423 if (sc->sc_wr_pipe != NULL) { 424 usbd_abort_pipe(sc->sc_wr_pipe); 425 usbd_close_pipe(sc->sc_wr_pipe); 426 sc->sc_wr_pipe = NULL; 427 } 428 if (sc->sc_rd_xfer != NULL) { 429 usbd_free_xfer(sc->sc_rd_xfer); 430 sc->sc_rd_xfer = NULL; 431 sc->sc_rd_buf = NULL; 432 } 433 if (sc->sc_wr_xfer != NULL) { 434 usbd_free_xfer(sc->sc_wr_xfer); 435 sc->sc_wr_xfer = NULL; 436 sc->sc_wr_buf = NULL; 437 } 438 if (sc->sc_ur_buf != NULL) { 439 free(sc->sc_ur_buf, M_USBDEV); 440 sc->sc_ur_buf = NULL; 441 } 442 443 if (--sc->sc_refcnt < 0) 444 usb_detach_wakeupold(sc->sc_dev); 445 446 return 0; 447 } 448 449 /* ARGSUSED */ 450 static int 451 udsir_read(void *h, struct uio *uio, int flag) 452 { 453 struct udsir_softc *sc = h; 454 int s; 455 int error; 456 u_int uframelen; 457 458 DPRINTFN(1, ("%s: sc=%p\n", __func__, sc)); 459 460 if (sc->sc_dying) 461 return EIO; 462 463 #ifdef DIAGNOSTIC 464 if (sc->sc_rd_buf == NULL) 465 return EINVAL; 466 #endif 467 468 sc->sc_refcnt++; 469 470 if (!sc->sc_rd_readinprogress && !UDSIR_BLOCK_RX_DATA(sc)) 471 /* Possibly wake up polling thread */ 472 wakeup(&sc->sc_thread); 473 474 do { 475 s = splusb(); 476 while (sc->sc_ur_framelen == 0) { 477 DPRINTFN(5, ("%s: calling tsleep()\n", __func__)); 478 error = tsleep(&sc->sc_ur_framelen, PZERO | PCATCH, 479 "usirrd", 0); 480 if (sc->sc_dying) 481 error = EIO; 482 if (error) { 483 splx(s); 484 DPRINTFN(0, ("%s: tsleep() = %d\n", 485 __func__, error)); 486 goto ret; 487 } 488 } 489 splx(s); 490 491 uframelen = sc->sc_ur_framelen; 492 DPRINTFN(1, ("%s: sc=%p framelen=%u, hdr=0x%02x\n", 493 __func__, sc, uframelen, sc->sc_ur_buf[0])); 494 if (uframelen > uio->uio_resid) 495 error = EINVAL; 496 else 497 error = uiomove(sc->sc_ur_buf, uframelen, uio); 498 sc->sc_ur_framelen = 0; 499 500 if (deframe_rd_ur(sc) == 0 && uframelen > 0) { 501 /* 502 * Need to wait for another read to obtain a 503 * complete frame... If we also obtained 504 * actual data, wake up the possibly sleeping 505 * thread immediately... 506 */ 507 wakeup(&sc->sc_thread); 508 } 509 } while (uframelen == 0); 510 511 DPRINTFN(1, ("%s: return %d\n", __func__, error)); 512 513 ret: 514 if (--sc->sc_refcnt < 0) 515 usb_detach_wakeupold(sc->sc_dev); 516 return error; 517 } 518 519 /* ARGSUSED */ 520 static int 521 udsir_write(void *h, struct uio *uio, int flag) 522 { 523 struct udsir_softc *sc = h; 524 usbd_status err; 525 uint32_t wrlen; 526 int error, sirlength; 527 uint8_t *wrbuf; 528 int s; 529 530 DPRINTFN(1, ("%s: sc=%p\n", __func__, sc)); 531 532 if (sc->sc_dying) 533 return EIO; 534 535 #ifdef DIAGNOSTIC 536 if (sc->sc_wr_buf == NULL) 537 return EINVAL; 538 #endif 539 540 wrlen = uio->uio_resid; 541 if (wrlen > sc->sc_wr_maxpsz) 542 return EINVAL; 543 544 sc->sc_refcnt++; 545 546 if (!UDSIR_BLOCK_RX_DATA(sc)) { 547 /* 548 * If reads are not blocked, determine what action we 549 * should potentially take... 550 */ 551 if (sc->sc_direction == udir_output) { 552 /* 553 * If the last operation was an output, wait for the 554 * polling thread to check for incoming data. 555 */ 556 sc->sc_wr_stalewrite = 1; 557 wakeup(&sc->sc_thread); 558 } else if (!sc->sc_rd_readinprogress && 559 (sc->sc_direction == udir_idle || 560 sc->sc_direction == udir_input)) { 561 /* If idle, check for input before outputting */ 562 udsir_start_read(sc); 563 } 564 } 565 566 s = splusb(); 567 while (sc->sc_wr_stalewrite || 568 (sc->sc_direction != udir_output && 569 sc->sc_direction != udir_idle)) { 570 DPRINTFN(5, ("%s: sc=%p stalewrite=%d direction=%d, " 571 "calling tsleep()\n", 572 __func__, sc, sc->sc_wr_stalewrite, 573 sc->sc_direction)); 574 error = tsleep(&sc->sc_wr_buf, PZERO | PCATCH, "usirwr", 0); 575 if (sc->sc_dying) 576 error = EIO; 577 if (error) { 578 splx(s); 579 DPRINTFN(0, ("%s: tsleep() = %d\n", __func__, error)); 580 goto ret; 581 } 582 } 583 splx(s); 584 585 wrbuf = sc->sc_wr_buf; 586 587 sirlength = irda_sir_frame(wrbuf, MAX_UDSIR_OUTPUT_FRAME, 588 uio, sc->sc_params.ebofs); 589 if (sirlength < 0) 590 error = -sirlength; 591 else { 592 uint32_t btlen; 593 594 DPRINTFN(1, ("%s: transfer %u bytes\n", 595 __func__, (unsigned int)wrlen)); 596 597 btlen = sirlength; 598 599 sc->sc_direction = udir_output; 600 601 #ifdef UDSIR_DEBUG 602 if (udsirdebug >= 20) 603 udsir_dumpdata(wrbuf, btlen, __func__); 604 #endif 605 606 err = usbd_intr_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, 607 USBD_FORCE_SHORT_XFER | USBD_NO_COPY, 608 UDSIR_WR_TIMEOUT, wrbuf, &btlen, "udsiwr"); 609 DPRINTFN(2, ("%s: err=%d\n", __func__, err)); 610 if (err != USBD_NORMAL_COMPLETION) { 611 if (err == USBD_INTERRUPTED) 612 error = EINTR; 613 else if (err == USBD_TIMEOUT) 614 error = ETIMEDOUT; 615 else 616 error = EIO; 617 } else 618 error = 0; 619 } 620 621 ret: 622 if (--sc->sc_refcnt < 0) 623 usb_detach_wakeupold(sc->sc_dev); 624 625 DPRINTFN(1, ("%s: sc=%p done\n", __func__, sc)); 626 return error; 627 } 628 629 static int 630 udsir_poll(void *h, int events, struct lwp *l) 631 { 632 struct udsir_softc *sc = h; 633 int revents = 0; 634 635 DPRINTFN(1, ("%s: sc=%p\n", __func__, sc)); 636 637 if (events & (POLLOUT | POLLWRNORM)) { 638 if (sc->sc_direction != udir_input) 639 revents |= events & (POLLOUT | POLLWRNORM); 640 else { 641 DPRINTFN(2, ("%s: recording write select\n", __func__)); 642 selrecord(l, &sc->sc_wr_sel); 643 } 644 } 645 646 if (events & (POLLIN | POLLRDNORM)) { 647 if (sc->sc_ur_framelen != 0) { 648 DPRINTFN(2, ("%s: have data\n", __func__)); 649 revents |= events & (POLLIN | POLLRDNORM); 650 } else { 651 DPRINTFN(2, ("%s: recording read select\n", __func__)); 652 selrecord(l, &sc->sc_rd_sel); 653 } 654 } 655 656 return revents; 657 } 658 659 static const struct filterops udsirread_filtops = 660 { 1, NULL, filt_udsirrdetach, filt_udsirread }; 661 static const struct filterops udsirwrite_filtops = 662 { 1, NULL, filt_udsirwdetach, filt_udsirwrite }; 663 664 static int 665 udsir_kqfilter(void *h, struct knote *kn) 666 { 667 struct udsir_softc *sc = h; 668 struct klist *klist; 669 int s; 670 671 switch (kn->kn_filter) { 672 case EVFILT_READ: 673 klist = &sc->sc_rd_sel.sel_klist; 674 kn->kn_fop = &udsirread_filtops; 675 break; 676 case EVFILT_WRITE: 677 klist = &sc->sc_wr_sel.sel_klist; 678 kn->kn_fop = &udsirwrite_filtops; 679 break; 680 default: 681 return (EINVAL); 682 } 683 684 kn->kn_hook = sc; 685 686 s = splusb(); 687 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 688 splx(s); 689 690 return (0); 691 } 692 693 static int 694 udsir_set_params(void *h, struct irda_params *p) 695 { 696 struct udsir_softc *sc = h; 697 698 DPRINTFN(0, ("%s: sc=%p, speed=%d ebofs=%d maxsize=%d\n", 699 __func__, sc, p->speed, p->ebofs, p->maxsize)); 700 701 if (sc->sc_dying) 702 return EIO; 703 704 if (p->speed != 9600) 705 return EINVAL; 706 707 if (p->maxsize != sc->sc_params.maxsize) { 708 if (p->maxsize > min(sc->sc_rd_maxpsz, sc->sc_wr_maxpsz)) 709 return EINVAL; 710 sc->sc_params.maxsize = p->maxsize; 711 } 712 713 sc->sc_params = *p; 714 715 return 0; 716 } 717 718 static int 719 udsir_get_speeds(void *h, int *speeds) 720 { 721 struct udsir_softc *sc = h; 722 723 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 724 725 if (sc->sc_dying) 726 return EIO; 727 728 /* Support only 9600bps now. */ 729 *speeds = IRDA_SPEED_9600; 730 731 return 0; 732 } 733 734 static int 735 udsir_get_turnarounds(void *h, int *turnarounds) 736 { 737 struct udsir_softc *sc = h; 738 739 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 740 741 if (sc->sc_dying) 742 return EIO; 743 744 /* 745 * Documentation is on the light side with respect to 746 * turnaround time for this device. 747 */ 748 *turnarounds = IRDA_TURNT_10000; 749 750 return 0; 751 } 752 753 static void 754 filt_udsirrdetach(struct knote *kn) 755 { 756 struct udsir_softc *sc = kn->kn_hook; 757 int s; 758 759 s = splusb(); 760 SLIST_REMOVE(&sc->sc_rd_sel.sel_klist, kn, knote, kn_selnext); 761 splx(s); 762 } 763 764 /* ARGSUSED */ 765 static int 766 filt_udsirread(struct knote *kn, long hint) 767 { 768 struct udsir_softc *sc = kn->kn_hook; 769 770 kn->kn_data = sc->sc_ur_framelen; 771 return (kn->kn_data > 0); 772 } 773 774 static void 775 filt_udsirwdetach(struct knote *kn) 776 { 777 struct udsir_softc *sc = kn->kn_hook; 778 int s; 779 780 s = splusb(); 781 SLIST_REMOVE(&sc->sc_wr_sel.sel_klist, kn, knote, kn_selnext); 782 splx(s); 783 } 784 785 /* ARGSUSED */ 786 static int 787 filt_udsirwrite(struct knote *kn, long hint) 788 { 789 struct udsir_softc *sc = kn->kn_hook; 790 791 kn->kn_data = 0; 792 return (sc->sc_direction != udir_input); 793 } 794 795 796 static void 797 udsir_thread(void *arg) 798 { 799 struct udsir_softc *sc = arg; 800 int error; 801 802 DPRINTFN(20, ("%s: starting polling thread\n", __func__)); 803 804 while (!sc->sc_closing) { 805 if (!sc->sc_rd_readinprogress && !UDSIR_BLOCK_RX_DATA(sc)) 806 udsir_periodic(sc); 807 808 if (!sc->sc_closing) { 809 error = tsleep(&sc->sc_thread, PWAIT, "udsir", hz / 10); 810 if (error == EWOULDBLOCK && 811 sc->sc_rd_expectdataticks > 0) 812 /* 813 * After a timeout decrement the tick 814 * counter within which time we expect 815 * data to arrive if we are receiving 816 * data... 817 */ 818 sc->sc_rd_expectdataticks--; 819 } 820 } 821 822 DPRINTFN(20, ("%s: exiting polling thread\n", __func__)); 823 824 sc->sc_thread = NULL; 825 826 wakeup(&sc->sc_closing); 827 828 if (--sc->sc_refcnt < 0) 829 usb_detach_wakeupold(sc->sc_dev); 830 831 kthread_exit(0); 832 } 833 834 #ifdef UDSIR_DEBUG 835 static void 836 udsir_dumpdata(uint8_t const *data, size_t dlen, char const *desc) 837 { 838 size_t bdindex; 839 840 printf("%s: (%lx)", desc, (unsigned long)dlen); 841 for (bdindex = 0; bdindex < dlen; bdindex++) 842 printf(" %02x", (unsigned int)data[bdindex]); 843 printf("\n"); 844 } 845 #endif 846 847 /* Returns 0 if more data required, 1 if a complete frame was extracted */ 848 static int 849 deframe_rd_ur(struct udsir_softc *sc) 850 { 851 852 if (sc->sc_rd_index == 0) { 853 KASSERT(sc->sc_rd_count == sc->sc_rd_maxpsz); 854 /* valid count */ 855 sc->sc_rd_count = sc->sc_rd_buf[sc->sc_rd_index++] + 1; 856 KASSERT(sc->sc_rd_count < sc->sc_rd_maxpsz); 857 } 858 859 while (sc->sc_rd_index < sc->sc_rd_count) { 860 uint8_t const *buf; 861 size_t buflen; 862 enum frameresult fresult; 863 864 buf = &sc->sc_rd_buf[sc->sc_rd_index]; 865 buflen = sc->sc_rd_count - sc->sc_rd_index; 866 867 fresult = deframe_process(&sc->sc_framestate, &buf, &buflen); 868 869 sc->sc_rd_index = sc->sc_rd_count - buflen; 870 871 DPRINTFN(1,("%s: result=%d\n", __func__, (int)fresult)); 872 873 switch (fresult) { 874 case FR_IDLE: 875 case FR_INPROGRESS: 876 case FR_FRAMEBADFCS: 877 case FR_FRAMEMALFORMED: 878 case FR_BUFFEROVERRUN: 879 break; 880 case FR_FRAMEOK: 881 sc->sc_ur_framelen = sc->sc_framestate.bufindex; 882 wakeup(&sc->sc_ur_framelen); /* XXX should use flag */ 883 selnotify(&sc->sc_rd_sel, 0, 0); 884 return 1; 885 } 886 } 887 888 /* Reset indices into USB-side buffer */ 889 sc->sc_rd_index = sc->sc_rd_count = 0; 890 891 return 0; 892 } 893 894 /* 895 * Direction transitions: 896 * 897 * udsir_periodic() can switch the direction from: 898 * 899 * output -> idle 900 * output -> stalled 901 * stalled -> idle 902 * idle -> input 903 * 904 * udsir_rd_cb() can switch the direction from: 905 * 906 * input -> stalled 907 * input -> idle 908 * 909 * udsir_write() can switch the direction from: 910 * 911 * idle -> output 912 */ 913 static void 914 udsir_periodic(struct udsir_softc *sc) 915 { 916 917 DPRINTFN(60, ("%s: direction = %d\n", __func__, sc->sc_direction)); 918 919 if (sc->sc_wr_stalewrite && sc->sc_direction == udir_idle) { 920 /* 921 * In a stale write case, we need to check if the 922 * write has completed. Once that has happened, the 923 * write is no longer stale. 924 * 925 * But note that we may immediately start a read poll... 926 */ 927 sc->sc_wr_stalewrite = 0; 928 wakeup(&sc->sc_wr_buf); 929 } 930 931 if (!sc->sc_rd_readinprogress && 932 (sc->sc_direction == udir_idle || 933 sc->sc_direction == udir_input)) 934 /* Do a read poll if appropriate... */ 935 udsir_start_read(sc); 936 } 937 938 static void 939 udsir_rd_cb(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 940 { 941 struct udsir_softc *sc = priv; 942 uint32_t size; 943 944 DPRINTFN(60, ("%s: sc=%p\n", __func__, sc)); 945 946 /* Read is no longer in progress */ 947 sc->sc_rd_readinprogress = 0; 948 949 if (status == USBD_CANCELLED || sc->sc_closing) /* this is normal */ 950 return; 951 if (status) { 952 size = 0; 953 sc->sc_rd_err = 1; 954 955 if (sc->sc_direction == udir_input || 956 sc->sc_direction == udir_idle) { 957 /* 958 * Receive error, probably need to clear error 959 * condition. 960 */ 961 sc->sc_direction = udir_stalled; 962 } 963 } else 964 usbd_get_xfer_status(xfer, NULL, NULL, &size, NULL); 965 966 sc->sc_rd_index = 0; 967 sc->sc_rd_count = size; 968 969 DPRINTFN(((size > 0 || sc->sc_rd_err != 0) ? 20 : 60), 970 ("%s: sc=%p size=%u, err=%d\n", 971 __func__, sc, size, sc->sc_rd_err)); 972 973 #ifdef UDSIR_DEBUG 974 if (udsirdebug >= 20 && size > 0) 975 udsir_dumpdata(sc->sc_rd_buf, size, __func__); 976 #endif 977 978 if (deframe_rd_ur(sc) == 0) { 979 if (!deframe_isclear(&sc->sc_framestate) && size == 0 && 980 sc->sc_rd_expectdataticks == 0) { 981 /* 982 * Expected data, but didn't get it 983 * within expected time... 984 */ 985 DPRINTFN(5,("%s: incoming packet timeout\n", 986 __func__)); 987 deframe_clear(&sc->sc_framestate); 988 } else if (size > 0) { 989 /* 990 * If we also received actual data, reset the 991 * data read timeout and wake up the possibly 992 * sleeping thread... 993 */ 994 sc->sc_rd_expectdataticks = 2; 995 wakeup(&sc->sc_thread); 996 } 997 } 998 999 /* 1000 * Check if incoming data has stopped, or that we cannot 1001 * safely read any more data. In the case of the latter we 1002 * must switch to idle so that a write will not block... 1003 */ 1004 if (sc->sc_direction == udir_input && 1005 ((size == 0 && sc->sc_rd_expectdataticks == 0) || 1006 UDSIR_BLOCK_RX_DATA(sc))) { 1007 DPRINTFN(8, ("%s: idling on packet timeout, " 1008 "complete frame, or no data\n", __func__)); 1009 sc->sc_direction = udir_idle; 1010 1011 /* Wake up for possible output */ 1012 wakeup(&sc->sc_wr_buf); 1013 selnotify(&sc->sc_wr_sel, 0, 0); 1014 } 1015 } 1016 1017 static usbd_status 1018 udsir_start_read(struct udsir_softc *sc) 1019 { 1020 usbd_status err; 1021 1022 DPRINTFN(60, ("%s: sc=%p, size=%d\n", __func__, sc, sc->sc_rd_maxpsz)); 1023 1024 if (sc->sc_dying) 1025 return USBD_IOERROR; 1026 1027 if (UDSIR_BLOCK_RX_DATA(sc) || deframe_rd_ur(sc)) { 1028 /* 1029 * Can't start reading just yet. Since we aren't 1030 * going to start a read, have to switch direction to 1031 * idle. 1032 */ 1033 sc->sc_direction = udir_idle; 1034 return USBD_NORMAL_COMPLETION; 1035 } 1036 1037 /* Starting a read... */ 1038 sc->sc_rd_readinprogress = 1; 1039 sc->sc_direction = udir_input; 1040 1041 if (sc->sc_rd_err) { 1042 sc->sc_rd_err = 0; 1043 DPRINTFN(0, ("%s: clear stall\n", __func__)); 1044 usbd_clear_endpoint_stall(sc->sc_rd_pipe); 1045 } 1046 1047 usbd_setup_xfer(sc->sc_rd_xfer, sc->sc_rd_pipe, sc, sc->sc_rd_buf, 1048 sc->sc_rd_maxpsz, USBD_SHORT_XFER_OK | USBD_NO_COPY, 1049 USBD_NO_TIMEOUT, udsir_rd_cb); 1050 err = usbd_transfer(sc->sc_rd_xfer); 1051 if (err != USBD_IN_PROGRESS) { 1052 DPRINTFN(0, ("%s: err=%d\n", __func__, (int)err)); 1053 return err; 1054 } 1055 return USBD_NORMAL_COMPLETION; 1056 } 1057