aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/sierra.c
diff options
context:
space:
mode:
authorElina Pasheva <epasheva@sierrawireless.com>2009-05-12 16:12:54 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:45 -0400
commit9636b683769a6c3acfe121314ee9d7e19157f109 (patch)
tree4355b5ef7afc7f000ae4e18659bde41c4164f315 /drivers/usb/serial/sierra.c
parentc76a23da8e9a39222c4a7c29b0c5348cd8902a2b (diff)
USB: serial: sierra driver sierra_calc_num_ports() fix
- Removed potential kernel oops from sierra_calc_num_ports() function. Calling this function twice would likely have caused an oops because the function releases allocated memory after the first call. - Modified sierra_probe() function to reflect the changes in sierra_calc_num_ports(). Signed-off-by: Elina Pasheva <epasheva@sierrawireless.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/sierra.c')
-rw-r--r--drivers/usb/serial/sierra.c49
1 files changed, 14 insertions, 35 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index bcfe0ac1e221..f047ab5fa97b 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -83,18 +83,22 @@ static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable)
83 83
84static int sierra_calc_num_ports(struct usb_serial *serial) 84static int sierra_calc_num_ports(struct usb_serial *serial)
85{ 85{
86 int result; 86 int num_ports = 0;
87 int *num_ports = usb_get_serial_data(serial); 87 u8 ifnum, numendpoints;
88 dev_dbg(&serial->dev->dev, "%s\n", __func__);
89 88
90 result = *num_ports; 89 dev_dbg(&serial->dev->dev, "%s\n", __func__);
91 90
92 if (result) { 91 ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
93 kfree(num_ports); 92 numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints;
94 usb_set_serial_data(serial, NULL);
95 }
96 93
97 return result; 94 /* Dummy interface present on some SKUs should be ignored */
95 if (ifnum == 0x99)
96 num_ports = 0;
97 else if (numendpoints <= 3)
98 num_ports = 1;
99 else
100 num_ports = (numendpoints-1)/2;
101 return num_ports;
98} 102}
99 103
100static int is_blacklisted(const u8 ifnum, 104static int is_blacklisted(const u8 ifnum,
@@ -140,23 +144,12 @@ static int sierra_probe(struct usb_serial *serial,
140{ 144{
141 int result = 0; 145 int result = 0;
142 struct usb_device *udev; 146 struct usb_device *udev;
143 int *num_ports;
144 u8 ifnum; 147 u8 ifnum;
145 u8 numendpoints;
146
147 dev_dbg(&serial->dev->dev, "%s\n", __func__);
148 148
149 num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL);
150 if (!num_ports)
151 return -ENOMEM;
152
153 ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
154 numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints;
155 udev = serial->dev; 149 udev = serial->dev;
150 dev_dbg(&udev->dev, "%s\n", __func__);
156 151
157 /* Figure out the interface number from the serial structure */
158 ifnum = sierra_calc_interface(serial); 152 ifnum = sierra_calc_interface(serial);
159
160 /* 153 /*
161 * If this interface supports more than 1 alternate 154 * If this interface supports more than 1 alternate
162 * select the 2nd one 155 * select the 2nd one
@@ -168,20 +161,6 @@ static int sierra_probe(struct usb_serial *serial,
168 usb_set_interface(udev, ifnum, 1); 161 usb_set_interface(udev, ifnum, 1);
169 } 162 }
170 163
171 /* Dummy interface present on some SKUs should be ignored */
172 if (ifnum == 0x99)
173 *num_ports = 0;
174 else if (numendpoints <= 3)
175 *num_ports = 1;
176 else
177 *num_ports = (numendpoints-1)/2;
178
179 /*
180 * save off our num_ports info so that we can use it in the
181 * calc_num_ports callback
182 */
183 usb_set_serial_data(serial, (void *)num_ports);
184
185 /* ifnum could have changed - by calling usb_set_interface */ 164 /* ifnum could have changed - by calling usb_set_interface */
186 ifnum = sierra_calc_interface(serial); 165 ifnum = sierra_calc_interface(serial);
187 166