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 unsigned int count; 1074 const uint_t countmax = 50; /* at least 500ms */ 1075 const uint8_t txempty = 1076 FTDI_LSR_STATUS_TEMT | FTDI_LSR_STATUS_THRE; 1077 1078 USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_fifo_drain"); 1079 1080 mutex_enter(&uf->uf_lock); 1081 ASSERT(uf->uf_port_state == UFTDI_PORT_OPEN); 1082 1083 if (uftdi_wait_tx_drain(uf, 0) != USB_SUCCESS) { 1084 mutex_exit(&uf->uf_lock); 1085 return (USB_FAILURE); 1086 } 1087 1088 /* 1089 * Wait for the TX fifo to indicate empty. 1090 * 1091 * At all but the slowest baud rates, this is 1092 * likely to be a one-shot test that instantly 1093 * succeeds, but poll for at least 'countmax' 1094 * tries before giving up. 1095 */ 1096 for (count = 0; count < countmax; count++) { 1097 if ((uf->uf_lsr & txempty) == txempty) 1098 break; 1099 mutex_exit(&uf->uf_lock); 1100 delay(drv_usectohz(10*1000)); /* 10ms */ 1101 mutex_enter(&uf->uf_lock); 1102 } 1103 1104 mutex_exit(&uf->uf_lock); 1105 1106 return (count < countmax ? USB_SUCCESS : USB_FAILURE); 1107 } 1108 1109 1110 /* 1111 * configuration clean up 1112 */ 1113 static void 1114 uftdi_cleanup(uftdi_state_t *uf, int level) 1115 { 1116 ASSERT(level > 0 && level <= UFTDI_CLEANUP_LEVEL_MAX); 1117 1118 switch (level) { 1119 default: 1120 case 6: 1121 uftdi_close_pipes(uf); 1122 /*FALLTHROUGH*/ 1123 case 5: 1124 usb_unregister_event_cbs(uf->uf_dip, uf->uf_usb_events); 1125 /*FALLTHROUGH*/ 1126 case 4: 1127 uftdi_destroy_pm_components(uf); 1128 /*FALLTHROUGH*/ 1129 case 3: 1130 mutex_destroy(&uf->uf_lock); 1131 cv_destroy(&uf->uf_tx_cv); 1132 1133 usb_free_log_hdl(uf->uf_lh); 1134 uf->uf_lh = NULL; 1135 1136 usb_free_descr_tree(uf->uf_dip, uf->uf_dev_data); 1137 uf->uf_def_ph = NULL; 1138 /*FALLTHROUGH*/ 1139 case 2: 1140 usb_client_detach(uf->uf_dip, uf->uf_dev_data); 1141 /*FALLTHROUGH*/ 1142 case 1: 1143 kmem_free(uf, sizeof (*uf)); 1144 break; 1145 } 1146 } 1147 1148 1149 /* 1150 * device specific attach 1151 */ 1152 static int 1153 uftdi_dev_attach(uftdi_state_t *uf) 1154 { 1155 return (uftdi_open_pipes(uf)); 1156 } 1157 1158 1159 /* 1160 * restore device state after CPR resume or reconnect 1161 */ 1162 static int 1163 uftdi_restore_device_state(uftdi_state_t *uf) 1164 { 1165 int state; 1166 1167 mutex_enter(&uf->uf_lock); 1168 state = uf->uf_dev_state; 1169 mutex_exit(&uf->uf_lock); 1170 1171 if (state != USB_DEV_DISCONNECTED && state != USB_DEV_SUSPENDED) 1172 return (state); 1173 1174 if (usb_check_same_device(uf->uf_dip, uf->uf_lh, USB_LOG_L0, 1175 DPRINT_MASK_ALL, USB_CHK_ALL, NULL) != USB_SUCCESS) { 1176 mutex_enter(&uf->uf_lock); 1177 state = uf->uf_dev_state = USB_DEV_DISCONNECTED; 1178 mutex_exit(&uf->uf_lock); 1179 return (state); 1180 } 1181 1182 if (state == USB_DEV_DISCONNECTED) { 1183 USB_DPRINTF_L0(DPRINT_HOTPLUG, uf->uf_lh, 1184 "Device has been reconnected but data may have been lost"); 1185 } 1186 1187 if (uftdi_reconnect_pipes(uf) != USB_SUCCESS) 1188 return (state); 1189 1190 /* 1191 * init device state 1192 */ 1193 mutex_enter(&uf->uf_lock); 1194 state = uf->uf_dev_state = USB_DEV_ONLINE; 1195 mutex_exit(&uf->uf_lock); 1196 1197 if ((uftdi_restore_port_state(uf, 0) != USB_SUCCESS)) { 1198 USB_DPRINTF_L2(DPRINT_HOTPLUG, uf->uf_lh, 1199 "uftdi_restore_device_state: failed"); 1200 } 1201 1202 return (state); 1203 } 1204 1205 1206 /* 1207 * restore ports state after CPR resume or reconnect 1208 */ 1209 static int 1210 uftdi_restore_port_state(uftdi_state_t *uf, int portno) 1211 { 1212 int rval; 1213 1214 mutex_enter(&uf->uf_lock); 1215 if (uf->uf_port_state != UFTDI_PORT_OPEN) { 1216 mutex_exit(&uf->uf_lock); 1217 return (USB_SUCCESS); 1218 } 1219 mutex_exit(&uf->uf_lock); 1220 1221 /* open hardware serial port, restoring old settings */ 1222 if ((rval = uftdi_open_hw_port(uf, portno, 1)) != USB_SUCCESS) { 1223 USB_DPRINTF_L2(DPRINT_HOTPLUG, uf->uf_lh, 1224 "uftdi_restore_port_state: failed"); 1225 } 1226 1227 return (rval); 1228 } 1229 1230 1231 /* 1232 * create PM components 1233 */ 1234 static int 1235 uftdi_create_pm_components(uftdi_state_t *uf) 1236 { 1237 dev_info_t *dip = uf->uf_dip; 1238 uftdi_pm_t *pm; 1239 uint_t pwr_states; 1240 1241 if (usb_create_pm_components(dip, &pwr_states) != USB_SUCCESS) { 1242 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, 1243 "uftdi_create_pm_components: failed"); 1244 return (USB_SUCCESS); 1245 } 1246 1247 pm = uf->uf_pm = kmem_zalloc(sizeof (*pm), KM_SLEEP); 1248 1249 pm->pm_pwr_states = (uint8_t)pwr_states; 1250 pm->pm_cur_power = USB_DEV_OS_FULL_PWR; 1251 pm->pm_wakeup_enabled = usb_handle_remote_wakeup(dip, 1252 USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS; 1253 1254 (void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR); 1255 1256 return (USB_SUCCESS); 1257 } 1258 1259 1260 /* 1261 * destroy PM components 1262 */ 1263 static void 1264 uftdi_destroy_pm_components(uftdi_state_t *uf) 1265 { 1266 uftdi_pm_t *pm = uf->uf_pm; 1267 dev_info_t *dip = uf->uf_dip; 1268 int rval; 1269 1270 if (!pm) 1271 return; 1272 1273 if (uf->uf_dev_state != USB_DEV_DISCONNECTED) { 1274 if (pm->pm_wakeup_enabled) { 1275 rval = pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR); 1276 if (rval != DDI_SUCCESS) { 1277 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, 1278 "uftdi_destroy_pm_components: " 1279 "raising power failed, rval=%d", rval); 1280 } 1281 rval = usb_handle_remote_wakeup(dip, 1282 USB_REMOTE_WAKEUP_DISABLE); 1283 if (rval != USB_SUCCESS) { 1284 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, 1285 "uftdi_destroy_pm_components: disable " 1286 "remote wakeup failed, rval=%d", rval); 1287 } 1288 } 1289 (void) pm_lower_power(dip, 0, USB_DEV_OS_PWR_OFF); 1290 } 1291 kmem_free(pm, sizeof (*pm)); 1292 uf->uf_pm = NULL; 1293 } 1294 1295 1296 /* 1297 * mark device busy and raise power 1298 */ 1299 static int 1300 uftdi_pm_set_busy(uftdi_state_t *uf) 1301 { 1302 uftdi_pm_t *pm = uf->uf_pm; 1303 dev_info_t *dip = uf->uf_dip; 1304 int rval; 1305 1306 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_pm_set_busy"); 1307 1308 if (!pm) 1309 return (USB_SUCCESS); 1310 1311 mutex_enter(&uf->uf_lock); 1312 /* if already marked busy, just increment the counter */ 1313 if (pm->pm_busy_cnt++ > 0) { 1314 mutex_exit(&uf->uf_lock); 1315 return (USB_SUCCESS); 1316 } 1317 1318 rval = pm_busy_component(dip, 0); 1319 ASSERT(rval == DDI_SUCCESS); 1320 1321 if (pm->pm_cur_power == USB_DEV_OS_FULL_PWR) { 1322 mutex_exit(&uf->uf_lock); 1323 return (USB_SUCCESS); 1324 } 1325 1326 /* need to raise power */ 1327 pm->pm_raise_power = B_TRUE; 1328 mutex_exit(&uf->uf_lock); 1329 1330 rval = pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR); 1331 if (rval != DDI_SUCCESS) { 1332 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, "raising power failed"); 1333 } 1334 1335 mutex_enter(&uf->uf_lock); 1336 pm->pm_raise_power = B_FALSE; 1337 mutex_exit(&uf->uf_lock); 1338 1339 return (USB_SUCCESS); 1340 } 1341 1342 1343 /* 1344 * mark device idle 1345 */ 1346 static void 1347 uftdi_pm_set_idle(uftdi_state_t *uf) 1348 { 1349 uftdi_pm_t *pm = uf->uf_pm; 1350 dev_info_t *dip = uf->uf_dip; 1351 1352 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_pm_set_idle"); 1353 1354 if (!pm) 1355 return; 1356 1357 /* 1358 * if more ports use the device, do not mark as yet 1359 */ 1360 mutex_enter(&uf->uf_lock); 1361 if (--pm->pm_busy_cnt > 0) { 1362 mutex_exit(&uf->uf_lock); 1363 return; 1364 } 1365 (void) pm_idle_component(dip, 0); 1366 mutex_exit(&uf->uf_lock); 1367 } 1368 1369 1370 /* 1371 * Functions to handle power transition for OS levels 0 -> 3 1372 * The same level as OS state, different from USB state 1373 */ 1374 static int 1375 uftdi_pwrlvl0(uftdi_state_t *uf) 1376 { 1377 int rval; 1378 1379 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_pwrlvl0"); 1380 1381 switch (uf->uf_dev_state) { 1382 case USB_DEV_ONLINE: 1383 /* issue USB D3 command to the device */ 1384 rval = usb_set_device_pwrlvl3(uf->uf_dip); 1385 ASSERT(rval == USB_SUCCESS); 1386 1387 uf->uf_dev_state = USB_DEV_PWRED_DOWN; 1388 uf->uf_pm->pm_cur_power = USB_DEV_OS_PWR_OFF; 1389 1390 /*FALLTHROUGH*/ 1391 case USB_DEV_DISCONNECTED: 1392 case USB_DEV_SUSPENDED: 1393 /* allow a disconnect/cpr'ed device to go to lower power */ 1394 return (USB_SUCCESS); 1395 case USB_DEV_PWRED_DOWN: 1396 default: 1397 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, 1398 "uftdi_pwrlvl0: illegal device state"); 1399 return (USB_FAILURE); 1400 } 1401 } 1402 1403 1404 static int 1405 uftdi_pwrlvl1(uftdi_state_t *uf) 1406 { 1407 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_pwrlvl1"); 1408 1409 /* issue USB D2 command to the device */ 1410 (void) usb_set_device_pwrlvl2(uf->uf_dip); 1411 return (USB_FAILURE); 1412 } 1413 1414 1415 static int 1416 uftdi_pwrlvl2(uftdi_state_t *uf) 1417 { 1418 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_pwrlvl2"); 1419 1420 /* issue USB D1 command to the device */ 1421 (void) usb_set_device_pwrlvl1(uf->uf_dip); 1422 return (USB_FAILURE); 1423 } 1424 1425 1426 static int 1427 uftdi_pwrlvl3(uftdi_state_t *uf) 1428 { 1429 int rval; 1430 1431 USB_DPRINTF_L4(DPRINT_PM, uf->uf_lh, "uftdi_pwrlvl3"); 1432 1433 switch (uf->uf_dev_state) { 1434 case USB_DEV_PWRED_DOWN: 1435 /* Issue USB D0 command to the device here */ 1436 rval = usb_set_device_pwrlvl0(uf->uf_dip); 1437 ASSERT(rval == USB_SUCCESS); 1438 1439 uf->uf_dev_state = USB_DEV_ONLINE; 1440 uf->uf_pm->pm_cur_power = USB_DEV_OS_FULL_PWR; 1441 1442 /*FALLTHROUGH*/ 1443 case USB_DEV_ONLINE: 1444 /* we are already in full power */ 1445 1446 /*FALLTHROUGH*/ 1447 case USB_DEV_DISCONNECTED: 1448 case USB_DEV_SUSPENDED: 1449 return (USB_SUCCESS); 1450 default: 1451 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh, 1452 "uftdi_pwrlvl3: illegal device state"); 1453 return (USB_FAILURE); 1454 } 1455 } 1456 1457 1458 /* 1459 * pipe operations 1460 */ 1461 static int 1462 uftdi_open_pipes(uftdi_state_t *uf) 1463 { 1464 int ifc, alt; 1465 usb_pipe_policy_t policy; 1466 usb_ep_data_t *in_data, *out_data; 1467 1468 /* get ep data */ 1469 ifc = uf->uf_dev_data->dev_curr_if; 1470 alt = 0; 1471 1472 in_data = usb_lookup_ep_data(uf->uf_dip, uf->uf_dev_data, ifc, alt, 1473 0, USB_EP_ATTR_BULK, USB_EP_DIR_IN); 1474 1475 out_data = usb_lookup_ep_data(uf->uf_dip, uf->uf_dev_data, ifc, alt, 1476 0, USB_EP_ATTR_BULK, USB_EP_DIR_OUT); 1477 1478 if (in_data == NULL || out_data == NULL) { 1479 USB_DPRINTF_L2(DPRINT_ATTACH, uf->uf_lh, 1480 "uftdi_open_pipes: can't get ep data"); 1481 return (USB_FAILURE); 1482 } 1483 1484 /* open pipes */ 1485 policy.pp_max_async_reqs = 2; 1486 1487 if (usb_pipe_open(uf->uf_dip, &in_data->ep_descr, &policy, 1488 USB_FLAGS_SLEEP, &uf->uf_bulkin_ph) != USB_SUCCESS) 1489 return (USB_FAILURE); 1490 1491 if (usb_pipe_open(uf->uf_dip, &out_data->ep_descr, &policy, 1492 USB_FLAGS_SLEEP, &uf->uf_bulkout_ph) != USB_SUCCESS) { 1493 usb_pipe_close(uf->uf_dip, uf->uf_bulkin_ph, USB_FLAGS_SLEEP, 1494 NULL, NULL); 1495 return (USB_FAILURE); 1496 } 1497 1498 mutex_enter(&uf->uf_lock); 1499 uf->uf_bulkin_state = UFTDI_PIPE_IDLE; 1500 uf->uf_bulkout_state = UFTDI_PIPE_IDLE; 1501 mutex_exit(&uf->uf_lock); 1502 1503 return (USB_SUCCESS); 1504 } 1505 1506 1507 static void 1508 uftdi_close_pipes(uftdi_state_t *uf) 1509 { 1510 if (uf->uf_bulkin_ph) 1511 usb_pipe_close(uf->uf_dip, uf->uf_bulkin_ph, 1512 USB_FLAGS_SLEEP, 0, 0); 1513 if (uf->uf_bulkout_ph) 1514 usb_pipe_close(uf->uf_dip, uf->uf_bulkout_ph, 1515 USB_FLAGS_SLEEP, 0, 0); 1516 1517 mutex_enter(&uf->uf_lock); 1518 uf->uf_bulkin_state = UFTDI_PIPE_CLOSED; 1519 uf->uf_bulkout_state = UFTDI_PIPE_CLOSED; 1520 mutex_exit(&uf->uf_lock); 1521 } 1522 1523 1524 static void 1525 uftdi_disconnect_pipes(uftdi_state_t *uf) 1526 { 1527 uftdi_close_pipes(uf); 1528 } 1529 1530 1531 static int 1532 uftdi_reconnect_pipes(uftdi_state_t *uf) 1533 { 1534 return (uftdi_open_pipes(uf)); 1535 } 1536 1537 1538 static void 1539 uftdi_rxerr_put(mblk_t **rx_mpp, mblk_t *data, uint8_t lsr) 1540 { 1541 uchar_t errflg; 1542 1543 if (lsr & FTDI_LSR_STATUS_BI) { 1544 /* 1545 * parity and framing errors only "count" if they 1546 * occur independently of a break being received. 1547 */ 1548 lsr &= ~(uint8_t)(FTDI_LSR_STATUS_PE | FTDI_LSR_STATUS_FE); 1549 } 1550 errflg = 1551 ((lsr & FTDI_LSR_STATUS_OE) ? DS_OVERRUN_ERR : 0) | 1552 ((lsr & FTDI_LSR_STATUS_PE) ? DS_PARITY_ERR : 0) | 1553 ((lsr & FTDI_LSR_STATUS_FE) ? DS_FRAMING_ERR : 0) | 1554 ((lsr & FTDI_LSR_STATUS_BI) ? DS_BREAK_ERR : 0); 1555 1556 /* 1557 * If there's no actual data, we send a NUL character along 1558 * with the error flags. Otherwise, the data mblk contains 1559 * some number of highly questionable characters. 1560 * 1561 * According to FTDI tech support, there is no synchronous 1562 * error reporting i.e. we cannot assume that only the 1563 * first character in the mblk is bad -- so we treat all 1564 * of them them as if they have the error noted in the LSR. 1565 */ 1566 do { 1567 mblk_t *mp; 1568 uchar_t c = (MBLKL(data) == 0) ? '\0' : *data->b_rptr++; 1569 1570 if ((mp = allocb(2, BPRI_HI)) != NULL) { 1571 DB_TYPE(mp) = M_BREAK; 1572 *mp->b_wptr++ = errflg; 1573 *mp->b_wptr++ = c; 1574 uftdi_put_tail(rx_mpp, mp); 1575 } else { 1576 /* 1577 * low memory - just discard the bad data 1578 */ 1579 data->b_rptr = data->b_wptr; 1580 break; 1581 } 1582 } while (MBLKL(data) > 0); 1583 } 1584 1585 1586 /* 1587 * bulk in pipe normal and exception callback handler 1588 */ 1589 /*ARGSUSED*/ 1590 static void 1591 uftdi_bulkin_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 1592 { 1593 uftdi_state_t *uf = (uftdi_state_t *)req->bulk_client_private; 1594 mblk_t *data; 1595 int data_len; 1596 1597 data = req->bulk_data; 1598 data_len = data ? MBLKL(data) : 0; 1599 1600 /* 1601 * The first two bytes of data are status register bytes 1602 * that arrive with every packet from the device. Process 1603 * them here before handing the rest of the data on. 1604 * 1605 * When active, the device will send us these bytes at least 1606 * every 40 milliseconds, even if there's no received data. 1607 */ 1608 if (req->bulk_completion_reason == USB_CR_OK && data_len >= 2) { 1609 uint8_t msr = FTDI_GET_MSR(data->b_rptr); 1610 uint8_t lsr = FTDI_GET_LSR(data->b_rptr); 1611 int new_rx_err; 1612 1613 data->b_rptr += 2; 1614 1615 mutex_enter(&uf->uf_lock); 1616 1617 if (uf->uf_msr != msr) { 1618 /* 1619 * modem status register changed 1620 */ 1621 USB_DPRINTF_L3(DPRINT_IN_PIPE, uf->uf_lh, 1622 "uftdi_bulkin_cb: new msr: 0x%02x -> 0x%02x", 1623 uf->uf_msr, msr); 1624 1625 uf->uf_msr = msr; 1626 1627 if (uf->uf_port_state == UFTDI_PORT_OPEN && 1628 uf->uf_cb.cb_status) { 1629 mutex_exit(&uf->uf_lock); 1630 uf->uf_cb.cb_status(uf->uf_cb.cb_arg); 1631 mutex_enter(&uf->uf_lock); 1632 } 1633 } 1634 1635 if ((uf->uf_lsr & FTDI_LSR_MASK) != (lsr & FTDI_LSR_MASK)) { 1636 /* 1637 * line status register *receive* bits changed 1638 * 1639 * (The THRE and TEMT (transmit) status bits are 1640 * masked out above.) 1641 */ 1642 USB_DPRINTF_L3(DPRINT_IN_PIPE, uf->uf_lh, 1643 "uftdi_bulkin_cb: new lsr: 0x%02x -> 0x%02x", 1644 uf->uf_lsr, lsr); 1645 new_rx_err = B_TRUE; 1646 } else 1647 new_rx_err = B_FALSE; 1648 1649 uf->uf_lsr = lsr; /* THRE and TEMT captured here */ 1650 1651 if ((lsr & FTDI_LSR_MASK) != 0 && 1652 (MBLKL(data) > 0 || new_rx_err) && 1653 uf->uf_port_state == UFTDI_PORT_OPEN) { 1654 /* 1655 * The current line status register value indicates 1656 * that there's been some sort of unusual condition 1657 * on the receive side. We either received a break, 1658 * or got some badly formed characters from the 1659 * serial port - framing errors, overrun, parity etc. 1660 * So there's either some new data to post, or a 1661 * new error (break) to post, or both. 1662 * 1663 * Invoke uftdi_rxerr_put() to place the inbound 1664 * characters as M_BREAK messages on the receive 1665 * mblk chain, decorated with error flag(s) for 1666 * upper-level modules (e.g. ldterm) to process. 1667 */ 1668 mutex_exit(&uf->uf_lock); 1669 uftdi_rxerr_put(&uf->uf_rx_mp, data, lsr); 1670 ASSERT(MBLKL(data) == 0); 1671 1672 /* 1673 * Since we've converted all the received 1674 * characters into M_BREAK messages, we 1675 * invoke the rx callback to shove the mblks 1676 * up the STREAM. 1677 */ 1678 if (uf->uf_cb.cb_rx) 1679 uf->uf_cb.cb_rx(uf->uf_cb.cb_arg); 1680 mutex_enter(&uf->uf_lock); 1681 } 1682 1683 mutex_exit(&uf->uf_lock); 1684 data_len = MBLKL(data); 1685 } 1686 1687 USB_DPRINTF_L4(DPRINT_IN_PIPE, uf->uf_lh, "uftdi_bulkin_cb: " 1688 "cr=%d len=%d", req->bulk_completion_reason, data_len); 1689 1690 /* save data and notify GSD */ 1691 if (data_len > 0 && 1692 uf->uf_port_state == UFTDI_PORT_OPEN && 1693 req->bulk_completion_reason == USB_CR_OK) { 1694 req->bulk_data = NULL; 1695 uftdi_put_tail(&uf->uf_rx_mp, data); 1696 if (uf->uf_cb.cb_rx) 1697 uf->uf_cb.cb_rx(uf->uf_cb.cb_arg); 1698 } 1699 1700 usb_free_bulk_req(req); 1701 1702 /* receive more */ 1703 mutex_enter(&uf->uf_lock); 1704 uf->uf_bulkin_state = UFTDI_PIPE_IDLE; 1705 if (uf->uf_port_state == UFTDI_PORT_OPEN && 1706 uf->uf_dev_state == USB_DEV_ONLINE) { 1707 if (uftdi_rx_start(uf) != USB_SUCCESS) { 1708 USB_DPRINTF_L2(DPRINT_IN_PIPE, uf->uf_lh, 1709 "uftdi_bulkin_cb: restart rx fail"); 1710 } 1711 } 1712 mutex_exit(&uf->uf_lock); 1713 } 1714 1715 1716 /* 1717 * bulk out common and exception callback 1718 */ 1719 /*ARGSUSED*/ 1720 static void 1721 uftdi_bulkout_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req) 1722 { 1723 uftdi_state_t *uf = (uftdi_state_t *)req->bulk_client_private; 1724 int data_len; 1725 mblk_t *data = req->bulk_data; 1726 1727 data_len = data ? MBLKL(data) : 0; 1728 1729 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, 1730 "uftdi_bulkout_cb: cr=%d len=%d", 1731 req->bulk_completion_reason, data_len); 1732 1733 if (uf->uf_port_state == UFTDI_PORT_OPEN && 1734 req->bulk_completion_reason && data_len > 0) { 1735 uftdi_put_head(&uf->uf_tx_mp, data); 1736 req->bulk_data = NULL; 1737 } 1738 1739 usb_free_bulk_req(req); 1740 1741 /* notify GSD */ 1742 if (uf->uf_cb.cb_tx) 1743 uf->uf_cb.cb_tx(uf->uf_cb.cb_arg); 1744 1745 /* send more */ 1746 mutex_enter(&uf->uf_lock); 1747 uf->uf_bulkout_state = UFTDI_PIPE_IDLE; 1748 if (uf->uf_tx_mp == NULL) 1749 cv_broadcast(&uf->uf_tx_cv); 1750 else 1751 uftdi_tx_start(uf, NULL); 1752 mutex_exit(&uf->uf_lock); 1753 } 1754 1755 1756 /* 1757 * start receiving data 1758 */ 1759 static int 1760 uftdi_rx_start(uftdi_state_t *uf) 1761 { 1762 usb_bulk_req_t *br; 1763 int rval; 1764 1765 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, "uftdi_rx_start"); 1766 1767 ASSERT(mutex_owned(&uf->uf_lock)); 1768 1769 uf->uf_bulkin_state = UFTDI_PIPE_BUSY; 1770 mutex_exit(&uf->uf_lock); 1771 1772 br = usb_alloc_bulk_req(uf->uf_dip, uf->uf_xfer_sz, USB_FLAGS_SLEEP); 1773 br->bulk_len = uf->uf_xfer_sz; 1774 br->bulk_timeout = UFTDI_BULKIN_TIMEOUT; 1775 br->bulk_cb = uftdi_bulkin_cb; 1776 br->bulk_exc_cb = uftdi_bulkin_cb; 1777 br->bulk_client_private = (usb_opaque_t)uf; 1778 br->bulk_attributes = USB_ATTRS_AUTOCLEARING | USB_ATTRS_SHORT_XFER_OK; 1779 1780 rval = usb_pipe_bulk_xfer(uf->uf_bulkin_ph, br, 0); 1781 1782 if (rval != USB_SUCCESS) { 1783 USB_DPRINTF_L2(DPRINT_IN_PIPE, uf->uf_lh, 1784 "uftdi_rx_start: xfer failed %d", rval); 1785 usb_free_bulk_req(br); 1786 } 1787 1788 mutex_enter(&uf->uf_lock); 1789 if (rval != USB_SUCCESS) 1790 uf->uf_bulkin_state = UFTDI_PIPE_IDLE; 1791 1792 return (rval); 1793 } 1794 1795 1796 /* 1797 * start data transmit 1798 */ 1799 static void 1800 uftdi_tx_start(uftdi_state_t *uf, int *xferd) 1801 { 1802 int len; /* bytes we can transmit */ 1803 mblk_t *data; /* data to be transmitted */ 1804 int data_len; /* bytes in 'data' */ 1805 mblk_t *mp; /* current msgblk */ 1806 int copylen; /* bytes copy from 'mp' to 'data' */ 1807 int rval; 1808 1809 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, "uftdi_tx_start"); 1810 ASSERT(mutex_owned(&uf->uf_lock)); 1811 ASSERT(uf->uf_port_state != UFTDI_PORT_CLOSED); 1812 1813 if (xferd) 1814 *xferd = 0; 1815 if ((uf->uf_port_flags & UFTDI_PORT_TX_STOPPED) || 1816 uf->uf_tx_mp == NULL) { 1817 return; 1818 } 1819 if (uf->uf_bulkout_state != UFTDI_PIPE_IDLE) { 1820 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, 1821 "uftdi_tx_start: pipe busy"); 1822 return; 1823 } 1824 ASSERT(MBLKL(uf->uf_tx_mp) > 0); 1825 1826 /* send as much data as port can receive */ 1827 len = min(msgdsize(uf->uf_tx_mp), uf->uf_xfer_sz); 1828 1829 if (len <= 0) 1830 return; 1831 if ((data = allocb(len, BPRI_LO)) == NULL) 1832 return; 1833 1834 /* 1835 * copy no more than 'len' bytes from mblk chain to transmit mblk 'data' 1836 */ 1837 data_len = 0; 1838 while (data_len < len && uf->uf_tx_mp) { 1839 mp = uf->uf_tx_mp; 1840 copylen = min(MBLKL(mp), len - data_len); 1841 bcopy(mp->b_rptr, data->b_wptr, copylen); 1842 mp->b_rptr += copylen; 1843 data->b_wptr += copylen; 1844 data_len += copylen; 1845 1846 if (MBLKL(mp) < 1) { 1847 uf->uf_tx_mp = unlinkb(mp); 1848 freeb(mp); 1849 } else { 1850 ASSERT(data_len == len); 1851 } 1852 } 1853 1854 ASSERT(data_len > 0); 1855 1856 uf->uf_bulkout_state = UFTDI_PIPE_BUSY; 1857 mutex_exit(&uf->uf_lock); 1858 1859 rval = uftdi_send_data(uf, data); 1860 mutex_enter(&uf->uf_lock); 1861 1862 if (rval != USB_SUCCESS) { 1863 uf->uf_bulkout_state = UFTDI_PIPE_IDLE; 1864 uftdi_put_head(&uf->uf_tx_mp, data); 1865 } else { 1866 if (xferd) 1867 *xferd = data_len; 1868 } 1869 } 1870 1871 1872 static int 1873 uftdi_send_data(uftdi_state_t *uf, mblk_t *data) 1874 { 1875 usb_bulk_req_t *br; 1876 int len = MBLKL(data); 1877 int rval; 1878 1879 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, 1880 "uftdi_send_data: %d 0x%x 0x%x 0x%x", len, data->b_rptr[0], 1881 (len > 1) ? data->b_rptr[1] : 0, (len > 2) ? data->b_rptr[2] : 0); 1882 1883 ASSERT(!mutex_owned(&uf->uf_lock)); 1884 1885 br = usb_alloc_bulk_req(uf->uf_dip, 0, USB_FLAGS_SLEEP); 1886 br->bulk_data = data; 1887 br->bulk_len = len; 1888 br->bulk_timeout = UFTDI_BULKOUT_TIMEOUT; 1889 br->bulk_cb = uftdi_bulkout_cb; 1890 br->bulk_exc_cb = uftdi_bulkout_cb; 1891 br->bulk_client_private = (usb_opaque_t)uf; 1892 br->bulk_attributes = USB_ATTRS_AUTOCLEARING; 1893 1894 rval = usb_pipe_bulk_xfer(uf->uf_bulkout_ph, br, 0); 1895 1896 if (rval != USB_SUCCESS) { 1897 USB_DPRINTF_L2(DPRINT_OUT_PIPE, uf->uf_lh, 1898 "uftdi_send_data: xfer failed %d", rval); 1899 br->bulk_data = NULL; 1900 usb_free_bulk_req(br); 1901 } 1902 1903 return (rval); 1904 } 1905 1906 1907 /* 1908 * wait until local tx buffer drains. 1909 * 'timeout' is in seconds, zero means wait forever 1910 */ 1911 static int 1912 uftdi_wait_tx_drain(uftdi_state_t *uf, int timeout) 1913 { 1914 clock_t until; 1915 int over = 0; 1916 1917 until = ddi_get_lbolt() + drv_usectohz(1000 * 1000 * timeout); 1918 1919 while (uf->uf_tx_mp && !over) { 1920 if (timeout > 0) { 1921 /* whether timedout or signal pending */ 1922 over = cv_timedwait_sig(&uf->uf_tx_cv, 1923 &uf->uf_lock, until) <= 0; 1924 } else { 1925 /* whether a signal is pending */ 1926 over = cv_wait_sig(&uf->uf_tx_cv, 1927 &uf->uf_lock) == 0; 1928 } 1929 } 1930 1931 return (uf->uf_tx_mp == NULL ? USB_SUCCESS : USB_FAILURE); 1932 } 1933 1934 /* 1935 * initialize hardware serial port 1936 */ 1937 static int 1938 uftdi_open_hw_port(uftdi_state_t *uf, int portno, int dorestore) 1939 { 1940 int rval; 1941 1942 /* 1943 * Perform a full reset on the device 1944 */ 1945 rval = uftdi_cmd_vendor_write0(uf, 1946 FTDI_SIO_RESET, FTDI_SIO_RESET_SIO, portno); 1947 if (rval != USB_SUCCESS) { 1948 USB_DPRINTF_L2(DPRINT_DEF_PIPE, uf->uf_lh, 1949 "uftdi_open_hw_port: failed to reset!"); 1950 return (rval); 1951 } 1952 1953 if (dorestore) { 1954 /* 1955 * Restore settings from our soft copy of HW registers 1956 */ 1957 (void) uftdi_setregs(uf, portno, NULL); 1958 } else { 1959 /* 1960 * 9600 baud, 2 stop bits, no parity, 8-bit, h/w flow control 1961 */ 1962 static ds_port_param_entry_t ents[] = { 1963 #if defined(__lock_lint) 1964 /* 1965 * (Sigh - wlcc doesn't understand this newer 1966 * form of structure member initialization.) 1967 */ 1968 { 0 } 1969 #else 1970 { DS_PARAM_BAUD, .val.ui = B9600 }, 1971 { DS_PARAM_STOPB, .val.ui = CSTOPB }, 1972 { DS_PARAM_PARITY, .val.ui = 0 }, 1973 { DS_PARAM_CHARSZ, .val.ui = CS8 }, 1974 { DS_PARAM_FLOW_CTL, .val.ui = CTSXON } 1975 #endif 1976 }; 1977 static ds_port_params_t params = { 1978 ents, 1979 sizeof (ents) / sizeof (ents[0]) 1980 }; 1981 1982 rval = uftdi_set_port_params(uf, portno, ¶ms); 1983 if (rval != USB_SUCCESS) { 1984 USB_DPRINTF_L2(DPRINT_DEF_PIPE, uf->uf_lh, 1985 "uftdi_open_hw_port: failed 9600/2/n/8 rval %d", 1986 rval); 1987 } 1988 } 1989 1990 return (rval); 1991 } 1992 1993 static int 1994 uftdi_cmd_vendor_write0(uftdi_state_t *uf, 1995 uint16_t reqno, uint16_t val, uint16_t idx) 1996 { 1997 usb_ctrl_setup_t req; 1998 usb_cb_flags_t cb_flags; 1999 usb_cr_t cr; 2000 int rval; 2001 2002 ASSERT(!mutex_owned(&uf->uf_lock)); 2003 2004 req.bmRequestType = 2005 USB_DEV_REQ_TYPE_VENDOR | USB_DEV_REQ_HOST_TO_DEV; 2006 req.bRequest = (uchar_t)reqno; 2007 req.wValue = val; 2008 req.wIndex = idx; 2009 req.wLength = 0; 2010 req.attrs = USB_ATTRS_NONE; 2011 2012 if ((rval = usb_pipe_ctrl_xfer_wait(uf->uf_def_ph, 2013 &req, NULL, &cr, &cb_flags, 0)) != USB_SUCCESS) { 2014 USB_DPRINTF_L2(DPRINT_DEF_PIPE, uf->uf_lh, 2015 "uftdi_cmd_vendor_write0: 0x%x 0x%x 0x%x failed %d %d 0x%x", 2016 reqno, val, idx, rval, cr, cb_flags); 2017 } 2018 2019 return (rval); 2020 } 2021 2022 /* 2023 * misc routines 2024 */ 2025 2026 /* 2027 * link a message block to tail of message 2028 * account for the case when message is null 2029 */ 2030 static void 2031 uftdi_put_tail(mblk_t **mpp, mblk_t *bp) 2032 { 2033 if (*mpp) 2034 linkb(*mpp, bp); 2035 else 2036 *mpp = bp; 2037 } 2038 2039 /* 2040 * put a message block at the head of the message 2041 * account for the case when message is null 2042 */ 2043 static void 2044 uftdi_put_head(mblk_t **mpp, mblk_t *bp) 2045 { 2046 if (*mpp) 2047 linkb(bp, *mpp); 2048 *mpp = bp; 2049 } 2050 2051 /*ARGSUSED*/ 2052 static usb_pipe_handle_t 2053 uftdi_out_pipe(ds_hdl_t hdl, uint_t portno) 2054 { 2055 return (((uftdi_state_t *)hdl)->uf_bulkout_ph); 2056 } 2057 2058 /*ARGSUSED*/ 2059 static usb_pipe_handle_t 2060 uftdi_in_pipe(ds_hdl_t hdl, uint_t portno) 2061 { 2062 return (((uftdi_state_t *)hdl)->uf_bulkin_ph); 2063 } 2064