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