aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ftdi_sio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r--drivers/usb/serial/ftdi_sio.c105
1 files changed, 75 insertions, 30 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 5fc13e717911..bd4298bb6750 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -73,6 +73,7 @@ struct ftdi_private {
73 */ 73 */
74 int flags; /* some ASYNC_xxxx flags are supported */ 74 int flags; /* some ASYNC_xxxx flags are supported */
75 unsigned long last_dtr_rts; /* saved modem control outputs */ 75 unsigned long last_dtr_rts; /* saved modem control outputs */
76 struct async_icount icount;
76 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ 77 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
77 char prev_status, diff_status; /* Used for TIOCMIWAIT */ 78 char prev_status, diff_status; /* Used for TIOCMIWAIT */
78 char transmit_empty; /* If transmitter is empty or not */ 79 char transmit_empty; /* If transmitter is empty or not */
@@ -207,6 +208,8 @@ static struct usb_device_id id_table_combined [] = {
207 { USB_DEVICE(FTDI_VID, FTDI_XF_640_PID) }, 208 { USB_DEVICE(FTDI_VID, FTDI_XF_640_PID) },
208 { USB_DEVICE(FTDI_VID, FTDI_XF_642_PID) }, 209 { USB_DEVICE(FTDI_VID, FTDI_XF_642_PID) },
209 { USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) }, 210 { USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) },
211 { USB_DEVICE(FTDI_VID, FTDI_URBAN_0_PID) },
212 { USB_DEVICE(FTDI_VID, FTDI_URBAN_1_PID) },
210 { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, 213 { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
211 { USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) }, 214 { USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) },
212 { USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) }, 215 { USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) },
@@ -745,6 +748,8 @@ static struct usb_device_id id_table_combined [] = {
745 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 748 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
746 { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), 749 { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID),
747 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 750 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
751 { USB_DEVICE(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID),
752 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
748 { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID), 753 { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID),
749 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 754 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
750 { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, 755 { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
@@ -885,6 +890,8 @@ static void ftdi_set_termios(struct tty_struct *tty,
885static int ftdi_tiocmget(struct tty_struct *tty); 890static int ftdi_tiocmget(struct tty_struct *tty);
886static int ftdi_tiocmset(struct tty_struct *tty, 891static int ftdi_tiocmset(struct tty_struct *tty,
887 unsigned int set, unsigned int clear); 892 unsigned int set, unsigned int clear);
893static int ftdi_get_icount(struct tty_struct *tty,
894 struct serial_icounter_struct *icount);
888static int ftdi_ioctl(struct tty_struct *tty, 895static int ftdi_ioctl(struct tty_struct *tty,
889 unsigned int cmd, unsigned long arg); 896 unsigned int cmd, unsigned long arg);
890static void ftdi_break_ctl(struct tty_struct *tty, int break_state); 897static void ftdi_break_ctl(struct tty_struct *tty, int break_state);
@@ -919,6 +926,7 @@ static struct usb_serial_driver ftdi_sio_device = {
919 .prepare_write_buffer = ftdi_prepare_write_buffer, 926 .prepare_write_buffer = ftdi_prepare_write_buffer,
920 .tiocmget = ftdi_tiocmget, 927 .tiocmget = ftdi_tiocmget,
921 .tiocmset = ftdi_tiocmset, 928 .tiocmset = ftdi_tiocmset,
929 .get_icount = ftdi_get_icount,
922 .ioctl = ftdi_ioctl, 930 .ioctl = ftdi_ioctl,
923 .set_termios = ftdi_set_termios, 931 .set_termios = ftdi_set_termios,
924 .break_ctl = ftdi_break_ctl, 932 .break_ctl = ftdi_break_ctl,
@@ -1486,7 +1494,7 @@ static void ftdi_set_max_packet_size(struct usb_serial_port *port)
1486 } 1494 }
1487 1495
1488 /* set max packet size based on descriptor */ 1496 /* set max packet size based on descriptor */
1489 priv->max_packet_size = le16_to_cpu(ep_desc->wMaxPacketSize); 1497 priv->max_packet_size = usb_endpoint_maxp(ep_desc);
1490 1498
1491 dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); 1499 dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size);
1492} 1500}
@@ -1646,6 +1654,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
1646 1654
1647 kref_init(&priv->kref); 1655 kref_init(&priv->kref);
1648 mutex_init(&priv->cfg_lock); 1656 mutex_init(&priv->cfg_lock);
1657 memset(&priv->icount, 0x00, sizeof(priv->icount));
1649 init_waitqueue_head(&priv->delta_msr_wait); 1658 init_waitqueue_head(&priv->delta_msr_wait);
1650 1659
1651 priv->flags = ASYNC_LOW_LATENCY; 1660 priv->flags = ASYNC_LOW_LATENCY;
@@ -1909,6 +1918,7 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port,
1909 c = kfifo_out(&port->write_fifo, &buffer[i + 1], len); 1918 c = kfifo_out(&port->write_fifo, &buffer[i + 1], len);
1910 if (!c) 1919 if (!c)
1911 break; 1920 break;
1921 priv->icount.tx += c;
1912 buffer[i] = (c << 2) + 1; 1922 buffer[i] = (c << 2) + 1;
1913 count += c + 1; 1923 count += c + 1;
1914 } 1924 }
@@ -1916,6 +1926,7 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port,
1916 } else { 1926 } else {
1917 count = kfifo_out_locked(&port->write_fifo, dest, size, 1927 count = kfifo_out_locked(&port->write_fifo, dest, size,
1918 &port->lock); 1928 &port->lock);
1929 priv->icount.tx += count;
1919 } 1930 }
1920 1931
1921 return count; 1932 return count;
@@ -1943,6 +1954,14 @@ static int ftdi_process_packet(struct tty_struct *tty,
1943 N.B. packet may be processed more than once, but differences 1954 N.B. packet may be processed more than once, but differences
1944 are only processed once. */ 1955 are only processed once. */
1945 status = packet[0] & FTDI_STATUS_B0_MASK; 1956 status = packet[0] & FTDI_STATUS_B0_MASK;
1957 if (status & FTDI_RS0_CTS)
1958 priv->icount.cts++;
1959 if (status & FTDI_RS0_DSR)
1960 priv->icount.dsr++;
1961 if (status & FTDI_RS0_RI)
1962 priv->icount.rng++;
1963 if (status & FTDI_RS0_RLSD)
1964 priv->icount.dcd++;
1946 if (status != priv->prev_status) { 1965 if (status != priv->prev_status) {
1947 priv->diff_status |= status ^ priv->prev_status; 1966 priv->diff_status |= status ^ priv->prev_status;
1948 wake_up_interruptible(&priv->delta_msr_wait); 1967 wake_up_interruptible(&priv->delta_msr_wait);
@@ -1955,15 +1974,20 @@ static int ftdi_process_packet(struct tty_struct *tty,
1955 * over framing errors */ 1974 * over framing errors */
1956 if (packet[1] & FTDI_RS_BI) { 1975 if (packet[1] & FTDI_RS_BI) {
1957 flag = TTY_BREAK; 1976 flag = TTY_BREAK;
1977 priv->icount.brk++;
1958 usb_serial_handle_break(port); 1978 usb_serial_handle_break(port);
1959 } else if (packet[1] & FTDI_RS_PE) { 1979 } else if (packet[1] & FTDI_RS_PE) {
1960 flag = TTY_PARITY; 1980 flag = TTY_PARITY;
1981 priv->icount.parity++;
1961 } else if (packet[1] & FTDI_RS_FE) { 1982 } else if (packet[1] & FTDI_RS_FE) {
1962 flag = TTY_FRAME; 1983 flag = TTY_FRAME;
1984 priv->icount.frame++;
1963 } 1985 }
1964 /* Overrun is special, not associated with a char */ 1986 /* Overrun is special, not associated with a char */
1965 if (packet[1] & FTDI_RS_OE) 1987 if (packet[1] & FTDI_RS_OE) {
1988 priv->icount.overrun++;
1966 tty_insert_flip_char(tty, 0, TTY_OVERRUN); 1989 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
1990 }
1967 } 1991 }
1968 1992
1969 /* save if the transmitter is empty or not */ 1993 /* save if the transmitter is empty or not */
@@ -1975,6 +1999,7 @@ static int ftdi_process_packet(struct tty_struct *tty,
1975 len -= 2; 1999 len -= 2;
1976 if (!len) 2000 if (!len)
1977 return 0; /* status only */ 2001 return 0; /* status only */
2002 priv->icount.rx += len;
1978 ch = packet + 2; 2003 ch = packet + 2;
1979 2004
1980 if (port->port.console && port->sysrq) { 2005 if (port->port.console && port->sysrq) {
@@ -2079,13 +2104,19 @@ static void ftdi_set_termios(struct tty_struct *tty,
2079 2104
2080 cflag = termios->c_cflag; 2105 cflag = termios->c_cflag;
2081 2106
2082 /* FIXME -For this cut I don't care if the line is really changing or 2107 if (old_termios->c_cflag == termios->c_cflag
2083 not - so just do the change regardless - should be able to 2108 && old_termios->c_ispeed == termios->c_ispeed
2084 compare old_termios and tty->termios */ 2109 && old_termios->c_ospeed == termios->c_ospeed)
2110 goto no_c_cflag_changes;
2111
2085 /* NOTE These routines can get interrupted by 2112 /* NOTE These routines can get interrupted by
2086 ftdi_sio_read_bulk_callback - need to examine what this means - 2113 ftdi_sio_read_bulk_callback - need to examine what this means -
2087 don't see any problems yet */ 2114 don't see any problems yet */
2088 2115
2116 if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) ==
2117 (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)))
2118 goto no_data_parity_stop_changes;
2119
2089 /* Set number of data bits, parity, stop bits */ 2120 /* Set number of data bits, parity, stop bits */
2090 2121
2091 urb_value = 0; 2122 urb_value = 0;
@@ -2126,6 +2157,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
2126 } 2157 }
2127 2158
2128 /* Now do the baudrate */ 2159 /* Now do the baudrate */
2160no_data_parity_stop_changes:
2129 if ((cflag & CBAUD) == B0) { 2161 if ((cflag & CBAUD) == B0) {
2130 /* Disable flow control */ 2162 /* Disable flow control */
2131 if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 2163 if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
@@ -2153,6 +2185,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
2153 2185
2154 /* Set flow control */ 2186 /* Set flow control */
2155 /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ 2187 /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */
2188no_c_cflag_changes:
2156 if (cflag & CRTSCTS) { 2189 if (cflag & CRTSCTS) {
2157 dbg("%s Setting to CRTSCTS flow control", __func__); 2190 dbg("%s Setting to CRTSCTS flow control", __func__);
2158 if (usb_control_msg(dev, 2191 if (usb_control_msg(dev,
@@ -2277,11 +2310,34 @@ static int ftdi_tiocmset(struct tty_struct *tty,
2277 return update_mctrl(port, set, clear); 2310 return update_mctrl(port, set, clear);
2278} 2311}
2279 2312
2313static int ftdi_get_icount(struct tty_struct *tty,
2314 struct serial_icounter_struct *icount)
2315{
2316 struct usb_serial_port *port = tty->driver_data;
2317 struct ftdi_private *priv = usb_get_serial_port_data(port);
2318 struct async_icount *ic = &priv->icount;
2319
2320 icount->cts = ic->cts;
2321 icount->dsr = ic->dsr;
2322 icount->rng = ic->rng;
2323 icount->dcd = ic->dcd;
2324 icount->tx = ic->tx;
2325 icount->rx = ic->rx;
2326 icount->frame = ic->frame;
2327 icount->parity = ic->parity;
2328 icount->overrun = ic->overrun;
2329 icount->brk = ic->brk;
2330 icount->buf_overrun = ic->buf_overrun;
2331 return 0;
2332}
2333
2280static int ftdi_ioctl(struct tty_struct *tty, 2334static int ftdi_ioctl(struct tty_struct *tty,
2281 unsigned int cmd, unsigned long arg) 2335 unsigned int cmd, unsigned long arg)
2282{ 2336{
2283 struct usb_serial_port *port = tty->driver_data; 2337 struct usb_serial_port *port = tty->driver_data;
2284 struct ftdi_private *priv = usb_get_serial_port_data(port); 2338 struct ftdi_private *priv = usb_get_serial_port_data(port);
2339 struct async_icount cnow;
2340 struct async_icount cprev;
2285 2341
2286 dbg("%s cmd 0x%04x", __func__, cmd); 2342 dbg("%s cmd 0x%04x", __func__, cmd);
2287 2343
@@ -2301,41 +2357,30 @@ static int ftdi_ioctl(struct tty_struct *tty,
2301 * - mask passed in arg for lines of interest 2357 * - mask passed in arg for lines of interest
2302 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) 2358 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
2303 * Caller should use TIOCGICOUNT to see which one it was. 2359 * Caller should use TIOCGICOUNT to see which one it was.
2304 * (except that the driver doesn't support it !)
2305 * 2360 *
2306 * This code is borrowed from linux/drivers/char/serial.c 2361 * This code is borrowed from linux/drivers/char/serial.c
2307 */ 2362 */
2308 case TIOCMIWAIT: 2363 case TIOCMIWAIT:
2309 while (priv != NULL) { 2364 cprev = priv->icount;
2365 while (1) {
2310 interruptible_sleep_on(&priv->delta_msr_wait); 2366 interruptible_sleep_on(&priv->delta_msr_wait);
2311 /* see if a signal did it */ 2367 /* see if a signal did it */
2312 if (signal_pending(current)) 2368 if (signal_pending(current))
2313 return -ERESTARTSYS; 2369 return -ERESTARTSYS;
2314 else { 2370 cnow = priv->icount;
2315 char diff = priv->diff_status; 2371 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2316 2372 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
2317 if (diff == 0) 2373 return -EIO; /* no change => error */
2318 return -EIO; /* no change => error */ 2374 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
2319 2375 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
2320 /* Consume all events */ 2376 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
2321 priv->diff_status = 0; 2377 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
2322 2378 return 0;
2323 /* Return 0 if caller wanted to know about
2324 these bits */
2325 if (((arg & TIOCM_RNG) && (diff & FTDI_RS0_RI)) ||
2326 ((arg & TIOCM_DSR) && (diff & FTDI_RS0_DSR)) ||
2327 ((arg & TIOCM_CD) && (diff & FTDI_RS0_RLSD)) ||
2328 ((arg & TIOCM_CTS) && (diff & FTDI_RS0_CTS))) {
2329 return 0;
2330 }
2331 /*
2332 * Otherwise caller can't care less about what
2333 * happened,and so we continue to wait for more
2334 * events.
2335 */
2336 } 2379 }
2380 cprev = cnow;
2337 } 2381 }
2338 return 0; 2382 /* not reached */
2383 break;
2339 case TIOCSERGETLSR: 2384 case TIOCSERGETLSR:
2340 return get_lsr_info(port, (struct serial_struct __user *)arg); 2385 return get_lsr_info(port, (struct serial_struct __user *)arg);
2341 break; 2386 break;