diff options
| author | Johan Hovold <jhovold@gmail.com> | 2013-07-01 08:03:33 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-25 14:30:17 -0400 |
| commit | 5f8a2e68b679b41cc8e9b642f2f5aa45dd678641 (patch) | |
| tree | b82e7c40cb32249e6ffed1b67e784819062e1ff0 /drivers/usb/serial | |
| parent | 878c69aae986ae97084458c0183a8c0a059865b1 (diff) | |
USB: mos7840: fix memory leak in open
Allocated urbs and buffers were never freed on errors in open.
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/serial')
| -rw-r--r-- | drivers/usb/serial/mos7840.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 0a818b238508..603fb70dde80 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
| @@ -905,20 +905,20 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 905 | status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data); | 905 | status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data); |
| 906 | if (status < 0) { | 906 | if (status < 0) { |
| 907 | dev_dbg(&port->dev, "Reading Spreg failed\n"); | 907 | dev_dbg(&port->dev, "Reading Spreg failed\n"); |
| 908 | return -1; | 908 | goto err; |
| 909 | } | 909 | } |
| 910 | Data |= 0x80; | 910 | Data |= 0x80; |
| 911 | status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); | 911 | status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); |
| 912 | if (status < 0) { | 912 | if (status < 0) { |
| 913 | dev_dbg(&port->dev, "writing Spreg failed\n"); | 913 | dev_dbg(&port->dev, "writing Spreg failed\n"); |
| 914 | return -1; | 914 | goto err; |
| 915 | } | 915 | } |
| 916 | 916 | ||
| 917 | Data &= ~0x80; | 917 | Data &= ~0x80; |
| 918 | status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); | 918 | status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data); |
| 919 | if (status < 0) { | 919 | if (status < 0) { |
| 920 | dev_dbg(&port->dev, "writing Spreg failed\n"); | 920 | dev_dbg(&port->dev, "writing Spreg failed\n"); |
| 921 | return -1; | 921 | goto err; |
| 922 | } | 922 | } |
| 923 | /* End of block to be checked */ | 923 | /* End of block to be checked */ |
| 924 | 924 | ||
| @@ -927,7 +927,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 927 | &Data); | 927 | &Data); |
| 928 | if (status < 0) { | 928 | if (status < 0) { |
| 929 | dev_dbg(&port->dev, "Reading Controlreg failed\n"); | 929 | dev_dbg(&port->dev, "Reading Controlreg failed\n"); |
| 930 | return -1; | 930 | goto err; |
| 931 | } | 931 | } |
| 932 | Data |= 0x08; /* Driver done bit */ | 932 | Data |= 0x08; /* Driver done bit */ |
| 933 | Data |= 0x20; /* rx_disable */ | 933 | Data |= 0x20; /* rx_disable */ |
| @@ -935,7 +935,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 935 | mos7840_port->ControlRegOffset, Data); | 935 | mos7840_port->ControlRegOffset, Data); |
| 936 | if (status < 0) { | 936 | if (status < 0) { |
| 937 | dev_dbg(&port->dev, "writing Controlreg failed\n"); | 937 | dev_dbg(&port->dev, "writing Controlreg failed\n"); |
| 938 | return -1; | 938 | goto err; |
| 939 | } | 939 | } |
| 940 | /* do register settings here */ | 940 | /* do register settings here */ |
| 941 | /* Set all regs to the device default values. */ | 941 | /* Set all regs to the device default values. */ |
| @@ -946,21 +946,21 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 946 | status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); | 946 | status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); |
| 947 | if (status < 0) { | 947 | if (status < 0) { |
| 948 | dev_dbg(&port->dev, "disabling interrupts failed\n"); | 948 | dev_dbg(&port->dev, "disabling interrupts failed\n"); |
| 949 | return -1; | 949 | goto err; |
| 950 | } | 950 | } |
| 951 | /* Set FIFO_CONTROL_REGISTER to the default value */ | 951 | /* Set FIFO_CONTROL_REGISTER to the default value */ |
| 952 | Data = 0x00; | 952 | Data = 0x00; |
| 953 | status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); | 953 | status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); |
| 954 | if (status < 0) { | 954 | if (status < 0) { |
| 955 | dev_dbg(&port->dev, "Writing FIFO_CONTROL_REGISTER failed\n"); | 955 | dev_dbg(&port->dev, "Writing FIFO_CONTROL_REGISTER failed\n"); |
| 956 | return -1; | 956 | goto err; |
| 957 | } | 957 | } |
| 958 | 958 | ||
| 959 | Data = 0xcf; | 959 | Data = 0xcf; |
| 960 | status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); | 960 | status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); |
| 961 | if (status < 0) { | 961 | if (status < 0) { |
| 962 | dev_dbg(&port->dev, "Writing FIFO_CONTROL_REGISTER failed\n"); | 962 | dev_dbg(&port->dev, "Writing FIFO_CONTROL_REGISTER failed\n"); |
| 963 | return -1; | 963 | goto err; |
| 964 | } | 964 | } |
| 965 | 965 | ||
| 966 | Data = 0x03; | 966 | Data = 0x03; |
| @@ -1103,6 +1103,15 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 1103 | /* mos7840_change_port_settings(mos7840_port,old_termios); */ | 1103 | /* mos7840_change_port_settings(mos7840_port,old_termios); */ |
| 1104 | 1104 | ||
| 1105 | return 0; | 1105 | return 0; |
| 1106 | err: | ||
| 1107 | for (j = 0; j < NUM_URBS; ++j) { | ||
| 1108 | urb = mos7840_port->write_urb_pool[j]; | ||
| 1109 | if (!urb) | ||
| 1110 | continue; | ||
| 1111 | kfree(urb->transfer_buffer); | ||
| 1112 | usb_free_urb(urb); | ||
| 1113 | } | ||
| 1114 | return status; | ||
| 1106 | } | 1115 | } |
| 1107 | 1116 | ||
| 1108 | /***************************************************************************** | 1117 | /***************************************************************************** |
