diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 9 | ||||
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.c | 11 | ||||
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00usb.h | 4 |
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 | ||
| 117 | static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, | 117 | static 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 | ||
| 141 | static void rt2800usb_tx_dma_done(struct queue_entry *entry) | 142 | static 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 | ||
| 176 | static void rt2x00usb_register_read_async_cb(struct urb *urb) | 176 | static 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 | ||
| 183 | void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, | 186 | void 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 | */ |
| 353 | void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, | 355 | void 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 |
