diff options
Diffstat (limited to 'drivers/usb/class/cdc-wdm.c')
-rw-r--r-- | drivers/usb/class/cdc-wdm.c | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index a051a7a2b1bd..61ea87917433 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -245,7 +245,7 @@ static void wdm_int_callback(struct urb *urb) | |||
245 | case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: | 245 | case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: |
246 | dev_dbg(&desc->intf->dev, | 246 | dev_dbg(&desc->intf->dev, |
247 | "NOTIFY_RESPONSE_AVAILABLE received: index %d len %d", | 247 | "NOTIFY_RESPONSE_AVAILABLE received: index %d len %d", |
248 | dr->wIndex, dr->wLength); | 248 | le16_to_cpu(dr->wIndex), le16_to_cpu(dr->wLength)); |
249 | break; | 249 | break; |
250 | 250 | ||
251 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: | 251 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: |
@@ -262,7 +262,9 @@ static void wdm_int_callback(struct urb *urb) | |||
262 | clear_bit(WDM_POLL_RUNNING, &desc->flags); | 262 | clear_bit(WDM_POLL_RUNNING, &desc->flags); |
263 | dev_err(&desc->intf->dev, | 263 | dev_err(&desc->intf->dev, |
264 | "unknown notification %d received: index %d len %d\n", | 264 | "unknown notification %d received: index %d len %d\n", |
265 | dr->bNotificationType, dr->wIndex, dr->wLength); | 265 | dr->bNotificationType, |
266 | le16_to_cpu(dr->wIndex), | ||
267 | le16_to_cpu(dr->wLength)); | ||
266 | goto exit; | 268 | goto exit; |
267 | } | 269 | } |
268 | 270 | ||
@@ -339,7 +341,7 @@ static ssize_t wdm_write | |||
339 | desc->werr = 0; | 341 | desc->werr = 0; |
340 | spin_unlock_irq(&desc->iuspin); | 342 | spin_unlock_irq(&desc->iuspin); |
341 | if (we < 0) | 343 | if (we < 0) |
342 | return -EIO; | 344 | return usb_translate_errors(we); |
343 | 345 | ||
344 | buf = kmalloc(count, GFP_KERNEL); | 346 | buf = kmalloc(count, GFP_KERNEL); |
345 | if (!buf) { | 347 | if (!buf) { |
@@ -349,30 +351,25 @@ static ssize_t wdm_write | |||
349 | 351 | ||
350 | r = copy_from_user(buf, buffer, count); | 352 | r = copy_from_user(buf, buffer, count); |
351 | if (r > 0) { | 353 | if (r > 0) { |
352 | kfree(buf); | ||
353 | rv = -EFAULT; | 354 | rv = -EFAULT; |
354 | goto outnl; | 355 | goto out_free_mem; |
355 | } | 356 | } |
356 | 357 | ||
357 | /* concurrent writes and disconnect */ | 358 | /* concurrent writes and disconnect */ |
358 | r = mutex_lock_interruptible(&desc->wlock); | 359 | r = mutex_lock_interruptible(&desc->wlock); |
359 | rv = -ERESTARTSYS; | 360 | rv = -ERESTARTSYS; |
360 | if (r) { | 361 | if (r) |
361 | kfree(buf); | 362 | goto out_free_mem; |
362 | goto outnl; | ||
363 | } | ||
364 | 363 | ||
365 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | 364 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { |
366 | kfree(buf); | ||
367 | rv = -ENODEV; | 365 | rv = -ENODEV; |
368 | goto outnp; | 366 | goto out_free_mem_lock; |
369 | } | 367 | } |
370 | 368 | ||
371 | r = usb_autopm_get_interface(desc->intf); | 369 | r = usb_autopm_get_interface(desc->intf); |
372 | if (r < 0) { | 370 | if (r < 0) { |
373 | kfree(buf); | ||
374 | rv = usb_translate_errors(r); | 371 | rv = usb_translate_errors(r); |
375 | goto outnp; | 372 | goto out_free_mem_lock; |
376 | } | 373 | } |
377 | 374 | ||
378 | if (!(file->f_flags & O_NONBLOCK)) | 375 | if (!(file->f_flags & O_NONBLOCK)) |
@@ -386,9 +383,8 @@ static ssize_t wdm_write | |||
386 | r = -EIO; | 383 | r = -EIO; |
387 | 384 | ||
388 | if (r < 0) { | 385 | if (r < 0) { |
389 | kfree(buf); | ||
390 | rv = r; | 386 | rv = r; |
391 | goto out; | 387 | goto out_free_mem_pm; |
392 | } | 388 | } |
393 | 389 | ||
394 | req = desc->orq; | 390 | req = desc->orq; |
@@ -408,28 +404,35 @@ static ssize_t wdm_write | |||
408 | USB_RECIP_INTERFACE); | 404 | USB_RECIP_INTERFACE); |
409 | req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND; | 405 | req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND; |
410 | req->wValue = 0; | 406 | req->wValue = 0; |
411 | req->wIndex = desc->inum; | 407 | req->wIndex = desc->inum; /* already converted */ |
412 | req->wLength = cpu_to_le16(count); | 408 | req->wLength = cpu_to_le16(count); |
413 | set_bit(WDM_IN_USE, &desc->flags); | 409 | set_bit(WDM_IN_USE, &desc->flags); |
414 | desc->outbuf = buf; | 410 | desc->outbuf = buf; |
415 | 411 | ||
416 | rv = usb_submit_urb(desc->command, GFP_KERNEL); | 412 | rv = usb_submit_urb(desc->command, GFP_KERNEL); |
417 | if (rv < 0) { | 413 | if (rv < 0) { |
418 | kfree(buf); | ||
419 | desc->outbuf = NULL; | 414 | desc->outbuf = NULL; |
420 | clear_bit(WDM_IN_USE, &desc->flags); | 415 | clear_bit(WDM_IN_USE, &desc->flags); |
421 | dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv); | 416 | dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv); |
422 | rv = usb_translate_errors(rv); | 417 | rv = usb_translate_errors(rv); |
418 | goto out_free_mem_pm; | ||
423 | } else { | 419 | } else { |
424 | dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d", | 420 | dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d", |
425 | req->wIndex); | 421 | le16_to_cpu(req->wIndex)); |
426 | } | 422 | } |
427 | out: | 423 | |
428 | usb_autopm_put_interface(desc->intf); | 424 | usb_autopm_put_interface(desc->intf); |
429 | outnp: | ||
430 | mutex_unlock(&desc->wlock); | 425 | mutex_unlock(&desc->wlock); |
431 | outnl: | 426 | outnl: |
432 | return rv < 0 ? rv : count; | 427 | return rv < 0 ? rv : count; |
428 | |||
429 | out_free_mem_pm: | ||
430 | usb_autopm_put_interface(desc->intf); | ||
431 | out_free_mem_lock: | ||
432 | mutex_unlock(&desc->wlock); | ||
433 | out_free_mem: | ||
434 | kfree(buf); | ||
435 | return rv; | ||
433 | } | 436 | } |
434 | 437 | ||
435 | /* | 438 | /* |
@@ -519,9 +522,9 @@ retry: | |||
519 | spin_lock_irq(&desc->iuspin); | 522 | spin_lock_irq(&desc->iuspin); |
520 | 523 | ||
521 | if (desc->rerr) { /* read completed, error happened */ | 524 | if (desc->rerr) { /* read completed, error happened */ |
525 | rv = usb_translate_errors(desc->rerr); | ||
522 | desc->rerr = 0; | 526 | desc->rerr = 0; |
523 | spin_unlock_irq(&desc->iuspin); | 527 | spin_unlock_irq(&desc->iuspin); |
524 | rv = -EIO; | ||
525 | goto err; | 528 | goto err; |
526 | } | 529 | } |
527 | /* | 530 | /* |
@@ -820,7 +823,7 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor | |||
820 | desc->irq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); | 823 | desc->irq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); |
821 | desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; | 824 | desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; |
822 | desc->irq->wValue = 0; | 825 | desc->irq->wValue = 0; |
823 | desc->irq->wIndex = desc->inum; | 826 | desc->irq->wIndex = desc->inum; /* already converted */ |
824 | desc->irq->wLength = cpu_to_le16(desc->wMaxCommand); | 827 | desc->irq->wLength = cpu_to_le16(desc->wMaxCommand); |
825 | 828 | ||
826 | usb_fill_control_urb( | 829 | usb_fill_control_urb( |