summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2014-12-02 00:29:54 +0200
committerBen Hutchings <ben@decadent.org.uk>2014-12-14 16:24:00 +0000
commit3d7b5eb99e9ee3317966426e86816d327c910eed (patch)
tree6bd5419ba21dc01978a5bee2348816468509823b
parent7250ff7dd18b7a7a650af4079bbf940f20fd4253 (diff)
mei: limit the number of consecutive resets
commit 6adb8efb024a7e413b93b22848fc13395b1a438a upstream. give up reseting after 3 unsuccessful tries [Backported to 3.2: files were moved] Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--drivers/staging/mei/init.c9
-rw-r--r--drivers/staging/mei/interrupt.c4
-rw-r--r--drivers/staging/mei/mei_dev.h12
3 files changed, 23 insertions, 2 deletions
diff --git a/drivers/staging/mei/init.c b/drivers/staging/mei/init.c
index 8bf34794489c..a78e63bc6dbe 100644
--- a/drivers/staging/mei/init.c
+++ b/drivers/staging/mei/init.c
@@ -132,6 +132,7 @@ struct mei_device *mei_device_init(struct pci_dev *pdev)
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;
@@ -290,6 +291,14 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
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)
diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c
index 882d106d54e5..42b7c9a4a3c4 100644
--- a/drivers/staging/mei/interrupt.c
+++ b/drivers/staging/mei/interrupt.c
@@ -770,6 +770,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
*/
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
@@ -1527,7 +1528,8 @@ void mei_timer(struct work_struct *work)
}
}
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);
}
diff --git a/drivers/staging/mei/mei_dev.h b/drivers/staging/mei/mei_dev.h
index af4b1af9eeac..264bf2366276 100644
--- a/drivers/staging/mei/mei_dev.h
+++ b/drivers/staging/mei/mei_dev.h
@@ -64,6 +64,11 @@ extern const uuid_le mei_wd_guid;
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.
*
@@ -178,7 +183,11 @@ struct mei_io_list {
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 */
/*
@@ -225,6 +234,7 @@ struct mei_device {
/*
* mei device states
*/
+ unsigned long reset_count;
enum mei_states mei_state;
enum mei_init_clients_states init_clients_state;
u16 init_clients_timer;