]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 31 Oct 2012 22:20:52 +0000 (15:20 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 31 Oct 2012 22:20:52 +0000 (15:20 -0700)
added patches:
usb-io_edgeport-remove-unused-variable.patch
usb-iuu_phoenix-fix-backported-patches.patch
usb-mos7840-fix-port-data-memory-leak.patch

queue-3.6/series
queue-3.6/usb-io_edgeport-remove-unused-variable.patch [new file with mode: 0644]
queue-3.6/usb-iuu_phoenix-fix-backported-patches.patch [new file with mode: 0644]
queue-3.6/usb-mos7840-fix-port-data-memory-leak.patch [new file with mode: 0644]

index 2ab5d053561a5cba07805738cb8c49eba65a5df5..30fcbc555a5fbd9281f2beb97ccdf6aa50cabf3f 100644 (file)
@@ -12,3 +12,6 @@ ceph-fix-dentry-reference-leak-in-encode_fh.patch
 ceph-fix-oops-when-handling-mdsmap-that-decreases-max_mds.patch
 libceph-check-for-invalid-mapping.patch
 ceph-avoid-32-bit-page-index-overflow.patch
+usb-mos7840-fix-port-data-memory-leak.patch
+usb-iuu_phoenix-fix-backported-patches.patch
+usb-io_edgeport-remove-unused-variable.patch
diff --git a/queue-3.6/usb-io_edgeport-remove-unused-variable.patch b/queue-3.6/usb-io_edgeport-remove-unused-variable.patch
new file mode 100644 (file)
index 0000000..ffa6c89
--- /dev/null
@@ -0,0 +1,33 @@
+From pebolle@tiscali.nl  Wed Oct 31 15:19:22 2012
+From: Paul Bolle <pebolle@tiscali.nl>
+Date: Tue, 30 Oct 2012 10:38:06 +0100
+Subject: USB: io_edgeport: remove unused variable
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+From: Paul Bolle <pebolle@tiscali.nl>
+
+The stable commit 12ddc74e8e25107eda81aceb74e3311c1480b381
+("USB: io_edgeport: fix port-data memory leak") left one variable
+unused:
+    drivers/usb/serial/io_edgeport.c: In function 'edge_release':
+    drivers/usb/serial/io_edgeport.c:3155:6: warning: unused variable 'i' [-Wunused-variable]
+
+Remove this unused variable.
+
+Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/io_edgeport.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -3152,7 +3152,6 @@ static void edge_disconnect(struct usb_s
+ static void edge_release(struct usb_serial *serial)
+ {
+       struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
+-      int i;
+       dbg("%s", __func__);
diff --git a/queue-3.6/usb-iuu_phoenix-fix-backported-patches.patch b/queue-3.6/usb-iuu_phoenix-fix-backported-patches.patch
new file mode 100644 (file)
index 0000000..52d65a2
--- /dev/null
@@ -0,0 +1,42 @@
+From jhovold@gmail.com  Wed Oct 31 15:18:38 2012
+From: Johan Hovold <jhovold@gmail.com>
+Date: Wed, 31 Oct 2012 20:48:54 +0100
+Subject: USB: iuu_phoenix: fix backported patches
+To: Greg KH <gregkh@linuxfoundation.org>
+
+From: Johan Hovold <jhovold@gmail.com>
+
+Fix two memory leaks involving dbgbuf that were introduced in port-probe
+error paths when backporting the following port-data fixes from v3.7
+(which doesn't have dbgbuf):
+
+0978c94 USB: iuu_phoenix: fix sysfs-attribute creation
+5363655 USB: iuu_phoenix: fix port-data memory leak
+
+Reported-by: Fengguang Wu <fengguang.wu@intel.com>
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/iuu_phoenix.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/iuu_phoenix.c
++++ b/drivers/usb/serial/iuu_phoenix.c
+@@ -105,7 +105,7 @@ static int iuu_port_probe(struct usb_ser
+       }
+       priv->dbgbuf = kzalloc(256, GFP_KERNEL);
+-      if (!priv->writebuf) {
++      if (!priv->dbgbuf) {
+               kfree(priv->writebuf);
+               kfree(priv->buf);
+               kfree(priv);
+@@ -120,6 +120,7 @@ static int iuu_port_probe(struct usb_ser
+       ret = iuu_create_sysfs_attrs(port);
+       if (ret) {
++              kfree(priv->dbgbuf);
+               kfree(priv->writebuf);
+               kfree(priv->buf);
+               kfree(priv);
diff --git a/queue-3.6/usb-mos7840-fix-port-data-memory-leak.patch b/queue-3.6/usb-mos7840-fix-port-data-memory-leak.patch
new file mode 100644 (file)
index 0000000..70a3ea2
--- /dev/null
@@ -0,0 +1,384 @@
+From jhovold@gmail.com  Wed Oct 31 15:18:22 2012
+From: Johan Hovold <jhovold@gmail.com>
+Date: Wed, 31 Oct 2012 20:52:42 +0100
+Subject: USB: mos7840: fix port-data memory leak
+To: Greg KH <gregkh@linuxfoundation.org>
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 80c00750f0c9867a65b30a17880939b6bc660a77 upstream.
+
+Fix port-data memory leak by moving port data allocation and
+deallocation to port_probe and port_remove.
+
+Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no
+driver is bound) the port private data is no longer freed at release as
+it is no longer accessible.
+
+Note that the indentation was kept intact using a do-while(0) in order
+to facilitate review. A follow-up patch will remove it.
+
+Compile-only tested.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+
+This a backport of 80c00750f0c9867 from v3.7-rc to v3.6.5 as requested.
+
+Thanks,
+Johan
+
+
+ drivers/usb/serial/mos7840.c |  198 +++++++++++++++----------------------------
+ 1 file changed, 71 insertions(+), 127 deletions(-)
+
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -2405,52 +2405,43 @@ static int mos7840_calc_num_ports(struct
+       return mos7840_num_ports;
+ }
+-/****************************************************************************
+- * mos7840_startup
+- ****************************************************************************/
+-
+-static int mos7840_startup(struct usb_serial *serial)
++static int mos7840_port_probe(struct usb_serial_port *port)
+ {
++      struct usb_serial *serial = port->serial;
+       struct moschip_port *mos7840_port;
+-      struct usb_device *dev;
+-      int i, status;
++      int status;
++      int pnum;
+       __u16 Data;
+-      if (!serial) {
+-              dbg("%s", "Invalid Handler");
+-              return -1;
+-      }
+-
+-      dev = serial->dev;
+-
+       /* we set up the pointers to the endpoints in the mos7840_open *
+        * function, as the structures aren't created yet.             */
+-      /* set up port private structures */
+-      for (i = 0; i < serial->num_ports; ++i) {
+-              dbg ("mos7840_startup: configuring port %d............", i);
++      pnum = port->number - serial->minor;
++
++      /* FIXME: remove do-while(0) loop used to keep stable patch minimal.
++       */
++      do {
++              dbg("mos7840_startup: configuring port %d............", pnum);
+               mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
+               if (mos7840_port == NULL) {
+-                      dev_err(&dev->dev, "%s - Out of memory\n", __func__);
+-                      status = -ENOMEM;
+-                      i--; /* don't follow NULL pointer cleaning up */
+-                      goto error;
++                      dev_err(&port->dev, "%s - Out of memory\n", __func__);
++                      return -ENOMEM;
+               }
+               /* Initialize all port interrupt end point to port 0 int
+                * endpoint. Our device has only one interrupt end point
+                * common to all port */
+-              mos7840_port->port = serial->port[i];
+-              mos7840_set_port_private(serial->port[i], mos7840_port);
++              mos7840_port->port = port;
++              mos7840_set_port_private(port, mos7840_port);
+               spin_lock_init(&mos7840_port->pool_lock);
+               /* minor is not initialised until later by
+                * usb-serial.c:get_free_serial() and cannot therefore be used
+                * to index device instances */
+-              mos7840_port->port_num = i + 1;
+-              dbg ("serial->port[i]->number = %d", serial->port[i]->number);
+-              dbg ("serial->port[i]->serial->minor = %d", serial->port[i]->serial->minor);
++              mos7840_port->port_num = pnum + 1;
++              dbg("port->number = %d", port->number);
++              dbg("port->serial->minor = %d", port->serial->minor);
+               dbg ("mos7840_port->port_num = %d", mos7840_port->port_num);
+               dbg ("serial->minor = %d", serial->minor);
+@@ -2480,10 +2471,10 @@ static int mos7840_startup(struct usb_se
+                       mos7840_port->DcrRegOffset = 0x1c;
+               }
+               mos7840_dump_serial_port(mos7840_port);
+-              mos7840_set_port_private(serial->port[i], mos7840_port);
++              mos7840_set_port_private(port, mos7840_port);
+               /* enable rx_disable bit in control register */
+-              status = mos7840_get_reg_sync(serial->port[i],
++              status = mos7840_get_reg_sync(port,
+                                mos7840_port->ControlRegOffset, &Data);
+               if (status < 0) {
+                       dbg("Reading ControlReg failed status-0x%x", status);
+@@ -2491,12 +2482,13 @@ static int mos7840_startup(struct usb_se
+               } else
+                       dbg("ControlReg Reading success val is %x, status%d",
+                           Data, status);
++
+               Data |= 0x08;   /* setting driver done bit */
+               Data |= 0x04;   /* sp1_bit to have cts change reflect in
+                                  modem status reg */
+               /* Data |= 0x20; //rx_disable bit */
+-              status = mos7840_set_reg_sync(serial->port[i],
++              status = mos7840_set_reg_sync(port,
+                                        mos7840_port->ControlRegOffset, Data);
+               if (status < 0) {
+                       dbg("Writing ControlReg failed(rx_disable) status-0x%x", status);
+@@ -2508,7 +2500,7 @@ static int mos7840_startup(struct usb_se
+               /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
+                  and 0x24 in DCR3 */
+               Data = 0x01;
+-              status = mos7840_set_reg_sync(serial->port[i],
++              status = mos7840_set_reg_sync(port,
+                        (__u16) (mos7840_port->DcrRegOffset + 0), Data);
+               if (status < 0) {
+                       dbg("Writing DCR0 failed status-0x%x", status);
+@@ -2517,7 +2509,7 @@ static int mos7840_startup(struct usb_se
+                       dbg("DCR0 Writing success status%d", status);
+               Data = 0x05;
+-              status = mos7840_set_reg_sync(serial->port[i],
++              status = mos7840_set_reg_sync(port,
+                        (__u16) (mos7840_port->DcrRegOffset + 1), Data);
+               if (status < 0) {
+                       dbg("Writing DCR1 failed status-0x%x", status);
+@@ -2526,7 +2518,7 @@ static int mos7840_startup(struct usb_se
+                       dbg("DCR1 Writing success status%d", status);
+               Data = 0x24;
+-              status = mos7840_set_reg_sync(serial->port[i],
++              status = mos7840_set_reg_sync(port,
+                        (__u16) (mos7840_port->DcrRegOffset + 2), Data);
+               if (status < 0) {
+                       dbg("Writing DCR2 failed status-0x%x", status);
+@@ -2536,7 +2528,7 @@ static int mos7840_startup(struct usb_se
+               /* write values in clkstart0x0 and clkmulti 0x20 */
+               Data = 0x0;
+-              status = mos7840_set_reg_sync(serial->port[i],
++              status = mos7840_set_reg_sync(port,
+                                        CLK_START_VALUE_REGISTER, Data);
+               if (status < 0) {
+                       dbg("Writing CLK_START_VALUE_REGISTER failed status-0x%x", status);
+@@ -2545,7 +2537,7 @@ static int mos7840_startup(struct usb_se
+                       dbg("CLK_START_VALUE_REGISTER Writing success status%d", status);
+               Data = 0x20;
+-              status = mos7840_set_reg_sync(serial->port[i],
++              status = mos7840_set_reg_sync(port,
+                                       CLK_MULTI_REGISTER, Data);
+               if (status < 0) {
+                       dbg("Writing CLK_MULTI_REGISTER failed status-0x%x",
+@@ -2557,7 +2549,7 @@ static int mos7840_startup(struct usb_se
+               /* write value 0x0 to scratchpad register */
+               Data = 0x00;
+-              status = mos7840_set_uart_reg(serial->port[i],
++              status = mos7840_set_uart_reg(port,
+                                               SCRATCH_PAD_REGISTER, Data);
+               if (status < 0) {
+                       dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x",
+@@ -2572,7 +2564,7 @@ static int mos7840_startup(struct usb_se
+                   && (serial->num_ports == 2)) {
+                       Data = 0xff;
+-                      status = mos7840_set_reg_sync(serial->port[i],
++                      status = mos7840_set_reg_sync(port,
+                                     (__u16) (ZLP_REG1 +
+                                     ((__u16)mos7840_port->port_num)), Data);
+                       dbg("ZLIP offset %x",
+@@ -2580,14 +2572,14 @@ static int mos7840_startup(struct usb_se
+                                       ((__u16) mos7840_port->port_num)));
+                       if (status < 0) {
+                               dbg("Writing ZLP_REG%d failed status-0x%x",
+-                                  i + 2, status);
++                                  pnum + 2, status);
+                               break;
+                       } else
+                               dbg("ZLP_REG%d Writing success status%d",
+-                                  i + 2, status);
++                                  pnum + 2, status);
+               } else {
+                       Data = 0xff;
+-                      status = mos7840_set_reg_sync(serial->port[i],
++                      status = mos7840_set_reg_sync(port,
+                             (__u16) (ZLP_REG1 +
+                             ((__u16)mos7840_port->port_num) - 0x1), Data);
+                       dbg("ZLIP offset %x",
+@@ -2595,11 +2587,11 @@ static int mos7840_startup(struct usb_se
+                                    ((__u16) mos7840_port->port_num) - 0x1));
+                       if (status < 0) {
+                               dbg("Writing ZLP_REG%d failed status-0x%x",
+-                                  i + 1, status);
++                                  pnum + 1, status);
+                               break;
+                       } else
+                               dbg("ZLP_REG%d Writing success status%d",
+-                                  i + 1, status);
++                                  pnum + 1, status);
+               }
+               mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
+@@ -2636,105 +2628,58 @@ static int mos7840_startup(struct usb_se
+                       mos7840_port->led_flag = false;
+                       /* Turn off LED */
+-                      mos7840_set_led_sync(serial->port[i],
++                      mos7840_set_led_sync(port,
+                                               MODEM_CONTROL_REGISTER, 0x0300);
+               }
+-      }
+-      dbg ("mos7840_startup: all ports configured...........");
++      } while (0);
+-      /* Zero Length flag enable */
+-      Data = 0x0f;
+-      status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
+-      if (status < 0) {
+-              dbg("Writing ZLP_REG5 failed status-0x%x", status);
+-              goto error;
+-      } else
+-              dbg("ZLP_REG5 Writing success status%d", status);
+-
+-      /* setting configuration feature to one */
+-      usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+-                      (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, MOS_WDR_TIMEOUT);
++      if (pnum == serial->num_ports - 1) {
++              dbg("mos7840_startup: all ports configured...........");
++
++              /* Zero Length flag enable */
++              Data = 0x0f;
++              status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
++              if (status < 0) {
++                      dbg("Writing ZLP_REG5 failed status-0x%x", status);
++                      goto error;
++              } else
++                      dbg("ZLP_REG5 Writing success status%d", status);
++
++              /* setting configuration feature to one */
++              usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
++                              0x03, 0x00, 0x01, 0x00, NULL, 0x00,
++                              MOS_WDR_TIMEOUT);
++      }
+       return 0;
+ error:
+-      for (/* nothing */; i >= 0; i--) {
+-              mos7840_port = mos7840_get_port_private(serial->port[i]);
++      kfree(mos7840_port->dr);
++      kfree(mos7840_port->ctrl_buf);
++      usb_free_urb(mos7840_port->control_urb);
++      kfree(mos7840_port);
+-              kfree(mos7840_port->dr);
+-              kfree(mos7840_port->ctrl_buf);
+-              usb_free_urb(mos7840_port->control_urb);
+-              kfree(mos7840_port);
+-      }
+       return status;
+ }
+-/****************************************************************************
+- * mos7840_disconnect
+- *    This function is called whenever the device is removed from the usb bus.
+- ****************************************************************************/
+-
+-static void mos7840_disconnect(struct usb_serial *serial)
++static int mos7840_port_remove(struct usb_serial_port *port)
+ {
+-      int i;
+-      unsigned long flags;
+       struct moschip_port *mos7840_port;
+-      if (!serial) {
+-              dbg("%s", "Invalid Handler");
+-              return;
+-      }
+-
+-      /* check for the ports to be closed,close the ports and disconnect */
++      mos7840_port = mos7840_get_port_private(port);
+-      /* free private structure allocated for serial port  *
+-       * stop reads and writes on all ports                */
++      if (mos7840_port->has_led) {
++              /* Turn off LED */
++              mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300);
+-      for (i = 0; i < serial->num_ports; ++i) {
+-              mos7840_port = mos7840_get_port_private(serial->port[i]);
+-              dbg ("mos7840_port %d = %p", i, mos7840_port);
+-              if (mos7840_port) {
+-                      usb_kill_urb(mos7840_port->control_urb);
+-              }
++              del_timer_sync(&mos7840_port->led_timer1);
++              del_timer_sync(&mos7840_port->led_timer2);
+       }
+-}
+-
+-/****************************************************************************
+- * mos7840_release
+- *    This function is called when the usb_serial structure is freed.
+- ****************************************************************************/
++      usb_kill_urb(mos7840_port->control_urb);
++      usb_free_urb(mos7840_port->control_urb);
++      kfree(mos7840_port->ctrl_buf);
++      kfree(mos7840_port->dr);
++      kfree(mos7840_port);
+-static void mos7840_release(struct usb_serial *serial)
+-{
+-      int i;
+-      struct moschip_port *mos7840_port;
+-
+-      if (!serial) {
+-              dbg("%s", "Invalid Handler");
+-              return;
+-      }
+-
+-      /* check for the ports to be closed,close the ports and disconnect */
+-
+-      /* free private structure allocated for serial port  *
+-       * stop reads and writes on all ports                */
+-
+-      for (i = 0; i < serial->num_ports; ++i) {
+-              mos7840_port = mos7840_get_port_private(serial->port[i]);
+-              dbg("mos7840_port %d = %p", i, mos7840_port);
+-              if (mos7840_port) {
+-                      if (mos7840_port->has_led) {
+-                              /* Turn off LED */
+-                              mos7840_set_led_sync(mos7840_port->port,
+-                                              MODEM_CONTROL_REGISTER, 0x0300);
+-
+-                              del_timer_sync(&mos7840_port->led_timer1);
+-                              del_timer_sync(&mos7840_port->led_timer2);
+-                      }
+-                      usb_free_urb(mos7840_port->control_urb);
+-                      kfree(mos7840_port->ctrl_buf);
+-                      kfree(mos7840_port->dr);
+-                      kfree(mos7840_port);
+-              }
+-      }
++      return 0;
+ }
+ static struct usb_serial_driver moschip7840_4port_device = {
+@@ -2762,9 +2707,8 @@ static struct usb_serial_driver moschip7
+       .tiocmget = mos7840_tiocmget,
+       .tiocmset = mos7840_tiocmset,
+       .get_icount = mos7840_get_icount,
+-      .attach = mos7840_startup,
+-      .disconnect = mos7840_disconnect,
+-      .release = mos7840_release,
++      .port_probe = mos7840_port_probe,
++      .port_remove = mos7840_port_remove,
+       .read_bulk_callback = mos7840_bulk_in_callback,
+       .read_int_callback = mos7840_interrupt_callback,
+ };