Commit 98e70866 authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman

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: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b34e9a15
...@@ -863,7 +863,7 @@ int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -863,7 +863,7 @@ int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb,
int slots; int slots;
int ret; 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); slots = mei_hbuf_empty_slots(dev);
if (slots < 0) if (slots < 0)
return -EOVERFLOW; return -EOVERFLOW;
...@@ -1055,11 +1055,10 @@ int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -1055,11 +1055,10 @@ int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb,
int slots; int slots;
int rets; int rets;
msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request));
if (mei_cl_is_other_connecting(cl)) if (mei_cl_is_other_connecting(cl))
return 0; return 0;
msg_slots = mei_hbm2slots(sizeof(struct hbm_client_connect_request));
slots = mei_hbuf_empty_slots(dev); slots = mei_hbuf_empty_slots(dev);
if (slots < 0) if (slots < 0)
return -EOVERFLOW; return -EOVERFLOW;
...@@ -1299,7 +1298,7 @@ int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -1299,7 +1298,7 @@ int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb,
int ret; int ret;
bool request; 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); slots = mei_hbuf_empty_slots(dev);
if (slots < 0) if (slots < 0)
return -EOVERFLOW; return -EOVERFLOW;
...@@ -1571,6 +1570,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -1571,6 +1570,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
struct mei_device *dev; struct mei_device *dev;
struct mei_msg_data *buf; struct mei_msg_data *buf;
struct mei_msg_hdr mei_hdr; struct mei_msg_hdr mei_hdr;
size_t hdr_len = sizeof(mei_hdr);
size_t len; size_t len;
size_t hbuf_len; size_t hbuf_len;
int hbuf_slots; int hbuf_slots;
...@@ -1601,7 +1601,8 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -1601,7 +1601,8 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
rets = -EOVERFLOW; rets = -EOVERFLOW;
goto err; 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); 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, ...@@ -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 * Split the message only if we can write the whole host buffer
* otherwise wait for next time the host buffer is empty. * 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.length = len;
mei_hdr.msg_complete = 1; mei_hdr.msg_complete = 1;
} else if ((u32)hbuf_slots == mei_hbuf_depth(dev)) { } else if ((u32)hbuf_slots == mei_hbuf_depth(dev)) {
mei_hdr.length = hbuf_len; mei_hdr.length = hbuf_len - hdr_len;
} else { } else {
return 0; return 0;
} }
...@@ -1621,7 +1622,8 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -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", cl_dbg(dev, cl, "buf: size = %zu idx = %zu\n",
cb->buf.size, cb->buf_idx); 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) if (rets)
goto err; goto err;
...@@ -1661,6 +1663,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) ...@@ -1661,6 +1663,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb)
struct mei_device *dev; struct mei_device *dev;
struct mei_msg_data *buf; struct mei_msg_data *buf;
struct mei_msg_hdr mei_hdr; struct mei_msg_hdr mei_hdr;
size_t hdr_len = sizeof(mei_hdr);
size_t len; size_t len;
size_t hbuf_len; size_t hbuf_len;
int hbuf_slots; int hbuf_slots;
...@@ -1716,15 +1719,17 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) ...@@ -1716,15 +1719,17 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb)
goto out; goto out;
} }
hbuf_len = mei_slots2data(hbuf_slots) - sizeof(struct mei_msg_hdr); hbuf_len = mei_slots2data(hbuf_slots);
if (hbuf_len >= len) {
if (len + hdr_len <= hbuf_len) {
mei_hdr.length = len; mei_hdr.length = len;
mei_hdr.msg_complete = 1; mei_hdr.msg_complete = 1;
} else { } 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) if (rets)
goto err; goto err;
...@@ -1761,7 +1766,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) ...@@ -1761,7 +1766,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb)
} }
} }
rets = len; rets = buf->size;
err: err:
cl_dbg(dev, cl, "rpm: autosuspend\n"); cl_dbg(dev, cl, "rpm: autosuspend\n");
pm_runtime_mark_last_busy(dev->dev); pm_runtime_mark_last_busy(dev->dev);
......
...@@ -95,6 +95,20 @@ static int mei_cl_conn_status_to_errno(enum mei_cl_connect_status status) ...@@ -95,6 +95,20 @@ static int mei_cl_conn_status_to_errno(enum mei_cl_connect_status status)
} }
} }
/**
* mei_hbm_write_message - wrapper for sending hbm messages.
*
* @dev: mei device
* @hdr: mei header
* @data: payload
*/
static inline int mei_hbm_write_message(struct mei_device *dev,
struct mei_msg_hdr *hdr,
const void *data)
{
return mei_write_message(dev, hdr, sizeof(*hdr), data, hdr->length);
}
/** /**
* mei_hbm_idle - set hbm to idle state * mei_hbm_idle - set hbm to idle state
* *
...@@ -174,7 +188,7 @@ static inline int mei_hbm_cl_write(struct mei_device *dev, struct mei_cl *cl, ...@@ -174,7 +188,7 @@ static inline int mei_hbm_cl_write(struct mei_device *dev, struct mei_cl *cl,
mei_hbm_hdr(&mei_hdr, len); mei_hbm_hdr(&mei_hdr, len);
mei_hbm_cl_hdr(cl, hbm_cmd, buf, len); mei_hbm_cl_hdr(cl, hbm_cmd, buf, len);
return mei_write_message(dev, &mei_hdr, buf); return mei_hbm_write_message(dev, &mei_hdr, buf);
} }
/** /**
...@@ -267,7 +281,7 @@ int mei_hbm_start_req(struct mei_device *dev) ...@@ -267,7 +281,7 @@ int mei_hbm_start_req(struct mei_device *dev)
start_req.host_version.minor_version = HBM_MINOR_VERSION; start_req.host_version.minor_version = HBM_MINOR_VERSION;
dev->hbm_state = MEI_HBM_IDLE; dev->hbm_state = MEI_HBM_IDLE;
ret = mei_write_message(dev, &mei_hdr, &start_req); ret = mei_hbm_write_message(dev, &mei_hdr, &start_req);
if (ret) { if (ret) {
dev_err(dev->dev, "version message write failed: ret = %d\n", dev_err(dev->dev, "version message write failed: ret = %d\n",
ret); ret);
...@@ -304,7 +318,7 @@ static int mei_hbm_enum_clients_req(struct mei_device *dev) ...@@ -304,7 +318,7 @@ static int mei_hbm_enum_clients_req(struct mei_device *dev)
enum_req.flags |= dev->hbm_f_ie_supported ? enum_req.flags |= dev->hbm_f_ie_supported ?
MEI_HBM_ENUM_F_IMMEDIATE_ENUM : 0; MEI_HBM_ENUM_F_IMMEDIATE_ENUM : 0;
ret = mei_write_message(dev, &mei_hdr, &enum_req); ret = mei_hbm_write_message(dev, &mei_hdr, &enum_req);
if (ret) { if (ret) {
dev_err(dev->dev, "enumeration request write failed: ret = %d.\n", dev_err(dev->dev, "enumeration request write failed: ret = %d.\n",
ret); ret);
...@@ -373,7 +387,7 @@ static int mei_hbm_add_cl_resp(struct mei_device *dev, u8 addr, u8 status) ...@@ -373,7 +387,7 @@ static int mei_hbm_add_cl_resp(struct mei_device *dev, u8 addr, u8 status)
resp.me_addr = addr; resp.me_addr = addr;
resp.status = status; resp.status = status;
ret = mei_write_message(dev, &mei_hdr, &resp); ret = mei_hbm_write_message(dev, &mei_hdr, &resp);
if (ret) if (ret)
dev_err(dev->dev, "add client response write failed: ret = %d\n", dev_err(dev->dev, "add client response write failed: ret = %d\n",
ret); ret);
...@@ -430,7 +444,7 @@ int mei_hbm_cl_notify_req(struct mei_device *dev, ...@@ -430,7 +444,7 @@ int mei_hbm_cl_notify_req(struct mei_device *dev,
req.start = start; req.start = start;
ret = mei_write_message(dev, &mei_hdr, &req); ret = mei_hbm_write_message(dev, &mei_hdr, &req);
if (ret) if (ret)
dev_err(dev->dev, "notify request failed: ret = %d\n", ret); dev_err(dev->dev, "notify request failed: ret = %d\n", ret);
...@@ -555,7 +569,7 @@ static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx) ...@@ -555,7 +569,7 @@ static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx)
prop_req.hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; prop_req.hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
prop_req.me_addr = addr; prop_req.me_addr = addr;
ret = mei_write_message(dev, &mei_hdr, &prop_req); ret = mei_hbm_write_message(dev, &mei_hdr, &prop_req);
if (ret) { if (ret) {
dev_err(dev->dev, "properties request write failed: ret = %d\n", dev_err(dev->dev, "properties request write failed: ret = %d\n",
ret); ret);
...@@ -592,7 +606,7 @@ int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd) ...@@ -592,7 +606,7 @@ int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd)
memset(&req, 0, len); memset(&req, 0, len);
req.hbm_cmd = pg_cmd; req.hbm_cmd = pg_cmd;
ret = mei_write_message(dev, &mei_hdr, &req); ret = mei_hbm_write_message(dev, &mei_hdr, &req);
if (ret) if (ret)
dev_err(dev->dev, "power gate command write failed.\n"); dev_err(dev->dev, "power gate command write failed.\n");
return ret; return ret;
...@@ -618,7 +632,7 @@ static int mei_hbm_stop_req(struct mei_device *dev) ...@@ -618,7 +632,7 @@ static int mei_hbm_stop_req(struct mei_device *dev)
req.hbm_cmd = HOST_STOP_REQ_CMD; req.hbm_cmd = HOST_STOP_REQ_CMD;
req.reason = DRIVER_STOP_REQUEST; req.reason = DRIVER_STOP_REQUEST;
return mei_write_message(dev, &mei_hdr, &req); return mei_hbm_write_message(dev, &mei_hdr, &req);
} }
/** /**
......
...@@ -517,28 +517,31 @@ static u32 mei_me_hbuf_depth(const struct mei_device *dev) ...@@ -517,28 +517,31 @@ static u32 mei_me_hbuf_depth(const struct mei_device *dev)
return hw->hbuf_depth; return hw->hbuf_depth;
} }
/** /**
* mei_me_hbuf_write - writes a message to host hw buffer. * mei_me_hbuf_write - writes a message to host hw buffer.
* *
* @dev: the device structure * @dev: the device structure
* @header: mei HECI header of message * @hdr: header of message
* @buf: message payload will be written * @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, static int mei_me_hbuf_write(struct mei_device *dev,
struct mei_msg_hdr *header, const void *hdr, size_t hdr_len,
const unsigned char *buf) const void *data, size_t data_len)
{ {
unsigned long rem; unsigned long rem;
unsigned long length = header->length;
unsigned long i; unsigned long i;
u32 *reg_buf = (u32 *)buf; const u32 *reg_buf;
u32 dw_cnt; u32 dw_cnt;
int empty_slots; 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); empty_slots = mei_hbuf_empty_slots(dev);
dev_dbg(dev->dev, "empty slots = %hu.\n", empty_slots); dev_dbg(dev->dev, "empty slots = %hu.\n", empty_slots);
...@@ -546,20 +549,23 @@ static int mei_me_hbuf_write(struct mei_device *dev, ...@@ -546,20 +549,23 @@ static int mei_me_hbuf_write(struct mei_device *dev,
if (empty_slots < 0) if (empty_slots < 0)
return -EOVERFLOW; return -EOVERFLOW;
dw_cnt = mei_data2slots(length); dw_cnt = mei_data2slots(hdr_len + data_len);
if (dw_cnt > (u32)empty_slots) if (dw_cnt > (u32)empty_slots)
return -EMSGSIZE; 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]); mei_me_hcbww_write(dev, reg_buf[i]);
rem = length & 0x3; rem = data_len & 0x3;
if (rem > 0) { if (rem > 0) {
u32 reg = 0; u32 reg = 0;
memcpy(&reg, &buf[length - rem], rem); memcpy(&reg, (const u8 *)data + data_len - rem, rem);
mei_me_hcbww_write(dev, reg); mei_me_hcbww_write(dev, reg);
} }
......
...@@ -689,37 +689,34 @@ static void mei_txe_hw_config(struct mei_device *dev) ...@@ -689,37 +689,34 @@ static void mei_txe_hw_config(struct mei_device *dev)
hw->aliveness, hw->readiness); hw->aliveness, hw->readiness);
} }
/** /**
* mei_txe_write - writes a message to device. * mei_txe_write - writes a message to device.
* *
* @dev: the device structure * @dev: the device structure
* @header: header of message * @hdr: header of message
* @buf: message buffer will be written * @hdr_len: header length in bytes - must multiplication of a slot (4bytes)
* @data: payload
* @data_len: paylead length in bytes
* *
* Return: 0 if success, <0 - otherwise. * Return: 0 if success, < 0 - otherwise.
*/ */
static int mei_txe_write(struct mei_device *dev, static int mei_txe_write(struct mei_device *dev,
struct mei_msg_hdr *header, const void *hdr, size_t hdr_len,
const unsigned char *buf) const void *data, size_t data_len)
{ {
struct mei_txe_hw *hw = to_txe_hw(dev); struct mei_txe_hw *hw = to_txe_hw(dev);
unsigned long rem; unsigned long rem;
unsigned long length; const u32 *reg_buf;
unsigned long i;
u32 slots = TXE_HBUF_DEPTH; u32 slots = TXE_HBUF_DEPTH;
u32 *reg_buf = (u32 *)buf;
u32 dw_cnt; u32 dw_cnt;
unsigned long i, j;
if (WARN_ON(!header || !buf)) if (WARN_ON(!hdr || !data || hdr_len & 0x3))
return -EINVAL; return -EINVAL;
length = header->length; dev_dbg(dev->dev, MEI_HDR_FMT, MEI_HDR_PRM((struct mei_msg_hdr *)hdr));
dev_dbg(dev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header));
dw_cnt = mei_data2slots(length); dw_cnt = mei_data2slots(hdr_len + data_len);
if (dw_cnt > slots) if (dw_cnt > slots)
return -EMSGSIZE; return -EMSGSIZE;
...@@ -737,17 +734,20 @@ static int mei_txe_write(struct mei_device *dev, ...@@ -737,17 +734,20 @@ static int mei_txe_write(struct mei_device *dev,
return -EAGAIN; return -EAGAIN;
} }
mei_txe_input_payload_write(dev, 0, *((u32 *)header)); reg_buf = hdr;
for (i = 0; i < hdr_len / MEI_SLOT_SIZE; i++)
mei_txe_input_payload_write(dev, i, reg_buf[i]);
for (i = 0; i < length / 4; i++) reg_buf = data;
mei_txe_input_payload_write(dev, i + 1, reg_buf[i]); for (j = 0; j < data_len / MEI_SLOT_SIZE; j++)
mei_txe_input_payload_write(dev, i + j, reg_buf[j]);
rem = length & 0x3; rem = data_len & 0x3;
if (rem > 0) { if (rem > 0) {
u32 reg = 0; u32 reg = 0;
memcpy(&reg, &buf[length - rem], rem); memcpy(&reg, (const u8 *)data + data_len - rem, rem);
mei_txe_input_payload_write(dev, i + 1, reg); mei_txe_input_payload_write(dev, i + j, reg);
} }
/* after each write the whole buffer is consumed */ /* after each write the whole buffer is consumed */
......
...@@ -173,7 +173,7 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -173,7 +173,7 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb,
int slots; int slots;
int ret; int ret;
msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_response)); msg_slots = mei_hbm2slots(sizeof(struct hbm_client_connect_response));
slots = mei_hbuf_empty_slots(dev); slots = mei_hbuf_empty_slots(dev);
if (slots < 0) if (slots < 0)
return -EOVERFLOW; return -EOVERFLOW;
...@@ -208,7 +208,7 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -208,7 +208,7 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
if (!list_empty(&cl->rd_pending)) if (!list_empty(&cl->rd_pending))
return 0; return 0;
msg_slots = mei_data2slots(sizeof(struct hbm_flow_control)); msg_slots = mei_hbm2slots(sizeof(struct hbm_flow_control));
slots = mei_hbuf_empty_slots(dev); slots = mei_hbuf_empty_slots(dev);
if (slots < 0) if (slots < 0)
return -EOVERFLOW; return -EOVERFLOW;
......
...@@ -300,8 +300,8 @@ struct mei_hw_ops { ...@@ -300,8 +300,8 @@ struct mei_hw_ops {
bool (*hbuf_is_ready)(struct mei_device *dev); bool (*hbuf_is_ready)(struct mei_device *dev);
u32 (*hbuf_depth)(const struct mei_device *dev); u32 (*hbuf_depth)(const struct mei_device *dev);
int (*write)(struct mei_device *dev, int (*write)(struct mei_device *dev,
struct mei_msg_hdr *hdr, const void *hdr, size_t hdr_len,
const unsigned char *buf); const void *data, size_t data_len);
int (*rdbuf_full_slots)(struct mei_device *dev); int (*rdbuf_full_slots)(struct mei_device *dev);
...@@ -528,14 +528,26 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec) ...@@ -528,14 +528,26 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
} }
/** /**
* mei_data2slots - get slots - number of (dwords) from a message length * mei_data2slots - get slots number from a message length
* + size of the mei header
* *
* @length: size of the messages in bytes * @length: size of the messages in bytes
* *
* Return: number of slots * Return: number of slots
*/ */
static inline u32 mei_data2slots(size_t length) static inline u32 mei_data2slots(size_t length)
{
return DIV_ROUND_UP(length, MEI_SLOT_SIZE);
}
/**
* mei_hbm2slots - get slots number from a hbm message length
* length + size of the mei message header
*
* @length: size of the messages in bytes
*
* Return: number of slots
*/
static inline u32 mei_hbm2slots(size_t length)
{ {
return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, MEI_SLOT_SIZE); return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, MEI_SLOT_SIZE);
} }
...@@ -656,9 +668,10 @@ static inline u32 mei_hbuf_depth(const struct mei_device *dev) ...@@ -656,9 +668,10 @@ static inline u32 mei_hbuf_depth(const struct mei_device *dev)
} }
static inline int mei_write_message(struct mei_device *dev, static inline int mei_write_message(struct mei_device *dev,
struct mei_msg_hdr *hdr, const void *buf) const void *hdr, size_t hdr_len,
const void *data, size_t data_len)
{ {
return dev->ops->write(dev, hdr, buf); return dev->ops->write(dev, hdr, hdr_len, data, data_len);
} }
static inline u32 mei_read_hdr(const struct mei_device *dev) static inline u32 mei_read_hdr(const struct mei_device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment