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