All of lore.kernel.org
 help / color / mirror / Atom feed
* [char-misc-next 1/7] mei: compact code for mei bus message creation
@ 2012-11-18 13:13 Tomas Winkler
  2012-11-18 13:13 ` [char-misc-next 2/7] mei: use structured buffer for extra write buffer Tomas Winkler
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Tomas Winkler @ 2012-11-18 13:13 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler

1. replace boilerplate code for filling up the bus message header
 with a common wrapper function
2. shorten variable names and use temporal variables
 to save some screen space

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/init.c      |   78 +++++++++++++++-------------------
 drivers/misc/mei/interface.c |   75 +++++++++++++--------------------
 drivers/misc/mei/interrupt.c |   96 ++++++++++++++++-------------------------
 drivers/misc/mei/mei_dev.h   |   11 +++++
 4 files changed, 112 insertions(+), 148 deletions(-)

diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 4fcb0bb..02784af 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -43,6 +43,7 @@ const char *mei_dev_state_str(int state)
 }
 
 
+
 /**
  * mei_io_list_flush - removes list entry belonging to cl.
  *
@@ -331,25 +332,20 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
 void mei_host_start_message(struct mei_device *dev)
 {
 	struct mei_msg_hdr *mei_hdr;
-	struct hbm_host_version_request *host_start_req;
+	struct hbm_host_version_request *start_req;
+	const size_t len = sizeof(struct hbm_host_version_request);
+
+	mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
 
 	/* host start message */
-	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
-	mei_hdr->host_addr = 0;
-	mei_hdr->me_addr = 0;
-	mei_hdr->length = sizeof(struct hbm_host_version_request);
-	mei_hdr->msg_complete = 1;
-	mei_hdr->reserved = 0;
-
-	host_start_req =
-	    (struct hbm_host_version_request *) &dev->wr_msg_buf[1];
-	memset(host_start_req, 0, sizeof(struct hbm_host_version_request));
-	host_start_req->hbm_cmd = HOST_START_REQ_CMD;
-	host_start_req->host_version.major_version = HBM_MAJOR_VERSION;
-	host_start_req->host_version.minor_version = HBM_MINOR_VERSION;
+	start_req = (struct hbm_host_version_request *)&dev->wr_msg_buf[1];
+	memset(start_req, 0, len);
+	start_req->hbm_cmd = HOST_START_REQ_CMD;
+	start_req->host_version.major_version = HBM_MAJOR_VERSION;
+	start_req->host_version.minor_version = HBM_MINOR_VERSION;
+
 	dev->recvd_msg = false;
-	if (mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req,
-				       mei_hdr->length)) {
+	if (mei_write_message(dev, mei_hdr, (unsigned char *)start_req, len)) {
 		dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n");
 		dev->dev_state = MEI_DEV_RESETING;
 		mei_reset(dev, 1);
@@ -369,20 +365,16 @@ void mei_host_start_message(struct mei_device *dev)
 void mei_host_enum_clients_message(struct mei_device *dev)
 {
 	struct mei_msg_hdr *mei_hdr;
-	struct hbm_host_enum_request *host_enum_req;
-	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+	struct hbm_host_enum_request *enum_req;
+	const size_t len = sizeof(struct hbm_host_enum_request);
 	/* enumerate clients */
-	mei_hdr->host_addr = 0;
-	mei_hdr->me_addr = 0;
-	mei_hdr->length = sizeof(struct hbm_host_enum_request);
-	mei_hdr->msg_complete = 1;
-	mei_hdr->reserved = 0;
-
-	host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1];
-	memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request));
-	host_enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
-	if (mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req,
-				mei_hdr->length)) {
+	mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
+
+	enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1];
+	memset(enum_req, 0, sizeof(struct hbm_host_enum_request));
+	enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
+
+	if (mei_write_message(dev, mei_hdr, (unsigned char *)enum_req, len)) {
 		dev->dev_state = MEI_DEV_RESETING;
 		dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
 		mei_reset(dev, 1);
@@ -443,33 +435,31 @@ void mei_allocate_me_clients_storage(struct mei_device *dev)
  */
 int mei_host_client_properties(struct mei_device *dev)
 {
-	struct mei_msg_hdr *mei_header;
-	struct hbm_props_request *host_cli_req;
+
+	struct mei_msg_hdr *mei_hdr;
+	struct hbm_props_request *prop_req;
+	const size_t len = sizeof(struct hbm_props_request);
+
 	int b;
 	u8 client_num = dev->me_client_presentation_num;
 
+	prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1];
+
 	b = dev->me_client_index;
 	b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b);
 	if (b < MEI_CLIENTS_MAX) {
 		dev->me_clients[client_num].client_id = b;
 		dev->me_clients[client_num].mei_flow_ctrl_creds = 0;
-		mei_header = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
-		mei_header->host_addr = 0;
-		mei_header->me_addr = 0;
-		mei_header->length = sizeof(struct hbm_props_request);
-		mei_header->msg_complete = 1;
-		mei_header->reserved = 0;
+		mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
 
-		host_cli_req = (struct hbm_props_request *)&dev->wr_msg_buf[1];
 
-		memset(host_cli_req, 0, sizeof(struct hbm_props_request));
+		memset(prop_req, 0, sizeof(struct hbm_props_request));
 
-		host_cli_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
-		host_cli_req->address = b;
+		prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
+		prop_req->address = b;
 
-		if (mei_write_message(dev, mei_header,
-				(unsigned char *)host_cli_req,
-				mei_header->length)) {
+		if (mei_write_message(dev, mei_hdr,
+				(unsigned char *)prop_req, len)) {
 			dev->dev_state = MEI_DEV_RESETING;
 			dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
 			mei_reset(dev, 1);
diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c
index 6b50cf0..8de8547 100644
--- a/drivers/misc/mei/interface.c
+++ b/drivers/misc/mei/interface.c
@@ -292,28 +292,23 @@ int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl)
 int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl)
 {
 	struct mei_msg_hdr *mei_hdr;
-	struct hbm_flow_control *mei_flow_control;
-
-	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
-	mei_hdr->host_addr = 0;
-	mei_hdr->me_addr = 0;
-	mei_hdr->length = sizeof(struct hbm_flow_control);
-	mei_hdr->msg_complete = 1;
-	mei_hdr->reserved = 0;
-
-	mei_flow_control = (struct hbm_flow_control *) &dev->wr_msg_buf[1];
-	memset(mei_flow_control, 0, sizeof(*mei_flow_control));
-	mei_flow_control->host_addr = cl->host_client_id;
-	mei_flow_control->me_addr = cl->me_client_id;
-	mei_flow_control->hbm_cmd = MEI_FLOW_CONTROL_CMD;
-	memset(mei_flow_control->reserved, 0,
-			sizeof(mei_flow_control->reserved));
+	struct hbm_flow_control *flow_ctrl;
+	const size_t len = sizeof(struct hbm_flow_control);
+
+	mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
+
+	flow_ctrl = (struct hbm_flow_control *)&dev->wr_msg_buf[1];
+	memset(flow_ctrl, 0, len);
+	flow_ctrl->hbm_cmd = MEI_FLOW_CONTROL_CMD;
+	flow_ctrl->host_addr = cl->host_client_id;
+	flow_ctrl->me_addr = cl->me_client_id;
+	/* FIXME: reserved !? */
+	memset(flow_ctrl->reserved, 0, sizeof(flow_ctrl->reserved));
 	dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n",
 		cl->host_client_id, cl->me_client_id);
 
 	return mei_write_message(dev, mei_hdr,
-				(unsigned char *) mei_flow_control,
-				sizeof(struct hbm_flow_control));
+			(unsigned char *) flow_ctrl, len);
 }
 
 /**
@@ -353,23 +348,18 @@ int mei_disconnect(struct mei_device *dev, struct mei_cl *cl)
 {
 	struct mei_msg_hdr *mei_hdr;
 	struct hbm_client_connect_request *req;
+	const size_t len = sizeof(struct hbm_client_connect_request);
 
-	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
-	mei_hdr->host_addr = 0;
-	mei_hdr->me_addr = 0;
-	mei_hdr->length = sizeof(struct hbm_client_connect_request);
-	mei_hdr->msg_complete = 1;
-	mei_hdr->reserved = 0;
+	mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
 
 	req = (struct hbm_client_connect_request *)&dev->wr_msg_buf[1];
-	memset(req, 0, sizeof(*req));
+	memset(req, 0, len);
+	req->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD;
 	req->host_addr = cl->host_client_id;
 	req->me_addr = cl->me_client_id;
-	req->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD;
 	req->reserved = 0;
 
-	return mei_write_message(dev, mei_hdr, (unsigned char *)req,
-				sizeof(struct hbm_client_connect_request));
+	return mei_write_message(dev, mei_hdr, (unsigned char *)req, len);
 }
 
 /**
@@ -383,23 +373,16 @@ int mei_disconnect(struct mei_device *dev, struct mei_cl *cl)
 int mei_connect(struct mei_device *dev, struct mei_cl *cl)
 {
 	struct mei_msg_hdr *mei_hdr;
-	struct hbm_client_connect_request *mei_cli_connect;
-
-	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
-	mei_hdr->host_addr = 0;
-	mei_hdr->me_addr = 0;
-	mei_hdr->length = sizeof(struct hbm_client_connect_request);
-	mei_hdr->msg_complete = 1;
-	mei_hdr->reserved = 0;
-
-	mei_cli_connect =
-	    (struct hbm_client_connect_request *) &dev->wr_msg_buf[1];
-	mei_cli_connect->host_addr = cl->host_client_id;
-	mei_cli_connect->me_addr = cl->me_client_id;
-	mei_cli_connect->hbm_cmd = CLIENT_CONNECT_REQ_CMD;
-	mei_cli_connect->reserved = 0;
+	struct hbm_client_connect_request *req;
+	const size_t len = sizeof(struct hbm_client_connect_request);
 
-	return mei_write_message(dev, mei_hdr,
-				(unsigned char *) mei_cli_connect,
-				sizeof(struct hbm_client_connect_request));
+	mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
+
+	req = (struct hbm_client_connect_request *) &dev->wr_msg_buf[1];
+	req->hbm_cmd = CLIENT_CONNECT_REQ_CMD;
+	req->host_addr = cl->host_client_id;
+	req->me_addr = cl->me_client_id;
+	req->reserved = 0;
+
+	return mei_write_message(dev, mei_hdr, (unsigned char *) req, len);
 }
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index f882101..14becc0 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -429,39 +429,30 @@ static int same_disconn_addr(struct mei_cl *cl,
 static void mei_client_disconnect_request(struct mei_device *dev,
 		struct hbm_client_connect_request *disconnect_req)
 {
-	struct mei_msg_hdr *mei_hdr;
 	struct hbm_client_connect_response *disconnect_res;
-	struct mei_cl *cl_pos = NULL;
-	struct mei_cl *cl_next = NULL;
+	struct mei_cl *pos, *next;
+	const size_t len = sizeof(struct hbm_client_connect_response);
 
-	list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
-		if (same_disconn_addr(cl_pos, disconnect_req)) {
+	list_for_each_entry_safe(pos, next, &dev->file_list, link) {
+		if (same_disconn_addr(pos, disconnect_req)) {
 			dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n",
 					disconnect_req->host_addr,
 					disconnect_req->me_addr);
-			cl_pos->state = MEI_FILE_DISCONNECTED;
-			cl_pos->timer_count = 0;
-			if (cl_pos == &dev->wd_cl)
+			pos->state = MEI_FILE_DISCONNECTED;
+			pos->timer_count = 0;
+			if (pos == &dev->wd_cl)
 				dev->wd_pending = false;
-			else if (cl_pos == &dev->iamthif_cl)
+			else if (pos == &dev->iamthif_cl)
 				dev->iamthif_timer = 0;
 
 			/* prepare disconnect response */
-			mei_hdr =
-				(struct mei_msg_hdr *) &dev->ext_msg_buf[0];
-			mei_hdr->host_addr = 0;
-			mei_hdr->me_addr = 0;
-			mei_hdr->length =
-				sizeof(struct hbm_client_connect_response);
-			mei_hdr->msg_complete = 1;
-			mei_hdr->reserved = 0;
-
+			(void)mei_hbm_hdr(&dev->ext_msg_buf[0], len);
 			disconnect_res =
 				(struct hbm_client_connect_response *)
 				&dev->ext_msg_buf[1];
-			disconnect_res->host_addr = cl_pos->host_client_id;
-			disconnect_res->me_addr = cl_pos->me_client_id;
 			disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD;
+			disconnect_res->host_addr = pos->host_client_id;
+			disconnect_res->me_addr = pos->me_client_id;
 			disconnect_res->status = 0;
 			dev->extra_write_index = 2;
 			break;
@@ -469,7 +460,6 @@ static void mei_client_disconnect_request(struct mei_device *dev,
 	}
 }
 
-
 /**
  * mei_irq_thread_read_bus_message - bottom half read routine after ISR to
  * handle the read bus message cmd processing.
@@ -488,7 +478,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
 	struct hbm_flow_control *flow_control;
 	struct hbm_props_response *props_res;
 	struct hbm_host_enum_response *enum_res;
-	struct hbm_host_stop_request *host_stop_req;
+	struct hbm_host_stop_request *stop_req;
 	int res;
 
 
@@ -514,26 +504,20 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
 				return;
 			}
 		} else {
+			u32 *buf = dev->wr_msg_buf;
+			const size_t len = sizeof(struct hbm_host_stop_request);
+
 			dev->version = version_res->me_max_version;
+
 			/* send stop message */
-			mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
-			mei_hdr->host_addr = 0;
-			mei_hdr->me_addr = 0;
-			mei_hdr->length = sizeof(struct hbm_host_stop_request);
-			mei_hdr->msg_complete = 1;
-			mei_hdr->reserved = 0;
-
-			host_stop_req = (struct hbm_host_stop_request *)
-							&dev->wr_msg_buf[1];
-
-			memset(host_stop_req,
-					0,
-					sizeof(struct hbm_host_stop_request));
-			host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
-			host_stop_req->reason = DRIVER_STOP_REQUEST;
+			mei_hdr = mei_hbm_hdr(&buf[0], len);
+			stop_req = (struct hbm_host_stop_request *)&buf[1];
+			memset(stop_req, 0, len);
+			stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
+			stop_req->reason = DRIVER_STOP_REQUEST;
+
 			mei_write_message(dev, mei_hdr,
-					   (unsigned char *) (host_stop_req),
-					   mei_hdr->length);
+					(unsigned char *)stop_req, len);
 			dev_dbg(&dev->pdev->dev, "version mismatch.\n");
 			return;
 		}
@@ -543,16 +527,14 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
 		break;
 
 	case CLIENT_CONNECT_RES_CMD:
-		connect_res =
-			(struct hbm_client_connect_response *) mei_msg;
+		connect_res = (struct hbm_client_connect_response *) mei_msg;
 		mei_client_connect_response(dev, connect_res);
 		dev_dbg(&dev->pdev->dev, "client connect response message received.\n");
 		wake_up(&dev->wait_recvd_msg);
 		break;
 
 	case CLIENT_DISCONNECT_RES_CMD:
-		disconnect_res =
-			(struct hbm_client_connect_response *) mei_msg;
+		disconnect_res = (struct hbm_client_connect_response *) mei_msg;
 		mei_client_disconnect_response(dev, disconnect_res);
 		dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n");
 		wake_up(&dev->wait_recvd_msg);
@@ -658,23 +640,21 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
 		break;
 
 	case ME_STOP_REQ_CMD:
-		/* prepare stop request */
-		mei_hdr = (struct mei_msg_hdr *) &dev->ext_msg_buf[0];
-		mei_hdr->host_addr = 0;
-		mei_hdr->me_addr = 0;
-		mei_hdr->length = sizeof(struct hbm_host_stop_request);
-		mei_hdr->msg_complete = 1;
-		mei_hdr->reserved = 0;
-		host_stop_req =
-			(struct hbm_host_stop_request *) &dev->ext_msg_buf[1];
-		memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request));
-		host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
-		host_stop_req->reason = DRIVER_STOP_REQUEST;
-		host_stop_req->reserved[0] = 0;
-		host_stop_req->reserved[1] = 0;
+	{
+		/* prepare stop request: sent in next interrupt event */
+
+		u32 *buf = dev->ext_msg_buf;
+		const size_t len = sizeof(struct hbm_host_stop_request);
+
+		mei_hdr = mei_hbm_hdr(&buf[0], len);
+		stop_req = (struct hbm_host_stop_request *)&buf[1];
+		memset(stop_req, 0, len);
+		stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
+		stop_req->reason = DRIVER_STOP_REQUEST;
+
 		dev->extra_write_index = 2;
 		break;
-
+	}
 	default:
 		BUG();
 		break;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index aaee666..e511b84 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -491,4 +491,15 @@ void mei_csr_clear_his(struct mei_device *dev);
 void mei_enable_interrupts(struct mei_device *dev);
 void mei_disable_interrupts(struct mei_device *dev);
 
+static inline struct mei_msg_hdr *mei_hbm_hdr(u32 *buf, size_t length)
+{
+	struct mei_msg_hdr *hdr = (struct mei_msg_hdr *)buf;
+	hdr->host_addr = 0;
+	hdr->me_addr = 0;
+	hdr->length = length;
+	hdr->msg_complete = 1;
+	hdr->reserved = 0;
+	return hdr;
+}
+
 #endif
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [char-misc-next 2/7] mei: use structured buffer for extra write buffer
  2012-11-18 13:13 [char-misc-next 1/7] mei: compact code for mei bus message creation Tomas Winkler
@ 2012-11-18 13:13 ` Tomas Winkler
  2012-11-18 13:13 ` [char-misc-next 3/7] mei: streamline write complete flow function Tomas Winkler
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Tomas Winkler @ 2012-11-18 13:13 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler

The structure of the message is static so we don't have
to use and cast the buffer. We can also drop extra_write_index
variable as this information can be extracted directly
from the message header

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/init.c      |    2 +-
 drivers/misc/mei/interrupt.c |   36 ++++++++++++++----------------------
 drivers/misc/mei/mei_dev.h   |   11 +++++++----
 3 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 02784af..49600d6 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -288,7 +288,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
 		mei_me_cl_unlink(dev, &dev->iamthif_cl);
 
 		mei_amthif_reset_params(dev);
-		dev->extra_write_index = 0;
+		memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
 	}
 
 	dev->me_clients_num = 0;
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 14becc0..9224646 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -446,15 +446,14 @@ static void mei_client_disconnect_request(struct mei_device *dev,
 				dev->iamthif_timer = 0;
 
 			/* prepare disconnect response */
-			(void)mei_hbm_hdr(&dev->ext_msg_buf[0], len);
+			(void)mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len);
 			disconnect_res =
 				(struct hbm_client_connect_response *)
-				&dev->ext_msg_buf[1];
+				&dev->wr_ext_msg.data;
 			disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD;
 			disconnect_res->host_addr = pos->host_client_id;
 			disconnect_res->me_addr = pos->me_client_id;
 			disconnect_res->status = 0;
-			dev->extra_write_index = 2;
 			break;
 		}
 	}
@@ -643,16 +642,13 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
 	{
 		/* prepare stop request: sent in next interrupt event */
 
-		u32 *buf = dev->ext_msg_buf;
 		const size_t len = sizeof(struct hbm_host_stop_request);
 
-		mei_hdr = mei_hbm_hdr(&buf[0], len);
-		stop_req = (struct hbm_host_stop_request *)&buf[1];
+		mei_hdr = mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len);
+		stop_req = (struct hbm_host_stop_request *)&dev->wr_ext_msg.data;
 		memset(stop_req, 0, len);
 		stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
 		stop_req->reason = DRIVER_STOP_REQUEST;
-
-		dev->extra_write_index = 2;
 		break;
 	}
 	default:
@@ -988,15 +984,11 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list,
 		wake_up_interruptible(&dev->wait_stop_wd);
 	}
 
-	if (dev->extra_write_index) {
-		dev_dbg(&dev->pdev->dev, "extra_write_index =%d.\n",
-				dev->extra_write_index);
-		mei_write_message(dev,
-				(struct mei_msg_hdr *) &dev->ext_msg_buf[0],
-				(unsigned char *) &dev->ext_msg_buf[1],
-				(dev->extra_write_index - 1) * sizeof(u32));
-		*slots -= dev->extra_write_index;
-		dev->extra_write_index = 0;
+	if (dev->wr_ext_msg.hdr.length) {
+		mei_write_message(dev, &dev->wr_ext_msg.hdr,
+			dev->wr_ext_msg.data, dev->wr_ext_msg.hdr.length);
+		*slots -= mei_data2slots(dev->wr_ext_msg.hdr.length);
+		dev->wr_ext_msg.hdr.length = 0;
 	}
 	if (dev->dev_state == MEI_DEV_ENABLED) {
 		if (dev->wd_pending &&
@@ -1263,11 +1255,11 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
 	}
 	/* check slots available for reading */
 	slots = mei_count_full_read_slots(dev);
-	dev_dbg(&dev->pdev->dev, "slots =%08x  extra_write_index =%08x.\n",
-		slots, dev->extra_write_index);
-	while (slots > 0 && !dev->extra_write_index) {
-		dev_dbg(&dev->pdev->dev, "slots =%08x  extra_write_index =%08x.\n",
-				slots, dev->extra_write_index);
+	while (slots > 0) {
+		/* we have urgent data to send so break the read */
+		if (dev->wr_ext_msg.hdr.length)
+			break;
+		dev_dbg(&dev->pdev->dev, "slots =%08x\n", slots);
 		dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n");
 		rets = mei_irq_thread_read_handler(&complete_list, dev, &slots);
 		if (rets)
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index e511b84..2a38e95 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -192,8 +192,9 @@ struct mei_cl {
 };
 
 /**
- * struct mei_deive -  MEI private device struct
+ * struct mei_device -  MEI private device struct
  * @hbuf_depth - depth of host(write) buffer
+ * @wr_ext_msg - buffer for hbm control responses (set in read cycle)
  */
 struct mei_device {
 	struct pci_dev *pdev;	/* pointer to pci device struct */
@@ -244,11 +245,13 @@ struct mei_device {
 	u16 init_clients_timer;
 	bool need_reset;
 
-	u32 extra_write_index;
 	unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE];	/* control messages */
-	u32 wr_msg_buf[128];	/* used for control messages */
-	u32 ext_msg_buf[8];	/* for control responses */
 	u32 rd_msg_hdr;
+	u32 wr_msg_buf[128];	/* used for control messages */
+	struct {
+		struct mei_msg_hdr hdr;
+		unsigned char data[4];	/* All HBM messages are 4 bytes */
+	} wr_ext_msg;		/* for control responses */
 
 	struct hbm_version version;
 
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [char-misc-next 3/7] mei: streamline write complete flow function
  2012-11-18 13:13 [char-misc-next 1/7] mei: compact code for mei bus message creation Tomas Winkler
  2012-11-18 13:13 ` [char-misc-next 2/7] mei: use structured buffer for extra write buffer Tomas Winkler
