diff options
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r-- | drivers/misc/mei/bus-fixup.c | 4 | ||||
-rw-r--r-- | drivers/misc/mei/bus.c | 31 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 7 |
3 files changed, 37 insertions, 5 deletions
diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c index 7f2cef9011ae..18e05ca7584f 100644 --- a/drivers/misc/mei/bus-fixup.c +++ b/drivers/misc/mei/bus-fixup.c @@ -141,7 +141,7 @@ static int mei_osver(struct mei_cl_device *cldev) if (ret < 0) return ret; - ret = __mei_cl_recv(cldev->cl, buf, length); + ret = __mei_cl_recv(cldev->cl, buf, length, 0); if (ret < 0) return ret; @@ -272,7 +272,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); + bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0); if (bytes_recv < if_version_length) { dev_err(bus->dev, "Could not read IF version\n"); ret = -EIO; diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 2fd254ecde2f..0037153c80a6 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -98,15 +98,18 @@ out: * @cl: host client * @buf: buffer to receive * @length: buffer length + * @mode: io mode * * Return: read size in bytes of < 0 on error */ -ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) +ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, + unsigned int mode) { struct mei_device *bus; struct mei_cl_cb *cb; size_t r_length; ssize_t rets; + bool nonblock = !!(mode & MEI_CL_IO_RX_NONBLOCK); if (WARN_ON(!cl || !cl->dev)) return -ENODEV; @@ -127,6 +130,11 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) if (rets && rets != -EBUSY) goto out; + if (nonblock) { + rets = -EAGAIN; + goto out; + } + /* wait on event only if there is no other waiter */ /* synchronized under device mutex */ if (!waitqueue_active(&cl->rx_wait)) { @@ -192,6 +200,25 @@ ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length) EXPORT_SYMBOL_GPL(mei_cldev_send); /** + * mei_cldev_recv_nonblock - non block client receive (read) + * + * @cldev: me client device + * @buf: buffer to receive + * @length: buffer length + * + * Return: read size in bytes of < 0 on error + * -EAGAIN if function will block. + */ +ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf, + size_t length) +{ + struct mei_cl *cl = cldev->cl; + + return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK); +} +EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock); + +/** * mei_cldev_recv - client receive (read) * * @cldev: me client device @@ -204,7 +231,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); + return __mei_cl_recv(cl, buf, length, 0); } EXPORT_SYMBOL_GPL(mei_cldev_recv); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 0e94df517410..699693cd8c59 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -115,10 +115,14 @@ enum mei_cb_file_ops { * * @MEI_CL_IO_TX_BLOCKING: send is blocking * @MEI_CL_IO_TX_INTERNAL: internal communication between driver and FW + * + * @MEI_CL_IO_RX_NONBLOCK: recv is non-blocking */ enum mei_cl_io_mode { MEI_CL_IO_TX_BLOCKING = BIT(0), MEI_CL_IO_TX_INTERNAL = BIT(1), + + MEI_CL_IO_RX_NONBLOCK = BIT(2), }; /* @@ -319,7 +323,8 @@ void mei_cl_bus_rescan_work(struct work_struct *work); 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); +ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, + unsigned int mode); 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); |