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

Commit 44d88d91 authored by Samuel Ortiz's avatar Samuel Ortiz Committed by Greg Kroah-Hartman
Browse files

mei: bus: Synchronous API for the data transmission



Define a truly synchronous API for the bus Tx path by putting all pending
request to the write list and wait for the interrupt tx handler to wake
us up.
The ___mei_cl_send() out path is also slightly reworked to make it look more
like main.c:mei_write().

Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent cf3baefb
Loading
Loading
Loading
Loading
+29 −10
Original line number Diff line number Diff line
@@ -222,7 +222,8 @@ void mei_cl_driver_unregister(struct mei_cl_driver *driver)
}
EXPORT_SYMBOL_GPL(mei_cl_driver_unregister);

int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length)
static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
			bool blocking)
{
	struct mei_device *dev;
	struct mei_msg_hdr mei_hdr;
@@ -273,11 +274,8 @@ int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length)
		cb->buf_idx = 0;
		mei_hdr.msg_complete = 0;
		cl->writing_state = MEI_WRITING;
		list_add_tail(&cb->list, &dev->write_list.list);

		mutex_unlock(&dev->device_lock);

		return length;
		goto out;
	}

	dev->hbuf_is_ready = false;
@@ -303,19 +301,30 @@ int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length)
	cl->writing_state = MEI_WRITING;
	cb->buf_idx = mei_hdr.length;

	if (!mei_hdr.msg_complete) {
		list_add_tail(&cb->list, &dev->write_list.list);
	} else {
out:
	if (mei_hdr.msg_complete) {
		if (mei_cl_flow_ctrl_reduce(cl)) {
			err = -EIO;
			err = -ENODEV;
			goto out_err;
		}

		list_add_tail(&cb->list, &dev->write_waiting_list.list);
	} else {
		list_add_tail(&cb->list, &dev->write_list.list);
	}

	mutex_unlock(&dev->device_lock);

	if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) {
		if (wait_event_interruptible(cl->tx_wait,
			cl->writing_state == MEI_WRITE_COMPLETE)) {
				if (signal_pending(current))
					err = -EINTR;
			err = -ERESTARTSYS;
			mutex_lock(&dev->device_lock);
			goto out_err;
		}
	}

	return mei_hdr.length;

out_err:
@@ -382,6 +391,16 @@ out:
	return r_length;
}

inline int __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length)
{
	return ___mei_cl_send(cl, buf, length, 0);
}

inline int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length)
{
	return ___mei_cl_send(cl, buf, length, 1);
}

int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length)
{
	struct mei_cl *cl = device->cl;
+1 −0
Original line number Diff line number Diff line
@@ -273,6 +273,7 @@ struct mei_cl_device *mei_cl_add_device(struct mei_device *dev,
				  uuid_le uuid, char *name);
void mei_cl_remove_device(struct mei_cl_device *device);

int __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length);
int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length);
int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length);