aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorOliver Neukum <oneukum@suse.de>2007-03-29 05:23:54 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-04-27 16:28:38 -0400
commit9306fff17d3852e088dfc512e6f6673f3d80e71e (patch)
treeb682c2103a2ddfbab2e7186fd462812c8c106739 /drivers
parent5a9f4e338179e75e7e9b56293acb17023e342d81 (diff)
USB: fix error handling in kl5kusb
- report errors - cleanup in error case - use of endianness macros Signed-off-by: Oliver Neukum <oneukum@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/serial/kl5kusb105.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index b2097c45a235..7b085f334ceb 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -238,7 +238,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
238 if (rc < 0) 238 if (rc < 0)
239 err("Reading line status failed (error = %d)", rc); 239 err("Reading line status failed (error = %d)", rc);
240 else { 240 else {
241 status = status_buf[0] + (status_buf[1]<<8); 241 status = le16_to_cpu(*(u16 *)status_buf);
242 242
243 info("%s - read status %x %x", __FUNCTION__, 243 info("%s - read status %x %x", __FUNCTION__,
244 status_buf[0], status_buf[1]); 244 status_buf[0], status_buf[1]);
@@ -257,7 +257,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
257static int klsi_105_startup (struct usb_serial *serial) 257static int klsi_105_startup (struct usb_serial *serial)
258{ 258{
259 struct klsi_105_private *priv; 259 struct klsi_105_private *priv;
260 int i; 260 int i, j;
261 261
262 /* check if we support the product id (see keyspan.c) 262 /* check if we support the product id (see keyspan.c)
263 * FIXME 263 * FIXME
@@ -265,12 +265,12 @@ static int klsi_105_startup (struct usb_serial *serial)
265 265
266 /* allocate the private data structure */ 266 /* allocate the private data structure */
267 for (i=0; i<serial->num_ports; i++) { 267 for (i=0; i<serial->num_ports; i++) {
268 int j;
269 priv = kmalloc(sizeof(struct klsi_105_private), 268 priv = kmalloc(sizeof(struct klsi_105_private),
270 GFP_KERNEL); 269 GFP_KERNEL);
271 if (!priv) { 270 if (!priv) {
272 dbg("%skmalloc for klsi_105_private failed.", __FUNCTION__); 271 dbg("%skmalloc for klsi_105_private failed.", __FUNCTION__);
273 return -ENOMEM; 272 i--;
273 goto err_cleanup;
274 } 274 }
275 /* set initial values for control structures */ 275 /* set initial values for control structures */
276 priv->cfg.pktlen = 5; 276 priv->cfg.pktlen = 5;
@@ -292,15 +292,14 @@ static int klsi_105_startup (struct usb_serial *serial)
292 priv->write_urb_pool[j] = urb; 292 priv->write_urb_pool[j] = urb;
293 if (urb == NULL) { 293 if (urb == NULL) {
294 err("No more urbs???"); 294 err("No more urbs???");
295 continue; 295 goto err_cleanup;
296 } 296 }
297 297
298 urb->transfer_buffer = NULL;
299 urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, 298 urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE,
300 GFP_KERNEL); 299 GFP_KERNEL);
301 if (!urb->transfer_buffer) { 300 if (!urb->transfer_buffer) {
302 err("%s - out of memory for urb buffers.", __FUNCTION__); 301 err("%s - out of memory for urb buffers.", __FUNCTION__);
303 continue; 302 goto err_cleanup;
304 } 303 }
305 } 304 }
306 305
@@ -308,7 +307,20 @@ static int klsi_105_startup (struct usb_serial *serial)
308 init_waitqueue_head(&serial->port[i]->write_wait); 307 init_waitqueue_head(&serial->port[i]->write_wait);
309 } 308 }
310 309
311 return (0); 310 return 0;
311
312err_cleanup:
313 for (; i >= 0; i--) {
314 priv = usb_get_serial_port_data(serial->port[i]);
315 for (j=0; j < NUM_URBS; j++) {
316 if (priv->write_urb_pool[j]) {
317 kfree(priv->write_urb_pool[j]->transfer_buffer);
318 usb_free_urb(priv->write_urb_pool[j]);
319 }
320 }
321 usb_set_serial_port_data(serial->port[i], NULL);
322 }
323 return -ENOMEM;
312} /* klsi_105_startup */ 324} /* klsi_105_startup */
313 325
314 326