Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2b31644 authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman
Browse files

mei: bus: stop wait for read during cl state transition



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: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1aee351a
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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;
+6 −0
Original line number Diff line number Diff line
@@ -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);
+4 −7
Original line number Diff line number Diff line
@@ -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;
		}