aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/cdc-wdm.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-10 14:12:55 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-10 14:13:53 -0500
commit7483948fdd31a8642ef0288aab6f368b98d53c29 (patch)
tree031020a5553701d2aae8dddb0fa509aa65854eb1 /drivers/usb/class/cdc-wdm.c
parent22a416c4e0f2179b57028e084ac0ed2c110333bd (diff)
parentfe250923bbbbcbccc9aa7b84d05ee7a060450534 (diff)
Merge tag 'usb-3.3-rc3' into usb-next
This is done to resolve a merge conflict with: drivers/usb/class/cdc-wdm.c and to better handle future patches for this driver as it is under active development at the moment. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/class/cdc-wdm.c')
-rw-r--r--drivers/usb/class/cdc-wdm.c53
1 files changed, 34 insertions, 19 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 23cf9d38eb54..f63601a2054c 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -105,7 +105,8 @@ struct wdm_device {
105 int count; 105 int count;
106 dma_addr_t shandle; 106 dma_addr_t shandle;
107 dma_addr_t ihandle; 107 dma_addr_t ihandle;
108 struct mutex lock; 108 struct mutex wlock;
109 struct mutex rlock;
109 wait_queue_head_t wait; 110 wait_queue_head_t wait;
110 struct work_struct rxwork; 111 struct work_struct rxwork;
111 int werr; 112 int werr;
@@ -314,7 +315,7 @@ static ssize_t wdm_write
314 } 315 }
315 316
316 /* concurrent writes and disconnect */ 317 /* concurrent writes and disconnect */
317 r = mutex_lock_interruptible(&desc->lock); 318 r = mutex_lock_interruptible(&desc->wlock);
318 rv = -ERESTARTSYS; 319 rv = -ERESTARTSYS;
319 if (r) { 320 if (r) {
320 kfree(buf); 321 kfree(buf);
@@ -377,7 +378,7 @@ static ssize_t wdm_write
377out: 378out:
378 usb_autopm_put_interface(desc->intf); 379 usb_autopm_put_interface(desc->intf);
379outnp: 380outnp:
380 mutex_unlock(&desc->lock); 381 mutex_unlock(&desc->wlock);
381outnl: 382outnl:
382 return rv < 0 ? rv : count; 383 return rv < 0 ? rv : count;
383} 384}
@@ -390,7 +391,7 @@ static ssize_t wdm_read
390 struct wdm_device *desc = file->private_data; 391 struct wdm_device *desc = file->private_data;
391 392
392 393
393 rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */ 394 rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */
394 if (rv < 0) 395 if (rv < 0)
395 return -ERESTARTSYS; 396 return -ERESTARTSYS;
396 397
@@ -458,14 +459,16 @@ retry:
458 for (i = 0; i < desc->length - cntr; i++) 459 for (i = 0; i < desc->length - cntr; i++)
459 desc->ubuf[i] = desc->ubuf[i + cntr]; 460 desc->ubuf[i] = desc->ubuf[i + cntr];
460 461
462 spin_lock_irq(&desc->iuspin);
461 desc->length -= cntr; 463 desc->length -= cntr;
464 spin_unlock_irq(&desc->iuspin);
462 /* in case we had outstanding data */ 465 /* in case we had outstanding data */
463 if (!desc->length) 466 if (!desc->length)
464 clear_bit(WDM_READ, &desc->flags); 467 clear_bit(WDM_READ, &desc->flags);
465 rv = cntr; 468 rv = cntr;
466 469
467err: 470err:
468 mutex_unlock(&desc->lock); 471 mutex_unlock(&desc->rlock);
469 return rv; 472 return rv;
470} 473}
471 474
@@ -531,7 +534,8 @@ static int wdm_open(struct inode *inode, struct file *file)
531 } 534 }
532 intf->needs_remote_wakeup = 1; 535 intf->needs_remote_wakeup = 1;
533 536
534 mutex_lock(&desc->lock); 537 /* using write lock to protect desc->count */
538 mutex_lock(&desc->wlock);
535 if (!desc->count++) { 539 if (!desc->count++) {
536 desc->werr = 0; 540 desc->werr = 0;
537 desc->rerr = 0; 541 desc->rerr = 0;
@@ -544,7 +548,7 @@ static int wdm_open(struct inode *inode, struct file *file)
544 } else { 548 } else {
545 rv = 0; 549 rv = 0;
546 } 550 }
547 mutex_unlock(&desc->lock); 551 mutex_unlock(&desc->wlock);
548 usb_autopm_put_interface(desc->intf); 552 usb_autopm_put_interface(desc->intf);
549out: 553out:
550 mutex_unlock(&wdm_mutex); 554 mutex_unlock(&wdm_mutex);
@@ -556,9 +560,11 @@ static int wdm_release(struct inode *inode, struct file *file)
556 struct wdm_device *desc = file->private_data; 560 struct wdm_device *desc = file->private_data;
557 561
558 mutex_lock(&wdm_mutex); 562 mutex_lock(&wdm_mutex);
559 mutex_lock(&desc->lock); 563
564 /* using write lock to protect desc->count */
565 mutex_lock(&desc->wlock);
560 desc->count--; 566 desc->count--;
561 mutex_unlock(&desc->lock); 567 mutex_unlock(&desc->wlock);
562 568
563 if (!desc->count) { 569 if (!desc->count) {
564 dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); 570 dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
@@ -655,7 +661,8 @@ next_desc:
655 desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); 661 desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
656 if (!desc) 662 if (!desc)
657 goto out; 663 goto out;
658 mutex_init(&desc->lock); 664 mutex_init(&desc->rlock);
665 mutex_init(&desc->wlock);
659 spin_lock_init(&desc->iuspin); 666 spin_lock_init(&desc->iuspin);
660 init_waitqueue_head(&desc->wait); 667 init_waitqueue_head(&desc->wait);
661 desc->wMaxCommand = maxcom; 668 desc->wMaxCommand = maxcom;
@@ -771,11 +778,13 @@ static void wdm_disconnect(struct usb_interface *intf)
771 /* to terminate pending flushes */ 778 /* to terminate pending flushes */
772 clear_bit(WDM_IN_USE, &desc->flags); 779 clear_bit(WDM_IN_USE, &desc->flags);
773 spin_unlock_irqrestore(&desc->iuspin, flags); 780 spin_unlock_irqrestore(&desc->iuspin, flags);
774 mutex_lock(&desc->lock); 781 wake_up_all(&desc->wait);
782 mutex_lock(&desc->rlock);
783 mutex_lock(&desc->wlock);
775 kill_urbs(desc); 784 kill_urbs(desc);
776 cancel_work_sync(&desc->rxwork); 785 cancel_work_sync(&desc->rxwork);
777 mutex_unlock(&desc->lock); 786 mutex_unlock(&desc->wlock);
778 wake_up_all(&desc->wait); 787 mutex_unlock(&desc->rlock);
779 if (!desc->count) 788 if (!desc->count)
780 cleanup(desc); 789 cleanup(desc);
781 mutex_unlock(&wdm_mutex); 790 mutex_unlock(&wdm_mutex);
@@ -790,8 +799,10 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
790 dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); 799 dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
791 800
792 /* if this is an autosuspend the caller does the locking */ 801 /* if this is an autosuspend the caller does the locking */
793 if (!PMSG_IS_AUTO(message)) 802 if (!PMSG_IS_AUTO(message)) {
794 mutex_lock(&desc->lock); 803 mutex_lock(&desc->rlock);
804 mutex_lock(&desc->wlock);
805 }
795 spin_lock_irq(&desc->iuspin); 806 spin_lock_irq(&desc->iuspin);
796 807
797 if (PMSG_IS_AUTO(message) && 808 if (PMSG_IS_AUTO(message) &&
@@ -807,8 +818,10 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
807 kill_urbs(desc); 818 kill_urbs(desc);
808 cancel_work_sync(&desc->rxwork); 819 cancel_work_sync(&desc->rxwork);
809 } 820 }
810 if (!PMSG_IS_AUTO(message)) 821 if (!PMSG_IS_AUTO(message)) {
811 mutex_unlock(&desc->lock); 822 mutex_unlock(&desc->wlock);
823 mutex_unlock(&desc->rlock);
824 }
812 825
813 return rv; 826 return rv;
814} 827}
@@ -846,7 +859,8 @@ static int wdm_pre_reset(struct usb_interface *intf)
846{ 859{
847 struct wdm_device *desc = usb_get_intfdata(intf); 860 struct wdm_device *desc = usb_get_intfdata(intf);
848 861
849 mutex_lock(&desc->lock); 862 mutex_lock(&desc->rlock);
863 mutex_lock(&desc->wlock);
850 kill_urbs(desc); 864 kill_urbs(desc);
851 865
852 /* 866 /*
@@ -868,7 +882,8 @@ static int wdm_post_reset(struct usb_interface *intf)
868 int rv; 882 int rv;
869 883
870 rv = recover_from_urb_loss(desc); 884 rv = recover_from_urb_loss(desc);
871 mutex_unlock(&desc->lock); 885 mutex_unlock(&desc->wlock);
886 mutex_unlock(&desc->rlock);
872 return 0; 887 return 0;
873} 888}
874 889