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