From db086fa926e57e1bd70e8c41235d230b3caa5e99 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 12 May 2013 15:34:45 +0300 Subject: mei: move mei_cl_complete to client.c 1. rename mei_cl_complete_handler to mei_cl_complete 2. move the function client.c where it belongs Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers/misc/mei/client.c') diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index e310ca6ed1a3..c2534ca5c6f1 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -785,6 +785,32 @@ err: } +/** + * mei_cl_complete - processes completed operation for a client + * + * @cl: private data of the file object. + * @cb: callback block. + */ +void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb) +{ + if (cb->fop_type == MEI_FOP_WRITE) { + mei_io_cb_free(cb); + cb = NULL; + cl->writing_state = MEI_WRITE_COMPLETE; + if (waitqueue_active(&cl->tx_wait)) + wake_up_interruptible(&cl->tx_wait); + + } else if (cb->fop_type == MEI_FOP_READ && + MEI_READING == cl->reading_state) { + cl->reading_state = MEI_READ_COMPLETE; + if (waitqueue_active(&cl->rx_wait)) + wake_up_interruptible(&cl->rx_wait); + else + mei_cl_bus_rx_event(cl); + + } +} + /** * mei_cl_all_disconnect - disconnect forcefully all connected clients -- cgit v1.2.3 From 21767546e955c3c1705387ca4548db812382fe08 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 23 Jun 2013 09:36:59 +0300 Subject: mei: move mei_cl_irq_write_complete to client.c mei_cl_irq_write_complete operates on a client so move it to client.c Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'drivers/misc/mei/client.c') diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index c2534ca5c6f1..788f6478b4ab 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -681,6 +681,66 @@ err: return rets; } +/** + * mei_cl_irq_write_complete - write a message to device + * from the interrupt thread context + * + * @cl: client + * @cb: callback block. + * @slots: free slots. + * @cmpl_list: complete list. + * + * returns 0, OK; otherwise error. + */ +int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb, + s32 *slots, struct mei_cl_cb *cmpl_list) +{ + struct mei_device *dev = cl->dev; + struct mei_msg_hdr mei_hdr; + size_t len = cb->request_buffer.size - cb->buf_idx; + u32 msg_slots = mei_data2slots(len); + + mei_hdr.host_addr = cl->host_client_id; + mei_hdr.me_addr = cl->me_client_id; + mei_hdr.reserved = 0; + + if (*slots >= msg_slots) { + mei_hdr.length = len; + mei_hdr.msg_complete = 1; + /* Split the message only if we can write the whole host buffer */ + } else if (*slots == dev->hbuf_depth) { + msg_slots = *slots; + len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); + mei_hdr.length = len; + mei_hdr.msg_complete = 0; + } else { + /* wait for next time the host buffer is empty */ + return 0; + } + + dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n", + cb->request_buffer.size, cb->buf_idx); + dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr)); + + *slots -= msg_slots; + if (mei_write_message(dev, &mei_hdr, + cb->request_buffer.data + cb->buf_idx)) { + cl->status = -ENODEV; + list_move_tail(&cb->list, &cmpl_list->list); + return -ENODEV; + } + + cl->status = 0; + cb->buf_idx += mei_hdr.length; + if (mei_hdr.msg_complete) { + if (mei_cl_flow_ctrl_reduce(cl)) + return -ENODEV; + list_move_tail(&cb->list, &dev->write_waiting_list.list); + } + + return 0; +} + /** * mei_cl_write - submit a write cb to mei device assumes device_lock is locked -- cgit v1.2.3 From 4dfaa9f7020b1ff4bf87899f4797d2efd76e80fd Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 23 Jun 2013 09:37:00 +0300 Subject: mei: do not override a client writing state when buffering when we buffer write request we should not switch to MEI_WRITING since this will override MEI_WRITE_COMPLETE state of preceding write Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/misc/mei/client.c') diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 788f6478b4ab..11a465a25896 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -731,7 +731,9 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb, } cl->status = 0; + cl->writing_state = MEI_WRITING; cb->buf_idx += mei_hdr.length; + if (mei_hdr.msg_complete) { if (mei_cl_flow_ctrl_reduce(cl)) return -ENODEV; @@ -783,7 +785,6 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) cb->buf_idx = 0; /* unseting complete will enqueue the cb for write */ mei_hdr.msg_complete = 0; - cl->writing_state = MEI_WRITING; rets = buf->size; goto out; } -- cgit v1.2.3 From 206ecfc21121aa272f3f9fa23e1ed252a12e8a5c Mon Sep 17 00:00:00 2001 From: Frode Isaksen Date: Sun, 23 Jun 2013 09:37:01 +0300 Subject: mei: mei_cl_connect: don't multiply the timeout twice MEI_CL_CONNECT_TIMEOUT is the timeout in seconds to wait for a response in mei_cl_connect. The value was converted to jiffies using mei_secs_to_jiffies helper function and assigned to a local variable which is by mistake again multiplied by HZ Signed-off-by: Frode Isaksen Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/misc/mei/client.c') diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 11a465a25896..21d3f5aa8353 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -485,7 +485,6 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) { struct mei_device *dev; struct mei_cl_cb *cb; - long timeout = mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT); int rets; if (WARN_ON(!cl || !cl->dev)) @@ -518,7 +517,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) rets = wait_event_timeout(dev->wait_recvd_msg, (cl->state == MEI_FILE_CONNECTED || cl->state == MEI_FILE_DISCONNECTED), - timeout * HZ); + mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); mutex_lock(&dev->device_lock); if (cl->state != MEI_FILE_CONNECTED) { -- cgit v1.2.3