From: Greg Kroah-Hartman Date: Wed, 31 Oct 2012 22:20:52 +0000 (-0700) Subject: 3.6-stable patches X-Git-Tag: v3.0.51~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b6fd915060ee8f974a8c3d104973a1b86e474485;p=thirdparty%2Fkernel%2Fstable-queue.git 3.6-stable patches added patches: usb-io_edgeport-remove-unused-variable.patch usb-iuu_phoenix-fix-backported-patches.patch usb-mos7840-fix-port-data-memory-leak.patch --- diff --git a/queue-3.6/series b/queue-3.6/series index 2ab5d053561..30fcbc555a5 100644 --- a/queue-3.6/series +++ b/queue-3.6/series @@ -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 index 00000000000..ffa6c891833 --- /dev/null +++ b/queue-3.6/usb-io_edgeport-remove-unused-variable.patch @@ -0,0 +1,33 @@ +From pebolle@tiscali.nl Wed Oct 31 15:19:22 2012 +From: Paul Bolle +Date: Tue, 30 Oct 2012 10:38:06 +0100 +Subject: USB: io_edgeport: remove unused variable +To: Greg Kroah-Hartman + +From: Paul Bolle + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..52d65a2f1c7 --- /dev/null +++ b/queue-3.6/usb-iuu_phoenix-fix-backported-patches.patch @@ -0,0 +1,42 @@ +From jhovold@gmail.com Wed Oct 31 15:18:38 2012 +From: Johan Hovold +Date: Wed, 31 Oct 2012 20:48:54 +0100 +Subject: USB: iuu_phoenix: fix backported patches +To: Greg KH + +From: Johan Hovold + +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 +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..70a3ea2dd17 --- /dev/null +++ b/queue-3.6/usb-mos7840-fix-port-data-memory-leak.patch @@ -0,0 +1,384 @@ +From jhovold@gmail.com Wed Oct 31 15:18:22 2012 +From: Johan Hovold +Date: Wed, 31 Oct 2012 20:52:42 +0100 +Subject: USB: mos7840: fix port-data memory leak +To: Greg KH + +From: Johan Hovold + +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 +Signed-off-by: Greg Kroah-Hartman +--- + +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, + };