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 2007 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"
720 			    " product id can't 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 		 * If usbser dev_state is DISCONNECTED or SUSPENDED, it shows
829 		 * that the usb serial device is disconnected/suspended while it
830 		 * is under power down state, now the device is powered up
831 		 * before it is reconnected/resumed. xxx_pwrlvl3() will set dev
832 		 * state to ONLINE, we need to set the dev state back to
833 		 * DISCONNECTED/SUSPENDED.
834 		 */
835 		if ((rval == USB_SUCCESS) &&
836 		    ((*new_state == USB_DEV_DISCONNECTED) ||
837 		    (*new_state == USB_DEV_SUSPENDED))) {
838 			ksp->ks_dev_state = *new_state;
839 		}
840 
841 		break;
842 	default:
843 		ASSERT(0);	/* cannot happen */
844 	}
845 
846 	*new_state = ksp->ks_dev_state;
847 	mutex_exit(&ksp->ks_mutex);
848 
849 	return (rval);
850 }
851 
852 
853 /*
854  * ds_suspend
855  */
856 static int
857 keyspan_suspend(ds_hdl_t hdl)
858 {
859 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
860 	int		state = USB_DEV_SUSPENDED;
861 
862 	USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_suspend");
863 
864 	/*
865 	 * If the device is suspended while it is under PWRED_DOWN state, we
866 	 * need to keep the PWRED_DOWN state so that it could be powered up
867 	 * later. In the mean while, usbser dev state will be changed to
868 	 * SUSPENDED state.
869 	 */
870 	mutex_enter(&ksp->ks_mutex);
871 	if (ksp->ks_dev_state != USB_DEV_PWRED_DOWN) {
872 		ksp->ks_dev_state = USB_DEV_SUSPENDED;
873 	}
874 	mutex_exit(&ksp->ks_mutex);
875 
876 	keyspan_disconnect_pipes(ksp);
877 
878 	return (state);
879 }
880 
881 
882 /*
883  * ds_resume
884  */
885 static int
886 keyspan_resume(ds_hdl_t hdl)
887 {
888 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
889 	int		current_state;
890 	int		rval;
891 
892 	USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_resume");
893 
894 	mutex_enter(&ksp->ks_mutex);
895 	current_state = ksp->ks_dev_state;
896 	mutex_exit(&ksp->ks_mutex);
897 
898 	if (current_state != USB_DEV_ONLINE) {
899 		rval = keyspan_restore_device_state(ksp);
900 	} else {
901 		rval = USB_SUCCESS;
902 	}
903 
904 	return (rval);
905 }
906 
907 
908 /*
909  * ds_disconnect
910  */
911 static int
912 keyspan_disconnect(ds_hdl_t hdl)
913 {
914 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
915 	int		state = USB_DEV_DISCONNECTED;
916 
917 	USB_DPRINTF_L4(DPRINT_HOTPLUG, ksp->ks_lh, "keyspan_disconnect");
918 
919 	/*
920 	 * If the device is disconnected while it is under PWRED_DOWN state, we
921 	 * need to keep the PWRED_DOWN state so that it could be powered up
922 	 * later. In the mean while, usbser dev state will be changed to
923 	 * DISCONNECTED state.
924 	 */
925 	mutex_enter(&ksp->ks_mutex);
926 	if (ksp->ks_dev_state != USB_DEV_PWRED_DOWN) {
927 		ksp->ks_dev_state = USB_DEV_DISCONNECTED;
928 	}
929 	mutex_exit(&ksp->ks_mutex);
930 
931 	keyspan_disconnect_pipes(ksp);
932 
933 	return (state);
934 }
935 
936 
937 /*
938  * ds_reconnect
939  */
940 static int
941 keyspan_reconnect(ds_hdl_t hdl)
942 {
943 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
944 
945 	USB_DPRINTF_L4(DPRINT_HOTPLUG, ksp->ks_lh, "keyspan_reconnect");
946 
947 	return (keyspan_restore_device_state(ksp));
948 }
949 
950 /*
951  * ds_set_port_params
952  */
953 static int
954 keyspan_set_port_params(ds_hdl_t hdl, uint_t port_num, ds_port_params_t *tp)
955 {
956 	int		cnt = tp->tp_cnt;
957 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
958 	keyspan_port_t	*kp = &ksp->ks_ports[port_num];
959 
960 	ASSERT(port_num < ksp->ks_dev_spec.port_cnt);
961 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh,
962 	    "keyspan_set_port_params: port: %d params", cnt);
963 
964 	if (cnt <= 0) {
965 
966 		return (USB_SUCCESS);
967 	}
968 
969 	mutex_enter(&kp->kp_mutex);
970 	ASSERT((kp->kp_state == KEYSPAN_PORT_OPENING) ||
971 	    (kp->kp_state == KEYSPAN_PORT_OPEN));
972 	keyspan_build_cmd_msg(kp, tp);
973 	mutex_exit(&kp->kp_mutex);
974 
975 	if (keyspan_send_cmd(kp) != USB_SUCCESS) {
976 			USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh,
977 			    "keyspan_send_cmd() FAILED");
978 
979 			return (USB_FAILURE);
980 	}
981 
982 	return (USB_SUCCESS);
983 }
984 
985 
986 /*
987  * ds_set_modem_ctl
988  */
989 static int
990 keyspan_set_modem_ctl(ds_hdl_t hdl, uint_t port_num, int mask, int val)
991 {
992 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
993 	keyspan_port_t	*kp = &ksp->ks_ports[port_num];
994 
995 	ASSERT(port_num < ksp->ks_dev_spec.port_cnt);
996 
997 	mutex_enter(&kp->kp_mutex);
998 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_set_modem_ctl: "
999 	    "mask=%x, val=%x", mask, val);
1000 
1001 	keyspan_build_cmd_msg(kp, NULL);
1002 
1003 	switch (ksp->ks_dev_spec.id_product) {
1004 	case KEYSPAN_USA19HS_PID:
1005 		if (mask & TIOCM_RTS) {
1006 
1007 			kp->kp_ctrl_msg.usa19hs.setRts = 0x01;
1008 
1009 			if (val & TIOCM_RTS) {
1010 				kp->kp_ctrl_msg.usa19hs.rts = 0x1;
1011 			} else {
1012 				kp->kp_ctrl_msg.usa19hs.rts = 0x0;
1013 			}
1014 
1015 		} else {
1016 			kp->kp_ctrl_msg.usa19hs.setRts = 0x0;
1017 		}
1018 
1019 		if (mask & TIOCM_DTR) {
1020 			kp->kp_ctrl_msg.usa19hs.setDtr = 0x01;
1021 
1022 			if (val & TIOCM_DTR) {
1023 				kp->kp_ctrl_msg.usa19hs.dtr = 0x1;
1024 			} else {
1025 				kp->kp_ctrl_msg.usa19hs.dtr = 0x0;
1026 			}
1027 
1028 		} else {
1029 			kp->kp_ctrl_msg.usa19hs.setDtr = 0x0;
1030 		}
1031 
1032 		break;
1033 
1034 
1035 	case KEYSPAN_USA49WLC_PID:
1036 	case KEYSPAN_USA49WG_PID:
1037 		if (mask & TIOCM_RTS) {
1038 
1039 			kp->kp_ctrl_msg.usa49.setRts = 0x1;
1040 
1041 			if (val & TIOCM_RTS) {
1042 				kp->kp_ctrl_msg.usa49.rts = 0x1;
1043 			} else {
1044 				kp->kp_ctrl_msg.usa49.rts = 0x0;
1045 			}
1046 
1047 		} else {
1048 			kp->kp_ctrl_msg.usa49.setRts = 0x0;
1049 		}
1050 
1051 		if (mask & TIOCM_DTR) {
1052 			kp->kp_ctrl_msg.usa49.setDtr = 0x1;
1053 
1054 			if (val & TIOCM_DTR) {
1055 				kp->kp_ctrl_msg.usa49.dtr = 0x1;
1056 			} else {
1057 				kp->kp_ctrl_msg.usa49.dtr = 0x0;
1058 			}
1059 
1060 		} else {
1061 			kp->kp_ctrl_msg.usa49.setDtr = 0x0;
1062 		}
1063 
1064 		break;
1065 
1066 	default:
1067 		USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh,
1068 		    "keyspan_get_modem_ctl:"
1069 		    "the device's product id can't be recognized");
1070 		mutex_exit(&kp->kp_mutex);
1071 
1072 		return (USB_FAILURE);
1073 	}
1074 
1075 	mutex_exit(&kp->kp_mutex);
1076 
1077 	if (keyspan_send_cmd(kp) != USB_SUCCESS) {
1078 			USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh,
1079 			    "keyspan_send_cmd() FAILED");
1080 
1081 			return (USB_FAILURE);
1082 	}
1083 
1084 	return (USB_SUCCESS);
1085 }
1086 
1087 /*
1088  * ds_get_modem_ctl
1089  */
1090 static int
1091 keyspan_get_modem_ctl(ds_hdl_t hdl, uint_t port_num, int mask, int *valp)
1092 {
1093 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
1094 	keyspan_port_t	*kp = &ksp->ks_ports[port_num];
1095 	int	val = 0;
1096 
1097 	ASSERT(port_num < ksp->ks_dev_spec.port_cnt);
1098 
1099 	mutex_enter(&kp->kp_mutex);
1100 
1101 	/*
1102 	 * rts and dtr are not in status_msg, but we can get it from
1103 	 * status_flag since it represents what we set the device last time.
1104 	 */
1105 	if (kp->kp_status_flag & KEYSPAN_PORT_RTS) {
1106 		val |= TIOCM_RTS;
1107 	}
1108 	if (kp->kp_status_flag & KEYSPAN_PORT_DTR) {
1109 		val |= TIOCM_DTR;
1110 	}
1111 
1112 	/* usbser don't deal with TIOCM_RI status */
1113 	switch (ksp->ks_dev_spec.id_product) {
1114 	case KEYSPAN_USA19HS_PID:
1115 		if (kp->kp_status_msg.usa19hs.dcd) {
1116 			val |= TIOCM_CD;
1117 		}
1118 		if (kp->kp_status_msg.usa19hs.cts) {
1119 			val |= TIOCM_CTS;
1120 		}
1121 		if (kp->kp_status_msg.usa19hs.dsr) {
1122 			val |= TIOCM_DSR;
1123 		}
1124 		break;
1125 
1126 
1127 	case KEYSPAN_USA49WLC_PID:
1128 	case KEYSPAN_USA49WG_PID:
1129 		if (kp->kp_status_msg.usa49.dcd) {
1130 			val |= TIOCM_CD;
1131 		}
1132 		if (kp->kp_status_msg.usa49.cts) {
1133 			val |= TIOCM_CTS;
1134 		}
1135 		if (kp->kp_status_msg.usa49.dsr) {
1136 			val |= TIOCM_DSR;
1137 		}
1138 		break;
1139 
1140 	default:
1141 		USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
1142 		    "keyspan_get_modem_ctl:"
1143 		    "the device's product id can't be recognized");
1144 		mutex_exit(&kp->kp_mutex);
1145 
1146 		return (USB_FAILURE);
1147 	}
1148 
1149 	*valp = val & mask;
1150 
1151 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_get_modem_ctl:"
1152 	    "success. status_flag = %x, val=0%o",
1153 	    kp->kp_status_flag, *valp);
1154 
1155 	mutex_exit(&kp->kp_mutex);
1156 
1157 	return (USB_SUCCESS);
1158 }
1159 
1160 
1161 /*
1162  * ds_break_ctl
1163  */
1164 static int
1165 keyspan_break_ctl(ds_hdl_t hdl, uint_t port_num, int ctl)
1166 {
1167 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
1168 	keyspan_port_t	*kp = &ksp->ks_ports[port_num];
1169 	int		is_break;
1170 	int		rval = USB_SUCCESS;
1171 
1172 	ASSERT(port_num < ksp->ks_dev_spec.port_cnt);
1173 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh,
1174 	    "keyspan_break_ctl: ctl = %s", (ctl == DS_ON) ? "on" : "off");
1175 
1176 	mutex_enter(&kp->kp_mutex);
1177 	ASSERT(kp->kp_state == KEYSPAN_PORT_OPEN);
1178 	ASSERT(ctl == DS_ON || ctl == DS_OFF);
1179 
1180 	is_break = kp->kp_status_flag & KEYSPAN_PORT_TXBREAK;
1181 
1182 	if ((ctl == DS_ON) && !is_break) {
1183 
1184 		keyspan_build_cmd_msg(kp, NULL);
1185 
1186 		switch (ksp->ks_dev_spec.id_product) {
1187 		case KEYSPAN_USA19HS_PID:
1188 			kp->kp_ctrl_msg.usa19hs.txBreak = 1;
1189 
1190 			break;
1191 
1192 		case KEYSPAN_USA49WLC_PID:
1193 		case KEYSPAN_USA49WG_PID:
1194 			kp->kp_ctrl_msg.usa49.txBreak = 1;
1195 
1196 			break;
1197 
1198 		default:
1199 			mutex_exit(&kp->kp_mutex);
1200 			USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
1201 			    "keyspan_break_ctl:"
1202 			    "the device's product id can't be recognized");
1203 
1204 			return (USB_FAILURE);
1205 		}
1206 
1207 		mutex_exit(&kp->kp_mutex);
1208 		rval = keyspan_send_cmd(kp);
1209 		return (rval);
1210 	}
1211 
1212 	if ((ctl == DS_OFF) && is_break) {
1213 		keyspan_build_cmd_msg(kp, NULL);
1214 
1215 		switch (ksp->ks_dev_spec.id_product) {
1216 		case KEYSPAN_USA19HS_PID:
1217 			kp->kp_ctrl_msg.usa19hs.txBreak = 0;
1218 
1219 			break;
1220 
1221 		case KEYSPAN_USA49WLC_PID:
1222 		case KEYSPAN_USA49WG_PID:
1223 			kp->kp_ctrl_msg.usa49._txOn = 1;
1224 			kp->kp_ctrl_msg.usa49.txBreak = 0;
1225 
1226 			break;
1227 
1228 		default:
1229 			mutex_exit(&kp->kp_mutex);
1230 			USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
1231 			    "keyspan_break_ctl:"
1232 			    "the device's product id can't be recognized");
1233 
1234 			return (USB_FAILURE);
1235 		}
1236 
1237 		mutex_exit(&kp->kp_mutex);
1238 		rval = keyspan_send_cmd(kp);
1239 		if (rval == USB_SUCCESS) {
1240 			mutex_enter(&kp->kp_mutex);
1241 
1242 			/* resume transmit */
1243 			keyspan_tx_start(kp, NULL);
1244 			mutex_exit(&kp->kp_mutex);
1245 		}
1246 
1247 		return (rval);
1248 	}
1249 
1250 	mutex_exit(&kp->kp_mutex);
1251 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh,
1252 	    "keyspan_break_ctl: not necessary to set break, is_break = %d",
1253 	    is_break);
1254 
1255 	return (rval);
1256 }
1257 
1258 
1259 /*
1260  * ds_loopback
1261  */
1262 static int
1263 keyspan_loopback(ds_hdl_t hdl, uint_t port_num, int ctl)
1264 {
1265 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
1266 	keyspan_port_t	*kp = &ksp->ks_ports[port_num];
1267 	int		is_loop;
1268 	int		rval = USB_SUCCESS;
1269 
1270 	ASSERT(port_num < ksp->ks_dev_spec.port_cnt);
1271 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh,
1272 	    "keyspan_loopback: %s", (ctl == DS_ON) ? "on" : "off");
1273 
1274 	mutex_enter(&kp->kp_mutex);
1275 	ASSERT(kp->kp_state == KEYSPAN_PORT_OPEN);
1276 	ASSERT(ctl == DS_ON || ctl == DS_OFF);
1277 
1278 	/* check bit indicating internal loopback state */
1279 	is_loop = kp->kp_status_flag & KEYSPAN_PORT_LOOPBACK;
1280 
1281 	if ((ctl == DS_ON) && !is_loop) {
1282 
1283 		keyspan_build_cmd_msg(kp, NULL);
1284 		switch (ksp->ks_dev_spec.id_product) {
1285 		case KEYSPAN_USA19HS_PID:
1286 			kp->kp_ctrl_msg.usa19hs.loopbackMode = 0;
1287 
1288 			break;
1289 
1290 		case KEYSPAN_USA49WLC_PID:
1291 		case KEYSPAN_USA49WG_PID:
1292 			kp->kp_ctrl_msg.usa49.loopbackMode = 0;
1293 
1294 			break;
1295 
1296 		default:
1297 			mutex_exit(&kp->kp_mutex);
1298 			USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
1299 			    "keyspan_loopback:"
1300 			    "the device's product id can't be recognized");
1301 
1302 			return (USB_FAILURE);
1303 		}
1304 		mutex_exit(&kp->kp_mutex);
1305 		rval = keyspan_send_cmd(kp);
1306 	} else if ((ctl == DS_OFF) && is_loop) {
1307 
1308 		keyspan_build_cmd_msg(kp, NULL);
1309 		switch (ksp->ks_dev_spec.id_product) {
1310 		case KEYSPAN_USA19HS_PID:
1311 			kp->kp_ctrl_msg.usa19hs.loopbackMode = 1;
1312 
1313 			break;
1314 
1315 		case KEYSPAN_USA49WLC_PID:
1316 		case KEYSPAN_USA49WG_PID:
1317 			kp->kp_ctrl_msg.usa49.loopbackMode = 1;
1318 
1319 			break;
1320 
1321 		default:
1322 			mutex_exit(&kp->kp_mutex);
1323 			USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
1324 			    "keyspan_loopback:"
1325 			    "the device's product id can't be recognized");
1326 
1327 			return (USB_FAILURE);
1328 		}
1329 		mutex_exit(&kp->kp_mutex);
1330 		rval = keyspan_send_cmd(kp);
1331 	} else {
1332 		mutex_exit(&kp->kp_mutex);
1333 		USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh,
1334 		    "keyspan_loopback: not necessary to set loopback,"
1335 		    "is_loop = %d", is_loop);
1336 	}
1337 
1338 	return (rval);
1339 }
1340 
1341 
1342 /*
1343  * ds_tx
1344  */
1345 static int
1346 keyspan_tx(ds_hdl_t hdl, uint_t port_num, mblk_t *mp)
1347 {
1348 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
1349 	keyspan_port_t	*kp = &ksp->ks_ports[port_num];
1350 	int		xferd;
1351 
1352 	ASSERT(port_num < ksp->ks_dev_spec.port_cnt);
1353 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_tx");
1354 
1355 	/*
1356 	 * sanity checks
1357 	 */
1358 	if (mp == NULL) {
1359 		USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh, "keyspan_tx: mp=NULL");
1360 
1361 		return (USB_SUCCESS);
1362 	}
1363 
1364 	kp = &ksp->ks_ports[port_num];
1365 
1366 	mutex_enter(&kp->kp_mutex);
1367 
1368 	keyspan_put_tail(&kp->kp_tx_mp, mp);	/* add to the chain */
1369 
1370 	keyspan_tx_start(kp, &xferd);		/* go! */
1371 
1372 	mutex_exit(&kp->kp_mutex);
1373 
1374 	return (USB_SUCCESS);
1375 }
1376 
1377 
1378 /*
1379  * ds_rx. the real data receiving is in keyspan_open_hw_port
1380  */
1381 static mblk_t *
1382 keyspan_rx(ds_hdl_t hdl, uint_t port_num)
1383 {
1384 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
1385 	keyspan_port_t	*kp = &ksp->ks_ports[port_num];
1386 	mblk_t		*mp;
1387 
1388 	ASSERT(port_num < ksp->ks_dev_spec.port_cnt);
1389 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_rx");
1390 
1391 	mutex_enter(&kp->kp_mutex);
1392 	mp = kp->kp_rx_mp;
1393 	kp->kp_rx_mp = NULL;
1394 	mutex_exit(&kp->kp_mutex);
1395 
1396 	return (mp);
1397 }
1398 
1399 
1400 /*
1401  * ds_stop
1402  */
1403 static void
1404 keyspan_stop(ds_hdl_t hdl, uint_t port_num, int dir)
1405 {
1406 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
1407 	keyspan_port_t	*kp = &ksp->ks_ports[port_num];
1408 
1409 	ASSERT(port_num < ksp->ks_dev_spec.port_cnt);
1410 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_stop");
1411 
1412 	if (dir & DS_TX) {
1413 		mutex_enter(&kp->kp_mutex);
1414 		kp->kp_flags |= KEYSPAN_PORT_TX_STOPPED;
1415 		mutex_exit(&kp->kp_mutex);
1416 	}
1417 }
1418 
1419 
1420 /*
1421  * ds_start
1422  */
1423 static void
1424 keyspan_start(ds_hdl_t hdl, uint_t port_num, int dir)
1425 {
1426 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
1427 	keyspan_port_t	*kp = &ksp->ks_ports[port_num];
1428 
1429 	ASSERT(port_num < ksp->ks_dev_spec.port_cnt);
1430 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_start");
1431 
1432 	if (dir & DS_TX) {
1433 		mutex_enter(&kp->kp_mutex);
1434 		if (kp->kp_flags & KEYSPAN_PORT_TX_STOPPED) {
1435 			kp->kp_flags &= ~KEYSPAN_PORT_TX_STOPPED;
1436 			keyspan_tx_start(kp, NULL);
1437 		}
1438 		mutex_exit(&kp->kp_mutex);
1439 	}
1440 }
1441 
1442 
1443 /*
1444  * ds_fifo_flush
1445  * send flush cmd and wait for completion, then turn off the flush.
1446  */
1447 static int
1448 keyspan_fifo_flush(ds_hdl_t hdl, uint_t port_num, int dir)
1449 {
1450 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
1451 	keyspan_port_t	*kp = &ksp->ks_ports[port_num];
1452 
1453 	ASSERT(port_num < ksp->ks_dev_spec.port_cnt);
1454 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh,
1455 	    "keyspan_fifo_flush: dir=%x", dir);
1456 
1457 	mutex_enter(&kp->kp_mutex);
1458 	ASSERT(kp->kp_state == KEYSPAN_PORT_OPEN);
1459 
1460 	/* discard the data in DSD buffers */
1461 	if ((dir & DS_TX) && kp->kp_tx_mp) {
1462 		freemsg(kp->kp_tx_mp);
1463 		kp->kp_tx_mp = NULL;
1464 	}
1465 	if ((dir & DS_RX) && kp->kp_rx_mp) {
1466 		freemsg(kp->kp_rx_mp);
1467 		kp->kp_rx_mp = NULL;
1468 	}
1469 
1470 	mutex_exit(&kp->kp_mutex);
1471 
1472 	return (USB_SUCCESS);
1473 }
1474 
1475 /*
1476  * ds_fifo_drain
1477  *
1478  * it is the caller's responsibility to cease submitting new tx data
1479  * while this function executes
1480  */
1481 static int
1482 keyspan_fifo_drain(ds_hdl_t hdl, uint_t port_num, int timeout)
1483 {
1484 	keyspan_state_t	*ksp = (keyspan_state_t *)hdl;
1485 	keyspan_port_t	*kp = &ksp->ks_ports[port_num];
1486 	int		rval = USB_SUCCESS;
1487 
1488 	ASSERT(port_num < ksp->ks_dev_spec.port_cnt);
1489 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh,
1490 	    "keyspan_fifo_drain, timeout = %d", timeout);
1491 
1492 	mutex_enter(&kp->kp_mutex);
1493 	ASSERT(kp->kp_state == KEYSPAN_PORT_OPEN);
1494 
1495 	/* wait until local data drains */
1496 	if (keyspan_wait_tx_drain(kp, 0) != USB_SUCCESS) {
1497 		mutex_exit(&kp->kp_mutex);
1498 
1499 		return (USB_FAILURE);
1500 	}
1501 	mutex_exit(&kp->kp_mutex);
1502 
1503 	/* wait until hw fifo drains */
1504 	delay(drv_usectohz(500*1000));
1505 
1506 	return (rval);
1507 }
1508 
1509 
1510 /*
1511  * configuration routines
1512  * ----------------------
1513  *
1514  */
1515 
1516 /*
1517  * free state structure
1518  */
1519 static void
1520 keyspan_free_soft_state(keyspan_state_t *ksp)
1521 {
1522 	kmem_free(ksp, sizeof (keyspan_state_t));
1523 }
1524 
1525 
1526 /*
1527  * register/unregister USBA client
1528  */
1529 static int
1530 keyspan_usb_register(keyspan_state_t *ksp)
1531 {
1532 	int	rval;
1533 
1534 	rval = usb_client_attach(ksp->ks_dip, USBDRV_VERSION, 0);
1535 	if (rval == USB_SUCCESS) {
1536 		rval = usb_get_dev_data(ksp->ks_dip, &ksp->ks_dev_data,
1537 		    USB_PARSE_LVL_IF, 0);
1538 		if (rval == USB_SUCCESS) {
1539 			ksp->ks_lh =
1540 			    usb_alloc_log_hdl(ksp->ks_dip, "keyspan[*].",
1541 			    &keyspan_errlevel, &keyspan_errmask,
1542 			    &keyspan_instance_debug, 0);
1543 
1544 			ksp->ks_def_pipe.pipe_handle =
1545 			    ksp->ks_dev_data->dev_default_ph;
1546 			ksp->ks_def_pipe.pipe_ksp = ksp;
1547 			ksp->ks_def_pipe.pipe_lh = ksp->ks_lh;
1548 		}
1549 	}
1550 
1551 	return (rval);
1552 }
1553 
1554 
1555 static void
1556 keyspan_usb_unregister(keyspan_state_t *ksp)
1557 {
1558 	usb_free_log_hdl(ksp->ks_lh);
1559 	ksp->ks_lh = NULL;
1560 	usb_client_detach(ksp->ks_dip, ksp->ks_dev_data);
1561 	ksp->ks_def_pipe.pipe_handle = NULL;
1562 	ksp->ks_dev_data = NULL;
1563 }
1564 
1565 
1566 /*
1567  * init/fini soft state during attach
1568  */
1569 static void
1570 keyspan_init_sync_objs(keyspan_state_t *ksp)
1571 {
1572 	mutex_init(&ksp->ks_mutex, NULL, MUTEX_DRIVER,
1573 	    ksp->ks_dev_data->dev_iblock_cookie);
1574 	sema_init(&ksp->ks_pipes_sema, 1, NULL, SEMA_DRIVER, NULL);
1575 }
1576 
1577 
1578 static void
1579 keyspan_fini_sync_objs(keyspan_state_t *ksp)
1580 {
1581 	mutex_destroy(&ksp->ks_mutex);
1582 	sema_destroy(&ksp->ks_pipes_sema);
1583 }
1584 
1585 
1586 /*
1587  * device specific attributes
1588  */
1589 static int
1590 keyspan_attach_dev(keyspan_state_t *ksp)
1591 {
1592 
1593 	mutex_enter(&ksp->ks_mutex);
1594 	switch (ksp->ks_dev_data->dev_descr->idProduct) {
1595 	case KEYSPAN_USA19HS_PID:
1596 		ksp->ks_dev_spec.id_product = KEYSPAN_USA19HS_PID;
1597 		ksp->ks_dev_spec.port_cnt = 1;
1598 		ksp->ks_dev_spec.ctrl_ep_addr = 0x02;
1599 		ksp->ks_dev_spec.stat_ep_addr = 0x82;
1600 		ksp->ks_dev_spec.dataout_ep_addr[0] = 0x01;
1601 		ksp->ks_dev_spec.datain_ep_addr[0] = 0x81;
1602 
1603 		break;
1604 
1605 	case KEYSPAN_USA49WLC_PID:
1606 		ksp->ks_dev_spec.id_product = KEYSPAN_USA49WLC_PID;
1607 		ksp->ks_dev_spec.port_cnt = 4;
1608 		ksp->ks_dev_spec.ctrl_ep_addr = 0x07;
1609 		ksp->ks_dev_spec.stat_ep_addr = 0x87;
1610 		ksp->ks_dev_spec.dataout_ep_addr[0] = 0x01;
1611 		ksp->ks_dev_spec.dataout_ep_addr[1] = 0x02;
1612 		ksp->ks_dev_spec.dataout_ep_addr[2] = 0x03;
1613 		ksp->ks_dev_spec.dataout_ep_addr[3] = 0x04;
1614 		ksp->ks_dev_spec.datain_ep_addr[0] = 0x81;
1615 		ksp->ks_dev_spec.datain_ep_addr[1] = 0x82;
1616 		ksp->ks_dev_spec.datain_ep_addr[2] = 0x83;
1617 		ksp->ks_dev_spec.datain_ep_addr[3] = 0x84;
1618 
1619 		break;
1620 
1621 	case KEYSPAN_USA49WG_PID:
1622 		ksp->ks_dev_spec.id_product = KEYSPAN_USA49WG_PID;
1623 		ksp->ks_dev_spec.port_cnt = 4;
1624 		ksp->ks_dev_spec.stat_ep_addr = 0x81;
1625 		ksp->ks_dev_spec.dataout_ep_addr[0] = 0x01;
1626 		ksp->ks_dev_spec.dataout_ep_addr[1] = 0x02;
1627 		ksp->ks_dev_spec.dataout_ep_addr[2] = 0x04;
1628 		ksp->ks_dev_spec.dataout_ep_addr[3] = 0x06;
1629 		ksp->ks_dev_spec.datain_ep_addr[0] = 0x88;
1630 		ksp->ks_dev_spec.datain_ep_addr[1] = 0x88;
1631 		ksp->ks_dev_spec.datain_ep_addr[2] = 0x88;
1632 		ksp->ks_dev_spec.datain_ep_addr[3] = 0x88;
1633 
1634 		break;
1635 
1636 	default:
1637 		mutex_exit(&ksp->ks_mutex);
1638 		USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
1639 		    "keyspan_attach_dev:"
1640 		    "the device's product id can't be recognized");
1641 
1642 		return (USB_FAILURE);
1643 	}
1644 
1645 	mutex_exit(&ksp->ks_mutex);
1646 
1647 	return (USB_SUCCESS);
1648 }
1649 
1650 /*
1651  * allocate and initialize per port resources.
1652  */
1653 static void
1654 keyspan_attach_ports(keyspan_state_t *ksp)
1655 {
1656 	int		i;
1657 	keyspan_port_t	*kp;
1658 
1659 	ksp->ks_ports = kmem_zalloc(ksp->ks_dev_spec.port_cnt *
1660 	    sizeof (keyspan_port_t), KM_SLEEP);
1661 
1662 	for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) {
1663 		kp = &ksp->ks_ports[i];
1664 		kp->kp_port_num = i;
1665 		kp->kp_ksp = ksp;
1666 
1667 		(void) sprintf(kp->kp_lh_name, "keyspan[%d].", i);
1668 		kp->kp_lh = usb_alloc_log_hdl(ksp->ks_dip, kp->kp_lh_name,
1669 		    &keyspan_errlevel, &keyspan_errmask,
1670 		    &keyspan_instance_debug, 0);
1671 
1672 		kp->kp_state = KEYSPAN_PORT_CLOSED;
1673 		mutex_init(&kp->kp_mutex, NULL, MUTEX_DRIVER,
1674 		    ksp->ks_dev_data->dev_iblock_cookie);
1675 		cv_init(&kp->kp_tx_cv, NULL, CV_DRIVER, NULL);
1676 	}
1677 }
1678 
1679 
1680 /*
1681  * free per port resources
1682  */
1683 static void
1684 keyspan_detach_ports(keyspan_state_t *ksp)
1685 {
1686 	int		i;
1687 	keyspan_port_t	*kp;
1688 
1689 	for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) {
1690 		kp = &ksp->ks_ports[i];
1691 		if (kp->kp_state != KEYSPAN_PORT_NOT_INIT) {
1692 			ASSERT(kp->kp_state == KEYSPAN_PORT_CLOSED);
1693 
1694 			mutex_destroy(&kp->kp_mutex);
1695 			cv_destroy(&kp->kp_tx_cv);
1696 			usb_free_log_hdl(kp->kp_lh);
1697 		}
1698 	}
1699 	kmem_free(ksp->ks_ports,
1700 	    ksp->ks_dev_spec.port_cnt * sizeof (keyspan_port_t));
1701 }
1702 
1703 static void
1704 keyspan_init_port_params(keyspan_state_t *ksp)
1705 {
1706 	int		i;
1707 	size_t		sz;
1708 	uint_t		read_len;
1709 	uint_t		write_len;
1710 
1711 	/* the max data len of every bulk in req. */
1712 	if (usb_pipe_get_max_bulk_transfer_size(ksp->ks_dip, &sz) ==
1713 	    USB_SUCCESS) {
1714 		if (ksp->ks_dev_spec.id_product == KEYSPAN_USA49WG_PID) {
1715 			read_len = min(sz, KEYSPAN_BULKIN_MAX_LEN_49WG);
1716 		} else {
1717 			read_len = min(sz, KEYSPAN_BULKIN_MAX_LEN);
1718 		}
1719 	} else {
1720 		if (ksp->ks_dev_spec.id_product == KEYSPAN_USA49WG_PID) {
1721 			read_len = KEYSPAN_BULKIN_MAX_LEN_49WG;
1722 		} else {
1723 			read_len = KEYSPAN_BULKIN_MAX_LEN;
1724 		}
1725 	}
1726 
1727 	for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) {
1728 		ksp->ks_ports[i].kp_read_len = read_len;
1729 		/* the max data len of every bulk out req. */
1730 		switch (ksp->ks_dev_spec.id_product) {
1731 		case KEYSPAN_USA19HS_PID:
1732 			ksp->ks_ports[i].kp_write_len =
1733 			    KEYSPAN_BULKOUT_MAX_LEN_19HS;
1734 
1735 			break;
1736 		case KEYSPAN_USA49WLC_PID:
1737 			ksp->ks_ports[i].kp_write_len =
1738 			    KEYSPAN_BULKOUT_MAX_LEN_49WLC;
1739 
1740 			break;
1741 		case KEYSPAN_USA49WG_PID:
1742 			/*
1743 			 * USA49WG port0 uses intr out pipe send data while
1744 			 * other ports use bulk out pipes, so port0's max
1745 			 * packet length for "bulk out" is different from other
1746 			 * ports' while the same as USA49WLC.
1747 			 */
1748 			write_len = ((i == 0) ? KEYSPAN_BULKOUT_MAX_LEN_49WLC :
1749 			    KEYSPAN_BULKOUT_MAX_LEN_49WG);
1750 			ksp->ks_ports[i].kp_write_len = write_len;
1751 
1752 			break;
1753 		default:
1754 			USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
1755 			    "keyspan_init_port_params:"
1756 			    "the device's product id can't be recognized");
1757 
1758 			return;
1759 		}
1760 	}
1761 }
1762 
1763 
1764 /*
1765  * free descriptor tree
1766  */
1767 static void
1768 keyspan_free_descr_tree(keyspan_state_t *ksp)
1769 {
1770 	usb_free_descr_tree(ksp->ks_dip, ksp->ks_dev_data);
1771 
1772 }
1773 
1774 
1775 /*
1776  * register/unregister USB event callbacks
1777  */
1778 static int
1779 keyspan_register_events(keyspan_state_t *ksp)
1780 {
1781 	return (usb_register_event_cbs(ksp->ks_dip, ksp->ks_usb_events, 0));
1782 }
1783 
1784 
1785 static void
1786 keyspan_unregister_events(keyspan_state_t *ksp)
1787 {
1788 	usb_unregister_event_cbs(ksp->ks_dip, ksp->ks_usb_events);
1789 }
1790 
1791 
1792 static void
1793 keyspan_set_dev_state_online(keyspan_state_t *ksp)
1794 {
1795 	ksp->ks_dev_state = USB_DEV_ONLINE;
1796 }
1797 
1798 /*
1799  * send command to the port and save the params after its completion for
1800  * USA19HS and USA49WLC
1801  */
1802 int
1803 keyspan_send_cmd_usa49(keyspan_port_t *kp)
1804 {
1805 	keyspan_state_t	*ksp = kp->kp_ksp;
1806 	mblk_t		*mp;
1807 	int		rval = USB_SUCCESS;
1808 	int	size;
1809 	usb_bulk_req_t	*br;
1810 
1811 	ASSERT(!mutex_owned(&kp->kp_mutex));
1812 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_send_cmd_usa49");
1813 
1814 	switch (ksp->ks_dev_spec.id_product) {
1815 	case KEYSPAN_USA19HS_PID:
1816 		size = sizeof (keyspan_usa19hs_port_ctrl_msg_t);
1817 
1818 		break;
1819 
1820 
1821 	case KEYSPAN_USA49WLC_PID:
1822 		size = sizeof (keyspan_usa49_port_ctrl_msg_t);
1823 
1824 		break;
1825 
1826 	default:
1827 		USB_DPRINTF_L2(DPRINT_CTLOP, ksp->ks_lh,
1828 		    "keyspan_send_cmd_usa49:"
1829 		    "the device's product id can't be recognized");
1830 		return (USB_FAILURE);
1831 	}
1832 
1833 	if ((mp = allocb(size, BPRI_LO)) == NULL) {
1834 
1835 		return (USB_FAILURE);
1836 	}
1837 	bcopy(&kp->kp_ctrl_msg, mp->b_rptr, size);
1838 
1839 	br = usb_alloc_bulk_req(ksp->ks_dip, 0, USB_FLAGS_SLEEP);
1840 	br->bulk_len = size;
1841 	br->bulk_data = mp;
1842 	br->bulk_timeout = KEYSPAN_BULK_TIMEOUT;
1843 	br->bulk_client_private = (void *)kp;
1844 	br->bulk_attributes = USB_ATTRS_AUTOCLEARING;
1845 
1846 	rval = usb_pipe_bulk_xfer(ksp->ks_ctrlout_pipe.pipe_handle, br,
1847 	    USB_FLAGS_SLEEP);
1848 	if (rval == USB_SUCCESS) {
1849 		mutex_enter(&kp->kp_mutex);
1850 		keyspan_save_port_params(kp);
1851 		mutex_exit(&kp->kp_mutex);
1852 	} else {
1853 		USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh, "keyspan_send_cmd_usa49"
1854 		    ": failure, rval=%d", rval);
1855 	}
1856 
1857 	usb_free_bulk_req(br);
1858 
1859 	return (rval);
1860 }
1861 
1862 /*
1863  * send command to the port and save the params after its completion for
1864  * USA_49WG only
1865  */
1866 int
1867 keyspan_send_cmd_usa49wg(keyspan_port_t *kp)
1868 {
1869 	keyspan_state_t	*ksp = kp->kp_ksp;
1870 	mblk_t		*mp;
1871 	int		rval = USB_SUCCESS;
1872 	int		size = sizeof (keyspan_usa49_port_ctrl_msg_t);
1873 	usb_cb_flags_t	cb_flags;
1874 	usb_cr_t	cr;
1875 	usb_ctrl_setup_t setup;
1876 
1877 	ASSERT(!mutex_owned(&kp->kp_mutex));
1878 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh, "keyspan_send_cmd_usa49wg");
1879 
1880 	if ((mp = allocb(size, BPRI_LO)) == NULL) {
1881 
1882 		return (USB_FAILURE);
1883 	}
1884 	bcopy(&kp->kp_ctrl_msg, mp->b_rptr, size);
1885 
1886 	setup.bmRequestType = USB_DEV_REQ_TYPE_VENDOR;
1887 	setup.bRequest = KEYSPAN_SET_CONTROL_REQUEST;
1888 	setup.wValue = 0;
1889 	setup.wIndex = 0;
1890 	setup.wLength = size;
1891 	setup.attrs = 0;
1892 
1893 	rval = usb_pipe_ctrl_xfer_wait(ksp->ks_def_pipe.pipe_handle, &setup,
1894 	    &mp, &cr, &cb_flags, 0);
1895 
1896 	if (rval == USB_SUCCESS) {
1897 		mutex_enter(&kp->kp_mutex);
1898 		keyspan_save_port_params(kp);
1899 		mutex_exit(&kp->kp_mutex);
1900 	} else {
1901 		USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh,
1902 		    "keyspan_send_cmd_usa49wg: failure, rval=%d", rval);
1903 	}
1904 	if (mp) {
1905 		freemsg(mp);
1906 	}
1907 
1908 	return (rval);
1909 }
1910 
1911 /*
1912  * send command to the port and save the params after its completion
1913  */
1914 int
1915 keyspan_send_cmd(keyspan_port_t *kp)
1916 {
1917 	keyspan_state_t	*ksp = kp->kp_ksp;
1918 	int		rval = USB_FAILURE;
1919 
1920 	switch (ksp->ks_dev_spec.id_product) {
1921 	case KEYSPAN_USA19HS_PID:
1922 	case KEYSPAN_USA49WLC_PID:
1923 		rval = keyspan_send_cmd_usa49(kp);
1924 
1925 		break;
1926 	case KEYSPAN_USA49WG_PID:
1927 		rval = keyspan_send_cmd_usa49wg(kp);
1928 
1929 		break;
1930 	default:
1931 		USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh,
1932 		    "keyspan_send_cmd: "
1933 		    "the device's product id can't be recognized");
1934 	}
1935 
1936 	if (rval != USB_SUCCESS) {
1937 			USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh,
1938 			    "keyspan_send_cmd() FAILED");
1939 
1940 			return (rval);
1941 	}
1942 
1943 	return (USB_SUCCESS);
1944 
1945 }
1946 
1947 /*
1948  * hotplug
1949  * -------
1950  *
1951  * restore device state after CPR resume or reconnect
1952  */
1953 static int
1954 keyspan_restore_device_state(keyspan_state_t *ksp)
1955 {
1956 	int	state;
1957 
1958 	mutex_enter(&ksp->ks_mutex);
1959 	state = ksp->ks_dev_state;
1960 	mutex_exit(&ksp->ks_mutex);
1961 
1962 	if ((state != USB_DEV_DISCONNECTED) && (state != USB_DEV_SUSPENDED)) {
1963 
1964 		return (state);
1965 	}
1966 
1967 	if (usb_check_same_device(ksp->ks_dip, ksp->ks_lh, USB_LOG_L0,
1968 	    DPRINT_MASK_ALL, USB_CHK_ALL, NULL) != USB_SUCCESS) {
1969 		mutex_enter(&ksp->ks_mutex);
1970 		state = ksp->ks_dev_state = USB_DEV_DISCONNECTED;
1971 		mutex_exit(&ksp->ks_mutex);
1972 
1973 		return (state);
1974 	}
1975 
1976 	if (state == USB_DEV_DISCONNECTED) {
1977 		USB_DPRINTF_L0(DPRINT_HOTPLUG, ksp->ks_lh,
1978 		    "device has been reconnected but data may have been lost");
1979 	}
1980 
1981 	if (keyspan_reconnect_pipes(ksp) != USB_SUCCESS) {
1982 
1983 		return (state);
1984 	}
1985 
1986 	/*
1987 	 * init device state
1988 	 */
1989 	mutex_enter(&ksp->ks_mutex);
1990 	state = ksp->ks_dev_state = USB_DEV_ONLINE;
1991 	ksp->ks_reconnect_flag = 1;
1992 	mutex_exit(&ksp->ks_mutex);
1993 
1994 	/*
1995 	 * now restore each open port
1996 	 */
1997 	(void) keyspan_restore_ports_state(ksp);
1998 
1999 	return (state);
2000 }
2001 
2002 /*
2003  * restore ports state after CPR resume or reconnect
2004  */
2005 static int
2006 keyspan_restore_ports_state(keyspan_state_t *ksp)
2007 {
2008 	keyspan_port_t	*kp;
2009 	int		rval = USB_SUCCESS;
2010 	int		err;
2011 	int		i;
2012 
2013 	for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) {
2014 		kp = &ksp->ks_ports[i];
2015 		/*
2016 		 * only care about open ports
2017 		 */
2018 		mutex_enter(&kp->kp_mutex);
2019 		if (kp->kp_state != KEYSPAN_PORT_OPEN) {
2020 			mutex_exit(&kp->kp_mutex);
2021 			continue;
2022 		}
2023 		mutex_exit(&kp->kp_mutex);
2024 
2025 		sema_p(&ksp->ks_pipes_sema);
2026 		/* open hardware serial port */
2027 		err = keyspan_open_hw_port(kp, B_FALSE);
2028 		sema_v(&ksp->ks_pipes_sema);
2029 		if (err != USB_SUCCESS) {
2030 			USB_DPRINTF_L2(DPRINT_HOTPLUG, kp->kp_lh,
2031 			    "keyspan_restore_ports_state: failed");
2032 			rval = err;
2033 		}
2034 	}
2035 
2036 	return (rval);
2037 }
2038 
2039 
2040 /*
2041  * power management
2042  * ----------------
2043  *
2044  *
2045  * create PM components
2046  */
2047 static int
2048 keyspan_create_pm_components(keyspan_state_t *ksp)
2049 {
2050 	dev_info_t	*dip = ksp->ks_dip;
2051 	keyspan_pm_t	*pm;
2052 	uint_t		pwr_states;
2053 
2054 	pm = ksp->ks_pm = kmem_zalloc(sizeof (keyspan_pm_t), KM_SLEEP);
2055 	pm->pm_cur_power = USB_DEV_OS_FULL_PWR;
2056 
2057 	if (usb_create_pm_components(dip, &pwr_states) != USB_SUCCESS) {
2058 		USB_DPRINTF_L2(DPRINT_PM, ksp->ks_lh,
2059 		    "keyspan_create_pm_components: failed");
2060 
2061 		return (USB_SUCCESS);
2062 	}
2063 
2064 	pm->pm_wakeup_enabled = (usb_handle_remote_wakeup(dip,
2065 	    USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS);
2066 	pm->pm_pwr_states = (uint8_t)pwr_states;
2067 
2068 	(void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR);
2069 
2070 	return (USB_SUCCESS);
2071 }
2072 
2073 
2074 /*
2075  * destroy PM components
2076  */
2077 static void
2078 keyspan_destroy_pm_components(keyspan_state_t *ksp)
2079 {
2080 	keyspan_pm_t	*pm = ksp->ks_pm;
2081 	dev_info_t	*dip = ksp->ks_dip;
2082 	int		rval;
2083 
2084 	if (ksp->ks_dev_state != USB_DEV_DISCONNECTED) {
2085 		if (pm->pm_wakeup_enabled) {
2086 			(void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR);
2087 
2088 			rval = usb_handle_remote_wakeup(dip,
2089 			    USB_REMOTE_WAKEUP_DISABLE);
2090 			if (rval != USB_SUCCESS) {
2091 				USB_DPRINTF_L2(DPRINT_PM, ksp->ks_lh,
2092 				    "keyspan_destroy_pm_components: disable "
2093 				    "remote wakeup failed, rval=%d", rval);
2094 			}
2095 		}
2096 
2097 		(void) pm_lower_power(dip, 0, USB_DEV_OS_PWR_OFF);
2098 	}
2099 	kmem_free(pm, sizeof (keyspan_pm_t));
2100 	ksp->ks_pm = NULL;
2101 }
2102 
2103 
2104 /*
2105  * mark device busy and raise power
2106  */
2107 static int
2108 keyspan_pm_set_busy(keyspan_state_t *ksp)
2109 {
2110 	keyspan_pm_t	*pm = ksp->ks_pm;
2111 	dev_info_t	*dip = ksp->ks_dip;
2112 
2113 	USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pm_set_busy");
2114 
2115 	mutex_enter(&ksp->ks_mutex);
2116 	/* if already marked busy, just increment the counter */
2117 	if (pm->pm_busy_cnt++ > 0) {
2118 		USB_DPRINTF_L3(DPRINT_PM, ksp->ks_lh, "keyspan_pm_set_busy:"
2119 		    "already busy, busy_cnt = %d", pm->pm_busy_cnt);
2120 		mutex_exit(&ksp->ks_mutex);
2121 
2122 		return (USB_SUCCESS);
2123 	}
2124 
2125 	(void) pm_busy_component(dip, 0);
2126 
2127 	if (pm->pm_cur_power == USB_DEV_OS_FULL_PWR) {
2128 		mutex_exit(&ksp->ks_mutex);
2129 
2130 		return (USB_SUCCESS);
2131 	}
2132 
2133 	/* need to raise power	*/
2134 	pm->pm_raise_power = B_TRUE;
2135 	mutex_exit(&ksp->ks_mutex);
2136 
2137 	USB_DPRINTF_L3(DPRINT_PM, ksp->ks_lh,
2138 	    "keyspan_pm_set_busy: raise power");
2139 	(void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR);
2140 
2141 	mutex_enter(&ksp->ks_mutex);
2142 	pm->pm_raise_power = B_FALSE;
2143 	mutex_exit(&ksp->ks_mutex);
2144 
2145 	return (USB_SUCCESS);
2146 }
2147 
2148 
2149 /*
2150  * mark device idle
2151  */
2152 static void
2153 keyspan_pm_set_idle(keyspan_state_t *ksp)
2154 {
2155 	keyspan_pm_t	*pm = ksp->ks_pm;
2156 	dev_info_t	*dip = ksp->ks_dip;
2157 
2158 	USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pm_set_idle");
2159 
2160 	/*
2161 	 * if more ports use the device, do not mark as yet
2162 	 */
2163 	mutex_enter(&ksp->ks_mutex);
2164 	if (--pm->pm_busy_cnt > 0) {
2165 		mutex_exit(&ksp->ks_mutex);
2166 
2167 		return;
2168 	}
2169 
2170 	USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pm_set_idle: set idle");
2171 	(void) pm_idle_component(dip, 0);
2172 
2173 	mutex_exit(&ksp->ks_mutex);
2174 }
2175 
2176 
2177 /*
2178  * Functions to handle power transition for OS levels 0 -> 3
2179  */
2180 static int
2181 keyspan_pwrlvl0(keyspan_state_t *ksp)
2182 {
2183 	int	rval;
2184 	keyspan_pipe_t *statin = &ksp->ks_statin_pipe;
2185 
2186 	USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pwrlvl0");
2187 
2188 	switch (ksp->ks_dev_state) {
2189 	case USB_DEV_ONLINE:
2190 		/* issue USB D3 command to the device */
2191 		rval = usb_set_device_pwrlvl3(ksp->ks_dip);
2192 		ASSERT(rval == USB_SUCCESS);
2193 
2194 		if (ksp->ks_dev_spec.id_product == KEYSPAN_USA49WG_PID) {
2195 			mutex_exit(&ksp->ks_mutex);
2196 			usb_pipe_stop_intr_polling(statin->pipe_handle,
2197 			    USB_FLAGS_SLEEP);
2198 			mutex_enter(&ksp->ks_mutex);
2199 
2200 			mutex_enter(&statin->pipe_mutex);
2201 			statin->pipe_state = KEYSPAN_PIPE_CLOSED;
2202 			mutex_exit(&statin->pipe_mutex);
2203 		}
2204 		ksp->ks_dev_state = USB_DEV_PWRED_DOWN;
2205 		ksp->ks_pm->pm_cur_power = USB_DEV_OS_PWR_OFF;
2206 
2207 		/* FALLTHRU */
2208 	case USB_DEV_DISCONNECTED:
2209 	case USB_DEV_SUSPENDED:
2210 		/* allow a disconnect/cpr'ed device to go to lower power */
2211 
2212 		return (USB_SUCCESS);
2213 	case USB_DEV_PWRED_DOWN:
2214 	default:
2215 		USB_DPRINTF_L2(DPRINT_PM, ksp->ks_lh,
2216 		    "keyspan_pwrlvl0: illegal device state");
2217 
2218 		return (USB_FAILURE);
2219 	}
2220 }
2221 
2222 
2223 static int
2224 keyspan_pwrlvl1(keyspan_state_t *ksp)
2225 {
2226 	USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pwrlvl1");
2227 
2228 	/* issue USB D2 command to the device */
2229 	(void) usb_set_device_pwrlvl2(ksp->ks_dip);
2230 
2231 	return (USB_FAILURE);
2232 }
2233 
2234 
2235 static int
2236 keyspan_pwrlvl2(keyspan_state_t *ksp)
2237 {
2238 	USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pwrlvl2");
2239 
2240 	/* issue USB D1 command to the device */
2241 	(void) usb_set_device_pwrlvl1(ksp->ks_dip);
2242 
2243 	return (USB_FAILURE);
2244 }
2245 
2246 
2247 static int
2248 keyspan_pwrlvl3(keyspan_state_t *ksp)
2249 {
2250 	int	rval;
2251 
2252 	USB_DPRINTF_L4(DPRINT_PM, ksp->ks_lh, "keyspan_pwrlvl3");
2253 
2254 	switch (ksp->ks_dev_state) {
2255 	case USB_DEV_PWRED_DOWN:
2256 		/* Issue USB D0 command to the device here */
2257 		rval = usb_set_device_pwrlvl0(ksp->ks_dip);
2258 		ASSERT(rval == USB_SUCCESS);
2259 
2260 		if (ksp->ks_dev_spec.id_product == KEYSPAN_USA49WG_PID) {
2261 			mutex_exit(&ksp->ks_mutex);
2262 			keyspan_pipe_start_polling(&ksp->ks_statin_pipe);
2263 			mutex_enter(&ksp->ks_mutex);
2264 		}
2265 
2266 		ksp->ks_dev_state = USB_DEV_ONLINE;
2267 		ksp->ks_pm->pm_cur_power = USB_DEV_OS_FULL_PWR;
2268 
2269 		/* FALLTHRU */
2270 	case USB_DEV_ONLINE:
2271 		/* we are already in full power */
2272 
2273 		/* FALLTHRU */
2274 	case USB_DEV_DISCONNECTED:
2275 	case USB_DEV_SUSPENDED:
2276 
2277 		return (USB_SUCCESS);
2278 	default:
2279 		USB_DPRINTF_L2(DPRINT_PM, ksp->ks_lh,
2280 		    "keyspan_pwrlvl3: illegal device state");
2281 
2282 		return (USB_FAILURE);
2283 	}
2284 }
2285 
2286 
2287 /*
2288  * pipe operations
2289  * ---------------
2290  *
2291  * XXX keyspan seem to malfunction after the pipes are closed
2292  * and reopened again (does not respond to OPEN_PORT command).
2293  * so we open them once in attach
2294  */
2295 static int
2296 keyspan_attach_pipes(keyspan_state_t *ksp)
2297 {
2298 	return (keyspan_open_dev_pipes(ksp));
2299 }
2300 
2301 void
2302 keyspan_detach_pipes(keyspan_state_t *ksp)
2303 {
2304 
2305 	/*
2306 	 * Blow away status bulk in requests or
2307 	 * pipe close will wait until timeout.
2308 	 */
2309 	if (ksp->ks_statin_pipe.pipe_handle) {
2310 		usb_pipe_stop_intr_polling(ksp->ks_statin_pipe.pipe_handle,
2311 		    USB_FLAGS_SLEEP);
2312 	}
2313 
2314 	/* Close the globle pipes */
2315 	keyspan_close_dev_pipes(ksp);
2316 }
2317 
2318 
2319 /*
2320  * during device disconnect/suspend, close pipes if they are open.
2321  */
2322 static void
2323 keyspan_disconnect_pipes(keyspan_state_t *ksp)
2324 {
2325 	sema_p(&ksp->ks_pipes_sema);
2326 	keyspan_close_pipes(ksp);
2327 	sema_v(&ksp->ks_pipes_sema);
2328 }
2329 
2330 
2331 /*
2332  * during device reconnect/resume, reopen pipes if they were open.
2333  */
2334 static int
2335 keyspan_reconnect_pipes(keyspan_state_t *ksp)
2336 {
2337 	int	rval = USB_SUCCESS;
2338 
2339 	sema_p(&ksp->ks_pipes_sema);
2340 	rval = keyspan_reopen_pipes(ksp);
2341 	sema_v(&ksp->ks_pipes_sema);
2342 
2343 	return (rval);
2344 }
2345 
2346 /*
2347  * data transfer routines
2348  * ----------------------
2349  *
2350  *
2351  * start data transmit
2352  */
2353 void
2354 keyspan_tx_start(keyspan_port_t *kp, int *xferd)
2355 {
2356 	keyspan_state_t	*ksp = kp->kp_ksp;
2357 	int		len;		/* # of bytes we can transmit */
2358 	mblk_t		*data;		/* data to be transmitted */
2359 	int		data_len = 0;	/* # of bytes in 'data' */
2360 	int		tran_len;
2361 	int		rval;
2362 	int		status_len = 0;
2363 
2364 	ASSERT(!mutex_owned(&ksp->ks_mutex));
2365 	ASSERT(mutex_owned(&kp->kp_mutex));
2366 	ASSERT(kp->kp_state != KEYSPAN_PORT_CLOSED);
2367 
2368 	USB_DPRINTF_L4(DPRINT_OUT_PIPE, kp->kp_lh, "keyspan_tx_start");
2369 
2370 	if (xferd) {
2371 		*xferd = 0;
2372 	}
2373 	if ((kp->kp_flags & KEYSPAN_PORT_TX_STOPPED) ||
2374 	    (kp->kp_tx_mp == NULL)) {
2375 
2376 		return;
2377 	}
2378 
2379 	len = min(msgdsize(kp->kp_tx_mp), kp->kp_write_len);
2380 	USB_DPRINTF_L4(DPRINT_OUT_PIPE, kp->kp_lh, "keyspan_tx_start:"
2381 	    "len = %d, tx_mp_len = %d", len, (int)msgdsize(kp->kp_tx_mp));
2382 
2383 	mutex_exit(&kp->kp_mutex);
2384 
2385 	/*
2386 	 * Some keyspan adapters, such as usa49wlc,
2387 	 * need use the first byte as flag.
2388 	 */
2389 	switch (ksp->ks_dev_spec.id_product) {
2390 	case KEYSPAN_USA19HS_PID:
2391 
2392 		if ((data = allocb(len, BPRI_LO)) == NULL) {
2393 			mutex_enter(&kp->kp_mutex);
2394 
2395 			return;
2396 		}
2397 		mutex_enter(&kp->kp_mutex);
2398 
2399 		/* copy at most 'len' bytes from mblk chain for transmission */
2400 		data_len = keyspan_tx_copy_data(kp, data, len);
2401 		if (data_len <= 0) {
2402 			USB_DPRINTF_L3(DPRINT_OUT_PIPE, kp->kp_lh,
2403 			    "keyspan_tx_start:keyspan_tx_copy_data copied"
2404 			    " zero bytes");
2405 		}
2406 
2407 		break;
2408 
2409 	case KEYSPAN_USA49WLC_PID:
2410 	case KEYSPAN_USA49WG_PID:
2411 		status_len = len / 64 + 1;
2412 		if ((data = allocb(len + status_len, BPRI_LO)) == NULL) {
2413 			mutex_enter(&kp->kp_mutex);
2414 
2415 			return;
2416 		}
2417 		mutex_enter(&kp->kp_mutex);
2418 		/*
2419 		 * the data format is [status byte][63 data bytes][...][status]
2420 		 * byte][up to 63 bytes] according to keyspan spec
2421 		 */
2422 		while (data_len < len) {
2423 			/* Add status byte per 63 data bytes */
2424 			*(data->b_wptr++) = 0;
2425 			/* copy at most 63 bytes from mblk chain for trans */
2426 			tran_len = keyspan_tx_copy_data(kp, data, 63);
2427 			if (tran_len <= 0) {
2428 				USB_DPRINTF_L3(DPRINT_OUT_PIPE, kp->kp_lh,
2429 				    "keyspan_tx_start:keyspan_tx_copy_data"
2430 				    " copied zero bytes");
2431 
2432 				break;
2433 			}
2434 			data_len += tran_len;
2435 		}
2436 
2437 		break;
2438 	default:
2439 
2440 		mutex_enter(&kp->kp_mutex);
2441 		USB_DPRINTF_L2(DPRINT_OUT_PIPE, ksp->ks_lh, "keyspan_tx_start:"
2442 		    "the device's product id can't be recognized");
2443 
2444 		return;
2445 	}
2446 
2447 	mutex_exit(&kp->kp_mutex);
2448 
2449 	/*
2450 	 * For USA-49WG, the port0 uses intr out pipe as data out pipe, while
2451 	 * other ports use bulk out pipe.
2452 	 */
2453 
2454 	if ((kp->kp_port_num == 0) &&
2455 	    (ksp->ks_dev_spec.id_product == KEYSPAN_USA49WG_PID)) {
2456 		rval = keyspan_send_data_port0(&kp->kp_dataout_pipe, &data, kp);
2457 	} else {
2458 		rval = keyspan_send_data(&kp->kp_dataout_pipe, &data, kp);
2459 	}
2460 	mutex_enter(&kp->kp_mutex);
2461 
2462 	/*
2463 	 * if send failed, put data back
2464 	 */
2465 	if (rval != USB_SUCCESS) {
2466 		ASSERT(data);
2467 		keyspan_put_head(&kp->kp_tx_mp, data, kp);
2468 	} else if (xferd) {
2469 		*xferd = data_len;
2470 	}
2471 
2472 	USB_DPRINTF_L4(DPRINT_OUT_PIPE, kp->kp_lh, "keyspan_tx_start[%d]: over"
2473 	    "(%d) rval=%d", kp->kp_port_num, data_len, rval);
2474 
2475 }
2476 
2477 
2478 /*
2479  * copy no more than 'len' bytes from mblk chain to transmit mblk 'data'.
2480  * return number of bytes copied
2481  */
2482 int
2483 keyspan_tx_copy_data(keyspan_port_t *kp, mblk_t *data, int len)
2484 {
2485 	mblk_t		*mp;	/* current msgblk */
2486 	int		copylen; /* # of bytes to copy from 'mp' to 'data' */
2487 	int		data_len = 0;
2488 
2489 	ASSERT(mutex_owned(&kp->kp_mutex));
2490 
2491 	if (msgdsize(kp->kp_tx_mp) == 0) {
2492 		data->b_wptr = data->b_rptr;
2493 		freeb(kp->kp_tx_mp);
2494 		kp->kp_tx_mp = NULL;
2495 
2496 		return (data_len);
2497 	}
2498 
2499 	while ((data_len < len) && kp->kp_tx_mp) {
2500 		mp = kp->kp_tx_mp;
2501 		copylen = min(MBLKL(mp), len - data_len);
2502 		bcopy(mp->b_rptr, data->b_wptr, copylen);
2503 
2504 		mp->b_rptr += copylen;
2505 		data->b_wptr += copylen;
2506 		data_len += copylen;
2507 
2508 		if (MBLKL(mp) <= 0) {
2509 			kp->kp_tx_mp = unlinkb(mp);
2510 			freeb(mp);
2511 		} else {
2512 			ASSERT(data_len == len);
2513 		}
2514 	}
2515 	USB_DPRINTF_L3(DPRINT_OUT_DATA, kp->kp_lh, "keyspan_tx_copy_data:"
2516 	    "copied data_len = %d", data_len);
2517 
2518 	return (data_len);
2519 }
2520 
2521 
2522 /*
2523  * wait until local tx buffer drains.
2524  * 'timeout' is in seconds, zero means wait forever
2525  */
2526 static int
2527 keyspan_wait_tx_drain(keyspan_port_t *kp, int timeout)
2528 {
2529 	clock_t	until;
2530 	int	over = 0;
2531 
2532 	USB_DPRINTF_L4(DPRINT_OUT_DATA, kp->kp_lh, "keyspan_wait_tx_drain:"
2533 	    "timeout = %d", timeout);
2534 	until = ddi_get_lbolt() + drv_usectohz(1000000 * timeout);
2535 
2536 	while (kp->kp_tx_mp && !over) {
2537 		if (timeout > 0) {
2538 			over = (cv_timedwait_sig(&kp->kp_tx_cv,
2539 			    &kp->kp_mutex, until) <= 0);
2540 		} else {
2541 			over = (cv_wait_sig(&kp->kp_tx_cv, &kp->kp_mutex) == 0);
2542 		}
2543 	}
2544 
2545 	return ((kp->kp_tx_mp == NULL) ? USB_SUCCESS : USB_FAILURE);
2546 }
2547 
2548 /*
2549  * returns 0 if device is not online, != 0 otherwise
2550  */
2551 int
2552 keyspan_dev_is_online(keyspan_state_t *ksp)
2553 {
2554 	int	rval;
2555 
2556 	mutex_enter(&ksp->ks_mutex);
2557 	rval = (ksp->ks_dev_state == USB_DEV_ONLINE);
2558 	mutex_exit(&ksp->ks_mutex);
2559 
2560 	return (rval);
2561 }
2562 
2563 /*
2564  * link a message block to tail of message
2565  * account for the case when message is null
2566  */
2567 void
2568 keyspan_put_tail(mblk_t **mpp, mblk_t *bp)
2569 {
2570 	if (*mpp) {
2571 		linkb(*mpp, bp);
2572 	} else {
2573 		*mpp = bp;
2574 	}
2575 }
2576 
2577 /*
2578  * put a message block at the head of the message
2579  * account for the case when message is null
2580  */
2581 void
2582 keyspan_put_head(mblk_t **mpp, mblk_t *bp, keyspan_port_t *kp)
2583 {
2584 	switch (kp->kp_ksp->ks_dev_spec.id_product) {
2585 	case KEYSPAN_USA19HS_PID:
2586 		if (*mpp) {
2587 			linkb(bp, *mpp);
2588 		}
2589 		*mpp = bp;
2590 
2591 		break;
2592 
2593 
2594 	case KEYSPAN_USA49WLC_PID:
2595 	case KEYSPAN_USA49WG_PID:
2596 
2597 		/* get rid of the first byte of the msg data which is a flag */
2598 		if (*mpp) {
2599 			linkb(bp, *mpp);
2600 		}
2601 		bp->b_rptr = bp->b_datap->db_base + 1;
2602 		*mpp = bp;
2603 
2604 		break;
2605 
2606 	default:
2607 		USB_DPRINTF_L2(DPRINT_OUT_DATA, kp->kp_lh, "keyspan_put_head:"
2608 		    "the device's product id can't be recognized");
2609 
2610 		return;
2611 	}
2612 
2613 }
2614 
2615 /*
2616  * Set the port parameters to default values
2617  */
2618 static void
2619 keyspan_default_port_params(keyspan_port_t *kp)
2620 {
2621 	keyspan_state_t	*ksp = kp->kp_ksp;
2622 
2623 	ASSERT(mutex_owned(&kp->kp_mutex));
2624 
2625 	switch (ksp->ks_dev_spec.id_product) {
2626 	case KEYSPAN_USA19HS_PID:
2627 		keyspan_default_port_params_usa19hs(kp);
2628 
2629 		break;
2630 
2631 
2632 	case KEYSPAN_USA49WLC_PID:
2633 	case KEYSPAN_USA49WG_PID:
2634 		keyspan_default_port_params_usa49(kp);
2635 
2636 		break;
2637 
2638 	default:
2639 		USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
2640 		    "keyspan_default_port_params:"
2641 		    "the device's product id can't be recognized");
2642 	}
2643 
2644 	USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2645 	    "keyspan_default_port_params: setted.");
2646 }
2647 
2648 /*
2649  * Build the command message according to the params from usbser.
2650  * The message will then be sent to deivce by keyspan_send_cmd.
2651  */
2652 static void
2653 keyspan_build_cmd_msg(keyspan_port_t *kp, ds_port_params_t *tp)
2654 {
2655 	keyspan_state_t	*ksp = kp->kp_ksp;
2656 
2657 	switch (ksp->ks_dev_spec.id_product) {
2658 	case KEYSPAN_USA19HS_PID:
2659 		keyspan_build_cmd_msg_usa19hs(kp, tp);
2660 
2661 		break;
2662 
2663 
2664 	case KEYSPAN_USA49WLC_PID:
2665 	case KEYSPAN_USA49WG_PID:
2666 		keyspan_build_cmd_msg_usa49(kp, tp);
2667 
2668 		break;
2669 
2670 	default:
2671 		USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
2672 		    "keyspan_build_cmd_msg:"
2673 		    "the device's product id can't be recognized");
2674 	}
2675 }
2676 
2677 /* save the port params after send cmd successfully */
2678 static void
2679 keyspan_save_port_params(keyspan_port_t	*kp)
2680 {
2681 	keyspan_state_t	*ksp = kp->kp_ksp;
2682 
2683 	ASSERT(mutex_owned(&kp->kp_mutex));
2684 
2685 	switch (ksp->ks_dev_spec.id_product) {
2686 	case KEYSPAN_USA19HS_PID:
2687 		keyspan_save_port_params_usa19hs(kp);
2688 
2689 		break;
2690 
2691 
2692 	case KEYSPAN_USA49WLC_PID:
2693 	case KEYSPAN_USA49WG_PID:
2694 		keyspan_save_port_params_usa49(kp);
2695 
2696 		break;
2697 
2698 	default:
2699 		USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
2700 		    "keyspan_save_port_params:"
2701 		    "the device's product id can't be recognized");
2702 	}
2703 
2704 	USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2705 	    "keyspan_save_port_params: baud = %x, lcr = %x,"
2706 	    "status_flag = %x", kp->kp_baud, kp->kp_lcr, kp->kp_status_flag);
2707 
2708 }
2709 
2710 /* save the port params after send cmd successfully */
2711 static void
2712 keyspan_save_port_params_usa19hs(keyspan_port_t	*kp)
2713 {
2714 	keyspan_usa19hs_port_ctrl_msg_t	*ctrl_msg = &(kp->kp_ctrl_msg.usa19hs);
2715 
2716 	ASSERT(mutex_owned(&kp->kp_mutex));
2717 
2718 	if (ctrl_msg->setClocking) {
2719 		kp->kp_baud = ctrl_msg->baudHi;
2720 		kp->kp_baud = (kp->kp_baud << 8);
2721 		kp->kp_baud |= ctrl_msg->baudLo;
2722 	}
2723 	if (ctrl_msg->setLcr) {
2724 		kp->kp_lcr = ctrl_msg->lcr;
2725 	}
2726 	if (ctrl_msg->setRts) {
2727 		if (ctrl_msg->rts) {
2728 			kp->kp_status_flag |= KEYSPAN_PORT_RTS;
2729 		} else {
2730 			kp->kp_status_flag &= ~KEYSPAN_PORT_RTS;
2731 		}
2732 	}
2733 	if (ctrl_msg->setDtr) {
2734 		if (ctrl_msg->dtr) {
2735 			kp->kp_status_flag |= KEYSPAN_PORT_DTR;
2736 		} else {
2737 			kp->kp_status_flag &= ~KEYSPAN_PORT_DTR;
2738 		}
2739 	}
2740 
2741 	if (ctrl_msg->portEnabled) {
2742 		kp->kp_status_flag |= KEYSPAN_PORT_ENABLE;
2743 	} else {
2744 		kp->kp_status_flag &= ~KEYSPAN_PORT_ENABLE;
2745 	}
2746 
2747 	USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2748 	    "keyspan_save_port_params: baud = %x, lcr = %x,"
2749 	    "status_flag = %x", kp->kp_baud, kp->kp_lcr, kp->kp_status_flag);
2750 
2751 }
2752 
2753 /*
2754  * Set the port parameters to default values
2755  */
2756 static void
2757 keyspan_default_port_params_usa19hs(keyspan_port_t *kp)
2758 {
2759 	keyspan_usa19hs_port_ctrl_msg_t	*ctrl_msg = &(kp->kp_ctrl_msg.usa19hs);
2760 	ASSERT(mutex_owned(&kp->kp_mutex));
2761 
2762 	keyspan_build_cmd_msg(kp, NULL);
2763 
2764 	ctrl_msg->setRts = 0x01;
2765 	ctrl_msg->rts = 0x1;
2766 	ctrl_msg->setDtr = 0x01;
2767 	ctrl_msg->dtr = 0x1;
2768 
2769 	ctrl_msg->setClocking = 1;
2770 	ctrl_msg->setRxMode = 1;
2771 	ctrl_msg->setTxMode = 1;
2772 
2773 	/* set baud rate to 9600 */
2774 	ctrl_msg->baudLo = keyspan_speedtab_usa19hs[13] & 0xff;
2775 	ctrl_msg->baudHi = (keyspan_speedtab_usa19hs[13] >> 8) & 0xff;
2776 	ctrl_msg->rxMode = RXMODE_BYHAND;
2777 	ctrl_msg->txMode = TXMODE_BYHAND;
2778 
2779 	ctrl_msg->lcr = 0x3;
2780 	ctrl_msg->setLcr = 0x1;
2781 
2782 	ctrl_msg->xonChar = CSTART;
2783 	ctrl_msg->xoffChar = CSTOP;
2784 	ctrl_msg->setTxFlowControl = 1;
2785 	ctrl_msg->txFlowControl = TXFLOW_CTS;
2786 	ctrl_msg->setRxFlowControl = 1;
2787 	ctrl_msg->rxFlowControl = RXFLOW_RTS;
2788 	ctrl_msg->rxFlush = 0;
2789 
2790 }
2791 
2792 /*
2793  * Build the command message according to the params from usbser.
2794  * The message will then be sent to deivce by keyspan_send_cmd.
2795  */
2796 static void
2797 keyspan_build_cmd_msg_usa19hs(keyspan_port_t *kp, ds_port_params_t *tp)
2798 {
2799 	int		cnt, i;
2800 	uint_t		ui;
2801 	ds_port_param_entry_t *pe;
2802 	keyspan_usa19hs_port_ctrl_msg_t	*ctrl_msg = &(kp->kp_ctrl_msg.usa19hs);
2803 
2804 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh,
2805 	    "keyspan_build_cmd_msg_usa19hs: tp = %p", (void *)tp);
2806 
2807 	ASSERT(mutex_owned(&kp->kp_mutex));
2808 	ASSERT(kp->kp_state == KEYSPAN_PORT_OPEN ||
2809 	    kp->kp_state == KEYSPAN_PORT_OPENING);
2810 
2811 	/* bzero all elements */
2812 	bzero(ctrl_msg, sizeof (keyspan_usa19hs_port_ctrl_msg_t));
2813 
2814 	/* it is usaually 16, according to Keyspan spec */
2815 	ctrl_msg->rxForwardingLength = 16;
2816 	/* from 1ms to 31ms, according to Keyspan spec. */
2817 	ctrl_msg->rxForwardingTimeout = 16;
2818 
2819 	ctrl_msg->portEnabled = 1;
2820 	ctrl_msg->returnStatus = 1;
2821 
2822 	if (tp == NULL) {
2823 
2824 		return;
2825 	}
2826 
2827 	cnt = tp->tp_cnt;
2828 	pe = tp->tp_entries;
2829 
2830 	/* translate tp parameters into cmd_msg elements */
2831 	for (i = 0; i < cnt; i++, pe++) {
2832 		switch (pe->param) {
2833 		case DS_PARAM_BAUD:
2834 			ui = pe->val.ui;
2835 
2836 			/*
2837 			 * if we don't support this speed,
2838 			 * then return failure.
2839 			 */
2840 			if ((ui >= NELEM(keyspan_speedtab_usa19hs)) ||
2841 			    ((ui > 0) && (keyspan_speedtab_usa19hs[ui] == 0))) {
2842 
2843 				USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2844 				    "keyspan_build_cmd_msg_usa19hs:"
2845 				    " bad baud %d", ui);
2846 
2847 				break;
2848 			}
2849 
2850 			/* if the same as the old rate, need not set the rate */
2851 			if (kp->kp_baud == keyspan_speedtab_usa19hs[ui]) {
2852 
2853 				USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2854 				    "keyspan_build_cmd_msg_usa19hs:"
2855 				    " same as old baud setting, baud = %d",
2856 				    keyspan_speed2baud[ui]);
2857 
2858 				break;
2859 			}
2860 			ctrl_msg->setClocking = 1; /* enable the setting */
2861 			ctrl_msg->setRxMode = 1;
2862 			ctrl_msg->setTxMode = 1;
2863 
2864 			ctrl_msg->baudLo = keyspan_speedtab_usa19hs[ui] & 0xff;
2865 			ctrl_msg->baudHi = (keyspan_speedtab_usa19hs[ui] >> 8)
2866 			    & 0xff;
2867 
2868 			ctrl_msg->rxMode = RXMODE_BYHAND;
2869 			ctrl_msg->txMode = TXMODE_BYHAND;
2870 
2871 			USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2872 			    "keyspan_build_cmd_msg_usa19hs: baud=%d",
2873 			    keyspan_speed2baud[ui]);
2874 
2875 			break;
2876 		case DS_PARAM_PARITY:
2877 			if (pe->val.ui & PARENB) {
2878 
2879 				/*
2880 				 * Since USA_PARITY_NONE == 0, it's not
2881 				 * necessary to or it in here.
2882 				 */
2883 				if (pe->val.ui & PARODD) {
2884 					ctrl_msg->lcr |= USA_PARITY_ODD;
2885 				} else {
2886 					ctrl_msg->lcr |= USA_PARITY_EVEN;
2887 				}
2888 			}
2889 			USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2890 			    "keyspan_build_cmd_msg_usa19hs: parity=%x,lcr = %x",
2891 			    pe->val.ui, ctrl_msg->lcr);
2892 
2893 			break;
2894 		case DS_PARAM_STOPB:
2895 			if (pe->val.ui & CSTOPB) {
2896 				ctrl_msg->lcr |= STOPBITS_678_2;
2897 			} else {
2898 
2899 				/*
2900 				 * STOPBITS_5678_1 equals zero,
2901 				 * so it's not necessary to or it in.
2902 				 */
2903 				USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2904 				    "keyspan_build_cmd_msg_usa19hs:"
2905 				    " STOPBITS_5678_1");
2906 			}
2907 
2908 			USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2909 			    "keyspan_build_cmd_msg_usa19hs: stopb=%x, lcr = %x",
2910 			    pe->val.ui, ctrl_msg->lcr);
2911 
2912 			break;
2913 		case DS_PARAM_CHARSZ:
2914 			switch (pe->val.ui) {
2915 			case CS5:
2916 
2917 				/*
2918 				 * USA_DATABITS_5 equals zero,
2919 				 * not necessary to or it in.
2920 				 */
2921 				USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2922 				    "keyspan_build_cmd_msg_usa19hs:"
2923 				    " USA_DATABITS_5");
2924 
2925 				break;
2926 			case CS6:
2927 				ctrl_msg->lcr |= USA_DATABITS_6;
2928 
2929 				break;
2930 			case CS7:
2931 				ctrl_msg->lcr |= USA_DATABITS_7;
2932 
2933 				break;
2934 			case CS8:
2935 			default:
2936 				/*
2937 				 * The default value is USA_DATABITS_8. It is
2938 				 * safe to set to the default one here.
2939 				 */
2940 				ctrl_msg->lcr |= USA_DATABITS_8;
2941 
2942 				break;
2943 			}
2944 
2945 			USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2946 			    "keyspan_build_cmd_msg_usa19hs: cs=%x, lcr = %x",
2947 			    pe->val.ui, ctrl_msg->lcr);
2948 
2949 			break;
2950 		case DS_PARAM_XON_XOFF:
2951 			ctrl_msg->xonChar = pe->val.uc[0]; /* init to CSTART */
2952 			ctrl_msg->xoffChar = pe->val.uc[1]; /* init to CSTOP */
2953 
2954 			USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2955 			    "keyspan_build_cmd_msg_usa19hs: xonChar=%x, "
2956 			    "xoffChar = %x", ctrl_msg->xonChar,
2957 			    ctrl_msg->xoffChar);
2958 
2959 			break;
2960 		case DS_PARAM_FLOW_CTL:
2961 			if (pe->val.ui & CTSXON) {
2962 				ctrl_msg->txFlowControl = TXFLOW_CTS;
2963 				ctrl_msg->setTxFlowControl = 1;
2964 			} else {
2965 				/* Clear the tx flow control setting */
2966 				ctrl_msg->txFlowControl = 0;
2967 				ctrl_msg->setTxFlowControl = 1;
2968 			}
2969 			if (pe->val.ui & RTSXOFF) {
2970 				ctrl_msg->rxFlowControl = RXFLOW_RTS;
2971 				ctrl_msg->setRxFlowControl = 1;
2972 			} else {
2973 				/* Clear the rx flow control setting */
2974 				ctrl_msg->rxFlowControl = 0;
2975 				ctrl_msg->setRxFlowControl = 1;
2976 			}
2977 
2978 			USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
2979 			    "keyspan_build_cmd_msg_usa19hs: txFlowControl = %x,"
2980 			    "rxFlowControl = %x", ctrl_msg->txFlowControl,
2981 			    ctrl_msg->rxFlowControl);
2982 
2983 			break;
2984 		default:
2985 			USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh,
2986 			    "keyspan_build_cmd_msg_usa19hs: bad param %d",
2987 			    pe->param);
2988 
2989 			break;
2990 		}
2991 
2992 	}
2993 
2994 	/*
2995 	 * Enable the lcr settings only if they are different
2996 	 * with the existing settings.
2997 	 */
2998 	ctrl_msg->setLcr =  (ctrl_msg->lcr == kp->kp_lcr) ? 0 : 1;
2999 
3000 }
3001 
3002 
3003 /*
3004  * Build the command message according to the params from usbser.
3005  * The message will then be sent to deivce by keyspan_send_cmd.
3006  */
3007 static void
3008 keyspan_build_cmd_msg_usa49(keyspan_port_t *kp, ds_port_params_t *tp)
3009 {
3010 	int		cnt, i;
3011 	uint_t		ui;
3012 	ds_port_param_entry_t *pe;
3013 	keyspan_usa49_port_ctrl_msg_t	*ctrl_msg = &(kp->kp_ctrl_msg.usa49);
3014 
3015 	USB_DPRINTF_L4(DPRINT_CTLOP, kp->kp_lh,
3016 	    "keyspan_build_cmd_msg_usa49: tp = %p", (void *)tp);
3017 
3018 	ASSERT(mutex_owned(&kp->kp_mutex));
3019 	ASSERT(kp->kp_state == KEYSPAN_PORT_OPEN ||
3020 	    kp->kp_state == KEYSPAN_PORT_OPENING);
3021 
3022 	/* bzero all elements */
3023 	bzero(ctrl_msg, sizeof (keyspan_usa49_port_ctrl_msg_t));
3024 
3025 	ctrl_msg->portNumber = kp->kp_port_num;
3026 
3027 	/* it is usaually 16, according to Keyspan spec */
3028 	ctrl_msg->forwardingLength = 16;
3029 
3030 	ctrl_msg->enablePort = 1;
3031 	ctrl_msg->returnStatus = 1;
3032 
3033 	if (tp == NULL) {
3034 
3035 		return;
3036 	}
3037 
3038 	cnt = tp->tp_cnt;
3039 	pe = tp->tp_entries;
3040 
3041 	/* translate tp parameters into cmd_msg elements */
3042 	for (i = 0; i < cnt; i++, pe++) {
3043 		switch (pe->param) {
3044 		case DS_PARAM_BAUD:
3045 			ui = pe->val.ui;
3046 
3047 			/*
3048 			 * If we don't support this speed,
3049 			 * then return failure.
3050 			 */
3051 			if ((ui >= NELEM(keyspan_speedtab_usa49)) ||
3052 			    ((ui > 0) && (keyspan_speedtab_usa49[ui] == 0))) {
3053 
3054 				USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
3055 				    "keyspan_build_cmd_msg_usa49:"
3056 				    " bad baud %d", ui);
3057 
3058 				break;
3059 			}
3060 
3061 			/* if the same as the old rate, need not set the rate */
3062 			if (kp->kp_baud == keyspan_speedtab_usa49[ui]) {
3063 
3064 				USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
3065 				    "keyspan_build_cmd_msg_usa49: "
3066 				    "same as old baud setting, baud = %d",
3067 				    keyspan_speed2baud[ui]);
3068 
3069 				break;
3070 			}
3071 			ctrl_msg->setClocking = 0xff; /* enable the setting */
3072 			ctrl_msg->baudLo = keyspan_speedtab_usa49[ui] & 0xff;
3073 			ctrl_msg->baudHi = (keyspan_speedtab_usa49[ui] >> 8)
3074 			    & 0xff;
3075 			ctrl_msg->prescaler = keyspan_prescaler_49wlc[ui];
3076 
3077 			USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
3078 			    "keyspan_build_cmd_msg_usa49: baud=%d",
3079 			    keyspan_speed2baud[ui]);
3080 
3081 			break;
3082 		case DS_PARAM_PARITY:
3083 			if (pe->val.ui & PARENB) {
3084 
3085 				/*
3086 				 * Since USA_PARITY_NONE == 0,
3087 				 * it's not necessary to or it in here.
3088 				 */
3089 				if (pe->val.ui & PARODD) {
3090 					ctrl_msg->lcr |= USA_PARITY_ODD;
3091 				} else {
3092 					ctrl_msg->lcr |= USA_PARITY_EVEN;
3093 				}
3094 			}
3095 			USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
3096 			    "keyspan_build_cmd_msg_usa49: parity=%x, lcr = %x",
3097 			    pe->val.ui, ctrl_msg->lcr);
3098 
3099 			break;
3100 		case DS_PARAM_STOPB:
3101 			if (pe->val.ui & CSTOPB) {
3102 				ctrl_msg->lcr |= STOPBITS_678_2;
3103 			} else {
3104 
3105 				/*
3106 				 * STOPBITS_5678_1 equals zero,
3107 				 * not necessary to or it in.
3108 				 */
3109 				USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
3110 				    "keyspan_build_cmd_msg_usa49: "
3111 				    "STOPBITS_5678_1");
3112 			}
3113 
3114 			USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
3115 			    "keyspan_build_cmd_msg_usa49: stopb=%x, lcr = %x",
3116 			    pe->val.ui, ctrl_msg->lcr);
3117 
3118 			break;
3119 		case DS_PARAM_CHARSZ:
3120 			switch (pe->val.ui) {
3121 			case CS5:
3122 
3123 				/*
3124 				 * USA_DATABITS_5 equals zero,
3125 				 * not necessary to or it in.
3126 				 */
3127 				USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
3128 				    "keyspan_build_cmd_msg_usa49:"
3129 				    " USA_DATABITS_5");
3130 
3131 				break;
3132 			case CS6:
3133 				ctrl_msg->lcr |= USA_DATABITS_6;
3134 
3135 				break;
3136 			case CS7:
3137 				ctrl_msg->lcr |= USA_DATABITS_7;
3138 
3139 				break;
3140 			case CS8:
3141 			default:
3142 				ctrl_msg->lcr |= USA_DATABITS_8;
3143 
3144 				break;
3145 			}
3146 
3147 			USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
3148 			    "keyspan_build_cmd_msg_usa49: cs=%x, lcr = %x",
3149 			    pe->val.ui, ctrl_msg->lcr);
3150 
3151 			break;
3152 		case DS_PARAM_XON_XOFF:
3153 			ctrl_msg->xonChar = pe->val.uc[0]; /* init to CSTART */
3154 			ctrl_msg->xoffChar = pe->val.uc[1]; /* init to CSTOP */
3155 
3156 			USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
3157 			    "keyspan_build_cmd_msg_usa49: xonChar=%x, "
3158 			    "xoffChar = %x", ctrl_msg->xonChar,
3159 			    ctrl_msg->xoffChar);
3160 
3161 			break;
3162 		case DS_PARAM_FLOW_CTL:
3163 			if (pe->val.ui & CTSXON) {
3164 				ctrl_msg->ctsFlowControl = 1;
3165 				ctrl_msg->setFlowControl = 1;
3166 			} else {
3167 				ctrl_msg->ctsFlowControl = 0;
3168 				ctrl_msg->setFlowControl = 1;
3169 			}
3170 			if (pe->val.ui & RTSXOFF) {
3171 				USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
3172 				    "keyspan_build_cmd_msg_usa49: "
3173 				    "pe->val.ui = %x, flow_ctl: RTSXOFF, "
3174 				    "no hardware support", pe->val.ui);
3175 			}
3176 
3177 			USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
3178 			    "keyspan_build_cmd_msg_usa49: ctsFlowControl = %x,"
3179 			    "dsrFlowControl = %x", ctrl_msg->ctsFlowControl,
3180 			    ctrl_msg->dsrFlowControl);
3181 
3182 			break;
3183 		default:
3184 			USB_DPRINTF_L2(DPRINT_CTLOP, kp->kp_lh,
3185 			    "keyspan_build_cmd_msg_usa49: bad param %d",
3186 			    pe->param);
3187 
3188 			break;
3189 		}
3190 	}
3191 
3192 	/*
3193 	 * enable the lcr settings only if they are different
3194 	 * with the existing settings.
3195 	 */
3196 	ctrl_msg->setLcr =  (ctrl_msg->lcr == kp->kp_lcr) ? 0 : 1;
3197 
3198 }
3199 
3200 
3201 /*
3202  * Set the port parameters to default values
3203  */
3204 static void
3205 keyspan_default_port_params_usa49(keyspan_port_t *kp)
3206 {
3207 	keyspan_usa49_port_ctrl_msg_t	*ctrl_msg = &(kp->kp_ctrl_msg.usa49);
3208 	ASSERT(mutex_owned(&kp->kp_mutex));
3209 
3210 	keyspan_build_cmd_msg(kp, NULL);
3211 
3212 	ctrl_msg->setRts = 1;
3213 	ctrl_msg->rts = 1;
3214 	ctrl_msg->setDtr = 1;
3215 	ctrl_msg->dtr = 1;
3216 
3217 	ctrl_msg->_txOn = 1;
3218 	ctrl_msg->_txOff = 0;
3219 	ctrl_msg->txFlush = 0;
3220 	ctrl_msg->txBreak = 0;
3221 	ctrl_msg->rxOn = 1;
3222 	ctrl_msg->rxOff = 0;
3223 	ctrl_msg->rxFlush = 0;
3224 	ctrl_msg->rxForward = 0;
3225 	ctrl_msg->returnStatus = 1;
3226 	ctrl_msg->resetDataToggle = 0;
3227 	ctrl_msg->enablePort = 1;
3228 	ctrl_msg->disablePort = 0;
3229 
3230 	/* set baud rate to 9600 */
3231 	ctrl_msg->setClocking = 1;
3232 	ctrl_msg->baudLo = keyspan_speedtab_usa49[13] & 0xff;
3233 	ctrl_msg->baudHi = (keyspan_speedtab_usa49[13] >> 8) & 0xff;
3234 	ctrl_msg->prescaler = keyspan_prescaler_49wlc[13];
3235 
3236 	ctrl_msg->lcr = 0x3;
3237 	ctrl_msg->setLcr = 1;
3238 
3239 	ctrl_msg->xonChar = CSTART;
3240 	ctrl_msg->xoffChar = CSTOP;
3241 	ctrl_msg->ctsFlowControl = 1;
3242 	ctrl_msg->setFlowControl = 1;
3243 
3244 }
3245 
3246 
3247 /* save the port params after send cmd successfully */
3248 static void
3249 keyspan_save_port_params_usa49(keyspan_port_t	*kp)
3250 {
3251 	keyspan_usa49_port_ctrl_msg_t	*ctrl_msg = &(kp->kp_ctrl_msg.usa49);
3252 
3253 	ASSERT(mutex_owned(&kp->kp_mutex));
3254 
3255 	if (ctrl_msg->setClocking) {
3256 		kp->kp_baud = ctrl_msg->baudHi;
3257 		kp->kp_baud = (kp->kp_baud << 8);
3258 		kp->kp_baud |= ctrl_msg->baudLo;
3259 	}
3260 	if (ctrl_msg->setLcr) {
3261 		kp->kp_lcr = ctrl_msg->lcr;
3262 	}
3263 	if (ctrl_msg->setRts) {
3264 		if (ctrl_msg->rts) {
3265 			kp->kp_status_flag |= KEYSPAN_PORT_RTS;
3266 		} else {
3267 			kp->kp_status_flag &= ~KEYSPAN_PORT_RTS;
3268 		}
3269 	}
3270 	if (ctrl_msg->setDtr) {
3271 		if (ctrl_msg->dtr) {
3272 			kp->kp_status_flag |= KEYSPAN_PORT_DTR;
3273 		} else {
3274 			kp->kp_status_flag &= ~KEYSPAN_PORT_DTR;
3275 		}
3276 	}
3277 
3278 	if (ctrl_msg->enablePort) {
3279 		kp->kp_status_flag |= KEYSPAN_PORT_ENABLE;
3280 	} else {
3281 		kp->kp_status_flag &= ~KEYSPAN_PORT_ENABLE;
3282 	}
3283 
3284 	/*
3285 	 * There are no flags in status msg (49wlc) can indicate the
3286 	 * break status, so we make use of ctrl_msg->txBreak here.
3287 	 */
3288 	if (ctrl_msg->txBreak) {
3289 		kp->kp_status_flag |= KEYSPAN_PORT_TXBREAK;
3290 	} else {
3291 		kp->kp_status_flag &= ~KEYSPAN_PORT_TXBREAK;
3292 	}
3293 
3294 	USB_DPRINTF_L3(DPRINT_CTLOP, kp->kp_lh,
3295 	    "keyspan_save_port_params: baud = %x, lcr = %x,"
3296 	    "status_flag = %x", kp->kp_baud, kp->kp_lcr, kp->kp_status_flag);
3297 
3298 }
3299