aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt73usb.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-06-20 16:11:00 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-25 10:56:16 -0400
commit99ade2597e3f7f0ad463c489aaccd6cc605e242c (patch)
treea644c9c689cded6ebdb46953180af82d7d3fcdd4 /drivers/net/wireless/rt2x00/rt73usb.c
parent2f9ec47d0954f9d2e5a00209c2689cbc477a8c89 (diff)
rt2x00: Fix unbalanced mutex locking
The usb_cache_mutex was not correctly released under all circumstances. Both rt73usb as rt2500usb didn't release the mutex under certain conditions when the register access failed. Obviously such failure would lead to deadlocks. In addition under similar circumstances when the bbp register couldn't be read the value must be set to 0xff to indicate that the value is wrong. This too didn't happen under all circumstances. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt73usb.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index fff8386e816b..83cc0147f698 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -134,11 +134,8 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
134 * Wait until the BBP becomes ready. 134 * Wait until the BBP becomes ready.
135 */ 135 */
136 reg = rt73usb_bbp_check(rt2x00dev); 136 reg = rt73usb_bbp_check(rt2x00dev);
137 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { 137 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
138 ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); 138 goto exit_fail;
139 mutex_unlock(&rt2x00dev->usb_cache_mutex);
140 return;
141 }
142 139
143 /* 140 /*
144 * Write the data into the BBP. 141 * Write the data into the BBP.
@@ -151,6 +148,13 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
151 148
152 rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); 149 rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
153 mutex_unlock(&rt2x00dev->usb_cache_mutex); 150 mutex_unlock(&rt2x00dev->usb_cache_mutex);
151
152 return;
153
154exit_fail:
155 mutex_unlock(&rt2x00dev->usb_cache_mutex);
156
157 ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
154} 158}
155 159
156static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, 160static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -164,11 +168,8 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
164 * Wait until the BBP becomes ready. 168 * Wait until the BBP becomes ready.
165 */ 169 */
166 reg = rt73usb_bbp_check(rt2x00dev); 170 reg = rt73usb_bbp_check(rt2x00dev);
167 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { 171 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
168 ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); 172 goto exit_fail;
169 mutex_unlock(&rt2x00dev->usb_cache_mutex);
170 return;
171 }
172 173
173 /* 174 /*
174 * Write the request into the BBP. 175 * Write the request into the BBP.
@@ -184,14 +185,19 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
184 * Wait until the BBP becomes ready. 185 * Wait until the BBP becomes ready.
185 */ 186 */
186 reg = rt73usb_bbp_check(rt2x00dev); 187 reg = rt73usb_bbp_check(rt2x00dev);
187 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { 188 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
188 ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); 189 goto exit_fail;
189 *value = 0xff;
190 return;
191 }
192 190
193 *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); 191 *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
194 mutex_unlock(&rt2x00dev->usb_cache_mutex); 192 mutex_unlock(&rt2x00dev->usb_cache_mutex);
193
194 return;
195
196exit_fail:
197 mutex_unlock(&rt2x00dev->usb_cache_mutex);
198
199 ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
200 *value = 0xff;
195} 201}
196 202
197static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, 203static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,