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)
 	return false;
 }
 
-static void rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
+static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
 						 int urb_status, u32 tx_status)
 {
 	if (urb_status) {
 		WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status);
-		return;
+		return false;
 	}
 
 	/* 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,
 				"drop tx status report.\n");
 			queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
 		} else
-			rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO,
-						      rt2800usb_tx_sta_fifo_read_completed);
+			return true;
 	} else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) {
 		queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
 	} else if (rt2800usb_txstatus_pending(rt2x00dev)) {
 		mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2));
 	}
+
+	return false;
 }
 
 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 {
 	__le32 reg;
 	struct usb_ctrlrequest cr;
 	struct rt2x00_dev *rt2x00dev;
-	void (*callback)(struct rt2x00_dev *,int,u32);
+	bool (*callback)(struct rt2x00_dev *, int, u32);
 };
 
 static void rt2x00usb_register_read_async_cb(struct urb *urb)
 {
 	struct rt2x00_async_read_data *rd = urb->context;
-	rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg));
-	kfree(urb->context);
+	if (rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg))) {
+		if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
+			kfree(rd);
+	} else
+		kfree(rd);
 }
 
 void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
 				   const unsigned int offset,
-				   void (*callback)(struct rt2x00_dev*,int,u32))
+				   bool (*callback)(struct rt2x00_dev*, int, u32))
 {
 	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
 	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,
  * be called from atomic context.  The callback will be called
  * when the URB completes. Otherwise the function is similar
  * to rt2x00usb_register_read().
+ * When the callback function returns false, the memory will be cleaned up,
+ * when it returns true, the urb will be fired again.
  */
 void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
 				   const unsigned int offset,
-				   void (*callback)(struct rt2x00_dev*,int,u32));
+				   bool (*callback)(struct rt2x00_dev*, int, u32));
 
 /*
  * Radio handlers