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, &params);
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 }