aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2012-10-25 04:29:08 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-10-25 12:36:58 -0400
commit40d04738491d7ac1aa708ba434ff3480ec9e1b96 (patch)
treedf646d43263f63e526d05dc3d60ad114cab47fc2 /drivers/usb
parentb8a0055050b6294826171641b182c09f78f4cc63 (diff)
USB: quatech2: fix port-data memory leaks
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 this also fixes memory leaks in the error path of attach where the write urbs were not freed on errors. Make sure all interface-data deallocation is done in release by moving the read urb deallocation from disconnect. Note that the write urb is killed during close so that the call in disconnect was superfluous. Compile-only tested. Cc: Bill Pemberton <wfp5p@virginia.edu> 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')
-rw-r--r--drivers/usb/serial/quatech2.c121
1 files changed, 51 insertions, 70 deletions
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
index 5adb7428fbb1..8d0c4a0b6a7b 100644
--- a/drivers/usb/serial/quatech2.c
+++ b/drivers/usb/serial/quatech2.c
@@ -143,12 +143,12 @@ static void qt2_read_bulk_callback(struct urb *urb);
143 143
144static void qt2_release(struct usb_serial *serial) 144static void qt2_release(struct usb_serial *serial)
145{ 145{
146 int i; 146 struct qt2_serial_private *serial_priv;
147 147
148 kfree(usb_get_serial_data(serial)); 148 serial_priv = usb_get_serial_data(serial);
149 149
150 for (i = 0; i < serial->num_ports; i++) 150 usb_free_urb(serial_priv->read_urb);
151 kfree(usb_get_serial_port_data(serial->port[i])); 151 kfree(serial_priv);
152} 152}
153 153
154static inline int calc_baud_divisor(int baudrate) 154static inline int calc_baud_divisor(int baudrate)
@@ -464,21 +464,9 @@ static void qt2_close(struct usb_serial_port *port)
464static void qt2_disconnect(struct usb_serial *serial) 464static void qt2_disconnect(struct usb_serial *serial)
465{ 465{
466 struct qt2_serial_private *serial_priv = usb_get_serial_data(serial); 466 struct qt2_serial_private *serial_priv = usb_get_serial_data(serial);
467 struct qt2_port_private *port_priv;
468 int i;
469 467
470 if (serial_priv->read_urb->status == -EINPROGRESS) 468 if (serial_priv->read_urb->status == -EINPROGRESS)
471 usb_kill_urb(serial_priv->read_urb); 469 usb_kill_urb(serial_priv->read_urb);
472
473 usb_free_urb(serial_priv->read_urb);
474
475 for (i = 0; i < serial->num_ports; i++) {
476 port_priv = usb_get_serial_port_data(serial->port[i]);
477
478 if (port_priv->write_urb->status == -EINPROGRESS)
479 usb_kill_urb(port_priv->write_urb);
480 usb_free_urb(port_priv->write_urb);
481 }
482} 470}
483 471
484static int get_serial_info(struct usb_serial_port *port, 472static int get_serial_info(struct usb_serial_port *port,
@@ -773,11 +761,9 @@ static void qt2_read_bulk_callback(struct urb *urb)
773 761
774static int qt2_setup_urbs(struct usb_serial *serial) 762static int qt2_setup_urbs(struct usb_serial *serial)
775{ 763{
776 struct usb_serial_port *port;
777 struct usb_serial_port *port0; 764 struct usb_serial_port *port0;
778 struct qt2_serial_private *serial_priv; 765 struct qt2_serial_private *serial_priv;
779 struct qt2_port_private *port_priv; 766 int status;
780 int pcount, status;
781 767
782 port0 = serial->port[0]; 768 port0 = serial->port[0];
783 769
@@ -795,30 +781,6 @@ static int qt2_setup_urbs(struct usb_serial *serial)
795 sizeof(serial_priv->read_buffer), 781 sizeof(serial_priv->read_buffer),
796 qt2_read_bulk_callback, serial); 782 qt2_read_bulk_callback, serial);
797 783
798 /* setup write_urb for each port */
799 for (pcount = 0; pcount < serial->num_ports; pcount++) {
800
801 port = serial->port[pcount];
802 port_priv = usb_get_serial_port_data(port);
803
804 port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL);
805 if (!port_priv->write_urb) {
806 dev_err(&serial->dev->dev,
807 "failed to alloc write_urb for port %i\n",
808 pcount);
809 return -ENOMEM;
810 }
811
812 usb_fill_bulk_urb(port_priv->write_urb,
813 serial->dev,
814 usb_sndbulkpipe(serial->dev,
815 port0->
816 bulk_out_endpointAddress),
817 port_priv->write_buffer,
818 sizeof(port_priv->write_buffer),
819 qt2_write_bulk_callback, port);
820 }
821
822 status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL); 784 status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL);
823 if (status != 0) { 785 if (status != 0) {
824 dev_err(&serial->dev->dev, 786 dev_err(&serial->dev->dev,
@@ -828,14 +790,12 @@ static int qt2_setup_urbs(struct usb_serial *serial)
828 } 790 }
829 791
830 return 0; 792 return 0;
831
832} 793}
833 794
834static int qt2_attach(struct usb_serial *serial) 795static int qt2_attach(struct usb_serial *serial)
835{ 796{
836 struct qt2_serial_private *serial_priv; 797 struct qt2_serial_private *serial_priv;
837 struct qt2_port_private *port_priv; 798 int status;
838 int status, pcount;
839 799
840 /* power on unit */ 800 /* power on unit */
841 status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 801 status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
@@ -855,26 +815,6 @@ static int qt2_attach(struct usb_serial *serial)
855 815
856 usb_set_serial_data(serial, serial_priv); 816 usb_set_serial_data(serial, serial_priv);
857 817
858 for (pcount = 0; pcount < serial->num_ports; pcount++) {
859 port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL);
860 if (!port_priv) {
861 dev_err(&serial->dev->dev,
862 "%s- kmalloc(%Zd) failed.\n", __func__,
863 sizeof(*port_priv));
864 pcount--;
865 status = -ENOMEM;
866 goto attach_failed;
867 }
868
869 spin_lock_init(&port_priv->lock);
870 spin_lock_init(&port_priv->urb_lock);
871 init_waitqueue_head(&port_priv->delta_msr_wait);
872
873 port_priv->port = serial->port[pcount];
874
875 usb_set_serial_port_data(serial->port[pcount], port_priv);
876 }
877
878 status = qt2_setup_urbs(serial); 818 status = qt2_setup_urbs(serial);
879 if (status != 0) 819 if (status != 0)
880 goto attach_failed; 820 goto attach_failed;
@@ -882,14 +822,53 @@ static int qt2_attach(struct usb_serial *serial)
882 return 0; 822 return 0;
883 823
884attach_failed: 824attach_failed:
885 for (/* empty */; pcount >= 0; pcount--) {
886 port_priv = usb_get_serial_port_data(serial->port[pcount]);
887 kfree(port_priv);
888 }
889 kfree(serial_priv); 825 kfree(serial_priv);
890 return status; 826 return status;
891} 827}
892 828
829static int qt2_port_probe(struct usb_serial_port *port)
830{
831 struct usb_serial *serial = port->serial;
832 struct qt2_port_private *port_priv;
833 u8 bEndpointAddress;
834
835 port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL);
836 if (!port_priv)
837 return -ENOMEM;
838
839 spin_lock_init(&port_priv->lock);
840 spin_lock_init(&port_priv->urb_lock);
841 init_waitqueue_head(&port_priv->delta_msr_wait);
842 port_priv->port = port;
843
844 port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL);
845 if (!port_priv->write_urb) {
846 kfree(port_priv);
847 return -ENOMEM;
848 }
849 bEndpointAddress = serial->port[0]->bulk_out_endpointAddress;
850 usb_fill_bulk_urb(port_priv->write_urb, serial->dev,
851 usb_sndbulkpipe(serial->dev, bEndpointAddress),
852 port_priv->write_buffer,
853 sizeof(port_priv->write_buffer),
854 qt2_write_bulk_callback, port);
855
856 usb_set_serial_port_data(port, port_priv);
857
858 return 0;
859}
860
861static int qt2_port_remove(struct usb_serial_port *port)
862{
863 struct qt2_port_private *port_priv;
864
865 port_priv = usb_get_serial_port_data(port);
866 usb_free_urb(port_priv->write_urb);
867 kfree(port_priv);
868
869 return 0;
870}
871
893static int qt2_tiocmget(struct tty_struct *tty) 872static int qt2_tiocmget(struct tty_struct *tty)
894{ 873{
895 struct usb_serial_port *port = tty->driver_data; 874 struct usb_serial_port *port = tty->driver_data;
@@ -1128,6 +1107,8 @@ static struct usb_serial_driver qt2_device = {
1128 .attach = qt2_attach, 1107 .attach = qt2_attach,
1129 .release = qt2_release, 1108 .release = qt2_release,
1130 .disconnect = qt2_disconnect, 1109 .disconnect = qt2_disconnect,
1110 .port_probe = qt2_port_probe,
1111 .port_remove = qt2_port_remove,
1131 .dtr_rts = qt2_dtr_rts, 1112 .dtr_rts = qt2_dtr_rts,
1132 .break_ctl = qt2_break_ctl, 1113 .break_ctl = qt2_break_ctl,
1133 .tiocmget = qt2_tiocmget, 1114 .tiocmget = qt2_tiocmget,