Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Oliver Neukum and committed by
Greg Kroah-Hartman
9306fff1 5a9f4e33

+20 -8
+20 -8
drivers/usb/serial/kl5kusb105.c
··· 238 238 if (rc < 0) 239 239 err("Reading line status failed (error = %d)", rc); 240 240 else { 241 - status = status_buf[0] + (status_buf[1]<<8); 241 + status = le16_to_cpu(*(u16 *)status_buf); 242 242 243 243 info("%s - read status %x %x", __FUNCTION__, 244 244 status_buf[0], status_buf[1]); ··· 257 257 static int klsi_105_startup (struct usb_serial *serial) 258 258 { 259 259 struct klsi_105_private *priv; 260 - int i; 260 + int i, j; 261 261 262 262 /* check if we support the product id (see keyspan.c) 263 263 * FIXME ··· 265 265 266 266 /* allocate the private data structure */ 267 267 for (i=0; i<serial->num_ports; i++) { 268 - int j; 269 268 priv = kmalloc(sizeof(struct klsi_105_private), 270 269 GFP_KERNEL); 271 270 if (!priv) { 272 271 dbg("%skmalloc for klsi_105_private failed.", __FUNCTION__); 273 - return -ENOMEM; 272 + i--; 273 + goto err_cleanup; 274 274 } 275 275 /* set initial values for control structures */ 276 276 priv->cfg.pktlen = 5; ··· 292 292 priv->write_urb_pool[j] = urb; 293 293 if (urb == NULL) { 294 294 err("No more urbs???"); 295 - continue; 295 + goto err_cleanup; 296 296 } 297 297 298 - urb->transfer_buffer = NULL; 299 298 urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, 300 299 GFP_KERNEL); 301 300 if (!urb->transfer_buffer) { 302 301 err("%s - out of memory for urb buffers.", __FUNCTION__); 303 - continue; 302 + goto err_cleanup; 304 303 } 305 304 } 306 305 ··· 307 308 init_waitqueue_head(&serial->port[i]->write_wait); 308 309 } 309 310 310 - return (0); 311 + return 0; 312 + 313 + err_cleanup: 314 + for (; i >= 0; i--) { 315 + priv = usb_get_serial_port_data(serial->port[i]); 316 + for (j=0; j < NUM_URBS; j++) { 317 + if (priv->write_urb_pool[j]) { 318 + kfree(priv->write_urb_pool[j]->transfer_buffer); 319 + usb_free_urb(priv->write_urb_pool[j]); 320 + } 321 + } 322 + usb_set_serial_port_data(serial->port[i], NULL); 323 + } 324 + return -ENOMEM; 311 325 } /* klsi_105_startup */ 312 326 313 327