@ 2012-11-18 13:13 ` Tomas Winkler
  2012-11-18 13:13 ` [char-misc-next 4/7] mei: streamline amthif write complete function Tomas Winkler
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Tomas Winkler @ 2012-11-18 13:13 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler

Rename the function  _mei_irq_thread_cmpl to
mei_irq_thread_write_complete to make clear it deals
with writing. Remove cl from the parameter list as it
can be extracted from cb block.
Extract the common flow from if statements and document
the logic properly

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/interrupt.c |  113 ++++++++++++++++--------------------------
 1 files changed, 43 insertions(+), 70 deletions(-)

diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 9224646..85e2722 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -734,90 +734,63 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
 }
 
 /**
- * _mei_irq_thread_cmpl - processes completed and no-iamthif operation.
+ * mei_irq_thread_write_complete - write messages to device.
  *
  * @dev: the device structure.
  * @slots: free slots.
- * @cb_pos: callback block.
- * @cl: private data of the file object.
+ * @cb: callback block.
  * @cmpl_list: complete list.
  *
  * returns 0, OK; otherwise, error.
  */
-static int _mei_irq_thread_cmpl(struct mei_device *dev,	s32 *slots,
-			struct mei_cl_cb *cb_pos,
-			struct mei_cl *cl,
-			struct mei_cl_cb *cmpl_list)
+static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots,
+			struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
 {
 	struct mei_msg_hdr *mei_hdr;
+	struct mei_cl *cl = cb->cl;
+	size_t len = cb->request_buffer.size - cb->buf_idx;
+	size_t msg_slots = mei_data2slots(len);
+
+	mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
+	mei_hdr->host_addr = cl->host_client_id;
+	mei_hdr->me_addr = cl->me_client_id;
+	mei_hdr->reserved = 0;
 
-	if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
-			(cb_pos->request_buffer.size - cb_pos->buf_idx))) {
-		mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
-		mei_hdr->host_addr = cl->host_client_id;
-		mei_hdr->me_addr = cl->me_client_id;
-		mei_hdr->length = cb_pos->request_buffer.size - cb_pos->buf_idx;
+	if (*slots >= msg_slots) {
+		mei_hdr->length = len;
 		mei_hdr->msg_complete = 1;
-		mei_hdr->reserved = 0;
-		dev_dbg(&dev->pdev->dev, "cb_pos->request_buffer.size =%d"
-			"mei_hdr->msg_complete = %d\n",
-				cb_pos->request_buffer.size,
-				mei_hdr->msg_complete);
-		dev_dbg(&dev->pdev->dev, "cb_pos->buf_idx  =%lu\n",
-				cb_pos->buf_idx);
-		dev_dbg(&dev->pdev->dev, "mei_hdr->length  =%d\n",
-				mei_hdr->length);
-		*slots -= mei_data2slots(mei_hdr->length);
-		if (mei_write_message(dev, mei_hdr,
-				(unsigned char *)
-				(cb_pos->request_buffer.data +
-				cb_pos->buf_idx),
-				mei_hdr->length)) {
-			cl->status = -ENODEV;
-			list_move_tail(&cb_pos->list, &cmpl_list->list);
-			return -ENODEV;
-		} else {
-			if (mei_flow_ctrl_reduce(dev, cl))
-				return -ENODEV;
-			cl->status = 0;
-			cb_pos->buf_idx += mei_hdr->length;
-			list_move_tail(&cb_pos->list, &dev->write_waiting_list.list);
-		}
+	/* Split the message only if we can write the whole host buffer */
 	} else if (*slots == dev->hbuf_depth) {
-		/* buffer is still empty */
-		mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
-		mei_hdr->host_addr = cl->host_client_id;
-		mei_hdr->me_addr = cl->me_client_id;
-		mei_hdr->length =
-			(*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
+		msg_slots = *slots;
+		len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
+		mei_hdr->length = len;
 		mei_hdr->msg_complete = 0;
-		mei_hdr->reserved = 0;
-		*slots -= mei_data2slots(mei_hdr->length);
-		if (mei_write_message(dev, mei_hdr,
-					(unsigned char *)
-					(cb_pos->request_buffer.data +
-					cb_pos->buf_idx),
-					mei_hdr->length)) {
-			cl->status = -ENODEV;
-			list_move_tail(&cb_pos->list, &cmpl_list->list);
-			return -ENODEV;
-		} else {
-			cb_pos->buf_idx += mei_hdr->length;
-			dev_dbg(&dev->pdev->dev,
-					"cb_pos->request_buffer.size =%d"
-					" mei_hdr->msg_complete = %d\n",
-					cb_pos->request_buffer.size,
-					mei_hdr->msg_complete);
-			dev_dbg(&dev->pdev->dev, "cb_pos->buf_idx  =%lu\n",
-					cb_pos->buf_idx);
-			dev_dbg(&dev->pdev->dev, "mei_hdr->length  =%d\n",
-					mei_hdr->length);
-		}
-		return -EMSGSIZE;
 	} else {
-		return -EBADMSG;
+		/* 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, "msg: len = %d complete = %d\n",
+			mei_hdr->length, mei_hdr->msg_complete);
+
+	*slots -=  msg_slots;
+	if (mei_write_message(dev, mei_hdr,
+		cb->request_buffer.data + cb->buf_idx, len)) {
+		cl->status = -ENODEV;
+		list_move_tail(&cb->list, &cmpl_list->list);
+		return -ENODEV;
+	}
+
+	if (mei_flow_ctrl_reduce(dev, cl))
+		return -ENODEV;
+
+	cl->status = 0;
+	cb->buf_idx += mei_hdr->length;
+	if (mei_hdr->msg_complete)
+		list_move_tail(&cb->list, &dev->write_waiting_list.list);
+
 	return 0;
 }
 
@@ -1059,8 +1032,8 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list,
 					cl->host_client_id);
 				continue;
 			}
-			ret = _mei_irq_thread_cmpl(dev, slots, pos,
-						cl, cmpl_list);
+			ret = mei_irq_thread_write_complete(dev, slots, pos,
+						cmpl_list);
 			if (ret)
 				return ret;
 
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [char-misc-next 4/7] mei: streamline amthif write complete function
  2012-11-18 13:13 [char-misc-next 1/7] mei: compact code for mei bus message creation Tomas Winkler
  2012-11-18 13:13 ` [char-misc-next 2/7] mei: use structured buffer for extra write buffer Tomas Winkler
  2012-11-18 13:13 ` [char-misc-next 3/7] mei: streamline write complete flow function Tomas Winkler
@ 2012-11-18 13:13 ` Tomas Winkler
  2012-11-18 13:13 ` [char-misc-next 5/7] mei: don't mix read and write slots Tomas Winkler
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Tomas Winkler @ 2012-11-18 13:13 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler

Rename the function mei_amthif_irq_process_completed
to mei_amthif_irq_write_complete
Remove cl from the parameter list as it
can be extracted from cb block.
Extract the common flow from if statements
and document the logic properly

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/amthif.c    |   98 +++++++++++++++++++-----------------------
 drivers/misc/mei/interrupt.c |    4 +-
 drivers/misc/mei/mei_dev.h   |    6 +--
 3 files changed, 48 insertions(+), 60 deletions(-)

diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 095d059..18794ae 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -431,74 +431,64 @@ unsigned int mei_amthif_poll(struct mei_device *dev,
  *
  * returns 0, OK; otherwise, error.
  */
-int mei_amthif_irq_process_completed(struct mei_device *dev, s32 *slots,
-			struct mei_cl_cb *cb_pos,
-			struct mei_cl *cl,
-			struct mei_cl_cb *cmpl_list)
+int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
+			struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
 {
 	struct mei_msg_hdr *mei_hdr;
+	struct mei_cl *cl = cb->cl;
+	size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
+	size_t msg_slots = mei_data2slots(len);
 
-	if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
-			dev->iamthif_msg_buf_size -
-			dev->iamthif_msg_buf_index)) {
-		mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
-		mei_hdr->host_addr = cl->host_client_id;
-		mei_hdr->me_addr = cl->me_client_id;
-		mei_hdr->length = dev->iamthif_msg_buf_size -
-			dev->iamthif_msg_buf_index;
+	mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
+	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;
-		mei_hdr->reserved = 0;
+	/* 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;
+	}
 
-		*slots -= mei_data2slots(mei_hdr->length);
+	dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n",
+			mei_hdr->length, mei_hdr->msg_complete);
 
-		if (mei_write_message(dev, mei_hdr,
-					(dev->iamthif_msg_buf +
-					dev->iamthif_msg_buf_index),
-					mei_hdr->length)) {
+	*slots -=  msg_slots;
+	if (mei_write_message(dev, mei_hdr,
+		dev->iamthif_msg_buf + dev->iamthif_msg_buf_index,
+		mei_hdr->length)) {
 			dev->iamthif_state = MEI_IAMTHIF_IDLE;
 			cl->status = -ENODEV;
-			list_del(&cb_pos->list);
+			list_del(&cb->list);
 			return -ENODEV;
-		} else {
-			if (mei_flow_ctrl_reduce(dev, cl))
-				return -ENODEV;
-			dev->iamthif_msg_buf_index += mei_hdr->length;
-			cb_pos->buf_idx = dev->iamthif_msg_buf_index;
-			cl->status = 0;
-			dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
-			dev->iamthif_flow_control_pending = true;
-			/* save iamthif cb sent to amthi client */
-			dev->iamthif_current_cb = cb_pos;
-			list_move_tail(&cb_pos->list,
-					&dev->write_waiting_list.list);
+	}
 
-		}
-	} else if (*slots == dev->hbuf_depth) {
-		/* buffer is still empty */
-		mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
-		mei_hdr->host_addr = cl->host_client_id;
-		mei_hdr->me_addr = cl->me_client_id;
-		mei_hdr->length =
-			(*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
-		mei_hdr->msg_complete = 0;
-		mei_hdr->reserved = 0;
+	if (mei_flow_ctrl_reduce(dev, cl))
+		return -ENODEV;
 
-		*slots -= mei_data2slots(mei_hdr->length);
+	dev->iamthif_msg_buf_index += mei_hdr->length;
+	cl->status = 0;
 
-		if (mei_write_message(dev, mei_hdr,
-					(dev->iamthif_msg_buf +
-					dev->iamthif_msg_buf_index),
-					mei_hdr->length)) {
-			cl->status = -ENODEV;
-			list_del(&cb_pos->list);
-		} else {
-			dev->iamthif_msg_buf_index += mei_hdr->length;
-		}
-		return -EMSGSIZE;
-	} else {
-		return -EBADMSG;
+	if (mei_hdr->msg_complete) {
+		dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
+		dev->iamthif_flow_control_pending = true;
+
+		/* save iamthif cb sent to amthi client */
+		cb->buf_idx = dev->iamthif_msg_buf_index;
+		dev->iamthif_current_cb = cb;
+
+		list_move_tail(&cb->list, &dev->write_waiting_list.list);
 	}
 
+
 	return 0;
 }
 
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 85e2722..d30db38 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -1046,8 +1046,8 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list,
 					cl->host_client_id);
 				continue;
 			}
