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