diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2009-10-08 11:04:13 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-10-08 11:04:13 -0700 |
| commit | d45b8296a27902697867a18f638e846c84985cb0 (patch) | |
| tree | 6137eaa4cfbf78d6de99716ccabb9fe919dbe60e /usb.current | |
| parent | 5ac84e99a60c34d072b93427ce362057e7f6c518 (diff) | |
| download | patches-d45b8296a27902697867a18f638e846c84985cb0.tar.gz | |
staging patches and other fixes
Diffstat (limited to 'usb.current')
4 files changed, 706 insertions, 0 deletions
diff --git a/usb.current/usb-ftdi_sio-clean-up-read-completion-handler.patch b/usb.current/usb-ftdi_sio-clean-up-read-completion-handler.patch new file mode 100644 index 00000000000000..6468726c5d914f --- /dev/null +++ b/usb.current/usb-ftdi_sio-clean-up-read-completion-handler.patch @@ -0,0 +1,81 @@ +From jhovold@gmail.com Thu Oct 8 09:54:30 2009 +From: Johan Hovold <jhovold@gmail.com> +Date: Wed, 7 Oct 2009 20:05:06 +0200 +Subject: USB: ftdi_sio: clean up read completion handler +To: Greg Kroah-Hartman <gregkh@suse.de>, Alan Cox <alan@linux.intel.com> +Cc: Oliver Neukum <oliver@neukum.org>, Alan Stern <stern@rowland.harvard.edu>, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Johan Hovold <jhovold@gmail.com> +Message-ID: <1254938707-6996-4-git-send-email-jhovold@gmail.com> + + +Remove superfluous error checks in completion handler: + + - No need to check private data and urb pointers as we check urb-status + before dereferencing priv (which is not freed until urb has been killed + on close). + - No need to check tty as it is checked again when processing. + - No need to check urb->number_of_packets on bulk urb. + +Note that both private data and tty are checked again before processing +(possibly from work queue which also is cancelled on close). + +Signed-off-by: Johan Hovold <jhovold@gmail.com> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/ftdi_sio.c | 28 +--------------------------- + 1 file changed, 1 insertion(+), 27 deletions(-) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -2008,39 +2008,14 @@ static int ftdi_chars_in_buffer(struct t + static void ftdi_read_bulk_callback(struct urb *urb) + { + struct usb_serial_port *port = urb->context; +- struct tty_struct *tty; + struct ftdi_private *priv; + int status = urb->status; + +- if (urb->number_of_packets > 0) { +- dev_err(&port->dev, "%s transfer_buffer_length %d " +- "actual_length %d number of packets %d\n", __func__, +- urb->transfer_buffer_length, +- urb->actual_length, urb->number_of_packets); +- dev_err(&port->dev, "%s transfer_flags %x\n", __func__, +- urb->transfer_flags); +- } +- + dbg("%s - port %d", __func__, port->number); + + if (port->port.count <= 0) + return; + +- tty = tty_port_tty_get(&port->port); +- if (!tty) { +- dbg("%s - bad tty pointer - exiting", __func__); +- return; +- } +- +- priv = usb_get_serial_port_data(port); +- if (!priv) { +- dbg("%s - bad port private data pointer - exiting", __func__); +- goto out; +- } +- +- if (urb != port->read_urb) +- dev_err(&port->dev, "%s - Not my urb!\n", __func__); +- + if (status) { + /* This will happen at close every time so it is a dbg not an + err */ +@@ -2048,9 +2023,8 @@ static void ftdi_read_bulk_callback(stru + goto out; + } + ++ priv = usb_get_serial_port_data(port); + ftdi_process_read(&priv->rx_work.work); +-out: +- tty_kref_put(tty); + } /* ftdi_read_bulk_callback */ + + diff --git a/usb.current/usb-ftdi_sio-re-implement-read-processing.patch b/usb.current/usb-ftdi_sio-re-implement-read-processing.patch new file mode 100644 index 00000000000000..c3b66b67ab14b2 --- /dev/null +++ b/usb.current/usb-ftdi_sio-re-implement-read-processing.patch @@ -0,0 +1,522 @@ +From jhovold@gmail.com Thu Oct 8 09:54:58 2009 +From: Johan Hovold <jhovold@gmail.com> +Date: Wed, 7 Oct 2009 20:05:07 +0200 +Subject: USB: ftdi_sio: re-implement read processing +To: Greg Kroah-Hartman <gregkh@suse.de>, Alan Cox <alan@linux.intel.com> +Cc: Oliver Neukum <oliver@neukum.org>, Alan Stern <stern@rowland.harvard.edu>, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Johan Hovold <jhovold@gmail.com> +Message-ID: <1254938707-6996-5-git-send-email-jhovold@gmail.com> + + + - 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> + +--- + drivers/usb/serial/ftdi_sio.c | 383 ++++++++++++++---------------------------- + 1 file changed, 131 insertions(+), 252 deletions(-) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -76,12 +76,7 @@ struct ftdi_private { + unsigned long last_dtr_rts; /* saved modem control outputs */ + wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ + char prev_status, diff_status; /* Used for TIOCMIWAIT */ +- __u8 rx_flags; /* receive state flags (throttling) */ +- spinlock_t rx_lock; /* spinlock for receive state */ +- struct delayed_work rx_work; + struct usb_serial_port *port; +- int rx_processed; +- + __u16 interface; /* FT2232C, FT2232H or FT4232H port interface + (0 for FT232/245) */ + +@@ -736,10 +731,6 @@ static const char *ftdi_chip_name[] = { + /* Constants for read urb and write urb */ + #define BUFSZ 512 + +-/* rx_flags */ +-#define THROTTLED 0x01 +-#define ACTUALLY_THROTTLED 0x02 +- + /* Used for TIOCMIWAIT */ + #define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) + #define FTDI_STATUS_B1_MASK (FTDI_RS_BI) +@@ -762,7 +753,7 @@ static int ftdi_write_room(struct tty_s + static int ftdi_chars_in_buffer(struct tty_struct *tty); + static void ftdi_write_bulk_callback(struct urb *urb); + static void ftdi_read_bulk_callback(struct urb *urb); +-static void ftdi_process_read(struct work_struct *work); ++static void ftdi_process_read(struct usb_serial_port *port); + static void ftdi_set_termios(struct tty_struct *tty, + struct usb_serial_port *port, struct ktermios *old); + static int ftdi_tiocmget(struct tty_struct *tty, struct file *file); +@@ -1525,7 +1516,6 @@ static int ftdi_sio_port_probe(struct us + } + + kref_init(&priv->kref); +- spin_lock_init(&priv->rx_lock); + spin_lock_init(&priv->tx_lock); + init_waitqueue_head(&priv->delta_msr_wait); + /* This will push the characters through immediately rather +@@ -1547,7 +1537,6 @@ static int ftdi_sio_port_probe(struct us + port->read_urb->transfer_buffer_length = BUFSZ; + } + +- INIT_DELAYED_WORK(&priv->rx_work, ftdi_process_read); + priv->port = port; + + /* Free port's existing write urb and transfer buffer. */ +@@ -1684,6 +1673,26 @@ static int ftdi_sio_port_remove(struct u + return 0; + } + ++static int ftdi_submit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) ++{ ++ struct urb *urb = port->read_urb; ++ struct usb_serial *serial = port->serial; ++ int result; ++ ++ usb_fill_bulk_urb(urb, serial->dev, ++ usb_rcvbulkpipe(serial->dev, ++ port->bulk_in_endpointAddress), ++ urb->transfer_buffer, ++ urb->transfer_buffer_length, ++ ftdi_read_bulk_callback, port); ++ result = usb_submit_urb(urb, mem_flags); ++ if (result) ++ dev_err(&port->dev, ++ "%s - failed submitting read urb, error %d\n", ++ __func__, result); ++ return result; ++} ++ + static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) + { /* ftdi_open */ + struct usb_device *dev = port->serial->dev; +@@ -1717,23 +1726,14 @@ static int ftdi_open(struct tty_struct * + ftdi_set_termios(tty, port, tty->termios); + + /* Not throttled */ +- spin_lock_irqsave(&priv->rx_lock, flags); +- priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); +- spin_unlock_irqrestore(&priv->rx_lock, flags); ++ spin_lock_irqsave(&port->lock, flags); ++ port->throttled = 0; ++ port->throttle_req = 0; ++ spin_unlock_irqrestore(&port->lock, flags); + + /* Start reading from the device */ +- priv->rx_processed = 0; +- usb_fill_bulk_urb(port->read_urb, dev, +- usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress), +- port->read_urb->transfer_buffer, +- port->read_urb->transfer_buffer_length, +- ftdi_read_bulk_callback, port); +- result = usb_submit_urb(port->read_urb, GFP_KERNEL); +- if (result) +- dev_err(&port->dev, +- "%s - failed submitting read urb, error %d\n", +- __func__, result); +- else ++ result = ftdi_submit_read_urb(port, GFP_KERNEL); ++ if (!result) + kref_get(&priv->kref); + + return result; +@@ -1779,10 +1779,6 @@ static void ftdi_close(struct usb_serial + + dbg("%s", __func__); + +- +- /* cancel any scheduled reading */ +- cancel_delayed_work_sync(&priv->rx_work); +- + /* shutdown our bulk read */ + usb_kill_urb(port->read_urb); + kref_put(&priv->kref, ftdi_sio_priv_release); +@@ -2005,236 +2001,121 @@ static int ftdi_chars_in_buffer(struct t + return buffered; + } + +-static void ftdi_read_bulk_callback(struct urb *urb) ++static int ftdi_process_packet(struct tty_struct *tty, ++ struct usb_serial_port *port, struct ftdi_private *priv, ++ char *packet, int len) + { +- struct usb_serial_port *port = urb->context; +- struct ftdi_private *priv; +- int status = urb->status; +- +- dbg("%s - port %d", __func__, port->number); +- +- if (port->port.count <= 0) +- return; +- +- if (status) { +- /* This will happen at close every time so it is a dbg not an +- err */ +- dbg("(this is ok on close) nonzero read bulk status received: %d", status); +- goto out; +- } +- +- priv = usb_get_serial_port_data(port); +- ftdi_process_read(&priv->rx_work.work); +-} /* ftdi_read_bulk_callback */ +- +- +-static void ftdi_process_read(struct work_struct *work) +-{ /* ftdi_process_read */ +- struct ftdi_private *priv = +- container_of(work, struct ftdi_private, rx_work.work); +- struct usb_serial_port *port = priv->port; +- struct urb *urb; +- struct tty_struct *tty; +- char error_flag; +- unsigned char *data; +- + int i; +- int result; +- int need_flip; +- int packet_offset; +- unsigned long flags; ++ char status; ++ char flag; ++ char *ch; + + dbg("%s - port %d", __func__, port->number); + +- if (port->port.count <= 0) +- return; +- +- tty = tty_port_tty_get(&port->port); +- if (!tty) { +- dbg("%s - bad tty pointer - exiting", __func__); +- return; ++ if (len < 2) { ++ dbg("malformed packet"); ++ return 0; + } + +- priv = usb_get_serial_port_data(port); +- if (!priv) { +- dbg("%s - bad port private data pointer - exiting", __func__); +- goto out; ++ /* Compare new line status to the old one, signal if different/ ++ N.B. packet may be processed more than once, but differences ++ are only processed once. */ ++ status = packet[0] & FTDI_STATUS_B0_MASK; ++ if (status != priv->prev_status) { ++ priv->diff_status |= status ^ priv->prev_status; ++ wake_up_interruptible(&priv->delta_msr_wait); ++ priv->prev_status = status; + } + +- urb = port->read_urb; +- if (!urb) { +- dbg("%s - bad read_urb pointer - exiting", __func__); +- goto out; ++ /* ++ * Although the device uses a bitmask and hence can have multiple ++ * errors on a packet - the order here sets the priority the error is ++ * returned to the tty layer. ++ */ ++ flag = TTY_NORMAL; ++ if (packet[1] & FTDI_RS_OE) { ++ flag = TTY_OVERRUN; ++ dbg("OVERRRUN error"); + } +- +- data = urb->transfer_buffer; +- +- if (priv->rx_processed) { +- dbg("%s - already processed: %d bytes, %d remain", __func__, +- priv->rx_processed, +- urb->actual_length - priv->rx_processed); +- } else { +- /* The first two bytes of every read packet are status */ +- if (urb->actual_length > 2) +- usb_serial_debug_data(debug, &port->dev, __func__, +- urb->actual_length, data); +- else +- dbg("Status only: %03oo %03oo", data[0], data[1]); ++ if (packet[1] & FTDI_RS_BI) { ++ flag = TTY_BREAK; ++ dbg("BREAK received"); ++ usb_serial_handle_break(port); ++ } ++ if (packet[1] & FTDI_RS_PE) { ++ flag = TTY_PARITY; ++ dbg("PARITY error"); ++ } ++ if (packet[1] & FTDI_RS_FE) { ++ flag = TTY_FRAME; ++ dbg("FRAMING error"); + } + ++ len -= 2; ++ if (!len) ++ return 0; /* status only */ ++ ch = packet + 2; + +- /* TO DO -- check for hung up line and handle appropriately: */ +- /* send hangup */ +- /* See acm.c - you do a tty_hangup - eg tty_hangup(tty) */ +- /* if CD is dropped and the line is not CLOCAL then we should hangup */ +- +- need_flip = 0; +- for (packet_offset = priv->rx_processed; +- packet_offset < urb->actual_length; packet_offset += priv->max_packet_size) { +- int length; +- +- /* Compare new line status to the old one, signal if different/ +- N.B. packet may be processed more than once, but differences +- are only processed once. */ +- char new_status = data[packet_offset + 0] & +- FTDI_STATUS_B0_MASK; +- if (new_status != priv->prev_status) { +- priv->diff_status |= +- new_status ^ priv->prev_status; +- wake_up_interruptible(&priv->delta_msr_wait); +- priv->prev_status = new_status; +- } +- +- length = min_t(u32, priv->max_packet_size, urb->actual_length-packet_offset)-2; +- if (length < 0) { +- dev_err(&port->dev, "%s - bad packet length: %d\n", +- __func__, length+2); +- length = 0; ++ if (!(port->console && port->sysrq) && flag == TTY_NORMAL) ++ tty_insert_flip_string(tty, ch, len); ++ else { ++ for (i = 0; i < len; i++, ch++) { ++ if (!usb_serial_handle_sysrq_char(tty, port, *ch)) ++ tty_insert_flip_char(tty, *ch, flag); + } ++ } ++ return len; ++} + +- if (priv->rx_flags & THROTTLED) { +- dbg("%s - throttled", __func__); +- break; +- } +- if (tty_buffer_request_room(tty, length) < length) { +- /* break out & wait for throttling/unthrottling to +- happen */ +- dbg("%s - receive room low", __func__); +- break; +- } ++static void ftdi_process_read(struct usb_serial_port *port) ++{ ++ struct urb *urb = port->read_urb; ++ struct tty_struct *tty; ++ struct ftdi_private *priv = usb_get_serial_port_data(port); ++ char *data = (char *)urb->transfer_buffer; ++ int i; ++ int len; ++ int count = 0; + +- /* Handle errors and break */ +- error_flag = TTY_NORMAL; +- /* Although the device uses a bitmask and hence can have +- multiple errors on a packet - the order here sets the +- priority the error is returned to the tty layer */ +- +- if (data[packet_offset+1] & FTDI_RS_OE) { +- error_flag = TTY_OVERRUN; +- dbg("OVERRRUN error"); +- } +- if (data[packet_offset+1] & FTDI_RS_BI) { +- error_flag = TTY_BREAK; +- dbg("BREAK received"); +- usb_serial_handle_break(port); +- } +- if (data[packet_offset+1] & FTDI_RS_PE) { +- error_flag = TTY_PARITY; +- dbg("PARITY error"); +- } +- if (data[packet_offset+1] & FTDI_RS_FE) { +- error_flag = TTY_FRAME; +- dbg("FRAMING error"); +- } +- if (length > 0) { +- for (i = 2; i < length+2; i++) { +- /* Note that the error flag is duplicated for +- every character received since we don't know +- which character it applied to */ +- if (!usb_serial_handle_sysrq_char(tty, port, +- data[packet_offset + i])) +- tty_insert_flip_char(tty, +- data[packet_offset + i], +- error_flag); +- } +- need_flip = 1; +- } ++ tty = tty_port_tty_get(&port->port); ++ if (!tty) ++ return; + +-#ifdef NOT_CORRECT_BUT_KEEPING_IT_FOR_NOW +- /* if a parity error is detected you get status packets forever +- until a character is sent without a parity error. +- This doesn't work well since the application receives a +- never ending stream of bad data - even though new data +- hasn't been sent. Therefore I (bill) have taken this out. +- However - this might make sense for framing errors and so on +- so I am leaving the code in for now. +- */ +- else { +- if (error_flag != TTY_NORMAL) { +- dbg("error_flag is not normal"); +- /* In this case it is just status - if that is +- an error send a bad character */ +- if (tty->flip.count >= TTY_FLIPBUF_SIZE) +- tty_flip_buffer_push(tty); +- tty_insert_flip_char(tty, 0xff, error_flag); +- need_flip = 1; +- } +- } +-#endif +- } /* "for(packet_offset=0..." */ ++ for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { ++ len = min_t(int, urb->actual_length - i, priv->max_packet_size); ++ count += ftdi_process_packet(tty, port, priv, &data[i], len); ++ } + +- /* Low latency */ +- if (need_flip) ++ if (count) + tty_flip_buffer_push(tty); ++ tty_kref_put(tty); ++} + +- if (packet_offset < urb->actual_length) { +- /* not completely processed - record progress */ +- priv->rx_processed = packet_offset; +- dbg("%s - incomplete, %d bytes processed, %d remain", +- __func__, packet_offset, +- urb->actual_length - packet_offset); +- /* check if we were throttled while processing */ +- spin_lock_irqsave(&priv->rx_lock, flags); +- if (priv->rx_flags & THROTTLED) { +- priv->rx_flags |= ACTUALLY_THROTTLED; +- spin_unlock_irqrestore(&priv->rx_lock, flags); +- dbg("%s - deferring remainder until unthrottled", +- __func__); +- goto out; +- } +- spin_unlock_irqrestore(&priv->rx_lock, flags); +- /* if the port is closed stop trying to read */ +- if (port->port.count > 0) +- /* delay processing of remainder */ +- schedule_delayed_work(&priv->rx_work, 1); +- else +- dbg("%s - port is closed", __func__); +- goto out; +- } +- +- /* urb is completely processed */ +- priv->rx_processed = 0; ++static void ftdi_read_bulk_callback(struct urb *urb) ++{ ++ struct usb_serial_port *port = urb->context; ++ unsigned long flags; + +- /* if the port is closed stop trying to read */ +- if (port->port.count > 0) { +- /* Continue trying to always read */ +- usb_fill_bulk_urb(port->read_urb, port->serial->dev, +- usb_rcvbulkpipe(port->serial->dev, +- port->bulk_in_endpointAddress), +- port->read_urb->transfer_buffer, +- port->read_urb->transfer_buffer_length, +- ftdi_read_bulk_callback, port); ++ dbg("%s - port %d", __func__, port->number); + +- result = usb_submit_urb(port->read_urb, GFP_ATOMIC); +- if (result) +- dev_err(&port->dev, +- "%s - failed resubmitting read urb, error %d\n", +- __func__, result); ++ if (urb->status) { ++ dbg("%s - nonzero read bulk status received: %d", ++ __func__, urb->status); ++ return; + } +-out: +- tty_kref_put(tty); +-} /* ftdi_process_read */ + ++ usb_serial_debug_data(debug, &port->dev, __func__, ++ urb->actual_length, urb->transfer_buffer); ++ ftdi_process_read(port); ++ ++ spin_lock_irqsave(&port->lock, flags); ++ port->throttled = port->throttle_req; ++ if (!port->throttled) { ++ spin_unlock_irqrestore(&port->lock, flags); ++ ftdi_submit_read_urb(port, GFP_ATOMIC); ++ } else ++ spin_unlock_irqrestore(&port->lock, flags); ++} + + static void ftdi_break_ctl(struct tty_struct *tty, int break_state) + { +@@ -2566,33 +2447,31 @@ static int ftdi_ioctl(struct tty_struct + static void ftdi_throttle(struct tty_struct *tty) + { + struct usb_serial_port *port = tty->driver_data; +- struct ftdi_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + + dbg("%s - port %d", __func__, port->number); + +- spin_lock_irqsave(&priv->rx_lock, flags); +- priv->rx_flags |= THROTTLED; +- spin_unlock_irqrestore(&priv->rx_lock, flags); ++ spin_lock_irqsave(&port->lock, flags); ++ port->throttle_req = 1; ++ spin_unlock_irqrestore(&port->lock, flags); + } + +- +-static void ftdi_unthrottle(struct tty_struct *tty) ++void ftdi_unthrottle(struct tty_struct *tty) + { + struct usb_serial_port *port = tty->driver_data; +- struct ftdi_private *priv = usb_get_serial_port_data(port); +- int actually_throttled; ++ int was_throttled; + unsigned long flags; + + dbg("%s - port %d", __func__, port->number); + +- spin_lock_irqsave(&priv->rx_lock, flags); +- actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; +- priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); +- spin_unlock_irqrestore(&priv->rx_lock, flags); +- +- if (actually_throttled) +- schedule_delayed_work(&priv->rx_work, 0); ++ spin_lock_irqsave(&port->lock, flags); ++ was_throttled = port->throttled; ++ port->throttled = port->throttle_req = 0; ++ spin_unlock_irqrestore(&port->lock, flags); ++ ++ /* Resubmit urb if throttled and open. */ ++ if (was_throttled && test_bit(ASYNCB_INITIALIZED, &port->port.flags)) ++ ftdi_submit_read_urb(port, GFP_KERNEL); + } + + static int __init ftdi_init(void) diff --git a/usb.current/usb-ftdi_sio-remove-tty-low_latency.patch b/usb.current/usb-ftdi_sio-remove-tty-low_latency.patch new file mode 100644 index 00000000000000..d439b44e691d7f --- /dev/null +++ b/usb.current/usb-ftdi_sio-remove-tty-low_latency.patch @@ -0,0 +1,40 @@ +From jhovold@gmail.com Thu Oct 8 09:53:57 2009 +From: Johan Hovold <jhovold@gmail.com> +Date: Wed, 7 Oct 2009 20:05:04 +0200 +Subject: USB: ftdi_sio: remove tty->low_latency +To: Greg Kroah-Hartman <gregkh@suse.de>, Alan Cox <alan@linux.intel.com> +Cc: Oliver Neukum <oliver@neukum.org>, Alan Stern <stern@rowland.harvard.edu>, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Johan Hovold <jhovold@gmail.com> +Message-ID: <1254938707-6996-2-git-send-email-jhovold@gmail.com> + + +Fixes tty_flip_buffer_push being called from hard interrupt context with +low_latency set. + +Signed-off-by: Johan Hovold <jhovold@gmail.com> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/ftdi_sio.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1234,7 +1234,6 @@ static int set_serial_info(struct tty_st + (new_serial.flags & ASYNC_FLAGS)); + priv->custom_divisor = new_serial.custom_divisor; + +- tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + write_latency_timer(port); + + check_and_exit: +@@ -1704,9 +1703,6 @@ static int ftdi_open(struct tty_struct * + priv->rx_bytes = 0; + spin_unlock_irqrestore(&priv->rx_lock, flags); + +- if (tty) +- tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; +- + write_latency_timer(port); + + /* No error checking for this (will get errors later anyway) */ diff --git a/usb.current/usb-ftdi_sio-remove-unused-rx_byte-counter.patch b/usb.current/usb-ftdi_sio-remove-unused-rx_byte-counter.patch new file mode 100644 index 00000000000000..3fb8440747317f --- /dev/null +++ b/usb.current/usb-ftdi_sio-remove-unused-rx_byte-counter.patch @@ -0,0 +1,63 @@ +From jhovold@gmail.com Thu Oct 8 09:54:15 2009 +From: Johan Hovold <jhovold@gmail.com> +Date: Wed, 7 Oct 2009 20:05:05 +0200 +Subject: USB: ftdi_sio: remove unused rx_byte counter +To: Greg Kroah-Hartman <gregkh@suse.de>, Alan Cox <alan@linux.intel.com> +Cc: Oliver Neukum <oliver@neukum.org>, Alan Stern <stern@rowland.harvard.edu>, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Johan Hovold <jhovold@gmail.com> +Message-ID: <1254938707-6996-3-git-send-email-jhovold@gmail.com> + + +Remove unused rx_byte counter which is never exposed as noted by Alan +Cox. + +Signed-off-by: Johan Hovold <jhovold@gmail.com> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/ftdi_sio.c | 13 ------------- + 1 file changed, 13 deletions(-) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -81,7 +81,6 @@ struct ftdi_private { + struct delayed_work rx_work; + struct usb_serial_port *port; + int rx_processed; +- unsigned long rx_bytes; + + __u16 interface; /* FT2232C, FT2232H or FT4232H port interface + (0 for FT232/245) */ +@@ -1699,9 +1698,6 @@ static int ftdi_open(struct tty_struct * + spin_lock_irqsave(&priv->tx_lock, flags); + priv->tx_bytes = 0; + spin_unlock_irqrestore(&priv->tx_lock, flags); +- spin_lock_irqsave(&priv->rx_lock, flags); +- priv->rx_bytes = 0; +- spin_unlock_irqrestore(&priv->rx_lock, flags); + + write_latency_timer(port); + +@@ -2014,8 +2010,6 @@ static void ftdi_read_bulk_callback(stru + struct usb_serial_port *port = urb->context; + struct tty_struct *tty; + struct ftdi_private *priv; +- unsigned long countread; +- unsigned long flags; + int status = urb->status; + + if (urb->number_of_packets > 0) { +@@ -2054,13 +2048,6 @@ static void ftdi_read_bulk_callback(stru + goto out; + } + +- /* count data bytes, but not status bytes */ +- countread = urb->actual_length; +- countread -= 2 * DIV_ROUND_UP(countread, priv->max_packet_size); +- spin_lock_irqsave(&priv->rx_lock, flags); +- priv->rx_bytes += countread; +- spin_unlock_irqrestore(&priv->rx_lock, flags); +- + ftdi_process_read(&priv->rx_work.work); + out: + tty_kref_put(tty); |
