Re: [Bugme-new] [Bug 8561] New: list_add corruption. prev->next should be next (f7d28794), but was f0df8ed4

Andrew Morton <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
On Wed, 6 Jun 2007 18:33:53 +0100 Paulo Pereira <[email protected]> wrote:

> Hi I have a problem instaling the patch, I hope that anyone can help me...
> When a trie to install the patch:
> 	patching file drivers/usb/serial/option.c
> 	patch: **** malformed patch at line 4:  #include <linux/tty.h>

Here it is as an attachment.

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/

_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
usb-serial-fix-something.patch (application/octet-stream, 3.5 KB)
From: Alan Stern <[email protected]>

Might fix bug 8561

On Mon, 4 Jun 2007, Paulo Pereira wrote:

> The patch that you send is not resolving the problem... :(
> I stil have Kernel panic after 45/60 min of work with Ktorrent/Amule...
>
> The Drump is:
>
> Call Trace:
> [<c055fb36>] usb_hcd_submit+0xb1/0x763
> [<f9276488>] ipt_do_table+0x2c7/0x2ef [ip_tables]
> [<f929a6d7>] nf_ct_deliver_cached_events+0x41/0x96 [nf_conntrak]
> [<f9288254>] ipv4_confirm+0x36/0c3b [nf_conntrack_ipv4]
> [<c05ce7c2>] tcp_v4_rcv+0x827/0x899
> [<c05afcc0>] nf_hook_slow+0x4d/0xb5
> [<c042826f>] irq_enter+0x19/0x23
> [<c042826f>] irq_enter+0x19/0x23
> [<c040794c>] do_IRQ+0xbd/0xd1
> [<f90893c9>] option_write+0xa7/0xef [option]

Okay, from this it looks like there's a problem in the option.c serial
driver.  Glancing at the code, it's obvious why: The thing totally
abuses the USB API.

Try applying this patch; it should help.

Cc: Paulo Pereira <[email protected]>
Cc: Greg KH <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
---

 drivers/usb/serial/option.c |   20 +++++++++++++++++---
 1 files changed, 17 insertions(+), 3 deletions(-)

diff -puN drivers/usb/serial/option.c~usb-serial-fix-something drivers/usb/serial/option.c
--- a/drivers/usb/serial/option.c~usb-serial-fix-something
+++ a/drivers/usb/serial/option.c
@@ -38,6 +38,7 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/module.h>
+#include <linux/bitops.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
@@ -238,6 +239,7 @@ struct option_port_private {
 	/* Output endpoints and buffer for this port */
 	struct urb *out_urbs[N_OUT_URB];
 	char out_buffer[N_OUT_URB][OUT_BUFLEN];
+	unsigned long out_busy;		/* Bit vector of URBs in use */
 
 	/* Settings for the port */
 	int rts_state;	/* Handshaking pins (outputs) */
@@ -368,7 +370,7 @@ static int option_write(struct usb_seria
 			todo = OUT_BUFLEN;
 
 		this_urb = portdata->out_urbs[i];
-		if (this_urb->status == -EINPROGRESS) {
+		if (test_and_set_bit(i, &portdata->out_busy)) {
 			if (time_before(jiffies,
 					portdata->tx_start_time[i] + 10 * HZ))
 				continue;
@@ -392,6 +394,7 @@ static int option_write(struct usb_seria
 			dbg("usb_submit_urb %p (write bulk) failed "
 				"(%d, has %d)", this_urb,
 				err, this_urb->status);
+			clear_bit(i, &portdata->out_busy);
 			continue;
 		}
 		portdata->tx_start_time[i] = jiffies;
@@ -444,12 +447,23 @@ static void option_indat_callback(struct
 static void option_outdat_callback(struct urb *urb)
 {
 	struct usb_serial_port *port;
+	struct option_port_private *portdata;
+	int i;
 
 	dbg("%s", __FUNCTION__);
 
 	port = (struct usb_serial_port *) urb->context;
 
 	usb_serial_port_softint(port);
+
+	portdata = usb_get_serial_port_data(port);
+	for (i = 0; i < N_OUT_URB; ++i) {
+		if (portdata->out_urbs[i] == urb) {
+			smp_mb__before_clear_bit();
+			clear_bit(i, &portdata->out_busy);
+			break;
+		}
+	}
 }
 
 static void option_instat_callback(struct urb *urb)
@@ -516,7 +530,7 @@ static int option_write_room(struct usb_
 
 	for (i=0; i < N_OUT_URB; i++) {
 		this_urb = portdata->out_urbs[i];
-		if (this_urb && this_urb->status != -EINPROGRESS)
+		if (this_urb && !test_bit(i, &portdata->out_busy))
 			data_len += OUT_BUFLEN;
 	}
 
@@ -535,7 +549,7 @@ static int option_chars_in_buffer(struct
 
 	for (i=0; i < N_OUT_URB; i++) {
 		this_urb = portdata->out_urbs[i];
-		if (this_urb && this_urb->status == -EINPROGRESS)
+		if (this_urb && test_bit(i, &portdata->out_busy))
 			data_len += this_urb->transfer_buffer_length;
 	}
 	dbg("%s: %d", __FUNCTION__, data_len);
_
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.