提交 85261c1f 编写于 作者: A Alexander Usyskin 提交者: Greg Kroah-Hartman

mei: bus: add vtag support

Add API to support vtag in communication on mei bus.

Add mei_cldev_send_vtag, mei_cldev_recv_vtag and
mei_cldev_recv_nonblock_vtag functions to allow sending a message
with vtag set and to receive vtag of an incoming message.

Cc: Sean Z Huang <sean.z.huang@intel.com>
Signed-off-by: NAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: NTomas Winkler <tomas.winkler@intel.com>
Link: https://lore.kernel.org/r/20201116125612.1660971-1-tomas.winkler@intel.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 6e559fe1
......@@ -148,7 +148,7 @@ static int mei_osver(struct mei_cl_device *cldev)
os_ver = (struct mei_os_ver *)fwcaps->data;
os_ver->os_type = OSTYPE_LINUX;
return __mei_cl_send(cldev->cl, buf, size, mode);
return __mei_cl_send(cldev->cl, buf, size, 0, mode);
}
#define MKHI_FWVER_BUF_LEN (sizeof(struct mkhi_msg_hdr) + \
......@@ -169,7 +169,7 @@ static int mei_fwver(struct mei_cl_device *cldev)
req.hdr.group_id = MKHI_GEN_GROUP_ID;
req.hdr.command = MKHI_GEN_GET_FW_VERSION_CMD;
ret = __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req),
ret = __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req), 0,
MEI_CL_IO_TX_BLOCKING);
if (ret < 0) {
dev_err(&cldev->dev, "Could not send ReqFWVersion cmd\n");
......@@ -177,7 +177,7 @@ static int mei_fwver(struct mei_cl_device *cldev)
}
ret = 0;
bytes_recv = __mei_cl_recv(cldev->cl, buf, sizeof(buf), 0,
bytes_recv = __mei_cl_recv(cldev->cl, buf, sizeof(buf), NULL, 0,
MKHI_RCV_TIMEOUT);
if (bytes_recv < 0 || (size_t)bytes_recv < MKHI_FWVER_LEN(1)) {
/*
......@@ -324,13 +324,15 @@ static int mei_nfc_if_version(struct mei_cl *cl,
};
struct mei_nfc_reply *reply = NULL;
size_t if_version_length;
u8 vtag;
int bytes_recv, ret;
bus = cl->dev;
WARN_ON(mutex_is_locked(&bus->device_lock));
ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(cmd), MEI_CL_IO_TX_BLOCKING);
ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(cmd), 0,
MEI_CL_IO_TX_BLOCKING);
if (ret < 0) {
dev_err(bus->dev, "Could not send IF version cmd\n");
return ret;
......@@ -344,7 +346,8 @@ static int mei_nfc_if_version(struct mei_cl *cl,
return -ENOMEM;
ret = 0;
bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0, 0);
bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, &vtag,
0, 0);
if (bytes_recv < 0 || (size_t)bytes_recv < if_version_length) {
dev_err(bus->dev, "Could not read IF version\n");
ret = -EIO;
......
......@@ -26,11 +26,12 @@
* @cl: host client
* @buf: buffer to send
* @length: buffer length
* @vtag: virtual tag
* @mode: sending mode
*
* Return: written size bytes or < 0 on error
*/
ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, u8 vtag,
unsigned int mode)
{
struct mei_device *bus;
......@@ -86,6 +87,7 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
rets = -ENOMEM;
goto out;
}
cb->vtag = vtag;
cb->internal = !!(mode & MEI_CL_IO_TX_INTERNAL);
cb->blocking = !!(mode & MEI_CL_IO_TX_BLOCKING);
......@@ -106,11 +108,12 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
* @buf: buffer to receive
* @length: buffer length
* @mode: io mode
* @vtag: virtual tag
* @timeout: recv timeout, 0 for infinite timeout
*
* Return: read size in bytes of < 0 on error
*/
ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, u8 *vtag,
unsigned int mode, unsigned long timeout)
{
struct mei_device *bus;
......@@ -196,6 +199,8 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
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;
free:
mei_cl_del_rd_completed(cl, cb);
......@@ -206,40 +211,87 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
}
/**
* mei_cldev_send - me device send (write)
* mei_cldev_send_vtag - me device send with vtag (write)
*
* @cldev: me client device
* @buf: buffer to send
* @length: buffer length
* @vtag: virtual tag
*
* Return: written size in bytes or < 0 on error
* Return:
* * written size in bytes
* * < 0 on error
*/
ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
ssize_t mei_cldev_send_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length,
u8 vtag)
{
struct mei_cl *cl = cldev->cl;
return __mei_cl_send(cl, buf, length, MEI_CL_IO_TX_BLOCKING);
return __mei_cl_send(cl, buf, length, vtag, MEI_CL_IO_TX_BLOCKING);
}
EXPORT_SYMBOL_GPL(mei_cldev_send);
EXPORT_SYMBOL_GPL(mei_cldev_send_vtag);
/**
* mei_cldev_recv_nonblock - non block client receive (read)
* mei_cldev_recv_vtag - client receive with vtag (read)
*
* @cldev: me client device
* @buf: buffer to receive
* @length: buffer length
* @vtag: virtual tag
*
* Return: read size in bytes of < 0 on error
* -EAGAIN if function will block.
* Return:
* * read size in bytes
* * < 0 on error
*/
ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf,
size_t length)
ssize_t mei_cldev_recv_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length,
u8 *vtag)
{
struct mei_cl *cl = cldev->cl;
return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK, 0);
return __mei_cl_recv(cl, buf, length, vtag, 0, 0);
}
EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock);
EXPORT_SYMBOL_GPL(mei_cldev_recv_vtag);
/**
* mei_cldev_recv_nonblock_vtag - non block client receive with vtag (read)
*
* @cldev: me client device
* @buf: buffer to receive
* @length: buffer length
* @vtag: virtual tag
*
* Return:
* * read size in bytes
* * -EAGAIN if function will block.
* * < 0 on other error
*/
ssize_t mei_cldev_recv_nonblock_vtag(struct mei_cl_device *cldev, u8 *buf,
size_t length, u8 *vtag)
{
struct mei_cl *cl = cldev->cl;
return __mei_cl_recv(cl, buf, length, vtag, MEI_CL_IO_RX_NONBLOCK, 0);
}
EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock_vtag);
/**
* mei_cldev_send - me device send (write)
*
* @cldev: me client device
* @buf: buffer to send
* @length: buffer length
*
* Return:
* * written size in bytes
* * < 0 on error
*/
ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length)
{
return mei_cldev_send_vtag(cldev, buf, length, 0);
}
EXPORT_SYMBOL_GPL(mei_cldev_send);
/**
* mei_cldev_recv - client receive (read)
......@@ -252,12 +304,27 @@ EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock);
*/
ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length)
{
struct mei_cl *cl = cldev->cl;
return __mei_cl_recv(cl, buf, length, 0, 0);
return mei_cldev_recv_vtag(cldev, buf, length, NULL);
}
EXPORT_SYMBOL_GPL(mei_cldev_recv);
/**
* mei_cldev_recv_nonblock - non block client receive (read)
*
* @cldev: me client device
* @buf: buffer to receive
* @length: buffer length
*
* Return: read size in bytes of < 0 on error
* -EAGAIN if function will block.
*/
ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf,
size_t length)
{
return mei_cldev_recv_nonblock_vtag(cldev, buf, length, NULL);
}
EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock);
/**
* mei_cl_bus_rx_work - dispatch rx event for a bus device
*
......
......@@ -1306,7 +1306,7 @@ struct mei_cl_vtag *mei_cl_vtag_alloc(struct file *fp, u8 vtag)
* mei_cl_fp_by_vtag - obtain the file pointer by vtag
*
* @cl: host client
* @vtag: vm tag
* @vtag: virtual tag
*
* Return:
* * A file pointer - on success
......@@ -1317,7 +1317,9 @@ const struct file *mei_cl_fp_by_vtag(const struct mei_cl *cl, u8 vtag)
struct mei_cl_vtag *vtag_l;
list_for_each_entry(vtag_l, &cl->vtag_map, list)
if (vtag_l->vtag == vtag)
/* The client on bus has one fixed fp */
if ((cl->cldev && mei_cldev_enabled(cl->cldev)) ||
vtag_l->vtag == vtag)
return vtag_l->fp;
return ERR_PTR(-ENOENT);
......
......@@ -340,9 +340,9 @@ struct mei_hw_ops {
/* MEI bus API*/
void mei_cl_bus_rescan_work(struct work_struct *work);
void mei_cl_bus_dev_fixup(struct mei_cl_device *dev);
ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, u8 vtag,
unsigned int mode);
ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length,
ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, u8 *vtag,
unsigned int mode, unsigned long timeout);
bool mei_cl_bus_rx_event(struct mei_cl *cl);
bool mei_cl_bus_notify_event(struct mei_cl *cl);
......
......@@ -95,6 +95,12 @@ ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length);
ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length);
ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf,
size_t length);
ssize_t mei_cldev_send_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length,
u8 vtag);
ssize_t mei_cldev_recv_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length,
u8 *vtag);
ssize_t mei_cldev_recv_nonblock_vtag(struct mei_cl_device *cldev, u8 *buf,
size_t length, u8 *vtag);
int mei_cldev_register_rx_cb(struct mei_cl_device *cldev, mei_cldev_cb_t rx_cb);
int mei_cldev_register_notif_cb(struct mei_cl_device *cldev,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册