aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2009-10-07 14:05:07 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-10-09 16:52:05 -0400
commitcc01f17d5cb8ac604108515735aeca72e17944c1 (patch)
tree88f2dd91bf41f9a4b8881264ba0efdd2d64b9631 /drivers
parente63e278b4d2d867893962d3c7cd13a3a24ceb3f1 (diff)
USB: ftdi_sio: re-implement read processing
- Re-structure read processing. - Kill obsolete work queue and always push to tty in completion handler. - Use tty_insert_flip_string instead of per character push when possible. - Fix stalled-read regression in 2.6.31 by using urb status to determine when port is closed rather than port count. - Fix race with open/close by checking ASYNCB_INITIALIZED in unthrottle. - Kill private rx_flag and lock and use throttle flags in usb_serial_port instead. Signed-off-by: Johan Hovold <jhovold@gmail.com> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/serial/ftdi_sio.c383
1 files changed, 131 insertions, 252 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 75c84d9b080d..9c60d6d4908a 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -76,12 +76,7 @@ struct ftdi_private {
76 unsigned long last_dtr_rts; /* saved modem control outputs */ 76 unsigned long last_dtr_rts; /* saved modem control outputs */
77 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ 77 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
78 char prev_status, diff_status; /* Used for TIOCMIWAIT */ 78 char prev_status, diff_status; /* Used for TIOCMIWAIT */
79 __u8 rx_flags; /* receive state flags (throttling) */
80 spinlock_t rx_lock; /* spinlock for receive state */
81 struct delayed_work rx_work;
82 struct usb_serial_port *port; 79 struct usb_serial_port *port;
83 int rx_processed;
84
85 __u16 interface; /* FT2232C, FT2232H or FT4232H port interface 80 __u16 interface; /* FT2232C, FT2232H or FT4232H port interface
86 (0 for FT232/245) */ 81 (0 for FT232/245) */
87 82
@@ -736,10 +731,6 @@ static const char *ftdi_chip_name[] = {
736/* Constants for read urb and write urb */ 731/* Constants for read urb and write urb */
737#define BUFSZ 512 732#define BUFSZ 512
738 733
739/* rx_flags */
740#define THROTTLED 0x01
741#define ACTUALLY_THROTTLED 0x02
742
743/* Used for TIOCMIWAIT */ 734/* Used for TIOCMIWAIT */
744#define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) 735#define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD)
745#define FTDI_STATUS_B1_MASK (FTDI_RS_BI) 736#define FTDI_STATUS_B1_MASK (FTDI_RS_BI)
@@ -762,7 +753,7 @@ static int ftdi_write_room(struct tty_struct *tty);
762static int ftdi_chars_in_buffer(struct tty_struct *tty); 753static int ftdi_chars_in_buffer(struct tty_struct *tty);
763static void ftdi_write_bulk_callback(struct urb *urb); 754static void ftdi_write_bulk_callback(struct urb *urb);
764static void ftdi_read_bulk_callback(struct urb *urb); 755static void ftdi_read_bulk_callback(struct urb *urb);
765static void ftdi_process_read(struct work_struct *work); 756static void ftdi_process_read(struct usb_serial_port *port);
766static void ftdi_set_termios(struct tty_struct *tty, 757static void ftdi_set_termios(struct tty_struct *tty,
767 struct usb_serial_port *port, struct ktermios *old); 758 struct usb_serial_port *port, struct ktermios *old);
768static int ftdi_tiocmget(struct tty_struct *tty, struct file *file); 759static int ftdi_tiocmget(struct tty_struct *tty, struct file *file);
@@ -1525,7 +1516,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
1525 } 1516 }
1526 1517
1527 kref_init(&priv->kref); 1518 kref_init(&priv->kref);
1528 spin_lock_init(&priv->rx_lock);
1529 spin_lock_init(&priv->tx_lock); 1519 spin_lock_init(&priv->tx_lock);
1530 init_waitqueue_head(&priv->delta_msr_wait); 1520 init_waitqueue_head(&priv->delta_msr_wait);
1531 /* This will push the characters through immediately rather 1521 /* This will push the characters through immediately rather
@@ -1547,7 +1537,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
1547 port->read_urb->transfer_buffer_length = BUFSZ; 1537 port->read_urb->transfer_buffer_length = BUFSZ;
1548 } 1538 }
1549 1539
1550 INIT_DELAYED_WORK(&priv->rx_work, ftdi_process_read);
1551 priv->port = port; 1540 priv->port = port;
1552 1541
1553 /* Free port's existing write urb and transfer buffer. */ 1542 /* Free port's existing write urb and transfer buffer. */
@@ -1684,6 +1673,26 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
1684 return 0; 1673 return 0;
1685} 1674}
1686 1675
1676static int ftdi_submit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
1677{
1678 struct urb *urb = port->read_urb;
1679 struct usb_serial *serial = port->serial;
1680 int result;
1681
1682 usb_fill_bulk_urb(urb, serial->dev,
1683 usb_rcvbulkpipe(serial->dev,
1684 port->bulk_in_endpointAddress),
1685 urb->transfer_buffer,
1686 urb->transfer_buffer_length,
1687 ftdi_read_bulk_callback, port);
1688 result = usb_submit_urb(urb, mem_flags);
1689 if (result)
1690 dev_err(&port->dev,
1691 "%s - failed submitting read urb, error %d\n",
1692 __func__, result);
1693 return result;
1694}
1695
1687static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) 1696static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
1688{ /* ftdi_open */ 1697{ /* ftdi_open */
1689 struct usb_device *dev = port->serial->dev; 1698 struct usb_device *dev = port->serial->dev;
@@ -1717,23 +1726,14 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
1717 ftdi_set_termios(tty, port, tty->termios); 1726 ftdi_set_termios(tty, port, tty->termios);
1718 1727
1719 /* Not throttled */ 1728 /* Not throttled */
1720 spin_lock_irqsave(&priv->rx_lock, flags); 1729 spin_lock_irqsave(&port->lock, flags);
1721 priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); 1730 port->throttled = 0;
1722 spin_unlock_irqrestore(&priv->rx_lock, flags); 1731 port->throttle_req = 0;
1732 spin_unlock_irqrestore(&port->lock, flags);
1723 1733
1724 /* Start reading from the device */ 1734 /* Start reading from the device */
1725 priv->rx_processed = 0; 1735 result = ftdi_submit_read_urb(port, GFP_KERNEL);
1726 usb_fill_bulk_urb(port->read_urb, dev, 1736 if (!result)
1727 usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),
1728 port->read_urb->transfer_buffer,
1729 port->read_urb->transfer_buffer_length,
1730 ftdi_read_bulk_callback, port);
1731 result = usb_submit_urb(port->read_urb, GFP_KERNEL);
1732 if (result)
1733 dev_err(&port->dev,
1734 "%s - failed submitting read urb, error %d\n",
1735 __func__, result);
1736 else
1737 kref_get(&priv->kref); 1737 kref_get(&priv->kref);
1738 1738
1739 return result; 1739 return result;
@@ -1779,10 +1779,6 @@ static void ftdi_close(struct usb_serial_port *port)
1779 1779
1780 dbg("%s", __func__); 1780 dbg("%s", __func__);
1781 1781
1782
1783 /* cancel any scheduled reading */
1784 cancel_delayed_work_sync(&priv->rx_work);
1785
1786 /* shutdown our bulk read */ 1782 /* shutdown our bulk read */
1787 usb_kill_urb(port->read_urb); 1783 usb_kill_urb(port->read_urb);
1788 kref_put(&priv->kref, ftdi_sio_priv_release); 1784 kref_put(&priv->kref, ftdi_sio_priv_release);
@@ -2005,236 +2001,121 @@ static int ftdi_chars_in_buffer(struct tty_struct *tty)
2005 return buffered; 2001 return buffered;
2006} 2002}
2007 2003
2008static void ftdi_read_bulk_callback(struct urb *urb) 2004static int ftdi_process_packet(struct tty_struct *tty,
2005 struct usb_serial_port *port, struct ftdi_private *priv,
2006 char *packet, int len)
2009{ 2007{
2010 struct usb_serial_port *port = urb->context;
2011 struct ftdi_private *priv;
2012 int status = urb->status;
2013
2014 dbg("%s - port %d", __func__, port->number);
2015
2016 if (port->port.count <= 0)
2017 return;
2018
2019 if (status) {
2020 /* This will happen at close every time so it is a dbg not an
2021 err */
2022 dbg("(this is ok on close) nonzero read bulk status received: %d", status);
2023 goto out;
2024 }
2025
2026 priv = usb_get_serial_port_data(port);
2027 ftdi_process_read(&priv->rx_work.work);
2028} /* ftdi_read_bulk_callback */
2029
2030
2031static void ftdi_process_read(struct work_struct *work)
2032{ /* ftdi_process_read */
2033 struct ftdi_private *priv =
2034 container_of(work, struct ftdi_private, rx_work.work);
2035 struct usb_serial_port *port = priv->port;
2036 struct urb *urb;
2037 struct tty_struct *tty;
2038 char error_flag;
2039 unsigned char *data;
2040
2041 int i; 2008 int i;
2042 int result; 2009 char status;
2043 int need_flip; 2010 char flag;
2044 int packet_offset; 2011 char *ch;
2045 unsigned long flags;
2046 2012
2047 dbg("%s - port %d", __func__, port->number); 2013 dbg("%s - port %d", __func__, port->number);
2048 2014
2049 if (port->port.count <= 0) 2015 if (len < 2) {
2050 return; 2016 dbg("malformed packet");
2051 2017 return 0;
2052 tty = tty_port_tty_get(&port->port);
2053 if (!tty) {
2054 dbg("%s - bad tty pointer - exiting", __func__);
2055 return;
2056 } 2018 }
2057 2019
2058 priv = usb_get_serial_port_data(port); 2020 /* Compare new line status to the old one, signal if different/
2059 if (!priv) { 2021 N.B. packet may be processed more than once, but differences
2060 dbg("%s - bad port private data pointer - exiting", __func__); 2022 are only processed once. */
2061 goto out; 2023 status = packet[0] & FTDI_STATUS_B0_MASK;
2024 if (status != priv->prev_status) {
2025 priv->diff_status |= status ^ priv->prev_status;
2026 wake_up_interruptible(&priv->delta_msr_wait);
2027 priv->prev_status = status;
2062 } 2028 }
2063 2029
2064 urb = port->read_urb; 2030 /*
2065 if (!urb) { 2031 * Although the device uses a bitmask and hence can have multiple
2066 dbg("%s - bad read_urb pointer - exiting", __func__); 2032 * errors on a packet - the order here sets the priority the error is
2067 goto out; 2033 * returned to the tty layer.
2034 */
2035 flag = TTY_NORMAL;
2036 if (packet[1] & FTDI_RS_OE) {
2037 flag = TTY_OVERRUN;
2038 dbg("OVERRRUN error");
2068 } 2039 }
2069 2040 if (packet[1] & FTDI_RS_BI) {
2070 data = urb->transfer_buffer; 2041 flag = TTY_BREAK;
2071 2042 dbg("BREAK received");
2072 if (priv->rx_processed) { 2043 usb_serial_handle_break(port);
2073 dbg("%s - already processed: %d bytes, %d remain", __func__, 2044 }
2074 priv->rx_processed, 2045 if (packet[1] & FTDI_RS_PE) {
2075 urb->actual_length - priv->rx_processed); 2046 flag = TTY_PARITY;
2076 } else { 2047 dbg("PARITY error");
2077 /* The first two bytes of every read packet are status */ 2048 }
2078 if (urb->actual_length > 2) 2049 if (packet[1] & FTDI_RS_FE) {
2079 usb_serial_debug_data(debug, &port->dev, __func__, 2050 flag = TTY_FRAME;
2080 urb->actual_length, data); 2051 dbg("FRAMING error");
2081 else
2082 dbg("Status only: %03oo %03oo", data[0], data[1]);
2083 } 2052 }
2084 2053
2085 2054 len -= 2;
2086 /* TO DO -- check for hung up line and handle appropriately: */ 2055 if (!len)
2087 /* send hangup */ 2056 return 0; /* status only */
2088 /* See acm.c - you do a tty_hangup - eg tty_hangup(tty) */ 2057 ch = packet + 2;
2089 /* if CD is dropped and the line is not CLOCAL then we should hangup */ 2058
2090 2059 if (!(port->console && port->sysrq) && flag == TTY_NORMAL)
2091 need_flip = 0; 2060 tty_insert_flip_string(tty, ch, len);
2092 for (packet_offset = priv->rx_processed; 2061 else {
2093 packet_offset < urb->actual_length; packet_offset += priv->max_packet_size) { 2062 for (i = 0; i < len; i++, ch++) {
2094 int length; 2063 if (!usb_serial_handle_sysrq_char(tty, port, *ch))
2095 2064 tty_insert_flip_char(tty, *ch, flag);
2096 /* Compare new line status to the old one, signal if different/
2097 N.B. packet may be processed more than once, but differences
2098 are only processed once. */
2099 char new_status = data[packet_offset + 0] &
2100 FTDI_STATUS_B0_MASK;
2101 if (new_status != priv->prev_status) {
2102 priv->diff_status |=
2103 new_status ^ priv->prev_status;
2104 wake_up_interruptible(&priv->delta_msr_wait);
2105 priv->prev_status = new_status;
2106 }
2107
2108 length = min_t(u32, priv->max_packet_size, urb->actual_length-packet_offset)-2;
2109 if (length < 0) {
2110 dev_err(&port->dev, "%s - bad packet length: %d\n",
2111 __func__, length+2);
2112 length = 0;
2113 }
2114
2115 if (priv->rx_flags & THROTTLED) {
2116 dbg("%s - throttled", __func__);
2117 break;
2118 }
2119 if (tty_buffer_request_room(tty, length) < length) {
2120 /* break out & wait for throttling/unthrottling to
2121 happen */
2122 dbg("%s - receive room low", __func__);
2123 break;
2124 } 2065 }
2066 }
2067 return len;
2068}
2125 2069
2126 /* Handle errors and break */ 2070static void ftdi_process_read(struct usb_serial_port *port)
2127 error_flag = TTY_NORMAL; 2071{
2128 /* Although the device uses a bitmask and hence can have 2072 struct urb *urb = port->read_urb;
2129 multiple errors on a packet - the order here sets the 2073 struct tty_struct *tty;
2130 priority the error is returned to the tty layer */ 2074 struct ftdi_private *priv = usb_get_serial_port_data(port);
2075 char *data = (char *)urb->transfer_buffer;
2076 int i;
2077 int len;
2078 int count = 0;
2131 2079
2132 if (data[packet_offset+1] & FTDI_RS_OE) { 2080 tty = tty_port_tty_get(&port->port);
2133 error_flag = TTY_OVERRUN; 2081 if (!tty)
2134 dbg("OVERRRUN error"); 2082 return;
2135 }
2136 if (data[packet_offset+1] & FTDI_RS_BI) {
2137 error_flag = TTY_BREAK;
2138 dbg("BREAK received");
2139 usb_serial_handle_break(port);
2140 }
2141 if (data[packet_offset+1] & FTDI_RS_PE) {
2142 error_flag = TTY_PARITY;
2143 dbg("PARITY error");
2144 }
2145 if (data[packet_offset+1] & FTDI_RS_FE) {
2146 error_flag = TTY_FRAME;
2147 dbg("FRAMING error");
2148 }
2149 if (length > 0) {
2150 for (i = 2; i < length+2; i++) {
2151 /* Note that the error flag is duplicated for
2152 every character received since we don't know
2153 which character it applied to */
2154 if (!usb_serial_handle_sysrq_char(tty, port,
2155 data[packet_offset + i]))
2156 tty_insert_flip_char(tty,
2157 data[packet_offset + i],
2158 error_flag);
2159 }
2160 need_flip = 1;
2161 }
2162 2083
2163#ifdef NOT_CORRECT_BUT_KEEPING_IT_FOR_NOW 2084 for (i = 0; i < urb->actual_length; i += priv->max_packet_size) {
2164 /* if a parity error is detected you get status packets forever 2085 len = min_t(int, urb->actual_length - i, priv->max_packet_size);
2165 until a character is sent without a parity error. 2086 count += ftdi_process_packet(tty, port, priv, &data[i], len);
2166 This doesn't work well since the application receives a 2087 }
2167 never ending stream of bad data - even though new data
2168 hasn't been sent. Therefore I (bill) have taken this out.
2169 However - this might make sense for framing errors and so on
2170 so I am leaving the code in for now.
2171 */
2172 else {
2173 if (error_flag != TTY_NORMAL) {
2174 dbg("error_flag is not normal");
2175 /* In this case it is just status - if that is
2176 an error send a bad character */
2177 if (tty->flip.count >= TTY_FLIPBUF_SIZE)
2178 tty_flip_buffer_push(tty);
2179 tty_insert_flip_char(tty, 0xff, error_flag);
2180 need_flip = 1;
2181 }
2182 }
2183#endif
2184 } /* "for(packet_offset=0..." */
2185 2088
2186 /* Low latency */ 2089 if (count)
2187 if (need_flip)
2188 tty_flip_buffer_push(tty); 2090 tty_flip_buffer_push(tty);
2091 tty_kref_put(tty);
2092}
2189 2093
2190 if (packet_offset < urb->actual_length) { 2094static void ftdi_read_bulk_callback(struct urb *urb)
2191 /* not completely processed - record progress */ 2095{
2192 priv->rx_processed = packet_offset; 2096 struct usb_serial_port *port = urb->context;
2193 dbg("%s - incomplete, %d bytes processed, %d remain", 2097 unsigned long flags;
2194 __func__, packet_offset,
2195 urb->actual_length - packet_offset);
2196 /* check if we were throttled while processing */
2197 spin_lock_irqsave(&priv->rx_lock, flags);
2198 if (priv->rx_flags & THROTTLED) {
2199 priv->rx_flags |= ACTUALLY_THROTTLED;
2200 spin_unlock_irqrestore(&priv->rx_lock, flags);
2201 dbg("%s - deferring remainder until unthrottled",
2202 __func__);
2203 goto out;
2204 }
2205 spin_unlock_irqrestore(&priv->rx_lock, flags);
2206 /* if the port is closed stop trying to read */
2207 if (port->port.count > 0)
2208 /* delay processing of remainder */
2209 schedule_delayed_work(&priv->rx_work, 1);
2210 else
2211 dbg("%s - port is closed", __func__);
2212 goto out;
2213 }
2214
2215 /* urb is completely processed */
2216 priv->rx_processed = 0;
2217 2098
2218 /* if the port is closed stop trying to read */ 2099 dbg("%s - port %d", __func__, port->number);
2219 if (port->port.count > 0) {
2220 /* Continue trying to always read */
2221 usb_fill_bulk_urb(port->read_urb, port->serial->dev,
2222 usb_rcvbulkpipe(port->serial->dev,
2223 port->bulk_in_endpointAddress),
2224 port->read_urb->transfer_buffer,
2225 port->read_urb->transfer_buffer_length,
2226 ftdi_read_bulk_callback, port);
2227 2100
2228 result = usb_submit_urb(port->read_urb, GFP_ATOMIC); 2101 if (urb->status) {
2229 if (result) 2102 dbg("%s - nonzero read bulk status received: %d",
2230 dev_err(&port->dev, 2103 __func__, urb->status);
2231 "%s - failed resubmitting read urb, error %d\n", 2104 return;
2232 __func__, result);
2233 } 2105 }
2234out:
2235 tty_kref_put(tty);
2236} /* ftdi_process_read */
2237 2106
2107 usb_serial_debug_data(debug, &port->dev, __func__,
2108 urb->actual_length, urb->transfer_buffer);
2109 ftdi_process_read(port);
2110
2111 spin_lock_irqsave(&port->lock, flags);
2112 port->throttled = port->throttle_req;
2113 if (!port->throttled) {
2114 spin_unlock_irqrestore(&port->lock, flags);
2115 ftdi_submit_read_urb(port, GFP_ATOMIC);
2116 } else
2117 spin_unlock_irqrestore(&port->lock, flags);
2118}
2238 2119
2239static void ftdi_break_ctl(struct tty_struct *tty, int break_state) 2120static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
2240{ 2121{
@@ -2566,33 +2447,31 @@ static int ftdi_ioctl(struct tty_struct *tty, struct file *file,
2566static void ftdi_throttle(struct tty_struct *tty) 2447static void ftdi_throttle(struct tty_struct *tty)
2567{ 2448{
2568 struct usb_serial_port *port = tty->driver_data; 2449 struct usb_serial_port *port = tty->driver_data;
2569 struct ftdi_private *priv = usb_get_serial_port_data(port);
2570 unsigned long flags; 2450 unsigned long flags;
2571 2451
2572 dbg("%s - port %d", __func__, port->number); 2452 dbg("%s - port %d", __func__, port->number);
2573 2453
2574 spin_lock_irqsave(&priv->rx_lock, flags); 2454 spin_lock_irqsave(&port->lock, flags);
2575 priv->rx_flags |= THROTTLED; 2455 port->throttle_req = 1;
2576 spin_unlock_irqrestore(&priv->rx_lock, flags); 2456 spin_unlock_irqrestore(&port->lock, flags);
2577} 2457}
2578 2458
2579 2459void ftdi_unthrottle(struct tty_struct *tty)
2580static void ftdi_unthrottle(struct tty_struct *tty)
2581{ 2460{
2582 struct usb_serial_port *port = tty->driver_data; 2461 struct usb_serial_port *port = tty->driver_data;
2583 struct ftdi_private *priv = usb_get_serial_port_data(port); 2462 int was_throttled;
2584 int actually_throttled;
2585 unsigned long flags; 2463 unsigned long flags;
2586 2464
2587 dbg("%s - port %d", __func__, port->number); 2465 dbg("%s - port %d", __func__, port->number);
2588 2466
2589 spin_lock_irqsave(&priv->rx_lock, flags); 2467 spin_lock_irqsave(&port->lock, flags);
2590 actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; 2468 was_throttled = port->throttled;
2591 priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); 2469 port->throttled = port->throttle_req = 0;
2592 spin_unlock_irqrestore(&priv->rx_lock, flags); 2470 spin_unlock_irqrestore(&port->lock, flags);
2593 2471
2594 if (actually_throttled) 2472 /* Resubmit urb if throttled and open. */
2595 schedule_delayed_work(&priv->rx_work, 0); 2473 if (was_throttled && test_bit(ASYNCB_INITIALIZED, &port->port.flags))
2474 ftdi_submit_read_urb(port, GFP_KERNEL);
2596} 2475}
2597 2476
2598static int __init ftdi_init(void) 2477static int __init ftdi_init(void)