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