]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
[PATCH] added visor oops fix to queue.
authorgregkh@suse.de <gregkh@suse.de>
Wed, 11 May 2005 07:52:54 +0000 (00:52 -0700)
committerGreg KH <gregkh@suse.de>
Thu, 12 May 2005 05:16:09 +0000 (22:16 -0700)
queue/visor-oops-fix.patch [new file with mode: 0644]

diff --git a/queue/visor-oops-fix.patch b/queue/visor-oops-fix.patch
new file mode 100644 (file)
index 0000000..6e03a33
--- /dev/null
@@ -0,0 +1,97 @@
+From foo@baz Tue Apr  9 12:12:43 2002
+To: Greg KH <greg@kroah.com>
+Date: 23 Mar 2005 15:26:40 -08:00
+From: gregkh@suse.de
+Subject: USB: fix bug in visor driver with throttle/unthrottle causing oopses.
+
+Thanks to Mark Lord <mlord@pobox.com> for reporting this and helping with testing.
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
+--- a/drivers/usb/serial/visor.c       2005-05-11 00:52:29 -07:00
++++ b/drivers/usb/serial/visor.c       2005-05-11 00:52:29 -07:00
+@@ -386,6 +386,7 @@
+       int bytes_in;
+       int bytes_out;
+       int outstanding_urbs;
++      int throttled;
+ };
+ /* number of outstanding urbs to prevent userspace DoS from happening */
+@@ -415,6 +416,7 @@
+       priv->bytes_in = 0;
+       priv->bytes_out = 0;
+       priv->outstanding_urbs = 0;
++      priv->throttled = 0;
+       spin_unlock_irqrestore(&priv->lock, flags);
+       /*
+@@ -602,6 +604,7 @@
+       struct tty_struct *tty;
+       unsigned long flags;
+       int i;
++      int throttled;
+       int result;
+       dbg("%s - port %d", __FUNCTION__, port->number);
+@@ -627,18 +630,21 @@
+       }
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->bytes_in += urb->actual_length;
++      throttled = priv->throttled;
+       spin_unlock_irqrestore(&priv->lock, flags);
+-      /* 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,
+-                         visor_read_bulk_callback, port);
+-      result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+-      if (result)
+-              dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
++      /* Continue trying to always read if we should */
++      if (!throttled) {
++              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,
++                                 visor_read_bulk_callback, port);
++              result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
++              if (result)
++                      dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
++      }
+       return;
+ }
+@@ -683,16 +689,26 @@
+ static void visor_throttle (struct usb_serial_port *port)
+ {
++      struct visor_private *priv = usb_get_serial_port_data(port);
++      unsigned long flags;
++
+       dbg("%s - port %d", __FUNCTION__, port->number);
+-      usb_kill_urb(port->read_urb);
++      spin_lock_irqsave(&priv->lock, flags);
++      priv->throttled = 1;
++      spin_unlock_irqrestore(&priv->lock, flags);
+ }
+ static void visor_unthrottle (struct usb_serial_port *port)
+ {
++      struct visor_private *priv = usb_get_serial_port_data(port);
++      unsigned long flags;
+       int result;
+       dbg("%s - port %d", __FUNCTION__, port->number);
++      spin_lock_irqsave(&priv->lock, flags);
++      priv->throttled = 0;
++      spin_unlock_irqrestore(&priv->lock, flags);
+       port->read_urb->dev = port->serial->dev;
+       result = usb_submit_urb(port->read_urb, GFP_ATOMIC);