diff options
author | Alexander Usyskin <alexander.usyskin@intel.com> | 2016-01-07 14:46:36 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-02-06 22:06:43 -0800 |
commit | 13cf988562b0c7f06e0016bea2b5304358397702 (patch) | |
tree | d3da0573389d0625ecf182028762978cece63365 /drivers/misc/mei | |
parent | 2bcfdc23c6a418b441a1d17f237e9ea347e2fb1f (diff) |
mei: prevent queuing new flow control credit.
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>
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r-- | drivers/misc/mei/client.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index a6c87c713193..72e32615acd9 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1422,6 +1422,25 @@ out: } /** + * 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. * * @cl: host client @@ -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)) { |