diff options
author | Alexander Usyskin <alexander.usyskin@intel.com> | 2018-06-24 17:11:40 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-07-03 07:11:20 -0400 |
commit | 9a7c0b69b6e765c655133ef530876aea3da71d58 (patch) | |
tree | b4edefad96370d35f11de6b449c5457311f4cc1a /drivers/misc | |
parent | 3458657f9e1041838d6c3d1bccf251f14dbb1b29 (diff) |
mei: add optional timeout to internal bus recv
Add optional timeout to internal bus recv function to
enable break out of internal flows in case of no answer from FW.
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/mei/bus-fixup.c | 2 | ||||
-rw-r--r-- | drivers/misc/mei/bus.c | 36 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 2 |
3 files changed, 28 insertions, 12 deletions
diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c index 0208c4b027c5..b17c46a43812 100644 --- a/drivers/misc/mei/bus-fixup.c +++ b/drivers/misc/mei/bus-fixup.c | |||
@@ -266,7 +266,7 @@ static int mei_nfc_if_version(struct mei_cl *cl, | |||
266 | return -ENOMEM; | 266 | return -ENOMEM; |
267 | 267 | ||
268 | ret = 0; | 268 | ret = 0; |
269 | bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0); | 269 | bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0, 0); |
270 | if (bytes_recv < if_version_length) { | 270 | if (bytes_recv < if_version_length) { |
271 | dev_err(bus->dev, "Could not read IF version\n"); | 271 | dev_err(bus->dev, "Could not read IF version\n"); |
272 | ret = -EIO; | 272 | ret = -EIO; |
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index b1133739fb4b..7bba62a72921 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c | |||
@@ -116,11 +116,12 @@ out: | |||
116 | * @buf: buffer to receive | 116 | * @buf: buffer to receive |
117 | * @length: buffer length | 117 | * @length: buffer length |
118 | * @mode: io mode | 118 | * @mode: io mode |
119 | * @timeout: recv timeout, 0 for infinite timeout | ||
119 | * | 120 | * |
120 | * Return: read size in bytes of < 0 on error | 121 | * Return: read size in bytes of < 0 on error |
121 | */ | 122 | */ |
122 | ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, | 123 | ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, |
123 | unsigned int mode) | 124 | unsigned int mode, unsigned long timeout) |
124 | { | 125 | { |
125 | struct mei_device *bus; | 126 | struct mei_device *bus; |
126 | struct mei_cl_cb *cb; | 127 | struct mei_cl_cb *cb; |
@@ -158,13 +159,28 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, | |||
158 | 159 | ||
159 | mutex_unlock(&bus->device_lock); | 160 | mutex_unlock(&bus->device_lock); |
160 | 161 | ||
161 | if (wait_event_interruptible(cl->rx_wait, | 162 | if (timeout) { |
162 | (!list_empty(&cl->rd_completed)) || | 163 | rets = wait_event_interruptible_timeout |
163 | (!mei_cl_is_connected(cl)))) { | 164 | (cl->rx_wait, |
164 | 165 | (!list_empty(&cl->rd_completed)) || | |
165 | if (signal_pending(current)) | 166 | (!mei_cl_is_connected(cl)), |
166 | return -EINTR; | 167 | msecs_to_jiffies(timeout)); |
167 | return -ERESTARTSYS; | 168 | if (rets == 0) |
169 | return -ETIME; | ||
170 | if (rets < 0) { | ||
171 | if (signal_pending(current)) | ||
172 | return -EINTR; | ||
173 | return -ERESTARTSYS; | ||
174 | } | ||
175 | } else { | ||
176 | if (wait_event_interruptible | ||
177 | (cl->rx_wait, | ||
178 | (!list_empty(&cl->rd_completed)) || | ||
179 | (!mei_cl_is_connected(cl)))) { | ||
180 | if (signal_pending(current)) | ||
181 | return -EINTR; | ||
182 | return -ERESTARTSYS; | ||
183 | } | ||
168 | } | 184 | } |
169 | 185 | ||
170 | mutex_lock(&bus->device_lock); | 186 | mutex_lock(&bus->device_lock); |
@@ -231,7 +247,7 @@ ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf, | |||
231 | { | 247 | { |
232 | struct mei_cl *cl = cldev->cl; | 248 | struct mei_cl *cl = cldev->cl; |
233 | 249 | ||
234 | return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK); | 250 | return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK, 0); |
235 | } | 251 | } |
236 | EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock); | 252 | EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock); |
237 | 253 | ||
@@ -248,7 +264,7 @@ ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length) | |||
248 | { | 264 | { |
249 | struct mei_cl *cl = cldev->cl; | 265 | struct mei_cl *cl = cldev->cl; |
250 | 266 | ||
251 | return __mei_cl_recv(cl, buf, length, 0); | 267 | return __mei_cl_recv(cl, buf, length, 0, 0); |
252 | } | 268 | } |
253 | EXPORT_SYMBOL_GPL(mei_cldev_recv); | 269 | EXPORT_SYMBOL_GPL(mei_cldev_recv); |
254 | 270 | ||
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index be9c48415da9..4058ab5ad2d8 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h | |||
@@ -317,7 +317,7 @@ void mei_cl_bus_dev_fixup(struct mei_cl_device *dev); | |||
317 | ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, | 317 | ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, |
318 | unsigned int mode); | 318 | unsigned int mode); |
319 | ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, | 319 | ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, |
320 | unsigned int mode); | 320 | unsigned int mode, unsigned long timeout); |
321 | bool mei_cl_bus_rx_event(struct mei_cl *cl); | 321 | bool mei_cl_bus_rx_event(struct mei_cl *cl); |
322 | bool mei_cl_bus_notify_event(struct mei_cl *cl); | 322 | bool mei_cl_bus_notify_event(struct mei_cl *cl); |
323 | void mei_cl_bus_remove_devices(struct mei_device *bus); | 323 | void mei_cl_bus_remove_devices(struct mei_device *bus); |