summaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorAlexander Usyskin <alexander.usyskin@intel.com>2018-06-24 17:11:40 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-07-03 07:11:20 -0400
commit9a7c0b69b6e765c655133ef530876aea3da71d58 (patch)
treeb4edefad96370d35f11de6b449c5457311f4cc1a /drivers/misc
parent3458657f9e1041838d6c3d1bccf251f14dbb1b29 (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.c2
-rw-r--r--drivers/misc/mei/bus.c36
-rw-r--r--drivers/misc/mei/mei_dev.h2
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 */
122ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, 123ssize_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}
236EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock); 252EXPORT_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}
253EXPORT_SYMBOL_GPL(mei_cldev_recv); 269EXPORT_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);
317ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, 317ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
318 unsigned int mode); 318 unsigned int mode);
319ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, 319ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
320 unsigned int mode); 320 unsigned int mode, unsigned long timeout);
321bool mei_cl_bus_rx_event(struct mei_cl *cl); 321bool mei_cl_bus_rx_event(struct mei_cl *cl);
322bool mei_cl_bus_notify_event(struct mei_cl *cl); 322bool mei_cl_bus_notify_event(struct mei_cl *cl);
323void mei_cl_bus_remove_devices(struct mei_device *bus); 323void mei_cl_bus_remove_devices(struct mei_device *bus);