Merge tag 'char-misc-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[linux-2.6-microblaze.git] / drivers / misc / mei / client.c
index 6c8b71a..9ddb854 100644 (file)
@@ -1954,10 +1954,13 @@ err:
  *
  * @cl: host client
  * @cb: write callback with filled data
+ * @timeout: send timeout in milliseconds.
+ *           effective only for blocking writes: the cb->blocking is set.
+ *           set timeout to the MAX_SCHEDULE_TIMEOUT to maixum allowed wait.
  *
  * Return: number of bytes sent on success, <0 on failure.
  */
-ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb)
+ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, unsigned long timeout)
 {
        struct mei_device *dev;
        struct mei_msg_data *buf;
@@ -2081,11 +2084,20 @@ out:
        if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) {
 
                mutex_unlock(&dev->device_lock);
-               rets = wait_event_interruptible(cl->tx_wait,
-                               cl->writing_state == MEI_WRITE_COMPLETE ||
-                               (!mei_cl_is_connected(cl)));
+               rets = wait_event_interruptible_timeout(cl->tx_wait,
+                                                       cl->writing_state == MEI_WRITE_COMPLETE ||
+                                                       (!mei_cl_is_connected(cl)),
+                                                       msecs_to_jiffies(timeout));
                mutex_lock(&dev->device_lock);
+               /* clean all queue on timeout as something fatal happened */
+               if (rets == 0) {
+                       rets = -ETIME;
+                       mei_io_tx_list_free_cl(&dev->write_list, cl, NULL);
+                       mei_io_tx_list_free_cl(&dev->write_waiting_list, cl, NULL);
+               }
                /* wait_event_interruptible returns -ERESTARTSYS */
+               if (rets > 0)
+                       rets = 0;
                if (rets) {
                        if (signal_pending(current))
                                rets = -EINTR;