mei: hbm: drop hbm responses on shutdown
authorAlexander Usyskin <alexander.usyskin@intel.com>
Fri, 29 Jan 2021 12:07:49 +0000 (14:07 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Jan 2021 15:59:11 +0000 (16:59 +0100)
Ignore and drop HBM responses from init phase in shutdown phase.
Fixes stall if driver starting to stop in the middle of link init.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Link: https://lore.kernel.org/r/20210129120752.850325-4-tomas.winkler@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/mei/hbm.c

index 0cba3c6..df0f62d 100644 (file)
@@ -1177,6 +1177,10 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
 
                if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
                    dev->hbm_state != MEI_HBM_STARTING) {
+                       if (dev->dev_state == MEI_DEV_POWER_DOWN) {
+                               dev_dbg(dev->dev, "hbm: start: on shutdown, ignoring\n");
+                               return 0;
+                       }
                        dev_err(dev->dev, "hbm: start: state mismatch, [%d, %d]\n",
                                dev->dev_state, dev->hbm_state);
                        return -EPROTO;
@@ -1215,7 +1219,12 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
 
                dev->init_clients_timer = 0;
 
-               if (dev->hbm_state != MEI_HBM_CAP_SETUP) {
+               if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
+                   dev->hbm_state != MEI_HBM_CAP_SETUP) {
+                       if (dev->dev_state == MEI_DEV_POWER_DOWN) {
+                               dev_dbg(dev->dev, "hbm: capabilities response: on shutdown, ignoring\n");
+                               return 0;
+                       }
                        dev_err(dev->dev, "hbm: capabilities response: state mismatch, [%d, %d]\n",
                                dev->dev_state, dev->hbm_state);
                        return -EPROTO;
@@ -1247,7 +1256,12 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
 
                dev->init_clients_timer = 0;
 
-               if (dev->hbm_state != MEI_HBM_DR_SETUP) {
+               if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
+                   dev->hbm_state != MEI_HBM_DR_SETUP) {
+                       if (dev->dev_state == MEI_DEV_POWER_DOWN) {
+                               dev_dbg(dev->dev, "hbm: dma setup response: on shutdown, ignoring\n");
+                               return 0;
+                       }
                        dev_err(dev->dev, "hbm: dma setup response: state mismatch, [%d, %d]\n",
                                dev->dev_state, dev->hbm_state);
                        return -EPROTO;
@@ -1311,6 +1325,10 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
 
                if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
                    dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
+                       if (dev->dev_state == MEI_DEV_POWER_DOWN) {
+                               dev_dbg(dev->dev, "hbm: properties response: on shutdown, ignoring\n");
+                               return 0;
+                       }
                        dev_err(dev->dev, "hbm: properties response: state mismatch, [%d, %d]\n",
                                dev->dev_state, dev->hbm_state);
                        return -EPROTO;
@@ -1349,6 +1367,10 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
 
                if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
                    dev->hbm_state != MEI_HBM_ENUM_CLIENTS) {
+                       if (dev->dev_state == MEI_DEV_POWER_DOWN) {
+                               dev_dbg(dev->dev, "hbm: enumeration response: on shutdown, ignoring\n");
+                               return 0;
+                       }
                        dev_err(dev->dev, "hbm: enumeration response: state mismatch, [%d, %d]\n",
                                dev->dev_state, dev->hbm_state);
                        return -EPROTO;