8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * FTDI FT232R USB UART device-specific driver
29 *
30 * May work on the (many) devices based on earlier versions of the chip.
31 */
32
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/conf.h>
36 #include <sys/stream.h>
37 #include <sys/strsun.h>
38 #include <sys/termio.h>
39 #include <sys/termiox.h>
40 #include <sys/ddi.h>
41 #include <sys/sunddi.h>
42
43 #define USBDRV_MAJOR_VER 2
44 #define USBDRV_MINOR_VER 0
45
46 #include <sys/usb/usba.h>
47 #include <sys/usb/usba/usba_types.h>
203 }
204
205 uf->uf_hwport = FTDI_PIT_SIOA + uf->uf_dev_data->dev_curr_if;
206
207 mutex_init(&uf->uf_lock, NULL, MUTEX_DRIVER,
208 uf->uf_dev_data->dev_iblock_cookie);
209
210 cv_init(&uf->uf_tx_cv, NULL, CV_DRIVER, NULL);
211
212 uf->uf_lh = usb_alloc_log_hdl(uf->uf_dip, "uftdi",
213 &uftdi_errlevel, &uftdi_errmask, &uftdi_instance_debug, 0);
214
215 /*
216 * This device and its clones has numerous physical instantiations.
217 */
218 recognized = B_TRUE;
219 dd = uf->uf_dev_data->dev_descr;
220 switch (dd->idVendor) {
221 case USB_VENDOR_FTDI:
222 switch (dd->idProduct) {
223 case USB_PRODUCT_FTDI_SERIAL_8U232AM:
224 case USB_PRODUCT_FTDI_SEMC_DSS20:
225 case USB_PRODUCT_FTDI_CFA_631:
226 case USB_PRODUCT_FTDI_CFA_632:
227 case USB_PRODUCT_FTDI_CFA_633:
228 case USB_PRODUCT_FTDI_CFA_634:
229 case USB_PRODUCT_FTDI_CFA_635:
230 case USB_PRODUCT_FTDI_USBSERIAL:
231 case USB_PRODUCT_FTDI_MX2_3:
232 case USB_PRODUCT_FTDI_MX4_5:
233 case USB_PRODUCT_FTDI_LK202:
234 case USB_PRODUCT_FTDI_LK204:
235 case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13M:
236 case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13S:
237 case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13U:
238 case USB_PRODUCT_FTDI_EISCOU:
239 case USB_PRODUCT_FTDI_UOPTBR:
240 case USB_PRODUCT_FTDI_EMCU2D:
241 case USB_PRODUCT_FTDI_PCMSFU:
242 case USB_PRODUCT_FTDI_EMCU2H:
311 dd->idVendor, dd->idProduct, uf->uf_hwport);
312
313 uf->uf_def_ph = uf->uf_dev_data->dev_default_ph;
314
315 mutex_enter(&uf->uf_lock);
316 uf->uf_dev_state = USB_DEV_ONLINE;
317 uf->uf_port_state = UFTDI_PORT_CLOSED;
318 mutex_exit(&uf->uf_lock);
319
320 if (uftdi_create_pm_components(uf) != USB_SUCCESS) {
321 uftdi_cleanup(uf, 3);
322 return (USB_FAILURE);
323 }
324
325 if (usb_register_event_cbs(uf->uf_dip,
326 uf->uf_usb_events, 0) != USB_SUCCESS) {
327 uftdi_cleanup(uf, 4);
328 return (USB_FAILURE);
329 }
330
331 if (usb_pipe_get_max_bulk_transfer_size(uf->uf_dip,
332 &uf->uf_xfer_sz) != USB_SUCCESS) {
333 uftdi_cleanup(uf, 5);
334 return (USB_FAILURE);
335 }
336
337 /*
338 * TODO: modern ftdi devices have deeper (and asymmetric)
339 * fifos than this minimal 64 bytes .. but how to tell
340 * -safely- ?
341 */
342
343 #define FTDI_MAX_XFERSIZE 64
344
345 if (uf->uf_xfer_sz > FTDI_MAX_XFERSIZE)
346 uf->uf_xfer_sz = FTDI_MAX_XFERSIZE;
347
348 if (uftdi_dev_attach(uf) != USB_SUCCESS) {
349 uftdi_cleanup(uf, 5);
350 return (USB_FAILURE);
351 }
352
353 return (USB_SUCCESS);
354 }
355
356 #define FTDI_CLEANUP_LEVEL_MAX 6
357
358 /*
359 * ds_detach
360 */
361 static void
362 uftdi_detach(ds_hdl_t hdl)
363 {
364 uftdi_cleanup((uftdi_state_t *)hdl, FTDI_CLEANUP_LEVEL_MAX);
365 }
366
367
1484 case USB_DEV_DISCONNECTED:
1485 case USB_DEV_SUSPENDED:
1486 return (USB_SUCCESS);
1487 default:
1488 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh,
1489 "uftdi_pwrlvl3: illegal device state");
1490 return (USB_FAILURE);
1491 }
1492 }
1493
1494
1495 /*
1496 * pipe operations
1497 */
1498 static int
1499 uftdi_open_pipes(uftdi_state_t *uf)
1500 {
1501 int ifc, alt;
1502 usb_pipe_policy_t policy;
1503 usb_ep_data_t *in_data, *out_data;
1504
1505 /* get ep data */
1506 ifc = uf->uf_dev_data->dev_curr_if;
1507 alt = 0;
1508
1509 in_data = usb_lookup_ep_data(uf->uf_dip, uf->uf_dev_data, ifc, alt,
1510 0, USB_EP_ATTR_BULK, USB_EP_DIR_IN);
1511
1512 out_data = usb_lookup_ep_data(uf->uf_dip, uf->uf_dev_data, ifc, alt,
1513 0, USB_EP_ATTR_BULK, USB_EP_DIR_OUT);
1514
1515 if (in_data == NULL || out_data == NULL) {
1516 USB_DPRINTF_L2(DPRINT_ATTACH, uf->uf_lh,
1517 "uftdi_open_pipes: can't get ep data");
1518 return (USB_FAILURE);
1519 }
1520
1521 /* open pipes */
1522 policy.pp_max_async_reqs = 2;
1523
1524 if (usb_pipe_open(uf->uf_dip, &in_data->ep_descr, &policy,
1525 USB_FLAGS_SLEEP, &uf->uf_bulkin_ph) != USB_SUCCESS)
1526 return (USB_FAILURE);
1527
1528 if (usb_pipe_open(uf->uf_dip, &out_data->ep_descr, &policy,
1529 USB_FLAGS_SLEEP, &uf->uf_bulkout_ph) != USB_SUCCESS) {
1530 usb_pipe_close(uf->uf_dip, uf->uf_bulkin_ph, USB_FLAGS_SLEEP,
1531 NULL, NULL);
1532 return (USB_FAILURE);
1533 }
1534
1535 mutex_enter(&uf->uf_lock);
1536 uf->uf_bulkin_state = UFTDI_PIPE_IDLE;
1537 uf->uf_bulkout_state = UFTDI_PIPE_IDLE;
1538 mutex_exit(&uf->uf_lock);
1539
1540 return (USB_SUCCESS);
1789 mutex_exit(&uf->uf_lock);
1790 }
1791
1792
1793 /*
1794 * start receiving data
1795 */
1796 static int
1797 uftdi_rx_start(uftdi_state_t *uf)
1798 {
1799 usb_bulk_req_t *br;
1800 int rval;
1801
1802 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, "uftdi_rx_start");
1803
1804 ASSERT(mutex_owned(&uf->uf_lock));
1805
1806 uf->uf_bulkin_state = UFTDI_PIPE_BUSY;
1807 mutex_exit(&uf->uf_lock);
1808
1809 br = usb_alloc_bulk_req(uf->uf_dip, uf->uf_xfer_sz, USB_FLAGS_SLEEP);
1810 br->bulk_len = uf->uf_xfer_sz;
1811 br->bulk_timeout = UFTDI_BULKIN_TIMEOUT;
1812 br->bulk_cb = uftdi_bulkin_cb;
1813 br->bulk_exc_cb = uftdi_bulkin_cb;
1814 br->bulk_client_private = (usb_opaque_t)uf;
1815 br->bulk_attributes = USB_ATTRS_AUTOCLEARING | USB_ATTRS_SHORT_XFER_OK;
1816
1817 rval = usb_pipe_bulk_xfer(uf->uf_bulkin_ph, br, 0);
1818
1819 if (rval != USB_SUCCESS) {
1820 USB_DPRINTF_L2(DPRINT_IN_PIPE, uf->uf_lh,
1821 "uftdi_rx_start: xfer failed %d", rval);
1822 usb_free_bulk_req(br);
1823 }
1824
1825 mutex_enter(&uf->uf_lock);
1826 if (rval != USB_SUCCESS)
1827 uf->uf_bulkin_state = UFTDI_PIPE_IDLE;
1828
1829 return (rval);
1830 }
1844 int rval;
1845
1846 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, "uftdi_tx_start");
1847 ASSERT(mutex_owned(&uf->uf_lock));
1848 ASSERT(uf->uf_port_state != UFTDI_PORT_CLOSED);
1849
1850 if (xferd)
1851 *xferd = 0;
1852 if ((uf->uf_port_flags & UFTDI_PORT_TX_STOPPED) ||
1853 uf->uf_tx_mp == NULL) {
1854 return;
1855 }
1856 if (uf->uf_bulkout_state != UFTDI_PIPE_IDLE) {
1857 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh,
1858 "uftdi_tx_start: pipe busy");
1859 return;
1860 }
1861 ASSERT(MBLKL(uf->uf_tx_mp) > 0);
1862
1863 /* send as much data as port can receive */
1864 len = min(msgdsize(uf->uf_tx_mp), uf->uf_xfer_sz);
1865
1866 if (len <= 0)
1867 return;
1868 if ((data = allocb(len, BPRI_LO)) == NULL)
1869 return;
1870
1871 /*
1872 * copy no more than 'len' bytes from mblk chain to transmit mblk 'data'
1873 */
1874 data_len = 0;
1875 while (data_len < len && uf->uf_tx_mp) {
1876 mp = uf->uf_tx_mp;
1877 copylen = min(MBLKL(mp), len - data_len);
1878 bcopy(mp->b_rptr, data->b_wptr, copylen);
1879 mp->b_rptr += copylen;
1880 data->b_wptr += copylen;
1881 data_len += copylen;
1882
1883 if (MBLKL(mp) < 1) {
1884 uf->uf_tx_mp = unlinkb(mp);
|
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 2012 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>
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:
316 dd->idVendor, dd->idProduct, uf->uf_hwport);
317
318 uf->uf_def_ph = uf->uf_dev_data->dev_default_ph;
319
320 mutex_enter(&uf->uf_lock);
321 uf->uf_dev_state = USB_DEV_ONLINE;
322 uf->uf_port_state = UFTDI_PORT_CLOSED;
323 mutex_exit(&uf->uf_lock);
324
325 if (uftdi_create_pm_components(uf) != USB_SUCCESS) {
326 uftdi_cleanup(uf, 3);
327 return (USB_FAILURE);
328 }
329
330 if (usb_register_event_cbs(uf->uf_dip,
331 uf->uf_usb_events, 0) != USB_SUCCESS) {
332 uftdi_cleanup(uf, 4);
333 return (USB_FAILURE);
334 }
335
336 if (uftdi_dev_attach(uf) != USB_SUCCESS) {
337 uftdi_cleanup(uf, 5);
338 return (USB_FAILURE);
339 }
340
341 return (USB_SUCCESS);
342 }
343
344 #define FTDI_CLEANUP_LEVEL_MAX 6
345
346 /*
347 * ds_detach
348 */
349 static void
350 uftdi_detach(ds_hdl_t hdl)
351 {
352 uftdi_cleanup((uftdi_state_t *)hdl, FTDI_CLEANUP_LEVEL_MAX);
353 }
354
355
1472 case USB_DEV_DISCONNECTED:
1473 case USB_DEV_SUSPENDED:
1474 return (USB_SUCCESS);
1475 default:
1476 USB_DPRINTF_L2(DPRINT_PM, uf->uf_lh,
1477 "uftdi_pwrlvl3: illegal device state");
1478 return (USB_FAILURE);
1479 }
1480 }
1481
1482
1483 /*
1484 * pipe operations
1485 */
1486 static int
1487 uftdi_open_pipes(uftdi_state_t *uf)
1488 {
1489 int ifc, alt;
1490 usb_pipe_policy_t policy;
1491 usb_ep_data_t *in_data, *out_data;
1492 size_t max_xfer_sz;
1493
1494 /* get max transfer size */
1495 if (usb_pipe_get_max_bulk_transfer_size(uf->uf_dip, &max_xfer_sz)
1496 != USB_SUCCESS)
1497 return (USB_FAILURE);
1498
1499 /* get ep data */
1500 ifc = uf->uf_dev_data->dev_curr_if;
1501 alt = 0;
1502
1503 in_data = usb_lookup_ep_data(uf->uf_dip, uf->uf_dev_data, ifc, alt,
1504 0, USB_EP_ATTR_BULK, USB_EP_DIR_IN);
1505
1506 out_data = usb_lookup_ep_data(uf->uf_dip, uf->uf_dev_data, ifc, alt,
1507 0, USB_EP_ATTR_BULK, USB_EP_DIR_OUT);
1508
1509 if (in_data == NULL || out_data == NULL) {
1510 USB_DPRINTF_L2(DPRINT_ATTACH, uf->uf_lh,
1511 "uftdi_open_pipes: can't get ep data");
1512 return (USB_FAILURE);
1513 }
1514
1515 /*
1516 * Set buffer sizes. Default to UFTDI_XFER_SZ_MAX.
1517 * Use wMaxPacketSize from endpoint descriptor if it is nonzero..
1518 * Cap at a max transfer size of host controller.
1519 */
1520 uf->uf_ibuf_sz = uf->uf_obuf_sz = UFTDI_XFER_SZ_MAX;
1521
1522 if (in_data->ep_descr.wMaxPacketSize)
1523 uf->uf_ibuf_sz = in_data->ep_descr.wMaxPacketSize;
1524 uf->uf_ibuf_sz = min(uf->uf_ibuf_sz, max_xfer_sz);
1525
1526 if (out_data->ep_descr.wMaxPacketSize)
1527 uf->uf_obuf_sz = out_data->ep_descr.wMaxPacketSize;
1528 uf->uf_obuf_sz = min(uf->uf_obuf_sz, max_xfer_sz);
1529
1530 /* open pipes */
1531 policy.pp_max_async_reqs = 2;
1532
1533 if (usb_pipe_open(uf->uf_dip, &in_data->ep_descr, &policy,
1534 USB_FLAGS_SLEEP, &uf->uf_bulkin_ph) != USB_SUCCESS)
1535 return (USB_FAILURE);
1536
1537 if (usb_pipe_open(uf->uf_dip, &out_data->ep_descr, &policy,
1538 USB_FLAGS_SLEEP, &uf->uf_bulkout_ph) != USB_SUCCESS) {
1539 usb_pipe_close(uf->uf_dip, uf->uf_bulkin_ph, USB_FLAGS_SLEEP,
1540 NULL, NULL);
1541 return (USB_FAILURE);
1542 }
1543
1544 mutex_enter(&uf->uf_lock);
1545 uf->uf_bulkin_state = UFTDI_PIPE_IDLE;
1546 uf->uf_bulkout_state = UFTDI_PIPE_IDLE;
1547 mutex_exit(&uf->uf_lock);
1548
1549 return (USB_SUCCESS);
1798 mutex_exit(&uf->uf_lock);
1799 }
1800
1801
1802 /*
1803 * start receiving data
1804 */
1805 static int
1806 uftdi_rx_start(uftdi_state_t *uf)
1807 {
1808 usb_bulk_req_t *br;
1809 int rval;
1810
1811 USB_DPRINTF_L4(DPRINT_OUT_PIPE, uf->uf_lh, "uftdi_rx_start");
1812
1813 ASSERT(mutex_owned(&uf->uf_lock));
1814
1815 uf->uf_bulkin_state = UFTDI_PIPE_BUSY;
1816 mutex_exit(&uf->uf_lock);
1817
1818 br = usb_alloc_bulk_req(uf->uf_dip, uf->uf_ibuf_sz, USB_FLAGS_SLEEP);
1819 br->bulk_len = uf->uf_ibuf_sz;
1820 br->bulk_timeout = UFTDI_BULKIN_TIMEOUT;
1821 br->bulk_cb = uftdi_bulkin_cb;
1822 br->bulk_exc_cb = uftdi_bulkin_cb;
1823 br->bulk_client_private = (usb_opaque_t)uf;
1824 br->bulk_attributes = USB_ATTRS_AUTOCLEARING | USB_ATTRS_SHORT_XFER_OK;
1825
1826 rval = usb_pipe_bulk_xfer(uf->uf_bulkin_ph, br, 0);
1827
1828 if (rval != USB_SUCCESS) {
1829 USB_DPRINTF_L2(DPRINT_IN_PIPE, uf->uf_lh,
1830 "uftdi_rx_start: xfer failed %d", rval);
1831 usb_free_bulk_req(br);
1832 }
1833
1834 mutex_enter(&uf->uf_lock);
1835 if (rval != USB_SUCCESS)
1836 uf->uf_bulkin_state = UFTDI_PIPE_IDLE;
1837
1838 return (rval);
1839 }
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);
|