diff options
-rw-r--r-- | drivers/misc/mei/amthif.c | 14 | ||||
-rw-r--r-- | drivers/misc/mei/client.c | 5 | ||||
-rw-r--r-- | drivers/misc/mei/client.h | 7 | ||||
-rw-r--r-- | drivers/misc/mei/init.c | 13 | ||||
-rw-r--r-- | drivers/misc/mei/main.c | 22 |
5 files changed, 42 insertions, 19 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 749452f8e2f6..d0fdc134068a 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c | |||
@@ -418,15 +418,23 @@ unsigned int mei_amthif_poll(struct mei_device *dev, | |||
418 | struct file *file, poll_table *wait) | 418 | struct file *file, poll_table *wait) |
419 | { | 419 | { |
420 | unsigned int mask = 0; | 420 | unsigned int mask = 0; |
421 | mutex_unlock(&dev->device_lock); | 421 | |
422 | poll_wait(file, &dev->iamthif_cl.wait, wait); | 422 | poll_wait(file, &dev->iamthif_cl.wait, wait); |
423 | |||
423 | mutex_lock(&dev->device_lock); | 424 | mutex_lock(&dev->device_lock); |
424 | if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && | 425 | if (!mei_cl_is_connected(&dev->iamthif_cl)) { |
425 | dev->iamthif_file_object == file) { | 426 | |
427 | mask = POLLERR; | ||
428 | |||
429 | } else if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && | ||
430 | dev->iamthif_file_object == file) { | ||
431 | |||
426 | mask |= (POLLIN | POLLRDNORM); | 432 | mask |= (POLLIN | POLLRDNORM); |
427 | dev_dbg(&dev->pdev->dev, "run next amthif cb\n"); | 433 | dev_dbg(&dev->pdev->dev, "run next amthif cb\n"); |
428 | mei_amthif_run_next_cmd(dev); | 434 | mei_amthif_run_next_cmd(dev); |
429 | } | 435 | } |
436 | mutex_unlock(&dev->device_lock); | ||
437 | |||
430 | return mask; | 438 | return mask; |
431 | } | 439 | } |
432 | 440 | ||
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index af1e60205140..e0684b4d9a08 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
@@ -635,10 +635,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) | |||
635 | 635 | ||
636 | dev = cl->dev; | 636 | dev = cl->dev; |
637 | 637 | ||
638 | if (cl->state != MEI_FILE_CONNECTED) | 638 | if (!mei_cl_is_connected(cl)) |
639 | return -ENODEV; | ||
640 | |||
641 | if (dev->dev_state != MEI_DEV_ENABLED) | ||
642 | return -ENODEV; | 639 | return -ENODEV; |
643 | 640 | ||
644 | if (cl->read_cb) { | 641 | if (cl->read_cb) { |
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index 9bae4c724603..9eb031e92070 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h | |||
@@ -84,6 +84,13 @@ int mei_cl_flow_ctrl_reduce(struct mei_cl *cl); | |||
84 | /* | 84 | /* |
85 | * MEI input output function prototype | 85 | * MEI input output function prototype |
86 | */ | 86 | */ |
87 | static inline bool mei_cl_is_connected(struct mei_cl *cl) | ||
88 | { | ||
89 | return (cl->dev && | ||
90 | cl->dev->dev_state == MEI_DEV_ENABLED && | ||
91 | cl->state == MEI_FILE_CONNECTED); | ||
92 | } | ||
93 | |||
87 | bool mei_cl_is_other_connecting(struct mei_cl *cl); | 94 | bool mei_cl_is_other_connecting(struct mei_cl *cl); |
88 | int mei_cl_disconnect(struct mei_cl *cl); | 95 | int mei_cl_disconnect(struct mei_cl *cl); |
89 | int mei_cl_connect(struct mei_cl *cl, struct file *file); | 96 | int mei_cl_connect(struct mei_cl *cl, struct file *file); |
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 7929e14627ba..557eed2a1595 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c | |||
@@ -149,12 +149,20 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) | |||
149 | dev->hbm_state = MEI_HBM_IDLE; | 149 | dev->hbm_state = MEI_HBM_IDLE; |
150 | 150 | ||
151 | if (dev->dev_state != MEI_DEV_INITIALIZING) { | 151 | if (dev->dev_state != MEI_DEV_INITIALIZING) { |
152 | |||
152 | if (dev->dev_state != MEI_DEV_DISABLED && | 153 | if (dev->dev_state != MEI_DEV_DISABLED && |
153 | dev->dev_state != MEI_DEV_POWER_DOWN) | 154 | dev->dev_state != MEI_DEV_POWER_DOWN) |
154 | dev->dev_state = MEI_DEV_RESETTING; | 155 | dev->dev_state = MEI_DEV_RESETTING; |
155 | 156 | ||
157 | |||
158 | /* remove all waiting requests */ | ||
159 | mei_cl_all_write_clear(dev); | ||
160 | |||
156 | mei_cl_all_disconnect(dev); | 161 | mei_cl_all_disconnect(dev); |
157 | 162 | ||
163 | /* wake up all readings so they can be interrupted */ | ||
164 | mei_cl_all_wakeup(dev); | ||
165 | |||
158 | /* remove entry if already in list */ | 166 | /* remove entry if already in list */ |
159 | dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n"); | 167 | dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n"); |
160 | mei_cl_unlink(&dev->wd_cl); | 168 | mei_cl_unlink(&dev->wd_cl); |
@@ -195,11 +203,6 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) | |||
195 | 203 | ||
196 | mei_hbm_start_req(dev); | 204 | mei_hbm_start_req(dev); |
197 | 205 | ||
198 | /* wake up all readings so they can be interrupted */ | ||
199 | mei_cl_all_wakeup(dev); | ||
200 | |||
201 | /* remove all waiting requests */ | ||
202 | mei_cl_all_write_clear(dev); | ||
203 | } | 206 | } |
204 | EXPORT_SYMBOL_GPL(mei_reset); | 207 | EXPORT_SYMBOL_GPL(mei_reset); |
205 | 208 | ||
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 5e11b5b9b65d..173ff095be0d 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c | |||
@@ -625,24 +625,32 @@ static unsigned int mei_poll(struct file *file, poll_table *wait) | |||
625 | unsigned int mask = 0; | 625 | unsigned int mask = 0; |
626 | 626 | ||
627 | if (WARN_ON(!cl || !cl->dev)) | 627 | if (WARN_ON(!cl || !cl->dev)) |
628 | return mask; | 628 | return POLLERR; |
629 | 629 | ||
630 | dev = cl->dev; | 630 | dev = cl->dev; |
631 | 631 | ||
632 | mutex_lock(&dev->device_lock); | 632 | mutex_lock(&dev->device_lock); |
633 | 633 | ||
634 | if (dev->dev_state != MEI_DEV_ENABLED) | 634 | if (!mei_cl_is_connected(cl)) { |
635 | goto out; | 635 | mask = POLLERR; |
636 | |||
637 | |||
638 | if (cl == &dev->iamthif_cl) { | ||
639 | mask = mei_amthif_poll(dev, file, wait); | ||
640 | goto out; | 636 | goto out; |
641 | } | 637 | } |
642 | 638 | ||
643 | mutex_unlock(&dev->device_lock); | 639 | mutex_unlock(&dev->device_lock); |
640 | |||
641 | |||
642 | if (cl == &dev->iamthif_cl) | ||
643 | return mei_amthif_poll(dev, file, wait); | ||
644 | |||
644 | poll_wait(file, &cl->tx_wait, wait); | 645 | poll_wait(file, &cl->tx_wait, wait); |
646 | |||
645 | mutex_lock(&dev->device_lock); | 647 | mutex_lock(&dev->device_lock); |
648 | |||
649 | if (!mei_cl_is_connected(cl)) { | ||
650 | mask = POLLERR; | ||
651 | goto out; | ||
652 | } | ||
653 | |||
646 | if (MEI_WRITE_COMPLETE == cl->writing_state) | 654 | if (MEI_WRITE_COMPLETE == cl->writing_state) |
647 | mask |= (POLLIN | POLLRDNORM); | 655 | mask |= (POLLIN | POLLRDNORM); |
648 | 656 | ||