From 3e37ebb7183f0c4eb92a88c60657ac319c01b3e9 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Thu, 17 Jul 2014 10:53:34 +0300 Subject: mei: reset client connection state on timeout On connection timeout we leave the connecting client in connecting state. Since a new connection is stalled till previous connection is completed in this case no new connection is possible till the user space does release the file handle. Therefore on timeout we move the client to disconnected state. Cc: stable@vger.kernel.org # 3.15+ Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/misc/mei/client.c') diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 59d20c599b16..9f8ab28bcb60 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -616,6 +616,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) mutex_lock(&dev->device_lock); if (cl->state != MEI_FILE_CONNECTED) { + cl->state = MEI_FILE_DISCONNECTED; /* something went really wrong */ if (!cl->status) cl->status = -EFAULT; -- cgit v1.2.3 From 22b987a325701223f9a37db700c6eb20b9924c6f Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Thu, 17 Jul 2014 10:53:35 +0300 Subject: mei: start disconnect request timer consistently Link must be reset in case the fw doesn't respond to client disconnect request. We did charge the timer only in irq path from mei_cl_irq_close and not in mei_cl_disconnect Cc: stable@vger.kernel.org # 3.10+ Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/misc/mei/client.c') diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 9f8ab28bcb60..65545007745e 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -491,6 +491,7 @@ int mei_cl_disconnect(struct mei_cl *cl) cl_err(dev, cl, "failed to disconnect.\n"); goto free; } + cl->timer_count = MEI_CONNECT_TIMEOUT; mdelay(10); /* Wait for hardware disconnection ready */ list_add_tail(&cb->list, &dev->ctrl_rd_list.list); } else { -- cgit v1.2.3 From fe2f17eb3da38ac0d5a00c511255bf3a33d16d24 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Thu, 17 Jul 2014 10:53:38 +0300 Subject: mei: fix return value on disconnect timeout wait_event_timeout can return 0 or the remaining jiffies so return -ETIME if disconnected state not reached. Cc: stable@vger.kernel.org # 3.10+ Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/misc/mei/client.c') diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 65545007745e..324e1de93687 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -459,7 +459,7 @@ int mei_cl_disconnect(struct mei_cl *cl) { struct mei_device *dev; struct mei_cl_cb *cb; - int rets, err; + int rets; if (WARN_ON(!cl || !cl->dev)) return -ENODEV; @@ -501,23 +501,18 @@ int mei_cl_disconnect(struct mei_cl *cl) } mutex_unlock(&dev->device_lock); - err = wait_event_timeout(dev->wait_recvd_msg, + wait_event_timeout(dev->wait_recvd_msg, MEI_FILE_DISCONNECTED == cl->state, mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); mutex_lock(&dev->device_lock); + if (MEI_FILE_DISCONNECTED == cl->state) { rets = 0; cl_dbg(dev, cl, "successfully disconnected from FW client.\n"); } else { - rets = -ENODEV; - if (MEI_FILE_DISCONNECTED != cl->state) - cl_err(dev, cl, "wrong status client disconnect.\n"); - - if (err) - cl_dbg(dev, cl, "wait failed disconnect err=%d\n", err); - - cl_err(dev, cl, "failed to disconnect from FW client.\n"); + cl_dbg(dev, cl, "timeout on disconnect from FW client.\n"); + rets = -ETIME; } mei_io_list_flush(&dev->ctrl_rd_list, cl); -- cgit v1.2.3 From 73ab4232388b7a08f17c8d08141ff2099fa0b161 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Tue, 12 Aug 2014 18:07:56 +0300 Subject: mei: reset client state on queued connect request If connect request is queued (e.g. device in pg) set client state to initializing, thus avoid preliminary exit in wait if current state is disconnected. This is regression from: commit e4d8270e604c3202131bac607969605ac397b893 Author: Alexander Usyskin mei: set connecting state just upon connection request is sent to the fw CC: stable@vger.kernel.org # 3.15+ Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/misc/mei/client.c') diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 324e1de93687..2da05c0e113d 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -601,6 +601,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) cl->timer_count = MEI_CONNECT_TIMEOUT; list_add_tail(&cb->list, &dev->ctrl_rd_list.list); } else { + cl->state = MEI_FILE_INITIALIZING; list_add_tail(&cb->list, &dev->ctrl_wr_list.list); } -- cgit v1.2.3