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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 28 /* 29 * 30 * DSD code for keyspan usb2serial adapters 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 48 #include <sys/usb/clients/usbser/usbser_dsdi.h> 49 #include <sys/usb/clients/usbser/usbser_keyspan/keyspan_var.h> 50 #include <sys/usb/clients/usbser/usbser_keyspan/keyspan_pipe.h> 51 52 #include <sys/usb/clients/usbser/usbser_keyspan/usa90msg.h> 53 #include <sys/usb/clients/usbser/usbser_keyspan/usa49msg.h> 54 55 /* 56 * DSD operations which are filled in ds_ops structure. 57 */ 58 static int keyspan_attach(ds_attach_info_t *); 59 static void keyspan_detach(ds_hdl_t); 60 static int keyspan_register_cb(ds_hdl_t, uint_t, ds_cb_t *); 61 static void keyspan_unregister_cb(ds_hdl_t, uint_t); 62 static int keyspan_open_port(ds_hdl_t, uint_t); 63 static int keyspan_close_port(ds_hdl_t, uint_t); 64 65 /* power management */ 66 static int keyspan_usb_power(ds_hdl_t, int, int, int *); 67 static int keyspan_suspend(ds_hdl_t); 68 static int keyspan_resume(ds_hdl_t); 69 70 /* hotplug */ 71 static int keyspan_disconnect(ds_hdl_t); 72 static int keyspan_reconnect(ds_hdl_t); 73 74 /* standard UART operations */ 75 static int keyspan_set_port_params(ds_hdl_t, uint_t, ds_port_params_t *); 76 static int keyspan_set_modem_ctl(ds_hdl_t, uint_t, int, int); 77 static int keyspan_get_modem_ctl(ds_hdl_t, uint_t, int, int *); 78 static int keyspan_break_ctl(ds_hdl_t, uint_t, int); 79 static int keyspan_loopback(ds_hdl_t, uint_t, int); 80 81 /* data xfer */ 82 static int keyspan_tx(ds_hdl_t, uint_t, mblk_t *); 83 static mblk_t *keyspan_rx(ds_hdl_t, uint_t); 84 static void keyspan_stop(ds_hdl_t, uint_t, int); 85 static void keyspan_start(ds_hdl_t, uint_t, int); 86 static int keyspan_fifo_flush(ds_hdl_t, uint_t, int); 87 static int keyspan_fifo_drain(ds_hdl_t, uint_t, int); 88 89 /* 90 * Sub-routines 91 */ 92 93 /* configuration routines */ 94 static void keyspan_free_soft_state(keyspan_state_t *); 95 static void keyspan_init_sync_objs(keyspan_state_t *); 96 static void keyspan_fini_sync_objs(keyspan_state_t *); 97 static int keyspan_usb_register(keyspan_state_t *); 98 static void keyspan_usb_unregister(keyspan_state_t *); 99 static int keyspan_attach_dev(keyspan_state_t *); 100 static void keyspan_attach_ports(keyspan_state_t *); 101 static void keyspan_detach_ports(keyspan_state_t *); 102 static void keyspan_init_port_params(keyspan_state_t *); 103 static void keyspan_free_descr_tree(keyspan_state_t *); 104 static int keyspan_register_events(keyspan_state_t *); 105 static void keyspan_unregister_events(keyspan_state_t *); 106 static void keyspan_set_dev_state_online(keyspan_state_t *); 107 108 /* hotplug */ 109 static int keyspan_restore_device_state(keyspan_state_t *); 110 static int keyspan_restore_ports_state(keyspan_state_t *); 111 112 /* power management */ 113 static int keyspan_create_pm_components(keyspan_state_t *); 114 static void keyspan_destroy_pm_components(keyspan_state_t *); 115 static int keyspan_pm_set_busy(keyspan_state_t *); 116 static void keyspan_pm_set_idle(keyspan_state_t *); 117 static int keyspan_pwrlvl0(keyspan_state_t *); 118 static int keyspan_pwrlvl1(keyspan_state_t *); 119 static int keyspan_pwrlvl2(keyspan_state_t *); 120 static int keyspan_pwrlvl3(keyspan_state_t *); 121 122 /* pipe operations */ 123 static int keyspan_attach_pipes(keyspan_state_t *); 124 static void keyspan_detach_pipes(keyspan_state_t *); 125 static void keyspan_disconnect_pipes(keyspan_state_t *); 126 static int keyspan_reconnect_pipes(keyspan_state_t *); 127 128 /* data transfer routines */ 129 static int keyspan_wait_tx_drain(keyspan_port_t *, int); 130 131 /* misc */ 132 static void keyspan_default_port_params(keyspan_port_t *); 133 static void keyspan_build_cmd_msg(keyspan_port_t *, ds_port_params_t *); 134 static void keyspan_save_port_params(keyspan_port_t *); 135 136 /* 137 * Model specific functions. 138 */ 139 140 /* usa19hs specific functions */ 141 static void keyspan_build_cmd_msg_usa19hs(keyspan_port_t *, 142 ds_port_params_t *); 143 static void keyspan_default_port_params_usa19hs(keyspan_port_t *); 144 static void keyspan_save_port_params_usa19hs(keyspan_port_t *); 145 146 147 /* usa49 specific functions */ 148 static void keyspan_build_cmd_msg_usa49(keyspan_port_t *, 149 ds_port_params_t *); 150 static void keyspan_default_port_params_usa49(keyspan_port_t *); 151 static void keyspan_save_port_params_usa49(keyspan_port_t *); 152 153 154 /* 155 * DSD ops structure 156 */ 157 ds_ops_t ds_ops = { 158 DS_OPS_VERSION, 159 keyspan_attach, 160 keyspan_detach, 161 keyspan_register_cb, 162 keyspan_unregister_cb, 163 keyspan_open_port, 164 keyspan_close_port, 165 keyspan_usb_power, 166 keyspan_suspend, 167 keyspan_resume, 168 keyspan_disconnect, 169 keyspan_reconnect, 170 keyspan_set_port_params, 171 keyspan_set_modem_ctl, 172 keyspan_get_modem_ctl, 173 keyspan_break_ctl, 174 keyspan_loopback, 175 keyspan_tx, 176 keyspan_rx, 177 keyspan_stop, 178 keyspan_start, 179 keyspan_fifo_flush, 180 keyspan_fifo_drain 181 }; 182 183 /* 184 * For USA19HS baud speed, precalculated using the following algorithm: 185 * 186 * speed = (uint16_t)(14769231L / baud); 187 */ 188 static uint16_t keyspan_speedtab_usa19hs[] = { 189 0x0, /* B0 */ 190 0x481d, /* B50 */ 191 0x3013, /* B75 */ 192 0x20c7, /* B110 */ 193 0x1ae8, /* B134 */ 194 0x1809, /* B150 */ 195 0x1207, /* B200 */ 196 0xc04, /* B300 */ 197 0x602, /* B600 */ 198 0x301, /* B1200 */ 199 0x200, /* B1800 */ 200 0x180, /* B2400 */ 201 0xc0, /* B4800 */ 202 0x60, /* B9600 */ 203 0x30, /* B19200 */ 204 0x18, /* B38400 */ 205 0x10, /* B57600 */ 206 0xc, /* B76800 */ 207 0x8, /* B115200 */ 208 0x6, /* B153600 */ 209 0x4, /* B230400 */ 210 }; 211 212 /* 213 * For USA49WLC baud speed, precalculated. 214 */ 215 static uint16_t keyspan_speedtab_usa49[] = { 216 0x0, /* B0 */ 217 0x7530, /* B50 */ 218 0x4e20, /* B75 */ 219 0x3544, /* B110 */ 220 0x2bba, /* B134 */ 221 0x2710, /* B150 */ 222 0x1d4c, /* B200 */ 223 0x1388, /* B300 */ 224 0x9c4, /* B600 */ 225 0x4e2, /* B1200 */ 226 0x25e, /* B1800 */ 227 0x271, /* B2400 */ 228 0xfa, /* B4800 */ 229 0x7d, /* B9600 */ 230 0x19, /* B19200 */ 231 0x27, /* B38400 */ 232 0x1a, /* B57600 */ 233 0xd, /* B76800 */ 234 0xd, /* B115200 */ 235 0x6, /* B153600 */ 236 0x4, /* B230400 */ 237 }; 238 239 /* 240 * For USA49WLC prescaler, precalculated. 241 */ 242 static uint8_t keyspan_prescaler_49wlc[] = { 243 0x0, /* B0 */ 244 0x8, /* B50 */ 245 0x8, /* B75 */ 246 0x8, /* B110 */ 247 0x8, /* B134 */ 248 0x8, /* B150 */ 249 0x8, /* B200 */ 250 0x8, /* B300 */ 251 0x8, /* B600 */ 252 0x8, /* B1200 */ 253 0xb, /* B1800 */ 254 0x8, /* B2400 */ 255 0xa, /* B4800 */ 256 0xa, /* B9600 */ 257 0x19, /* B19200 */ 258 0x8, /* B38400 */ 259 0x8, /* B57600 */ 260 0xc, /* B76800 */ 261 0x8, /* B115200 */ 262 0xd, /* B153600 */ 263 0xd, /* B230400 */ 264 }; 265 266 267 /* convert baud code into baud rate */ 268 static int keyspan_speed2baud[] = { 269 0, /* B0 */ 270 50, /* B50 */ 271 75, /* B75 */ 272 110, /* B110 */ 273 134, /* B134 */ 274 150, /* B150 */ 275 200, /* B200 */ 276 300, /* B300 */ 277 600, /* B600 */ 278 1200, /* B1200 */ 279 1800, /* B1800 */ 280 2400, /* B2400 */ 281 4800, /* B4800 */ 282 9600, /* B9600 */ 283 19200, /* B19200 */ 284 38400, /* B38400 */ 285 57600, /* B57600 */ 286 76800, /* B76800 */ 287 115200, /* B115200 */ 288 153600, /* B153600 */ 289 230400, /* B230400 */ 290 }; 291 292 293 /* debug support */ 294 static uint_t keyspan_errlevel = USB_LOG_L4; 295 static uint_t keyspan_errmask = DPRINT_MASK_ALL; 296 static uint_t keyspan_instance_debug = (uint_t)-1; 297 298 static int 299 keyspan_attach(ds_attach_info_t *aip) 300 { 301 keyspan_state_t *ksp; 302 int rval = USB_SUCCESS; 303 304 ksp = (keyspan_state_t *)kmem_zalloc(sizeof (keyspan_state_t), 305 KM_SLEEP); 306 ksp->ks_dip = aip->ai_dip; 307 ksp->ks_usb_events = aip->ai_usb_events; 308 *aip->ai_hdl = (ds_hdl_t)ksp; 309 310 if (keyspan_usb_register(ksp) != USB_SUCCESS) { 311 312 goto fail_register; 313 } 314 315 /* init mutex and semaphore */ 316 keyspan_init_sync_objs(ksp); 317 318 /* get device specific parameters */ 319 if (keyspan_attach_dev(ksp) != USB_SUCCESS) { 320 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, "fail attach dev "); 321 322 goto fail_attach_dev; 323 } 324 325 keyspan_attach_ports(ksp); 326 327 switch (ksp->ks_dev_spec.id_product) { 328 case KEYSPAN_USA19HS_PID: 329 case KEYSPAN_USA49WLC_PID: 330 rval = keyspan_init_pipes(ksp); 331 332 break; 333 334 case KEYSPAN_USA49WG_PID: 335 rval = keyspan_init_pipes_usa49wg(ksp); 336 337 break; 338 339 default: 340 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, "keyspan_attach:" 341 "the device's product id can't be recognized"); 342 343 return (USB_FAILURE); 344 } 345 346 if (rval != USB_SUCCESS) { 347 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 348 "keyspan_init_pipes: failed."); 349 350 goto fail_init_pipes; 351 } 352 353 keyspan_init_port_params(ksp); 354 keyspan_free_descr_tree(ksp); 355 keyspan_set_dev_state_online(ksp); 356 357 if (keyspan_create_pm_components(ksp) != USB_SUCCESS) { 358 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 359 "keyspan_create_pm_components: failed."); 360 361 goto fail_pm; 362 } 363 364 if (keyspan_register_events(ksp) != USB_SUCCESS) { 365 366 goto fail_events; 367 } 368 369 /* open the global pipes */ 370 if (keyspan_attach_pipes(ksp) != USB_SUCCESS) { 371 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 372 "keyspan_attach_pipes: failed."); 373 374 goto fail_attach_pipes; 375 } 376 377 *aip->ai_port_cnt = ksp->ks_dev_spec.port_cnt; 378 379 return (USB_SUCCESS); 380 381 fail_attach_pipes: 382 keyspan_unregister_events(ksp); 383 fail_events: 384 keyspan_destroy_pm_components(ksp); 385 fail_pm: 386 keyspan_fini_pipes(ksp); 387 fail_init_pipes: 388 keyspan_detach_ports(ksp); 389 fail_attach_dev: 390 keyspan_fini_sync_objs(ksp); 391 keyspan_usb_unregister(ksp); 392 fail_register: 393 keyspan_free_soft_state(ksp); 394 395 return (USB_FAILURE); 396 } 397 398 399 /* 400 * ds_detach 401 */ 402 static void 403 keyspan_detach(ds_hdl_t hdl) 404 { 405 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 406 407 keyspan_detach_pipes(ksp); 408 keyspan_unregister_events(ksp); 409 keyspan_destroy_pm_components(ksp); 410 keyspan_fini_pipes(ksp); 411 keyspan_detach_ports(ksp); 412 keyspan_fini_sync_objs(ksp); 413 keyspan_usb_unregister(ksp); 414 keyspan_free_soft_state(ksp); 415 } 416 417 /* 418 * ds_register_cb 419 */ 420 static int 421 keyspan_register_cb(ds_hdl_t hdl, uint_t port_num, ds_cb_t *cb) 422 { 423 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 424 keyspan_port_t *kp; 425 426 if (port_num >= ksp->ks_dev_spec.port_cnt) { 427 428 return (USB_FAILURE); 429 } 430 kp = &ksp->ks_ports[port_num]; 431 kp->kp_cb = *cb; 432 433 return (USB_SUCCESS); 434 } 435 436 /* 437 * ds_unregister_cb 438 */ 439 static void 440 keyspan_unregister_cb(ds_hdl_t hdl, uint_t port_num) 441 { 442 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 443 keyspan_port_t *kp; 444 445 if (port_num < ksp->ks_dev_spec.port_cnt) { 446 kp = &ksp->ks_ports[port_num]; 447 bzero(&kp->kp_cb, sizeof (kp->kp_cb)); 448 } 449 } 450 451 /* 452 * initialize hardware serial port 453 * 454 * 'open_pipes' specifies whether to open USB pipes or not 455 */ 456 int 457 keyspan_open_hw_port(keyspan_port_t *kp, boolean_t open_pipes) 458 { 459 int rval; 460 keyspan_state_t *ksp = kp->kp_ksp; 461 462 USB_DPRINTF_L4(DPRINT_OPEN, kp->kp_lh, 463 "keyspan_open_hw_port: [%d]", kp->kp_port_num); 464 465 if (open_pipes) { 466 467 /* open r/w pipes for this port */ 468 if ((rval = keyspan_open_port_pipes(kp)) != USB_SUCCESS) { 469 470 return (rval); 471 } 472 } 473 474 mutex_enter(&kp->kp_mutex); 475 kp->kp_state = KEYSPAN_PORT_OPEN; 476 mutex_exit(&kp->kp_mutex); 477 478 switch (ksp->ks_dev_spec.id_product) { 479 case KEYSPAN_USA19HS_PID: 480 case KEYSPAN_USA49WLC_PID: 481 if ((rval = keyspan_receive_data(&kp->kp_datain_pipe, 482 kp->kp_read_len, kp)) != USB_SUCCESS) { 483 484 goto fail; 485 } 486 487 break; 488 489 case KEYSPAN_USA49WG_PID: 490 mutex_enter(&ksp->ks_mutex); 491 /* open data in pipe the first time, start receiving data */ 492 if ((ksp->ks_datain_open_cnt == 1) && open_pipes) { 493 mutex_exit(&ksp->ks_mutex); 494 if ((rval = keyspan_receive_data(&kp->kp_datain_pipe, 495 kp->kp_read_len, kp)) != USB_SUCCESS) { 496 497 goto fail; 498 } 499 /* the device is reconnected to host, restart receiving data */ 500 } else if ((ksp->ks_reconnect_flag) && (!open_pipes)) { 501 mutex_exit(&ksp->ks_mutex); 502 if ((rval = keyspan_receive_data(&kp->kp_datain_pipe, 503 kp->kp_read_len, kp)) != USB_SUCCESS) { 504 505 goto fail; 506 } 507 mutex_enter(&ksp->ks_mutex); 508 ksp->ks_reconnect_flag = 0; 509 mutex_exit(&ksp->ks_mutex); 510 511 } else { 512 mutex_exit(&ksp->ks_mutex); 513 } 514 515 break; 516 517 default: 518 USB_DPRINTF_L2(DPRINT_OPEN, ksp->ks_lh, "keyspan_open_hw_port:" 519 "the device's product id can't be recognized"); 520 521 return (USB_FAILURE); 522 } 523 524 /* set the default port parameters and send cmd msg to enable port */ 525 mutex_enter(&kp->kp_mutex); 526 keyspan_default_port_params(kp); 527 mutex_exit(&kp->kp_mutex); 528 529 (void) keyspan_send_cmd(kp); 530 531 USB_DPRINTF_L4(DPRINT_OPEN, kp->kp_lh, 532 "keyspan_open_hw_port: [%d] finished", kp->kp_port_num); 533 534 return (rval); 535 536 fail: 537 538 mutex_enter(&kp->kp_mutex); 539 kp->kp_state = KEYSPAN_PORT_CLOSED; 540 mutex_exit(&kp->kp_mutex); 541 542 if (open_pipes) { 543 544 /* close all ports' data pipes */ 545 keyspan_close_port_pipes(kp); 546 } 547 548 USB_DPRINTF_L2(DPRINT_OPEN, kp->kp_lh, 549 "keyspan_open_hw_port: failed. This port can't be used."); 550 551 return (rval); 552 } 553 554 /* 555 * ds_open_port 556 */ 557 static int 558 keyspan_open_port(ds_hdl_t hdl, uint_t port_num) 559 { 560 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 561 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 562 int rval; 563 564 if (port_num >= ksp->ks_dev_spec.port_cnt) { 565 566 return (USB_FAILURE); 567 } 568 USB_DPRINTF_L4(DPRINT_OPEN, kp->kp_lh, "keyspan_open_port"); 569 570 mutex_enter(&ksp->ks_mutex); 571 if (ksp->ks_dev_state == USB_DEV_DISCONNECTED) { 572 mutex_exit(&ksp->ks_mutex); 573 574 return (USB_FAILURE); 575 } 576 mutex_exit(&ksp->ks_mutex); 577 578 if (keyspan_pm_set_busy(ksp) != USB_SUCCESS) { 579 580 return (USB_FAILURE); 581 } 582 583 /* 584 * initialize state 585 */ 586 mutex_enter(&kp->kp_mutex); 587 ASSERT(kp->kp_state == KEYSPAN_PORT_CLOSED); 588 ASSERT((kp->kp_rx_mp == NULL) && (kp->kp_tx_mp == NULL)); 589 590 kp->kp_state = KEYSPAN_PORT_OPENING; 591 kp->kp_flags = 0; 592 mutex_exit(&kp->kp_mutex); 593 594 /* 595 * initialize hardware serial port, B_TRUE means open pipes 596 */ 597 sema_p(&ksp->ks_pipes_sema); 598 rval = keyspan_open_hw_port(kp, B_TRUE); 599 if (rval != USB_SUCCESS) { 600 keyspan_pm_set_idle(ksp); 601 } 602 sema_v(&ksp->ks_pipes_sema); 603 604 return (rval); 605 } 606 607 608 /* 609 * close hardware serial port 610 */ 611 void 612 keyspan_close_hw_port(keyspan_port_t *kp) 613 { 614 keyspan_state_t *ksp = kp->kp_ksp; 615 616 ASSERT(!mutex_owned(&kp->kp_mutex)); 617 618 USB_DPRINTF_L4(DPRINT_CLOSE, kp->kp_lh, 619 "keyspan_close_hw_port"); 620 621 /* 622 * The bulk IN/OUT pipes might have got closed due to 623 * a device disconnect event. So its required to check the 624 * pipe handle and proceed if it is not NULL 625 */ 626 627 mutex_enter(&kp->kp_mutex); 628 if ((kp->kp_datain_pipe.pipe_handle == NULL) && 629 (kp->kp_dataout_pipe.pipe_handle == NULL)) { 630 mutex_exit(&kp->kp_mutex); 631 632 return; 633 } 634 635 switch (ksp->ks_dev_spec.id_product) { 636 case KEYSPAN_USA19HS_PID: 637 keyspan_build_cmd_msg_usa19hs(kp, NULL); 638 kp->kp_ctrl_msg.usa19hs.portEnabled = 0; 639 kp->kp_ctrl_msg.usa19hs.rxFlush = 0; 640 kp->kp_ctrl_msg.usa19hs.txFlush = 0; 641 kp->kp_ctrl_msg.usa19hs.returnStatus = 0; 642 kp->kp_ctrl_msg.usa19hs.setRts = 1; 643 kp->kp_ctrl_msg.usa19hs.rts = 0; 644 kp->kp_ctrl_msg.usa19hs.setDtr = 1; 645 kp->kp_ctrl_msg.usa19hs.dtr = 0; 646 kp->kp_ctrl_msg.usa19hs.setTxFlowControl = 1; 647 kp->kp_ctrl_msg.usa19hs.txFlowControl = 0; 648 kp->kp_ctrl_msg.usa19hs.setRxFlowControl = 1; 649 kp->kp_ctrl_msg.usa19hs.rxFlowControl = 0; 650 kp->kp_ctrl_msg.usa19hs.rxForwardingTimeout = 0; 651 kp->kp_ctrl_msg.usa19hs.rxForwardingLength = 0; 652 653 break; 654 655 656 case KEYSPAN_USA49WLC_PID: 657 case KEYSPAN_USA49WG_PID: 658 keyspan_build_cmd_msg_usa49(kp, NULL); 659 kp->kp_ctrl_msg.usa49._txOn = 0; 660 kp->kp_ctrl_msg.usa49._txOff = 1; 661 kp->kp_ctrl_msg.usa49.txFlush = 0; 662 kp->kp_ctrl_msg.usa49.txBreak = 0; 663 kp->kp_ctrl_msg.usa49.rxOn = 0; 664 kp->kp_ctrl_msg.usa49.rxOff = 1; 665 kp->kp_ctrl_msg.usa49.rxFlush = 0; 666 kp->kp_ctrl_msg.usa49.rxForward = 0; 667 kp->kp_ctrl_msg.usa49.returnStatus = 0; 668 kp->kp_ctrl_msg.usa49.resetDataToggle = 0; 669 kp->kp_ctrl_msg.usa49.enablePort = 0; 670 kp->kp_ctrl_msg.usa49.disablePort = 1; 671 672 break; 673 674 default: 675 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 676 "keyspan_close_hw_port:" 677 "the device's product id can't be recognized"); 678 mutex_exit(&kp->kp_mutex); 679 680 return; 681 } 682 683 mutex_exit(&kp->kp_mutex); 684 /* send close port cmd to this port */ 685 if (keyspan_send_cmd(kp) != USB_SUCCESS) { 686 USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh, 687 "keyspan_close_hw_port: closing hw port, send cmd FAILED"); 688 } 689 690 /* blow away bulkin requests or pipe close will wait until timeout */ 691 switch (ksp->ks_dev_spec.id_product) { 692 case KEYSPAN_USA19HS_PID: 693 case KEYSPAN_USA49WLC_PID: 694 usb_pipe_reset(ksp->ks_dip, 695 kp->kp_datain_pipe.pipe_handle, 696 USB_FLAGS_SLEEP, NULL, NULL); 697 698 break; 699 case KEYSPAN_USA49WG_PID: 700 mutex_enter(&ksp->ks_mutex); 701 /* 702 * if only this port is opened, shared data in pipe 703 * can be reset. 704 */ 705 if (ksp->ks_datain_open_cnt == 1) { 706 mutex_exit(&ksp->ks_mutex); 707 708 usb_pipe_reset(ksp->ks_dip, 709 kp->kp_datain_pipe.pipe_handle, 710 USB_FLAGS_SLEEP, NULL, NULL); 711 } else { 712 mutex_exit(&ksp->ks_mutex); 713 } 714 715 break; 716 default: 717 USB_DPRINTF_L2(DPRINT_CLOSE, kp->kp_lh, 718 "keyspan_close_hw_port: the device's" 719 " product id can't be recognized"); 720 } 721 722 (void) keyspan_close_port_pipes(kp); 723 } 724 725 /* 726 * ds_close_port 727 */ 728 static int 729 keyspan_close_port(ds_hdl_t hdl, uint_t port_num) 730 { 731 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 732 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 733 734 if (port_num >= ksp->ks_dev_spec.port_cnt) { 735 736 return (USB_FAILURE); 737 } 738 USB_DPRINTF_L4(DPRINT_CLOSE, kp->kp_lh, "keyspan_close_port"); 739 740 sema_p(&ksp->ks_pipes_sema); 741 mutex_enter(&kp->kp_mutex); 742 kp->kp_no_more_reads = B_TRUE; 743 744 /* close hardware serial port */ 745 mutex_exit(&kp->kp_mutex); 746 747 keyspan_close_hw_port(kp); 748 mutex_enter(&kp->kp_mutex); 749 750 /* 751 * free resources and finalize state 752 */ 753 if (kp->kp_rx_mp) { 754 freemsg(kp->kp_rx_mp); 755 kp->kp_rx_mp = NULL; 756 } 757 if (kp->kp_tx_mp) { 758 freemsg(kp->kp_tx_mp); 759 kp->kp_tx_mp = NULL; 760 } 761 762 kp->kp_no_more_reads = B_FALSE; 763 kp->kp_state = KEYSPAN_PORT_CLOSED; 764 mutex_exit(&kp->kp_mutex); 765 766 keyspan_pm_set_idle(ksp); 767 768 sema_v(&ksp->ks_pipes_sema); 769 770 return (USB_SUCCESS); 771 } 772 773 /* 774 * power management 775 * 776 * ds_usb_power 777 */ 778 /*ARGSUSED*/ 779 static int 780 keyspan_usb_power(ds_hdl_t hdl, int comp, int level, int *new_state) 781 { 782 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 783 keyspan_pm_t *pm = ksp->ks_pm; 784 int rval; 785 786 USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_usb_power"); 787 788 mutex_enter(&ksp->ks_mutex); 789 790 /* 791 * check if we are transitioning to a legal power level 792 */ 793 if (USB_DEV_PWRSTATE_OK(pm->pm_pwr_states, level)) { 794 USB_DPRINTF_L2(DPRINT_PM, ksp->ks_lh, "keyspan_usb_power:" 795 "illegal power level %d, pwr_states=%x", 796 level, pm->pm_pwr_states); 797 mutex_exit(&ksp->ks_mutex); 798 799 return (USB_FAILURE); 800 } 801 802 /* 803 * if we are about to raise power and asked to lower power, fail 804 */ 805 if (pm->pm_raise_power && (level < (int)pm->pm_cur_power)) { 806 mutex_exit(&ksp->ks_mutex); 807 808 return (USB_FAILURE); 809 } 810 811 switch (level) { 812 case USB_DEV_OS_PWR_OFF: 813 rval = keyspan_pwrlvl0(ksp); 814 815 break; 816 case USB_DEV_OS_PWR_1: 817 rval = keyspan_pwrlvl1(ksp); 818 819 break; 820 case USB_DEV_OS_PWR_2: 821 rval = keyspan_pwrlvl2(ksp); 822 823 break; 824 case USB_DEV_OS_FULL_PWR: 825 rval = keyspan_pwrlvl3(ksp); 826 /* 827 * If usbser dev_state is DISCONNECTED or SUSPENDED, it shows 828 * that the usb serial device is disconnected/suspended while it 829 * is under power down state, now the device is powered up 830 * before it is reconnected/resumed. xxx_pwrlvl3() will set dev 831 * state to ONLINE, we need to set the dev state back to 832 * DISCONNECTED/SUSPENDED. 833 */ 834 if ((rval == USB_SUCCESS) && 835 ((*new_state == USB_DEV_DISCONNECTED) || 836 (*new_state == USB_DEV_SUSPENDED))) { 837 ksp->ks_dev_state = *new_state; 838 } 839 840 break; 841 default: 842 ASSERT(0); /* cannot happen */ 843 } 844 845 *new_state = ksp->ks_dev_state; 846 mutex_exit(&ksp->ks_mutex); 847 848 return (rval); 849 } 850 851 852 /* 853 * ds_suspend 854 */ 855 static int 856 keyspan_suspend(ds_hdl_t hdl) 857 { 858 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 859 int state = USB_DEV_SUSPENDED; 860 861 USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_suspend"); 862 863 /* 864 * If the device is suspended while it is under PWRED_DOWN state, we 865 * need to keep the PWRED_DOWN state so that it could be powered up 866 * later. In the mean while, usbser dev state will be changed to 867 * SUSPENDED state. 868 */ 869 mutex_enter(&ksp->ks_mutex); 870 if (ksp->ks_dev_state != USB_DEV_PWRED_DOWN) { 871 ksp->ks_dev_state = USB_DEV_SUSPENDED; 872 } 873 mutex_exit(&ksp->ks_mutex); 874 875 keyspan_disconnect_pipes(ksp); 876 877 return (state); 878 } 879 880 881 /* 882 * ds_resume 883 */ 884 static int 885 keyspan_resume(ds_hdl_t hdl) 886 { 887 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 888 int current_state; 889 int rval; 890 891 USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_resume"); 892 893 mutex_enter(&ksp->ks_mutex); 894 current_state = ksp->ks_dev_state; 895 mutex_exit(&ksp->ks_mutex); 896 897 if (current_state != USB_DEV_ONLINE) { 898 rval = keyspan_restore_device_state(ksp); 899 } else { 900 rval = USB_SUCCESS; 901 } 902 903 return (rval); 904 } 905 906 907 /* 908 * ds_disconnect 909 */ 910 static int 911 keyspan_disconnect(ds_hdl_t hdl) 912 { 913 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 914 int state = USB_DEV_DISCONNECTED; 915 916 USB_DPRINTF_L4(DPRINT_HOTPLUG, ksp->ks_lh, "keyspan_disconnect"); 917 918 /* 919 * If the device is disconnected while it is under PWRED_DOWN state, we 920 * need to keep the PWRED_DOWN state so that it could be powered up 921 * later. In the mean while, usbser dev state will be changed to 922 * DISCONNECTED state. 923 */ 924 mutex_enter(&ksp->ks_mutex); 925 if (ksp->ks_dev_state != USB_DEV_PWRED_DOWN) { 926 ksp->ks_dev_state = USB_DEV_DISCONNECTED; 927 } 928 mutex_exit(&ksp->ks_mutex); 929 930 keyspan_disconnect_pipes(ksp); 931 932 return (state); 933 } 934 935 936 /* 937 * ds_reconnect 938 */ 939 static int 940 keyspan_reconnect(ds_hdl_t hdl) 941 { 942 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 943 944 USB_DPRINTF_L4(DPRINT_HOTPLUG, ksp->ks_lh, "keyspan_reconnect"); 945 946 return (keyspan_restore_device_state(ksp)); 947 } 948 949 /* 950 * ds_set_port_params 951 */ 952 static int 953 keyspan_set_port_params(ds_hdl_t hdl, uint_t port_num, ds_port_params_t *tp) 954 { 955 int cnt = tp->tp_cnt; 956 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 957 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 958 959 ASSERT(port_num < ksp->ks_dev_spec.port_cnt); 960 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, 961 "keyspan_set_port_params: port: %d params", cnt); 962 963 if (cnt <= 0) { 964 965 return (USB_SUCCESS); 966 } 967 968 mutex_enter(&kp->kp_mutex); 969 ASSERT((kp->kp_state == KEYSPAN_PORT_OPENING) || 970 (kp->kp_state == KEYSPAN_PORT_OPEN)); 971 keyspan_build_cmd_msg(kp, tp); 972 mutex_exit(&kp->kp_mutex); 973 974 if (keyspan_send_cmd(kp) != USB_SUCCESS) { 975 USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh, 976 "keyspan_send_cmd() FAILED"); 977 978 return (USB_FAILURE); 979 } 980 981 return (USB_SUCCESS); 982 } 983 984 985 /* 986 * ds_set_modem_ctl 987 */ 988 static int 989 keyspan_set_modem_ctl(ds_hdl_t hdl, uint_t port_num, int mask, int val) 990 { 991 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 992 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 993 994 ASSERT(port_num < ksp->ks_dev_spec.port_cnt); 995 996 mutex_enter(&kp->kp_mutex); 997 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_set_modem_ctl: " 998 "mask=%x, val=%x", mask, val); 999 1000 keyspan_build_cmd_msg(kp, NULL); 1001 1002 switch (ksp->ks_dev_spec.id_product) { 1003 case KEYSPAN_USA19HS_PID: 1004 if (mask & TIOCM_RTS) { 1005 1006 kp->kp_ctrl_msg.usa19hs.setRts = 0x01; 1007 1008 if (val & TIOCM_RTS) { 1009 kp->kp_ctrl_msg.usa19hs.rts = 0x1; 1010 } else { 1011 kp->kp_ctrl_msg.usa19hs.rts = 0x0; 1012 } 1013 1014 } else { 1015 kp->kp_ctrl_msg.usa19hs.setRts = 0x0; 1016 } 1017 1018 if (mask & TIOCM_DTR) { 1019 kp->kp_ctrl_msg.usa19hs.setDtr = 0x01; 1020 1021 if (val & TIOCM_DTR) { 1022 kp->kp_ctrl_msg.usa19hs.dtr = 0x1; 1023 } else { 1024 kp->kp_ctrl_msg.usa19hs.dtr = 0x0; 1025 } 1026 1027 } else { 1028 kp->kp_ctrl_msg.usa19hs.setDtr = 0x0; 1029 } 1030 1031 break; 1032 1033 1034 case KEYSPAN_USA49WLC_PID: 1035 case KEYSPAN_USA49WG_PID: 1036 if (mask & TIOCM_RTS) { 1037 1038 kp->kp_ctrl_msg.usa49.setRts = 0x1; 1039 1040 if (val & TIOCM_RTS) { 1041 kp->kp_ctrl_msg.usa49.rts = 0x1; 1042 } else { 1043 kp->kp_ctrl_msg.usa49.rts = 0x0; 1044 } 1045 1046 } else { 1047 kp->kp_ctrl_msg.usa49.setRts = 0x0; 1048 } 1049 1050 if (mask & TIOCM_DTR) { 1051 kp->kp_ctrl_msg.usa49.setDtr = 0x1; 1052 1053 if (val & TIOCM_DTR) { 1054 kp->kp_ctrl_msg.usa49.dtr = 0x1; 1055 } else { 1056 kp->kp_ctrl_msg.usa49.dtr = 0x0; 1057 } 1058 1059 } else { 1060 kp->kp_ctrl_msg.usa49.setDtr = 0x0; 1061 } 1062 1063 break; 1064 1065 default: 1066 USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh, 1067 "keyspan_get_modem_ctl:" 1068 "the device's product id can't be recognized"); 1069 mutex_exit(&kp->kp_mutex); 1070 1071 return (USB_FAILURE); 1072 } 1073 1074 mutex_exit(&kp->kp_mutex); 1075 1076 if (keyspan_send_cmd(kp) != USB_SUCCESS) { 1077 USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh, 1078 "keyspan_send_cmd() FAILED"); 1079 1080 return (USB_FAILURE); 1081 } 1082 1083 return (USB_SUCCESS); 1084 } 1085 1086 /* 1087 * ds_get_modem_ctl 1088 */ 1089 static int 1090 keyspan_get_modem_ctl(ds_hdl_t hdl, uint_t port_num, int mask, int *valp) 1091 { 1092 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 1093 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 1094 int val = 0; 1095 1096 ASSERT(port_num < ksp->ks_dev_spec.port_cnt); 1097 1098 mutex_enter(&kp->kp_mutex); 1099 1100 /* 1101 * rts and dtr are not in status_msg, but we can get it from 1102 * status_flag since it represents what we set the device last time. 1103 */ 1104 if (kp->kp_status_flag & KEYSPAN_PORT_RTS) { 1105 val |= TIOCM_RTS; 1106 } 1107 if (kp->kp_status_flag & KEYSPAN_PORT_DTR) { 1108 val |= TIOCM_DTR; 1109 } 1110 1111 /* usbser don't deal with TIOCM_RI status */ 1112 switch (ksp->ks_dev_spec.id_product) { 1113 case KEYSPAN_USA19HS_PID: 1114 if (kp->kp_status_msg.usa19hs.dcd) { 1115 val |= TIOCM_CD; 1116 } 1117 if (kp->kp_status_msg.usa19hs.cts) { 1118 val |= TIOCM_CTS; 1119 } 1120 if (kp->kp_status_msg.usa19hs.dsr) { 1121 val |= TIOCM_DSR; 1122 } 1123 break; 1124 1125 1126 case KEYSPAN_USA49WLC_PID: 1127 case KEYSPAN_USA49WG_PID: 1128 if (kp->kp_status_msg.usa49.dcd) { 1129 val |= TIOCM_CD; 1130 } 1131 if (kp->kp_status_msg.usa49.cts) { 1132 val |= TIOCM_CTS; 1133 } 1134 if (kp->kp_status_msg.usa49.dsr) { 1135 val |= TIOCM_DSR; 1136 } 1137 break; 1138 1139 default: 1140 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 1141 "keyspan_get_modem_ctl:" 1142 "the device's product id can't be recognized"); 1143 mutex_exit(&kp->kp_mutex); 1144 1145 return (USB_FAILURE); 1146 } 1147 1148 *valp = val & mask; 1149 1150 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_get_modem_ctl:" 1151 "success. status_flag = %x, val=0%o", 1152 kp->kp_status_flag, *valp); 1153 1154 mutex_exit(&kp->kp_mutex); 1155 1156 return (USB_SUCCESS); 1157 } 1158 1159 1160 /* 1161 * ds_break_ctl 1162 */ 1163 static int 1164 keyspan_break_ctl(ds_hdl_t hdl, uint_t port_num, int ctl) 1165 { 1166 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 1167 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 1168 int is_break; 1169 int rval = USB_SUCCESS; 1170 1171 ASSERT(port_num < ksp->ks_dev_spec.port_cnt); 1172 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, 1173 "keyspan_break_ctl: ctl = %s", (ctl == DS_ON) ? "on" : "off"); 1174 1175 mutex_enter(&kp->kp_mutex); 1176 ASSERT(kp->kp_state == KEYSPAN_PORT_OPEN); 1177 ASSERT(ctl == DS_ON || ctl == DS_OFF); 1178 1179 is_break = kp->kp_status_flag & KEYSPAN_PORT_TXBREAK; 1180 1181 if ((ctl == DS_ON) && !is_break) { 1182 1183 keyspan_build_cmd_msg(kp, NULL); 1184 1185 switch (ksp->ks_dev_spec.id_product) { 1186 case KEYSPAN_USA19HS_PID: 1187 kp->kp_ctrl_msg.usa19hs.txBreak = 1; 1188 1189 break; 1190 1191 case KEYSPAN_USA49WLC_PID: 1192 case KEYSPAN_USA49WG_PID: 1193 kp->kp_ctrl_msg.usa49.txBreak = 1; 1194 1195 break; 1196 1197 default: 1198 mutex_exit(&kp->kp_mutex); 1199 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 1200 "keyspan_break_ctl:" 1201 "the device's product id can't be recognized"); 1202 1203 return (USB_FAILURE); 1204 } 1205 1206 mutex_exit(&kp->kp_mutex); 1207 rval = keyspan_send_cmd(kp); 1208 return (rval); 1209 } 1210 1211 if ((ctl == DS_OFF) && is_break) { 1212 keyspan_build_cmd_msg(kp, NULL); 1213 1214 switch (ksp->ks_dev_spec.id_product) { 1215 case KEYSPAN_USA19HS_PID: 1216 kp->kp_ctrl_msg.usa19hs.txBreak = 0; 1217 1218 break; 1219 1220 case KEYSPAN_USA49WLC_PID: 1221 case KEYSPAN_USA49WG_PID: 1222 kp->kp_ctrl_msg.usa49._txOn = 1; 1223 kp->kp_ctrl_msg.usa49.txBreak = 0; 1224 1225 break; 1226 1227 default: 1228 mutex_exit(&kp->kp_mutex); 1229 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 1230 "keyspan_break_ctl:" 1231 "the device's product id can't be recognized"); 1232 1233 return (USB_FAILURE); 1234 } 1235 1236 mutex_exit(&kp->kp_mutex); 1237 rval = keyspan_send_cmd(kp); 1238 if (rval == USB_SUCCESS) { 1239 mutex_enter(&kp->kp_mutex); 1240 1241 /* resume transmit */ 1242 keyspan_tx_start(kp, NULL); 1243 mutex_exit(&kp->kp_mutex); 1244 } 1245 1246 return (rval); 1247 } 1248 1249 mutex_exit(&kp->kp_mutex); 1250 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, 1251 "keyspan_break_ctl: not necessary to set break, is_break = %d", 1252 is_break); 1253 1254 return (rval); 1255 } 1256 1257 1258 /* 1259 * ds_loopback 1260 */ 1261 static int 1262 keyspan_loopback(ds_hdl_t hdl, uint_t port_num, int ctl) 1263 { 1264 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 1265 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 1266 int is_loop; 1267 int rval = USB_SUCCESS; 1268 1269 ASSERT(port_num < ksp->ks_dev_spec.port_cnt); 1270 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, 1271 "keyspan_loopback: %s", (ctl == DS_ON) ? "on" : "off"); 1272 1273 mutex_enter(&kp->kp_mutex); 1274 ASSERT(kp->kp_state == KEYSPAN_PORT_OPEN); 1275 ASSERT(ctl == DS_ON || ctl == DS_OFF); 1276 1277 /* check bit indicating internal loopback state */ 1278 is_loop = kp->kp_status_flag & KEYSPAN_PORT_LOOPBACK; 1279 1280 if ((ctl == DS_ON) && !is_loop) { 1281 1282 keyspan_build_cmd_msg(kp, NULL); 1283 switch (ksp->ks_dev_spec.id_product) { 1284 case KEYSPAN_USA19HS_PID: 1285 kp->kp_ctrl_msg.usa19hs.loopbackMode = 0; 1286 1287 break; 1288 1289 case KEYSPAN_USA49WLC_PID: 1290 case KEYSPAN_USA49WG_PID: 1291 kp->kp_ctrl_msg.usa49.loopbackMode = 0; 1292 1293 break; 1294 1295 default: 1296 mutex_exit(&kp->kp_mutex); 1297 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 1298 "keyspan_loopback:" 1299 "the device's product id can't be recognized"); 1300 1301 return (USB_FAILURE); 1302 } 1303 mutex_exit(&kp->kp_mutex); 1304 rval = keyspan_send_cmd(kp); 1305 } else if ((ctl == DS_OFF) && is_loop) { 1306 1307 keyspan_build_cmd_msg(kp, NULL); 1308 switch (ksp->ks_dev_spec.id_product) { 1309 case KEYSPAN_USA19HS_PID: 1310 kp->kp_ctrl_msg.usa19hs.loopbackMode = 1; 1311 1312 break; 1313 1314 case KEYSPAN_USA49WLC_PID: 1315 case KEYSPAN_USA49WG_PID: 1316 kp->kp_ctrl_msg.usa49.loopbackMode = 1; 1317 1318 break; 1319 1320 default: 1321 mutex_exit(&kp->kp_mutex); 1322 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 1323 "keyspan_loopback:" 1324 "the device's product id can't be recognized"); 1325 1326 return (USB_FAILURE); 1327 } 1328 mutex_exit(&kp->kp_mutex); 1329 rval = keyspan_send_cmd(kp); 1330 } else { 1331 mutex_exit(&kp->kp_mutex); 1332 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, 1333 "keyspan_loopback: not necessary to set loopback," 1334 "is_loop = %d", is_loop); 1335 } 1336 1337 return (rval); 1338 } 1339 1340 1341 /* 1342 * ds_tx 1343 */ 1344 static int 1345 keyspan_tx(ds_hdl_t hdl, uint_t port_num, mblk_t *mp) 1346 { 1347 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 1348 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 1349 int xferd; 1350 1351 ASSERT(port_num < ksp->ks_dev_spec.port_cnt); 1352 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_tx"); 1353 1354 /* 1355 * sanity checks 1356 */ 1357 if (mp == NULL) { 1358 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, "keyspan_tx: mp=NULL"); 1359 1360 return (USB_SUCCESS); 1361 } 1362 1363 kp = &ksp->ks_ports[port_num]; 1364 1365 mutex_enter(&kp->kp_mutex); 1366 1367 keyspan_put_tail(&kp->kp_tx_mp, mp); /* add to the chain */ 1368 1369 keyspan_tx_start(kp, &xferd); /* go! */ 1370 1371 mutex_exit(&kp->kp_mutex); 1372 1373 return (USB_SUCCESS); 1374 } 1375 1376 1377 /* 1378 * ds_rx. the real data receiving is in keyspan_open_hw_port 1379 */ 1380 static mblk_t * 1381 keyspan_rx(ds_hdl_t hdl, uint_t port_num) 1382 { 1383 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 1384 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 1385 mblk_t *mp; 1386 1387 ASSERT(port_num < ksp->ks_dev_spec.port_cnt); 1388 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_rx"); 1389 1390 mutex_enter(&kp->kp_mutex); 1391 mp = kp->kp_rx_mp; 1392 kp->kp_rx_mp = NULL; 1393 mutex_exit(&kp->kp_mutex); 1394 1395 return (mp); 1396 } 1397 1398 1399 /* 1400 * ds_stop 1401 */ 1402 static void 1403 keyspan_stop(ds_hdl_t hdl, uint_t port_num, int dir) 1404 { 1405 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 1406 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 1407 1408 ASSERT(port_num < ksp->ks_dev_spec.port_cnt); 1409 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_stop"); 1410 1411 if (dir & DS_TX) { 1412 mutex_enter(&kp->kp_mutex); 1413 kp->kp_flags |= KEYSPAN_PORT_TX_STOPPED; 1414 mutex_exit(&kp->kp_mutex); 1415 } 1416 } 1417 1418 1419 /* 1420 * ds_start 1421 */ 1422 static void 1423 keyspan_start(ds_hdl_t hdl, uint_t port_num, int dir) 1424 { 1425 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 1426 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 1427 1428 ASSERT(port_num < ksp->ks_dev_spec.port_cnt); 1429 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_start"); 1430 1431 if (dir & DS_TX) { 1432 mutex_enter(&kp->kp_mutex); 1433 if (kp->kp_flags & KEYSPAN_PORT_TX_STOPPED) { 1434 kp->kp_flags &= ~KEYSPAN_PORT_TX_STOPPED; 1435 keyspan_tx_start(kp, NULL); 1436 } 1437 mutex_exit(&kp->kp_mutex); 1438 } 1439 } 1440 1441 1442 /* 1443 * ds_fifo_flush 1444 * send flush cmd and wait for completion, then turn off the flush. 1445 */ 1446 static int 1447 keyspan_fifo_flush(ds_hdl_t hdl, uint_t port_num, int dir) 1448 { 1449 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 1450 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 1451 1452 ASSERT(port_num < ksp->ks_dev_spec.port_cnt); 1453 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, 1454 "keyspan_fifo_flush: dir=%x", dir); 1455 1456 mutex_enter(&kp->kp_mutex); 1457 ASSERT(kp->kp_state == KEYSPAN_PORT_OPEN); 1458 1459 /* discard the data in DSD buffers */ 1460 if ((dir & DS_TX) && kp->kp_tx_mp) { 1461 freemsg(kp->kp_tx_mp); 1462 kp->kp_tx_mp = NULL; 1463 } 1464 if ((dir & DS_RX) && kp->kp_rx_mp) { 1465 freemsg(kp->kp_rx_mp); 1466 kp->kp_rx_mp = NULL; 1467 } 1468 1469 mutex_exit(&kp->kp_mutex); 1470 1471 return (USB_SUCCESS); 1472 } 1473 1474 /* 1475 * ds_fifo_drain 1476 * 1477 * it is the caller's responsibility to cease submitting new tx data 1478 * while this function executes 1479 */ 1480 static int 1481 keyspan_fifo_drain(ds_hdl_t hdl, uint_t port_num, int timeout) 1482 { 1483 keyspan_state_t *ksp = (keyspan_state_t *)hdl; 1484 keyspan_port_t *kp = &ksp->ks_ports[port_num]; 1485 int rval = USB_SUCCESS; 1486 1487 ASSERT(port_num < ksp->ks_dev_spec.port_cnt); 1488 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, 1489 "keyspan_fifo_drain, timeout = %d", timeout); 1490 1491 mutex_enter(&kp->kp_mutex); 1492 ASSERT(kp->kp_state == KEYSPAN_PORT_OPEN); 1493 1494 /* wait until local data drains */ 1495 if (keyspan_wait_tx_drain(kp, 0) != USB_SUCCESS) { 1496 mutex_exit(&kp->kp_mutex); 1497 1498 return (USB_FAILURE); 1499 } 1500 mutex_exit(&kp->kp_mutex); 1501 1502 /* wait until hw fifo drains */ 1503 delay(drv_usectohz(500*1000)); 1504 1505 return (rval); 1506 } 1507 1508 1509 /* 1510 * configuration routines 1511 * ---------------------- 1512 * 1513 */ 1514 1515 /* 1516 * free state structure 1517 */ 1518 static void 1519 keyspan_free_soft_state(keyspan_state_t *ksp) 1520 { 1521 kmem_free(ksp, sizeof (keyspan_state_t)); 1522 } 1523 1524 1525 /* 1526 * register/unregister USBA client 1527 */ 1528 static int 1529 keyspan_usb_register(keyspan_state_t *ksp) 1530 { 1531 int rval; 1532 1533 rval = usb_client_attach(ksp->ks_dip, USBDRV_VERSION, 0); 1534 if (rval == USB_SUCCESS) { 1535 rval = usb_get_dev_data(ksp->ks_dip, &ksp->ks_dev_data, 1536 USB_PARSE_LVL_IF, 0); 1537 if (rval == USB_SUCCESS) { 1538 ksp->ks_lh = 1539 usb_alloc_log_hdl(ksp->ks_dip, "keyspan[*].", 1540 &keyspan_errlevel, &keyspan_errmask, 1541 &keyspan_instance_debug, 0); 1542 1543 ksp->ks_def_pipe.pipe_handle = 1544 ksp->ks_dev_data->dev_default_ph; 1545 ksp->ks_def_pipe.pipe_ksp = ksp; 1546 ksp->ks_def_pipe.pipe_lh = ksp->ks_lh; 1547 } 1548 } 1549 1550 return (rval); 1551 } 1552 1553 1554 static void 1555 keyspan_usb_unregister(keyspan_state_t *ksp) 1556 { 1557 usb_free_log_hdl(ksp->ks_lh); 1558 ksp->ks_lh = NULL; 1559 usb_client_detach(ksp->ks_dip, ksp->ks_dev_data); 1560 ksp->ks_def_pipe.pipe_handle = NULL; 1561 ksp->ks_dev_data = NULL; 1562 } 1563 1564 1565 /* 1566 * init/fini soft state during attach 1567 */ 1568 static void 1569 keyspan_init_sync_objs(keyspan_state_t *ksp) 1570 { 1571 mutex_init(&ksp->ks_mutex, NULL, MUTEX_DRIVER, 1572 ksp->ks_dev_data->dev_iblock_cookie); 1573 sema_init(&ksp->ks_pipes_sema, 1, NULL, SEMA_DRIVER, NULL); 1574 } 1575 1576 1577 static void 1578 keyspan_fini_sync_objs(keyspan_state_t *ksp) 1579 { 1580 mutex_destroy(&ksp->ks_mutex); 1581 sema_destroy(&ksp->ks_pipes_sema); 1582 } 1583 1584 1585 /* 1586 * device specific attributes 1587 */ 1588 static int 1589 keyspan_attach_dev(keyspan_state_t *ksp) 1590 { 1591 1592 mutex_enter(&ksp->ks_mutex); 1593 switch (ksp->ks_dev_data->dev_descr->idProduct) { 1594 case KEYSPAN_USA19HS_PID: 1595 ksp->ks_dev_spec.id_product = KEYSPAN_USA19HS_PID; 1596 ksp->ks_dev_spec.port_cnt = 1; 1597 ksp->ks_dev_spec.ctrl_ep_addr = 0x02; 1598 ksp->ks_dev_spec.stat_ep_addr = 0x82; 1599 ksp->ks_dev_spec.dataout_ep_addr[0] = 0x01; 1600 ksp->ks_dev_spec.datain_ep_addr[0] = 0x81; 1601 1602 break; 1603 1604 case KEYSPAN_USA49WLC_PID: 1605 ksp->ks_dev_spec.id_product = KEYSPAN_USA49WLC_PID; 1606 ksp->ks_dev_spec.port_cnt = 4; 1607 ksp->ks_dev_spec.ctrl_ep_addr = 0x07; 1608 ksp->ks_dev_spec.stat_ep_addr = 0x87; 1609 ksp->ks_dev_spec.dataout_ep_addr[0] = 0x01; 1610 ksp->ks_dev_spec.dataout_ep_addr[1] = 0x02; 1611 ksp->ks_dev_spec.dataout_ep_addr[2] = 0x03; 1612 ksp->ks_dev_spec.dataout_ep_addr[3] = 0x04; 1613 ksp->ks_dev_spec.datain_ep_addr[0] = 0x81; 1614 ksp->ks_dev_spec.datain_ep_addr[1] = 0x82; 1615 ksp->ks_dev_spec.datain_ep_addr[2] = 0x83; 1616 ksp->ks_dev_spec.datain_ep_addr[3] = 0x84; 1617 1618 break; 1619 1620 case KEYSPAN_USA49WG_PID: 1621 ksp->ks_dev_spec.id_product = KEYSPAN_USA49WG_PID; 1622 ksp->ks_dev_spec.port_cnt = 4; 1623 ksp->ks_dev_spec.stat_ep_addr = 0x81; 1624 ksp->ks_dev_spec.dataout_ep_addr[0] = 0x01; 1625 ksp->ks_dev_spec.dataout_ep_addr[1] = 0x02; 1626 ksp->ks_dev_spec.dataout_ep_addr[2] = 0x04; 1627 ksp->ks_dev_spec.dataout_ep_addr[3] = 0x06; 1628 ksp->ks_dev_spec.datain_ep_addr[0] = 0x88; 1629 ksp->ks_dev_spec.datain_ep_addr[1] = 0x88; 1630 ksp->ks_dev_spec.datain_ep_addr[2] = 0x88; 1631 ksp->ks_dev_spec.datain_ep_addr[3] = 0x88; 1632 1633 break; 1634 1635 default: 1636 mutex_exit(&ksp->ks_mutex); 1637 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 1638 "keyspan_attach_dev:" 1639 "the device's product id can't be recognized"); 1640 1641 return (USB_FAILURE); 1642 } 1643 1644 mutex_exit(&ksp->ks_mutex); 1645 1646 return (USB_SUCCESS); 1647 } 1648 1649 /* 1650 * allocate and initialize per port resources. 1651 */ 1652 static void 1653 keyspan_attach_ports(keyspan_state_t *ksp) 1654 { 1655 int i; 1656 keyspan_port_t *kp; 1657 1658 ksp->ks_ports = kmem_zalloc(ksp->ks_dev_spec.port_cnt * 1659 sizeof (keyspan_port_t), KM_SLEEP); 1660 1661 for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) { 1662 kp = &ksp->ks_ports[i]; 1663 kp->kp_port_num = i; 1664 kp->kp_ksp = ksp; 1665 1666 (void) sprintf(kp->kp_lh_name, "keyspan[%d].", i); 1667 kp->kp_lh = usb_alloc_log_hdl(ksp->ks_dip, kp->kp_lh_name, 1668 &keyspan_errlevel, &keyspan_errmask, 1669 &keyspan_instance_debug, 0); 1670 1671 kp->kp_state = KEYSPAN_PORT_CLOSED; 1672 mutex_init(&kp->kp_mutex, NULL, MUTEX_DRIVER, 1673 ksp->ks_dev_data->dev_iblock_cookie); 1674 cv_init(&kp->kp_tx_cv, NULL, CV_DRIVER, NULL); 1675 } 1676 } 1677 1678 1679 /* 1680 * free per port resources 1681 */ 1682 static void 1683 keyspan_detach_ports(keyspan_state_t *ksp) 1684 { 1685 int i; 1686 keyspan_port_t *kp; 1687 1688 for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) { 1689 kp = &ksp->ks_ports[i]; 1690 if (kp->kp_state != KEYSPAN_PORT_NOT_INIT) { 1691 ASSERT(kp->kp_state == KEYSPAN_PORT_CLOSED); 1692 1693 mutex_destroy(&kp->kp_mutex); 1694 cv_destroy(&kp->kp_tx_cv); 1695 usb_free_log_hdl(kp->kp_lh); 1696 } 1697 } 1698 kmem_free(ksp->ks_ports, 1699 ksp->ks_dev_spec.port_cnt * sizeof (keyspan_port_t)); 1700 } 1701 1702 static void 1703 keyspan_init_port_params(keyspan_state_t *ksp) 1704 { 1705 int i; 1706 size_t sz; 1707 uint_t read_len; 1708 uint_t write_len; 1709 1710 /* the max data len of every bulk in req. */ 1711 if (usb_pipe_get_max_bulk_transfer_size(ksp->ks_dip, &sz) == 1712 USB_SUCCESS) { 1713 if (ksp->ks_dev_spec.id_product == KEYSPAN_USA49WG_PID) { 1714 read_len = (uint_t)min(sz, KEYSPAN_BULKIN_MAX_LEN_49WG); 1715 } else { 1716 read_len = (uint_t)min(sz, KEYSPAN_BULKIN_MAX_LEN); 1717 } 1718 } else { 1719 if (ksp->ks_dev_spec.id_product == KEYSPAN_USA49WG_PID) { 1720 read_len = KEYSPAN_BULKIN_MAX_LEN_49WG; 1721 } else { 1722 read_len = KEYSPAN_BULKIN_MAX_LEN; 1723 } 1724 } 1725 1726 for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) { 1727 ksp->ks_ports[i].kp_read_len = read_len; 1728 /* the max data len of every bulk out req. */ 1729 switch (ksp->ks_dev_spec.id_product) { 1730 case KEYSPAN_USA19HS_PID: 1731 ksp->ks_ports[i].kp_write_len = 1732 KEYSPAN_BULKOUT_MAX_LEN_19HS; 1733 1734 break; 1735 case KEYSPAN_USA49WLC_PID: 1736 ksp->ks_ports[i].kp_write_len = 1737 KEYSPAN_BULKOUT_MAX_LEN_49WLC; 1738 1739 break; 1740 case KEYSPAN_USA49WG_PID: 1741 /* 1742 * USA49WG port0 uses intr out pipe send data while 1743 * other ports use bulk out pipes, so port0's max 1744 * packet length for "bulk out" is different from other 1745 * ports' while the same as USA49WLC. 1746 */ 1747 write_len = ((i == 0) ? KEYSPAN_BULKOUT_MAX_LEN_49WLC : 1748 KEYSPAN_BULKOUT_MAX_LEN_49WG); 1749 ksp->ks_ports[i].kp_write_len = write_len; 1750 1751 break; 1752 default: 1753 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 1754 "keyspan_init_port_params:" 1755 "the device's product id can't be recognized"); 1756 1757 return; 1758 } 1759 } 1760 } 1761 1762 1763 /* 1764 * free descriptor tree 1765 */ 1766 static void 1767 keyspan_free_descr_tree(keyspan_state_t *ksp) 1768 { 1769 usb_free_descr_tree(ksp->ks_dip, ksp->ks_dev_data); 1770 1771 } 1772 1773 1774 /* 1775 * register/unregister USB event callbacks 1776 */ 1777 static int 1778 keyspan_register_events(keyspan_state_t *ksp) 1779 { 1780 return (usb_register_event_cbs(ksp->ks_dip, ksp->ks_usb_events, 0)); 1781 } 1782 1783 1784 static void 1785 keyspan_unregister_events(keyspan_state_t *ksp) 1786 { 1787 usb_unregister_event_cbs(ksp->ks_dip, ksp->ks_usb_events); 1788 } 1789 1790 1791 static void 1792 keyspan_set_dev_state_online(keyspan_state_t *ksp) 1793 { 1794 ksp->ks_dev_state = USB_DEV_ONLINE; 1795 } 1796 1797 /* 1798 * send command to the port and save the params after its completion for 1799 * USA19HS and USA49WLC 1800 */ 1801 int 1802 keyspan_send_cmd_usa49(keyspan_port_t *kp) 1803 { 1804 keyspan_state_t *ksp = kp->kp_ksp; 1805 mblk_t *mp; 1806 int rval = USB_SUCCESS; 1807 int size; 1808 usb_bulk_req_t *br; 1809 1810 ASSERT(!mutex_owned(&kp->kp_mutex)); 1811 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_send_cmd_usa49"); 1812 1813 switch (ksp->ks_dev_spec.id_product) { 1814 case KEYSPAN_USA19HS_PID: 1815 size = sizeof (keyspan_usa19hs_port_ctrl_msg_t); 1816 1817 break; 1818 1819 1820 case KEYSPAN_USA49WLC_PID: 1821 size = sizeof (keyspan_usa49_port_ctrl_msg_t); 1822 1823 break; 1824 1825 default: 1826 USB_DPRINTF_L2(DPRINT_CTLOP, ksp->ks_lh, 1827 "keyspan_send_cmd_usa49:" 1828 "the device's product id can't be recognized"); 1829 return (USB_FAILURE); 1830 } 1831 1832 if ((mp = allocb(size, BPRI_LO)) == NULL) { 1833 1834 return (USB_FAILURE); 1835 } 1836 bcopy(&kp->kp_ctrl_msg, mp->b_rptr, size); 1837 1838 br = usb_alloc_bulk_req(ksp->ks_dip, 0, USB_FLAGS_SLEEP); 1839 br->bulk_len = size; 1840 br->bulk_data = mp; 1841 br->bulk_timeout = KEYSPAN_BULK_TIMEOUT; 1842 br->bulk_client_private = (void *)kp; 1843 br->bulk_attributes = USB_ATTRS_AUTOCLEARING; 1844 1845 rval = usb_pipe_bulk_xfer(ksp->ks_ctrlout_pipe.pipe_handle, br, 1846 USB_FLAGS_SLEEP); 1847 if (rval == USB_SUCCESS) { 1848 mutex_enter(&kp->kp_mutex); 1849 keyspan_save_port_params(kp); 1850 mutex_exit(&kp->kp_mutex); 1851 } else { 1852 USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh, "keyspan_send_cmd_usa49" 1853 ": failure, rval=%d", rval); 1854 } 1855 1856 usb_free_bulk_req(br); 1857 1858 return (rval); 1859 } 1860 1861 /* 1862 * send command to the port and save the params after its completion for 1863 * USA_49WG only 1864 */ 1865 int 1866 keyspan_send_cmd_usa49wg(keyspan_port_t *kp) 1867 { 1868 keyspan_state_t *ksp = kp->kp_ksp; 1869 mblk_t *mp; 1870 int rval = USB_SUCCESS; 1871 uint16_t size = sizeof (keyspan_usa49_port_ctrl_msg_t); 1872 usb_cb_flags_t cb_flags; 1873 usb_cr_t cr; 1874 usb_ctrl_setup_t setup; 1875 1876 ASSERT(!mutex_owned(&kp->kp_mutex)); 1877 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_send_cmd_usa49wg"); 1878 1879 if ((mp = allocb(size, BPRI_LO)) == NULL) { 1880 1881 return (USB_FAILURE); 1882 } 1883 bcopy(&kp->kp_ctrl_msg, mp->b_rptr, size); 1884 1885 setup.bmRequestType = USB_DEV_REQ_TYPE_VENDOR; 1886 setup.bRequest = KEYSPAN_SET_CONTROL_REQUEST; 1887 setup.wValue = 0; 1888 setup.wIndex = 0; 1889 setup.wLength = size; 1890 setup.attrs = 0; 1891 1892 rval = usb_pipe_ctrl_xfer_wait(ksp->ks_def_pipe.pipe_handle, &setup, 1893 &mp, &cr, &cb_flags, 0); 1894 1895 if (rval == USB_SUCCESS) { 1896 mutex_enter(&kp->kp_mutex); 1897 keyspan_save_port_params(kp); 1898 mutex_exit(&kp->kp_mutex); 1899 } else { 1900 USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh, 1901 "keyspan_send_cmd_usa49wg: failure, rval=%d", rval); 1902 } 1903 if (mp) { 1904 freemsg(mp); 1905 } 1906 1907 return (rval); 1908 } 1909 1910 /* 1911 * send command to the port and save the params after its completion 1912 */ 1913 int 1914 keyspan_send_cmd(keyspan_port_t *kp) 1915 { 1916 keyspan_state_t *ksp = kp->kp_ksp; 1917 int rval = USB_FAILURE; 1918 1919 switch (ksp->ks_dev_spec.id_product) { 1920 case KEYSPAN_USA19HS_PID: 1921 case KEYSPAN_USA49WLC_PID: 1922 rval = keyspan_send_cmd_usa49(kp); 1923 1924 break; 1925 case KEYSPAN_USA49WG_PID: 1926 rval = keyspan_send_cmd_usa49wg(kp); 1927 1928 break; 1929 default: 1930 USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh, 1931 "keyspan_send_cmd: " 1932 "the device's product id can't be recognized"); 1933 } 1934 1935 if (rval != USB_SUCCESS) { 1936 USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh, 1937 "keyspan_send_cmd() FAILED"); 1938 1939 return (rval); 1940 } 1941 1942 return (USB_SUCCESS); 1943 1944 } 1945 1946 /* 1947 * hotplug 1948 * ------- 1949 * 1950 * restore device state after CPR resume or reconnect 1951 */ 1952 static int 1953 keyspan_restore_device_state(keyspan_state_t *ksp) 1954 { 1955 int state; 1956 1957 mutex_enter(&ksp->ks_mutex); 1958 state = ksp->ks_dev_state; 1959 mutex_exit(&ksp->ks_mutex); 1960 1961 if ((state != USB_DEV_DISCONNECTED) && (state != USB_DEV_SUSPENDED)) { 1962 1963 return (state); 1964 } 1965 1966 if (usb_check_same_device(ksp->ks_dip, ksp->ks_lh, USB_LOG_L0, 1967 DPRINT_MASK_ALL, USB_CHK_ALL, NULL) != USB_SUCCESS) { 1968 mutex_enter(&ksp->ks_mutex); 1969 state = ksp->ks_dev_state = USB_DEV_DISCONNECTED; 1970 mutex_exit(&ksp->ks_mutex); 1971 1972 return (state); 1973 } 1974 1975 if (state == USB_DEV_DISCONNECTED) { 1976 USB_DPRINTF_L0(DPRINT_HOTPLUG, ksp->ks_lh, 1977 "device has been reconnected but data may have been lost"); 1978 } 1979 1980 if (keyspan_reconnect_pipes(ksp) != USB_SUCCESS) { 1981 1982 return (state); 1983 } 1984 1985 /* 1986 * init device state 1987 */ 1988 mutex_enter(&ksp->ks_mutex); 1989 state = ksp->ks_dev_state = USB_DEV_ONLINE; 1990 ksp->ks_reconnect_flag = 1; 1991 mutex_exit(&ksp->ks_mutex); 1992 1993 /* 1994 * now restore each open port 1995 */ 1996 (void) keyspan_restore_ports_state(ksp); 1997 1998 return (state); 1999 } 2000 2001 /* 2002 * restore ports state after CPR resume or reconnect 2003 */ 2004 static int 2005 keyspan_restore_ports_state(keyspan_state_t *ksp) 2006 { 2007 keyspan_port_t *kp; 2008 int rval = USB_SUCCESS; 2009 int err; 2010 int i; 2011 2012 for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) { 2013 kp = &ksp->ks_ports[i]; 2014 /* 2015 * only care about open ports 2016 */ 2017 mutex_enter(&kp->kp_mutex); 2018 if (kp->kp_state != KEYSPAN_PORT_OPEN) { 2019 mutex_exit(&kp->kp_mutex); 2020 continue; 2021 } 2022 mutex_exit(&kp->kp_mutex); 2023 2024 sema_p(&ksp->ks_pipes_sema); 2025 /* open hardware serial port */ 2026 err = keyspan_open_hw_port(kp, B_FALSE); 2027 sema_v(&ksp->ks_pipes_sema); 2028 if (err != USB_SUCCESS) { 2029 USB_DPRINTF_L2(DPRINT_HOTPLUG, kp->kp_lh, 2030 "keyspan_restore_ports_state: failed"); 2031 rval = err; 2032 } 2033 } 2034 2035 return (rval); 2036 } 2037 2038 2039 /* 2040 * power management 2041 * ---------------- 2042 * 2043 * 2044 * create PM components 2045 */ 2046 static int 2047 keyspan_create_pm_components(keyspan_state_t *ksp) 2048 { 2049 dev_info_t *dip = ksp->ks_dip; 2050 keyspan_pm_t *pm; 2051 uint_t pwr_states; 2052 2053 pm = ksp->ks_pm = kmem_zalloc(sizeof (keyspan_pm_t), KM_SLEEP); 2054 pm->pm_cur_power = USB_DEV_OS_FULL_PWR; 2055 2056 if (usb_create_pm_components(dip, &pwr_states) != USB_SUCCESS) { 2057 USB_DPRINTF_L2(DPRINT_PM, ksp->ks_lh, 2058 "keyspan_create_pm_components: failed"); 2059 2060 return (USB_SUCCESS); 2061 } 2062 2063 pm->pm_wakeup_enabled = (usb_handle_remote_wakeup(dip, 2064 USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS); 2065 pm->pm_pwr_states = (uint8_t)pwr_states; 2066 2067 (void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR); 2068 2069 return (USB_SUCCESS); 2070 } 2071 2072 2073 /* 2074 * destroy PM components 2075 */ 2076 static void 2077 keyspan_destroy_pm_components(keyspan_state_t *ksp) 2078 { 2079 keyspan_pm_t *pm = ksp->ks_pm; 2080 dev_info_t *dip = ksp->ks_dip; 2081 int rval; 2082 2083 if (ksp->ks_dev_state != USB_DEV_DISCONNECTED) { 2084 if (pm->pm_wakeup_enabled) { 2085 (void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR); 2086 2087 rval = usb_handle_remote_wakeup(dip, 2088 USB_REMOTE_WAKEUP_DISABLE); 2089 if (rval != USB_SUCCESS) { 2090 USB_DPRINTF_L2(DPRINT_PM, ksp->ks_lh, 2091 "keyspan_destroy_pm_components: disable " 2092 "remote wakeup failed, rval=%d", rval); 2093 } 2094 } 2095 2096 (void) pm_lower_power(dip, 0, USB_DEV_OS_PWR_OFF); 2097 } 2098 kmem_free(pm, sizeof (keyspan_pm_t)); 2099 ksp->ks_pm = NULL; 2100 } 2101 2102 2103 /* 2104 * mark device busy and raise power 2105 */ 2106 static int 2107 keyspan_pm_set_busy(keyspan_state_t *ksp) 2108 { 2109 keyspan_pm_t *pm = ksp->ks_pm; 2110 dev_info_t *dip = ksp->ks_dip; 2111 2112 USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pm_set_busy"); 2113 2114 mutex_enter(&ksp->ks_mutex); 2115 /* if already marked busy, just increment the counter */ 2116 if (pm->pm_busy_cnt++ > 0) { 2117 USB_DPRINTF_L3(DPRINT_PM, ksp->ks_lh, "keyspan_pm_set_busy:" 2118 "already busy, busy_cnt = %d", pm->pm_busy_cnt); 2119 mutex_exit(&ksp->ks_mutex); 2120 2121 return (USB_SUCCESS); 2122 } 2123 2124 (void) pm_busy_component(dip, 0); 2125 2126 if (pm->pm_cur_power == USB_DEV_OS_FULL_PWR) { 2127 mutex_exit(&ksp->ks_mutex); 2128 2129 return (USB_SUCCESS); 2130 } 2131 2132 /* need to raise power */ 2133 pm->pm_raise_power = B_TRUE; 2134 mutex_exit(&ksp->ks_mutex); 2135 2136 USB_DPRINTF_L3(DPRINT_PM, ksp->ks_lh, 2137 "keyspan_pm_set_busy: raise power"); 2138 (void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR); 2139 2140 mutex_enter(&ksp->ks_mutex); 2141 pm->pm_raise_power = B_FALSE; 2142 mutex_exit(&ksp->ks_mutex); 2143 2144 return (USB_SUCCESS); 2145 } 2146 2147 2148 /* 2149 * mark device idle 2150 */ 2151 static void 2152 keyspan_pm_set_idle(keyspan_state_t *ksp) 2153 { 2154 keyspan_pm_t *pm = ksp->ks_pm; 2155 dev_info_t *dip = ksp->ks_dip; 2156 2157 USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pm_set_idle"); 2158 2159 /* 2160 * if more ports use the device, do not mark as yet 2161 */ 2162 mutex_enter(&ksp->ks_mutex); 2163 if (--pm->pm_busy_cnt > 0) { 2164 mutex_exit(&ksp->ks_mutex); 2165 2166 return; 2167 } 2168 2169 USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pm_set_idle: set idle"); 2170 (void) pm_idle_component(dip, 0); 2171 2172 mutex_exit(&ksp->ks_mutex); 2173 } 2174 2175 2176 /* 2177 * Functions to handle power transition for OS levels 0 -> 3 2178 */ 2179 static int 2180 keyspan_pwrlvl0(keyspan_state_t *ksp) 2181 { 2182 int rval; 2183 keyspan_pipe_t *statin = &ksp->ks_statin_pipe; 2184 2185 USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pwrlvl0"); 2186 2187 switch (ksp->ks_dev_state) { 2188 case USB_DEV_ONLINE: 2189 /* issue USB D3 command to the device */ 2190 rval = usb_set_device_pwrlvl3(ksp->ks_dip); 2191 ASSERT(rval == USB_SUCCESS); 2192 2193 if (ksp->ks_dev_spec.id_product == KEYSPAN_USA49WG_PID) { 2194 mutex_exit(&ksp->ks_mutex); 2195 usb_pipe_stop_intr_polling(statin->pipe_handle, 2196 USB_FLAGS_SLEEP); 2197 mutex_enter(&ksp->ks_mutex); 2198 2199 mutex_enter(&statin->pipe_mutex); 2200 statin->pipe_state = KEYSPAN_PIPE_CLOSED; 2201 mutex_exit(&statin->pipe_mutex); 2202 } 2203 ksp->ks_dev_state = USB_DEV_PWRED_DOWN; 2204 ksp->ks_pm->pm_cur_power = USB_DEV_OS_PWR_OFF; 2205 2206 /* FALLTHRU */ 2207 case USB_DEV_DISCONNECTED: 2208 case USB_DEV_SUSPENDED: 2209 /* allow a disconnect/cpr'ed device to go to lower power */ 2210 2211 return (USB_SUCCESS); 2212 case USB_DEV_PWRED_DOWN: 2213 default: 2214 USB_DPRINTF_L2(DPRINT_PM, ksp->ks_lh, 2215 "keyspan_pwrlvl0: illegal device state"); 2216 2217 return (USB_FAILURE); 2218 } 2219 } 2220 2221 2222 static int 2223 keyspan_pwrlvl1(keyspan_state_t *ksp) 2224 { 2225 USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pwrlvl1"); 2226 2227 /* issue USB D2 command to the device */ 2228 (void) usb_set_device_pwrlvl2(ksp->ks_dip); 2229 2230 return (USB_FAILURE); 2231 } 2232 2233 2234 static int 2235 keyspan_pwrlvl2(keyspan_state_t *ksp) 2236 { 2237 USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pwrlvl2"); 2238 2239 /* issue USB D1 command to the device */ 2240 (void) usb_set_device_pwrlvl1(ksp->ks_dip); 2241 2242 return (USB_FAILURE); 2243 } 2244 2245 2246 static int 2247 keyspan_pwrlvl3(keyspan_state_t *ksp) 2248 { 2249 int rval; 2250 2251 USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pwrlvl3"); 2252 2253 switch (ksp->ks_dev_state) { 2254 case USB_DEV_PWRED_DOWN: 2255 /* Issue USB D0 command to the device here */ 2256 rval = usb_set_device_pwrlvl0(ksp->ks_dip); 2257 ASSERT(rval == USB_SUCCESS); 2258 2259 if (ksp->ks_dev_spec.id_product == KEYSPAN_USA49WG_PID) { 2260 mutex_exit(&ksp->ks_mutex); 2261 keyspan_pipe_start_polling(&ksp->ks_statin_pipe); 2262 mutex_enter(&ksp->ks_mutex); 2263 } 2264 2265 ksp->ks_dev_state = USB_DEV_ONLINE; 2266 ksp->ks_pm->pm_cur_power = USB_DEV_OS_FULL_PWR; 2267 2268 /* FALLTHRU */ 2269 case USB_DEV_ONLINE: 2270 /* we are already in full power */ 2271 2272 /* FALLTHRU */ 2273 case USB_DEV_DISCONNECTED: 2274 case USB_DEV_SUSPENDED: 2275 2276 return (USB_SUCCESS); 2277 default: 2278 USB_DPRINTF_L2(DPRINT_PM, ksp->ks_lh, 2279 "keyspan_pwrlvl3: illegal device state"); 2280 2281 return (USB_FAILURE); 2282 } 2283 } 2284 2285 2286 /* 2287 * pipe operations 2288 * --------------- 2289 * 2290 * XXX keyspan seem to malfunction after the pipes are closed 2291 * and reopened again (does not respond to OPEN_PORT command). 2292 * so we open them once in attach 2293 */ 2294 static int 2295 keyspan_attach_pipes(keyspan_state_t *ksp) 2296 { 2297 return (keyspan_open_dev_pipes(ksp)); 2298 } 2299 2300 void 2301 keyspan_detach_pipes(keyspan_state_t *ksp) 2302 { 2303 2304 /* 2305 * Blow away status bulk in requests or 2306 * pipe close will wait until timeout. 2307 */ 2308 if (ksp->ks_statin_pipe.pipe_handle) { 2309 usb_pipe_stop_intr_polling(ksp->ks_statin_pipe.pipe_handle, 2310 USB_FLAGS_SLEEP); 2311 } 2312 2313 /* Close the globle pipes */ 2314 keyspan_close_dev_pipes(ksp); 2315 } 2316 2317 2318 /* 2319 * during device disconnect/suspend, close pipes if they are open. 2320 */ 2321 static void 2322 keyspan_disconnect_pipes(keyspan_state_t *ksp) 2323 { 2324 sema_p(&ksp->ks_pipes_sema); 2325 keyspan_close_pipes(ksp); 2326 sema_v(&ksp->ks_pipes_sema); 2327 } 2328 2329 2330 /* 2331 * during device reconnect/resume, reopen pipes if they were open. 2332 */ 2333 static int 2334 keyspan_reconnect_pipes(keyspan_state_t *ksp) 2335 { 2336 int rval = USB_SUCCESS; 2337 2338 sema_p(&ksp->ks_pipes_sema); 2339 rval = keyspan_reopen_pipes(ksp); 2340 sema_v(&ksp->ks_pipes_sema); 2341 2342 return (rval); 2343 } 2344 2345 /* 2346 * data transfer routines 2347 * ---------------------- 2348 * 2349 * 2350 * start data transmit 2351 */ 2352 void 2353 keyspan_tx_start(keyspan_port_t *kp, int *xferd) 2354 { 2355 keyspan_state_t *ksp = kp->kp_ksp; 2356 int len; /* # of bytes we can transmit */ 2357 mblk_t *data; /* data to be transmitted */ 2358 int data_len = 0; /* # of bytes in 'data' */ 2359 int tran_len; 2360 int rval; 2361 int status_len = 0; 2362 2363 ASSERT(!mutex_owned(&ksp->ks_mutex)); 2364 ASSERT(mutex_owned(&kp->kp_mutex)); 2365 ASSERT(kp->kp_state != KEYSPAN_PORT_CLOSED); 2366 2367 USB_DPRINTF_L4(DPRINT_OUT_PIPE, kp->kp_lh, "keyspan_tx_start"); 2368 2369 if (xferd) { 2370 *xferd = 0; 2371 } 2372 if ((kp->kp_flags & KEYSPAN_PORT_TX_STOPPED) || 2373 (kp->kp_tx_mp == NULL)) { 2374 2375 return; 2376 } 2377 2378 len = min(msgdsize(kp->kp_tx_mp), kp->kp_write_len); 2379 USB_DPRINTF_L4(DPRINT_OUT_PIPE, kp->kp_lh, "keyspan_tx_start:" 2380 "len = %d, tx_mp_len = %d", len, (int)msgdsize(kp->kp_tx_mp)); 2381 2382 mutex_exit(&kp->kp_mutex); 2383 2384 /* 2385 * Some keyspan adapters, such as usa49wlc, 2386 * need use the first byte as flag. 2387 */ 2388 switch (ksp->ks_dev_spec.id_product) { 2389 case KEYSPAN_USA19HS_PID: 2390 2391 if ((data = allocb(len, BPRI_LO)) == NULL) { 2392 mutex_enter(&kp->kp_mutex); 2393 2394 return; 2395 } 2396 mutex_enter(&kp->kp_mutex); 2397 2398 /* copy at most 'len' bytes from mblk chain for transmission */ 2399 data_len = keyspan_tx_copy_data(kp, data, len); 2400 if (data_len <= 0) { 2401 USB_DPRINTF_L3(DPRINT_OUT_PIPE, kp->kp_lh, 2402 "keyspan_tx_start:keyspan_tx_copy_data copied" 2403 " zero bytes"); 2404 } 2405 2406 break; 2407 2408 case KEYSPAN_USA49WLC_PID: 2409 case KEYSPAN_USA49WG_PID: 2410 status_len = len / 64 + 1; 2411 if ((data = allocb(len + status_len, BPRI_LO)) == NULL) { 2412 mutex_enter(&kp->kp_mutex); 2413 2414 return; 2415 } 2416 mutex_enter(&kp->kp_mutex); 2417 /* 2418 * the data format is [status byte][63 data bytes][...][status] 2419 * byte][up to 63 bytes] according to keyspan spec 2420 */ 2421 while (data_len < len) { 2422 /* Add status byte per 63 data bytes */ 2423 *(data->b_wptr++) = 0; 2424 /* copy at most 63 bytes from mblk chain for trans */ 2425 tran_len = keyspan_tx_copy_data(kp, data, 63); 2426 if (tran_len <= 0) { 2427 USB_DPRINTF_L3(DPRINT_OUT_PIPE, kp->kp_lh, 2428 "keyspan_tx_start:keyspan_tx_copy_data" 2429 " copied zero bytes"); 2430 2431 break; 2432 } 2433 data_len += tran_len; 2434 } 2435 2436 break; 2437 default: 2438 2439 mutex_enter(&kp->kp_mutex); 2440 USB_DPRINTF_L2(DPRINT_OUT_PIPE, ksp->ks_lh, "keyspan_tx_start:" 2441 "the device's product id can't be recognized"); 2442 2443 return; 2444 } 2445 2446 mutex_exit(&kp->kp_mutex); 2447 2448 /* 2449 * For USA-49WG, the port0 uses intr out pipe as data out pipe, while 2450 * other ports use bulk out pipe. 2451 */ 2452 2453 if ((kp->kp_port_num == 0) && 2454 (ksp->ks_dev_spec.id_product == KEYSPAN_USA49WG_PID)) { 2455 rval = keyspan_send_data_port0(&kp->kp_dataout_pipe, &data, kp); 2456 } else { 2457 rval = keyspan_send_data(&kp->kp_dataout_pipe, &data, kp); 2458 } 2459 mutex_enter(&kp->kp_mutex); 2460 2461 /* 2462 * if send failed, put data back 2463 */ 2464 if (rval != USB_SUCCESS) { 2465 ASSERT(data); 2466 keyspan_put_head(&kp->kp_tx_mp, data, kp); 2467 } else if (xferd) { 2468 *xferd = data_len; 2469 } 2470 2471 USB_DPRINTF_L4(DPRINT_OUT_PIPE, kp->kp_lh, "keyspan_tx_start[%d]: over" 2472 "(%d) rval=%d", kp->kp_port_num, data_len, rval); 2473 2474 } 2475 2476 2477 /* 2478 * copy no more than 'len' bytes from mblk chain to transmit mblk 'data'. 2479 * return number of bytes copied 2480 */ 2481 int 2482 keyspan_tx_copy_data(keyspan_port_t *kp, mblk_t *data, int len) 2483 { 2484 mblk_t *mp; /* current msgblk */ 2485 int copylen; /* # of bytes to copy from 'mp' to 'data' */ 2486 int data_len = 0; 2487 2488 ASSERT(mutex_owned(&kp->kp_mutex)); 2489 2490 if (msgdsize(kp->kp_tx_mp) == 0) { 2491 data->b_wptr = data->b_rptr; 2492 freeb(kp->kp_tx_mp); 2493 kp->kp_tx_mp = NULL; 2494 2495 return (data_len); 2496 } 2497 2498 while ((data_len < len) && kp->kp_tx_mp) { 2499 mp = kp->kp_tx_mp; 2500 copylen = min(MBLKL(mp), len - data_len); 2501 bcopy(mp->b_rptr, data->b_wptr, copylen); 2502 2503 mp->b_rptr += copylen; 2504 data->b_wptr += copylen; 2505 data_len += copylen; 2506 2507 if (MBLKL(mp) < 1) { 2508 kp->kp_tx_mp = unlinkb(mp); 2509 freeb(mp); 2510 } else { 2511 ASSERT(data_len == len); 2512 } 2513 } 2514 USB_DPRINTF_L3(DPRINT_OUT_DATA, kp->kp_lh, "keyspan_tx_copy_data:" 2515 "copied data_len = %d", data_len); 2516 2517 return (data_len); 2518 } 2519 2520 2521 /* 2522 * wait until local tx buffer drains. 2523 * 'timeout' is in seconds, zero means wait forever 2524 */ 2525 static int 2526 keyspan_wait_tx_drain(keyspan_port_t *kp, int timeout) 2527 { 2528 clock_t until; 2529 int over = 0; 2530 2531 USB_DPRINTF_L4(DPRINT_OUT_DATA, kp->kp_lh, "keyspan_wait_tx_drain:" 2532 "timeout = %d", timeout); 2533 until = ddi_get_lbolt() + drv_usectohz(1000000 * timeout); 2534 2535 while (kp->kp_tx_mp && !over) { 2536 if (timeout > 0) { 2537 over = (cv_timedwait_sig(&kp->kp_tx_cv, 2538 &kp->kp_mutex, until) <= 0); 2539 } else { 2540 over = (cv_wait_sig(&kp->kp_tx_cv, &kp->kp_mutex) == 0); 2541 } 2542 } 2543 2544 return ((kp->kp_tx_mp == NULL) ? USB_SUCCESS : USB_FAILURE); 2545 } 2546 2547 /* 2548 * returns 0 if device is not online, != 0 otherwise 2549 */ 2550 int 2551 keyspan_dev_is_online(keyspan_state_t *ksp) 2552 { 2553 int rval; 2554 2555 mutex_enter(&ksp->ks_mutex); 2556 rval = (ksp->ks_dev_state == USB_DEV_ONLINE); 2557 mutex_exit(&ksp->ks_mutex); 2558 2559 return (rval); 2560 } 2561 2562 /* 2563 * link a message block to tail of message 2564 * account for the case when message is null 2565 */ 2566 void 2567 keyspan_put_tail(mblk_t **mpp, mblk_t *bp) 2568 { 2569 if (*mpp) { 2570 linkb(*mpp, bp); 2571 } else { 2572 *mpp = bp; 2573 } 2574 } 2575 2576 /* 2577 * put a message block at the head of the message 2578 * account for the case when message is null 2579 */ 2580 void 2581 keyspan_put_head(mblk_t **mpp, mblk_t *bp, keyspan_port_t *kp) 2582 { 2583 switch (kp->kp_ksp->ks_dev_spec.id_product) { 2584 case KEYSPAN_USA19HS_PID: 2585 if (*mpp) { 2586 linkb(bp, *mpp); 2587 } 2588 *mpp = bp; 2589 2590 break; 2591 2592 2593 case KEYSPAN_USA49WLC_PID: 2594 case KEYSPAN_USA49WG_PID: 2595 2596 /* get rid of the first byte of the msg data which is a flag */ 2597 if (*mpp) { 2598 linkb(bp, *mpp); 2599 } 2600 bp->b_rptr = bp->b_datap->db_base + 1; 2601 *mpp = bp; 2602 2603 break; 2604 2605 default: 2606 USB_DPRINTF_L2(DPRINT_OUT_DATA, kp->kp_lh, "keyspan_put_head:" 2607 "the device's product id can't be recognized"); 2608 2609 return; 2610 } 2611 2612 } 2613 2614 /* 2615 * Set the port parameters to default values 2616 */ 2617 static void 2618 keyspan_default_port_params(keyspan_port_t *kp) 2619 { 2620 keyspan_state_t *ksp = kp->kp_ksp; 2621 2622 ASSERT(mutex_owned(&kp->kp_mutex)); 2623 2624 switch (ksp->ks_dev_spec.id_product) { 2625 case KEYSPAN_USA19HS_PID: 2626 keyspan_default_port_params_usa19hs(kp); 2627 2628 break; 2629 2630 2631 case KEYSPAN_USA49WLC_PID: 2632 case KEYSPAN_USA49WG_PID: 2633 keyspan_default_port_params_usa49(kp); 2634 2635 break; 2636 2637 default: 2638 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 2639 "keyspan_default_port_params:" 2640 "the device's product id can't be recognized"); 2641 } 2642 2643 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2644 "keyspan_default_port_params: setted."); 2645 } 2646 2647 /* 2648 * Build the command message according to the params from usbser. 2649 * The message will then be sent to deivce by keyspan_send_cmd. 2650 */ 2651 static void 2652 keyspan_build_cmd_msg(keyspan_port_t *kp, ds_port_params_t *tp) 2653 { 2654 keyspan_state_t *ksp = kp->kp_ksp; 2655 2656 switch (ksp->ks_dev_spec.id_product) { 2657 case KEYSPAN_USA19HS_PID: 2658 keyspan_build_cmd_msg_usa19hs(kp, tp); 2659 2660 break; 2661 2662 2663 case KEYSPAN_USA49WLC_PID: 2664 case KEYSPAN_USA49WG_PID: 2665 keyspan_build_cmd_msg_usa49(kp, tp); 2666 2667 break; 2668 2669 default: 2670 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 2671 "keyspan_build_cmd_msg:" 2672 "the device's product id can't be recognized"); 2673 } 2674 } 2675 2676 /* save the port params after send cmd successfully */ 2677 static void 2678 keyspan_save_port_params(keyspan_port_t *kp) 2679 { 2680 keyspan_state_t *ksp = kp->kp_ksp; 2681 2682 ASSERT(mutex_owned(&kp->kp_mutex)); 2683 2684 switch (ksp->ks_dev_spec.id_product) { 2685 case KEYSPAN_USA19HS_PID: 2686 keyspan_save_port_params_usa19hs(kp); 2687 2688 break; 2689 2690 2691 case KEYSPAN_USA49WLC_PID: 2692 case KEYSPAN_USA49WG_PID: 2693 keyspan_save_port_params_usa49(kp); 2694 2695 break; 2696 2697 default: 2698 USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh, 2699 "keyspan_save_port_params:" 2700 "the device's product id can't be recognized"); 2701 } 2702 2703 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2704 "keyspan_save_port_params: baud = %x, lcr = %x," 2705 "status_flag = %x", kp->kp_baud, kp->kp_lcr, kp->kp_status_flag); 2706 2707 } 2708 2709 /* save the port params after send cmd successfully */ 2710 static void 2711 keyspan_save_port_params_usa19hs(keyspan_port_t *kp) 2712 { 2713 keyspan_usa19hs_port_ctrl_msg_t *ctrl_msg = &(kp->kp_ctrl_msg.usa19hs); 2714 2715 ASSERT(mutex_owned(&kp->kp_mutex)); 2716 2717 if (ctrl_msg->setClocking) { 2718 kp->kp_baud = ctrl_msg->baudHi; 2719 kp->kp_baud = (kp->kp_baud << 8); 2720 kp->kp_baud |= ctrl_msg->baudLo; 2721 } 2722 if (ctrl_msg->setLcr) { 2723 kp->kp_lcr = ctrl_msg->lcr; 2724 } 2725 if (ctrl_msg->setRts) { 2726 if (ctrl_msg->rts) { 2727 kp->kp_status_flag |= KEYSPAN_PORT_RTS; 2728 } else { 2729 kp->kp_status_flag &= ~KEYSPAN_PORT_RTS; 2730 } 2731 } 2732 if (ctrl_msg->setDtr) { 2733 if (ctrl_msg->dtr) { 2734 kp->kp_status_flag |= KEYSPAN_PORT_DTR; 2735 } else { 2736 kp->kp_status_flag &= ~KEYSPAN_PORT_DTR; 2737 } 2738 } 2739 2740 if (ctrl_msg->portEnabled) { 2741 kp->kp_status_flag |= KEYSPAN_PORT_ENABLE; 2742 } else { 2743 kp->kp_status_flag &= ~KEYSPAN_PORT_ENABLE; 2744 } 2745 2746 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2747 "keyspan_save_port_params: baud = %x, lcr = %x," 2748 "status_flag = %x", kp->kp_baud, kp->kp_lcr, kp->kp_status_flag); 2749 2750 } 2751 2752 /* 2753 * Set the port parameters to default values 2754 */ 2755 static void 2756 keyspan_default_port_params_usa19hs(keyspan_port_t *kp) 2757 { 2758 keyspan_usa19hs_port_ctrl_msg_t *ctrl_msg = &(kp->kp_ctrl_msg.usa19hs); 2759 ASSERT(mutex_owned(&kp->kp_mutex)); 2760 2761 keyspan_build_cmd_msg(kp, NULL); 2762 2763 ctrl_msg->setRts = 0x01; 2764 ctrl_msg->rts = 0x1; 2765 ctrl_msg->setDtr = 0x01; 2766 ctrl_msg->dtr = 0x1; 2767 2768 ctrl_msg->setClocking = 1; 2769 ctrl_msg->setRxMode = 1; 2770 ctrl_msg->setTxMode = 1; 2771 2772 /* set baud rate to 9600 */ 2773 ctrl_msg->baudLo = keyspan_speedtab_usa19hs[13] & 0xff; 2774 ctrl_msg->baudHi = (keyspan_speedtab_usa19hs[13] >> 8) & 0xff; 2775 ctrl_msg->rxMode = RXMODE_BYHAND; 2776 ctrl_msg->txMode = TXMODE_BYHAND; 2777 2778 ctrl_msg->lcr = 0x3; 2779 ctrl_msg->setLcr = 0x1; 2780 2781 ctrl_msg->xonChar = CSTART; 2782 ctrl_msg->xoffChar = CSTOP; 2783 ctrl_msg->setTxFlowControl = 1; 2784 ctrl_msg->txFlowControl = TXFLOW_CTS; 2785 ctrl_msg->setRxFlowControl = 1; 2786 ctrl_msg->rxFlowControl = RXFLOW_RTS; 2787 ctrl_msg->rxFlush = 0; 2788 2789 } 2790 2791 /* 2792 * Build the command message according to the params from usbser. 2793 * The message will then be sent to deivce by keyspan_send_cmd. 2794 */ 2795 static void 2796 keyspan_build_cmd_msg_usa19hs(keyspan_port_t *kp, ds_port_params_t *tp) 2797 { 2798 int cnt, i; 2799 uint_t ui; 2800 ds_port_param_entry_t *pe; 2801 keyspan_usa19hs_port_ctrl_msg_t *ctrl_msg = &(kp->kp_ctrl_msg.usa19hs); 2802 2803 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, 2804 "keyspan_build_cmd_msg_usa19hs: tp = %p", (void *)tp); 2805 2806 ASSERT(mutex_owned(&kp->kp_mutex)); 2807 ASSERT(kp->kp_state == KEYSPAN_PORT_OPEN || 2808 kp->kp_state == KEYSPAN_PORT_OPENING); 2809 2810 /* bzero all elements */ 2811 bzero(ctrl_msg, sizeof (keyspan_usa19hs_port_ctrl_msg_t)); 2812 2813 /* it is usaually 16, according to Keyspan spec */ 2814 ctrl_msg->rxForwardingLength = 16; 2815 /* from 1ms to 31ms, according to Keyspan spec. */ 2816 ctrl_msg->rxForwardingTimeout = 16; 2817 2818 ctrl_msg->portEnabled = 1; 2819 ctrl_msg->returnStatus = 1; 2820 2821 if (tp == NULL) { 2822 2823 return; 2824 } 2825 2826 cnt = tp->tp_cnt; 2827 pe = tp->tp_entries; 2828 2829 /* translate tp parameters into cmd_msg elements */ 2830 for (i = 0; i < cnt; i++, pe++) { 2831 switch (pe->param) { 2832 case DS_PARAM_BAUD: 2833 ui = pe->val.ui; 2834 2835 /* 2836 * if we don't support this speed, 2837 * then return failure. 2838 */ 2839 if ((ui >= NELEM(keyspan_speedtab_usa19hs)) || 2840 ((ui > 0) && (keyspan_speedtab_usa19hs[ui] == 0))) { 2841 2842 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2843 "keyspan_build_cmd_msg_usa19hs:" 2844 " bad baud %d", ui); 2845 2846 break; 2847 } 2848 2849 /* if the same as the old rate, need not set the rate */ 2850 if (kp->kp_baud == keyspan_speedtab_usa19hs[ui]) { 2851 2852 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2853 "keyspan_build_cmd_msg_usa19hs:" 2854 " same as old baud setting, baud = %d", 2855 keyspan_speed2baud[ui]); 2856 2857 break; 2858 } 2859 ctrl_msg->setClocking = 1; /* enable the setting */ 2860 ctrl_msg->setRxMode = 1; 2861 ctrl_msg->setTxMode = 1; 2862 2863 ctrl_msg->baudLo = keyspan_speedtab_usa19hs[ui] & 0xff; 2864 ctrl_msg->baudHi = (keyspan_speedtab_usa19hs[ui] >> 8) 2865 & 0xff; 2866 2867 ctrl_msg->rxMode = RXMODE_BYHAND; 2868 ctrl_msg->txMode = TXMODE_BYHAND; 2869 2870 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2871 "keyspan_build_cmd_msg_usa19hs: baud=%d", 2872 keyspan_speed2baud[ui]); 2873 2874 break; 2875 case DS_PARAM_PARITY: 2876 if (pe->val.ui & PARENB) { 2877 2878 /* 2879 * Since USA_PARITY_NONE == 0, it's not 2880 * necessary to or it in here. 2881 */ 2882 if (pe->val.ui & PARODD) { 2883 ctrl_msg->lcr |= USA_PARITY_ODD; 2884 } else { 2885 ctrl_msg->lcr |= USA_PARITY_EVEN; 2886 } 2887 } 2888 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2889 "keyspan_build_cmd_msg_usa19hs: parity=%x,lcr = %x", 2890 pe->val.ui, ctrl_msg->lcr); 2891 2892 break; 2893 case DS_PARAM_STOPB: 2894 if (pe->val.ui & CSTOPB) { 2895 ctrl_msg->lcr |= STOPBITS_678_2; 2896 } else { 2897 2898 /* 2899 * STOPBITS_5678_1 equals zero, 2900 * so it's not necessary to or it in. 2901 */ 2902 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2903 "keyspan_build_cmd_msg_usa19hs:" 2904 " STOPBITS_5678_1"); 2905 } 2906 2907 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2908 "keyspan_build_cmd_msg_usa19hs: stopb=%x, lcr = %x", 2909 pe->val.ui, ctrl_msg->lcr); 2910 2911 break; 2912 case DS_PARAM_CHARSZ: 2913 switch (pe->val.ui) { 2914 case CS5: 2915 2916 /* 2917 * USA_DATABITS_5 equals zero, 2918 * not necessary to or it in. 2919 */ 2920 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2921 "keyspan_build_cmd_msg_usa19hs:" 2922 " USA_DATABITS_5"); 2923 2924 break; 2925 case CS6: 2926 ctrl_msg->lcr |= USA_DATABITS_6; 2927 2928 break; 2929 case CS7: 2930 ctrl_msg->lcr |= USA_DATABITS_7; 2931 2932 break; 2933 case CS8: 2934 default: 2935 /* 2936 * The default value is USA_DATABITS_8. It is 2937 * safe to set to the default one here. 2938 */ 2939 ctrl_msg->lcr |= USA_DATABITS_8; 2940 2941 break; 2942 } 2943 2944 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2945 "keyspan_build_cmd_msg_usa19hs: cs=%x, lcr = %x", 2946 pe->val.ui, ctrl_msg->lcr); 2947 2948 break; 2949 case DS_PARAM_XON_XOFF: 2950 ctrl_msg->xonChar = pe->val.uc[0]; /* init to CSTART */ 2951 ctrl_msg->xoffChar = pe->val.uc[1]; /* init to CSTOP */ 2952 2953 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2954 "keyspan_build_cmd_msg_usa19hs: xonChar=%x, " 2955 "xoffChar = %x", ctrl_msg->xonChar, 2956 ctrl_msg->xoffChar); 2957 2958 break; 2959 case DS_PARAM_FLOW_CTL: 2960 if (pe->val.ui & CTSXON) { 2961 ctrl_msg->txFlowControl = TXFLOW_CTS; 2962 ctrl_msg->setTxFlowControl = 1; 2963 } else { 2964 /* Clear the tx flow control setting */ 2965 ctrl_msg->txFlowControl = 0; 2966 ctrl_msg->setTxFlowControl = 1; 2967 } 2968 if (pe->val.ui & RTSXOFF) { 2969 ctrl_msg->rxFlowControl = RXFLOW_RTS; 2970 ctrl_msg->setRxFlowControl = 1; 2971 } else { 2972 /* Clear the rx flow control setting */ 2973 ctrl_msg->rxFlowControl = 0; 2974 ctrl_msg->setRxFlowControl = 1; 2975 } 2976 2977 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 2978 "keyspan_build_cmd_msg_usa19hs: txFlowControl = %x," 2979 "rxFlowControl = %x", ctrl_msg->txFlowControl, 2980 ctrl_msg->rxFlowControl); 2981 2982 break; 2983 default: 2984 USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh, 2985 "keyspan_build_cmd_msg_usa19hs: bad param %d", 2986 pe->param); 2987 2988 break; 2989 } 2990 2991 } 2992 2993 /* 2994 * Enable the lcr settings only if they are different 2995 * with the existing settings. 2996 */ 2997 ctrl_msg->setLcr = (ctrl_msg->lcr == kp->kp_lcr) ? 0 : 1; 2998 2999 } 3000 3001 3002 /* 3003 * Build the command message according to the params from usbser. 3004 * The message will then be sent to deivce by keyspan_send_cmd. 3005 */ 3006 static void 3007 keyspan_build_cmd_msg_usa49(keyspan_port_t *kp, ds_port_params_t *tp) 3008 { 3009 int cnt, i; 3010 uint_t ui; 3011 ds_port_param_entry_t *pe; 3012 keyspan_usa49_port_ctrl_msg_t *ctrl_msg = &(kp->kp_ctrl_msg.usa49); 3013 3014 USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, 3015 "keyspan_build_cmd_msg_usa49: tp = %p", (void *)tp); 3016 3017 ASSERT(mutex_owned(&kp->kp_mutex)); 3018 ASSERT(kp->kp_state == KEYSPAN_PORT_OPEN || 3019 kp->kp_state == KEYSPAN_PORT_OPENING); 3020 3021 /* bzero all elements */ 3022 bzero(ctrl_msg, sizeof (keyspan_usa49_port_ctrl_msg_t)); 3023 3024 ctrl_msg->portNumber = kp->kp_port_num; 3025 3026 /* it is usaually 16, according to Keyspan spec */ 3027 ctrl_msg->forwardingLength = 16; 3028 3029 ctrl_msg->enablePort = 1; 3030 ctrl_msg->returnStatus = 1; 3031 3032 if (tp == NULL) { 3033 3034 return; 3035 } 3036 3037 cnt = tp->tp_cnt; 3038 pe = tp->tp_entries; 3039 3040 /* translate tp parameters into cmd_msg elements */ 3041 for (i = 0; i < cnt; i++, pe++) { 3042 switch (pe->param) { 3043 case DS_PARAM_BAUD: 3044 ui = pe->val.ui; 3045 3046 /* 3047 * If we don't support this speed, 3048 * then return failure. 3049 */ 3050 if ((ui >= NELEM(keyspan_speedtab_usa49)) || 3051 ((ui > 0) && (keyspan_speedtab_usa49[ui] == 0))) { 3052 3053 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 3054 "keyspan_build_cmd_msg_usa49:" 3055 " bad baud %d", ui); 3056 3057 break; 3058 } 3059 3060 /* if the same as the old rate, need not set the rate */ 3061 if (kp->kp_baud == keyspan_speedtab_usa49[ui]) { 3062 3063 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 3064 "keyspan_build_cmd_msg_usa49: " 3065 "same as old baud setting, baud = %d", 3066 keyspan_speed2baud[ui]); 3067 3068 break; 3069 } 3070 ctrl_msg->setClocking = 0xff; /* enable the setting */ 3071 ctrl_msg->baudLo = keyspan_speedtab_usa49[ui] & 0xff; 3072 ctrl_msg->baudHi = (keyspan_speedtab_usa49[ui] >> 8) 3073 & 0xff; 3074 ctrl_msg->prescaler = keyspan_prescaler_49wlc[ui]; 3075 3076 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 3077 "keyspan_build_cmd_msg_usa49: baud=%d", 3078 keyspan_speed2baud[ui]); 3079 3080 break; 3081 case DS_PARAM_PARITY: 3082 if (pe->val.ui & PARENB) { 3083 3084 /* 3085 * Since USA_PARITY_NONE == 0, 3086 * it's not necessary to or it in here. 3087 */ 3088 if (pe->val.ui & PARODD) { 3089 ctrl_msg->lcr |= USA_PARITY_ODD; 3090 } else { 3091 ctrl_msg->lcr |= USA_PARITY_EVEN; 3092 } 3093 } 3094 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 3095 "keyspan_build_cmd_msg_usa49: parity=%x, lcr = %x", 3096 pe->val.ui, ctrl_msg->lcr); 3097 3098 break; 3099 case DS_PARAM_STOPB: 3100 if (pe->val.ui & CSTOPB) { 3101 ctrl_msg->lcr |= STOPBITS_678_2; 3102 } else { 3103 3104 /* 3105 * STOPBITS_5678_1 equals zero, 3106 * not necessary to or it in. 3107 */ 3108 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 3109 "keyspan_build_cmd_msg_usa49: " 3110 "STOPBITS_5678_1"); 3111 } 3112 3113 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 3114 "keyspan_build_cmd_msg_usa49: stopb=%x, lcr = %x", 3115 pe->val.ui, ctrl_msg->lcr); 3116 3117 break; 3118 case DS_PARAM_CHARSZ: 3119 switch (pe->val.ui) { 3120 case CS5: 3121 3122 /* 3123 * USA_DATABITS_5 equals zero, 3124 * not necessary to or it in. 3125 */ 3126 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 3127 "keyspan_build_cmd_msg_usa49:" 3128 " USA_DATABITS_5"); 3129 3130 break; 3131 case CS6: 3132 ctrl_msg->lcr |= USA_DATABITS_6; 3133 3134 break; 3135 case CS7: 3136 ctrl_msg->lcr |= USA_DATABITS_7; 3137 3138 break; 3139 case CS8: 3140 default: 3141 ctrl_msg->lcr |= USA_DATABITS_8; 3142 3143 break; 3144 } 3145 3146 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 3147 "keyspan_build_cmd_msg_usa49: cs=%x, lcr = %x", 3148 pe->val.ui, ctrl_msg->lcr); 3149 3150 break; 3151 case DS_PARAM_XON_XOFF: 3152 ctrl_msg->xonChar = pe->val.uc[0]; /* init to CSTART */ 3153 ctrl_msg->xoffChar = pe->val.uc[1]; /* init to CSTOP */ 3154 3155 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 3156 "keyspan_build_cmd_msg_usa49: xonChar=%x, " 3157 "xoffChar = %x", ctrl_msg->xonChar, 3158 ctrl_msg->xoffChar); 3159 3160 break; 3161 case DS_PARAM_FLOW_CTL: 3162 if (pe->val.ui & CTSXON) { 3163 ctrl_msg->ctsFlowControl = 1; 3164 ctrl_msg->setFlowControl = 1; 3165 } else { 3166 ctrl_msg->ctsFlowControl = 0; 3167 ctrl_msg->setFlowControl = 1; 3168 } 3169 if (pe->val.ui & RTSXOFF) { 3170 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 3171 "keyspan_build_cmd_msg_usa49: " 3172 "pe->val.ui = %x, flow_ctl: RTSXOFF, " 3173 "no hardware support", pe->val.ui); 3174 } 3175 3176 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 3177 "keyspan_build_cmd_msg_usa49: ctsFlowControl = %x," 3178 "dsrFlowControl = %x", ctrl_msg->ctsFlowControl, 3179 ctrl_msg->dsrFlowControl); 3180 3181 break; 3182 default: 3183 USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh, 3184 "keyspan_build_cmd_msg_usa49: bad param %d", 3185 pe->param); 3186 3187 break; 3188 } 3189 } 3190 3191 /* 3192 * enable the lcr settings only if they are different 3193 * with the existing settings. 3194 */ 3195 ctrl_msg->setLcr = (ctrl_msg->lcr == kp->kp_lcr) ? 0 : 1; 3196 3197 } 3198 3199 3200 /* 3201 * Set the port parameters to default values 3202 */ 3203 static void 3204 keyspan_default_port_params_usa49(keyspan_port_t *kp) 3205 { 3206 keyspan_usa49_port_ctrl_msg_t *ctrl_msg = &(kp->kp_ctrl_msg.usa49); 3207 ASSERT(mutex_owned(&kp->kp_mutex)); 3208 3209 keyspan_build_cmd_msg(kp, NULL); 3210 3211 ctrl_msg->setRts = 1; 3212 ctrl_msg->rts = 1; 3213 ctrl_msg->setDtr = 1; 3214 ctrl_msg->dtr = 1; 3215 3216 ctrl_msg->_txOn = 1; 3217 ctrl_msg->_txOff = 0; 3218 ctrl_msg->txFlush = 0; 3219 ctrl_msg->txBreak = 0; 3220 ctrl_msg->rxOn = 1; 3221 ctrl_msg->rxOff = 0; 3222 ctrl_msg->rxFlush = 0; 3223 ctrl_msg->rxForward = 0; 3224 ctrl_msg->returnStatus = 1; 3225 ctrl_msg->resetDataToggle = 0; 3226 ctrl_msg->enablePort = 1; 3227 ctrl_msg->disablePort = 0; 3228 3229 /* set baud rate to 9600 */ 3230 ctrl_msg->setClocking = 1; 3231 ctrl_msg->baudLo = keyspan_speedtab_usa49[13] & 0xff; 3232 ctrl_msg->baudHi = (keyspan_speedtab_usa49[13] >> 8) & 0xff; 3233 ctrl_msg->prescaler = keyspan_prescaler_49wlc[13]; 3234 3235 ctrl_msg->lcr = 0x3; 3236 ctrl_msg->setLcr = 1; 3237 3238 ctrl_msg->xonChar = CSTART; 3239 ctrl_msg->xoffChar = CSTOP; 3240 ctrl_msg->ctsFlowControl = 1; 3241 ctrl_msg->setFlowControl = 1; 3242 3243 } 3244 3245 3246 /* save the port params after send cmd successfully */ 3247 static void 3248 keyspan_save_port_params_usa49(keyspan_port_t *kp) 3249 { 3250 keyspan_usa49_port_ctrl_msg_t *ctrl_msg = &(kp->kp_ctrl_msg.usa49); 3251 3252 ASSERT(mutex_owned(&kp->kp_mutex)); 3253 3254 if (ctrl_msg->setClocking) { 3255 kp->kp_baud = ctrl_msg->baudHi; 3256 kp->kp_baud = (kp->kp_baud << 8); 3257 kp->kp_baud |= ctrl_msg->baudLo; 3258 } 3259 if (ctrl_msg->setLcr) { 3260 kp->kp_lcr = ctrl_msg->lcr; 3261 } 3262 if (ctrl_msg->setRts) { 3263 if (ctrl_msg->rts) { 3264 kp->kp_status_flag |= KEYSPAN_PORT_RTS; 3265 } else { 3266 kp->kp_status_flag &= ~KEYSPAN_PORT_RTS; 3267 } 3268 } 3269 if (ctrl_msg->setDtr) { 3270 if (ctrl_msg->dtr) { 3271 kp->kp_status_flag |= KEYSPAN_PORT_DTR; 3272 } else { 3273 kp->kp_status_flag &= ~KEYSPAN_PORT_DTR; 3274 } 3275 } 3276 3277 if (ctrl_msg->enablePort) { 3278 kp->kp_status_flag |= KEYSPAN_PORT_ENABLE; 3279 } else { 3280 kp->kp_status_flag &= ~KEYSPAN_PORT_ENABLE; 3281 } 3282 3283 /* 3284 * There are no flags in status msg (49wlc) can indicate the 3285 * break status, so we make use of ctrl_msg->txBreak here. 3286 */ 3287 if (ctrl_msg->txBreak) { 3288 kp->kp_status_flag |= KEYSPAN_PORT_TXBREAK; 3289 } else { 3290 kp->kp_status_flag &= ~KEYSPAN_PORT_TXBREAK; 3291 } 3292 3293 USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, 3294 "keyspan_save_port_params: baud = %x, lcr = %x," 3295 "status_flag = %x", kp->kp_baud, kp->kp_lcr, kp->kp_status_flag); 3296 3297 } 3298