diff options
author | Elina Pasheva <epasheva@sierrawireless.com> | 2009-05-12 16:12:54 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:45 -0400 |
commit | 9636b683769a6c3acfe121314ee9d7e19157f109 (patch) | |
tree | 4355b5ef7afc7f000ae4e18659bde41c4164f315 /drivers/usb/serial/sierra.c | |
parent | c76a23da8e9a39222c4a7c29b0c5348cd8902a2b (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.c | 49 |
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 | ||
84 | static int sierra_calc_num_ports(struct usb_serial *serial) | 84 | static 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 | ||
100 | static int is_blacklisted(const u8 ifnum, | 104 | static 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 | ||