-			ret = mei_amthif_irq_process_completed(dev, slots, pos,
-								cl, cmpl_list);
+			ret = mei_amthif_irq_write_complete(dev, slots,
+							pos, cmpl_list);
 			if (ret)
 				return ret;
 
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 2a38e95..17d00aa 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -407,10 +407,8 @@ void mei_amthif_run_next_cmd(struct mei_device *dev);
 int mei_amthif_read_message(struct mei_cl_cb *complete_list,
 		struct mei_device *dev, struct mei_msg_hdr *mei_hdr);
 
-int mei_amthif_irq_process_completed(struct mei_device *dev, s32 *slots,
-			struct mei_cl_cb *cb_pos,
-			struct mei_cl *cl,
-			struct mei_cl_cb *cmpl_list);
+int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
+			struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list);
 
 void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb);
 int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [char-misc-next 5/7] mei: don't mix read and write slots
  2012-11-18 13:13 [char-misc-next 1/7] mei: compact code for mei bus message creation Tomas Winkler
                   ` (2 preceding siblings ...)
  2012-11-18 13:13 ` [char-misc-next 4/7] mei: streamline amthif write complete function Tomas Winkler
@ 2012-11-18 13:13 ` Tomas Winkler
  2012-11-18 13:13 ` [char-misc-next 6/7] mei: simplify write complete loop in irq handler Tomas Winkler
  2012-11-18 13:13 ` [char-misc-next 7/7] mei: Simplify the ME client enumeration code Tomas Winkler
  5 siblings, 0 replies; 7+ messages in thread
From: Tomas Winkler @ 2012-11-18 13:13 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler

Do not pass read slots pointer into function
mei_irq_thread_write_handler, the write
slots management is handled internally in the write
handler

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/interrupt.c |   35 +++++++++++++++++++----------------
 1 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index d30db38..cccb63a 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -901,27 +901,27 @@ end:
  * mei_irq_thread_write_handler - bottom half write routine after
  * ISR to handle the write processing.
  *
- * @cmpl_list: An instance of our list structure
  * @dev: the device structure
- * @slots: slots to write.
+ * @cmpl_list: An instance of our list structure
  *
  * returns 0 on success, <0 on failure.
  */
-static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list,
-		struct mei_device *dev, s32 *slots)
+static int mei_irq_thread_write_handler(struct mei_device *dev,
+				struct mei_cl_cb *cmpl_list)
 {
 
 	struct mei_cl *cl;
 	struct mei_cl_cb *pos = NULL, *next = NULL;
 	struct mei_cl_cb *list;
+	s32 slots;
 	int ret;
 
 	if (!mei_hbuf_is_empty(dev)) {
 		dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n");
 		return 0;
 	}
-	*slots = mei_hbuf_empty_slots(dev);
-	if (*slots <= 0)
+	slots = mei_hbuf_empty_slots(dev);
+	if (slots <= 0)
 		return -EMSGSIZE;
 
 	/* complete all waiting for write CB */
@@ -945,7 +945,7 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list,
 		if (cl == &dev->iamthif_cl) {
 			dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
 			if (dev->iamthif_flow_control_pending) {
-				ret = mei_amthif_irq_read(dev, slots);
+				ret = mei_amthif_irq_read(dev, &slots);
 				if (ret)
 					return ret;
 			}
@@ -960,7 +960,7 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list,
 	if (dev->wr_ext_msg.hdr.length) {
 		mei_write_message(dev, &dev->wr_ext_msg.hdr,
 			dev->wr_ext_msg.data, dev->wr_ext_msg.hdr.length);
-		*slots -= mei_data2slots(dev->wr_ext_msg.hdr.length);
+		slots -= mei_data2slots(dev->wr_ext_msg.hdr.length);
 		dev->wr_ext_msg.hdr.length = 0;
 	}
 	if (dev->dev_state == MEI_DEV_ENABLED) {
@@ -974,9 +974,9 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list,
 			dev->wd_pending = false;
 
 			if (dev->wd_state == MEI_WD_RUNNING)
-				*slots -= mei_data2slots(MEI_WD_START_MSG_SIZE);
+				slots -= mei_data2slots(MEI_WD_START_MSG_SIZE);
 			else
-				*slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE);
+				slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE);
 		}
 	}
 
@@ -991,14 +991,16 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list,
 		switch (pos->fop_type) {
 		case MEI_FOP_CLOSE:
 			/* send disconnect message */
-			ret = _mei_irq_thread_close(dev, slots, pos, cl, cmpl_list);
+			ret = _mei_irq_thread_close(dev, &slots, pos,
+						cl, cmpl_list);
 			if (ret)
 				return ret;
 
 			break;
 		case MEI_FOP_READ:
 			/* send flow control message */
-			ret = _mei_irq_thread_read(dev, slots, pos, cl, cmpl_list);
+			ret = _mei_irq_thread_read(dev, &slots, pos,
+						cl, cmpl_list);
 			if (ret)
 				return ret;
 
@@ -1007,7 +1009,8 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list,
 			/* connect message */
 			if (mei_other_client_is_connecting(dev, cl))
 				continue;
-			ret = _mei_irq_thread_ioctl(dev, slots, pos, cl, cmpl_list);
+			ret = _mei_irq_thread_ioctl(dev, &slots, pos,
+						cl, cmpl_list);
 			if (ret)
 				return ret;
 
@@ -1032,7 +1035,7 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list,
 					cl->host_client_id);
 				continue;
 			}
-			ret = mei_irq_thread_write_complete(dev, slots, pos,
+			ret = mei_irq_thread_write_complete(dev, &slots, pos,
 						cmpl_list);
 			if (ret)
 				return ret;
@@ -1046,7 +1049,7 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list,
 					cl->host_client_id);
 				continue;
 			}
-			ret = mei_amthif_irq_write_complete(dev, slots,
+			ret = mei_amthif_irq_write_complete(dev, &slots,
 							pos, cmpl_list);
 			if (ret)
 				return ret;
@@ -1238,7 +1241,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
 		if (rets)
 			goto end;
 	}
-	rets = mei_irq_thread_write_handler(&complete_list, dev, &slots);
+	rets = mei_irq_thread_write_handler(dev, &complete_list);
 end:
 	dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
 	dev->host_hw_state = mei_hcsr_read(dev);
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [char-misc-next 6/7] mei: simplify write complete loop in irq handler
  2012-11-18 13:13 [char-misc-next 1/7] mei: compact code for mei bus message creation Tomas Winkler
                   ` (3 preceding siblings ...)
  2012-11-18 13:13 ` [char-misc-next 5/7] mei: don't mix read and write slots Tomas Winkler
@ 2012-11-18 13:13 ` Tomas Winkler
  2012-11-18 13:13 ` [char-misc-next 7/7] mei: Simplify the ME client enumeration code Tomas Winkler
  5 siblings, 0 replies; 7+ messages in thread
From: Tomas Winkler @ 2012-11-18 13:13 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler

extract the common, hence non conditional code
from the if-else statment

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/interrupt.c |   37 ++++++++++++-------------------------
 1 files changed, 12 insertions(+), 25 deletions(-)

diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index cccb63a..e5aa0ed 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -1027,34 +1027,21 @@ static int mei_irq_thread_write_handler(struct mei_device *dev,
 		cl = pos->cl;
 		if (cl == NULL)
 			continue;
+		if (mei_flow_ctrl_creds(dev, cl) <= 0) {
+			dev_dbg(&dev->pdev->dev,
+				"No flow control credentials for client %d, not sending.\n",
+				cl->host_client_id);
+			continue;
+		}
 
-		if (cl != &dev->iamthif_cl) {
-			if (mei_flow_ctrl_creds(dev, cl) <= 0) {
-				dev_dbg(&dev->pdev->dev,
-					"No flow control credentials for client %d, not sending.\n",
-					cl->host_client_id);
-				continue;
-			}
-			ret = mei_irq_thread_write_complete(dev, &slots, pos,
-						cmpl_list);
-			if (ret)
-				return ret;
-
-		} else if (cl == &dev->iamthif_cl) {
-			/* IAMTHIF IOCTL */
-			dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n");
-			if (mei_flow_ctrl_creds(dev, cl) <= 0) {
-				dev_dbg(&dev->pdev->dev,
-					"No flow control credentials for amthi client %d.\n",
-					cl->host_client_id);
-				continue;
-			}
+		if (cl == &dev->iamthif_cl)
 			ret = mei_amthif_irq_write_complete(dev, &slots,
 							pos, cmpl_list);
-			if (ret)
-				return ret;
-
-		}
+		else
+			ret = mei_irq_thread_write_complete(dev, &slots, pos,
+						cmpl_list);
+		if (ret)
+			return ret;
 
 	}
 	return 0;
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [char-misc-next 7/7] mei: Simplify the ME client enumeration code
  2012-11-18 13:13 [char-misc-next 1/7] mei: compact code for mei bus message creation Tomas Winkler
                   ` (4 preceding siblings ...)
  2012-11-18 13:13 ` [char-misc-next 6/7] mei: simplify write complete loop in irq handler Tomas Winkler
@ 2012-11-18 13:13 ` Tomas Winkler
  5 siblings, 0 replies; 7+ messages in thread
