diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2014-02-19 10:35:51 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-28 18:15:57 -0500 |
commit | 5877255dc57403f49b4961070b206b832c931201 (patch) | |
tree | 17dd74aa0d9e00ee41a8674cd593707effc02f28 | |
parent | b6d81fd66155fb6d0965502e146b136047e428b3 (diff) |
mei: wd: fix stop completion failure
While running Documentation/watchdog/src/watchdog-simple.c
and quiting by Ctrl-C, fallowing error is displayed:
mei_me 0000:00:16.0: wd: stop failed to complete ret=-512.
The whatchdog core framework is not able to propagate
-ESYSRESTART or -EINTR. Also There is no much sense in
restarting the close system call so instead of using
wait_event_interruptible_timeout we can use wait_event_timeout
with reasonable 10 msecs timeout.
Reported-by: Prarit Bhargava <prarit@redhat.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/misc/mei/interrupt.c | 2 | ||||
-rw-r--r-- | drivers/misc/mei/wd.c | 32 |
2 files changed, 18 insertions, 16 deletions
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 834220af814f..5aab335f585b 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c | |||
@@ -474,7 +474,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) | |||
474 | 474 | ||
475 | if (dev->wd_state == MEI_WD_STOPPING) { | 475 | if (dev->wd_state == MEI_WD_STOPPING) { |
476 | dev->wd_state = MEI_WD_IDLE; | 476 | dev->wd_state = MEI_WD_IDLE; |
477 | wake_up_interruptible(&dev->wait_stop_wd); | 477 | wake_up(&dev->wait_stop_wd); |
478 | } | 478 | } |
479 | 479 | ||
480 | if (mei_cl_is_connected(&dev->wd_cl)) { | 480 | if (mei_cl_is_connected(&dev->wd_cl)) { |
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 13bb7a91ae12..e084adf27259 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c | |||
@@ -155,9 +155,11 @@ int mei_wd_send(struct mei_device *dev) | |||
155 | * @dev: the device structure | 155 | * @dev: the device structure |
156 | * @preserve: indicate if to keep the timeout value | 156 | * @preserve: indicate if to keep the timeout value |
157 | * | 157 | * |
158 | * returns 0 if success, | 158 | * returns 0 if success |
159 | * -EIO when message send fails | 159 | * on error: |
160 | * -EIO when message send fails | ||
160 | * -EINVAL when invalid message is to be sent | 161 | * -EINVAL when invalid message is to be sent |
162 | * -ETIME on message timeout | ||
161 | */ | 163 | */ |
162 | int mei_wd_stop(struct mei_device *dev) | 164 | int mei_wd_stop(struct mei_device *dev) |
163 | { | 165 | { |
@@ -173,12 +175,12 @@ int mei_wd_stop(struct mei_device *dev) | |||
173 | 175 | ||
174 | ret = mei_cl_flow_ctrl_creds(&dev->wd_cl); | 176 | ret = mei_cl_flow_ctrl_creds(&dev->wd_cl); |
175 | if (ret < 0) | 177 | if (ret < 0) |
176 | goto out; | 178 | goto err; |
177 | 179 | ||
178 | if (ret && mei_hbuf_acquire(dev)) { | 180 | if (ret && mei_hbuf_acquire(dev)) { |
179 | ret = mei_wd_send(dev); | 181 | ret = mei_wd_send(dev); |
180 | if (ret) | 182 | if (ret) |
181 | goto out; | 183 | goto err; |
182 | dev->wd_pending = false; | 184 | dev->wd_pending = false; |
183 | } else { | 185 | } else { |
184 | dev->wd_pending = true; | 186 | dev->wd_pending = true; |
@@ -186,21 +188,21 @@ int mei_wd_stop(struct mei_device *dev) | |||
186 | 188 | ||
187 | mutex_unlock(&dev->device_lock); | 189 | mutex_unlock(&dev->device_lock); |
188 | 190 | ||
189 | ret = wait_event_interruptible_timeout(dev->wait_stop_wd, | 191 | ret = wait_event_timeout(dev->wait_stop_wd, |
190 | dev->wd_state == MEI_WD_IDLE, | 192 | dev->wd_state == MEI_WD_IDLE, |
191 | msecs_to_jiffies(MEI_WD_STOP_TIMEOUT)); | 193 | msecs_to_jiffies(MEI_WD_STOP_TIMEOUT)); |
192 | mutex_lock(&dev->device_lock); | 194 | mutex_lock(&dev->device_lock); |
193 | if (dev->wd_state == MEI_WD_IDLE) { | 195 | if (dev->wd_state != MEI_WD_IDLE) { |
194 | dev_dbg(&dev->pdev->dev, "wd: stop completed ret=%d.\n", ret); | 196 | /* timeout */ |
195 | ret = 0; | 197 | ret = -ETIME; |
196 | } else { | ||
197 | if (!ret) | ||
198 | ret = -ETIME; | ||
199 | dev_warn(&dev->pdev->dev, | 198 | dev_warn(&dev->pdev->dev, |
200 | "wd: stop failed to complete ret=%d.\n", ret); | 199 | "wd: stop failed to complete ret=%d.\n", ret); |
200 | goto err; | ||
201 | } | 201 | } |
202 | 202 | dev_dbg(&dev->pdev->dev, "wd: stop completed after %u msec\n", | |
203 | out: | 203 | MEI_WD_STOP_TIMEOUT - jiffies_to_msecs(ret)); |
204 | return 0; | ||
205 | err: | ||
204 | return ret; | 206 | return ret; |
205 | } | 207 | } |
206 | 208 | ||