init_waitqueue_head(&dev->wait_recvd_msg);
init_waitqueue_head(&dev->wait_stop_wd);
dev->mei_state = MEI_INITIALIZING;
+ dev->reset_count = 0;
dev->iamthif_state = MEI_IAMTHIF_IDLE;
dev->wd_interface_reg = false;
dev->need_reset = false;
+ dev->reset_count++;
+ if (dev->reset_count > MEI_MAX_CONSEC_RESET) {
+ dev_err(&dev->pdev->dev, "reset: reached maximal consecutive resets: disabling the device\n");
+ dev->mei_state = MEI_DISABLED;
+ return;
+ }
+
+
if (dev->mei_state != MEI_INITIALIZING) {
if (dev->mei_state != MEI_DISABLED &&
dev->mei_state != MEI_POWER_DOWN)
*/
bitmap_set(dev->host_clients_map, 0, 3);
dev->mei_state = MEI_ENABLED;
+ dev->reset_count = 0;
/* if wd initialization fails, initialization the AMTHI client,
* otherwise the AMTHI client will be initialized after the WD client connect response
}
}
out:
- schedule_delayed_work(&dev->timer_work, 2 * HZ);
+ if (dev->mei_state != MEI_DISABLED)
+ schedule_delayed_work(&dev->timer_work, 2 * HZ);
mutex_unlock(&dev->device_lock);
}
*/
extern const u8 mei_wd_state_independence_msg[3][4];
+/*
+ * maximum number of consecutive resets
+ */
+#define MEI_MAX_CONSEC_RESET 3
+
/*
* Number of File descriptors/handles
* that can be opened to the driver.
int status;
};
-/* MEI private device struct */
+/**
+ * mei_device - MEI private device struct
+ *
+ * @reset_count - limits the number of consecutive resets
+ */
struct mei_device {
struct pci_dev *pdev; /* pointer to pci device struct */
/*
/*
* mei device states
*/
+ unsigned long reset_count;
enum mei_states mei_state;
enum mei_init_clients_states init_clients_state;
u16 init_clients_timer;