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