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/hw-me.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/hw-me.c')
-rw-r--r-- | drivers/misc/mei/hw-me.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index c50671cf47eb..0e3c31595dda 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -517,28 +517,31 @@ static u32 mei_me_hbuf_depth(const struct mei_device *dev) return hw->hbuf_depth; } - /** * mei_me_hbuf_write - writes a message to host hw buffer. * * @dev: the device structure - * @header: mei HECI header of message - * @buf: message payload will be written + * @hdr: header of message + * @hdr_len: header length in bytes: must be multiplication of a slot (4bytes) + * @data: payload + * @data_len: payload length in bytes * - * Return: -EIO if write has failed + * Return: 0 if success, < 0 - otherwise. */ static int mei_me_hbuf_write(struct mei_device *dev, - struct mei_msg_hdr *header, - const unsigned char *buf) + const void *hdr, size_t hdr_len, + const void *data, size_t data_len) { unsigned long rem; - unsigned long length = header->length; unsigned long i; - u32 *reg_buf = (u32 *)buf; + const u32 *reg_buf; u32 dw_cnt; int empty_slots; - dev_dbg(dev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header)); + if (WARN_ON(!hdr || !data || hdr_len & 0x3)) + return -EINVAL; + + dev_dbg(dev->dev, MEI_HDR_FMT, MEI_HDR_PRM((struct mei_msg_hdr *)hdr)); empty_slots = mei_hbuf_empty_slots(dev); dev_dbg(dev->dev, "empty slots = %hu.\n", empty_slots); @@ -546,20 +549,23 @@ static int mei_me_hbuf_write(struct mei_device *dev, if (empty_slots < 0) return -EOVERFLOW; - dw_cnt = mei_data2slots(length); + dw_cnt = mei_data2slots(hdr_len + data_len); if (dw_cnt > (u32)empty_slots) return -EMSGSIZE; - mei_me_hcbww_write(dev, *((u32 *) header)); + reg_buf = hdr; + for (i = 0; i < hdr_len / MEI_SLOT_SIZE; i++) + mei_me_hcbww_write(dev, reg_buf[i]); - for (i = 0; i < length / MEI_SLOT_SIZE; i++) + reg_buf = data; + for (i = 0; i < data_len / MEI_SLOT_SIZE; i++) mei_me_hcbww_write(dev, reg_buf[i]); - rem = length & 0x3; + rem = data_len & 0x3; if (rem > 0) { u32 reg = 0; - memcpy(®, &buf[length - rem], rem); + memcpy(®, (const u8 *)data + data_len - rem, rem); mei_me_hcbww_write(dev, reg); } |