aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/mei/amthif.c14
-rw-r--r--drivers/misc/mei/client.c5
-rw-r--r--drivers/misc/mei/client.h7
-rw-r--r--drivers/misc/mei/init.c13
-rw-r--r--drivers/misc/mei/main.c22
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 */
87static 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
87bool mei_cl_is_other_connecting(struct mei_cl *cl); 94bool mei_cl_is_other_connecting(struct mei_cl *cl);
88int mei_cl_disconnect(struct mei_cl *cl); 95int mei_cl_disconnect(struct mei_cl *cl);
89int mei_cl_connect(struct mei_cl *cl, struct file *file); 96int 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}
204EXPORT_SYMBOL_GPL(mei_reset); 207EXPORT_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