Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6aae48ff authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman
Browse files

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: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4a22176a
Loading
Loading
Loading
Loading
+1 −6
Original line number Diff line number Diff line
@@ -296,9 +296,8 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
	if (ret < 0)
		return ret;

	if (ret && dev->hbuf_is_ready) {
	if (ret && mei_hbuf_acquire(dev)) {
		ret = 0;
		dev->hbuf_is_ready = false;
		if (cb->request_buffer.size > mei_hbuf_max_len(dev)) {
			mei_hdr.length = mei_hbuf_max_len(dev);
			mei_hdr.msg_complete = 0;
@@ -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);
		}
	} 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);
	}
	return 0;
+36 −20
Original line number Diff line number Diff line
@@ -371,6 +371,23 @@ void mei_host_client_init(struct work_struct *work)
	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
@@ -402,8 +419,7 @@ int mei_cl_disconnect(struct mei_cl *cl)
		return -ENOMEM;

	cb->fop_type = MEI_FOP_CLOSE;
	if (dev->hbuf_is_ready) {
		dev->hbuf_is_ready = false;
	if (mei_hbuf_acquire(dev)) {
		if (mei_hbm_cl_disconnect_req(dev, cl)) {
			rets = -ENODEV;
			cl_err(dev, cl, "failed to disconnect.\n");
@@ -503,9 +519,8 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)

	cb->fop_type = MEI_FOP_CONNECT;

	if (dev->hbuf_is_ready && !mei_cl_is_other_connecting(cl)) {
		dev->hbuf_is_ready = false;

	/* run hbuf acquire last so we don't have to undo */
	if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) {
		if (mei_hbm_cl_connect_req(dev, cl)) {
			rets = -ENODEV;
			goto out;
@@ -663,8 +678,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
		goto err;

	cb->fop_type = MEI_FOP_READ;
	if (dev->hbuf_is_ready) {
		dev->hbuf_is_ready = false;
	if (mei_hbuf_acquire(dev)) {
		if (mei_hbm_cl_flow_control_req(dev, cl)) {
			cl_err(dev, cl, "flow control send failed\n");
			rets = -ENODEV;
@@ -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->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);
	if (rets < 0)
		goto err;

	/* Host buffer is not ready, we queue the request */
	if (rets == 0 || !dev->hbuf_is_ready) {
		cb->buf_idx = 0;
		/* unseting complete will enqueue the cb for write */
		mei_hdr.msg_complete = 0;
	if (rets == 0) {
		cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
		rets = buf->size;
		goto out;
	}
	if (!mei_hbuf_acquire(dev)) {
		cl_dbg(dev, cl, "Cannot acquire the host buffer: not sending.\n");
		rets = buf->size;
		goto out;
	}

	dev->hbuf_is_ready = false;

	/* Check for a maximum length */
	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)
		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);
	if (rets)
		goto err;
+2 −0
Original line number Diff line number Diff line
@@ -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);

	dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
+6 −11
Original line number Diff line number Diff line
@@ -605,7 +605,6 @@ static int mei_txe_write(struct mei_device *dev,
		mei_txe_input_payload_write(dev, i + 1, reg);
	}

	dev->hbuf_is_ready = false;
	/* Set Input-Doorbell */
	mei_txe_input_doorbell_set(hw);

@@ -983,20 +982,16 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id)
		dev->hbuf_is_ready = true;

	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);
		if (rets)
			dev_err(&dev->pdev->dev,
				"mei_irq_write_handler ret = %d.\n", rets);
		if (rets && rets != -EMSGSIZE)
			dev_err(&dev->pdev->dev, "mei_irq_write_handler ret = %d.\n",
				rets);
		dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
	}



	mei_irq_compl_handler(dev, &complete_list);

end:
+3 −3
Original line number Diff line number Diff line
@@ -446,10 +446,10 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
	s32 slots;
	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;
	}

	slots = mei_hbuf_empty_slots(dev);
	if (slots <= 0)
		return -EMSGSIZE;
Loading