diff options
author | Alexander Usyskin <alexander.usyskin@intel.com> | 2016-06-16 10:58:58 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-08-30 08:36:39 -0400 |
commit | a808c80cdaa83939b220176fcdffca8385d88ba6 (patch) | |
tree | 7664d544ae5d32099384620a92d60bd1cdeeea3d | |
parent | 97d549b4d5fca22ebde0798cb8c16c19b4ae837a (diff) |
mei: add read callback on demand for fixed_address clients
The Fixed address clients do not work with the flow control, and the
packet RX callback was allocated upon TX with anticipation of a
following RX. This won't work if the clients with unsolicited Rx. Rather
than preparing read callback upon a write we allocate one directly on
the reciev path if one doesn't exists.
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>
-rw-r--r-- | drivers/misc/mei/client.c | 15 | ||||
-rw-r--r-- | drivers/misc/mei/interrupt.c | 10 |
2 files changed, 12 insertions, 13 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 6658917be64f..2a09db86e50e 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
@@ -1145,26 +1145,19 @@ err: | |||
1145 | * mei_cl_flow_ctrl_creds - checks flow_control credits for cl. | 1145 | * mei_cl_flow_ctrl_creds - checks flow_control credits for cl. |
1146 | * | 1146 | * |
1147 | * @cl: host client | 1147 | * @cl: host client |
1148 | * @fp: the file pointer associated with the pointer | ||
1149 | * | 1148 | * |
1150 | * Return: 1 if mei_flow_ctrl_creds >0, 0 - otherwise. | 1149 | * Return: 1 if mei_flow_ctrl_creds >0, 0 - otherwise. |
1151 | */ | 1150 | */ |
1152 | static int mei_cl_flow_ctrl_creds(struct mei_cl *cl, const struct file *fp) | 1151 | static int mei_cl_flow_ctrl_creds(struct mei_cl *cl) |
1153 | { | 1152 | { |
1154 | int rets; | ||
1155 | |||
1156 | if (WARN_ON(!cl || !cl->me_cl)) | 1153 | if (WARN_ON(!cl || !cl->me_cl)) |
1157 | return -EINVAL; | 1154 | return -EINVAL; |
1158 | 1155 | ||
1159 | if (cl->mei_flow_ctrl_creds > 0) | 1156 | if (cl->mei_flow_ctrl_creds > 0) |
1160 | return 1; | 1157 | return 1; |
1161 | 1158 | ||
1162 | if (mei_cl_is_fixed_address(cl)) { | 1159 | if (mei_cl_is_fixed_address(cl)) |
1163 | rets = mei_cl_read_start(cl, mei_cl_mtu(cl), fp); | ||
1164 | if (rets && rets != -EBUSY) | ||
1165 | return rets; | ||
1166 | return 1; | 1160 | return 1; |
1167 | } | ||
1168 | 1161 | ||
1169 | if (mei_cl_is_single_recv_buf(cl)) { | 1162 | if (mei_cl_is_single_recv_buf(cl)) { |
1170 | if (cl->me_cl->mei_flow_ctrl_creds > 0) | 1163 | if (cl->me_cl->mei_flow_ctrl_creds > 0) |
@@ -1537,7 +1530,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, | |||
1537 | 1530 | ||
1538 | first_chunk = cb->buf_idx == 0; | 1531 | first_chunk = cb->buf_idx == 0; |
1539 | 1532 | ||
1540 | rets = first_chunk ? mei_cl_flow_ctrl_creds(cl, cb->fp) : 1; | 1533 | rets = first_chunk ? mei_cl_flow_ctrl_creds(cl) : 1; |
1541 | if (rets < 0) | 1534 | if (rets < 0) |
1542 | return rets; | 1535 | return rets; |
1543 | 1536 | ||
@@ -1643,7 +1636,7 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) | |||
1643 | mei_hdr.msg_complete = 0; | 1636 | mei_hdr.msg_complete = 0; |
1644 | mei_hdr.internal = cb->internal; | 1637 | mei_hdr.internal = cb->internal; |
1645 | 1638 | ||
1646 | rets = mei_cl_flow_ctrl_creds(cl, cb->fp); | 1639 | rets = mei_cl_flow_ctrl_creds(cl); |
1647 | if (rets < 0) | 1640 | if (rets < 0) |
1648 | goto err; | 1641 | goto err; |
1649 | 1642 | ||
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 8b5e4b4c4c15..44ba90140725 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c | |||
@@ -107,8 +107,14 @@ int mei_cl_irq_read_msg(struct mei_cl *cl, | |||
107 | 107 | ||
108 | cb = list_first_entry_or_null(&cl->rd_pending, struct mei_cl_cb, list); | 108 | cb = list_first_entry_or_null(&cl->rd_pending, struct mei_cl_cb, list); |
109 | if (!cb) { | 109 | if (!cb) { |
110 | cl_err(dev, cl, "pending read cb not found\n"); | 110 | if (!mei_cl_is_fixed_address(cl)) { |
111 | goto out; | 111 | cl_err(dev, cl, "pending read cb not found\n"); |
112 | goto out; | ||
113 | } | ||
114 | cb = mei_cl_alloc_cb(cl, mei_cl_mtu(cl), MEI_FOP_READ, cl->fp); | ||
115 | if (!cb) | ||
116 | goto out; | ||
117 | list_add_tail(&cb->list, &cl->rd_pending); | ||
112 | } | 118 | } |
113 | 119 | ||
114 | if (!mei_cl_is_connected(cl)) { | 120 | if (!mei_cl_is_connected(cl)) { |