From: Tomas Winkler @ 2012-11-18 13:13 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, alan, linux-kernel, Samuel Ortiz, Tomas Winkler

From: Samuel Ortiz <sameo@linux.intel.com>

After enumerating all ME clients we call the client init functions for
all matching UUIDs from a separate context.
This remove the hackish cascading client initialisation process that was
interleaving properties and connection command replies.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 drivers/misc/mei/init.c      |   99 ++++++++++++++++++++++++++++--------------
 drivers/misc/mei/interrupt.c |   75 ++++++++++----------------------
 drivers/misc/mei/main.c      |    2 +
 drivers/misc/mei/mei_dev.h   |    5 ++-
 4 files changed, 95 insertions(+), 86 deletions(-)

diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 49600d6..a54cd55 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -423,54 +423,87 @@ void mei_allocate_me_clients_storage(struct mei_device *dev)
 	dev->me_clients = clients;
 	return ;
 }
-/**
- * host_client_properties - reads properties for client
- *
- * @dev: the device structure
- *
- * returns:
- * 	< 0 - Error.
- *  = 0 - no more clients.
- *  = 1 - still have clients to send properties request.
- */
-int mei_host_client_properties(struct mei_device *dev)
+
+void mei_host_client_init(struct work_struct *work)
+{
+	struct mei_device *dev = container_of(work,
+					      struct mei_device, init_work);
+	struct mei_client_properties *client_props;
+	int i;
+
+	mutex_lock(&dev->device_lock);
+
+	bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
+	dev->open_handle_count = 0;
+
+	/*
+	 * Reserving the first three client IDs
+	 * 0: Reserved for MEI Bus Message communications
+	 * 1: Reserved for Watchdog
+	 * 2: Reserved for AMTHI
+	 */
+	bitmap_set(dev->host_clients_map, 0, 3);
+
+	for (i = 0; i < dev->me_clients_num; i++) {
+		client_props = &dev->me_clients[i].props;
+
+		if (!uuid_le_cmp(client_props->protocol_name, mei_amthi_guid))
+			mei_amthif_host_init(dev);
+		else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid))
+			mei_wd_host_init(dev);
+	}
+
+	dev->dev_state = MEI_DEV_ENABLED;
+
+	mutex_unlock(&dev->device_lock);
+}
+
+int mei_host_client_enumerate(struct mei_device *dev)
 {
 
 	struct mei_msg_hdr *mei_hdr;
 	struct hbm_props_request *prop_req;
 	const size_t len = sizeof(struct hbm_props_request);
+	unsigned long next_client_index;
+	u8 client_num;
 
-	int b;
-	u8 client_num = dev->me_client_presentation_num;
 
-	prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1];
+	client_num = dev->me_client_presentation_num;
 
