1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * FTDI FT232R USB UART device-specific driver 29 * 30 * May work on the (many) devices based on earlier versions of the chip. 31 */ 32 33 #include <sys/types.h> 34 #include <sys/param.h> 35 #include <sys/conf.h> 36 #include <sys/stream.h> 37 #include <sys/strsun.h> 38 #include <sys/termio.h> 39 #include <sys/termiox.h> 40 #include <sys/ddi.h> 41 #include <sys/sunddi.h> 42 43 #define USBDRV_MAJOR_VER 2 44 #define USBDRV_MINOR_VER 0 45 46 #include <sys/usb/usba.h> 47 #include <sys/usb/usba/usba_types.h> 48 #include <sys/usb/usba/usba_impl.h> 49 50 #include <sys/usb/clients/usbser/usbser_dsdi.h> 51 #include <sys/usb/clients/usbser/usbftdi/uftdi_var.h> 52 #include <sys/usb/clients/usbser/usbftdi/uftdi_reg.h> 53 54 #include <sys/usb/usbdevs.h> 55 56 /* 57 * DSD operations 58 */ 59 static int uftdi_attach(ds_attach_info_t *); 60 static void uftdi_detach(ds_hdl_t); 61 static int uftdi_register_cb(ds_hdl_t, uint_t, ds_cb_t *); 62 static void uftdi_unregister_cb(ds_hdl_t, uint_t); 63 static int uftdi_open_port(ds_hdl_t, uint_t); 64 static int uftdi_close_port(ds_hdl_t, uint_t); 65 66 /* power management */ 67 static int uftdi_usb_power(ds_hdl_t, int, int, int *); 68 static int uftdi_suspend(ds_hdl_t); 69 static int uftdi_resume(ds_hdl_t); 70 static int uftdi_disconnect(ds_hdl_t); 71 static int uftdi_reconnect(ds_hdl_t); 72 73 /* standard UART operations */ 74 static int uftdi_set_port_params(ds_hdl_t, uint_t, ds_port_params_t *); 75 static int uftdi_set_modem_ctl(ds_hdl_t, uint_t, int, int); 76 static int uftdi_get_modem_ctl(ds_hdl_t, uint_t, int, int *); 77 static int uftdi_break_ctl(ds_hdl_t, uint_t, int); 78 79 /* data xfer */ 80 static int uftdi_tx(ds_hdl_t, uint_t, mblk_t *); 81 static mblk_t *uftdi_rx(ds_hdl_t, uint_t); 82 static void uftdi_stop(ds_hdl_t, uint_t, int); 83 static void uftdi_start(ds_hdl_t, uint_t, int); 84 static int uftdi_fifo_flush(ds_hdl_t, uint_t, int); 85 static int uftdi_fifo_drain(ds_hdl_t, uint_t, int); 86 87 /* polled I/O support */ 88 static usb_pipe_handle_t uftdi_out_pipe(ds_hdl_t, uint_t); 89 static usb_pipe_handle_t uftdi_in_pipe(ds_hdl_t, uint_t); 90 91 /* 92 * Sub-routines 93 */ 94 95 /* configuration routines */ 96 static void uftdi_cleanup(uftdi_state_t *, int); 97 static int uftdi_dev_attach(uftdi_state_t *); 98 static int uftdi_open_hw_port(uftdi_state_t *, int, int); 99 100 /* hotplug */ 101 static int uftdi_restore_device_state(uftdi_state_t *); 102 static int uftdi_restore_port_state(uftdi_state_t *, int); 103 104 /* power management */ 105 static int uftdi_create_pm_components(uftdi_state_t *); 106 static void uftdi_destroy_pm_components(uftdi_state_t *); 107 static int uftdi_pm_set_busy(uftdi_state_t *); 108 static void uftdi_pm_set_idle(uftdi_state_t *); 109 static int uftdi_pwrlvl0(uftdi_state_t *); 110 static int uftdi_pwrlvl1(uftdi_state_t *); 111 static int uftdi_pwrlvl2(uftdi_state_t *); 112 static int uftdi_pwrlvl3(uftdi_state_t *); 113 114 /* pipe operations */ 115 static int uftdi_open_pipes(uftdi_state_t *); 116 static void uftdi_close_pipes(uftdi_state_t *); 117 static void uftdi_disconnect_pipes(uftdi_state_t *); 118 static int uftdi_reconnect_pipes(uftdi_state_t *); 119 120 /* pipe callbacks */ 121 static void uftdi_bulkin_cb(usb_pipe_handle_t, usb_bulk_req_t *); 122 static void uftdi_bulkout_cb(usb_pipe_handle_t, usb_bulk_req_t *); 123 124 /* data transfer routines */ 125 static int uftdi_rx_start(uftdi_state_t *); 126 static void uftdi_tx_start(uftdi_state_t *, int *); 127 static int uftdi_send_data(uftdi_state_t *, mblk_t *); 128 static int uftdi_wait_tx_drain(uftdi_state_t *, int); 129 130 /* vendor-specific commands */ 131 static int uftdi_cmd_vendor_write0(uftdi_state_t *, 132 uint16_t, uint16_t, uint16_t); 133 134 /* misc */ 135 static void uftdi_put_tail(mblk_t **, mblk_t *); 136 static void uftdi_put_head(mblk_t **, mblk_t *); 137 138 139 /* 140 * DSD ops structure 141 */ 142 ds_ops_t uftdi_ds_ops = { 143 DS_OPS_VERSION, 144 uftdi_attach, 145 uftdi_detach, 146 uftdi_register_cb, 147 uftdi_unregister_cb, 148 uftdi_open_port, 149 uftdi_close_port, 150 uftdi_usb_power, 151 uftdi_suspend, 152 uftdi_resume, 153 uftdi_disconnect, 154 uftdi_reconnect, 155 uftdi_set_port_params, 156 uftdi_set_modem_ctl, 157 uftdi_get_modem_ctl, 158 uftdi_break_ctl, 159 NULL, /* no loopback support */ 160 uftdi_tx, 161 uftdi_rx, 162 uftdi_stop, 163 uftdi_start, 164 uftdi_fifo_flush, 165 uftdi_fifo_drain, 166 uftdi_out_pipe, 167 uftdi_in_pipe 168 }; 169 170 /* debug support */ 171 static uint_t uftdi_errlevel = USB_LOG_L4; 172 static uint_t uftdi_errmask = DPRINT_MASK_ALL; 173 static uint_t uftdi_instance_debug = (uint_t)-1; 174 static uint_t uftdi_attach_unrecognized = B_FALSE; 175 176 /* 177 * ds_attach 178 */ 179 static int 180 uftdi_attach(ds_attach_info_t *aip) 181 { 182 uftdi_state_t *uf; 183 usb_dev_descr_t *dd; 184 int recognized; 185 186 uf = kmem_zalloc(sizeof (*uf), KM_SLEEP); 187 uf->uf_dip = aip->ai_dip; 188 uf->uf_usb_events = aip->ai_usb_events; 189 *aip->ai_hdl = (ds_hdl_t)uf; 190 191 /* only one port */ 192 *aip->ai_port_cnt = 1; 193 194 if (usb_client_attach(uf->uf_dip, USBDRV_VERSION, 0) != USB_SUCCESS) { 195 uftdi_cleanup(uf, 1); 196 return (USB_FAILURE); 197 } 198 199 if (usb_get_dev_data(uf->uf_dip, 200 &uf->uf_dev_data, USB_PARSE_LVL_IF, 0) != USB_SUCCESS) { 201 uftdi_cleanup(uf, 2); 202 return (USB_FAILURE); 203 } 204 205 mutex_init(&uf->uf_lock, NULL, MUTEX_DRIVER, 206 uf->uf_dev_data->dev_iblock_cookie); 207 208 cv_init(&uf->uf_tx_cv, NULL, CV_DRIVER, NULL); 209 210 uf->uf_lh = usb_alloc_log_hdl(uf->uf_dip, "uftdi", 211 &uftdi_errlevel, &uftdi_errmask, &uftdi_instance_debug, 0); 212 213 /* 214 * This device and its clones has numerous physical instantiations. 215 */ 216 recognized = B_TRUE; 217 dd = uf->uf_dev_data->dev_descr; 218 switch (dd->idVendor) { 219 case USB_VENDOR_FTDI: 220 switch (dd->idProduct) { 221 case USB_PRODUCT_FTDI_SERIAL_8U232AM: 222 case USB_PRODUCT_FTDI_SEMC_DSS20: 223 case USB_PRODUCT_FTDI_CFA_631: 224 case USB_PRODUCT_FTDI_CFA_632: 225 case USB_PRODUCT_FTDI_CFA_633: 226 case USB_PRODUCT_FTDI_CFA_634: 227 case USB_PRODUCT_FTDI_CFA_635: 228 case USB_PRODUCT_FTDI_USBSERIAL: 229 case USB_PRODUCT_FTDI_MX2_3: 230 case USB_PRODUCT_FTDI_MX4_5: 231 case USB_PRODUCT_FTDI_LK202: 232 case USB_PRODUCT_FTDI_LK204: 233 case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13M: 234 case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13S: 235 case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13U: 236 case USB_PRODUCT_FTDI_EISCOU: 237 case USB_PRODUCT_FTDI_UOPTBR: 238 case USB_PRODUCT_FTDI_EMCU2D: 239 case USB_PRODUCT_FTDI_PCMSFU: 240 case USB_PRODUCT_FTDI_EMCU2H: 241 break; 242 default: 243 recognized = B_FALSE; 244 break; 245 } 246 break; 247 case USB_VENDOR_SIIG2: 248 switch (dd->idProduct) { 249 case USB_PRODUCT_SIIG2_US2308: 250 break; 251 default: 252 recognized = B_FALSE; 253 break; 254 } 255 break; 256 case USB_VENDOR_INTREPIDCS: 257 switch (dd->idProduct) { 258 case USB_PRODUCT_INTREPIDCS_VALUECAN: 259 case USB_PRODUCT_INTREPIDCS_NEOVI: 260 break; 261 default: 262 recognized = B_FALSE; 263 break; 264 } 265 break; 266 case USB_VENDOR_BBELECTRONICS: 267 switch (dd->idProduct) { 268 case USB_PRODUCT_BBELECTRONICS_USOTL4: 269 break; 270 default: 271 recognized = B_FALSE; 272 break; 273 } 274 break; 275 case USB_VENDOR_MELCO: 276 switch (dd->idProduct) { 277 case USB_PRODUCT_MELCO_PCOPRS1: 278 break; 279 default: 280 recognized = B_FALSE; 281 break; 282 } 283 break; 284 default: 285 recognized = B_FALSE; 286 break; 287 } 288 289 /* 290 * Set 'uftdi_attach_unrecognized' to non-zero to 291 * experiment with newer devices .. 292 */ 293 if (!recognized && !uftdi_attach_unrecognized) { 294 uftdi_cleanup(uf, 3); 295 return (USB_FAILURE); 296 } 297 298 USB_DPRINTF_L3(DPRINT_ATTACH, uf->uf_lh, 299 "uftdi: matched vendor 0x%x product 0x%x", 300 dd->idVendor, dd->idProduct); 301 302 uf->uf_def_ph = uf->uf_dev_data->dev_default_ph; 303 304 mutex_enter(&uf->uf_lock); 305 uf->uf_dev_state = USB_DEV_ONLINE; 306 uf->uf_port_state = UFTDI_PORT_CLOSED; 307 mutex_exit(&uf->uf_lock); 308 309 if (uftdi_create_pm_components(uf) != USB_SUCCESS) { 310 uftdi_cleanup(uf, 3); 311 return (USB_FAILURE); 312 } 313 314 if (usb_register_event_cbs(uf->uf_dip, 315 uf->uf_usb_events, 0) != USB_SUCCESS) { 316 uftdi_cleanup(uf, 4); 317 return (USB_FAILURE); 318 } 319 320 if (usb_pipe_get_max_bulk_transfer_size(uf->uf_dip, 321 &uf->uf_xfer_sz) != USB_SUCCESS) { 322 uftdi_cleanup(uf, 5); 323 return (USB_FAILURE); 324 } 325 326 /* 327 * TODO: modern ftdi devices have deeper (and asymmetric) 328 * fifos than this minimal 64 bytes .. but how to tell 329 * -safely- ? 330 */ 331 332 #define FTDI_MAX_XFERSIZE 64 333 334 if (uf->uf_xfer_sz > FTDI_MAX_XFERSIZE) 335 uf->uf_xfer_sz = FTDI_MAX_XFERSIZE; 336 337 if (uftdi_dev_attach(uf) != USB_SUCCESS) { 338 uftdi_cleanup(uf, 5); 339 return (USB_FAILURE); 340 } 341 342 return (USB_SUCCESS); 343 } 344 345 #define FTDI_CLEANUP_LEVEL_MAX 6 346 347 /* 348 * ds_detach 349 */ 350 static void 351 uftdi_detach(ds_hdl_t hdl) 352 { 353 uftdi_cleanup((uftdi_state_t *)hdl, FTDI_CLEANUP_LEVEL_MAX); 354 } 355 356 357 /* 358 * ds_register_cb 359 */ 360 /*ARGSUSED*/ 361 static int 362 uftdi_register_cb(ds_hdl_t hdl, uint_t portno, ds_cb_t *cb) 363 { 364 uftdi_state_t *uf = (uftdi_state_t *)hdl; 365 366 uf->uf_cb = *cb; 367 return (USB_SUCCESS); 368 } 369 370 371 /* 372 * ds_unregister_cb 373 */ 374 /*ARGSUSED*/ 375 static void 376 uftdi_unregister_cb(ds_hdl_t hdl, uint_t portno) 377 { 378 uftdi_state_t *uf = (uftdi_state_t *)hdl; 379 380 bzero(&uf->uf_cb, sizeof (uf->uf_cb)); 381 } 382 383 384 /* 385 * ds_open_port 386 */ 387 /*ARGSUSED*/ 388 static int 389 uftdi_open_port(ds_hdl_t hdl, uint_t portno) 390 { 391 uftdi_state_t *uf = (uftdi_state_t *)hdl; 392 int rval; 393 394 USB_DPRINTF_L4(DPRINT_OPEN, uf->uf_lh, "uftdi_open_port %d", portno); 395 396 mutex_enter(&uf->uf_lock); 397 if (uf->uf_dev_state == USB_DEV_DISCONNECTED || 398 uf->uf_port_state != UFTDI_PORT_CLOSED) { 399 mutex_exit(&uf->uf_lock); 400 return (USB_FAILURE); 401 } 402 mutex_exit(&uf->uf_lock); 403 404 if ((rval = uftdi_pm_set_busy(uf)) != USB_SUCCESS) 405 return (rval); 406 407 /* initialize hardware serial port */ 408 rval = uftdi_open_hw_port(uf, portno, 0); 409 410 if (rval == USB_SUCCESS) { 411 mutex_enter(&uf->uf_lock); 412 413 /* start to receive data */ 414 if (uftdi_rx_start(uf) != USB_SUCCESS) { 415 mutex_exit(&uf->uf_lock); 416 return (USB_FAILURE); 417 } 418 uf->uf_port_state = UFTDI_PORT_OPEN; 419 mutex_exit(&uf->uf_lock); 420 } else 421 uftdi_pm_set_idle(uf); 422 423 return (rval); 424 } 425 426 427 /* 428 * ds_close_port 429 */ 430 /*ARGSUSED*/ 431 static int 432 uftdi_close_port(ds_hdl_t hdl, uint_t portno) 433 { 434 uftdi_state_t *uf = (uftdi_state_t *)hdl; 435 436 USB_DPRINTF_L4(DPRINT_CLOSE, uf->uf_lh, "uftdi_close_port %d", portno); 437 438 mutex_enter(&uf->uf_lock); 439 440 /* free resources and finalize state */ 441 freemsg(uf->uf_rx_mp); 442 uf->uf_rx_mp = NULL; 443 444 freemsg(uf->uf_tx_mp); 445 uf->uf_tx_mp = NULL; 446 447 uf->uf_port_state = UFTDI_PORT_CLOSED; 448 mutex_exit(&uf->uf_lock); 449 450 uftdi_pm_set_idle(uf); 451 452 return (USB_SUCCESS); 453 } 454 455 456 /* 457 * ds_usb_power 458 */ 459 /*ARGSUSED*/ 460 static int 461 uftdi_usb_power(ds_hdl_t hdl, int comp, int level, int *new_state) 462 { 463 uftdi_state_t *uf = (uftdi_state_t *)hdl; 464 uftdi_pm_t *pm = uf->uf_pm; 465 int rval; 466 467 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_usb_power"); 468 469 if (!pm) 470 return (USB_FAILURE); 471 472 mutex_enter(&uf->uf_lock); 473 474 /* 475 * check if we are transitioning to a legal power level 476 */ 477 if (USB_DEV_PWRSTATE_OK(pm->pm_pwr_states, level)) { 478 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, "uftdi_usb_power: " 479 "illegal power level %d, pwr_states=0x%x", 480 level, pm->pm_pwr_states); 481 mutex_exit(&uf->uf_lock); 482 return (USB_FAILURE); 483 } 484 485 /* 486 * if we are about to raise power and asked to lower power, fail 487 */ 488 if (pm->pm_raise_power && (level < (int)pm->pm_cur_power)) { 489 mutex_exit(&uf->uf_lock); 490 return (USB_FAILURE); 491 } 492 493 switch (level) { 494 case USB_DEV_OS_PWR_OFF: 495 rval = uftdi_pwrlvl0(uf); 496 break; 497 case USB_DEV_OS_PWR_1: 498 rval = uftdi_pwrlvl1(uf); 499 break; 500 case USB_DEV_OS_PWR_2: 501 rval = uftdi_pwrlvl2(uf); 502 break; 503 case USB_DEV_OS_FULL_PWR: 504 rval = uftdi_pwrlvl3(uf); 505 /* 506 * If usbser dev_state is DISCONNECTED or SUSPENDED, it shows 507 * that the usb serial device is disconnected/suspended while it 508 * is under power down state, now the device is powered up 509 * before it is reconnected/resumed. xxx_pwrlvl3() will set dev 510 * state to ONLINE, we need to set the dev state back to 511 * DISCONNECTED/SUSPENDED. 512 */ 513 if (rval == USB_SUCCESS && 514 (*new_state == USB_DEV_DISCONNECTED || 515 *new_state == USB_DEV_SUSPENDED)) 516 uf->uf_dev_state = *new_state; 517 break; 518 default: 519 ASSERT(0); /* cannot happen */ 520 } 521 522 *new_state = uf->uf_dev_state; 523 mutex_exit(&uf->uf_lock); 524 525 return (rval); 526 } 527 528 529 /* 530 * ds_suspend 531 */ 532 static int 533 uftdi_suspend(ds_hdl_t hdl) 534 { 535 uftdi_state_t *uf = (uftdi_state_t *)hdl; 536 int state = USB_DEV_SUSPENDED; 537 538 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_suspend"); 539 540 /* 541 * If the device is suspended while it is under PWRED_DOWN state, we 542 * need to keep the PWRED_DOWN state so that it could be powered up 543 * later. In the mean while, usbser dev state will be changed to 544 * SUSPENDED state. 545 */ 546 mutex_enter(&uf->uf_lock); 547 if (uf->uf_dev_state != USB_DEV_PWRED_DOWN) 548 uf->uf_dev_state = USB_DEV_SUSPENDED; 549 mutex_exit(&uf->uf_lock); 550 551 uftdi_disconnect_pipes(uf); 552 return (state); 553 } 554 555 556 /* 557 * ds_resume 558 */ 559 static int 560 uftdi_resume(ds_hdl_t hdl) 561 { 562 uftdi_state_t *uf = (uftdi_state_t *)hdl; 563 int current_state; 564 int rval; 565 566 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_resume"); 567 568 mutex_enter(&uf->uf_lock); 569 current_state = uf->uf_dev_state; 570 mutex_exit(&uf->uf_lock); 571 572 if (current_state == USB_DEV_ONLINE) 573 rval = USB_SUCCESS; 574 else 575 rval = uftdi_restore_device_state(uf); 576 return (rval); 577 } 578 579 580 /* 581 * ds_disconnect 582 */ 583 static int 584 uftdi_disconnect(ds_hdl_t hdl) 585 { 586 uftdi_state_t *uf = (uftdi_state_t *)hdl; 587 int state = USB_DEV_DISCONNECTED; 588 589 USB_DPRINTF_L4(DPRINT_HOTPLUG, uf->uf_lh, "uftdi_disconnect"); 590 591 /* 592 * If the device is disconnected while it is under PWRED_DOWN state, we 593 * need to keep the PWRED_DOWN state so that it could be powered up 594 * later. In the mean while, usbser dev state will be changed to 595 * DISCONNECTED state. 596 */ 597 mutex_enter(&uf->uf_lock); 598 if (uf->uf_dev_state != USB_DEV_PWRED_DOWN) 599 uf->uf_dev_state = USB_DEV_DISCONNECTED; 600 mutex_exit(&uf->uf_lock); 601 602 uftdi_disconnect_pipes(uf); 603 return (state); 604 } 605 606 607 /* 608 * ds_reconnect 609 */ 610 static int 611 uftdi_reconnect(ds_hdl_t hdl) 612 { 613 uftdi_state_t *uf = (uftdi_state_t *)hdl; 614 615 USB_DPRINTF_L4(DPRINT_HOTPLUG, uf->uf_lh, "uftdi_reconnect"); 616 return (uftdi_restore_device_state(uf)); 617 } 618 619 /* translate parameters into device-specific bits */ 620 621 static int 622 uftdi_param2regs(uftdi_state_t *uf, ds_port_params_t *tp, uftdi_regs_t *ur) 623 { 624 ds_port_param_entry_t *pe; 625 int i; 626 627 ur->ur_data = 0; 628 ur->ur_flowval = 0; 629 ur->ur_flowidx = FTDI_SIO_DISABLE_FLOW_CTRL << 8; 630 631 for (i = 0, pe = tp->tp_entries; i < tp->tp_cnt; i++, pe++) { 632 switch (pe->param) { 633 case DS_PARAM_BAUD: 634 switch (pe->val.ui) { 635 case B300: 636 ur->ur_baud = ftdi_8u232am_b300; 637 break; 638 case B600: 639 ur->ur_baud = ftdi_8u232am_b600; 640 break; 641 case B1200: 642 ur->ur_baud = ftdi_8u232am_b1200; 643 break; 644 case B2400: 645 ur->ur_baud = ftdi_8u232am_b2400; 646 break; 647 case B4800: 648 ur->ur_baud = ftdi_8u232am_b4800; 649 break; 650 case B9600: 651 ur->ur_baud = ftdi_8u232am_b9600; 652 break; 653 case B19200: 654 ur->ur_baud = ftdi_8u232am_b19200; 655 break; 656 case B38400: 657 ur->ur_baud = ftdi_8u232am_b38400; 658 break; 659 case B57600: 660 ur->ur_baud = ftdi_8u232am_b57600; 661 break; 662 case B115200: 663 ur->ur_baud = ftdi_8u232am_b115200; 664 break; 665 case B230400: 666 ur->ur_baud = ftdi_8u232am_b230400; 667 break; 668 case B460800: 669 ur->ur_baud = ftdi_8u232am_b460800; 670 break; 671 case B921600: 672 ur->ur_baud = ftdi_8u232am_b921600; 673 break; 674 default: 675 USB_DPRINTF_L3(DPRINT_CTLOP, uf->uf_lh, 676 "uftdi_param2regs: bad baud %d", 677 pe->val.ui); 678 return (USB_FAILURE); 679 } 680 break; 681 682 case DS_PARAM_PARITY: 683 if (pe->val.ui & PARENB) { 684 if (pe->val.ui & PARODD) 685 ur->ur_data |= 686 FTDI_SIO_SET_DATA_PARITY_ODD; 687 else 688 ur->ur_data |= 689 FTDI_SIO_SET_DATA_PARITY_EVEN; 690 } else { 691 /* LINTED [E_EXPR_NULL_EFFECT] */ 692 ur->ur_data |= FTDI_SIO_SET_DATA_PARITY_NONE; 693 } 694 break; 695 696 case DS_PARAM_STOPB: 697 if (pe->val.ui & CSTOPB) 698 ur->ur_data |= FTDI_SIO_SET_DATA_STOP_BITS_2; 699 else { 700 /* LINTED [E_EXPR_NULL_EFFECT] */ 701 ur->ur_data |= FTDI_SIO_SET_DATA_STOP_BITS_1; 702 } 703 break; 704 705 case DS_PARAM_CHARSZ: 706 switch (pe->val.ui) { 707 case CS5: 708 ur->ur_data |= FTDI_SIO_SET_DATA_BITS(5); 709 break; 710 case CS6: 711 ur->ur_data |= FTDI_SIO_SET_DATA_BITS(6); 712 break; 713 case CS7: 714 ur->ur_data |= FTDI_SIO_SET_DATA_BITS(7); 715 break; 716 case CS8: 717 default: 718 ur->ur_data |= FTDI_SIO_SET_DATA_BITS(8); 719 break; 720 } 721 break; 722 723 case DS_PARAM_XON_XOFF: /* Software flow control */ 724 if ((pe->val.ui & IXON) || (pe->val.ui & IXOFF)) { 725 uint8_t xonc = pe->val.uc[0]; 726 uint8_t xoffc = pe->val.uc[1]; 727 728 ur->ur_flowval = (xoffc << 8) | xonc; 729 ur->ur_flowidx = FTDI_SIO_XON_XOFF_HS << 8; 730 } 731 break; 732 733 case DS_PARAM_FLOW_CTL: /* Hardware flow control */ 734 if (pe->val.ui & (RTSXOFF | CTSXON)) { 735 ur->ur_flowval = 0; 736 ur->ur_flowidx = FTDI_SIO_RTS_CTS_HS << 8; 737 } 738 if (pe->val.ui & DTRXOFF) { 739 ur->ur_flowval = 0; 740 ur->ur_flowidx = FTDI_SIO_DTR_DSR_HS << 8; 741 } 742 break; 743 default: 744 USB_DPRINTF_L2(DPRINT_CTLOP, uf->uf_lh, 745 "uftdi_param2regs: bad param %d", pe->param); 746 break; 747 } 748 } 749 return (USB_SUCCESS); 750 } 751 752 /* 753 * Write the register set to the device and update the state structure. 754 * If there are errors, return the device to its previous state. 755 */ 756 static int 757 uftdi_setregs(uftdi_state_t *uf, uint_t portno, uftdi_regs_t *ur) 758 { 759 int rval; 760 uftdi_regs_t uold; 761 762 mutex_enter(&uf->uf_lock); 763 uold = uf->uf_softr; 764 mutex_exit(&uf->uf_lock); 765 766 if (ur == NULL) 767 ur = &uold; /* NULL => restore previous values */ 768 769 rval = uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_BAUD_RATE, 770 ur->ur_baud, portno); 771 if (rval != USB_SUCCESS) { 772 (void) uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_BAUD_RATE, 773 uold.ur_baud, portno); 774 goto out; 775 } else { 776 mutex_enter(&uf->uf_lock); 777 uf->uf_softr.ur_baud = ur->ur_baud; 778 mutex_exit(&uf->uf_lock); 779 } 780 781 rval = uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_DATA, 782 ur->ur_data, portno); 783 if (rval != USB_SUCCESS) { 784 (void) uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_DATA, 785 uold.ur_data, portno); 786 goto out; 787 } else { 788 mutex_enter(&uf->uf_lock); 789 uf->uf_softr.ur_data = ur->ur_data; 790 mutex_exit(&uf->uf_lock); 791 } 792 793 rval = uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_FLOW_CTRL, 794 ur->ur_flowval, ur->ur_flowidx | portno); 795 if (rval != USB_SUCCESS) { 796 (void) uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_FLOW_CTRL, 797 uold.ur_flowval, uold.ur_flowidx | portno); 798 goto out; 799 } else { 800 mutex_enter(&uf->uf_lock); 801 uf->uf_softr.ur_flowval = ur->ur_flowval; 802 uf->uf_softr.ur_flowidx = ur->ur_flowidx; 803 mutex_exit(&uf->uf_lock); 804 } 805 out: 806 return (rval); 807 } 808 809 /* 810 * ds_set_port_params 811 */ 812 static int 813 uftdi_set_port_params(ds_hdl_t hdl, uint_t portno, ds_port_params_t *tp) 814 { 815 uftdi_state_t *uf = (uftdi_state_t *)hdl; 816 int rval; 817 uftdi_regs_t uregs; 818 819 USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_set_port_params"); 820 821 rval = uftdi_param2regs(uf, tp, &uregs); 822 if (rval == USB_SUCCESS) 823 rval = uftdi_setregs(uf, portno, &uregs); 824 return (rval); 825 } 826 827 /* 828 * ds_set_modem_ctl 829 */ 830 static int 831 uftdi_set_modem_ctl(ds_hdl_t hdl, uint_t portno, int mask, int val) 832 { 833 uftdi_state_t *uf = (uftdi_state_t *)hdl; 834 int rval; 835 uint16_t mctl; 836 837 USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_set_modem_ctl"); 838 839 /* 840 * Note that we cannot set DTR and RTS simultaneously, so 841 * we do separate operations for each bit. 842 */ 843 844 if (mask & TIOCM_DTR) { 845 mctl = (val & TIOCM_DTR) ? 846 FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW; 847 848 rval = uftdi_cmd_vendor_write0(uf, 849 FTDI_SIO_MODEM_CTRL, mctl, portno); 850 851 if (rval == USB_SUCCESS) { 852 mutex_enter(&uf->uf_lock); 853 uf->uf_mctl &= ~FTDI_SIO_SET_DTR_HIGH; 854 uf->uf_mctl |= mctl & FTDI_SIO_SET_DTR_HIGH; 855 mutex_exit(&uf->uf_lock); 856 } else 857 return (rval); 858 } 859 860 if (mask & TIOCM_RTS) { 861 mctl = (val & TIOCM_RTS) ? 862 FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW; 863 864 rval = uftdi_cmd_vendor_write0(uf, 865 FTDI_SIO_MODEM_CTRL, mctl, portno); 866 867 if (rval == USB_SUCCESS) { 868 mutex_enter(&uf->uf_lock); 869 uf->uf_mctl &= ~FTDI_SIO_SET_RTS_HIGH; 870 uf->uf_mctl |= mctl & FTDI_SIO_SET_RTS_HIGH; 871 mutex_exit(&uf->uf_lock); 872 } 873 } 874 875 return (rval); 876 } 877 878 /* 879 * ds_get_modem_ctl 880 */ 881 static int 882 uftdi_get_modem_ctl(ds_hdl_t hdl, uint_t portno, int mask, int *valp) 883 { 884 uftdi_state_t *uf = (uftdi_state_t *)hdl; 885 uint_t val = 0; 886 887 ASSERT(portno == 0); 888 889 USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_get_modem_ctl"); 890 891 mutex_enter(&uf->uf_lock); 892 /* 893 * This status info is delivered to us at least every 40ms 894 * while the receive pipe is active 895 */ 896 if (uf->uf_msr & FTDI_MSR_STATUS_CTS) 897 val |= TIOCM_CTS; 898 if (uf->uf_msr & FTDI_MSR_STATUS_DSR) 899 val |= TIOCM_DSR; 900 if (uf->uf_msr & FTDI_MSR_STATUS_RI) 901 val |= TIOCM_RI; 902 if (uf->uf_msr & FTDI_MSR_STATUS_RLSD) 903 val |= TIOCM_CD; 904 905 /* 906 * Note, this status info is simply a replay of what we 907 * asked it to be in some previous "set" command, and 908 * is *not* directly sensed from the hardware. 909 */ 910 if ((uf->uf_mctl & FTDI_SIO_SET_RTS_HIGH) == FTDI_SIO_SET_RTS_HIGH) 911 val |= TIOCM_RTS; 912 if ((uf->uf_mctl & FTDI_SIO_SET_DTR_HIGH) == FTDI_SIO_SET_DTR_HIGH) 913 val |= TIOCM_DTR; 914 mutex_exit(&uf->uf_lock); 915 916 *valp = val & mask; 917 918 return (USB_SUCCESS); 919 } 920 921 922 /* 923 * ds_break_ctl 924 */ 925 static int 926 uftdi_break_ctl(ds_hdl_t hdl, uint_t portno, int ctl) 927 { 928 uftdi_state_t *uf = (uftdi_state_t *)hdl; 929 uftdi_regs_t *ur = &uf->uf_softr; 930 uint16_t data; 931 932 USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_break_ctl"); 933 934 mutex_enter(&uf->uf_lock); 935 data = ur->ur_data | (ctl == DS_ON) ? FTDI_SIO_SET_BREAK : 0; 936 mutex_exit(&uf->uf_lock); 937 938 return (uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_DATA, 939 data, portno)); 940 } 941 942 943 /* 944 * ds_tx 945 */ 946 /*ARGSUSED*/ 947 static int 948 uftdi_tx(ds_hdl_t hdl, uint_t portno, mblk_t *mp) 949 { 950 uftdi_state_t *uf = (uftdi_state_t *)hdl; 951 952 USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_tx"); 953 954 ASSERT(mp != NULL && MBLKL(mp) >= 1); 955 956 mutex_enter(&uf->uf_lock); 957 uftdi_put_tail(&uf->uf_tx_mp, mp); /* add to the chain */ 958 uftdi_tx_start(uf, NULL); 959 mutex_exit(&uf->uf_lock); 960 961 return (USB_SUCCESS); 962 } 963 964 965 /* 966 * ds_rx 967 */ 968 /*ARGSUSED*/ 969 static mblk_t * 970 uftdi_rx(ds_hdl_t hdl, uint_t portno) 971 { 972 uftdi_state_t *uf = (uftdi_state_t *)hdl; 973 mblk_t *mp; 974 975 USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_rx"); 976 977 mutex_enter(&uf->uf_lock); 978 mp = uf->uf_rx_mp; 979 uf->uf_rx_mp = NULL; 980 mutex_exit(&uf->uf_lock); 981 982 return (mp); 983 } 984 985 986 /* 987 * ds_stop 988 */ 989 /*ARGSUSED*/ 990 static void 991 uftdi_stop(ds_hdl_t hdl, uint_t portno, int dir) 992 { 993 uftdi_state_t *uf = (uftdi_state_t *)hdl; 994 995 USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_stop"); 996 997 if (dir & DS_TX) { 998 mutex_enter(&uf->uf_lock); 999 uf->uf_port_flags |= UFTDI_PORT_TX_STOPPED; 1000 mutex_exit(&uf->uf_lock); 1001 } 1002 } 1003 1004 1005 /* 1006 * ds_start 1007 */ 1008 /*ARGSUSED*/ 1009 static void 1010 uftdi_start(ds_hdl_t hdl, uint_t portno, int dir) 1011 { 1012 uftdi_state_t *uf = (uftdi_state_t *)hdl; 1013 1014 USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_start"); 1015 1016 if (dir & DS_TX) { 1017 mutex_enter(&uf->uf_lock); 1018 if (uf->uf_port_flags & UFTDI_PORT_TX_STOPPED) { 1019 uf->uf_port_flags &= ~UFTDI_PORT_TX_STOPPED; 1020 uftdi_tx_start(uf, NULL); 1021 } 1022 mutex_exit(&uf->uf_lock); 1023 } 1024 } 1025 1026 1027 /* 1028 * ds_fifo_flush 1029 */ 1030 /*ARGSUSED*/ 1031 static int 1032 uftdi_fifo_flush(ds_hdl_t hdl, uint_t portno, int dir) 1033 { 1034 uftdi_state_t *uf = (uftdi_state_t *)hdl; 1035 1036 USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, 1037 "uftdi_fifo_flush: dir=0x%x", dir); 1038 1039 mutex_enter(&uf->uf_lock); 1040 ASSERT(uf->uf_port_state == UFTDI_PORT_OPEN); 1041 1042 if (dir & DS_TX) { 1043 freemsg(uf->uf_tx_mp); 1044 uf->uf_tx_mp = NULL; 1045 } 1046 1047 if (dir & DS_RX) { 1048 freemsg(uf->uf_rx_mp); 1049 uf->uf_rx_mp = NULL; 1050 } 1051 mutex_exit(&uf->uf_lock); 1052 1053 if (dir & DS_TX) 1054 (void) uftdi_cmd_vendor_write0(uf, 1055 FTDI_SIO_RESET, FTDI_SIO_RESET_PURGE_TX, portno); 1056 1057 if (dir & DS_RX) 1058 (void) uftdi_cmd_vendor_write0(uf, 1059 FTDI_SIO_RESET, FTDI_SIO_RESET_PURGE_RX, portno); 1060 1061 return (USB_SUCCESS); 1062 } 1063 1064 1065 /* 1066 * ds_fifo_drain 1067 */ 1068 /*ARGSUSED*/ 1069 static int 1070 uftdi_fifo_drain(ds_hdl_t hdl, uint_t portno, int timeout) 1071 { 1072 uftdi_state_t *uf = (uftdi_state_t *)hdl; 1073 int rval = USB_SUCCESS; 1074 1075 USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_fifo_drain"); 1076 1077 mutex_enter(&uf->uf_lock); 1078 ASSERT(uf->uf_port_state == UFTDI_PORT_OPEN); 1079 1080 if (uftdi_wait_tx_drain(uf, 0) != USB_SUCCESS) { 1081 mutex_exit(&uf->uf_lock); 1082 return (USB_FAILURE); 1083 } 1084 1085 mutex_exit(&uf->uf_lock); 1086 1087 /* wait 500 ms until hw fifo drains */ 1088 delay(drv_usectohz(500*1000)); 1089 1090 return (rval); 1091 } 1092 1093 1094 /* 1095 * configuration clean up 1096 */ 1097 static void 1098 uftdi_cleanup(uftdi_state_t *uf, int level) 1099 { 1100 ASSERT(level > 0 && level <= UFTDI_CLEANUP_LEVEL_MAX); 1101 1102 switch (level) { 1103 default: 1104 case 6: 1105 uftdi_close_pipes(uf); 1106 /*FALLTHROUGH*/ 1107 case 5: 1108 usb_unregister_event_cbs(uf->uf_dip, uf->uf_usb_events); 1109 /*FALLTHROUGH*/ 1110 case 4: 1111 uftdi_destroy_pm_components(uf); 1112 /*FALLTHROUGH*/ 1113 case 3: 1114 mutex_destroy(&uf->uf_lock); 1115 cv_destroy(&uf->uf_tx_cv); 1116 1117 usb_free_log_hdl(uf->uf_lh); 1118 uf->uf_lh = NULL; 1119 1120 usb_free_descr_tree(uf->uf_dip, uf->uf_dev_data); 1121 uf->uf_def_ph = NULL; 1122 /*FALLTHROUGH*/ 1123 case 2: 1124 usb_client_detach(uf->uf_dip, uf->uf_dev_data); 1125 /*FALLTHROUGH*/ 1126 case 1: 1127 kmem_free(uf, sizeof (*uf)); 1128 break; 1129 } 1130 } 1131 1132 1133 /* 1134 * device specific attach 1135 */ 1136 static int 1137 uftdi_dev_attach(uftdi_state_t *uf) 1138 { 1139 return (uftdi_open_pipes(uf)); 1140 } 1141 1142 1143 /* 1144 * restore device state after CPR resume or reconnect 1145 */ 1146 static int 1147 uftdi_restore_device_state(uftdi_state_t *uf) 1148 { 1149 int state; 1150 1151 mutex_enter(&uf->uf_lock); 1152 state = uf->uf_dev_state; 1153 mutex_exit(&uf->uf_lock); 1154 1155 if (state != USB_DEV_DISCONNECTED && state != USB_DEV_SUSPENDED) 1156 return (state); 1157 1158 if (usb_check_same_device(uf->uf_dip, uf->uf_lh, USB_LOG_L0, 1159 DPRINT_MASK_ALL, USB_CHK_ALL, NULL) != USB_SUCCESS) { 1160 mutex_enter(&uf->uf_lock); 1161 state = uf->uf_dev_state = USB_DEV_DISCONNECTED; 1162 mutex_exit(&uf->uf_lock); 1163 return (state); 1164 } 1165 1166 if (state == USB_DEV_DISCONNECTED) { 1167 USB_DPRINTF_L0(DPRINT_HOTPLUG, uf->uf_lh, 1168 "Device has been reconnected but data may have been lost"); 1169 } 1170 1171 if (uftdi_reconnect_pipes(uf) != USB_SUCCESS) 1172 return (state); 1173 1174 /* 1175 * init device state 1176 */ 1177 mutex_enter(&uf->uf_lock); 1178 state = uf->uf_dev_state = USB_DEV_ONLINE; 1179 mutex_exit(&uf->uf_lock); 1180 1181 if ((uftdi_restore_port_state(uf, 0) != USB_SUCCESS)) { 1182 USB_DPRINTF_L2(DPRINT_HOTPLUG, uf->uf_lh, 1183 "uftdi_restore_device_state: failed"); 1184 } 1185 1186 return (state); 1187 } 1188 1189 1190 /* 1191 * restore ports state after CPR resume or reconnect 1192 */ 1193 static int 1194 uftdi_restore_port_state(uftdi_state_t *uf, int portno) 1195 { 1196 int rval; 1197 1198 mutex_enter(&uf->uf_lock); 1199 if (uf->uf_port_state != UFTDI_PORT_OPEN) { 1200 mutex_exit(&uf->uf_lock); 1201 return (USB_SUCCESS); 1202 } 1203 mutex_exit(&uf->uf_lock); 1204 1205 /* open hardware serial port, restoring old settings */ 1206 if ((rval = uftdi_open_hw_port(uf, portno, 1)) != USB_SUCCESS) { 1207 USB_DPRINTF_L2(DPRINT_HOTPLUG, uf->uf_lh, 1208 "uftdi_restore_port_state: failed"); 1209 } 1210 1211 return (rval); 1212 } 1213 1214 1215 /* 1216 * create PM components 1217 */ 1218 static int 1219 uftdi_create_pm_components(uftdi_state_t *uf) 1220 { 1221 dev_info_t *dip = uf->uf_dip; 1222 uftdi_pm_t *pm; 1223 uint_t pwr_states; 1224 1225 if (usb_create_pm_components(dip, &pwr_states) != USB_SUCCESS) { 1226 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, 1227 "uftdi_create_pm_components: failed"); 1228 return (USB_SUCCESS); 1229 } 1230 1231 pm = uf->uf_pm = kmem_zalloc(sizeof (*pm), KM_SLEEP); 1232 1233 pm->pm_pwr_states = (uint8_t)pwr_states; 1234 pm->pm_cur_power = USB_DEV_OS_FULL_PWR; 1235 pm->pm_wakeup_enabled = usb_handle_remote_wakeup(dip, 1236 USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS; 1237 1238 (void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR); 1239 1240 return (USB_SUCCESS); 1241 } 1242 1243 1244 /* 1245 * destroy PM components 1246 */ 1247 static void 1248 uftdi_destroy_pm_components(uftdi_state_t *uf) 1249 { 1250 uftdi_pm_t *pm = uf->uf_pm; 1251 dev_info_t *dip = uf->uf_dip; 1252 int rval; 1253 1254 if (!pm) 1255 return; 1256 1257 if (uf->uf_dev_state != USB_DEV_DISCONNECTED) { 1258 if (pm->pm_wakeup_enabled) { 1259 rval = pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR); 1260 if (rval != DDI_SUCCESS) { 1261 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, 1262 "uftdi_destroy_pm_components: " 1263 "raising power failed, rval=%d", rval); 1264 } 1265 rval = usb_handle_remote_wakeup(dip, 1266 USB_REMOTE_WAKEUP_DISABLE); 1267 if (rval != USB_SUCCESS) { 1268 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, 1269 "uftdi_destroy_pm_components: disable " 1270 "remote wakeup failed, rval=%d", rval); 1271 } 1272 } 1273 (void) pm_lower_power(dip, 0, USB_DEV_OS_PWR_OFF); 1274 } 1275 kmem_free(pm, sizeof (*pm)); 1276 uf->uf_pm = NULL; 1277 } 1278 1279 1280 /* 1281 * mark device busy and raise power 1282 */ 1283 static int 1284 uftdi_pm_set_busy(uftdi_state_t *uf) 1285 { 1286 uftdi_pm_t *pm = uf->uf_pm; 1287 dev_info_t *dip = uf->uf_dip; 1288 int rval; 1289 1290 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_pm_set_busy"); 1291 1292 if (!pm) 1293 return (USB_SUCCESS); 1294 1295 mutex_enter(&uf->uf_lock); 1296 /* if already marked busy, just increment the counter */ 1297 if (pm->pm_busy_cnt++ > 0) { 1298 mutex_exit(&uf->uf_lock); 1299 return (USB_SUCCESS); 1300 } 1301 1302 rval = pm_busy_component(dip, 0); 1303 ASSERT(rval == DDI_SUCCESS); 1304 1305 if (pm->pm_cur_power == USB_DEV_OS_FULL_PWR) { 1306 mutex_exit(&uf->uf_lock); 1307 return (USB_SUCCESS); 1308 } 1309 1310 /* need to raise power */ 1311 pm->pm_raise_power = B_TRUE; 1312 mutex_exit(&uf->uf_lock); 1313 1314 rval = pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR); 1315 if (rval != DDI_SUCCESS) { 1316 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, "raising power failed"); 1317 } 1318 1319 mutex_enter(&uf->uf_lock); 1320 pm->pm_raise_power = B_FALSE; 1321 mutex_exit(&uf->uf_lock); 1322 1323 return (USB_SUCCESS); 1324 } 1325 1326 1327 /* 1328 * mark device idle 1329 */ 1330 static void 1331 uftdi_pm_set_idle(uftdi_state_t *uf) 1332 { 1333 uftdi_pm_t *pm = uf->uf_pm; 1334 dev_info_t *dip = uf->uf_dip; 1335 1336 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_pm_set_idle"); 1337 1338 if (!pm) 1339 return; 1340 1341 /* 1342 * if more ports use the device, do not mark as yet 1343 */ 1344 mutex_enter(&uf->uf_lock); 1345 if (--pm->pm_busy_cnt > 0) { 1346 mutex_exit(&uf->uf_lock); 1347 return; 1348 } 1349 (void) pm_idle_component(dip, 0); 1350 mutex_exit(&uf->uf_lock); 1351 } 1352 1353 1354 /* 1355 * Functions to handle power transition for OS levels 0 -> 3 1356 * The same level as OS state, different from USB state 1357 */ 1358 static int 1359 uftdi_pwrlvl0(uftdi_state_t *uf) 1360 { 1361 int rval; 1362 1363 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_pwrlvl0"); 1364 1365 switch (uf->uf_dev_state) { 1366 case USB_DEV_ONLINE: 1367 /* issue USB D3 command to the device */ 1368 rval = usb_set_device_pwrlvl3(uf->uf_dip); 1369 ASSERT(rval == USB_SUCCESS); 1370 1371 uf->uf_dev_state = USB_DEV_PWRED_DOWN; 1372 uf->uf_pm->pm_cur_power = USB_DEV_OS_PWR_OFF; 1373 1374 /*FALLTHROUGH*/ 1375 case USB_DEV_DISCONNECTED: 1376 case USB_DEV_SUSPENDED: 1377 /* allow a disconnect/cpr'ed device to go to lower power */ 1378 return (USB_SUCCESS); 1379 case USB_DEV_PWRED_DOWN: 1380 default: 1381 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, 1382 "uftdi_pwrlvl0: illegal device state"); 1383 return (USB_FAILURE); 1384 } 1385 } 1386 1387 1388 static int 1389 uftdi_pwrlvl1(uftdi_state_t *uf) 1390 { 1391 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_pwrlvl1"); 1392 1393 /* issue USB D2 command to the device */ 1394 (void) usb_set_device_pwrlvl2(uf->uf_dip); 1395 return (USB_FAILURE); 1396 } 1397 1398 1399 static int 1400 uftdi_pwrlvl2(uftdi_state_t *uf) 1401 { 1402 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_pwrlvl2"); 1403 1404 /* issue USB D1 command to the device */ 1405 (void) usb_set_device_pwrlvl1(uf->uf_dip); 1406 return (USB_FAILURE); 1407 } 1408 1409 1410 static int 1411 uftdi_pwrlvl3(uftdi_state_t *uf) 1412 { 1413 int rval; 1414 1415 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_pwrlvl3"); 1416 1417 switch (uf->uf_dev_state) { 1418 case USB_DEV_PWRED_DOWN: 1419 /* Issue USB D0 command to the device here */ 1420 rval = usb_set_device_pwrlvl0(uf->uf_dip); 1421 ASSERT(rval == USB_SUCCESS); 1422 1423 uf->uf_dev_state = USB_DEV_ONLINE; 1424 uf->uf_pm->pm_cur_power = USB_DEV_OS_FULL_PWR; 1425 1426 /*FALLTHROUGH*/ 1427 case USB_DEV_ONLINE: 1428 /* we are already in full power */ 1429 1430 /*FALLTHROUGH*/ 1431 case USB_DEV_DISCONNECTED: 1432 case USB_DEV_SUSPENDED: 1433 return (USB_SUCCESS); 1434 default: 1435 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, 1436 "uftdi_pwrlvl3: illegal device state"); 1437 return (USB_FAILURE); 1438 } 1439 } 1440 1441 1442 /* 1443 * pipe operations 1444 */ 1445 static int 1446 uftdi_open_pipes(uftdi_state_t *uf) 1447 { 1448 int ifc, alt; 1449 usb_pipe_policy_t policy; 1450 usb_ep_data_t *in_data, *out_data; 1451 1452 /* get ep data */ 1453 ifc = uf->uf_dev_data->dev_curr_if; 1454 alt = 0; 1455 1456 in_data = usb_lookup_ep_data(uf->uf_dip, uf->uf_dev_data, ifc, alt, 1457 0, USB_EP_ATTR_BULK, USB_EP_DIR_IN); 1458 1459 out_data = usb_lookup_ep_data(uf->uf_dip, uf->uf_dev_data, ifc, alt, 1460 0, USB_EP_ATTR_BULK, USB_EP_DIR_OUT); 1461 1462 if (in_data == NULL || out_data == NULL) { 1463 USB_DPRINTF_L2(DPRINT_ATTACH, uf->uf_lh, 1464 "uftdi_open_pipes: can't get ep data"); 1465 return (USB_FAILURE); 1466 } 1467 1468 /* open pipes */ 1469 policy.pp_max_async_reqs = 2; 1470 1471 if (usb_pipe_open(uf->uf_dip, &in_data->ep_descr, &policy, 1472 USB_FLAGS_SLEEP, &uf->uf_bulkin_ph) != USB_SUCCESS) 1473 return (USB_FAILURE); 1474 1475 if (usb_pipe_open(uf->uf_dip, &out_data->ep_descr, &policy, 1476 USB_FLAGS_SLEEP, &uf->uf_bulkout_ph) != USB_SUCCESS) { 1477 usb_pipe_close(uf->uf_dip, uf->uf_bulkin_ph, USB_FLAGS_SLEEP, 1478 NULL, NULL); 1479 return (USB_FAILURE); 1480 } 1481 1482 mutex_enter(&uf->uf_lock); 1483 uf->uf_bulkin_state = UFTDI_PIPE_IDLE; 1484 uf->uf_bulkout_state = UFTDI_PIPE_IDLE; 1485 mutex_exit(&uf->uf_lock); 1486 1487 return (USB_SUCCESS); 1488 } 1489 1490 1491 static void 1492 uftdi_close_pipes(uftdi_state_t *uf) 1493 { 1494 if (uf->uf_bulkin_ph) 1495 usb_pipe_close(uf->uf_dip, uf->uf_bulkin_ph, 1496 USB_FLAGS_SLEEP, 0, 0); 1497 if (uf->uf_bulkout_ph) 1498 usb_pipe_close(uf->uf_dip, uf->uf_bulkout_ph, 1499 USB_FLAGS_SLEEP, 0, 0); 1500 1501 mutex_enter(&uf->uf_lock); 1502 uf->uf_bulkin_state = UFTDI_PIPE_CLOSED; 1503 uf->uf_bulkout_state = UFTDI_PIPE_CLOSED; 1504 mutex_exit(&uf->uf_lock); 1505 } 1506 1507 1508 static void 1509 uftdi_disconnect_pipes(uftdi_state_t *uf) 1510 { 1511 uftdi_close_pipes(uf); 1512 } 1513 1514 1515 static int 1516 uftdi_reconnect_pipes(uftdi_state_t *uf) 1517 { 1518 return (uftdi_open_pipes(uf)); 1519 } 1520 1521 /* 1522 * bulk in pipe normal and exception callback handler 1523 */ 1524 /*ARGSUSED*/ 1525 static void 1526 uftdi_bulkin_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 1527 { 1528 uftdi_state_t *uf = (uftdi_state_t *)req->bulk_client_private; 1529 mblk_t *data; 1530 int data_len; 1531 int notify = 0; 1532 1533 data = req->bulk_data; 1534 data_len = data ? MBLKL(data) : 0; 1535 1536 /* 1537 * The first two bytes of data are actually status register bytes 1538 * that arrive with every packet from the device. Strip 1539 * them here before handing the data on. Note that the device 1540 * will send us these bytes at least every 40 milliseconds, 1541 * even if there's no data .. 1542 */ 1543 if (req->bulk_completion_reason == USB_CR_OK && data_len >= 2) { 1544 uint8_t msr = FTDI_GET_MSR(data->b_rptr); 1545 uint8_t lsr = FTDI_GET_LSR(data->b_rptr); 1546 1547 mutex_enter(&uf->uf_lock); 1548 if (uf->uf_msr != msr || 1549 (uf->uf_lsr & FTDI_LSR_MASK) != (lsr & FTDI_LSR_MASK)) { 1550 USB_DPRINTF_L3(DPRINT_IN_PIPE, uf->uf_lh, 1551 "uftdi_bulkin_cb: status change " 1552 "0x%02x.0x%02x, was 0x%02x.0x%02x", 1553 msr, lsr, uf->uf_msr, uf->uf_lsr); 1554 uf->uf_msr = msr; 1555 uf->uf_lsr = lsr; 1556 /* 1557 * If we're waiting for a modem status change, 1558 * sending an empty message will cause us to 1559 * reexamine the modem flags. 1560 */ 1561 notify = 1; 1562 } 1563 mutex_exit(&uf->uf_lock); 1564 1565 data_len -= 2; 1566 data->b_rptr += 2; 1567 } 1568 1569 notify |= (data_len > 0); 1570 1571 USB_DPRINTF_L4(DPRINT_IN_PIPE, uf->uf_lh, "uftdi_bulkin_cb: " 1572 "cr=%d len=%d", req->bulk_completion_reason, data_len); 1573 1574 /* save data and notify GSD */ 1575 if (notify && uf->uf_port_state == UFTDI_PORT_OPEN && 1576 req->bulk_completion_reason == USB_CR_OK) { 1577 req->bulk_data = NULL; 1578 uftdi_put_tail(&uf->uf_rx_mp, data); 1579 if (uf->uf_cb.cb_rx) 1580 uf->uf_cb.cb_rx(uf->uf_cb.cb_arg); 1581 } 1582 1583 usb_free_bulk_req(req); 1584 1585 /* receive more */ 1586 mutex_enter(&uf->uf_lock); 1587 uf->uf_bulkin_state = UFTDI_PIPE_IDLE; 1588 if (uf->uf_port_state == UFTDI_PORT_OPEN && 1589 uf->uf_dev_state == USB_DEV_ONLINE) { 1590 if (uftdi_rx_start(uf) != USB_SUCCESS) { 1591 USB_DPRINTF_L2(DPRINT_IN_PIPE, uf->uf_lh, 1592 "uftdi_bulkin_cb: restart rx fail"); 1593 } 1594 } 1595 mutex_exit(&uf->uf_lock); 1596 } 1597 1598 1599 /* 1600 * bulk out common and exception callback 1601 */ 1602 /*ARGSUSED*/ 1603 static void 1604 uftdi_bulkout_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 1605 { 1606 uftdi_state_t *uf = (uftdi_state_t *)req->bulk_client_private; 1607 int data_len; 1608 mblk_t *data = req->bulk_data; 1609 1610 data_len = data ? MBLKL(data) : 0; 1611 1612 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, 1613 "uftdi_bulkout_cb: cr=%d len=%d", 1614 req->bulk_completion_reason, data_len); 1615 1616 if (uf->uf_port_state == UFTDI_PORT_OPEN && 1617 req->bulk_completion_reason && data_len > 0) { 1618 uftdi_put_head(&uf->uf_tx_mp, data); 1619 req->bulk_data = NULL; 1620 } 1621 1622 usb_free_bulk_req(req); 1623 1624 /* notify GSD */ 1625 if (uf->uf_cb.cb_tx) 1626 uf->uf_cb.cb_tx(uf->uf_cb.cb_arg); 1627 1628 /* send more */ 1629 mutex_enter(&uf->uf_lock); 1630 uf->uf_bulkout_state = UFTDI_PIPE_IDLE; 1631 if (uf->uf_tx_mp == NULL) 1632 cv_broadcast(&uf->uf_tx_cv); 1633 else 1634 uftdi_tx_start(uf, NULL); 1635 mutex_exit(&uf->uf_lock); 1636 } 1637 1638 1639 /* 1640 * start receiving data 1641 */ 1642 static int 1643 uftdi_rx_start(uftdi_state_t *uf) 1644 { 1645 usb_bulk_req_t *br; 1646 int rval; 1647 1648 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, "uftdi_rx_start"); 1649 1650 ASSERT(mutex_owned(&uf->uf_lock)); 1651 1652 uf->uf_bulkin_state = UFTDI_PIPE_BUSY; 1653 mutex_exit(&uf->uf_lock); 1654 1655 br = usb_alloc_bulk_req(uf->uf_dip, uf->uf_xfer_sz, USB_FLAGS_SLEEP); 1656 br->bulk_len = uf->uf_xfer_sz; 1657 br->bulk_timeout = UFTDI_BULKIN_TIMEOUT; 1658 br->bulk_cb = uftdi_bulkin_cb; 1659 br->bulk_exc_cb = uftdi_bulkin_cb; 1660 br->bulk_client_private = (usb_opaque_t)uf; 1661 br->bulk_attributes = USB_ATTRS_AUTOCLEARING | USB_ATTRS_SHORT_XFER_OK; 1662 1663 rval = usb_pipe_bulk_xfer(uf->uf_bulkin_ph, br, 0); 1664 1665 if (rval != USB_SUCCESS) { 1666 USB_DPRINTF_L2(DPRINT_IN_PIPE, uf->uf_lh, 1667 "uftdi_rx_start: xfer failed %d", rval); 1668 usb_free_bulk_req(br); 1669 } 1670 1671 mutex_enter(&uf->uf_lock); 1672 if (rval != USB_SUCCESS) 1673 uf->uf_bulkin_state = UFTDI_PIPE_IDLE; 1674 1675 return (rval); 1676 } 1677 1678 1679 /* 1680 * start data transmit 1681 */ 1682 static void 1683 uftdi_tx_start(uftdi_state_t *uf, int *xferd) 1684 { 1685 int len; /* bytes we can transmit */ 1686 mblk_t *data; /* data to be transmitted */ 1687 int data_len; /* bytes in 'data' */ 1688 mblk_t *mp; /* current msgblk */ 1689 int copylen; /* bytes copy from 'mp' to 'data' */ 1690 int rval; 1691 1692 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, "uftdi_tx_start"); 1693 ASSERT(mutex_owned(&uf->uf_lock)); 1694 ASSERT(uf->uf_port_state != UFTDI_PORT_CLOSED); 1695 1696 if (xferd) 1697 *xferd = 0; 1698 if ((uf->uf_port_flags & UFTDI_PORT_TX_STOPPED) || 1699 uf->uf_tx_mp == NULL) { 1700 return; 1701 } 1702 if (uf->uf_bulkout_state != UFTDI_PIPE_IDLE) { 1703 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, 1704 "uftdi_tx_start: pipe busy"); 1705 return; 1706 } 1707 ASSERT(MBLKL(uf->uf_tx_mp) > 0); 1708 1709 /* send as much data as port can receive */ 1710 len = min(msgdsize(uf->uf_tx_mp), uf->uf_xfer_sz); 1711 1712 if (len <= 0) 1713 return; 1714 if ((data = allocb(len, BPRI_LO)) == NULL) 1715 return; 1716 1717 /* 1718 * copy no more than 'len' bytes from mblk chain to transmit mblk 'data' 1719 */ 1720 data_len = 0; 1721 while (data_len < len && uf->uf_tx_mp) { 1722 mp = uf->uf_tx_mp; 1723 copylen = min(MBLKL(mp), len - data_len); 1724 bcopy(mp->b_rptr, data->b_wptr, copylen); 1725 mp->b_rptr += copylen; 1726 data->b_wptr += copylen; 1727 data_len += copylen; 1728 1729 if (MBLKL(mp) < 1) { 1730 uf->uf_tx_mp = unlinkb(mp); 1731 freeb(mp); 1732 } else { 1733 ASSERT(data_len == len); 1734 } 1735 } 1736 1737 ASSERT(data_len > 0); 1738 1739 uf->uf_bulkout_state = UFTDI_PIPE_BUSY; 1740 mutex_exit(&uf->uf_lock); 1741 1742 rval = uftdi_send_data(uf, data); 1743 mutex_enter(&uf->uf_lock); 1744 1745 if (rval != USB_SUCCESS) { 1746 uf->uf_bulkout_state = UFTDI_PIPE_IDLE; 1747 uftdi_put_head(&uf->uf_tx_mp, data); 1748 } else { 1749 if (xferd) 1750 *xferd = data_len; 1751 } 1752 } 1753 1754 1755 static int 1756 uftdi_send_data(uftdi_state_t *uf, mblk_t *data) 1757 { 1758 usb_bulk_req_t *br; 1759 int len = MBLKL(data); 1760 int rval; 1761 1762 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, 1763 "uftdi_send_data: %d 0x%x 0x%x 0x%x", len, data->b_rptr[0], 1764 (len > 1) ? data->b_rptr[1] : 0, (len > 2) ? data->b_rptr[2] : 0); 1765 1766 ASSERT(!mutex_owned(&uf->uf_lock)); 1767 1768 br = usb_alloc_bulk_req(uf->uf_dip, 0, USB_FLAGS_SLEEP); 1769 br->bulk_data = data; 1770 br->bulk_len = len; 1771 br->bulk_timeout = UFTDI_BULKOUT_TIMEOUT; 1772 br->bulk_cb = uftdi_bulkout_cb; 1773 br->bulk_exc_cb = uftdi_bulkout_cb; 1774 br->bulk_client_private = (usb_opaque_t)uf; 1775 br->bulk_attributes = USB_ATTRS_AUTOCLEARING; 1776 1777 rval = usb_pipe_bulk_xfer(uf->uf_bulkout_ph, br, 0); 1778 1779 if (rval != USB_SUCCESS) { 1780 USB_DPRINTF_L2(DPRINT_OUT_PIPE, uf->uf_lh, 1781 "uftdi_send_data: xfer failed %d", rval); 1782 br->bulk_data = NULL; 1783 usb_free_bulk_req(br); 1784 } 1785 1786 return (rval); 1787 } 1788 1789 1790 /* 1791 * wait until local tx buffer drains. 1792 * 'timeout' is in seconds, zero means wait forever 1793 */ 1794 static int 1795 uftdi_wait_tx_drain(uftdi_state_t *uf, int timeout) 1796 { 1797 clock_t until; 1798 int over = 0; 1799 1800 until = ddi_get_lbolt() + drv_usectohz(1000 * 1000 * timeout); 1801 1802 while (uf->uf_tx_mp && !over) { 1803 if (timeout > 0) { 1804 /* whether timedout or signal pending */ 1805 over = cv_timedwait_sig(&uf->uf_tx_cv, 1806 &uf->uf_lock, until) <= 0; 1807 } else { 1808 /* whether a signal is pending */ 1809 over = cv_wait_sig(&uf->uf_tx_cv, 1810 &uf->uf_lock) == 0; 1811 } 1812 } 1813 1814 return (uf->uf_tx_mp == NULL ? USB_SUCCESS : USB_FAILURE); 1815 } 1816 1817 /* 1818 * initialize hardware serial port 1819 */ 1820 static int 1821 uftdi_open_hw_port(uftdi_state_t *uf, int portno, int dorestore) 1822 { 1823 int rval; 1824 1825 /* 1826 * Perform a full reset on the device 1827 */ 1828 rval = uftdi_cmd_vendor_write0(uf, 1829 FTDI_SIO_RESET, FTDI_SIO_RESET_SIO, portno); 1830 if (rval != USB_SUCCESS) { 1831 USB_DPRINTF_L2(DPRINT_DEF_PIPE, uf->uf_lh, 1832 "uftdi_open_hw_port: failed to reset!"); 1833 return (rval); 1834 } 1835 1836 if (dorestore) { 1837 /* 1838 * Restore settings from our soft copy of HW registers 1839 */ 1840 (void) uftdi_setregs(uf, portno, NULL); 1841 } else { 1842 /* 1843 * 9600 baud, 2 stop bits, no parity, 8-bit, h/w flow control 1844 */ 1845 static ds_port_param_entry_t ents[] = { 1846 #if defined(__lock_lint) 1847 /* 1848 * (Sigh - wlcc doesn't understand this newer 1849 * form of structure member initialization.) 1850 */ 1851 { 0 } 1852 #else 1853 { DS_PARAM_BAUD, .val.ui = B9600 }, 1854 { DS_PARAM_STOPB, .val.ui = CSTOPB }, 1855 { DS_PARAM_PARITY, .val.ui = 0 }, 1856 { DS_PARAM_CHARSZ, .val.ui = CS8 }, 1857 { DS_PARAM_FLOW_CTL, .val.ui = CTSXON } 1858 #endif 1859 }; 1860 static ds_port_params_t params = { 1861 ents, 1862 sizeof (ents) / sizeof (ents[0]) 1863 }; 1864 1865 rval = uftdi_set_port_params(uf, portno, ¶ms); 1866 if (rval != USB_SUCCESS) { 1867 USB_DPRINTF_L2(DPRINT_DEF_PIPE, uf->uf_lh, 1868 "uftdi_open_hw_port: failed 9600/2/n/8 rval %d", 1869 rval); 1870 } 1871 } 1872 1873 return (rval); 1874 } 1875 1876 static int 1877 uftdi_cmd_vendor_write0(uftdi_state_t *uf, 1878 uint16_t reqno, uint16_t val, uint16_t idx) 1879 { 1880 usb_ctrl_setup_t req; 1881 usb_cb_flags_t cb_flags; 1882 usb_cr_t cr; 1883 int rval; 1884 1885 ASSERT(!mutex_owned(&uf->uf_lock)); 1886 1887 req.bmRequestType = 1888 USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_HOST_TO_DEV; 1889 req.bRequest = (uchar_t)reqno; 1890 req.wValue = val; 1891 req.wIndex = idx; 1892 req.wLength = 0; 1893 req.attrs = USB_ATTRS_NONE; 1894 1895 if ((rval = usb_pipe_ctrl_xfer_wait(uf->uf_def_ph, 1896 &req, NULL, &cr, &cb_flags, 0)) != USB_SUCCESS) { 1897 USB_DPRINTF_L2(DPRINT_DEF_PIPE, uf->uf_lh, 1898 "uftdi_cmd_vendor_write0: 0x%x 0x%x 0x%x failed %d %d 0x%x", 1899 reqno, val, idx, rval, cr, cb_flags); 1900 } 1901 1902 return (rval); 1903 } 1904 1905 /* 1906 * misc routines 1907 */ 1908 1909 /* 1910 * link a message block to tail of message 1911 * account for the case when message is null 1912 */ 1913 static void 1914 uftdi_put_tail(mblk_t **mpp, mblk_t *bp) 1915 { 1916 if (*mpp) 1917 linkb(*mpp, bp); 1918 else 1919 *mpp = bp; 1920 } 1921 1922 /* 1923 * put a message block at the head of the message 1924 * account for the case when message is null 1925 */ 1926 static void 1927 uftdi_put_head(mblk_t **mpp, mblk_t *bp) 1928 { 1929 if (*mpp) 1930 linkb(bp, *mpp); 1931 *mpp = bp; 1932 } 1933 1934 /*ARGSUSED*/ 1935 static usb_pipe_handle_t 1936 uftdi_out_pipe(ds_hdl_t hdl, uint_t portno) 1937 { 1938 return (((uftdi_state_t *)hdl)->uf_bulkout_ph); 1939 } 1940 1941 /*ARGSUSED*/ 1942 static usb_pipe_handle_t 1943 uftdi_in_pipe(ds_hdl_t hdl, uint_t portno) 1944 { 1945 return (((uftdi_state_t *)hdl)->uf_bulkin_ph); 1946 } 1947