diff options
| -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 | ||||
| -rw-r--r-- | include/linux/mei_cl_bus.h | 6 |
4 files changed, 41 insertions, 7 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) | |||
| 141 | if (ret < 0) | 141 | if (ret < 0) |
| 142 | return ret; | 142 | return ret; |
| 143 | 143 | ||
| 144 | ret = __mei_cl_recv(cldev->cl, buf, length); | 144 | ret = __mei_cl_recv(cldev->cl, buf, length, 0); |
| 145 | if (ret < 0) | 145 | if (ret < 0) |
| 146 | return ret; | 146 | return ret; |
| 147 | 147 | ||
| @@ -272,7 +272,7 @@ static int mei_nfc_if_version(struct mei_cl *cl, | |||
| 272 | return -ENOMEM; | 272 | return -ENOMEM; |
| 273 | 273 | ||
| 274 | ret = 0; | 274 | ret = 0; |
| 275 | bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length); | 275 | bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0); |
| 276 | if (bytes_recv < if_version_length) { | 276 | if (bytes_recv < if_version_length) { |
| 277 | dev_err(bus->dev, "Could not read IF version\n"); | 277 | dev_err(bus->dev, "Could not read IF version\n"); |
| 278 | ret = -EIO; | 278 | 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: | |||
| 98 | * @cl: host client | 98 | * @cl: host client |
| 99 | * @buf: buffer to receive | 99 | * @buf: buffer to receive |
| 100 | * @length: buffer length | 100 | * @length: buffer length |
| 101 | * @mode: io mode | ||
| 101 | * | 102 | * |
| 102 | * Return: read size in bytes of < 0 on error | 103 | * Return: read size in bytes of < 0 on error |
| 103 | */ | 104 | */ |
| 104 | ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) | 105 | ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, |
| 106 | unsigned int mode) | ||
| 105 | { | 107 | { |
| 106 | struct mei_device *bus; | 108 | struct mei_device *bus; |
| 107 | struct mei_cl_cb *cb; | 109 | struct mei_cl_cb *cb; |
| 108 | size_t r_length; | 110 | size_t r_length; |
| 109 | ssize_t rets; | 111 | ssize_t rets; |
| 112 | bool nonblock = !!(mode & MEI_CL_IO_RX_NONBLOCK); | ||
| 110 | 113 | ||
| 111 | if (WARN_ON(!cl || !cl->dev)) | 114 | if (WARN_ON(!cl || !cl->dev)) |
| 112 | return -ENODEV; | 115 | return -ENODEV; |
| @@ -127,6 +130,11 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) | |||
| 127 | if (rets && rets != -EBUSY) | 130 | if (rets && rets != -EBUSY) |
| 128 | goto out; | 131 | goto out; |
| 129 | 132 | ||
| 133 | if (nonblock) { | ||
| 134 | rets = -EAGAIN; | ||
| 135 | goto out; | ||
| 136 | } | ||
| 137 | |||
| 130 | /* wait on event only if there is no other waiter */ | 138 | /* wait on event only if there is no other waiter */ |
| 131 | /* synchronized under device mutex */ | 139 | /* synchronized under device mutex */ |
| 132 | if (!waitqueue_active(&cl->rx_wait)) { | 140 | 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) | |||
| 192 | EXPORT_SYMBOL_GPL(mei_cldev_send); | 200 | EXPORT_SYMBOL_GPL(mei_cldev_send); |
| 193 | 201 | ||
| 194 | /** | 202 | /** |
| 203 | * mei_cldev_recv_nonblock - non block client receive (read) | ||
| 204 | * | ||
| 205 | * @cldev: me client device | ||
| 206 | * @buf: buffer to receive | ||
| 207 | * @length: buffer length | ||
| 208 | * | ||
| 209 | * Return: read size in bytes of < 0 on error | ||
| 210 | * -EAGAIN if function will block. | ||
| 211 | */ | ||
| 212 | ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf, | ||
| 213 | size_t length) | ||
| 214 | { | ||
| 215 | struct mei_cl *cl = cldev->cl; | ||
| 216 | |||
| 217 | return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK); | ||
| 218 | } | ||
| 219 | EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock); | ||
| 220 | |||
| 221 | /** | ||
| 195 | * mei_cldev_recv - client receive (read) | 222 | * mei_cldev_recv - client receive (read) |
| 196 | * | 223 | * |
| 197 | * @cldev: me client device | 224 | * @cldev: me client device |
| @@ -204,7 +231,7 @@ ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length) | |||
| 204 | { | 231 | { |
| 205 | struct mei_cl *cl = cldev->cl; | 232 | struct mei_cl *cl = cldev->cl; |
| 206 | 233 | ||
| 207 | return __mei_cl_recv(cl, buf, length); | 234 | return __mei_cl_recv(cl, buf, length, 0); |
| 208 | } | 235 | } |
| 209 | EXPORT_SYMBOL_GPL(mei_cldev_recv); | 236 | EXPORT_SYMBOL_GPL(mei_cldev_recv); |
| 210 | 237 | ||
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 { | |||
| 115 | * | 115 | * |
| 116 | * @MEI_CL_IO_TX_BLOCKING: send is blocking | 116 | * @MEI_CL_IO_TX_BLOCKING: send is blocking |
| 117 | * @MEI_CL_IO_TX_INTERNAL: internal communication between driver and FW | 117 | * @MEI_CL_IO_TX_INTERNAL: internal communication between driver and FW |
| 118 | * | ||
| 119 | * @MEI_CL_IO_RX_NONBLOCK: recv is non-blocking | ||
| 118 | */ | 120 | */ |
| 119 | enum mei_cl_io_mode { | 121 | enum mei_cl_io_mode { |
| 120 | MEI_CL_IO_TX_BLOCKING = BIT(0), | 122 | MEI_CL_IO_TX_BLOCKING = BIT(0), |
| 121 | MEI_CL_IO_TX_INTERNAL = BIT(1), | 123 | MEI_CL_IO_TX_INTERNAL = BIT(1), |
| 124 | |||
| 125 | MEI_CL_IO_RX_NONBLOCK = BIT(2), | ||
| 122 | }; | 126 | }; |
| 123 | 127 | ||
| 124 | /* | 128 | /* |
| @@ -319,7 +323,8 @@ void mei_cl_bus_rescan_work(struct work_struct *work); | |||
| 319 | void mei_cl_bus_dev_fixup(struct mei_cl_device *dev); | 323 | void mei_cl_bus_dev_fixup(struct mei_cl_device *dev); |
| 320 | ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, | 324 | ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, |
| 321 | unsigned int mode); | 325 | unsigned int mode); |
| 322 | ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length); | 326 | ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, |
| 327 | unsigned int mode); | ||
| 323 | bool mei_cl_bus_rx_event(struct mei_cl *cl); | 328 | bool mei_cl_bus_rx_event(struct mei_cl *cl); |
| 324 | bool mei_cl_bus_notify_event(struct mei_cl *cl); | 329 | bool mei_cl_bus_notify_event(struct mei_cl *cl); |
| 325 | void mei_cl_bus_remove_devices(struct mei_device *bus); | 330 | void mei_cl_bus_remove_devices(struct mei_device *bus); |
diff --git a/include/linux/mei_cl_bus.h b/include/linux/mei_cl_bus.h index 017f5232b3de..a0d274fe08f1 100644 --- a/include/linux/mei_cl_bus.h +++ b/include/linux/mei_cl_bus.h | |||
| @@ -75,7 +75,7 @@ void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv); | |||
| 75 | /** | 75 | /** |
| 76 | * module_mei_cl_driver - Helper macro for registering mei cl driver | 76 | * module_mei_cl_driver - Helper macro for registering mei cl driver |
| 77 | * | 77 | * |
| 78 | * @__mei_cldrv mei_cl_driver structure | 78 | * @__mei_cldrv: mei_cl_driver structure |
| 79 | * | 79 | * |
| 80 | * Helper macro for mei cl drivers which do not do anything special in module | 80 | * Helper macro for mei cl drivers which do not do anything special in module |
| 81 | * init/exit, for eliminating a boilerplate code. | 81 | * init/exit, for eliminating a boilerplate code. |
| @@ -86,7 +86,9 @@ void mei_cldev_driver_unregister(struct mei_cl_driver *cldrv); | |||
| 86 | mei_cldev_driver_unregister) | 86 | mei_cldev_driver_unregister) |
| 87 | 87 | ||
| 88 | ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length); | 88 | ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length); |
| 89 | ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length); | 89 | ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length); |
| 90 | ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf, | ||
| 91 | size_t length); | ||
| 90 | 92 | ||
| 91 | int mei_cldev_register_rx_cb(struct mei_cl_device *cldev, mei_cldev_cb_t rx_cb); | 93 | int mei_cldev_register_rx_cb(struct mei_cl_device *cldev, mei_cldev_cb_t rx_cb); |
| 92 | int mei_cldev_register_notif_cb(struct mei_cl_device *cldev, | 94 | int mei_cldev_register_notif_cb(struct mei_cl_device *cldev, |
