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