-	b = dev->me_client_index;
-	b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b);
-	if (b < MEI_CLIENTS_MAX) {
-		dev->me_clients[client_num].client_id = b;
-		dev->me_clients[client_num].mei_flow_ctrl_creds = 0;
-		mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
+	next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX,
+					  dev->me_client_index);
 
+	/* We got all client properties */
+	if (next_client_index == MEI_CLIENTS_MAX) {
+		schedule_work(&dev->init_work);
 
-		memset(prop_req, 0, sizeof(struct hbm_props_request));
+		return 0;
+	}
 
-		prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
-		prop_req->address = b;
+	dev->me_clients[client_num].client_id = next_client_index;
+	dev->me_clients[client_num].mei_flow_ctrl_creds = 0;
+
+	mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
+	prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1];
+
+	memset(prop_req, 0, sizeof(struct hbm_props_request));
 
-		if (mei_write_message(dev, mei_hdr,
-				(unsigned char *)prop_req, len)) {
-			dev->dev_state = MEI_DEV_RESETING;
-			dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
-			mei_reset(dev, 1);
-			return -EIO;
-		}
 
-		dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
-		dev->me_client_index = b;
-		return 1;
+	prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
+	prop_req->address = next_client_index;
+
+	if (mei_write_message(dev, mei_hdr, (unsigned char *) prop_req,
+			      mei_hdr->length)) {
+		dev->dev_state = MEI_DEV_RESETING;
+		dev_err(&dev->pdev->dev, "Properties request command failed\n");
+		mei_reset(dev, 1);
+
+		return -EIO;
 	}
 
