aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c9
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h4
3 files changed, 15 insertions, 9 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index e4f82d2f341b..b5d5f2203c52 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -114,12 +114,12 @@ static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev)
114 return false; 114 return false;
115} 115}
116 116
117static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, 117static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
118 int urb_status, u32 tx_status) 118 int urb_status, u32 tx_status)
119{ 119{
120 if (urb_status) { 120 if (urb_status) {
121 WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status); 121 WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status);
122 return; 122 return false;
123 } 123 }
124 124
125 /* try to read all TX_STA_FIFO entries before scheduling txdone_work */ 125 /* try to read all TX_STA_FIFO entries before scheduling txdone_work */
@@ -129,13 +129,14 @@ static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
129 "drop tx status report.\n"); 129 "drop tx status report.\n");
130 queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); 130 queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
131 } else 131 } else
132 rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, 132 return true;
133 rt2800usb_tx_sta_fifo_read_completed);
134 } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { 133 } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) {
135 queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); 134 queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
136 } else if (rt2800usb_txstatus_pending(rt2x00dev)) { 135 } else if (rt2800usb_txstatus_pending(rt2x00dev)) {
137 mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2)); 136 mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2));
138 } 137 }
138
139 return false;
139} 140}
140 141
141static void rt2800usb_tx_dma_done(struct queue_entry *entry) 142static void rt2800usb_tx_dma_done(struct queue_entry *entry)
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 570184ee163c..e027ebd44583 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -170,19 +170,22 @@ struct rt2x00_async_read_data {
170 __le32 reg; 170 __le32 reg;
171 struct usb_ctrlrequest cr; 171 struct usb_ctrlrequest cr;
172 struct rt2x00_dev *rt2x00dev; 172 struct rt2x00_dev *rt2x00dev;
173 void (*callback)(struct rt2x00_dev *,int,u32); 173 bool (*callback)(struct rt2x00_dev *, int, u32);
174}; 174};
175 175
176static void rt2x00usb_register_read_async_cb(struct urb *urb) 176static void rt2x00usb_register_read_async_cb(struct urb *urb)
177{ 177{
178 struct rt2x00_async_read_data *rd = urb->context; 178 struct rt2x00_async_read_data *rd = urb->context;
179 rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg)); 179 if (rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg))) {
180 kfree(urb->context); 180 if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
181 kfree(rd);
182 } else
183 kfree(rd);
181} 184}
182 185
183void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, 186void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
184 const unsigned int offset, 187 const unsigned int offset,
185 void (*callback)(struct rt2x00_dev*,int,u32)) 188 bool (*callback)(struct rt2x00_dev*, int, u32))
186{ 189{
187 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 190 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
188 struct urb *urb; 191 struct urb *urb;
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 52b09d2e11de..a69f18758871 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -349,10 +349,12 @@ int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev,
349 * be called from atomic context. The callback will be called 349 * be called from atomic context. The callback will be called
350 * when the URB completes. Otherwise the function is similar 350 * when the URB completes. Otherwise the function is similar
351 * to rt2x00usb_register_read(). 351 * to rt2x00usb_register_read().
352 * When the callback function returns false, the memory will be cleaned up,
353 * when it returns true, the urb will be fired again.
352 */ 354 */
353void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, 355void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
354 const unsigned int offset, 356 const unsigned int offset,
355 void (*callback)(struct rt2x00_dev*,int,u32)); 357 bool (*callback)(struct rt2x00_dev*, int, u32));
356 358
357/* 359/*
358 * Radio handlers 360 * Radio handlers