From: Tomas Winkler <tomas.wink...@intel.com>

GSC command is and extended header containing a scatter gather
list and without a data buffer. Using MEI_CL_IO_SGL flag,
the caller send the GSC command as a data and the function internally
moves it to the extended header.

Signed-off-by: Tomas Winkler <tomas.wink...@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospu...@intel.com>
Cc: Vitaly Lubart <vitaly.lub...@intel.com>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/misc/mei/bus.c     | 20 ++++++++++++++++++--
 drivers/misc/mei/mei_dev.h |  4 ++++
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 46aa3554e97b..225f0b04c021 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -100,9 +100,18 @@ ssize_t __mei_cl_send(struct mei_cl *cl, const u8 *buf, 
size_t length, u8 vtag,
        cb->internal = !!(mode & MEI_CL_IO_TX_INTERNAL);
        cb->blocking = !!(mode & MEI_CL_IO_TX_BLOCKING);
        memcpy(cb->buf.data, buf, length);
+       /* hack we point data to header */
+       if (mode & MEI_CL_IO_SGL) {
+               cb->ext_hdr = (struct mei_ext_hdr *)cb->buf.data;
+               cb->buf.data = NULL;
+               cb->buf.size = 0;
+       }
 
        rets = mei_cl_write(cl, cb);
 
+       if (mode & MEI_CL_IO_SGL && rets == 0)
+               rets = length;
+
 out:
        mutex_unlock(&bus->device_lock);
 
@@ -205,9 +214,16 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t 
length, u8 *vtag,
                goto free;
        }
 
-       r_length = min_t(size_t, length, cb->buf_idx);
-       memcpy(buf, cb->buf.data, r_length);
+       /* for the GSC type - copy the extended header to the buffer */
+       if (cb->ext_hdr && cb->ext_hdr->type == MEI_EXT_HDR_GSC) {
+               r_length = min_t(size_t, length, cb->ext_hdr->length * 
sizeof(u32));
+               memcpy(buf, cb->ext_hdr, r_length);
+       } else {
+               r_length = min_t(size_t, length, cb->buf_idx);
+               memcpy(buf, cb->buf.data, r_length);
+       }
        rets = r_length;
+
        if (vtag)
                *vtag = cb->vtag;
 
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 862190b297aa..5e28294d5dca 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -109,12 +109,16 @@ enum mei_cb_file_ops {
  * @MEI_CL_IO_TX_INTERNAL: internal communication between driver and FW
  *
  * @MEI_CL_IO_RX_NONBLOCK: recv is non-blocking
+ *
+ * @MEI_CL_IO_SGL: send command with sgl list.
  */
 enum mei_cl_io_mode {
        MEI_CL_IO_TX_BLOCKING = BIT(0),
        MEI_CL_IO_TX_INTERNAL = BIT(1),
 
        MEI_CL_IO_RX_NONBLOCK = BIT(2),
+
+       MEI_CL_IO_SGL         = BIT(3),
 };
 
 /*
-- 
2.37.2

Reply via email to