+	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
+	dev->me_client_index = next_client_index;
+
 	return 0;
 }
 
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index e5aa0ed..04fa213 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -252,8 +252,6 @@ static void mei_client_connect_response(struct mei_device *dev,
 		dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
 		mei_watchdog_register(dev);
 
-		/* next step in the state maching */
-		mei_amthif_host_init(dev);
 		return;
 	}
 
@@ -470,6 +468,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
 		struct mei_msg_hdr *mei_hdr)
 {
 	struct mei_bus_message *mei_msg;
+	struct mei_me_client *me_client;
 	struct hbm_host_version_response *version_res;
 	struct hbm_client_connect_response *connect_res;
 	struct hbm_client_connect_response *disconnect_res;
@@ -478,8 +477,6 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
 	struct hbm_props_response *props_res;
 	struct hbm_host_enum_response *enum_res;
 	struct hbm_host_stop_request *stop_req;
-	int res;
-
 
 	/* read the message to our buffer */
 	BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf));
@@ -547,64 +544,37 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
 
 	case HOST_CLIENT_PROPERTIES_RES_CMD:
 		props_res = (struct hbm_props_response *)mei_msg;
+		me_client = &dev->me_clients[dev->me_client_presentation_num];
+
 		if (props_res->status || !dev->me_clients) {
 			dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n");
 			mei_reset(dev, 1);
 			return;
 		}
