提交 7ff4bdd4 编写于 作者: A Alexander Usyskin 提交者: Greg Kroah-Hartman

mei: fix waiting for wr_ctrl for corner cases.

A control message reply may not be received if either a link reset has
occurred or disconnection is initiated by the FW.
In the both cases the client state will be set straight to DISCONNECTED
and the driver will wait till timeout.
Adding DISCONNECTED state in the waiting condition will release the
client from the stall.
Signed-off-by: NAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: NTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 4a8eaa96
...@@ -727,6 +727,11 @@ static void mei_cl_wake_all(struct mei_cl *cl) ...@@ -727,6 +727,11 @@ static void mei_cl_wake_all(struct mei_cl *cl)
cl_dbg(dev, cl, "Waking up waiting for event clients!\n"); cl_dbg(dev, cl, "Waking up waiting for event clients!\n");
wake_up_interruptible(&cl->ev_wait); wake_up_interruptible(&cl->ev_wait);
} }
/* synchronized under device mutex */
if (waitqueue_active(&cl->wait)) {
cl_dbg(dev, cl, "Waking up ctrl write clients!\n");
wake_up_interruptible(&cl->wait);
}
} }
/** /**
...@@ -879,12 +884,15 @@ static int __mei_cl_disconnect(struct mei_cl *cl) ...@@ -879,12 +884,15 @@ static int __mei_cl_disconnect(struct mei_cl *cl)
} }
mutex_unlock(&dev->device_lock); mutex_unlock(&dev->device_lock);
wait_event_timeout(cl->wait, cl->state == MEI_FILE_DISCONNECT_REPLY, wait_event_timeout(cl->wait,
cl->state == MEI_FILE_DISCONNECT_REPLY ||
cl->state == MEI_FILE_DISCONNECTED,
mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
mutex_lock(&dev->device_lock); mutex_lock(&dev->device_lock);
rets = cl->status; rets = cl->status;
if (cl->state != MEI_FILE_DISCONNECT_REPLY) { if (cl->state != MEI_FILE_DISCONNECT_REPLY &&
cl->state != MEI_FILE_DISCONNECTED) {
cl_dbg(dev, cl, "timeout on disconnect from FW client.\n"); cl_dbg(dev, cl, "timeout on disconnect from FW client.\n");
rets = -ETIME; rets = -ETIME;
} }
...@@ -1085,6 +1093,7 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, ...@@ -1085,6 +1093,7 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl,
mutex_unlock(&dev->device_lock); mutex_unlock(&dev->device_lock);
wait_event_timeout(cl->wait, wait_event_timeout(cl->wait,
(cl->state == MEI_FILE_CONNECTED || (cl->state == MEI_FILE_CONNECTED ||
cl->state == MEI_FILE_DISCONNECTED ||
cl->state == MEI_FILE_DISCONNECT_REQUIRED || cl->state == MEI_FILE_DISCONNECT_REQUIRED ||
cl->state == MEI_FILE_DISCONNECT_REPLY), cl->state == MEI_FILE_DISCONNECT_REPLY),
mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
...@@ -1333,8 +1342,9 @@ int mei_cl_notify_request(struct mei_cl *cl, ...@@ -1333,8 +1342,9 @@ int mei_cl_notify_request(struct mei_cl *cl,
} }
mutex_unlock(&dev->device_lock); mutex_unlock(&dev->device_lock);
wait_event_timeout(cl->wait, cl->notify_en == request, wait_event_timeout(cl->wait,
mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); cl->notify_en == request || !mei_cl_is_connected(cl),
mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
mutex_lock(&dev->device_lock); mutex_lock(&dev->device_lock);
if (cl->notify_en != request && !cl->status) if (cl->notify_en != request && !cl->status)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册