[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-ti33x-psp-3.2 / 3.2.3 / 0046-USB-cdc-wdm-use-two-mutexes-to-allow-simultaneous-re.patch
1 From 4fa7700c9a0aaa37a3071ae7debbc6ba9a30488b Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
3 Date: Mon, 16 Jan 2012 12:41:48 +0100
4 Subject: [PATCH 46/90] USB: cdc-wdm: use two mutexes to allow simultaneous
5 read and write
6 MIME-Version: 1.0
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
10 commit e8537bd2c4f325a4796da33564ddcef9489b7feb upstream.
12 using a separate read and write mutex for locking is sufficient to make the
13 driver accept simultaneous read and write. This improves useability a lot.
15 Signed-off-by: Bjørn Mork <bjorn@mork.no>
16 Cc: Oliver Neukum <oneukum@suse.de>
17 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
18 ---
19 drivers/usb/class/cdc-wdm.c | 49 +++++++++++++++++++++++++++----------------
20 1 file changed, 31 insertions(+), 18 deletions(-)
22 diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
23 index 7e5e822..4a29a80 100644
24 --- a/drivers/usb/class/cdc-wdm.c
25 +++ b/drivers/usb/class/cdc-wdm.c
26 @@ -88,7 +88,8 @@ struct wdm_device {
27 int count;
28 dma_addr_t shandle;
29 dma_addr_t ihandle;
30 - struct mutex lock;
31 + struct mutex wlock;
32 + struct mutex rlock;
33 wait_queue_head_t wait;
34 struct work_struct rxwork;
35 int werr;
36 @@ -323,7 +324,7 @@ static ssize_t wdm_write
37 }
39 /* concurrent writes and disconnect */
40 - r = mutex_lock_interruptible(&desc->lock);
41 + r = mutex_lock_interruptible(&desc->wlock);
42 rv = -ERESTARTSYS;
43 if (r) {
44 kfree(buf);
45 @@ -386,7 +387,7 @@ static ssize_t wdm_write
46 out:
47 usb_autopm_put_interface(desc->intf);
48 outnp:
49 - mutex_unlock(&desc->lock);
50 + mutex_unlock(&desc->wlock);
51 outnl:
52 return rv < 0 ? rv : count;
53 }
54 @@ -399,7 +400,7 @@ static ssize_t wdm_read
55 struct wdm_device *desc = file->private_data;
58 - rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */
59 + rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */
60 if (rv < 0)
61 return -ERESTARTSYS;
63 @@ -476,7 +477,7 @@ retry:
64 rv = cntr;
66 err:
67 - mutex_unlock(&desc->lock);
68 + mutex_unlock(&desc->rlock);
69 return rv;
70 }
72 @@ -542,7 +543,8 @@ static int wdm_open(struct inode *inode, struct file *file)
73 }
74 intf->needs_remote_wakeup = 1;
76 - mutex_lock(&desc->lock);
77 + /* using write lock to protect desc->count */
78 + mutex_lock(&desc->wlock);
79 if (!desc->count++) {
80 desc->werr = 0;
81 desc->rerr = 0;
82 @@ -555,7 +557,7 @@ static int wdm_open(struct inode *inode, struct file *file)
83 } else {
84 rv = 0;
85 }
86 - mutex_unlock(&desc->lock);
87 + mutex_unlock(&desc->wlock);
88 usb_autopm_put_interface(desc->intf);
89 out:
90 mutex_unlock(&wdm_mutex);
91 @@ -567,9 +569,11 @@ static int wdm_release(struct inode *inode, struct file *file)
92 struct wdm_device *desc = file->private_data;
94 mutex_lock(&wdm_mutex);
95 - mutex_lock(&desc->lock);
96 +
97 + /* using write lock to protect desc->count */
98 + mutex_lock(&desc->wlock);
99 desc->count--;
100 - mutex_unlock(&desc->lock);
101 + mutex_unlock(&desc->wlock);
103 if (!desc->count) {
104 dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
105 @@ -667,7 +671,8 @@ next_desc:
106 desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
107 if (!desc)
108 goto out;
109 - mutex_init(&desc->lock);
110 + mutex_init(&desc->rlock);
111 + mutex_init(&desc->wlock);
112 spin_lock_init(&desc->iuspin);
113 init_waitqueue_head(&desc->wait);
114 desc->wMaxCommand = maxcom;
115 @@ -781,10 +786,12 @@ static void wdm_disconnect(struct usb_interface *intf)
116 /* to terminate pending flushes */
117 clear_bit(WDM_IN_USE, &desc->flags);
118 spin_unlock_irqrestore(&desc->iuspin, flags);
119 - mutex_lock(&desc->lock);
120 + mutex_lock(&desc->rlock);
121 + mutex_lock(&desc->wlock);
122 kill_urbs(desc);
123 cancel_work_sync(&desc->rxwork);
124 - mutex_unlock(&desc->lock);
125 + mutex_unlock(&desc->wlock);
126 + mutex_unlock(&desc->rlock);
127 wake_up_all(&desc->wait);
128 if (!desc->count)
129 cleanup(desc);
130 @@ -800,8 +807,10 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
131 dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
133 /* if this is an autosuspend the caller does the locking */
134 - if (!PMSG_IS_AUTO(message))
135 - mutex_lock(&desc->lock);
136 + if (!PMSG_IS_AUTO(message)) {
137 + mutex_lock(&desc->rlock);
138 + mutex_lock(&desc->wlock);
139 + }
140 spin_lock_irq(&desc->iuspin);
142 if (PMSG_IS_AUTO(message) &&
143 @@ -817,8 +826,10 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
144 kill_urbs(desc);
145 cancel_work_sync(&desc->rxwork);
146 }
147 - if (!PMSG_IS_AUTO(message))
148 - mutex_unlock(&desc->lock);
149 + if (!PMSG_IS_AUTO(message)) {
150 + mutex_unlock(&desc->wlock);
151 + mutex_unlock(&desc->rlock);
152 + }
154 return rv;
155 }
156 @@ -856,7 +867,8 @@ static int wdm_pre_reset(struct usb_interface *intf)
157 {
158 struct wdm_device *desc = usb_get_intfdata(intf);
160 - mutex_lock(&desc->lock);
161 + mutex_lock(&desc->rlock);
162 + mutex_lock(&desc->wlock);
163 kill_urbs(desc);
165 /*
166 @@ -878,7 +890,8 @@ static int wdm_post_reset(struct usb_interface *intf)
167 int rv;
169 rv = recover_from_urb_loss(desc);
170 - mutex_unlock(&desc->lock);
171 + mutex_unlock(&desc->wlock);
172 + mutex_unlock(&desc->rlock);
173 return 0;
174 }
176 --
177 1.7.9.4