-		if (dev->me_clients[dev->me_client_presentation_num]
-					.client_id == props_res->address) {
 
-			dev->me_clients[dev->me_client_presentation_num].props
-						= props_res->client_properties;
+		if (me_client->client_id != props_res->address) {
+			dev_err(&dev->pdev->dev,
+				"Host client properties reply mismatch\n");
+			mei_reset(dev, 1);
 
-			if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
-			    dev->init_clients_state ==
-					MEI_CLIENT_PROPERTIES_MESSAGE) {
-				dev->me_client_index++;
-				dev->me_client_presentation_num++;
-
-				/** Send Client Properties request **/
-				res = mei_host_client_properties(dev);
-				if (res < 0) {
-					dev_dbg(&dev->pdev->dev, "mei_host_client_properties() failed");
-					return;
-				} else if (!res) {
-					/*
-					 * No more clients to send to.
-					 * Clear Map for indicating now ME clients
-					 * with associated host client
-					 */
-					bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
-					dev->open_handle_count = 0;
-
-					/*
-					 * Reserving the first three client IDs
-					 * Client Id 0 - Reserved for MEI Bus Message communications
-					 * Client Id 1 - Reserved for Watchdog
-					 * Client ID 2 - Reserved for AMTHI
-					 */
-					bitmap_set(dev->host_clients_map, 0, 3);
-					dev->dev_state = MEI_DEV_ENABLED;
-
-					/* if wd initialization fails, initialization the AMTHI client,
-					 * otherwise the AMTHI client will be initialized after the WD client connect response
-					 * will be received
-					 */
-					if (mei_wd_host_init(dev))
-						mei_amthif_host_init(dev);
-				}
+			return;
+		}
 
-			} else {
-				dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message");
-				mei_reset(dev, 1);
-				return;
-			}
-		} else {
-			dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message for wrong client ID\n");
+		if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
+		    dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) {
+			dev_err(&dev->pdev->dev,
+				"Unexpected client properties reply\n");
 			mei_reset(dev, 1);
+
 			return;
 		}
+
+		me_client->props = props_res->client_properties;
+		dev->me_client_index++;
+		dev->me_client_presentation_num++;
+
+		mei_host_client_enumerate(dev);
+
 		break;
 
 	case HOST_ENUM_RES_CMD:
@@ -618,7 +588,8 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
 				mei_allocate_me_clients_storage(dev);
 				dev->init_clients_state =
 					MEI_CLIENT_PROPERTIES_MESSAGE;
-				mei_host_client_properties(dev);
+
+				mei_host_client_enumerate(dev);
 		} else {
 			dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n");
 			mei_reset(dev, 1);
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 251aaff..7c9c381 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -829,6 +829,8 @@ static int __devinit mei_probe(struct pci_dev *pdev,
 		goto disable_msi;
 	}
 	INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
+	INIT_WORK(&dev->init_work, mei_host_client_init);
+
 	if (mei_hw_init(dev)) {
 		dev_err(&pdev->dev, "init hw failure.\n");
 		err = -ENODEV;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 17d00aa..25da045 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -287,6 +287,8 @@ struct mei_device {
 	bool iamthif_flow_control_pending;
 	bool iamthif_ioctl;
 	bool iamthif_canceled;
+
+	struct work_struct init_work;
 };
 
 static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
@@ -363,7 +365,8 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
  */
 void mei_host_start_message(struct mei_device *dev);
 void mei_host_enum_clients_message(struct mei_device *dev);
-int mei_host_client_properties(struct mei_device *dev);
+int mei_host_client_enumerate(struct mei_device *dev);
+void mei_host_client_init(struct work_struct *work);
 
 /*
  *  MEI interrupt functions prototype
-- 
1.7.4.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-11-18 13:14 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-18 13:13 [char-misc-next 1/7] mei: compact code for mei bus message creation Tomas Winkler
2012-11-18 13:13 ` [char-misc-next 2/7] mei: use structured buffer for extra write buffer Tomas Winkler
2012-11-18 13:13 ` [char-misc-next 3/7] mei: streamline write complete flow function Tomas Winkler
2012-11-18 13:13 ` [char-misc-next 4/7] mei: streamline amthif write complete function Tomas Winkler
2012-11-18 13:13 ` [char-misc-next 5/7] mei: don't mix read and write slots Tomas Winkler
2012-11-18 13:13 ` [char-misc-next 6/7] mei: simplify write complete loop in irq handler Tomas Winkler
2012-11-18 13:13 ` [char-misc-next 7/7] mei: Simplify the ME client enumeration code Tomas Winkler

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.