1 /* $NetBSD: ustir.c,v 1.26 2008/05/24 16:40:58 cube 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: ustir.c,v 1.26 2008/05/24 16:40:58 cube Exp $"); 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/device.h> 39 #include <sys/malloc.h> 40 #include <sys/conf.h> 41 #include <sys/file.h> 42 #include <sys/poll.h> 43 #include <sys/select.h> 44 #include <sys/proc.h> 45 #include <sys/kthread.h> 46 47 #ifdef USTIR_DEBUG_IOCTLS 48 #include <sys/ioctl.h> 49 #include <dev/usb/ustir.h> 50 #endif 51 52 #include <dev/usb/usb.h> 53 #include <dev/usb/usbdevs.h> 54 #include <dev/usb/usbdi.h> 55 #include <dev/usb/usbdi_util.h> 56 #include <dev/usb/ustirreg.h> 57 58 #include <dev/ir/ir.h> 59 #include <dev/ir/irdaio.h> 60 #include <dev/ir/irframevar.h> 61 #include <dev/ir/sir.h> 62 63 #ifdef USTIR_DEBUG 64 #define DPRINTFN(n,x) if (ustirdebug>(n)) logprintf x 65 int ustirdebug = 0; 66 #else 67 #define DPRINTFN(n,x) 68 #endif 69 70 /* Max size with framing. */ 71 #define MAX_USTIR_OUTPUT_FRAME (2*IRDA_MAX_FRAME_SIZE + IRDA_MAX_EBOFS + STIR_OUTPUT_HEADER_SIZE + 4) 72 73 #define USTIR_NSPEEDS 9 74 struct ustir_speedrec { 75 unsigned int speed; 76 unsigned int config; 77 }; 78 79 Static struct ustir_speedrec const ustir_speeds[USTIR_NSPEEDS] = { 80 { 4000000, STIR_BRMODE_4000000 }, 81 { 1152000, STIR_BRMODE_1152000 }, 82 { 576000, STIR_BRMODE_576000 }, 83 { 115200, STIR_BRMODE_115200 }, 84 { 57600, STIR_BRMODE_57600 }, 85 { 38400, STIR_BRMODE_38400 }, 86 { 19200, STIR_BRMODE_19200 }, 87 { 9600, STIR_BRMODE_9600 }, 88 { 2400, STIR_BRMODE_2400 } 89 }; 90 91 struct framedefn { 92 unsigned int bof_count; 93 u_int8_t bof_byte; 94 95 u_int8_t esc_byte; 96 u_int8_t esc_xor; 97 98 unsigned int eof_count; 99 u_int8_t eof_byte; 100 101 unsigned int fcs_count; 102 u_int32_t fcs_init; 103 u_int32_t fcs_correct; 104 105 u_int32_t (*fcs_calc)(u_int32_t, u_int8_t const*, size_t); 106 }; 107 108 Static u_int32_t crc_ccitt_16(u_int32_t, u_int8_t const*, size_t); 109 110 struct framedefn const framedef_sir = { 111 1, 0xc0, 112 0x7d, 0x20, 113 1, 0xc1, 114 2, INITFCS, GOODFCS, 115 crc_ccitt_16 116 }; 117 118 enum framefsmstate { 119 FSTATE_END_OF_FRAME, 120 FSTATE_START_OF_FRAME, 121 FSTATE_IN_DATA, 122 FSTATE_IN_END 123 }; 124 125 enum frameresult { 126 FR_IDLE, 127 FR_INPROGRESS, 128 FR_FRAMEOK, 129 FR_FRAMEBADFCS, 130 FR_FRAMEMALFORMED, 131 FR_BUFFEROVERRUN 132 }; 133 134 struct framestate { 135 struct framedefn const *definition; 136 137 u_int8_t *buffer; 138 size_t buflen; 139 size_t bufindex; 140 141 enum framefsmstate fsmstate; 142 u_int escaped; 143 u_int state_index; 144 }; 145 146 #define deframe_isclear(fs) ((fs)->fsmstate == FSTATE_END_OF_FRAME) 147 148 Static void deframe_clear(struct framestate *); 149 Static void deframe_init(struct framestate *, struct framedefn const *, 150 u_int8_t *, size_t); 151 Static enum frameresult deframe_process(struct framestate *, u_int8_t const **, 152 size_t *); 153 154 struct ustir_softc { 155 USBBASEDEVICE sc_dev; 156 usbd_device_handle sc_udev; 157 usbd_interface_handle sc_iface; 158 159 u_int8_t *sc_ur_buf; /* Unencapsulated frame */ 160 u_int sc_ur_framelen; 161 162 u_int8_t *sc_rd_buf; /* Raw incoming data stream */ 163 size_t sc_rd_index; 164 int sc_rd_addr; 165 usbd_pipe_handle sc_rd_pipe; 166 usbd_xfer_handle sc_rd_xfer; 167 u_int sc_rd_count; 168 int sc_rd_readinprogress; 169 u_int sc_rd_expectdataticks; 170 u_char sc_rd_err; 171 struct framestate sc_framestate; 172 struct lwp *sc_thread; 173 struct selinfo sc_rd_sel; 174 175 u_int8_t *sc_wr_buf; 176 int sc_wr_addr; 177 int sc_wr_stalewrite; 178 usbd_xfer_handle sc_wr_xfer; 179 usbd_pipe_handle sc_wr_pipe; 180 struct selinfo sc_wr_sel; 181 182 enum { 183 udir_input, /* Receiving data */ 184 udir_output, /* Transmitting data */ 185 udir_stalled, /* Error preventing data flow */ 186 udir_idle /* Neither receiving nor transmitting */ 187 } sc_direction; 188 189 struct ustir_speedrec const *sc_speedrec; 190 191 device_t sc_child; 192 struct irda_params sc_params; 193 194 int sc_refcnt; 195 char sc_closing; 196 char sc_dying; 197 }; 198 199 /* True if we cannot safely read data from the device */ 200 #define USTIR_BLOCK_RX_DATA(sc) ((sc)->sc_ur_framelen != 0) 201 202 #define USTIR_WR_TIMEOUT 200 203 204 Static int ustir_activate(device_ptr_t self, enum devact act); 205 Static int ustir_open(void *h, int flag, int mode, struct lwp *l); 206 Static int ustir_close(void *h, int flag, int mode, struct lwp *l); 207 Static int ustir_read(void *h, struct uio *uio, int flag); 208 Static int ustir_write(void *h, struct uio *uio, int flag); 209 Static int ustir_set_params(void *h, struct irda_params *params); 210 Static int ustir_get_speeds(void *h, int *speeds); 211 Static int ustir_get_turnarounds(void *h, int *times); 212 Static int ustir_poll(void *h, int events, struct lwp *l); 213 Static int ustir_kqfilter(void *h, struct knote *kn); 214 215 #ifdef USTIR_DEBUG_IOCTLS 216 Static int ustir_ioctl(void *h, u_long cmd, void *addr, int flag, struct lwp *l); 217 #endif 218 219 Static struct irframe_methods const ustir_methods = { 220 ustir_open, ustir_close, ustir_read, ustir_write, ustir_poll, 221 ustir_kqfilter, ustir_set_params, ustir_get_speeds, 222 ustir_get_turnarounds, 223 #ifdef USTIR_DEBUG_IOCTLS 224 ustir_ioctl 225 #endif 226 }; 227 228 Static void ustir_rd_cb(usbd_xfer_handle, usbd_private_handle, usbd_status); 229 Static usbd_status ustir_start_read(struct ustir_softc *); 230 Static void ustir_periodic(struct ustir_softc *); 231 Static void ustir_thread(void *); 232 233 Static u_int32_t 234 crc_ccitt_16(u_int32_t crcinit, u_int8_t const *buf, size_t blen) 235 { 236 while (blen-- > 0) { 237 u_int8_t chr; 238 chr = *buf++; 239 crcinit = updateFCS(crcinit, chr); 240 } 241 return crcinit; 242 } 243 244 static usbd_status 245 ustir_read_reg(struct ustir_softc *sc, unsigned int reg, u_int8_t *data) 246 { 247 usb_device_request_t req; 248 249 req.bmRequestType = UT_READ_VENDOR_DEVICE; 250 req.bRequest = STIR_CMD_READMULTIREG; 251 USETW(req.wValue, 0); 252 USETW(req.wIndex, reg); 253 USETW(req.wLength, 1); 254 255 return usbd_do_request(sc->sc_udev, &req, data); 256 } 257 258 static usbd_status 259 ustir_write_reg(struct ustir_softc *sc, unsigned int reg, u_int8_t data) 260 { 261 usb_device_request_t req; 262 263 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 264 req.bRequest = STIR_CMD_WRITESINGLEREG; 265 USETW(req.wValue, data); 266 USETW(req.wIndex, reg); 267 USETW(req.wLength, 0); 268 269 return usbd_do_request(sc->sc_udev, &req, NULL); 270 } 271 272 #ifdef USTIR_DEBUG 273 static void 274 ustir_dumpdata(u_int8_t const *data, size_t dlen, char const *desc) 275 { 276 size_t bdindex; 277 printf("%s: (%lx)", desc, (unsigned long)dlen); 278 for (bdindex = 0; bdindex < dlen; bdindex++) 279 printf(" %02x", (unsigned int)data[bdindex]); 280 printf("\n"); 281 } 282 #endif 283 284 int ustir_match(device_t, cfdata_t, void *); 285 void ustir_attach(device_t, device_t, void *); 286 void ustir_childdet(device_t, device_t); 287 int ustir_detach(device_t, int); 288 int ustir_activate(device_t, enum devact); 289 extern struct cfdriver ustir_cd; 290 CFATTACH_DECL2_NEW(ustir, sizeof(struct ustir_softc), ustir_match, 291 ustir_attach, ustir_detach, ustir_activate, NULL, ustir_childdet); 292 293 USB_MATCH(ustir) 294 { 295 USB_MATCH_START(ustir, uaa); 296 297 DPRINTFN(50,("ustir_match\n")); 298 299 if (uaa->vendor == USB_VENDOR_SIGMATEL && 300 uaa->product == USB_PRODUCT_SIGMATEL_IRDA) 301 return UMATCH_VENDOR_PRODUCT; 302 303 return UMATCH_NONE; 304 } 305 306 USB_ATTACH(ustir) 307 { 308 USB_ATTACH_START(ustir, sc, uaa); 309 usbd_device_handle dev = uaa->device; 310 usbd_interface_handle iface; 311 char *devinfop; 312 usb_endpoint_descriptor_t *ed; 313 u_int8_t epcount; 314 int i; 315 struct ir_attach_args ia; 316 317 DPRINTFN(10,("ustir_attach: sc=%p\n", sc)); 318 319 sc->sc_dev = self; 320 321 devinfop = usbd_devinfo_alloc(dev, 0); 322 USB_ATTACH_SETUP; 323 aprint_normal_dev(self, "%s\n", devinfop); 324 usbd_devinfo_free(devinfop); 325 326 if (usbd_set_config_index(dev, 0, 1) 327 || usbd_device2interface_handle(dev, 0, &iface)) { 328 aprint_error_dev(self, "Configuration failed\n"); 329 USB_ATTACH_ERROR_RETURN; 330 } 331 332 sc->sc_udev = dev; 333 sc->sc_iface = iface; 334 335 epcount = 0; 336 (void)usbd_endpoint_count(iface, &epcount); 337 338 sc->sc_rd_addr = -1; 339 sc->sc_wr_addr = -1; 340 for (i = 0; i < epcount; i++) { 341 ed = usbd_interface2endpoint_descriptor(iface, i); 342 if (ed == NULL) { 343 aprint_error_dev(self, "couldn't get ep %d\n", i); 344 USB_ATTACH_ERROR_RETURN; 345 } 346 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 347 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 348 sc->sc_rd_addr = ed->bEndpointAddress; 349 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 350 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 351 sc->sc_wr_addr = ed->bEndpointAddress; 352 } 353 } 354 if (sc->sc_rd_addr == -1 || sc->sc_wr_addr == -1) { 355 aprint_error_dev(self, "missing endpoint\n"); 356 USB_ATTACH_ERROR_RETURN; 357 } 358 359 DPRINTFN(10, ("ustir_attach: %p\n", sc->sc_udev)); 360 361 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 362 USBDEV(sc->sc_dev)); 363 364 ia.ia_type = IR_TYPE_IRFRAME; 365 ia.ia_methods = &ustir_methods; 366 ia.ia_handle = sc; 367 368 sc->sc_child = config_found(self, &ia, ir_print); 369 selinit(&sc->sc_rd_sel); 370 selinit(&sc->sc_wr_sel); 371 372 USB_ATTACH_SUCCESS_RETURN; 373 } 374 375 void 376 ustir_childdet(device_t self, device_t child) 377 { 378 struct ustir_softc *sc = device_private(self); 379 380 KASSERT(sc->sc_child == child); 381 sc->sc_child = NULL; 382 } 383 384 USB_DETACH(ustir) 385 { 386 USB_DETACH_START(ustir, sc); 387 int s; 388 int rv = 0; 389 390 DPRINTFN(0, ("ustir_detach: sc=%p flags=%d\n", sc, flags)); 391 392 sc->sc_closing = sc->sc_dying = 1; 393 394 wakeup(&sc->sc_thread); 395 396 while (sc->sc_thread != NULL) 397 tsleep(&sc->sc_closing, PWAIT, "usircl", 0); 398 399 /* Abort all pipes. Causes processes waiting for transfer to wake. */ 400 if (sc->sc_rd_pipe != NULL) { 401 usbd_abort_pipe(sc->sc_rd_pipe); 402 usbd_close_pipe(sc->sc_rd_pipe); 403 sc->sc_rd_pipe = NULL; 404 } 405 if (sc->sc_wr_pipe != NULL) { 406 usbd_abort_pipe(sc->sc_wr_pipe); 407 usbd_close_pipe(sc->sc_wr_pipe); 408 sc->sc_wr_pipe = NULL; 409 } 410 wakeup(&sc->sc_ur_framelen); 411 wakeup(&sc->sc_wr_buf); 412 413 s = splusb(); 414 if (--sc->sc_refcnt >= 0) { 415 /* Wait for processes to go away. */ 416 usb_detach_wait(USBDEV(sc->sc_dev)); 417 } 418 splx(s); 419 420 if (sc->sc_child != NULL) 421 rv = config_detach(sc->sc_child, flags); 422 423 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 424 USBDEV(sc->sc_dev)); 425 426 seldestroy(&sc->sc_rd_sel); 427 seldestroy(&sc->sc_wr_sel); 428 429 return rv; 430 } 431 432 Static void 433 deframe_clear(struct framestate *fstate) 434 { 435 fstate->bufindex = 0; 436 fstate->fsmstate = FSTATE_END_OF_FRAME; 437 fstate->escaped = 0; 438 } 439 440 Static void 441 deframe_init(struct framestate *fstate, struct framedefn const *definition, 442 u_int8_t *buf, size_t buflen) 443 { 444 fstate->definition = definition; 445 fstate->buffer = buf; 446 fstate->buflen = buflen; 447 448 deframe_clear(fstate); 449 } 450 451 Static enum frameresult 452 deframe_process(struct framestate *fstate, u_int8_t const **bptr, size_t *blen) 453 { 454 struct framedefn const *definition; 455 u_int8_t const *cptr; 456 u_int8_t escchr; 457 size_t ibuflen, obufindex, obuflen; 458 enum framefsmstate fsmstate; 459 enum frameresult result; 460 461 cptr = *bptr; 462 fsmstate = fstate->fsmstate; 463 definition = fstate->definition; 464 escchr = definition->esc_byte; 465 obufindex = fstate->bufindex; 466 obuflen = fstate->buflen; 467 ibuflen = *blen; 468 469 while (ibuflen-- > 0) { 470 u_int8_t chr; 471 472 chr = *cptr++; 473 474 if (fstate->escaped) { 475 fstate->escaped = 0; 476 chr ^= definition->esc_xor; 477 } else if (chr == escchr) { 478 fstate->escaped = 1; 479 continue; 480 } 481 482 switch (fsmstate) { 483 case FSTATE_IN_DATA: 484 if (chr == definition->eof_byte) { 485 fsmstate = FSTATE_IN_END; 486 fstate->state_index = definition->eof_count; 487 goto state_in_end; 488 } 489 if (obufindex >= obuflen) { 490 result = FR_BUFFEROVERRUN; 491 fsmstate = FSTATE_END_OF_FRAME; 492 goto complete; 493 } 494 fstate->buffer[obufindex++] = chr; 495 break; 496 497 state_in_end: 498 /* FALLTHROUGH */ 499 500 case FSTATE_IN_END: 501 if (--fstate->state_index == 0) { 502 u_int32_t crc; 503 size_t fcslen; 504 505 fsmstate = FSTATE_END_OF_FRAME; 506 507 fcslen = definition->fcs_count; 508 509 if (obufindex < fcslen) { 510 result = FR_FRAMEMALFORMED; 511 goto complete; 512 } 513 514 crc = definition-> 515 fcs_calc(definition->fcs_init, 516 fstate->buffer, obufindex); 517 518 /* Remove check bytes from buffer length */ 519 obufindex -= fcslen; 520 521 if (crc == definition->fcs_correct) 522 result = FR_FRAMEOK; 523 else 524 result = FR_FRAMEBADFCS; 525 526 goto complete; 527 } 528 break; 529 530 case FSTATE_END_OF_FRAME: 531 if (chr != definition->bof_byte) 532 break; 533 534 fsmstate = FSTATE_START_OF_FRAME; 535 fstate->state_index = definition->bof_count; 536 /* FALLTHROUGH */ 537 case FSTATE_START_OF_FRAME: 538 if (--fstate->state_index == 0) { 539 fsmstate = FSTATE_IN_DATA; 540 obufindex = 0; 541 } 542 break; 543 } 544 } 545 546 result = (fsmstate == FSTATE_END_OF_FRAME) ? FR_IDLE : FR_INPROGRESS; 547 548 complete: 549 fstate->bufindex = obufindex; 550 fstate->fsmstate = fsmstate; 551 *blen = ibuflen; 552 553 return result; 554 } 555 556 /* Returns 0 if more data required, 1 if a complete frame was extracted */ 557 static int 558 deframe_rd_ur(struct ustir_softc *sc) 559 { 560 while (sc->sc_rd_index < sc->sc_rd_count) { 561 u_int8_t const *buf; 562 size_t buflen; 563 enum frameresult fresult; 564 565 buf = &sc->sc_rd_buf[sc->sc_rd_index]; 566 buflen = sc->sc_rd_count - sc->sc_rd_index; 567 568 fresult = deframe_process(&sc->sc_framestate, &buf, &buflen); 569 570 sc->sc_rd_index = sc->sc_rd_count - buflen; 571 572 DPRINTFN(1,("%s: result=%d\n", __func__, (int)fresult)); 573 574 switch (fresult) { 575 case FR_IDLE: 576 case FR_INPROGRESS: 577 case FR_FRAMEBADFCS: 578 case FR_FRAMEMALFORMED: 579 case FR_BUFFEROVERRUN: 580 break; 581 case FR_FRAMEOK: 582 sc->sc_ur_framelen = sc->sc_framestate.bufindex; 583 wakeup(&sc->sc_ur_framelen); /* XXX should use flag */ 584 selnotify(&sc->sc_rd_sel, 0, 0); 585 return 1; 586 } 587 } 588 589 /* Reset indices into USB-side buffer */ 590 sc->sc_rd_index = sc->sc_rd_count = 0; 591 592 return 0; 593 } 594 595 /* 596 * Direction transitions: 597 * 598 * ustir_periodic() can switch the direction from: 599 * 600 * output -> idle 601 * output -> stalled 602 * stalled -> idle 603 * idle -> input 604 * 605 * ustir_rd_cb() can switch the direction from: 606 * 607 * input -> stalled 608 * input -> idle 609 * 610 * ustir_write() can switch the direction from: 611 * 612 * idle -> output 613 */ 614 Static void 615 ustir_periodic(struct ustir_softc *sc) 616 { 617 DPRINTFN(60, ("%s: direction = %d\n", 618 __func__, sc->sc_direction)); 619 620 if (sc->sc_direction == udir_output || 621 sc->sc_direction == udir_stalled) { 622 usbd_status err; 623 u_int8_t regval; 624 625 DPRINTFN(60, ("%s: reading status register\n", 626 __func__)); 627 628 err = ustir_read_reg(sc, STIR_REG_STATUS, 629 ®val); 630 if (err != USBD_NORMAL_COMPLETION) { 631 aprint_error_dev(sc->sc_dev, 632 "status register read failed: %s\n", 633 usbd_errstr(err)); 634 } else { 635 DPRINTFN(10, ("%s: status register = 0x%x\n", 636 __func__, 637 (unsigned int)regval)); 638 if (sc->sc_direction == udir_output && 639 !(regval & STIR_RSTATUS_FFDIR)) 640 /* Output has completed */ 641 sc->sc_direction = udir_idle; 642 if (regval & STIR_RSTATUS_FFOVER) { 643 /* 644 * On an overrun the FIFO hangs, and 645 * any data bulk transfers will stall. 646 * Reset the FIFO. 647 */ 648 sc->sc_direction = udir_stalled; 649 650 DPRINTFN(10, ("%s: clearing FIFO error\n", 651 __func__)); 652 653 err = ustir_write_reg(sc, STIR_REG_STATUS, 654 STIR_RSTATUS_FFCLR); 655 /* XXX if we fail partway through 656 * this, we may not recover? */ 657 if (err == USBD_NORMAL_COMPLETION) 658 err = ustir_write_reg(sc, 659 STIR_REG_STATUS, 660 0); 661 if (err != USBD_NORMAL_COMPLETION) { 662 aprint_error_dev(sc->sc_dev, 663 "FIFO reset failed: %s\n", 664 usbd_errstr(err)); 665 } else { 666 /* FIFO reset */ 667 sc->sc_direction = udir_idle; 668 } 669 } 670 } 671 } 672 673 if (sc->sc_wr_stalewrite && sc->sc_direction == udir_idle) { 674 /* 675 * In a stale write case, we need to check if the 676 * write has completed. Once that has happened, the 677 * write is no longer stale. 678 * 679 * But note that we may immediately start a read poll... 680 */ 681 sc->sc_wr_stalewrite = 0; 682 wakeup(&sc->sc_wr_buf); 683 } 684 685 if (!sc->sc_rd_readinprogress && 686 (sc->sc_direction == udir_idle || 687 sc->sc_direction == udir_input)) 688 /* Do a read poll if appropriate... */ 689 ustir_start_read(sc); 690 } 691 692 Static void 693 ustir_thread(void *arg) 694 { 695 struct ustir_softc *sc = arg; 696 697 DPRINTFN(20, ("%s: starting polling thread\n", __func__)); 698 699 while (!sc->sc_closing) { 700 if (!sc->sc_rd_readinprogress && !USTIR_BLOCK_RX_DATA(sc)) 701 ustir_periodic(sc); 702 703 if (!sc->sc_closing) { 704 int error; 705 error = tsleep(&sc->sc_thread, PWAIT, 706 "ustir", hz / 10); 707 if (error == EWOULDBLOCK && 708 sc->sc_rd_expectdataticks > 0) 709 /* 710 * After a timeout decrement the tick 711 * counter within which time we expect 712 * data to arrive if we are receiving 713 * data... 714 */ 715 sc->sc_rd_expectdataticks--; 716 } 717 } 718 719 DPRINTFN(20, ("%s: exiting polling thread\n", __func__)); 720 721 sc->sc_thread = NULL; 722 723 wakeup(&sc->sc_closing); 724 725 if (--sc->sc_refcnt < 0) 726 usb_detach_wakeup(USBDEV(sc->sc_dev)); 727 728 kthread_exit(0); 729 } 730 731 Static void 732 ustir_rd_cb(usbd_xfer_handle xfer, usbd_private_handle priv, 733 usbd_status status) 734 { 735 struct ustir_softc *sc = priv; 736 u_int32_t size; 737 738 DPRINTFN(60, ("%s: sc=%p\n", __func__, sc)); 739 740 /* Read is no longer in progress */ 741 sc->sc_rd_readinprogress = 0; 742 743 if (status == USBD_CANCELLED || sc->sc_closing) /* this is normal */ 744 return; 745 if (status) { 746 size = 0; 747 sc->sc_rd_err = 1; 748 749 if (sc->sc_direction == udir_input || 750 sc->sc_direction == udir_idle) { 751 /* 752 * Receive error, probably need to clear error 753 * condition. 754 */ 755 sc->sc_direction = udir_stalled; 756 } 757 } else { 758 usbd_get_xfer_status(xfer, NULL, NULL, &size, NULL); 759 } 760 761 sc->sc_rd_index = 0; 762 sc->sc_rd_count = size; 763 764 DPRINTFN(((size > 0 || sc->sc_rd_err != 0) ? 20 : 60), 765 ("%s: sc=%p size=%u, err=%d\n", __func__, 766 sc, size, sc->sc_rd_err)); 767 768 #ifdef USTIR_DEBUG 769 if (ustirdebug >= 20 && size > 0) 770 ustir_dumpdata(sc->sc_rd_buf, size, __func__); 771 #endif 772 773 if (!deframe_rd_ur(sc)) { 774 if (!deframe_isclear(&sc->sc_framestate) && size == 0 && 775 sc->sc_rd_expectdataticks == 0) { 776 /* 777 * Expected data, but didn't get it 778 * within expected time... 779 */ 780 DPRINTFN(5,("%s: incoming packet timeout\n", 781 __func__)); 782 deframe_clear(&sc->sc_framestate); 783 } else if (size > 0) { 784 /* 785 * If we also received actual data, reset the 786 * data read timeout and wake up the possibly 787 * sleeping thread... 788 */ 789 sc->sc_rd_expectdataticks = 2; 790 wakeup(&sc->sc_thread); 791 } 792 } 793 794 /* 795 * Check if incoming data has stopped, or that we cannot 796 * safely read any more data. In the case of the latter we 797 * must switch to idle so that a write will not block... 798 */ 799 if (sc->sc_direction == udir_input && 800 ((size == 0 && sc->sc_rd_expectdataticks == 0) || 801 USTIR_BLOCK_RX_DATA(sc))) { 802 DPRINTFN(8,("%s: idling on packet timeout, " 803 "complete frame, or no data\n", __func__)); 804 sc->sc_direction = udir_idle; 805 806 /* Wake up for possible output */ 807 wakeup(&sc->sc_wr_buf); 808 selnotify(&sc->sc_wr_sel, 0, 0); 809 } 810 } 811 812 Static usbd_status 813 ustir_start_read(struct ustir_softc *sc) 814 { 815 usbd_status err; 816 817 DPRINTFN(60,("%s: sc=%p, size=%d\n", __func__, sc, 818 sc->sc_params.maxsize)); 819 820 if (sc->sc_dying) 821 return USBD_IOERROR; 822 823 if (USTIR_BLOCK_RX_DATA(sc) || deframe_rd_ur(sc)) { 824 /* 825 * Can't start reading just yet. Since we aren't 826 * going to start a read, have to switch direction to 827 * idle. 828 */ 829 sc->sc_direction = udir_idle; 830 return USBD_NORMAL_COMPLETION; 831 } 832 833 /* Starting a read... */ 834 sc->sc_rd_readinprogress = 1; 835 sc->sc_direction = udir_input; 836 837 if (sc->sc_rd_err) { 838 sc->sc_rd_err = 0; 839 DPRINTFN(0, ("%s: clear stall\n", __func__)); 840 usbd_clear_endpoint_stall(sc->sc_rd_pipe); 841 } 842 843 usbd_setup_xfer(sc->sc_rd_xfer, sc->sc_rd_pipe, sc, sc->sc_rd_buf, 844 sc->sc_params.maxsize, 845 USBD_SHORT_XFER_OK | USBD_NO_COPY, 846 USBD_NO_TIMEOUT, ustir_rd_cb); 847 err = usbd_transfer(sc->sc_rd_xfer); 848 if (err != USBD_IN_PROGRESS) { 849 DPRINTFN(0, ("%s: err=%d\n", __func__, (int)err)); 850 return err; 851 } 852 return USBD_NORMAL_COMPLETION; 853 } 854 855 Static int 856 ustir_activate(device_t self, enum devact act) 857 { 858 struct ustir_softc *sc = device_private(self); 859 int error = 0; 860 861 switch (act) { 862 case DVACT_ACTIVATE: 863 return EOPNOTSUPP; 864 865 case DVACT_DEACTIVATE: 866 sc->sc_dying = 1; 867 if (sc->sc_child != NULL) 868 error = config_deactivate(sc->sc_child); 869 break; 870 } 871 return error; 872 } 873 874 /* ARGSUSED */ 875 Static int 876 ustir_open(void *h, int flag, int mode, 877 struct lwp *l) 878 { 879 struct ustir_softc *sc = h; 880 int error; 881 usbd_status err; 882 883 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 884 885 err = usbd_open_pipe(sc->sc_iface, sc->sc_rd_addr, 0, &sc->sc_rd_pipe); 886 if (err != USBD_NORMAL_COMPLETION) { 887 error = EIO; 888 goto bad1; 889 } 890 err = usbd_open_pipe(sc->sc_iface, sc->sc_wr_addr, 0, &sc->sc_wr_pipe); 891 if (err != USBD_NORMAL_COMPLETION) { 892 error = EIO; 893 goto bad2; 894 } 895 sc->sc_rd_xfer = usbd_alloc_xfer(sc->sc_udev); 896 if (sc->sc_rd_xfer == NULL) { 897 error = ENOMEM; 898 goto bad3; 899 } 900 sc->sc_wr_xfer = usbd_alloc_xfer(sc->sc_udev); 901 if (sc->sc_wr_xfer == NULL) { 902 error = ENOMEM; 903 goto bad4; 904 } 905 sc->sc_rd_buf = usbd_alloc_buffer(sc->sc_rd_xfer, 906 IRDA_MAX_FRAME_SIZE); 907 if (sc->sc_rd_buf == NULL) { 908 error = ENOMEM; 909 goto bad5; 910 } 911 sc->sc_wr_buf = usbd_alloc_buffer(sc->sc_wr_xfer, 912 IRDA_MAX_FRAME_SIZE + STIR_OUTPUT_HEADER_SIZE); 913 if (sc->sc_wr_buf == NULL) { 914 error = ENOMEM; 915 goto bad5; 916 } 917 sc->sc_ur_buf = malloc(IRDA_MAX_FRAME_SIZE, M_USBDEV, M_NOWAIT); 918 if (sc->sc_ur_buf == NULL) { 919 error = ENOMEM; 920 goto bad5; 921 } 922 923 sc->sc_rd_index = sc->sc_rd_count = 0; 924 sc->sc_closing = 0; 925 sc->sc_rd_readinprogress = 0; 926 sc->sc_rd_expectdataticks = 0; 927 sc->sc_ur_framelen = 0; 928 sc->sc_rd_err = 0; 929 sc->sc_wr_stalewrite = 0; 930 sc->sc_speedrec = NULL; 931 sc->sc_direction = udir_idle; 932 sc->sc_params.speed = 0; 933 sc->sc_params.ebofs = 0; 934 sc->sc_params.maxsize = IRDA_MAX_FRAME_SIZE; 935 936 deframe_init(&sc->sc_framestate, &framedef_sir, sc->sc_ur_buf, 937 IRDA_MAX_FRAME_SIZE); 938 939 /* Increment reference for thread */ 940 sc->sc_refcnt++; 941 942 error = kthread_create(PRI_NONE, 0, NULL, ustir_thread, sc, 943 &sc->sc_thread, "%s", device_xname(sc->sc_dev)); 944 if (error) { 945 sc->sc_refcnt--; 946 goto bad5; 947 } 948 949 return 0; 950 951 bad5: 952 usbd_free_xfer(sc->sc_wr_xfer); 953 sc->sc_wr_xfer = NULL; 954 bad4: 955 usbd_free_xfer(sc->sc_rd_xfer); 956 sc->sc_rd_xfer = NULL; 957 bad3: 958 usbd_close_pipe(sc->sc_wr_pipe); 959 sc->sc_wr_pipe = NULL; 960 bad2: 961 usbd_close_pipe(sc->sc_rd_pipe); 962 sc->sc_rd_pipe = NULL; 963 bad1: 964 return error; 965 } 966 967 /* ARGSUSED */ 968 Static int 969 ustir_close(void *h, int flag, int mode, 970 struct lwp *l) 971 { 972 struct ustir_softc *sc = h; 973 974 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 975 976 sc->sc_refcnt++; 977 978 sc->sc_rd_readinprogress = 1; 979 sc->sc_closing = 1; 980 981 wakeup(&sc->sc_thread); 982 983 while (sc->sc_thread != NULL) 984 tsleep(&sc->sc_closing, PWAIT, "usircl", 0); 985 986 if (sc->sc_rd_pipe != NULL) { 987 usbd_abort_pipe(sc->sc_rd_pipe); 988 usbd_close_pipe(sc->sc_rd_pipe); 989 sc->sc_rd_pipe = NULL; 990 } 991 if (sc->sc_wr_pipe != NULL) { 992 usbd_abort_pipe(sc->sc_wr_pipe); 993 usbd_close_pipe(sc->sc_wr_pipe); 994 sc->sc_wr_pipe = NULL; 995 } 996 if (sc->sc_rd_xfer != NULL) { 997 usbd_free_xfer(sc->sc_rd_xfer); 998 sc->sc_rd_xfer = NULL; 999 sc->sc_rd_buf = NULL; 1000 } 1001 if (sc->sc_wr_xfer != NULL) { 1002 usbd_free_xfer(sc->sc_wr_xfer); 1003 sc->sc_wr_xfer = NULL; 1004 sc->sc_wr_buf = NULL; 1005 } 1006 if (sc->sc_ur_buf != NULL) { 1007 free(sc->sc_ur_buf, M_USBDEV); 1008 sc->sc_ur_buf = NULL; 1009 } 1010 1011 if (--sc->sc_refcnt < 0) 1012 usb_detach_wakeup(USBDEV(sc->sc_dev)); 1013 1014 return 0; 1015 } 1016 1017 /* ARGSUSED */ 1018 Static int 1019 ustir_read(void *h, struct uio *uio, int flag) 1020 { 1021 struct ustir_softc *sc = h; 1022 int s; 1023 int error; 1024 u_int uframelen; 1025 1026 DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 1027 1028 if (sc->sc_dying) 1029 return EIO; 1030 1031 #ifdef DIAGNOSTIC 1032 if (sc->sc_rd_buf == NULL) 1033 return EINVAL; 1034 #endif 1035 1036 sc->sc_refcnt++; 1037 1038 if (!sc->sc_rd_readinprogress && !USTIR_BLOCK_RX_DATA(sc)) 1039 /* Possibly wake up polling thread */ 1040 wakeup(&sc->sc_thread); 1041 1042 do { 1043 s = splusb(); 1044 while (sc->sc_ur_framelen == 0) { 1045 DPRINTFN(5,("%s: calling tsleep()\n", __func__)); 1046 error = tsleep(&sc->sc_ur_framelen, PZERO | PCATCH, 1047 "usirrd", 0); 1048 if (sc->sc_dying) 1049 error = EIO; 1050 if (error) { 1051 splx(s); 1052 DPRINTFN(0, ("%s: tsleep() = %d\n", 1053 __func__, error)); 1054 goto ret; 1055 } 1056 } 1057 splx(s); 1058 1059 uframelen = sc->sc_ur_framelen; 1060 DPRINTFN(1,("%s: sc=%p framelen=%u, hdr=0x%02x\n", 1061 __func__, sc, uframelen, sc->sc_ur_buf[0])); 1062 if (uframelen > uio->uio_resid) 1063 error = EINVAL; 1064 else 1065 error = uiomove(sc->sc_ur_buf, uframelen, uio); 1066 sc->sc_ur_framelen = 0; 1067 1068 if (!deframe_rd_ur(sc) && uframelen > 0) { 1069 /* 1070 * Need to wait for another read to obtain a 1071 * complete frame... If we also obtained 1072 * actual data, wake up the possibly sleeping 1073 * thread immediately... 1074 */ 1075 wakeup(&sc->sc_thread); 1076 } 1077 } while (uframelen == 0); 1078 1079 DPRINTFN(1,("%s: return %d\n", __func__, error)); 1080 1081 ret: 1082 if (--sc->sc_refcnt < 0) 1083 usb_detach_wakeup(USBDEV(sc->sc_dev)); 1084 return error; 1085 } 1086 1087 /* ARGSUSED */ 1088 Static int 1089 ustir_write(void *h, struct uio *uio, int flag) 1090 { 1091 struct ustir_softc *sc = h; 1092 usbd_status err; 1093 u_int32_t wrlen; 1094 int error, sirlength; 1095 u_int8_t *wrbuf; 1096 int s; 1097 1098 DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 1099 1100 if (sc->sc_dying) 1101 return EIO; 1102 1103 #ifdef DIAGNOSTIC 1104 if (sc->sc_wr_buf == NULL) 1105 return EINVAL; 1106 #endif 1107 1108 wrlen = uio->uio_resid; 1109 if (wrlen > sc->sc_params.maxsize) 1110 return EINVAL; 1111 1112 sc->sc_refcnt++; 1113 1114 if (!USTIR_BLOCK_RX_DATA(sc)) { 1115 /* 1116 * If reads are not blocked, determine what action we 1117 * should potentially take... 1118 */ 1119 if (sc->sc_direction == udir_output) { 1120 /* 1121 * If the last operation was an output, wait for the 1122 * polling thread to check for incoming data. 1123 */ 1124 sc->sc_wr_stalewrite = 1; 1125 wakeup(&sc->sc_thread); 1126 } else if (!sc->sc_rd_readinprogress && 1127 (sc->sc_direction == udir_idle || 1128 sc->sc_direction == udir_input)) { 1129 /* If idle, check for input before outputting */ 1130 ustir_start_read(sc); 1131 } 1132 } 1133 1134 s = splusb(); 1135 while (sc->sc_wr_stalewrite || 1136 (sc->sc_direction != udir_output && 1137 sc->sc_direction != udir_idle)) { 1138 DPRINTFN(5, ("%s: sc=%p stalewrite=%d direction=%d, " 1139 "calling tsleep()\n", __func__, 1140 sc, sc->sc_wr_stalewrite, sc->sc_direction)); 1141 error = tsleep(&sc->sc_wr_buf, PZERO | PCATCH, 1142 "usirwr", 0); 1143 if (sc->sc_dying) 1144 error = EIO; 1145 if (error) { 1146 splx(s); 1147 DPRINTFN(0, ("%s: tsleep() = %d\n", __func__, 1148 error)); 1149 goto ret; 1150 } 1151 } 1152 splx(s); 1153 1154 wrbuf = sc->sc_wr_buf; 1155 1156 /* Build header */ 1157 wrbuf[0] = STIR_OUTPUT_HEADER_BYTE0; 1158 wrbuf[1] = STIR_OUTPUT_HEADER_BYTE1; 1159 1160 sirlength = irda_sir_frame(&wrbuf[STIR_OUTPUT_HEADER_SIZE], 1161 MAX_USTIR_OUTPUT_FRAME - 1162 STIR_OUTPUT_HEADER_SIZE, 1163 uio, sc->sc_params.ebofs); 1164 if (sirlength < 0) { 1165 error = -sirlength; 1166 } else { 1167 u_int32_t btlen; 1168 1169 DPRINTFN(1, ("%s: transfer %u bytes\n", __func__, 1170 (unsigned int)wrlen)); 1171 1172 wrbuf[2] = sirlength & 0xff; 1173 wrbuf[3] = (sirlength >> 8) & 0xff; 1174 1175 btlen = STIR_OUTPUT_HEADER_SIZE + sirlength; 1176 1177 sc->sc_direction = udir_output; 1178 1179 #ifdef USTIR_DEBUG 1180 if (ustirdebug >= 20) 1181 ustir_dumpdata(wrbuf, btlen, __func__); 1182 #endif 1183 1184 err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, 1185 USBD_FORCE_SHORT_XFER | USBD_NO_COPY, 1186 USTIR_WR_TIMEOUT, 1187 wrbuf, &btlen, "ustiwr"); 1188 DPRINTFN(2, ("%s: err=%d\n", __func__, err)); 1189 if (err != USBD_NORMAL_COMPLETION) { 1190 if (err == USBD_INTERRUPTED) 1191 error = EINTR; 1192 else if (err == USBD_TIMEOUT) 1193 error = ETIMEDOUT; 1194 else 1195 error = EIO; 1196 } else { 1197 error = 0; 1198 } 1199 } 1200 1201 ret: 1202 if (--sc->sc_refcnt < 0) 1203 usb_detach_wakeup(USBDEV(sc->sc_dev)); 1204 1205 DPRINTFN(1,("%s: sc=%p done\n", __func__, sc)); 1206 return error; 1207 } 1208 1209 Static int 1210 ustir_poll(void *h, int events, struct lwp *l) 1211 { 1212 struct ustir_softc *sc = h; 1213 int revents = 0; 1214 1215 DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 1216 1217 if (events & (POLLOUT | POLLWRNORM)) { 1218 if (sc->sc_direction != udir_input) { 1219 revents |= events & (POLLOUT | POLLWRNORM); 1220 } else { 1221 DPRINTFN(2,("%s: recording write select\n", 1222 __func__)); 1223 selrecord(l, &sc->sc_wr_sel); 1224 } 1225 } 1226 1227 if (events & (POLLIN | POLLRDNORM)) { 1228 if (sc->sc_ur_framelen != 0) { 1229 DPRINTFN(2,("%s: have data\n", __func__)); 1230 revents |= events & (POLLIN | POLLRDNORM); 1231 } else { 1232 DPRINTFN(2,("%s: recording read select\n", 1233 __func__)); 1234 selrecord(l, &sc->sc_rd_sel); 1235 } 1236 } 1237 1238 return revents; 1239 } 1240 1241 static void 1242 filt_ustirrdetach(struct knote *kn) 1243 { 1244 struct ustir_softc *sc = kn->kn_hook; 1245 int s; 1246 1247 s = splusb(); 1248 SLIST_REMOVE(&sc->sc_rd_sel.sel_klist, kn, knote, kn_selnext); 1249 splx(s); 1250 } 1251 1252 /* ARGSUSED */ 1253 static int 1254 filt_ustirread(struct knote *kn, long hint) 1255 { 1256 struct ustir_softc *sc = kn->kn_hook; 1257 1258 kn->kn_data = sc->sc_ur_framelen; 1259 return (kn->kn_data > 0); 1260 } 1261 1262 static void 1263 filt_ustirwdetach(struct knote *kn) 1264 { 1265 struct ustir_softc *sc = kn->kn_hook; 1266 int s; 1267 1268 s = splusb(); 1269 SLIST_REMOVE(&sc->sc_wr_sel.sel_klist, kn, knote, kn_selnext); 1270 splx(s); 1271 } 1272 1273 /* ARGSUSED */ 1274 static int 1275 filt_ustirwrite(struct knote *kn, long hint) 1276 { 1277 struct ustir_softc *sc = kn->kn_hook; 1278 1279 kn->kn_data = 0; 1280 return (sc->sc_direction != udir_input); 1281 } 1282 1283 static const struct filterops ustirread_filtops = 1284 { 1, NULL, filt_ustirrdetach, filt_ustirread }; 1285 static const struct filterops ustirwrite_filtops = 1286 { 1, NULL, filt_ustirwdetach, filt_ustirwrite }; 1287 1288 Static int 1289 ustir_kqfilter(void *h, struct knote *kn) 1290 { 1291 struct ustir_softc *sc = h; 1292 struct klist *klist; 1293 int s; 1294 1295 switch (kn->kn_filter) { 1296 case EVFILT_READ: 1297 klist = &sc->sc_rd_sel.sel_klist; 1298 kn->kn_fop = &ustirread_filtops; 1299 break; 1300 case EVFILT_WRITE: 1301 klist = &sc->sc_wr_sel.sel_klist; 1302 kn->kn_fop = &ustirwrite_filtops; 1303 break; 1304 default: 1305 return (EINVAL); 1306 } 1307 1308 kn->kn_hook = sc; 1309 1310 s = splusb(); 1311 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 1312 splx(s); 1313 1314 return (0); 1315 } 1316 1317 #ifdef USTIR_DEBUG_IOCTLS 1318 Static int ustir_ioctl(void *h, u_long cmd, void *addr, int flag, struct lwp *l) 1319 { 1320 struct ustir_softc *sc = h; 1321 int error; 1322 unsigned int regnum; 1323 usbd_status err; 1324 u_int8_t regdata; 1325 1326 if (sc->sc_dying) 1327 return EIO; 1328 1329 sc->sc_refcnt++; 1330 1331 error = 0; 1332 switch (cmd) { 1333 case USTIR_READ_REGISTER: 1334 regnum = *(unsigned int *)addr; 1335 1336 if (regnum > STIR_MAX_REG) { 1337 error = EINVAL; 1338 break; 1339 } 1340 1341 err = ustir_read_reg(sc, regnum, ®data); 1342 1343 DPRINTFN(10, ("%s: regget(%u) = 0x%x\n", __func__, 1344 regnum, (unsigned int)regdata)); 1345 1346 *(unsigned int *)addr = regdata; 1347 if (err != USBD_NORMAL_COMPLETION) { 1348 printf("%s: register read failed: %s\n", 1349 USBDEVNAME(sc->sc_dev), 1350 usbd_errstr(err)); 1351 error = EIO; 1352 } 1353 break; 1354 1355 case USTIR_WRITE_REGISTER: 1356 regnum = *(unsigned int *)addr; 1357 regdata = (regnum >> 8) & 0xff; 1358 regnum = regnum & 0xff; 1359 1360 if (regnum > STIR_MAX_REG) { 1361 error = EINVAL; 1362 break; 1363 } 1364 1365 DPRINTFN(10, ("%s: regset(%u, 0x%x)\n", __func__, 1366 regnum, (unsigned int)regdata)); 1367 1368 err = ustir_write_reg(sc, regnum, regdata); 1369 if (err != USBD_NORMAL_COMPLETION) { 1370 printf("%s: register write failed: %s\n", 1371 USBDEVNAME(sc->sc_dev), 1372 usbd_errstr(err)); 1373 error = EIO; 1374 } 1375 break; 1376 1377 case USTIR_DEBUG_LEVEL: 1378 #ifdef USTIR_DEBUG 1379 ustirdebug = *(int *)addr; 1380 #endif 1381 break; 1382 1383 case USTIR_DEBUG_OPERATION: 1384 break; 1385 1386 default: 1387 error = EINVAL; 1388 break; 1389 } 1390 1391 if (--sc->sc_refcnt < 0) 1392 usb_detach_wakeup(USBDEV(sc->sc_dev)); 1393 1394 return error; 1395 } 1396 #endif 1397 1398 Static int 1399 ustir_set_params(void *h, struct irda_params *p) 1400 { 1401 struct ustir_softc *sc = h; 1402 struct ustir_speedrec const *speedblk; 1403 int i; 1404 1405 DPRINTFN(0, ("%s: sc=%p, speed=%d ebofs=%d maxsize=%d\n", __func__, 1406 sc, p->speed, p->ebofs, p->maxsize)); 1407 1408 if (sc->sc_dying) 1409 return EIO; 1410 1411 speedblk = NULL; 1412 1413 if (sc->sc_speedrec == NULL || p->speed != sc->sc_speedrec->speed) { 1414 /* find speed */ 1415 for (i = 0; i < USTIR_NSPEEDS; i++) { 1416 if (ustir_speeds[i].speed == p->speed) { 1417 speedblk = &ustir_speeds[i]; 1418 goto found2; 1419 } 1420 } 1421 /* no good value found */ 1422 return EINVAL; 1423 found2: 1424 ; 1425 } 1426 if (p->maxsize != sc->sc_params.maxsize) { 1427 if (p->maxsize > IRDA_MAX_FRAME_SIZE) 1428 return EINVAL; 1429 sc->sc_params.maxsize = p->maxsize; 1430 } 1431 1432 sc->sc_params = *p; 1433 1434 if (speedblk != NULL) { 1435 usbd_status err; 1436 u_int8_t regmode; 1437 u_int8_t regbrate; 1438 1439 sc->sc_speedrec = speedblk; 1440 1441 regmode = STIR_BRMODE_MODEREG(speedblk->config); 1442 regbrate = STIR_BRMODE_BRATEREG(speedblk->config); 1443 1444 /* 1445 * FFSPRST must be set to enable the FIFO. 1446 */ 1447 regmode |= STIR_RMODE_FFSPRST; 1448 1449 DPRINTFN(10, ("%s: setting BRATE = %x\n", __func__, 1450 (unsigned int)regbrate)); 1451 err = ustir_write_reg(sc, STIR_REG_BRATE, regbrate); 1452 if (err == USBD_NORMAL_COMPLETION) { 1453 DPRINTFN(10, ("%s: setting MODE = %x\n", __func__, 1454 (unsigned int)regmode)); 1455 err = ustir_write_reg(sc, STIR_REG_MODE, regmode); 1456 } 1457 if (err != USBD_NORMAL_COMPLETION) { 1458 DPRINTFN(10, ("%s: error setting register: %s\n", 1459 __func__, usbd_errstr(err))); 1460 return EIO; 1461 } 1462 } 1463 1464 return 0; 1465 } 1466 1467 Static int 1468 ustir_get_speeds(void *h, int *speeds) 1469 { 1470 struct ustir_softc *sc = h; 1471 1472 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 1473 1474 if (sc->sc_dying) 1475 return EIO; 1476 1477 /* All these speeds are supported */ 1478 *speeds = IRDA_SPEED_4000000 | 1479 IRDA_SPEED_1152000 | 1480 IRDA_SPEED_576000 | 1481 IRDA_SPEED_115200 | 1482 IRDA_SPEED_57600 | 1483 IRDA_SPEED_38400 | 1484 IRDA_SPEED_19200 | 1485 IRDA_SPEED_9600 | 1486 IRDA_SPEED_2400; 1487 1488 return 0; 1489 } 1490 1491 Static int 1492 ustir_get_turnarounds(void *h, int *turnarounds) 1493 { 1494 struct ustir_softc *sc = h; 1495 1496 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 1497 1498 if (sc->sc_dying) 1499 return EIO; 1500 1501 /* 1502 * Documentation is on the light side with respect to 1503 * turnaround time for this device. 1504 */ 1505 *turnarounds = IRDA_TURNT_10000; 1506 1507 return 0; 1508 } 1509