#include "rt2x00.h"
 #include "rt2x00usb.h"
 
+static bool rt2x00usb_check_usb_error(struct rt2x00_dev *rt2x00dev, int status)
+{
+       if (status == -ENODEV || status == -ENOENT)
+               return true;
+
+       if (status == -EPROTO || status == -ETIMEDOUT)
+               rt2x00dev->num_proto_errs++;
+       else
+               rt2x00dev->num_proto_errs = 0;
+
+       if (rt2x00dev->num_proto_errs > 3)
+               return true;
+
+       return false;
+}
+
 /*
  * Interfacing with the HW.
  */
                if (status >= 0)
                        return 0;
 
-               if (status == -ENODEV || status == -ENOENT) {
+               if (rt2x00usb_check_usb_error(rt2x00dev, status)) {
                        /* Device has disappeared. */
                        clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
                        break;
 
        status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
        if (status) {
-               if (status == -ENODEV || status == -ENOENT)
+               if (rt2x00usb_check_usb_error(rt2x00dev, status))
                        clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
                set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
                rt2x00lib_dmadone(entry);
 
        status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
        if (status) {
-               if (status == -ENODEV || status == -ENOENT)
+               if (rt2x00usb_check_usb_error(rt2x00dev, status))
                        clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
                set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
                rt2x00lib_dmadone(entry);