mei: bus: enable sending gsc commands
authorTomas Winkler <tomas.winkler@intel.com>
Wed, 28 Sep 2022 00:41:32 +0000 (17:41 -0700)
committerDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Mon, 3 Oct 2022 18:29:08 +0000 (11:29 -0700)
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.winkler@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Vitaly Lubart <vitaly.lubart@intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20220928004145.745803-3-daniele.ceraolospurio@intel.com
drivers/misc/mei/bus.c
drivers/misc/mei/mei_dev.h

index 46aa355..225f0b0 100644 (file)
@@ -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 @@ copy:
                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;
 
index 31784bb..8d80184 100644 (file)
@@ -116,12 +116,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),
 };
 
 /*