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: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
1aee351a73
commit
e2b31644e9
3 changed files with 14 additions and 8 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue