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: Alexander Usyskin <alexander.usyskin@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Link: https://lore.kernel.org/r/20201116125612.1660971-1-tomas.winkler@intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
6e559fe128
Коммит
85261c1ff1
|
@ -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 @@ out:
|
|||
* @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 @@ copy:
|
|||
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);
|
||||
|
@ -205,6 +210,72 @@ out:
|
|||
return rets;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* * < 0 on error
|
||||
*/
|
||||
|
||||
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, vtag, MEI_CL_IO_TX_BLOCKING);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mei_cldev_send_vtag);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* * < 0 on error
|
||||
*/
|
||||
|
||||
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, vtag, 0, 0);
|
||||
}
|
||||
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)
|
||||
*
|
||||
|
@ -212,16 +283,31 @@ out:
|
|||
* @buf: buffer to send
|
||||
* @length: buffer length
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
struct mei_cl *cl = cldev->cl;
|
||||
|
||||
return __mei_cl_send(cl, buf, length, MEI_CL_IO_TX_BLOCKING);
|
||||
return mei_cldev_send_vtag(cldev, buf, length, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mei_cldev_send);
|
||||
|
||||
/**
|
||||
* mei_cldev_recv - client receive (read)
|
||||
*
|
||||
* @cldev: me client device
|
||||
* @buf: buffer to receive
|
||||
* @length: buffer length
|
||||
*
|
||||
* Return: read size in bytes of < 0 on error
|
||||
*/
|
||||
ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length)
|
||||
{
|
||||
return mei_cldev_recv_vtag(cldev, buf, length, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mei_cldev_recv);
|
||||
|
||||
/**
|
||||
* mei_cldev_recv_nonblock - non block client receive (read)
|
||||
*
|
||||
|
@ -235,29 +321,10 @@ EXPORT_SYMBOL_GPL(mei_cldev_send);
|
|||
ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf,
|
||||
size_t length)
|
||||
{
|
||||
struct mei_cl *cl = cldev->cl;
|
||||
|
||||
return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK, 0);
|
||||
return mei_cldev_recv_nonblock_vtag(cldev, buf, length, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock);
|
||||
|
||||
/**
|
||||
* mei_cldev_recv - client receive (read)
|
||||
*
|
||||
* @cldev: me client device
|
||||
* @buf: buffer to receive
|
||||
* @length: buffer length
|
||||
*
|
||||
* Return: read size in bytes of < 0 on error
|
||||
*/
|
||||
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);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mei_cldev_recv);
|
||||
|
||||
/**
|
||||
* 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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче