diff options
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 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, | |||
257 | static int klsi_105_startup (struct usb_serial *serial) | 257 | static 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 | |||
312 | err_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 | ||