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