diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2018-07-31 08:35:33 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-08-02 10:18:29 +0200 |
commit | 98e70866aacb1fcaa7b710fc6bca9862bf47421a (patch) | |
tree | 877e70ee1236f04a09ce277181542e66a8fcb51e /drivers/misc/mei/client.c | |
parent | uio: fix possible circular locking dependency (diff) | |
download | linux-98e70866aacb1fcaa7b710fc6bca9862bf47421a.tar.xz linux-98e70866aacb1fcaa7b710fc6bca9862bf47421a.zip |
mei: add support for variable length mei headers.
Remove header size knowledge from me and txe hw layers,
this requires to change the write handler to accept
header and its length as well as data and its length.
HBM messages are fixed to use basic header, hence we add mei_hbm2slots()
that converts HBM message length and mei message header,
while mei_data2slots() converts data length directly to the slots.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei/client.c')
-rw-r--r-- | drivers/misc/mei/client.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 207d2f5d5702..0a9173827461 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -863,7 +863,7 @@ int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb, int slots; int ret; - msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request)); + msg_slots = mei_hbm2slots(sizeof(struct hbm_client_connect_request)); slots = mei_hbuf_empty_slots(dev); if (slots < 0) return -EOVERFLOW; @@ -1055,11 +1055,10 @@ int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, int slots; int rets; - msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request)); - if (mei_cl_is_other_connecting(cl)) return 0; + msg_slots = mei_hbm2slots(sizeof(struct hbm_client_connect_request)); slots = mei_hbuf_empty_slots(dev); if (slots < 0) return -EOVERFLOW; @@ -1299,7 +1298,7 @@ int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb, int ret; bool request; - msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request)); + msg_slots = mei_hbm2slots(sizeof(struct hbm_client_connect_request)); slots = mei_hbuf_empty_slots(dev); if (slots < 0) return -EOVERFLOW; @@ -1571,6 +1570,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, struct mei_device *dev; struct mei_msg_data *buf; struct mei_msg_hdr mei_hdr; + size_t hdr_len = sizeof(mei_hdr); size_t len; size_t hbuf_len; int hbuf_slots; @@ -1601,7 +1601,8 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, rets = -EOVERFLOW; goto err; } - hbuf_len = mei_slots2data(hbuf_slots) - sizeof(struct mei_msg_hdr); + + hbuf_len = mei_slots2data(hbuf_slots); mei_msg_hdr_init(&mei_hdr, cb); @@ -1609,11 +1610,11 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, * Split the message only if we can write the whole host buffer * otherwise wait for next time the host buffer is empty. */ - if (hbuf_len >= len) { + if (len + hdr_len <= hbuf_len) { mei_hdr.length = len; mei_hdr.msg_complete = 1; } else if ((u32)hbuf_slots == mei_hbuf_depth(dev)) { - mei_hdr.length = hbuf_len; + mei_hdr.length = hbuf_len - hdr_len; } else { return 0; } @@ -1621,7 +1622,8 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, cl_dbg(dev, cl, "buf: size = %zu idx = %zu\n", cb->buf.size, cb->buf_idx); - rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx); + rets = mei_write_message(dev, &mei_hdr, hdr_len, + buf->data + cb->buf_idx, mei_hdr.length); if (rets) goto err; @@ -1661,6 +1663,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) struct mei_device *dev; struct mei_msg_data *buf; struct mei_msg_hdr mei_hdr; + size_t hdr_len = sizeof(mei_hdr); size_t len; size_t hbuf_len; int hbuf_slots; @@ -1716,15 +1719,17 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) goto out; } - hbuf_len = mei_slots2data(hbuf_slots) - sizeof(struct mei_msg_hdr); - if (hbuf_len >= len) { + hbuf_len = mei_slots2data(hbuf_slots); + + if (len + hdr_len <= hbuf_len) { mei_hdr.length = len; mei_hdr.msg_complete = 1; } else { - mei_hdr.length = hbuf_len; + mei_hdr.length = hbuf_len - hdr_len; } - rets = mei_write_message(dev, &mei_hdr, buf->data); + rets = mei_write_message(dev, &mei_hdr, hdr_len, + buf->data, mei_hdr.length); if (rets) goto err; @@ -1761,7 +1766,7 @@ out: } } - rets = len; + rets = buf->size; err: cl_dbg(dev, cl, "rpm: autosuspend\n"); pm_runtime_mark_last_busy(dev->dev); |