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