diff options
author | Oliver Neukum <oneukum@suse.de> | 2007-03-29 11:23:54 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-04-27 13:28:38 -0700 |
commit | 9306fff17d3852e088dfc512e6f6673f3d80e71e (patch) | |
tree | b682c2103a2ddfbab2e7186fd462812c8c106739 /drivers/usb/serial/kl5kusb105.c | |
parent | 5a9f4e338179e75e7e9b56293acb17023e342d81 (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/usb/serial/kl5kusb105.c')
-rw-r--r-- | drivers/usb/serial/kl5kusb105.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index b2097c45a23..7b085f334ce 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, if (rc < 0) err("Reading line status failed (error = %d)", rc); else { - status = status_buf[0] + (status_buf[1]<<8); + status = le16_to_cpu(*(u16 *)status_buf); info("%s - read status %x %x", __FUNCTION__, status_buf[0], status_buf[1]); @@ -257,7 +257,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, static int klsi_105_startup (struct usb_serial *serial) { struct klsi_105_private *priv; - int i; + int i, j; /* check if we support the product id (see keyspan.c) * FIXME @@ -265,12 +265,12 @@ static int klsi_105_startup (struct usb_serial *serial) /* allocate the private data structure */ for (i=0; i<serial->num_ports; i++) { - int j; priv = kmalloc(sizeof(struct klsi_105_private), GFP_KERNEL); if (!priv) { dbg("%skmalloc for klsi_105_private failed.", __FUNCTION__); - return -ENOMEM; + i--; + goto err_cleanup; } /* set initial values for control structures */ priv->cfg.pktlen = 5; @@ -292,15 +292,14 @@ static int klsi_105_startup (struct usb_serial *serial) priv->write_urb_pool[j] = urb; if (urb == NULL) { err("No more urbs???"); - continue; + goto err_cleanup; } - urb->transfer_buffer = NULL; urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); if (!urb->transfer_buffer) { err("%s - out of memory for urb buffers.", __FUNCTION__); - continue; + goto err_cleanup; } } @@ -308,7 +307,20 @@ static int klsi_105_startup (struct usb_serial *serial) init_waitqueue_head(&serial->port[i]->write_wait); } - return (0); + return 0; + +err_cleanup: + for (; i >= 0; i--) { + priv = usb_get_serial_port_data(serial->port[i]); + for (j=0; j < NUM_URBS; j++) { + if (priv->write_urb_pool[j]) { + kfree(priv->write_urb_pool[j]->transfer_buffer); + usb_free_urb(priv->write_urb_pool[j]); + } + } + usb_set_serial_port_data(serial->port[i], NULL); + } + return -ENOMEM; } /* klsi_105_startup */ |