]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mei: limit the number of consecutive resets
authorTomas Winkler <tomas.winkler@intel.com>
Mon, 1 Dec 2014 22:29:54 +0000 (00:29 +0200)
committerBen Hutchings <ben@decadent.org.uk>
Sun, 14 Dec 2014 16:24:00 +0000 (16:24 +0000)
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>
drivers/staging/mei/init.c
drivers/staging/mei/interrupt.c
drivers/staging/mei/mei_dev.h

index 8bf34794489c51af1a281d2ca3650d9706f8f48f..a78e63bc6dbe5b6ffbee2d63331dd931dd69b316 100644 (file)
@@ -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)
index 882d106d54e52565682a2d634b396d53153239a9..42b7c9a4a3c46727b985bc220c0918e19d9d194e 100644 (file)
@@ -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);
 }
 
index af4b1af9eeac93e833e3a41585e2654d215e3b94..264bf23662768f005d14877fcc019eaf387a18e1 100644 (file)
@@ -63,6 +63,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;