Skip to content

Commit

Permalink
mei: bus: stop wait for read during cl state transition
Browse files Browse the repository at this point in the history
Bus layer omitted check for client state transition while waiting
for read completion
The client state transition may occur for example as result
of firmware initiated reset

Add mei_cl_is_transitioning wrapper to reduce the code
repetition.:

Cc:  <stable@vger.kernel.org> # 3.9+
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Tomas Winkler authored and Greg Kroah-Hartman committed Sep 26, 2013
1 parent 1aee351 commit e2b3164
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 8 deletions.
5 changes: 4 additions & 1 deletion drivers/misc/mei/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,13 @@ int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)

if (cl->reading_state != MEI_READ_COMPLETE &&
!waitqueue_active(&cl->rx_wait)) {

mutex_unlock(&dev->device_lock);

if (wait_event_interruptible(cl->rx_wait,
(MEI_READ_COMPLETE == cl->reading_state))) {
cl->reading_state == MEI_READ_COMPLETE ||
mei_cl_is_transitioning(cl))) {

if (signal_pending(current))
return -EINTR;
return -ERESTARTSYS;
Expand Down
6 changes: 6 additions & 0 deletions drivers/misc/mei/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ static inline bool mei_cl_is_connected(struct mei_cl *cl)
cl->dev->dev_state == MEI_DEV_ENABLED &&
cl->state == MEI_FILE_CONNECTED);
}
static inline bool mei_cl_is_transitioning(struct mei_cl *cl)
{
return (MEI_FILE_INITIALIZING == cl->state ||
MEI_FILE_DISCONNECTED == cl->state ||
MEI_FILE_DISCONNECTING == cl->state);
}

bool mei_cl_is_other_connecting(struct mei_cl *cl);
int mei_cl_disconnect(struct mei_cl *cl);
Expand Down
11 changes: 4 additions & 7 deletions drivers/misc/mei/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,19 +249,16 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
mutex_unlock(&dev->device_lock);

if (wait_event_interruptible(cl->rx_wait,
(MEI_READ_COMPLETE == cl->reading_state ||
MEI_FILE_INITIALIZING == cl->state ||
MEI_FILE_DISCONNECTED == cl->state ||
MEI_FILE_DISCONNECTING == cl->state))) {
MEI_READ_COMPLETE == cl->reading_state ||
mei_cl_is_transitioning(cl))) {

if (signal_pending(current))
return -EINTR;
return -ERESTARTSYS;
}

mutex_lock(&dev->device_lock);
if (MEI_FILE_INITIALIZING == cl->state ||
MEI_FILE_DISCONNECTED == cl->state ||
MEI_FILE_DISCONNECTING == cl->state) {
if (mei_cl_is_transitioning(cl)) {
rets = -EBUSY;
goto out;
}
Expand Down

0 comments on commit e2b3164

Please sign in to comment.