From: Tomas Winkler Date: Mon, 1 Dec 2014 22:29:54 +0000 (+0200) Subject: mei: limit the number of consecutive resets X-Git-Tag: v3.2.65~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d7b5eb99e9ee3317966426e86816d327c910eed;p=thirdparty%2Fkernel%2Fstable.git 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 Signed-off-by: Alexander Usyskin Signed-off-by: Greg Kroah-Hartman Signed-off-by: Ben Hutchings --- diff --git a/drivers/staging/mei/init.c b/drivers/staging/mei/init.c index 8bf34794489c5..a78e63bc6dbe5 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 882d106d54e52..42b7c9a4a3c46 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 af4b1af9eeac9..264bf23662768 100644 --- a/drivers/staging/mei/mei_dev.h +++ b/drivers/staging/mei/mei_dev.h @@ -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;