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