mei: prevent queuing new flow control credit.
authorAlexander Usyskin <alexander.usyskin@intel.com>
Thu, 7 Jan 2016 12:46:36 +0000 (14:46 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 7 Feb 2016 06:06:43 +0000 (22:06 -0800)
The MEI  FW can receive only one flow control for read.
Currently the driver only checks if a flow control credit was already
sent and read is pending in the rd_pending queue, but it also has to
check if flow control credit already queued in the write control queue
to prevent sending more than one flow control credits.

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>
drivers/misc/mei/client.c

index a6c87c7..72e3261 100644 (file)
@@ -1421,6 +1421,25 @@ out:
        return 0;
 }
 
+/**
+ * mei_cl_is_read_fc_cb - check if read cb is waiting for flow control
+ *                        for given host client
+ *
+ * @cl: host client
+ *
+ * Return: true, if found at least one cb.
+ */
+static bool mei_cl_is_read_fc_cb(struct mei_cl *cl)
+{
+       struct mei_device *dev = cl->dev;
+       struct mei_cl_cb *cb;
+
+       list_for_each_entry(cb, &dev->ctrl_wr_list.list, list)
+               if (cb->fop_type == MEI_FOP_READ && cb->cl == cl)
+                       return true;
+       return false;
+}
+
 /**
  * mei_cl_read_start - the start read client message function.
  *
@@ -1445,7 +1464,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length, struct file *fp)
                return -ENODEV;
 
        /* HW currently supports only one pending read */
-       if (!list_empty(&cl->rd_pending))
+       if (!list_empty(&cl->rd_pending) || mei_cl_is_read_fc_cb(cl))
                return -EBUSY;
 
        if (!mei_me_cl_is_active(cl->me_cl)) {