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
uftdi_attach(ds_attach_info_t * aip)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
uftdi_detach(ds_hdl_t hdl)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
uftdi_register_cb(ds_hdl_t hdl,uint_t portno,ds_cb_t * cb)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
uftdi_unregister_cb(ds_hdl_t hdl,uint_t portno)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
uftdi_open_port(ds_hdl_t hdl,uint_t portno)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
uftdi_close_port(ds_hdl_t hdl,uint_t portno)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
uftdi_usb_power(ds_hdl_t hdl,int comp,int level,int * new_state)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
uftdi_suspend(ds_hdl_t hdl)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
uftdi_resume(ds_hdl_t hdl)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
uftdi_disconnect(ds_hdl_t hdl)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
uftdi_reconnect(ds_hdl_t hdl)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
uftdi_param2regs(uftdi_state_t * uf,ds_port_params_t * tp,uftdi_regs_t * ur)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
uftdi_setregs(uftdi_state_t * uf,uftdi_regs_t * ur)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
uftdi_set_port_params(ds_hdl_t hdl,uint_t portno,ds_port_params_t * tp)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
uftdi_set_modem_ctl(ds_hdl_t hdl,uint_t portno,int mask,int val)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
uftdi_get_modem_ctl(ds_hdl_t hdl,uint_t portno,int mask,int * valp)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
uftdi_break_ctl(ds_hdl_t hdl,uint_t portno,int ctl)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
uftdi_tx(ds_hdl_t hdl,uint_t portno,mblk_t * mp)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 *
uftdi_rx(ds_hdl_t hdl,uint_t portno)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
uftdi_stop(ds_hdl_t hdl,uint_t portno,int dir)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
uftdi_start(ds_hdl_t hdl,uint_t portno,int dir)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
uftdi_fifo_flush(ds_hdl_t hdl,uint_t portno,int dir)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
uftdi_fifo_drain(ds_hdl_t hdl,uint_t portno,int timeout)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
uftdi_cleanup(uftdi_state_t * uf,int level)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
uftdi_dev_attach(uftdi_state_t * uf)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
uftdi_restore_device_state(uftdi_state_t * uf)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
uftdi_restore_port_state(uftdi_state_t * uf)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
uftdi_create_pm_components(uftdi_state_t * uf)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
uftdi_destroy_pm_components(uftdi_state_t * uf)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
uftdi_pm_set_busy(uftdi_state_t * uf)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
uftdi_pm_set_idle(uftdi_state_t * uf)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
uftdi_pwrlvl0(uftdi_state_t * uf)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
uftdi_pwrlvl1(uftdi_state_t * uf)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
uftdi_pwrlvl2(uftdi_state_t * uf)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
uftdi_pwrlvl3(uftdi_state_t * uf)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
uftdi_open_pipes(uftdi_state_t * uf)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
uftdi_close_pipes(uftdi_state_t * uf)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
uftdi_disconnect_pipes(uftdi_state_t * uf)1571 uftdi_disconnect_pipes(uftdi_state_t *uf)
1572 {
1573 uftdi_close_pipes(uf);
1574 }
1575
1576
1577 static int
uftdi_reconnect_pipes(uftdi_state_t * uf)1578 uftdi_reconnect_pipes(uftdi_state_t *uf)
1579 {
1580 return (uftdi_open_pipes(uf));
1581 }
1582
1583
1584 static void
uftdi_rxerr_put(mblk_t ** rx_mpp,mblk_t * data,uint8_t lsr)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
uftdi_bulkin_cb(usb_pipe_handle_t pipe,usb_bulk_req_t * req)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
uftdi_bulkout_cb(usb_pipe_handle_t pipe,usb_bulk_req_t * req)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
uftdi_rx_start(uftdi_state_t * uf)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
uftdi_tx_start(uftdi_state_t * uf,int * xferd)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
uftdi_send_data(uftdi_state_t * uf,mblk_t * data)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
uftdi_wait_tx_drain(uftdi_state_t * uf,int timeout)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
uftdi_open_hw_port(uftdi_state_t * uf,int dorestore)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, ¶ms);
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
uftdi_cmd_vendor_write0(uftdi_state_t * uf,uint16_t reqno,uint16_t val,uint16_t idx)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
uftdi_put_tail(mblk_t ** mpp,mblk_t * bp)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
uftdi_put_head(mblk_t ** mpp,mblk_t * bp)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
uftdi_out_pipe(ds_hdl_t hdl,uint_t portno)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
uftdi_in_pipe(ds_hdl_t hdl,uint_t portno)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