]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mei: bus: stop wait for read during cl state transition
authorTomas Winkler <tomas.winkler@intel.com>
Mon, 2 Sep 2013 10:29:46 +0000 (13:29 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Oct 2013 14:17:55 +0000 (07:17 -0700)
commit e2b31644e999e8bfe3efce880fb32840299abf41 upstream.

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.:

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/mei/bus.c
drivers/misc/mei/client.h
drivers/misc/mei/main.c

index 9ecd49a7be1b33cac4ece186e35e3ebc255d9d78..99cc0b07a71313e1970aad5efa0521888c3f7141 100644 (file)
@@ -295,10 +295,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;
index 26b157d8bad5ab421ea4f2476e399e25f2be1bfa..b1717bb7392fdfb1bfbaeda938625d297449289e 100644 (file)
@@ -76,6 +76,12 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
                (cl1->host_client_id == cl2->host_client_id) &&
                (cl1->me_client_id == cl2->me_client_id);
 }
+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);
+}
 
 
 int mei_cl_flow_ctrl_creds(struct mei_cl *cl);
index 5e11b5b9b65d2b9096164691f7feaf3a54c00ffc..e67de232c416cd2d89225247ddc42bf5d42dbaa9 100644 (file)
@@ -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;
                }