aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-02-17 11:35:28 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:37:24 -0500
commit47b10cd1375855dbc6675a176c71a512ac4b7317 (patch)
treea86ed1c88ea00371935f1ac3cd684d49b561bba2 /drivers/net
parent31562e802a72caf0757f351fff563d558d48d087 (diff)
rt2x00: Remove async vendor request calls from rt2x00usb
The async vendor requests are a ugly hack which is not working correctly. The proper fix for the scheduling while atomic issue is finding out why we can't use led classes for USB drivers and fix that. Just replace all async calls with the regular ones and print an error for the disallowed LED configuration attempts. That will help in determining which led class is causing the problem. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c52
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h18
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c23
4 files changed, 24 insertions, 79 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 826ed692878c..9f59db91cfc2 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -292,6 +292,12 @@ static void rt2500usb_led_brightness(struct led_classdev *led_cdev,
292 unsigned int activity = 292 unsigned int activity =
293 led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY; 293 led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY;
294 294
295 if (in_atomic()) {
296 NOTICE(led->rt2x00dev,
297 "Ignoring LED brightness command for led %d", led->type);
298 return;
299 }
300
295 if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { 301 if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) {
296 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, 302 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
297 MAC_CSR20_LINK, enabled); 303 MAC_CSR20_LINK, enabled);
@@ -299,8 +305,8 @@ static void rt2500usb_led_brightness(struct led_classdev *led_cdev,
299 MAC_CSR20_ACTIVITY, enabled && activity); 305 MAC_CSR20_ACTIVITY, enabled && activity);
300 } 306 }
301 307
302 rt2x00usb_vendor_request_async(led->rt2x00dev, USB_SINGLE_WRITE, 308 rt2500usb_register_write(led->rt2x00dev, MAC_CSR20,
303 MAC_CSR20, led->rt2x00dev->led_mcu_reg); 309 led->rt2x00dev->led_mcu_reg);
304} 310}
305#else 311#else
306#define rt2500usb_led_brightness NULL 312#define rt2500usb_led_brightness NULL
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 89471b24a443..063b167da31e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -122,58 +122,6 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
122} 122}
123EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); 123EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
124 124
125static void rt2x00usb_vendor_request_async_complete(struct urb *urb)
126{
127 /*
128 * We're done with it, descrease usage count and let the
129 * usb layer delete it as soon as it is done with it.
130 */
131 usb_put_urb(urb);
132}
133
134int rt2x00usb_vendor_request_async(struct rt2x00_dev *rt2x00dev,
135 const u8 request, const u16 offset,
136 const u16 value)
137{
138 struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev);
139 struct usb_ctrlrequest *ctrl;
140 struct urb *urb;
141 int status;
142
143 urb = usb_alloc_urb(0, GFP_NOIO);
144 if (!urb)
145 return -ENOMEM;
146
147 ctrl = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
148 if (!ctrl) {
149 status = -ENOMEM;
150 goto exit;
151 }
152
153 ctrl->bRequestType= USB_VENDOR_REQUEST_OUT;
154 ctrl->bRequest = request;
155 ctrl->wValue = cpu_to_le16p(&value);
156 ctrl->wIndex = cpu_to_le16p(&offset);
157 ctrl->wLength = 0;
158
159 usb_fill_control_urb(urb, usb_dev, usb_sndctrlpipe(usb_dev, 0),
160 (unsigned char *)ctrl, NULL, 0,
161 rt2x00usb_vendor_request_async_complete, NULL);
162
163 status = usb_submit_urb(urb, GFP_ATOMIC);
164 if (!status)
165 goto exit;
166
167 return 0;
168
169exit:
170 usb_put_urb(urb);
171 kfree(ctrl);
172
173 return status;
174}
175EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_async);
176
177/* 125/*
178 * TX data handlers. 126 * TX data handlers.
179 */ 127 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 275b089a2a4d..11e55180cbaf 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -194,24 +194,6 @@ static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev,
194 eeprom, lenght, timeout); 194 eeprom, lenght, timeout);
195} 195}
196 196
197/**
198 * rt2x00usb_vendor_request_async - Send register command to device (async)
199 * @rt2x00dev: Pointer to &struct rt2x00_dev
200 * @request: USB vendor command (See &enum rt2x00usb_vendor_request)
201 * @offset: Register offset to perform action on
202 * @value: Value to write to device
203 *
204 * Asynchroneous version of &rt2x00usb_vendor_request this is required
205 * for some routines where the driver cannot sleep because it is in
206 * irq context. Note that with this function the driver will not be
207 * notified on failure or timeout of the command. It will only be notified
208 * if the start of the command succeeded or not. This means it should not be
209 * used when the command must succeed.
210 */
211int rt2x00usb_vendor_request_async(struct rt2x00_dev *rt2x00dev,
212 const u8 request, const u16 offset,
213 const u16 value);
214
215/* 197/*
216 * Radio handlers 198 * Radio handlers
217 */ 199 */
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index bf2391b89571..6546b0d607b9 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -290,29 +290,38 @@ static void rt73usb_led_brightness(struct led_classdev *led_cdev,
290 unsigned int bg_mode = 290 unsigned int bg_mode =
291 (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); 291 (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
292 292
293 if (in_atomic()) {
294 NOTICE(led->rt2x00dev,
295 "Ignoring LED brightness command for led %d", led->type);
296 return;
297 }
298
293 if (led->type == LED_TYPE_RADIO) { 299 if (led->type == LED_TYPE_RADIO) {
294 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, 300 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
295 MCU_LEDCS_RADIO_STATUS, enabled); 301 MCU_LEDCS_RADIO_STATUS, enabled);
296 302
297 rt2x00usb_vendor_request_async(led->rt2x00dev, USB_LED_CONTROL, 303 rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL,
298 0, led->rt2x00dev->led_mcu_reg); 304 0, led->rt2x00dev->led_mcu_reg,
305 REGISTER_TIMEOUT);
299 } else if (led->type == LED_TYPE_ASSOC) { 306 } else if (led->type == LED_TYPE_ASSOC) {
300 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, 307 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
301 MCU_LEDCS_LINK_BG_STATUS, bg_mode); 308 MCU_LEDCS_LINK_BG_STATUS, bg_mode);
302 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, 309 rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg,
303 MCU_LEDCS_LINK_A_STATUS, a_mode); 310 MCU_LEDCS_LINK_A_STATUS, a_mode);
304 311
305 rt2x00usb_vendor_request_async(led->rt2x00dev, USB_LED_CONTROL, 312 rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL,
306 0, led->rt2x00dev->led_mcu_reg); 313 0, led->rt2x00dev->led_mcu_reg,
314 REGISTER_TIMEOUT);
307 } else if (led->type == LED_TYPE_QUALITY) { 315 } else if (led->type == LED_TYPE_QUALITY) {
308 /* 316 /*
309 * The brightness is divided into 6 levels (0 - 5), 317 * The brightness is divided into 6 levels (0 - 5),
310 * this means we need to convert the brightness 318 * this means we need to convert the brightness
311 * argument into the matching level within that range. 319 * argument into the matching level within that range.
312 */ 320 */
313 rt2x00usb_vendor_request_async(led->rt2x00dev, USB_LED_CONTROL, 321 rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL,
314 brightness / (LED_FULL / 6), 322 brightness / (LED_FULL / 6),
315 led->rt2x00dev->led_mcu_reg); 323 led->rt2x00dev->led_mcu_reg,
324 REGISTER_TIMEOUT);
316 } 325 }
317} 326}
318#else 327#else