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>
This commit is contained in:
parent
3458657f9e
commit
9a7c0b69b6
|
@ -266,7 +266,7 @@ static int mei_nfc_if_version(struct mei_cl *cl,
|
|||
return -ENOMEM;
|
||||
|
||||
ret = 0;
|
||||
bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0);
|
||||
bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0, 0);
|
||||
if (bytes_recv < if_version_length) {
|
||||
dev_err(bus->dev, "Could not read IF version\n");
|
||||
ret = -EIO;
|
||||
|
|
|
@ -116,11 +116,12 @@ out:
|
|||
* @buf: buffer to receive
|
||||
* @length: buffer length
|
||||
* @mode: io mode
|
||||
* @timeout: recv timeout, 0 for infinite timeout
|
||||
*
|
||||
* Return: read size in bytes of < 0 on error
|
||||
*/
|
||||
ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
|
||||
unsigned int mode)
|
||||
unsigned int mode, unsigned long timeout)
|
||||
{
|
||||
struct mei_device *bus;
|
||||
struct mei_cl_cb *cb;
|
||||
|
@ -158,13 +159,28 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
|
|||
|
||||
mutex_unlock(&bus->device_lock);
|
||||
|
||||
if (wait_event_interruptible(cl->rx_wait,
|
||||
(!list_empty(&cl->rd_completed)) ||
|
||||
(!mei_cl_is_connected(cl)))) {
|
||||
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
return -ERESTARTSYS;
|
||||
if (timeout) {
|
||||
rets = wait_event_interruptible_timeout
|
||||
(cl->rx_wait,
|
||||
(!list_empty(&cl->rd_completed)) ||
|
||||
(!mei_cl_is_connected(cl)),
|
||||
msecs_to_jiffies(timeout));
|
||||
if (rets == 0)
|
||||
return -ETIME;
|
||||
if (rets < 0) {
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
} else {
|
||||
if (wait_event_interruptible
|
||||
(cl->rx_wait,
|
||||
(!list_empty(&cl->rd_completed)) ||
|
||||
(!mei_cl_is_connected(cl)))) {
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&bus->device_lock);
|
||||
|
@ -231,7 +247,7 @@ ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf,
|
|||
{
|
||||
struct mei_cl *cl = cldev->cl;
|
||||
|
||||
return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK);
|
||||
return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock);
|
||||
|
||||
|
@ -248,7 +264,7 @@ ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length)
|
|||
{
|
||||
struct mei_cl *cl = cldev->cl;
|
||||
|
||||
return __mei_cl_recv(cl, buf, length, 0);
|
||||
return __mei_cl_recv(cl, buf, length, 0, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mei_cldev_recv);
|
||||
|
||||
|
|
|
@ -317,7 +317,7 @@ void mei_cl_bus_dev_fixup(struct mei_cl_device *dev);
|
|||
ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
|
||||
unsigned int mode);
|
||||
ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
|
||||
unsigned int mode);
|
||||
unsigned int mode, unsigned long timeout);
|
||||
bool mei_cl_bus_rx_event(struct mei_cl *cl);
|
||||
bool mei_cl_bus_notify_event(struct mei_cl *cl);
|
||||
void mei_cl_bus_remove_devices(struct mei_device *bus);
|
||||
|
|
Loading…
Reference in New Issue