diff options
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 13 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 42 |
5 files changed, 131 insertions, 16 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index c89103786b1c..a00420e9626b 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -52,6 +52,8 @@ | |||
52 | * between each attampt. When the busy bit is still set at that time, | 52 | * between each attampt. When the busy bit is still set at that time, |
53 | * the access attempt is considered to have failed, | 53 | * the access attempt is considered to have failed, |
54 | * and we will print an error. | 54 | * and we will print an error. |
55 | * If the usb_cache_mutex is already held then the _lock variants must | ||
56 | * be used instead. | ||
55 | */ | 57 | */ |
56 | static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, | 58 | static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, |
57 | const unsigned int offset, | 59 | const unsigned int offset, |
@@ -64,6 +66,17 @@ static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, | |||
64 | *value = le16_to_cpu(reg); | 66 | *value = le16_to_cpu(reg); |
65 | } | 67 | } |
66 | 68 | ||
69 | static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev, | ||
70 | const unsigned int offset, | ||
71 | u16 *value) | ||
72 | { | ||
73 | __le16 reg; | ||
74 | rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ, | ||
75 | USB_VENDOR_REQUEST_IN, offset, | ||
76 | ®, sizeof(u16), REGISTER_TIMEOUT); | ||
77 | *value = le16_to_cpu(reg); | ||
78 | } | ||
79 | |||
67 | static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev, | 80 | static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev, |
68 | const unsigned int offset, | 81 | const unsigned int offset, |
69 | void *value, const u16 length) | 82 | void *value, const u16 length) |
@@ -84,6 +97,16 @@ static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev, | |||
84 | ®, sizeof(u16), REGISTER_TIMEOUT); | 97 | ®, sizeof(u16), REGISTER_TIMEOUT); |
85 | } | 98 | } |
86 | 99 | ||
100 | static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev, | ||
101 | const unsigned int offset, | ||
102 | u16 value) | ||
103 | { | ||
104 | __le16 reg = cpu_to_le16(value); | ||
105 | rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE, | ||
106 | USB_VENDOR_REQUEST_OUT, offset, | ||
107 | ®, sizeof(u16), REGISTER_TIMEOUT); | ||
108 | } | ||
109 | |||
87 | static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, | 110 | static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, |
88 | const unsigned int offset, | 111 | const unsigned int offset, |
89 | void *value, const u16 length) | 112 | void *value, const u16 length) |
@@ -100,7 +123,7 @@ static u16 rt2500usb_bbp_check(struct rt2x00_dev *rt2x00dev) | |||
100 | unsigned int i; | 123 | unsigned int i; |
101 | 124 | ||
102 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 125 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
103 | rt2500usb_register_read(rt2x00dev, PHY_CSR8, ®); | 126 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR8, ®); |
104 | if (!rt2x00_get_field16(reg, PHY_CSR8_BUSY)) | 127 | if (!rt2x00_get_field16(reg, PHY_CSR8_BUSY)) |
105 | break; | 128 | break; |
106 | udelay(REGISTER_BUSY_DELAY); | 129 | udelay(REGISTER_BUSY_DELAY); |
@@ -114,12 +137,15 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
114 | { | 137 | { |
115 | u16 reg; | 138 | u16 reg; |
116 | 139 | ||
140 | mutex_lock(&rt2x00dev->usb_cache_mutex); | ||
141 | |||
117 | /* | 142 | /* |
118 | * Wait until the BBP becomes ready. | 143 | * Wait until the BBP becomes ready. |
119 | */ | 144 | */ |
120 | reg = rt2500usb_bbp_check(rt2x00dev); | 145 | reg = rt2500usb_bbp_check(rt2x00dev); |
121 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { | 146 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { |
122 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); | 147 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); |
148 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
123 | return; | 149 | return; |
124 | } | 150 | } |
125 | 151 | ||
@@ -131,7 +157,9 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
131 | rt2x00_set_field16(®, PHY_CSR7_REG_ID, word); | 157 | rt2x00_set_field16(®, PHY_CSR7_REG_ID, word); |
132 | rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 0); | 158 | rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 0); |
133 | 159 | ||
134 | rt2500usb_register_write(rt2x00dev, PHY_CSR7, reg); | 160 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); |
161 | |||
162 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
135 | } | 163 | } |
136 | 164 | ||
137 | static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | 165 | static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, |
@@ -139,6 +167,8 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
139 | { | 167 | { |
140 | u16 reg; | 168 | u16 reg; |
141 | 169 | ||
170 | mutex_lock(&rt2x00dev->usb_cache_mutex); | ||
171 | |||
142 | /* | 172 | /* |
143 | * Wait until the BBP becomes ready. | 173 | * Wait until the BBP becomes ready. |
144 | */ | 174 | */ |
@@ -155,7 +185,7 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
155 | rt2x00_set_field16(®, PHY_CSR7_REG_ID, word); | 185 | rt2x00_set_field16(®, PHY_CSR7_REG_ID, word); |
156 | rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 1); | 186 | rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 1); |
157 | 187 | ||
158 | rt2500usb_register_write(rt2x00dev, PHY_CSR7, reg); | 188 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); |
159 | 189 | ||
160 | /* | 190 | /* |
161 | * Wait until the BBP becomes ready. | 191 | * Wait until the BBP becomes ready. |
@@ -164,11 +194,14 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
164 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { | 194 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { |
165 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); | 195 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); |
166 | *value = 0xff; | 196 | *value = 0xff; |
197 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
167 | return; | 198 | return; |
168 | } | 199 | } |
169 | 200 | ||
170 | rt2500usb_register_read(rt2x00dev, PHY_CSR7, ®); | 201 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®); |
171 | *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); | 202 | *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); |
203 | |||
204 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
172 | } | 205 | } |
173 | 206 | ||
174 | static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, | 207 | static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, |
@@ -180,20 +213,23 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, | |||
180 | if (!word) | 213 | if (!word) |
181 | return; | 214 | return; |
182 | 215 | ||
216 | mutex_lock(&rt2x00dev->usb_cache_mutex); | ||
217 | |||
183 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 218 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
184 | rt2500usb_register_read(rt2x00dev, PHY_CSR10, ®); | 219 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, ®); |
185 | if (!rt2x00_get_field16(reg, PHY_CSR10_RF_BUSY)) | 220 | if (!rt2x00_get_field16(reg, PHY_CSR10_RF_BUSY)) |
186 | goto rf_write; | 221 | goto rf_write; |
187 | udelay(REGISTER_BUSY_DELAY); | 222 | udelay(REGISTER_BUSY_DELAY); |
188 | } | 223 | } |
189 | 224 | ||
225 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
190 | ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n"); | 226 | ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n"); |
191 | return; | 227 | return; |
192 | 228 | ||
193 | rf_write: | 229 | rf_write: |
194 | reg = 0; | 230 | reg = 0; |
195 | rt2x00_set_field16(®, PHY_CSR9_RF_VALUE, value); | 231 | rt2x00_set_field16(®, PHY_CSR9_RF_VALUE, value); |
196 | rt2500usb_register_write(rt2x00dev, PHY_CSR9, reg); | 232 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR9, reg); |
197 | 233 | ||
198 | reg = 0; | 234 | reg = 0; |
199 | rt2x00_set_field16(®, PHY_CSR10_RF_VALUE, value >> 16); | 235 | rt2x00_set_field16(®, PHY_CSR10_RF_VALUE, value >> 16); |
@@ -201,8 +237,10 @@ rf_write: | |||
201 | rt2x00_set_field16(®, PHY_CSR10_RF_IF_SELECT, 0); | 237 | rt2x00_set_field16(®, PHY_CSR10_RF_IF_SELECT, 0); |
202 | rt2x00_set_field16(®, PHY_CSR10_RF_BUSY, 1); | 238 | rt2x00_set_field16(®, PHY_CSR10_RF_BUSY, 1); |
203 | 239 | ||
204 | rt2500usb_register_write(rt2x00dev, PHY_CSR10, reg); | 240 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg); |
205 | rt2x00_rf_write(rt2x00dev, word, value); | 241 | rt2x00_rf_write(rt2x00dev, word, value); |
242 | |||
243 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
206 | } | 244 | } |
207 | 245 | ||
208 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 246 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 2cd2c9fab1a5..75c9a766e421 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
32 | #include <linux/workqueue.h> | 32 | #include <linux/workqueue.h> |
33 | #include <linux/firmware.h> | 33 | #include <linux/firmware.h> |
34 | #include <linux/mutex.h> | ||
34 | 35 | ||
35 | #include <net/mac80211.h> | 36 | #include <net/mac80211.h> |
36 | 37 | ||
@@ -659,6 +660,18 @@ struct rt2x00_dev { | |||
659 | void *csr_cache; | 660 | void *csr_cache; |
660 | 661 | ||
661 | /* | 662 | /* |
663 | * Mutex to protect register accesses on USB devices. | ||
664 | * There are 2 reasons this is needed, one is to ensure | ||
665 | * use of the csr_cache (for USB devices) by one thread | ||
666 | * isn't corrupted by another thread trying to access it. | ||
667 | * The other is that access to BBP and RF registers | ||
668 | * require multiple BUS transactions and if another thread | ||
669 | * attempted to access one of those registers at the same | ||
670 | * time one of the writes could silently fail. | ||
671 | */ | ||
672 | struct mutex usb_cache_mutex; | ||
673 | |||
674 | /* | ||
662 | * Interface configuration. | 675 | * Interface configuration. |
663 | */ | 676 | */ |
664 | struct interface interface; | 677 | struct interface interface; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index ab97b0600ec8..a8f0f80ddd21 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
34 | #include <linux/bug.h> | ||
34 | 35 | ||
35 | #include "rt2x00.h" | 36 | #include "rt2x00.h" |
36 | #include "rt2x00usb.h" | 37 | #include "rt2x00usb.h" |
@@ -52,6 +53,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, | |||
52 | (requesttype == USB_VENDOR_REQUEST_IN) ? | 53 | (requesttype == USB_VENDOR_REQUEST_IN) ? |
53 | usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0); | 54 | usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0); |
54 | 55 | ||
56 | |||
55 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 57 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
56 | status = usb_control_msg(usb_dev, pipe, request, requesttype, | 58 | status = usb_control_msg(usb_dev, pipe, request, requesttype, |
57 | value, offset, buffer, buffer_length, | 59 | value, offset, buffer, buffer_length, |
@@ -76,13 +78,15 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, | |||
76 | } | 78 | } |
77 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request); | 79 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request); |
78 | 80 | ||
79 | int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, | 81 | int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, |
80 | const u8 request, const u8 requesttype, | 82 | const u8 request, const u8 requesttype, |
81 | const u16 offset, void *buffer, | 83 | const u16 offset, void *buffer, |
82 | const u16 buffer_length, const int timeout) | 84 | const u16 buffer_length, const int timeout) |
83 | { | 85 | { |
84 | int status; | 86 | int status; |
85 | 87 | ||
88 | BUG_ON(!mutex_is_locked(&rt2x00dev->usb_cache_mutex)); | ||
89 | |||
86 | /* | 90 | /* |
87 | * Check for Cache availability. | 91 | * Check for Cache availability. |
88 | */ | 92 | */ |
@@ -103,6 +107,25 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, | |||
103 | 107 | ||
104 | return status; | 108 | return status; |
105 | } | 109 | } |
110 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_req_buff_lock); | ||
111 | |||
112 | int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, | ||
113 | const u8 request, const u8 requesttype, | ||
114 | const u16 offset, void *buffer, | ||
115 | const u16 buffer_length, const int timeout) | ||
116 | { | ||
117 | int status; | ||
118 | |||
119 | mutex_lock(&rt2x00dev->usb_cache_mutex); | ||
120 | |||
121 | status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request, | ||
122 | requesttype, offset, buffer, | ||
123 | buffer_length, timeout); | ||
124 | |||
125 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
126 | |||
127 | return status; | ||
128 | } | ||
106 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); | 129 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); |
107 | 130 | ||
108 | /* | 131 | /* |
@@ -507,6 +530,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, | |||
507 | rt2x00dev->dev = usb_intf; | 530 | rt2x00dev->dev = usb_intf; |
508 | rt2x00dev->ops = ops; | 531 | rt2x00dev->ops = ops; |
509 | rt2x00dev->hw = hw; | 532 | rt2x00dev->hw = hw; |
533 | mutex_init(&rt2x00dev->usb_cache_mutex); | ||
510 | 534 | ||
511 | rt2x00dev->usb_maxpacket = | 535 | rt2x00dev->usb_maxpacket = |
512 | usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1); | 536 | usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 53282b036927..2fa45c57a73f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -113,6 +113,14 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, | |||
113 | const u16 buffer_length, const int timeout); | 113 | const u16 buffer_length, const int timeout); |
114 | 114 | ||
115 | /* | 115 | /* |
116 | * A version of rt2x00usb_vendor_request_buff which must be called | ||
117 | * if the usb_cache_mutex is already held. */ | ||
118 | int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, | ||
119 | const u8 request, const u8 requesttype, | ||
120 | const u16 offset, void *buffer, | ||
121 | const u16 buffer_length, const int timeout); | ||
122 | |||
123 | /* | ||
116 | * Simple wrapper around rt2x00usb_vendor_request to write a single | 124 | * Simple wrapper around rt2x00usb_vendor_request to write a single |
117 | * command to the device. Since we don't use the buffer argument we | 125 | * command to the device. Since we don't use the buffer argument we |
118 | * don't have to worry about kmalloc here. | 126 | * don't have to worry about kmalloc here. |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index d89db266757c..7caa3639dadf 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -52,6 +52,7 @@ | |||
52 | * between each attampt. When the busy bit is still set at that time, | 52 | * between each attampt. When the busy bit is still set at that time, |
53 | * the access attempt is considered to have failed, | 53 | * the access attempt is considered to have failed, |
54 | * and we will print an error. | 54 | * and we will print an error. |
55 | * The _lock versions must be used if you already hold the usb_cache_mutex | ||
55 | */ | 56 | */ |
56 | static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev, | 57 | static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev, |
57 | const unsigned int offset, u32 *value) | 58 | const unsigned int offset, u32 *value) |
@@ -63,6 +64,16 @@ static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev, | |||
63 | *value = le32_to_cpu(reg); | 64 | *value = le32_to_cpu(reg); |
64 | } | 65 | } |
65 | 66 | ||
67 | static inline void rt73usb_register_read_lock(struct rt2x00_dev *rt2x00dev, | ||
68 | const unsigned int offset, u32 *value) | ||
69 | { | ||
70 | __le32 reg; | ||
71 | rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ, | ||
72 | USB_VENDOR_REQUEST_IN, offset, | ||
73 | ®, sizeof(u32), REGISTER_TIMEOUT); | ||
74 | *value = le32_to_cpu(reg); | ||
75 | } | ||
76 | |||
66 | static inline void rt73usb_register_multiread(struct rt2x00_dev *rt2x00dev, | 77 | static inline void rt73usb_register_multiread(struct rt2x00_dev *rt2x00dev, |
67 | const unsigned int offset, | 78 | const unsigned int offset, |
68 | void *value, const u32 length) | 79 | void *value, const u32 length) |
@@ -82,6 +93,15 @@ static inline void rt73usb_register_write(struct rt2x00_dev *rt2x00dev, | |||
82 | ®, sizeof(u32), REGISTER_TIMEOUT); | 93 | ®, sizeof(u32), REGISTER_TIMEOUT); |
83 | } | 94 | } |
84 | 95 | ||
96 | static inline void rt73usb_register_write_lock(struct rt2x00_dev *rt2x00dev, | ||
97 | const unsigned int offset, u32 value) | ||
98 | { | ||
99 | __le32 reg = cpu_to_le32(value); | ||
100 | rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE, | ||
101 | USB_VENDOR_REQUEST_OUT, offset, | ||
102 | ®, sizeof(u32), REGISTER_TIMEOUT); | ||
103 | } | ||
104 | |||
85 | static inline void rt73usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, | 105 | static inline void rt73usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, |
86 | const unsigned int offset, | 106 | const unsigned int offset, |
87 | void *value, const u32 length) | 107 | void *value, const u32 length) |
@@ -98,7 +118,7 @@ static u32 rt73usb_bbp_check(struct rt2x00_dev *rt2x00dev) | |||
98 | unsigned int i; | 118 | unsigned int i; |
99 | 119 | ||
100 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 120 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
101 | rt73usb_register_read(rt2x00dev, PHY_CSR3, ®); | 121 | rt73usb_register_read_lock(rt2x00dev, PHY_CSR3, ®); |
102 | if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | 122 | if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY)) |
103 | break; | 123 | break; |
104 | udelay(REGISTER_BUSY_DELAY); | 124 | udelay(REGISTER_BUSY_DELAY); |
@@ -112,12 +132,15 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
112 | { | 132 | { |
113 | u32 reg; | 133 | u32 reg; |
114 | 134 | ||
135 | mutex_lock(&rt2x00dev->usb_cache_mutex); | ||
136 | |||
115 | /* | 137 | /* |
116 | * Wait until the BBP becomes ready. | 138 | * Wait until the BBP becomes ready. |
117 | */ | 139 | */ |
118 | reg = rt73usb_bbp_check(rt2x00dev); | 140 | reg = rt73usb_bbp_check(rt2x00dev); |
119 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | 141 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { |
120 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); | 142 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); |
143 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
121 | return; | 144 | return; |
122 | } | 145 | } |
123 | 146 | ||
@@ -130,7 +153,8 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
130 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | 153 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); |
131 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); | 154 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); |
132 | 155 | ||
133 | rt73usb_register_write(rt2x00dev, PHY_CSR3, reg); | 156 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); |
157 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
134 | } | 158 | } |
135 | 159 | ||
136 | static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | 160 | static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, |
@@ -138,12 +162,15 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
138 | { | 162 | { |
139 | u32 reg; | 163 | u32 reg; |
140 | 164 | ||
165 | mutex_lock(&rt2x00dev->usb_cache_mutex); | ||
166 | |||
141 | /* | 167 | /* |
142 | * Wait until the BBP becomes ready. | 168 | * Wait until the BBP becomes ready. |
143 | */ | 169 | */ |
144 | reg = rt73usb_bbp_check(rt2x00dev); | 170 | reg = rt73usb_bbp_check(rt2x00dev); |
145 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | 171 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { |
146 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | 172 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); |
173 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
147 | return; | 174 | return; |
148 | } | 175 | } |
149 | 176 | ||
@@ -155,7 +182,7 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
155 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | 182 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); |
156 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); | 183 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); |
157 | 184 | ||
158 | rt73usb_register_write(rt2x00dev, PHY_CSR3, reg); | 185 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); |
159 | 186 | ||
160 | /* | 187 | /* |
161 | * Wait until the BBP becomes ready. | 188 | * Wait until the BBP becomes ready. |
@@ -168,6 +195,7 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
168 | } | 195 | } |
169 | 196 | ||
170 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); | 197 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); |
198 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
171 | } | 199 | } |
172 | 200 | ||
173 | static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, | 201 | static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, |
@@ -179,13 +207,16 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, | |||
179 | if (!word) | 207 | if (!word) |
180 | return; | 208 | return; |
181 | 209 | ||
210 | mutex_lock(&rt2x00dev->usb_cache_mutex); | ||
211 | |||
182 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 212 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
183 | rt73usb_register_read(rt2x00dev, PHY_CSR4, ®); | 213 | rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, ®); |
184 | if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY)) | 214 | if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY)) |
185 | goto rf_write; | 215 | goto rf_write; |
186 | udelay(REGISTER_BUSY_DELAY); | 216 | udelay(REGISTER_BUSY_DELAY); |
187 | } | 217 | } |
188 | 218 | ||
219 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
189 | ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n"); | 220 | ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n"); |
190 | return; | 221 | return; |
191 | 222 | ||
@@ -203,8 +234,9 @@ rf_write: | |||
203 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); | 234 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); |
204 | rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); | 235 | rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); |
205 | 236 | ||
206 | rt73usb_register_write(rt2x00dev, PHY_CSR4, reg); | 237 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg); |
207 | rt2x00_rf_write(rt2x00dev, word, value); | 238 | rt2x00_rf_write(rt2x00dev, word, value); |
239 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
208 | } | 240 | } |
209 | 241 | ||
210 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 242 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |