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