提交 6aae48ff 编写于 作者: T Tomas Winkler 提交者: Greg Kroah-Hartman

mei: add mei_hbuf_acquire wrapper

A client has to acquire host buffer
before writing, we add lock like wrapper
to replace the code snippet

if (dev->hbuf_is_ready)
        dev->hbuf_is_ready = false;
Signed-off-by: NTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 4a22176a
...@@ -296,9 +296,8 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) ...@@ -296,9 +296,8 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
if (ret < 0) if (ret < 0)
return ret; return ret;
if (ret && dev->hbuf_is_ready) { if (ret && mei_hbuf_acquire(dev)) {
ret = 0; ret = 0;
dev->hbuf_is_ready = false;
if (cb->request_buffer.size > mei_hbuf_max_len(dev)) { if (cb->request_buffer.size > mei_hbuf_max_len(dev)) {
mei_hdr.length = mei_hbuf_max_len(dev); mei_hdr.length = mei_hbuf_max_len(dev);
mei_hdr.msg_complete = 0; mei_hdr.msg_complete = 0;
...@@ -330,10 +329,6 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) ...@@ -330,10 +329,6 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
list_add_tail(&cb->list, &dev->write_list.list); list_add_tail(&cb->list, &dev->write_list.list);
} }
} else { } else {
if (!dev->hbuf_is_ready)
dev_dbg(&dev->pdev->dev, "host buffer is not empty");
dev_dbg(&dev->pdev->dev, "No flow control credentials, so add iamthif cb to write list.\n");
list_add_tail(&cb->list, &dev->write_list.list); list_add_tail(&cb->list, &dev->write_list.list);
} }
return 0; return 0;
......
...@@ -371,6 +371,23 @@ void mei_host_client_init(struct work_struct *work) ...@@ -371,6 +371,23 @@ void mei_host_client_init(struct work_struct *work)
mutex_unlock(&dev->device_lock); mutex_unlock(&dev->device_lock);
} }
/**
* mei_hbuf_acquire: try to acquire host buffer
*
* @dev: the device structure
* returns true if host buffer was acquired
*/
bool mei_hbuf_acquire(struct mei_device *dev)
{
if (!dev->hbuf_is_ready) {
dev_dbg(&dev->pdev->dev, "hbuf is not ready\n");
return false;
}
dev->hbuf_is_ready = false;
return true;
}
/** /**
* mei_cl_disconnect - disconnect host client from the me one * mei_cl_disconnect - disconnect host client from the me one
...@@ -402,8 +419,7 @@ int mei_cl_disconnect(struct mei_cl *cl) ...@@ -402,8 +419,7 @@ int mei_cl_disconnect(struct mei_cl *cl)
return -ENOMEM; return -ENOMEM;
cb->fop_type = MEI_FOP_CLOSE; cb->fop_type = MEI_FOP_CLOSE;
if (dev->hbuf_is_ready) { if (mei_hbuf_acquire(dev)) {
dev->hbuf_is_ready = false;
if (mei_hbm_cl_disconnect_req(dev, cl)) { if (mei_hbm_cl_disconnect_req(dev, cl)) {
rets = -ENODEV; rets = -ENODEV;
cl_err(dev, cl, "failed to disconnect.\n"); cl_err(dev, cl, "failed to disconnect.\n");
...@@ -503,9 +519,8 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) ...@@ -503,9 +519,8 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
cb->fop_type = MEI_FOP_CONNECT; cb->fop_type = MEI_FOP_CONNECT;
if (dev->hbuf_is_ready && !mei_cl_is_other_connecting(cl)) { /* run hbuf acquire last so we don't have to undo */
dev->hbuf_is_ready = false; if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) {
if (mei_hbm_cl_connect_req(dev, cl)) { if (mei_hbm_cl_connect_req(dev, cl)) {
rets = -ENODEV; rets = -ENODEV;
goto out; goto out;
...@@ -663,8 +678,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) ...@@ -663,8 +678,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
goto err; goto err;
cb->fop_type = MEI_FOP_READ; cb->fop_type = MEI_FOP_READ;
if (dev->hbuf_is_ready) { if (mei_hbuf_acquire(dev)) {
dev->hbuf_is_ready = false;
if (mei_hbm_cl_flow_control_req(dev, cl)) { if (mei_hbm_cl_flow_control_req(dev, cl)) {
cl_err(dev, cl, "flow control send failed\n"); cl_err(dev, cl, "flow control send failed\n");
rets = -ENODEV; rets = -ENODEV;
...@@ -799,21 +813,29 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) ...@@ -799,21 +813,29 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
cb->fop_type = MEI_FOP_WRITE; cb->fop_type = MEI_FOP_WRITE;
cb->buf_idx = 0;
cl->writing_state = MEI_IDLE;
mei_hdr.host_addr = cl->host_client_id;
mei_hdr.me_addr = cl->me_client_id;
mei_hdr.reserved = 0;
mei_hdr.msg_complete = 0;
mei_hdr.internal = cb->internal;
rets = mei_cl_flow_ctrl_creds(cl); rets = mei_cl_flow_ctrl_creds(cl);
if (rets < 0) if (rets < 0)
goto err; goto err;
/* Host buffer is not ready, we queue the request */ if (rets == 0) {
if (rets == 0 || !dev->hbuf_is_ready) { cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
cb->buf_idx = 0; rets = buf->size;
/* unseting complete will enqueue the cb for write */ goto out;
mei_hdr.msg_complete = 0; }
if (!mei_hbuf_acquire(dev)) {
cl_dbg(dev, cl, "Cannot acquire the host buffer: not sending.\n");
rets = buf->size; rets = buf->size;
goto out; goto out;
} }
dev->hbuf_is_ready = false;
/* Check for a maximum length */ /* Check for a maximum length */
if (buf->size > mei_hbuf_max_len(dev)) { if (buf->size > mei_hbuf_max_len(dev)) {
...@@ -824,12 +846,6 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) ...@@ -824,12 +846,6 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
mei_hdr.msg_complete = 1; mei_hdr.msg_complete = 1;
} }
mei_hdr.host_addr = cl->host_client_id;
mei_hdr.me_addr = cl->me_client_id;
mei_hdr.reserved = 0;
mei_hdr.internal = cb->internal;
rets = mei_write_message(dev, &mei_hdr, buf->data); rets = mei_write_message(dev, &mei_hdr, buf->data);
if (rets) if (rets)
goto err; goto err;
......
...@@ -513,6 +513,8 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) ...@@ -513,6 +513,8 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
} }
} }
dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
rets = mei_irq_write_handler(dev, &complete_list); rets = mei_irq_write_handler(dev, &complete_list);
dev->hbuf_is_ready = mei_hbuf_is_ready(dev); dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
......
...@@ -605,7 +605,6 @@ static int mei_txe_write(struct mei_device *dev, ...@@ -605,7 +605,6 @@ static int mei_txe_write(struct mei_device *dev,
mei_txe_input_payload_write(dev, i + 1, reg); mei_txe_input_payload_write(dev, i + 1, reg);
} }
dev->hbuf_is_ready = false;
/* Set Input-Doorbell */ /* Set Input-Doorbell */
mei_txe_input_doorbell_set(hw); mei_txe_input_doorbell_set(hw);
...@@ -983,20 +982,16 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) ...@@ -983,20 +982,16 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id)
dev->hbuf_is_ready = true; dev->hbuf_is_ready = true;
if (hw->aliveness && dev->hbuf_is_ready) { if (hw->aliveness && dev->hbuf_is_ready) {
/* if SeC did not complete reading the written data by host */
if (!mei_txe_is_input_ready(dev)) {
dev_dbg(&dev->pdev->dev, "got Input Ready Int, but SEC_IPC_INPUT_STATUS_RDY is 0.\n");
goto end;
}
/* get the real register value */
dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
rets = mei_irq_write_handler(dev, &complete_list); rets = mei_irq_write_handler(dev, &complete_list);
if (rets) if (rets && rets != -EMSGSIZE)
dev_err(&dev->pdev->dev, dev_err(&dev->pdev->dev, "mei_irq_write_handler ret = %d.\n",
"mei_irq_write_handler ret = %d.\n", rets); rets);
dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
} }
mei_irq_compl_handler(dev, &complete_list); mei_irq_compl_handler(dev, &complete_list);
end: end:
......
...@@ -446,10 +446,10 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) ...@@ -446,10 +446,10 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
s32 slots; s32 slots;
int ret; int ret;
if (!mei_hbuf_is_ready(dev)) {
dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); if (!mei_hbuf_acquire(dev))
return 0; return 0;
}
slots = mei_hbuf_empty_slots(dev); slots = mei_hbuf_empty_slots(dev);
if (slots <= 0) if (slots <= 0)
return -EMSGSIZE; return -EMSGSIZE;
......
...@@ -630,6 +630,8 @@ static inline int mei_count_full_read_slots(struct mei_device *dev) ...@@ -630,6 +630,8 @@ static inline int mei_count_full_read_slots(struct mei_device *dev)
return dev->ops->rdbuf_full_slots(dev); return dev->ops->rdbuf_full_slots(dev);
} }
bool mei_hbuf_acquire(struct mei_device *dev);
#if IS_ENABLED(CONFIG_DEBUG_FS) #if IS_ENABLED(CONFIG_DEBUG_FS)
int mei_dbgfs_register(struct mei_device *dev, const char *name); int mei_dbgfs_register(struct mei_device *dev, const char *name);
void mei_dbgfs_deregister(struct mei_device *dev); void mei_dbgfs_deregister(struct mei_device *dev);
......
...@@ -158,9 +158,8 @@ int mei_wd_stop(struct mei_device *dev) ...@@ -158,9 +158,8 @@ int mei_wd_stop(struct mei_device *dev)
if (ret < 0) if (ret < 0)
goto out; goto out;
if (ret && dev->hbuf_is_ready) { if (ret && mei_hbuf_acquire(dev)) {
ret = 0; ret = 0;
dev->hbuf_is_ready = false;
if (!mei_wd_send(dev)) { if (!mei_wd_send(dev)) {
ret = mei_cl_flow_ctrl_reduce(&dev->wd_cl); ret = mei_cl_flow_ctrl_reduce(&dev->wd_cl);
...@@ -265,8 +264,8 @@ static int mei_wd_ops_stop(struct watchdog_device *wd_dev) ...@@ -265,8 +264,8 @@ static int mei_wd_ops_stop(struct watchdog_device *wd_dev)
*/ */
static int mei_wd_ops_ping(struct watchdog_device *wd_dev) static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
{ {
int ret = 0;
struct mei_device *dev; struct mei_device *dev;
int ret;
dev = watchdog_get_drvdata(wd_dev); dev = watchdog_get_drvdata(wd_dev);
if (!dev) if (!dev)
...@@ -282,10 +281,12 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) ...@@ -282,10 +281,12 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
dev->wd_state = MEI_WD_RUNNING; dev->wd_state = MEI_WD_RUNNING;
ret = mei_cl_flow_ctrl_creds(&dev->wd_cl);
if (ret < 0)
goto end;
/* Check if we can send the ping to HW*/ /* Check if we can send the ping to HW*/
if (dev->hbuf_is_ready && mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) { if (ret && mei_hbuf_acquire(dev)) {
dev->hbuf_is_ready = false;
dev_dbg(&dev->pdev->dev, "wd: sending ping\n"); dev_dbg(&dev->pdev->dev, "wd: sending ping\n");
if (mei_wd_send(dev)) { if (mei_wd_send(dev)) {
...@@ -295,8 +296,7 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) ...@@ -295,8 +296,7 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
} }
if (mei_cl_flow_ctrl_reduce(&dev->wd_cl)) { if (mei_cl_flow_ctrl_reduce(&dev->wd_cl)) {
dev_err(&dev->pdev->dev, dev_err(&dev->pdev->dev, "wd: mei_cl_flow_ctrl_reduce() failed.\n");
"wd: mei_cl_flow_ctrl_reduce() failed.\n");
ret = -EIO; ret = -EIO;
goto end; goto end;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册