aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2500usb.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-11-09 17:40:46 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-11-21 11:08:16 -0500
commit8ff48a8bbe4a1ba29dea2836dfce74660f97c1be (patch)
tree611c0e996813c59c229694b52d329c24829b80e8 /drivers/net/wireless/rt2x00/rt2500usb.c
parentbad13639a30e1557fbe9d440adc1906673c9de4e (diff)
rt2x00: Fix race condition when using inderect registers
Indirect registers require multiple calls to the CSR register in order to access the indirect registers. This must be protected under a lock to prevent race conditions which could cause invalid data to be returned when reading from the indirect register or silent failures when writing data to the indirect register. USB drivers where already protected under a mutex, so rename the mutex and make PCI drivers use the mutex as well. This now means that BBP and RF registers are no longer accessible in interrupt context. That is not a bad situation since the slow behavior of accessing those registers means we don't _want_ to access them in interrupt context either. 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/rt2500usb.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index c40c9e706e98..e6bae4ae4c47 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -47,7 +47,7 @@
47 * between each attampt. When the busy bit is still set at that time, 47 * between each attampt. When the busy bit is still set at that time,
48 * the access attempt is considered to have failed, 48 * the access attempt is considered to have failed,
49 * and we will print an error. 49 * and we will print an error.
50 * If the usb_cache_mutex is already held then the _lock variants must 50 * If the csr_mutex is already held then the _lock variants must
51 * be used instead. 51 * be used instead.
52 */ 52 */
53static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, 53static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
@@ -132,7 +132,7 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
132{ 132{
133 u16 reg; 133 u16 reg;
134 134
135 mutex_lock(&rt2x00dev->usb_cache_mutex); 135 mutex_lock(&rt2x00dev->csr_mutex);
136 136
137 /* 137 /*
138 * Wait until the BBP becomes ready. 138 * Wait until the BBP becomes ready.
@@ -151,12 +151,12 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
151 151
152 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); 152 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
153 153
154 mutex_unlock(&rt2x00dev->usb_cache_mutex); 154 mutex_unlock(&rt2x00dev->csr_mutex);
155 155
156 return; 156 return;
157 157
158exit_fail: 158exit_fail:
159 mutex_unlock(&rt2x00dev->usb_cache_mutex); 159 mutex_unlock(&rt2x00dev->csr_mutex);
160 160
161 ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); 161 ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
162} 162}
@@ -166,7 +166,7 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
166{ 166{
167 u16 reg; 167 u16 reg;
168 168
169 mutex_lock(&rt2x00dev->usb_cache_mutex); 169 mutex_lock(&rt2x00dev->csr_mutex);
170 170
171 /* 171 /*
172 * Wait until the BBP becomes ready. 172 * Wait until the BBP becomes ready.
@@ -194,12 +194,12 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
194 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg); 194 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg);
195 *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); 195 *value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
196 196
197 mutex_unlock(&rt2x00dev->usb_cache_mutex); 197 mutex_unlock(&rt2x00dev->csr_mutex);
198 198
199 return; 199 return;
200 200
201exit_fail: 201exit_fail:
202 mutex_unlock(&rt2x00dev->usb_cache_mutex); 202 mutex_unlock(&rt2x00dev->csr_mutex);
203 203
204 ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); 204 ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
205 *value = 0xff; 205 *value = 0xff;
@@ -214,7 +214,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
214 if (!word) 214 if (!word)
215 return; 215 return;
216 216
217 mutex_lock(&rt2x00dev->usb_cache_mutex); 217 mutex_lock(&rt2x00dev->csr_mutex);
218 218
219 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 219 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
220 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, &reg); 220 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, &reg);
@@ -223,7 +223,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
223 udelay(REGISTER_BUSY_DELAY); 223 udelay(REGISTER_BUSY_DELAY);
224 } 224 }
225 225
226 mutex_unlock(&rt2x00dev->usb_cache_mutex); 226 mutex_unlock(&rt2x00dev->csr_mutex);
227 ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n"); 227 ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n");
228 return; 228 return;
229 229
@@ -241,7 +241,7 @@ rf_write:
241 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg); 241 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg);
242 rt2x00_rf_write(rt2x00dev, word, value); 242 rt2x00_rf_write(rt2x00dev, word, value);
243 243
244 mutex_unlock(&rt2x00dev->usb_cache_mutex); 244 mutex_unlock(&rt2x00dev->csr_mutex);
245} 245}
246 246
247#ifdef CONFIG_RT2X00_LIB_DEBUGFS 247#ifdef CONFIG_RT2X00_LIB_DEBUGFS