Re: [char-misc-next 3/3 V2] mei: disconnect on connection request timeout

2015-08-03 Thread Greg Kroah-Hartman
On Wed, Jul 29, 2015 at 02:59:34PM +0300, Tomas Winkler wrote:
> From: Alexander Usyskin 
> 
> For the FW with  HBM version >= 2.0 we don't need to reset the whole
> device in case of a particular client failing to connect. It is
> sufficient to send a disconnect request to bring the device to the
> stable state.
> 
> Signed-off-by: Alexander Usyskin 
> Signed-off-by: Tomas Winkler 
> ---
> V2: 1. Remove bougous check on pm_runtime_active that prevented
>disconnection from a client

I applied the previous version, can you send a fix-up for the
differences?

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[char-misc-next 3/3 V2] mei: disconnect on connection request timeout

2015-07-29 Thread Tomas Winkler
From: Alexander Usyskin 

For the FW with  HBM version >= 2.0 we don't need to reset the whole
device in case of a particular client failing to connect. It is
sufficient to send a disconnect request to bring the device to the
stable state.

Signed-off-by: Alexander Usyskin 
Signed-off-by: Tomas Winkler 
---
V2: 1. Remove bougous check on pm_runtime_active that prevented
   disconnection from a client
2. Fix the commit message
  
 drivers/misc/mei/client.c| 84 ++--
 drivers/misc/mei/debugfs.c   |  2 ++
 drivers/misc/mei/hbm.c   |  4 +++
 drivers/misc/mei/hw.h|  6 
 drivers/misc/mei/interrupt.c | 20 ++-
 drivers/misc/mei/mei_dev.h   |  7 ++--
 6 files changed, 93 insertions(+), 30 deletions(-)

diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 9dacea7a9a60..5c1b0cf92e23 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -836,45 +836,22 @@ int mei_cl_irq_disconnect(struct mei_cl *cl, struct 
mei_cl_cb *cb,
return ret;
 }
 
-
-
 /**
- * mei_cl_disconnect - disconnect host client from the me one
+ * __mei_cl_disconnect - disconnect host client from the me one
+ * internal function runtime pm has to be already acquired
  *
  * @cl: host client
  *
- * Locking: called under "dev->device_lock" lock
- *
  * Return: 0 on success, <0 on failure.
  */
-int mei_cl_disconnect(struct mei_cl *cl)
+static int __mei_cl_disconnect(struct mei_cl *cl)
 {
struct mei_device *dev;
struct mei_cl_cb *cb;
int rets;
 
-   if (WARN_ON(!cl || !cl->dev))
-   return -ENODEV;
-
dev = cl->dev;
 
-   cl_dbg(dev, cl, "disconnecting");
-
-   if (!mei_cl_is_connected(cl))
-   return 0;
-
-   if (mei_cl_is_fixed_address(cl)) {
-   mei_cl_set_disconnected(cl);
-   return 0;
-   }
-
-   rets = pm_runtime_get(dev->dev);
-   if (rets < 0 && rets != -EINPROGRESS) {
-   pm_runtime_put_noidle(dev->dev);
-   cl_err(dev, cl, "rpm: get failed %d\n", rets);
-   return rets;
-   }
-
cl->state = MEI_FILE_DISCONNECTING;
 
cb = mei_io_cb_init(cl, MEI_FOP_DISCONNECT, NULL);
@@ -910,11 +887,52 @@ out:
if (!rets)
cl_dbg(dev, cl, "successfully disconnected from FW client.\n");
 
+   mei_io_cb_free(cb);
+   return rets;
+}
+
+/**
+ * mei_cl_disconnect - disconnect host client from the me one
+ *
+ * @cl: host client
+ *
+ * Locking: called under "dev->device_lock" lock
+ *
+ * Return: 0 on success, <0 on failure.
+ */
+int mei_cl_disconnect(struct mei_cl *cl)
+{
+   struct mei_device *dev;
+   int rets;
+
+   if (WARN_ON(!cl || !cl->dev))
+   return -ENODEV;
+
+   dev = cl->dev;
+
+   cl_dbg(dev, cl, "disconnecting");
+
+   if (!mei_cl_is_connected(cl))
+   return 0;
+
+   if (mei_cl_is_fixed_address(cl)) {
+   mei_cl_set_disconnected(cl);
+   return 0;
+   }
+
+   rets = pm_runtime_get(dev->dev);
+   if (rets < 0 && rets != -EINPROGRESS) {
+   pm_runtime_put_noidle(dev->dev);
+   cl_err(dev, cl, "rpm: get failed %d\n", rets);
+   return rets;
+   }
+
+   rets = __mei_cl_disconnect(cl);
+
cl_dbg(dev, cl, "rpm: autosuspend\n");
pm_runtime_mark_last_busy(dev->dev);
pm_runtime_put_autosuspend(dev->dev);
 
-   mei_io_cb_free(cb);
return rets;
 }
 
@@ -1059,11 +1077,23 @@ int mei_cl_connect(struct mei_cl *cl, struct 
mei_me_client *me_cl,
mutex_unlock(&dev->device_lock);
wait_event_timeout(cl->wait,
(cl->state == MEI_FILE_CONNECTED ||
+cl->state == MEI_FILE_DISCONNECT_REQUIRED ||
 cl->state == MEI_FILE_DISCONNECT_REPLY),
mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
mutex_lock(&dev->device_lock);
 
if (!mei_cl_is_connected(cl)) {
+   if (cl->state == MEI_FILE_DISCONNECT_REQUIRED) {
+   mei_io_list_flush(&dev->ctrl_rd_list, cl);
+   mei_io_list_flush(&dev->ctrl_wr_list, cl);
+/* ignore disconnect return valuue;
+ * in case of failure reset will be invoked
+ */
+   __mei_cl_disconnect(cl);
+   rets = -EFAULT;
+   goto out;
+   }
+
/* timeout or something went really wrong */
if (!cl->status)
cl->status = -EFAULT;
diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c
index a65a1e6f386f..e39cfe6bc5bc 100644
--- a/drivers/misc/mei/debugfs.c
+++ b/drivers/misc/mei/debugfs.c
@@ -156,6 +156,8 @@ static ssize_t mei_dbgfs_read_devstate(struct file *fp, 
char __user *ubuf,
 de