* [char-misc-next 01/21] mei: add new hbm.h header to export hbm protocol
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 02/21] mei: move client functions to client.c Tomas Winkler
` (19 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
hbm.h provides access host bus messaging functionality
for other MEI layers
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/amthif.c | 1 +
drivers/misc/mei/hbm.c | 1 +
drivers/misc/mei/hbm.h | 39 +++++++++++++++++++++++++++++++++++++++
drivers/misc/mei/init.c | 1 +
drivers/misc/mei/interface.h | 7 ++-----
drivers/misc/mei/interrupt.c | 1 +
drivers/misc/mei/iorw.c | 1 +
drivers/misc/mei/mei_dev.h | 10 ----------
drivers/misc/mei/wd.c | 1 +
9 files changed, 47 insertions(+), 15 deletions(-)
create mode 100644 drivers/misc/mei/hbm.h
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 6e3cd31..add4254 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -34,6 +34,7 @@
#include <linux/mei.h>
#include "mei_dev.h"
+#include "hbm.h"
#include "interface.h"
const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac,
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 6b58b0a..9956aaf 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -20,6 +20,7 @@
#include <linux/mei.h>
#include "mei_dev.h"
+#include "hbm.h"
#include "interface.h"
/**
diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h
new file mode 100644
index 0000000..b552afb
--- /dev/null
+++ b/drivers/misc/mei/hbm.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2012, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _MEI_HBM_H_
+#define _MEI_HBM_H_
+
+void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr);
+
+static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length)
+{
+ hdr->host_addr = 0;
+ hdr->me_addr = 0;
+ hdr->length = length;
+ hdr->msg_complete = 1;
+ hdr->reserved = 0;
+}
+
+void mei_hbm_start_req(struct mei_device *dev);
+
+int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl);
+int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl);
+int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl);
+
+
+#endif /* _MEI_HBM_H_ */
+
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 418a85f..55895fc 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -22,6 +22,7 @@
#include <linux/mei.h>
#include "mei_dev.h"
+#include "hbm.h"
#include "interface.h"
const char *mei_dev_state_str(int state)
diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h
index 90a3dfd..3d06c08 100644
--- a/drivers/misc/mei/interface.h
+++ b/drivers/misc/mei/interface.h
@@ -72,12 +72,9 @@ void mei_watchdog_unregister(struct mei_device *dev);
int mei_other_client_is_connecting(struct mei_device *dev, struct mei_cl *cl);
int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl);
-void mei_hbm_start_req(struct mei_device *dev);
+void mei_host_client_init(struct work_struct *work);
+
-int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl);
-int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl);
-int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl);
-void mei_host_client_init(struct work_struct *work);
#endif /* _MEI_INTERFACE_H_ */
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index a735c8b..2495e35 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -24,6 +24,7 @@
#include <linux/mei.h>
#include "mei_dev.h"
+#include "hbm.h"
#include "interface.h"
diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c
index d8e08bc..4328c2d 100644
--- a/drivers/misc/mei/iorw.c
+++ b/drivers/misc/mei/iorw.c
@@ -36,6 +36,7 @@
#include <linux/mei.h>
#include "mei_dev.h"
+#include "hbm.h"
#include "interface.h"
/**
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 54ddac3..1b54e67 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -445,16 +445,6 @@ void mei_enable_interrupts(struct mei_device *dev);
void mei_disable_interrupts(struct mei_device *dev);
-void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr);
-
-static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length)
-{
- hdr->host_addr = 0;
- hdr->me_addr = 0;
- hdr->length = length;
- hdr->msg_complete = 1;
- hdr->reserved = 0;
-}
#define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d comp=%1d"
#define MEI_HDR_PRM(hdr) \
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index 4f2e9db..9814bc1 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -24,6 +24,7 @@
#include <linux/mei.h>
#include "mei_dev.h"
+#include "hbm.h"
#include "interface.h"
static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 };
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 02/21] mei: move client functions to client.c
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 01/21] mei: add new hbm.h header to export hbm protocol Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 03/21] mei: fix client functions names Tomas Winkler
` (18 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
This file now contains me and host client functions
and also io callback helpers
We also kill iorw.c which is no longer needed
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/Makefile | 2 +-
drivers/misc/mei/{iorw.c => client.c} | 377 +++++++++++++++++++++++++++++++--
drivers/misc/mei/init.c | 252 ----------------------
drivers/misc/mei/interface.c | 96 ---------
4 files changed, 361 insertions(+), 366 deletions(-)
rename drivers/misc/mei/{iorw.c => client.c} (50%)
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index 1f382a5..67f543a 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -7,7 +7,7 @@ mei-objs := init.o
mei-objs += hbm.o
mei-objs += interrupt.o
mei-objs += interface.o
-mei-objs += iorw.o
mei-objs += main.o
mei-objs += amthif.o
mei-objs += wd.o
+mei-objs += client.o
diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/client.c
similarity index 50%
rename from drivers/misc/mei/iorw.c
rename to drivers/misc/mei/client.c
index 4328c2d..19f6207 100644
--- a/drivers/misc/mei/iorw.c
+++ b/drivers/misc/mei/client.c
@@ -14,24 +14,10 @@
*
*/
-
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/aio.h>
#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ioctl.h>
-#include <linux/cdev.h>
-#include <linux/list.h>
-#include <linux/delay.h>
#include <linux/sched.h>
-#include <linux/uuid.h>
-#include <linux/jiffies.h>
-#include <linux/uaccess.h>
-
+#include <linux/wait.h>
+#include <linux/delay.h>
#include <linux/mei.h>
@@ -39,6 +25,24 @@
#include "hbm.h"
#include "interface.h"
+
+/**
+ * mei_io_list_flush - removes list entry belonging to cl.
+ *
+ * @list: An instance of our list structure
+ * @cl: host client
+ */
+void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
+{
+ struct mei_cl_cb *cb;
+ struct mei_cl_cb *next;
+
+ list_for_each_entry_safe(cb, next, &list->list, list) {
+ if (cb->cl && mei_cl_cmp_id(cl, cb->cl))
+ list_del(&cb->list);
+ }
+}
+
/**
* mei_io_cb_free - free mei_cb_private related memory
*
@@ -53,6 +57,7 @@ void mei_io_cb_free(struct mei_cl_cb *cb)
kfree(cb->response_buffer.data);
kfree(cb);
}
+
/**
* mei_io_cb_init - allocate and initialize io callback
*
@@ -77,7 +82,6 @@ struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp)
return cb;
}
-
/**
* mei_io_cb_alloc_req_buf - allocate request buffer
*
@@ -128,6 +132,50 @@ int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length)
}
+
+/**
+ * mei_cl_flush_queues - flushes queue lists belonging to cl.
+ *
+ * @dev: the device structure
+ * @cl: host client
+ */
+int mei_cl_flush_queues(struct mei_cl *cl)
+{
+ if (!cl || !cl->dev)
+ return -EINVAL;
+
+ dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n");
+ mei_io_list_flush(&cl->dev->read_list, cl);
+ mei_io_list_flush(&cl->dev->write_list, cl);
+ mei_io_list_flush(&cl->dev->write_waiting_list, cl);
+ mei_io_list_flush(&cl->dev->ctrl_wr_list, cl);
+ mei_io_list_flush(&cl->dev->ctrl_rd_list, cl);
+ mei_io_list_flush(&cl->dev->amthif_cmd_list, cl);
+ mei_io_list_flush(&cl->dev->amthif_rd_complete_list, cl);
+ return 0;
+}
+
+/**
+ * mei_me_cl_by_uuid - locate index of me client
+ *
+ * @dev: mei device
+ * returns me client index or -ENOENT if not found
+ */
+int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *uuid)
+{
+ int i, res = -ENOENT;
+
+ for (i = 0; i < dev->me_clients_num; ++i)
+ if (uuid_le_cmp(*uuid,
+ dev->me_clients[i].props.protocol_name) == 0) {
+ res = i;
+ break;
+ }
+
+ return res;
+}
+
+
/**
* mei_me_cl_by_id return index to me_clients for client_id
*
@@ -155,6 +203,301 @@ int mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
}
/**
+ * mei_cl_init - initializes intialize cl.
+ *
+ * @cl: host client to be initialized
+ * @dev: mei device
+ */
+void mei_cl_init(struct mei_cl *cl, struct mei_device *dev)
+{
+ memset(cl, 0, sizeof(struct mei_cl));
+ init_waitqueue_head(&cl->wait);
+ init_waitqueue_head(&cl->rx_wait);
+ init_waitqueue_head(&cl->tx_wait);
+ INIT_LIST_HEAD(&cl->link);
+ cl->reading_state = MEI_IDLE;
+ cl->writing_state = MEI_IDLE;
+ cl->dev = dev;
+}
+
+/**
+ * mei_cl_allocate - allocates cl structure and sets it up.
+ *
+ * @dev: mei device
+ * returns The allocated file or NULL on failure
+ */
+struct mei_cl *mei_cl_allocate(struct mei_device *dev)
+{
+ struct mei_cl *cl;
+
+ cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL);
+ if (!cl)
+ return NULL;
+
+ mei_cl_init(cl, dev);
+
+ return cl;
+}
+
+
+/**
+ * mei_me_cl_link - create link between host and me clinet and add
+ * me_cl to the list
+ *
+ * @dev: the device structure
+ * @cl: link between me and host client assocated with opened file descriptor
+ * @uuid: uuid of ME client
+ * @client_id: id of the host client
+ *
+ * returns ME client index if ME client
+ * -EINVAL on incorrect values
+ * -ENONET if client not found
+ */
+int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl,
+ const uuid_le *uuid, u8 host_cl_id)
+{
+ int i;
+
+ if (!dev || !cl || !uuid)
+ return -EINVAL;
+
+ /* check for valid client id */
+ i = mei_me_cl_by_uuid(dev, uuid);
+ if (i >= 0) {
+ cl->me_client_id = dev->me_clients[i].client_id;
+ cl->state = MEI_FILE_CONNECTING;
+ cl->host_client_id = host_cl_id;
+
+ list_add_tail(&cl->link, &dev->file_list);
+ return (u8)i;
+ }
+
+ return -ENOENT;
+}
+/**
+ * mei_me_cl_unlink - remove me_cl from the list
+ *
+ * @dev: the device structure
+ * @host_client_id: host client id to be removed
+ */
+void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl)
+{
+ struct mei_cl *pos, *next;
+ list_for_each_entry_safe(pos, next, &dev->file_list, link) {
+ if (cl->host_client_id == pos->host_client_id) {
+ dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n",
+ pos->host_client_id, pos->me_client_id);
+ list_del_init(&pos->link);
+ break;
+ }
+ }
+}
+
+
+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);
+}
+
+
+/**
+ * mei_disconnect_host_client - sends disconnect message to fw from host client.
+ *
+ * @dev: the device structure
+ * @cl: private data of the file object
+ *
+ * Locking: called under "dev->device_lock" lock
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
+{
+ struct mei_cl_cb *cb;
+ int rets, err;
+
+ if (!dev || !cl)
+ return -ENODEV;
+
+ if (cl->state != MEI_FILE_DISCONNECTING)
+ return 0;
+
+ cb = mei_io_cb_init(cl, NULL);
+ if (!cb)
+ return -ENOMEM;
+
+ cb->fop_type = MEI_FOP_CLOSE;
+ if (dev->mei_host_buffer_is_empty) {
+ dev->mei_host_buffer_is_empty = false;
+ if (mei_hbm_cl_disconnect_req(dev, cl)) {
+ rets = -ENODEV;
+ dev_err(&dev->pdev->dev, "failed to disconnect.\n");
+ goto free;
+ }
+ mdelay(10); /* Wait for hardware disconnection ready */
+ list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
+ } else {
+ dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n");
+ list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
+
+ }
+ mutex_unlock(&dev->device_lock);
+
+ err = wait_event_timeout(dev->wait_recvd_msg,
+ MEI_FILE_DISCONNECTED == cl->state,
+ mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
+
+ mutex_lock(&dev->device_lock);
+ if (MEI_FILE_DISCONNECTED == cl->state) {
+ rets = 0;
+ dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n");
+ } else {
+ rets = -ENODEV;
+ if (MEI_FILE_DISCONNECTED != cl->state)
+ dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n");
+
+ if (err)
+ dev_dbg(&dev->pdev->dev,
+ "wait failed disconnect err=%08x\n",
+ err);
+
+ dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n");
+ }
+
+ mei_io_list_flush(&dev->ctrl_rd_list, cl);
+ mei_io_list_flush(&dev->ctrl_wr_list, cl);
+free:
+ mei_io_cb_free(cb);
+ return rets;
+}
+
+
+/**
+ * mei_other_client_is_connecting - checks if other
+ * client with the same client id is connected.
+ *
+ * @dev: the device structure
+ * @cl: private data of the file object
+ *
+ * returns 1 if other client is connected, 0 - otherwise.
+ */
+int mei_other_client_is_connecting(struct mei_device *dev,
+ struct mei_cl *cl)
+{
+ struct mei_cl *cl_pos = NULL;
+ struct mei_cl *cl_next = NULL;
+
+ list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
+ if ((cl_pos->state == MEI_FILE_CONNECTING) &&
+ (cl_pos != cl) &&
+ cl->me_client_id == cl_pos->me_client_id)
+ return 1;
+
+ }
+ return 0;
+}
+
+/**
+ * mei_flow_ctrl_creds - checks flow_control credentials.
+ *
+ * @dev: the device structure
+ * @cl: private data of the file object
+ *
+ * returns 1 if mei_flow_ctrl_creds >0, 0 - otherwise.
+ * -ENOENT if mei_cl is not present
+ * -EINVAL if single_recv_buf == 0
+ */
+int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl)
+{
+ int i;
+
+ if (!dev->me_clients_num)
+ return 0;
+
+ if (cl->mei_flow_ctrl_creds > 0)
+ return 1;
+
+ for (i = 0; i < dev->me_clients_num; i++) {
+ struct mei_me_client *me_cl = &dev->me_clients[i];
+ if (me_cl->client_id == cl->me_client_id) {
+ if (me_cl->mei_flow_ctrl_creds) {
+ if (WARN_ON(me_cl->props.single_recv_buf == 0))
+ return -EINVAL;
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ }
+ return -ENOENT;
+}
+
+/**
+ * mei_flow_ctrl_reduce - reduces flow_control.
+ *
+ * @dev: the device structure
+ * @cl: private data of the file object
+ * @returns
+ * 0 on success
+ * -ENOENT when me client is not found
+ * -EINVAL when ctrl credits are <= 0
+ */
+int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl)
+{
+ int i;
+
+ if (!dev->me_clients_num)
+ return -ENOENT;
+
+ for (i = 0; i < dev->me_clients_num; i++) {
+ struct mei_me_client *me_cl = &dev->me_clients[i];
+ if (me_cl->client_id == cl->me_client_id) {
+ if (me_cl->props.single_recv_buf != 0) {
+ if (WARN_ON(me_cl->mei_flow_ctrl_creds <= 0))
+ return -EINVAL;
+ dev->me_clients[i].mei_flow_ctrl_creds--;
+ } else {
+ if (WARN_ON(cl->mei_flow_ctrl_creds <= 0))
+ return -EINVAL;
+ cl->mei_flow_ctrl_creds--;
+ }
+ return 0;
+ }
+ }
+ return -ENOENT;
+}
+
+
+
+/**
* mei_ioctl_connect_client - the connect to fw client IOCTL function
*
* @dev: the device structure
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 55895fc..6c1f1f8 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -22,7 +22,6 @@
#include <linux/mei.h>
#include "mei_dev.h"
-#include "hbm.h"
#include "interface.h"
const char *mei_dev_state_str(int state)
@@ -45,47 +44,6 @@ const char *mei_dev_state_str(int state)
-/**
- * mei_io_list_flush - removes list entry belonging to cl.
- *
- * @list: An instance of our list structure
- * @cl: private data of the file object
- */
-void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
-{
- struct mei_cl_cb *pos;
- struct mei_cl_cb *next;
-
- list_for_each_entry_safe(pos, next, &list->list, list) {
- if (pos->cl) {
- if (mei_cl_cmp_id(cl, pos->cl))
- list_del(&pos->list);
- }
- }
-}
-/**
- * mei_cl_flush_queues - flushes queue lists belonging to cl.
- *
- * @dev: the device structure
- * @cl: private data of the file object
- */
-int mei_cl_flush_queues(struct mei_cl *cl)
-{
- if (!cl || !cl->dev)
- return -EINVAL;
-
- dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n");
- mei_io_list_flush(&cl->dev->read_list, cl);
- mei_io_list_flush(&cl->dev->write_list, cl);
- mei_io_list_flush(&cl->dev->write_waiting_list, cl);
- mei_io_list_flush(&cl->dev->ctrl_wr_list, cl);
- mei_io_list_flush(&cl->dev->ctrl_rd_list, cl);
- mei_io_list_flush(&cl->dev->amthif_cmd_list, cl);
- mei_io_list_flush(&cl->dev->amthif_rd_complete_list, cl);
- return 0;
-}
-
-
/**
* init_mei_device - allocates and initializes the mei device structure
@@ -360,215 +318,5 @@ void mei_allocate_me_clients_storage(struct mei_device *dev)
return ;
}
-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);
-}
-
-
-/**
- * mei_init_file_private - initializes private file structure.
- *
- * @priv: private file structure to be initialized
- * @file: the file structure
- */
-void mei_cl_init(struct mei_cl *priv, struct mei_device *dev)
-{
- memset(priv, 0, sizeof(struct mei_cl));
- init_waitqueue_head(&priv->wait);
- init_waitqueue_head(&priv->rx_wait);
- init_waitqueue_head(&priv->tx_wait);
- INIT_LIST_HEAD(&priv->link);
- priv->reading_state = MEI_IDLE;
- priv->writing_state = MEI_IDLE;
- priv->dev = dev;
-}
-
-int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid)
-{
- int i, res = -ENOENT;
-
- for (i = 0; i < dev->me_clients_num; ++i)
- if (uuid_le_cmp(*cuuid,
- dev->me_clients[i].props.protocol_name) == 0) {
- res = i;
- break;
- }
-
- return res;
-}
-
-
-/**
- * mei_me_cl_link - create link between host and me clinet and add
- * me_cl to the list
- *
- * @dev: the device structure
- * @cl: link between me and host client assocated with opened file descriptor
- * @cuuid: uuid of ME client
- * @client_id: id of the host client
- *
- * returns ME client index if ME client
- * -EINVAL on incorrect values
- * -ENONET if client not found
- */
-int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl,
- const uuid_le *cuuid, u8 host_cl_id)
-{
- int i;
-
- if (!dev || !cl || !cuuid)
- return -EINVAL;
-
- /* check for valid client id */
- i = mei_me_cl_by_uuid(dev, cuuid);
- if (i >= 0) {
- cl->me_client_id = dev->me_clients[i].client_id;
- cl->state = MEI_FILE_CONNECTING;
- cl->host_client_id = host_cl_id;
-
- list_add_tail(&cl->link, &dev->file_list);
- return (u8)i;
- }
-
- return -ENOENT;
-}
-/**
- * mei_me_cl_unlink - remove me_cl from the list
- *
- * @dev: the device structure
- * @host_client_id: host client id to be removed
- */
-void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl)
-{
- struct mei_cl *pos, *next;
- list_for_each_entry_safe(pos, next, &dev->file_list, link) {
- if (cl->host_client_id == pos->host_client_id) {
- dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n",
- pos->host_client_id, pos->me_client_id);
- list_del_init(&pos->link);
- break;
- }
- }
-}
-
-/**
- * mei_alloc_file_private - allocates a private file structure and sets it up.
- * @file: the file structure
- *
- * returns The allocated file or NULL on failure
- */
-struct mei_cl *mei_cl_allocate(struct mei_device *dev)
-{
- struct mei_cl *cl;
-
- cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL);
- if (!cl)
- return NULL;
-
- mei_cl_init(cl, dev);
-
- return cl;
-}
-
-
-
-/**
- * mei_disconnect_host_client - sends disconnect message to fw from host client.
- *
- * @dev: the device structure
- * @cl: private data of the file object
- *
- * Locking: called under "dev->device_lock" lock
- *
- * returns 0 on success, <0 on failure.
- */
-int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
-{
- struct mei_cl_cb *cb;
- int rets, err;
-
- if (!dev || !cl)
- return -ENODEV;
-
- if (cl->state != MEI_FILE_DISCONNECTING)
- return 0;
-
- cb = mei_io_cb_init(cl, NULL);
- if (!cb)
- return -ENOMEM;
-
- cb->fop_type = MEI_FOP_CLOSE;
- if (dev->mei_host_buffer_is_empty) {
- dev->mei_host_buffer_is_empty = false;
- if (mei_hbm_cl_disconnect_req(dev, cl)) {
- rets = -ENODEV;
- dev_err(&dev->pdev->dev, "failed to disconnect.\n");
- goto free;
- }
- mdelay(10); /* Wait for hardware disconnection ready */
- list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
- } else {
- dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n");
- list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
-
- }
- mutex_unlock(&dev->device_lock);
-
- err = wait_event_timeout(dev->wait_recvd_msg,
- MEI_FILE_DISCONNECTED == cl->state,
- mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
-
- mutex_lock(&dev->device_lock);
- if (MEI_FILE_DISCONNECTED == cl->state) {
- rets = 0;
- dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n");
- } else {
- rets = -ENODEV;
- if (MEI_FILE_DISCONNECTED != cl->state)
- dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n");
-
- if (err)
- dev_dbg(&dev->pdev->dev,
- "wait failed disconnect err=%08x\n",
- err);
-
- dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n");
- }
-
- mei_io_list_flush(&dev->ctrl_rd_list, cl);
- mei_io_list_flush(&dev->ctrl_wr_list, cl);
-free:
- mei_io_cb_free(cb);
- return rets;
-}
diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c
index 155bd7e..3cb0cff 100644
--- a/drivers/misc/mei/interface.c
+++ b/drivers/misc/mei/interface.c
@@ -297,99 +297,3 @@ void mei_read_slots(struct mei_device *dev, unsigned char *buffer,
mei_hcsr_set(dev);
}
-/**
- * mei_flow_ctrl_creds - checks flow_control credentials.
- *
- * @dev: the device structure
- * @cl: private data of the file object
- *
- * returns 1 if mei_flow_ctrl_creds >0, 0 - otherwise.
- * -ENOENT if mei_cl is not present
- * -EINVAL if single_recv_buf == 0
- */
-int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl)
-{
- int i;
-
- if (!dev->me_clients_num)
- return 0;
-
- if (cl->mei_flow_ctrl_creds > 0)
- return 1;
-
- for (i = 0; i < dev->me_clients_num; i++) {
- struct mei_me_client *me_cl = &dev->me_clients[i];
- if (me_cl->client_id == cl->me_client_id) {
- if (me_cl->mei_flow_ctrl_creds) {
- if (WARN_ON(me_cl->props.single_recv_buf == 0))
- return -EINVAL;
- return 1;
- } else {
- return 0;
- }
- }
- }
- return -ENOENT;
-}
-
-/**
- * mei_flow_ctrl_reduce - reduces flow_control.
- *
- * @dev: the device structure
- * @cl: private data of the file object
- * @returns
- * 0 on success
- * -ENOENT when me client is not found
- * -EINVAL when ctrl credits are <= 0
- */
-int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl)
-{
- int i;
-
- if (!dev->me_clients_num)
- return -ENOENT;
-
- for (i = 0; i < dev->me_clients_num; i++) {
- struct mei_me_client *me_cl = &dev->me_clients[i];
- if (me_cl->client_id == cl->me_client_id) {
- if (me_cl->props.single_recv_buf != 0) {
- if (WARN_ON(me_cl->mei_flow_ctrl_creds <= 0))
- return -EINVAL;
- dev->me_clients[i].mei_flow_ctrl_creds--;
- } else {
- if (WARN_ON(cl->mei_flow_ctrl_creds <= 0))
- return -EINVAL;
- cl->mei_flow_ctrl_creds--;
- }
- return 0;
- }
- }
- return -ENOENT;
-}
-
-
-/**
- * mei_other_client_is_connecting - checks if other
- * client with the same client id is connected.
- *
- * @dev: the device structure
- * @cl: private data of the file object
- *
- * returns 1 if other client is connected, 0 - otherwise.
- */
-int mei_other_client_is_connecting(struct mei_device *dev,
- struct mei_cl *cl)
-{
- struct mei_cl *cl_pos = NULL;
- struct mei_cl *cl_next = NULL;
-
- list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
- if ((cl_pos->state == MEI_FILE_CONNECTING) &&
- (cl_pos != cl) &&
- cl->me_client_id == cl_pos->me_client_id)
- return 1;
-
- }
- return 0;
-}
-
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 03/21] mei: fix client functions names
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 01/21] mei: add new hbm.h header to export hbm protocol Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 02/21] mei: move client functions to client.c Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 04/21] mei: implement mei_cl_connect function Tomas Winkler
` (17 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
Use common prefix for function names:
mei_cl_ - for host clients
mei_me_ - for me clients
mei_io_ - for io callback functions
Because mei_cl holds mei_device back pointer
we can also drop the dev argument from the client
functions
add client.h header to export the clients API
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/amthif.c | 9 +-
drivers/misc/mei/client.c | 221 ++++++++++++++++++++++++++----------------
drivers/misc/mei/client.h | 97 ++++++++++++++++++
drivers/misc/mei/init.c | 6 +-
drivers/misc/mei/interface.h | 8 --
drivers/misc/mei/interrupt.c | 11 +-
drivers/misc/mei/main.c | 47 +++-------
drivers/misc/mei/mei_dev.h | 53 ----------
drivers/misc/mei/wd.c | 13 ++-
9 files changed, 267 insertions(+), 198 deletions(-)
create mode 100644 drivers/misc/mei/client.h
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index add4254..cbc9c4e 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -36,6 +36,7 @@
#include "mei_dev.h"
#include "hbm.h"
#include "interface.h"
+#include "client.h"
const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac,
0xa8, 0x46, 0xe0, 0xff, 0x65,
@@ -73,7 +74,7 @@ void mei_amthif_host_init(struct mei_device *dev)
dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
/* find ME amthi client */
- i = mei_me_cl_link(dev, &dev->iamthif_cl,
+ i = mei_cl_link_me(&dev->iamthif_cl,
&mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
if (i < 0) {
dev_info(&dev->pdev->dev, "failed to find iamthif client.\n");
@@ -280,7 +281,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
memcpy(dev->iamthif_msg_buf, cb->request_buffer.data,
cb->request_buffer.size);
- ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl);
+ ret = mei_cl_flow_ctrl_creds(&dev->iamthif_cl);
if (ret < 0)
return ret;
@@ -304,7 +305,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
return -ENODEV;
if (mei_hdr.msg_complete) {
- if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl))
+ if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl))
return -ENODEV;
dev->iamthif_flow_control_pending = true;
dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
@@ -467,7 +468,7 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
return -ENODEV;
}
- if (mei_flow_ctrl_reduce(dev, cl))
+ if (mei_cl_flow_ctrl_reduce(cl))
return -ENODEV;
dev->iamthif_msg_buf_index += mei_hdr.length;
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 19f6207..e300637 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -24,6 +24,54 @@
#include "mei_dev.h"
#include "hbm.h"
#include "interface.h"
+#include "client.h"
+
+/**
+ * mei_me_cl_by_uuid - locate index of me client
+ *
+ * @dev: mei device
+ * returns me client index or -ENOENT if not found
+ */
+int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *uuid)
+{
+ int i, res = -ENOENT;
+
+ for (i = 0; i < dev->me_clients_num; ++i)
+ if (uuid_le_cmp(*uuid,
+ dev->me_clients[i].props.protocol_name) == 0) {
+ res = i;
+ break;
+ }
+
+ return res;
+}
+
+
+/**
+ * mei_me_cl_by_id return index to me_clients for client_id
+ *
+ * @dev: the device structure
+ * @client_id: me client id
+ *
+ * Locking: called under "dev->device_lock" lock
+ *
+ * returns index on success, -ENOENT on failure.
+ */
+
+int mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
+{
+ int i;
+ for (i = 0; i < dev->me_clients_num; i++)
+ if (dev->me_clients[i].client_id == client_id)
+ break;
+ if (WARN_ON(dev->me_clients[i].client_id != client_id))
+ return -ENOENT;
+
+ if (i == dev->me_clients_num)
+ return -ENOENT;
+
+ return i;
+}
/**
@@ -141,7 +189,7 @@ int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length)
*/
int mei_cl_flush_queues(struct mei_cl *cl)
{
- if (!cl || !cl->dev)
+ if (WARN_ON(!cl || !cl->dev))
return -EINVAL;
dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n");
@@ -155,52 +203,6 @@ int mei_cl_flush_queues(struct mei_cl *cl)
return 0;
}
-/**
- * mei_me_cl_by_uuid - locate index of me client
- *
- * @dev: mei device
- * returns me client index or -ENOENT if not found
- */
-int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *uuid)
-{
- int i, res = -ENOENT;
-
- for (i = 0; i < dev->me_clients_num; ++i)
- if (uuid_le_cmp(*uuid,
- dev->me_clients[i].props.protocol_name) == 0) {
- res = i;
- break;
- }
-
- return res;
-}
-
-
-/**
- * mei_me_cl_by_id return index to me_clients for client_id
- *
- * @dev: the device structure
- * @client_id: me client id
- *
- * Locking: called under "dev->device_lock" lock
- *
- * returns index on success, -ENOENT on failure.
- */
-
-int mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
-{
- int i;
- for (i = 0; i < dev->me_clients_num; i++)
- if (dev->me_clients[i].client_id == client_id)
- break;
- if (WARN_ON(dev->me_clients[i].client_id != client_id))
- return -ENOENT;
-
- if (i == dev->me_clients_num)
- return -ENOENT;
-
- return i;
-}
/**
* mei_cl_init - initializes intialize cl.
@@ -239,12 +241,29 @@ struct mei_cl *mei_cl_allocate(struct mei_device *dev)
return cl;
}
+/**
+ * mei_cl_find_read_cb - find this cl's callback in the read list
+ *
+ * @dev: device structure
+ * returns cb on success, NULL on error
+ */
+struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl)
+{
+ struct mei_device *dev = cl->dev;
+ struct mei_cl_cb *cb = NULL;
+ struct mei_cl_cb *next = NULL;
+
+ list_for_each_entry_safe(cb, next, &dev->read_list.list, list)
+ if (mei_cl_cmp_id(cl, cb->cl))
+ return cb;
+ return NULL;
+}
+
/**
* mei_me_cl_link - create link between host and me clinet and add
* me_cl to the list
*
- * @dev: the device structure
* @cl: link between me and host client assocated with opened file descriptor
* @uuid: uuid of ME client
* @client_id: id of the host client
@@ -253,14 +272,16 @@ struct mei_cl *mei_cl_allocate(struct mei_device *dev)
* -EINVAL on incorrect values
* -ENONET if client not found
*/
-int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl,
- const uuid_le *uuid, u8 host_cl_id)
+int mei_cl_link_me(struct mei_cl *cl, const uuid_le *uuid, u8 host_cl_id)
{
+ struct mei_device *dev;
int i;
- if (!dev || !cl || !uuid)
+ if (WARN_ON(!cl || !cl->dev || !uuid))
return -EINVAL;
+ dev = cl->dev;
+
/* check for valid client id */
i = mei_me_cl_by_uuid(dev, uuid);
if (i >= 0) {
@@ -275,22 +296,30 @@ int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl,
return -ENOENT;
}
/**
- * mei_me_cl_unlink - remove me_cl from the list
+ * mei_cl_unlink - remove me_cl from the list
*
* @dev: the device structure
* @host_client_id: host client id to be removed
*/
-void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl)
+int mei_cl_unlink(struct mei_cl *cl)
{
+ struct mei_device *dev;
struct mei_cl *pos, *next;
+
+ if (WARN_ON(!cl || !cl->dev))
+ return -EINVAL;
+
+ dev = cl->dev;
+
list_for_each_entry_safe(pos, next, &dev->file_list, link) {
if (cl->host_client_id == pos->host_client_id) {
dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n",
- pos->host_client_id, pos->me_client_id);
+ pos->host_client_id, pos->me_client_id);
list_del_init(&pos->link);
break;
}
}
+ return 0;
}
@@ -330,23 +359,25 @@ void mei_host_client_init(struct work_struct *work)
/**
- * mei_disconnect_host_client - sends disconnect message to fw from host client.
+ * mei_cl_disconnect - disconnect host clinet form the me one
*
- * @dev: the device structure
- * @cl: private data of the file object
+ * @cl: host client
*
* Locking: called under "dev->device_lock" lock
*
* returns 0 on success, <0 on failure.
*/
-int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
+int mei_cl_disconnect(struct mei_cl *cl)
{
+ struct mei_device *dev;
struct mei_cl_cb *cb;
int rets, err;
- if (!dev || !cl)
+ if (WARN_ON(!cl || !cl->dev))
return -ENODEV;
+ dev = cl->dev;
+
if (cl->state != MEI_FILE_DISCONNECTING)
return 0;
@@ -401,32 +432,36 @@ free:
/**
- * mei_other_client_is_connecting - checks if other
- * client with the same client id is connected.
+ * mei_cl_is_other_connecting - checks if other
+ * client with the same me client id is connecting
*
- * @dev: the device structure
* @cl: private data of the file object
*
- * returns 1 if other client is connected, 0 - otherwise.
+ * returns ture if other client is connected, 0 - otherwise.
*/
-int mei_other_client_is_connecting(struct mei_device *dev,
- struct mei_cl *cl)
+bool mei_cl_is_other_connecting(struct mei_cl *cl)
{
- struct mei_cl *cl_pos = NULL;
- struct mei_cl *cl_next = NULL;
+ struct mei_device *dev;
+ struct mei_cl *pos;
+ struct mei_cl *next;
- list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
- if ((cl_pos->state == MEI_FILE_CONNECTING) &&
- (cl_pos != cl) &&
- cl->me_client_id == cl_pos->me_client_id)
- return 1;
+ if (WARN_ON(!cl || !cl->dev))
+ return false;
+
+ dev = cl->dev;
+
+ list_for_each_entry_safe(pos, next, &dev->file_list, link) {
+ if ((pos->state == MEI_FILE_CONNECTING) &&
+ (pos != cl) && cl->me_client_id == pos->me_client_id)
+ return true;
}
- return 0;
+
+ return false;
}
/**
- * mei_flow_ctrl_creds - checks flow_control credentials.
+ * mei_cl_flow_ctrl_creds - checks flow_control credits for cl.
*
* @dev: the device structure
* @cl: private data of the file object
@@ -435,10 +470,16 @@ int mei_other_client_is_connecting(struct mei_device *dev,
* -ENOENT if mei_cl is not present
* -EINVAL if single_recv_buf == 0
*/
-int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl)
+int mei_cl_flow_ctrl_creds(struct mei_cl *cl)
{
+ struct mei_device *dev;
int i;
+ if (WARN_ON(!cl || !cl->dev))
+ return -EINVAL;
+
+ dev = cl->dev;
+
if (!dev->me_clients_num)
return 0;
@@ -461,7 +502,7 @@ int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl)
}
/**
- * mei_flow_ctrl_reduce - reduces flow_control.
+ * mei_cl_flow_ctrl_reduce - reduces flow_control.
*
* @dev: the device structure
* @cl: private data of the file object
@@ -470,10 +511,16 @@ int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl)
* -ENOENT when me client is not found
* -EINVAL when ctrl credits are <= 0
*/
-int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl)
+int mei_cl_flow_ctrl_reduce(struct mei_cl *cl)
{
+ struct mei_device *dev;
int i;
+ if (WARN_ON(!cl || !cl->dev))
+ return -EINVAL;
+
+ dev = cl->dev;
+
if (!dev->me_clients_num)
return -ENOENT;
@@ -571,7 +618,7 @@ int mei_ioctl_connect_client(struct file *file,
goto end;
}
clear_bit(cl->host_client_id, dev->host_clients_map);
- mei_me_cl_unlink(dev, cl);
+ mei_cl_unlink(cl);
kfree(cl);
cl = NULL;
@@ -598,8 +645,8 @@ int mei_ioctl_connect_client(struct file *file,
client->max_msg_length = dev->me_clients[i].props.max_msg_length;
client->protocol_version = dev->me_clients[i].props.protocol_version;
dev_dbg(&dev->pdev->dev, "Can connect?\n");
- if (dev->mei_host_buffer_is_empty
- && !mei_other_client_is_connecting(dev, cl)) {
+ if (dev->mei_host_buffer_is_empty &&
+ !mei_cl_is_other_connecting(cl)) {
dev_dbg(&dev->pdev->dev, "Sending Connect Message\n");
dev->mei_host_buffer_is_empty = false;
if (mei_hbm_cl_connect_req(dev, cl)) {
@@ -650,20 +697,24 @@ end:
}
/**
- * mei_start_read - the start read client message function.
+ * mei_cl_start_read - the start read client message function.
*
- * @dev: the device structure
- * @if_num: minor number
- * @cl: private data of the file object
+ * @cl: host client
*
* returns 0 on success, <0 on failure.
*/
-int mei_start_read(struct mei_device *dev, struct mei_cl *cl)
+int mei_cl_read_start(struct mei_cl *cl)
{
+ struct mei_device *dev;
struct mei_cl_cb *cb;
int rets;
int i;
+ if (WARN_ON(!cl || !cl->dev))
+ return -ENODEV;
+
+ dev = cl->dev;
+
if (cl->state != MEI_FILE_CONNECTED)
return -ENODEV;
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
new file mode 100644
index 0000000..8dfd052
--- /dev/null
+++ b/drivers/misc/mei/client.h
@@ -0,0 +1,97 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2012, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _MEI_CLIENT_H_
+#define _MEI_CLIENT_H_
+
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <linux/poll.h>
+#include <linux/mei.h>
+
+#include "mei_dev.h"
+
+int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid);
+int mei_me_cl_by_id(struct mei_device *dev, u8 client_id);
+
+/*
+ * MEI IO Functions
+ */
+struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp);
+void mei_io_cb_free(struct mei_cl_cb *priv_cb);
+int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length);
+int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length);
+
+
+/**
+ * mei_io_list_init - Sets up a queue list.
+ *
+ * @list: An instance cl callback structure
+ */
+static inline void mei_io_list_init(struct mei_cl_cb *list)
+{
+ INIT_LIST_HEAD(&list->list);
+}
+void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl);
+
+/*
+ * MEI Host Client Functions
+ */
+
+struct mei_cl *mei_cl_allocate(struct mei_device *dev);
+void mei_cl_init(struct mei_cl *cl, struct mei_device *dev);
+
+
+int mei_cl_link_me(struct mei_cl *cl, const uuid_le *uuid, u8 host_cl_id);
+int mei_cl_unlink(struct mei_cl *cl);
+
+int mei_cl_flush_queues(struct mei_cl *cl);
+struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl);
+
+/**
+ * mei_cl_cmp_id - tells if file private data have same id
+ *
+ * @fe1: private data of 1. file object
+ * @fe2: private data of 2. file object
+ *
+ * returns true - if ids are the same and not NULL
+ */
+static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
+ const struct mei_cl *cl2)
+{
+ return cl1 && cl2 &&
+ (cl1->host_client_id == cl2->host_client_id) &&
+ (cl1->me_client_id == cl2->me_client_id);
+}
+
+
+int mei_cl_flow_ctrl_creds(struct mei_cl *cl);
+
+int mei_cl_flow_ctrl_reduce(struct mei_cl *cl);
+/*
+ * MEI input output function prototype
+ */
+bool mei_cl_is_other_connecting(struct mei_cl *cl);
+int mei_cl_disconnect(struct mei_cl *cl);
+
+int mei_cl_read_start(struct mei_cl *cl);
+
+int mei_cl_connect(struct mei_cl *cl, struct file *file);
+
+void mei_host_client_init(struct work_struct *work);
+
+
+#endif /* _MEI_CLIENT_H_ */
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 6c1f1f8..7028dbd 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -23,6 +23,7 @@
#include "mei_dev.h"
#include "interface.h"
+#include "client.h"
const char *mei_dev_state_str(int state)
{
@@ -241,9 +242,8 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
}
/* remove entry if already in list */
dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n");
- mei_me_cl_unlink(dev, &dev->wd_cl);
-
- mei_me_cl_unlink(dev, &dev->iamthif_cl);
+ mei_cl_unlink(&dev->wd_cl);
+ mei_cl_unlink(&dev->iamthif_cl);
mei_amthif_reset_params(dev);
memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h
index 3d06c08..01d1ef5 100644
--- a/drivers/misc/mei/interface.h
+++ b/drivers/misc/mei/interface.h
@@ -50,7 +50,6 @@ static inline unsigned char mei_data2slots(size_t length)
int mei_count_full_read_slots(struct mei_device *dev);
-int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl);
@@ -69,12 +68,5 @@ void mei_watchdog_register(struct mei_device *dev);
*/
void mei_watchdog_unregister(struct mei_device *dev);
-int mei_other_client_is_connecting(struct mei_device *dev, struct mei_cl *cl);
-int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl);
-
-void mei_host_client_init(struct work_struct *work);
-
-
-
#endif /* _MEI_INTERFACE_H_ */
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 2495e35..0a141af 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -26,6 +26,7 @@
#include "mei_dev.h"
#include "hbm.h"
#include "interface.h"
+#include "client.h"
/**
@@ -297,7 +298,7 @@ static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots,
return -ENODEV;
}
- if (mei_flow_ctrl_reduce(dev, cl))
+ if (mei_cl_flow_ctrl_reduce(cl))
return -ENODEV;
cl->status = 0;
@@ -478,10 +479,10 @@ static int mei_irq_thread_write_handler(struct mei_device *dev,
}
if (dev->dev_state == MEI_DEV_ENABLED) {
if (dev->wd_pending &&
- mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
+ mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) {
if (mei_wd_send(dev))
dev_dbg(&dev->pdev->dev, "wd send failed.\n");
- else if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
+ else if (mei_cl_flow_ctrl_reduce(&dev->wd_cl))
return -ENODEV;
dev->wd_pending = false;
@@ -520,7 +521,7 @@ static int mei_irq_thread_write_handler(struct mei_device *dev,
break;
case MEI_FOP_IOCTL:
/* connect message */
- if (mei_other_client_is_connecting(dev, cl))
+ if (mei_cl_is_other_connecting(cl))
continue;
ret = _mei_irq_thread_ioctl(dev, &slots, pos,
cl, cmpl_list);
@@ -540,7 +541,7 @@ 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) {
+ if (mei_cl_flow_ctrl_creds(cl) <= 0) {
dev_dbg(&dev->pdev->dev,
"No flow control credentials for client %d, not sending.\n",
cl->host_client_id);
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index da94260..95f05d9 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -41,6 +41,7 @@
#include "mei_dev.h"
#include "interface.h"
+#include "client.h"
/* AMT device is a singleton on the platform */
static struct pci_dev *mei_pdev;
@@ -91,28 +92,6 @@ static DEFINE_MUTEX(mei_mutex);
/**
- * find_read_list_entry - find read list entry
- *
- * @dev: device structure
- * @file: pointer to file structure
- *
- * returns cb on success, NULL on error
- */
-static struct mei_cl_cb *find_read_list_entry(
- struct mei_device *dev,
- struct mei_cl *cl)
-{
- struct mei_cl_cb *pos = NULL;
- struct mei_cl_cb *next = NULL;
-
- dev_dbg(&dev->pdev->dev, "remove read_list CB\n");
- list_for_each_entry_safe(pos, next, &dev->read_list.list, list)
- if (mei_cl_cmp_id(cl, pos->cl))
- return pos;
- return NULL;
-}
-
-/**
* mei_open - the open function
*
* @inode: pointer to inode structure
@@ -217,7 +196,7 @@ static int mei_release(struct inode *inode, struct file *file)
"ME client = %d\n",
cl->host_client_id,
cl->me_client_id);
- rets = mei_disconnect_host_client(dev, cl);
+ rets = mei_cl_disconnect(cl);
}
mei_cl_flush_queues(cl);
dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n",
@@ -228,12 +207,12 @@ static int mei_release(struct inode *inode, struct file *file)
clear_bit(cl->host_client_id, dev->host_clients_map);
dev->open_handle_count--;
}
- mei_me_cl_unlink(dev, cl);
+ mei_cl_unlink(cl);
/* free read cb */
cb = NULL;
if (cl->read_cb) {
- cb = find_read_list_entry(dev, cl);
+ cb = mei_cl_find_read_cb(cl);
/* Remove entry from read list */
if (cb)
list_del(&cb->list);
@@ -323,7 +302,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
goto out;
}
- err = mei_start_read(dev, cl);
+ err = mei_cl_read_start(cl);
if (err && err != -EBUSY) {
dev_dbg(&dev->pdev->dev,
"mei start read failure with status = %d\n", err);
@@ -394,7 +373,7 @@ copy_buffer:
goto out;
free:
- cb_pos = find_read_list_entry(dev, cl);
+ cb_pos = mei_cl_find_read_cb(cl);
/* Remove entry from read list */
if (cb_pos)
list_del(&cb_pos->list);
@@ -476,7 +455,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
/* free entry used in read */
if (cl->reading_state == MEI_READ_COMPLETE) {
*offset = 0;
- write_cb = find_read_list_entry(dev, cl);
+ write_cb = mei_cl_find_read_cb(cl);
if (write_cb) {
list_del(&write_cb->list);
mei_io_cb_free(write_cb);
@@ -531,7 +510,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n",
cl->host_client_id, cl->me_client_id);
- rets = mei_flow_ctrl_creds(dev, cl);
+ rets = mei_cl_flow_ctrl_creds(cl);
if (rets < 0)
goto err;
@@ -565,7 +544,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
out:
if (mei_hdr.msg_complete) {
- if (mei_flow_ctrl_reduce(dev, cl)) {
+ if (mei_cl_flow_ctrl_reduce(cl)) {
rets = -ENODEV;
goto err;
}
@@ -904,11 +883,11 @@ static void mei_remove(struct pci_dev *pdev)
if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) {
dev->iamthif_cl.state = MEI_FILE_DISCONNECTING;
- mei_disconnect_host_client(dev, &dev->iamthif_cl);
+ mei_cl_disconnect(&dev->iamthif_cl);
}
if (dev->wd_cl.state == MEI_FILE_CONNECTED) {
dev->wd_cl.state = MEI_FILE_DISCONNECTING;
- mei_disconnect_host_client(dev, &dev->wd_cl);
+ mei_cl_disconnect(&dev->wd_cl);
}
/* Unregistering watchdog device */
@@ -916,8 +895,8 @@ static void mei_remove(struct pci_dev *pdev)
/* remove entry if already in list */
dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
- mei_me_cl_unlink(dev, &dev->wd_cl);
- mei_me_cl_unlink(dev, &dev->iamthif_cl);
+ mei_cl_unlink(&dev->wd_cl);
+ mei_cl_unlink(&dev->iamthif_cl);
dev->iamthif_current_cb = NULL;
dev->me_clients_num = 0;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 1b54e67..5a1ac9a 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -329,59 +329,9 @@ void mei_reset(struct mei_device *dev, int interrupts);
int mei_hw_init(struct mei_device *dev);
int mei_task_initialize_clients(void *data);
int mei_initialize_clients(struct mei_device *dev);
-int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl);
void mei_allocate_me_clients_storage(struct mei_device *dev);
-int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl,
- const uuid_le *cguid, u8 host_client_id);
-void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl);
-int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid);
-int mei_me_cl_by_id(struct mei_device *dev, u8 client_id);
-
-/*
- * MEI IO Functions
- */
-struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp);
-void mei_io_cb_free(struct mei_cl_cb *priv_cb);
-int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length);
-int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length);
-
-
-/**
- * mei_io_list_init - Sets up a queue list.
- *
- * @list: An instance cl callback structure
- */
-static inline void mei_io_list_init(struct mei_cl_cb *list)
-{
- INIT_LIST_HEAD(&list->list);
-}
-void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl);
-
-/*
- * MEI ME Client Functions
- */
-
-struct mei_cl *mei_cl_allocate(struct mei_device *dev);
-void mei_cl_init(struct mei_cl *cl, struct mei_device *dev);
-int mei_cl_flush_queues(struct mei_cl *cl);
-/**
- * mei_cl_cmp_id - tells if file private data have same id
- *
- * @fe1: private data of 1. file object
- * @fe2: private data of 2. file object
- *
- * returns true - if ids are the same and not NULL
- */
-static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
- const struct mei_cl *cl2)
-{
- return cl1 && cl2 &&
- (cl1->host_client_id == cl2->host_client_id) &&
- (cl1->me_client_id == cl2->me_client_id);
-}
-
/*
* MEI interrupt functions prototype
@@ -395,9 +345,6 @@ void mei_timer(struct work_struct *work);
*/
int mei_ioctl_connect_client(struct file *file,
struct mei_connect_client_data *data);
-
-int mei_start_read(struct mei_device *dev, struct mei_cl *cl);
-
/*
* AMTHIF - AMT Host Interface Functions
*/
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index 9814bc1..5ad5225 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -26,6 +26,7 @@
#include "mei_dev.h"
#include "hbm.h"
#include "interface.h"
+#include "client.h"
static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 };
static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 };
@@ -72,7 +73,7 @@ int mei_wd_host_init(struct mei_device *dev)
dev->wd_state = MEI_WD_IDLE;
/* Connect WD ME client to the host client */
- id = mei_me_cl_link(dev, &dev->wd_cl,
+ id = mei_cl_link_me(&dev->wd_cl,
&mei_wd_guid, MEI_WD_HOST_CLIENT_ID);
if (id < 0) {
@@ -141,7 +142,7 @@ int mei_wd_stop(struct mei_device *dev)
dev->wd_state = MEI_WD_STOPPING;
- ret = mei_flow_ctrl_creds(dev, &dev->wd_cl);
+ ret = mei_cl_flow_ctrl_creds(&dev->wd_cl);
if (ret < 0)
goto out;
@@ -150,7 +151,7 @@ int mei_wd_stop(struct mei_device *dev)
dev->mei_host_buffer_is_empty = false;
if (!mei_wd_send(dev)) {
- ret = mei_flow_ctrl_reduce(dev, &dev->wd_cl);
+ ret = mei_cl_flow_ctrl_reduce(&dev->wd_cl);
if (ret)
goto out;
} else {
@@ -271,7 +272,7 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
/* Check if we can send the ping to HW*/
if (dev->mei_host_buffer_is_empty &&
- mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
+ mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) {
dev->mei_host_buffer_is_empty = false;
dev_dbg(&dev->pdev->dev, "wd: sending ping\n");
@@ -282,9 +283,9 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
goto end;
}
- if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) {
+ if (mei_cl_flow_ctrl_reduce(&dev->wd_cl)) {
dev_err(&dev->pdev->dev,
- "wd: mei_flow_ctrl_reduce() failed.\n");
+ "wd: mei_cl_flow_ctrl_reduce() failed.\n");
ret = -EIO;
goto end;
}
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 04/21] mei: implement mei_cl_connect function
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (2 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 03/21] mei: fix client functions names Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 05/21] mei: move watchdog prototypes to mei_dev.h from interface.h Tomas Winkler
` (16 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
Implement mei_cl_connect that warps host client
parts of the connection and leave the ioctl specifics
in the mei_ioctl_connect_client function.
Move mei_ioctl_connect_client to main.c where it
belongs
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/client.c | 219 +++++++++++++-------------------------------
drivers/misc/mei/main.c | 98 ++++++++++++++++++++
drivers/misc/mei/mei_dev.h | 5 -
3 files changed, 163 insertions(+), 159 deletions(-)
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index e300637..cc3e76c 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -461,6 +461,71 @@ bool mei_cl_is_other_connecting(struct mei_cl *cl)
}
/**
+ * mei_cl_connect - connect host clinet to the me one
+ *
+ * @cl: host client
+ *
+ * Locking: called under "dev->device_lock" lock
+ *
+ * returns 0 on success, <0 on failure.
+ */
+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))
+ return -ENODEV;
+
+ dev = cl->dev;
+
+ cb = mei_io_cb_init(cl, file);
+ if (!cb) {
+ rets = -ENOMEM;
+ goto out;
+ }
+
+ cb->fop_type = MEI_FOP_IOCTL;
+
+ if (dev->mei_host_buffer_is_empty &&
+ !mei_cl_is_other_connecting(cl)) {
+ dev->mei_host_buffer_is_empty = false;
+
+ if (mei_hbm_cl_connect_req(dev, cl)) {
+ rets = -ENODEV;
+ goto out;
+ }
+ cl->timer_count = MEI_CONNECT_TIMEOUT;
+ list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
+ } else {
+ list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
+ }
+
+ mutex_unlock(&dev->device_lock);
+ rets = wait_event_timeout(dev->wait_recvd_msg,
+ (cl->state == MEI_FILE_CONNECTED ||
+ cl->state == MEI_FILE_DISCONNECTED),
+ timeout * HZ);
+ mutex_lock(&dev->device_lock);
+
+ if (cl->state != MEI_FILE_CONNECTED) {
+ rets = -EFAULT;
+
+ mei_io_list_flush(&dev->ctrl_rd_list, cl);
+ mei_io_list_flush(&dev->ctrl_wr_list, cl);
+ goto out;
+ }
+
+ rets = cl->status;
+
+out:
+ mei_io_cb_free(cb);
+ return rets;
+}
+
+/**
* mei_cl_flow_ctrl_creds - checks flow_control credits for cl.
*
* @dev: the device structure
@@ -542,160 +607,6 @@ int mei_cl_flow_ctrl_reduce(struct mei_cl *cl)
return -ENOENT;
}
-
-
-/**
- * mei_ioctl_connect_client - the connect to fw client IOCTL function
- *
- * @dev: the device structure
- * @data: IOCTL connect data, input and output parameters
- * @file: private data of the file object
- *
- * Locking: called under "dev->device_lock" lock
- *
- * returns 0 on success, <0 on failure.
- */
-int mei_ioctl_connect_client(struct file *file,
- struct mei_connect_client_data *data)
-{
- struct mei_device *dev;
- struct mei_cl_cb *cb;
- struct mei_client *client;
- struct mei_cl *cl;
- long timeout = mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT);
- int i;
- int err;
- int rets;
-
- cl = file->private_data;
- if (WARN_ON(!cl || !cl->dev))
- return -ENODEV;
-
- dev = cl->dev;
-
- dev_dbg(&dev->pdev->dev, "mei_ioctl_connect_client() Entry\n");
-
- /* buffered ioctl cb */
- cb = mei_io_cb_init(cl, file);
- if (!cb) {
- rets = -ENOMEM;
- goto end;
- }
-
- cb->fop_type = MEI_FOP_IOCTL;
-
- if (dev->dev_state != MEI_DEV_ENABLED) {
- rets = -ENODEV;
- goto end;
- }
- if (cl->state != MEI_FILE_INITIALIZING &&
- cl->state != MEI_FILE_DISCONNECTED) {
- rets = -EBUSY;
- goto end;
- }
-
- /* find ME client we're trying to connect to */
- i = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
- if (i >= 0 && !dev->me_clients[i].props.fixed_address) {
- cl->me_client_id = dev->me_clients[i].client_id;
- cl->state = MEI_FILE_CONNECTING;
- }
-
- dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n",
- cl->me_client_id);
- dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n",
- dev->me_clients[i].props.protocol_version);
- dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n",
- dev->me_clients[i].props.max_msg_length);
-
- /* if we're connecting to amthi client then we will use the
- * existing connection
- */
- if (uuid_le_cmp(data->in_client_uuid, mei_amthi_guid) == 0) {
- dev_dbg(&dev->pdev->dev, "FW Client is amthi\n");
- if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) {
- rets = -ENODEV;
- goto end;
- }
- clear_bit(cl->host_client_id, dev->host_clients_map);
- mei_cl_unlink(cl);
-
- kfree(cl);
- cl = NULL;
- file->private_data = &dev->iamthif_cl;
-
- client = &data->out_client_properties;
- client->max_msg_length =
- dev->me_clients[i].props.max_msg_length;
- client->protocol_version =
- dev->me_clients[i].props.protocol_version;
- rets = dev->iamthif_cl.status;
-
- goto end;
- }
-
- if (cl->state != MEI_FILE_CONNECTING) {
- rets = -ENODEV;
- goto end;
- }
-
-
- /* prepare the output buffer */
- client = &data->out_client_properties;
- client->max_msg_length = dev->me_clients[i].props.max_msg_length;
- client->protocol_version = dev->me_clients[i].props.protocol_version;
- dev_dbg(&dev->pdev->dev, "Can connect?\n");
- if (dev->mei_host_buffer_is_empty &&
- !mei_cl_is_other_connecting(cl)) {
- dev_dbg(&dev->pdev->dev, "Sending Connect Message\n");
- dev->mei_host_buffer_is_empty = false;
- if (mei_hbm_cl_connect_req(dev, cl)) {
- dev_dbg(&dev->pdev->dev, "Sending connect message - failed\n");
- rets = -ENODEV;
- goto end;
- } else {
- dev_dbg(&dev->pdev->dev, "Sending connect message - succeeded\n");
- cl->timer_count = MEI_CONNECT_TIMEOUT;
- list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
- }
-
-
- } else {
- dev_dbg(&dev->pdev->dev, "Queuing the connect request due to device busy\n");
- dev_dbg(&dev->pdev->dev, "add connect cb to control write list.\n");
- list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
- }
- mutex_unlock(&dev->device_lock);
- err = wait_event_timeout(dev->wait_recvd_msg,
- (MEI_FILE_CONNECTED == cl->state ||
- MEI_FILE_DISCONNECTED == cl->state), timeout);
-
- mutex_lock(&dev->device_lock);
- if (MEI_FILE_CONNECTED == cl->state) {
- dev_dbg(&dev->pdev->dev, "successfully connected to FW client.\n");
- rets = cl->status;
- goto end;
- } else {
- dev_dbg(&dev->pdev->dev, "failed to connect to FW client.cl->state = %d.\n",
- cl->state);
- if (!err) {
- dev_dbg(&dev->pdev->dev,
- "wait_event_interruptible_timeout failed on client"
- " connect message fw response message.\n");
- }
- rets = -EFAULT;
-
- mei_io_list_flush(&dev->ctrl_rd_list, cl);
- mei_io_list_flush(&dev->ctrl_wr_list, cl);
- goto end;
- }
- rets = 0;
-end:
- dev_dbg(&dev->pdev->dev, "free connect cb memory.");
- mei_io_cb_free(cb);
- return rets;
-}
-
/**
* mei_cl_start_read - the start read client message function.
*
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 95f05d9..8d3c134 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -562,6 +562,103 @@ err:
return rets;
}
+/**
+ * mei_ioctl_connect_client - the connect to fw client IOCTL function
+ *
+ * @dev: the device structure
+ * @data: IOCTL connect data, input and output parameters
+ * @file: private data of the file object
+ *
+ * Locking: called under "dev->device_lock" lock
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int mei_ioctl_connect_client(struct file *file,
+ struct mei_connect_client_data *data)
+{
+ struct mei_device *dev;
+ struct mei_client *client;
+ struct mei_cl *cl;
+ int i;
+ int rets;
+
+ cl = file->private_data;
+ if (WARN_ON(!cl || !cl->dev))
+ return -ENODEV;
+
+ dev = cl->dev;
+
+ if (dev->dev_state != MEI_DEV_ENABLED) {
+ rets = -ENODEV;
+ goto end;
+ }
+
+ if (cl->state != MEI_FILE_INITIALIZING &&
+ cl->state != MEI_FILE_DISCONNECTED) {
+ rets = -EBUSY;
+ goto end;
+ }
+
+ /* find ME client we're trying to connect to */
+ i = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
+ if (i >= 0 && !dev->me_clients[i].props.fixed_address) {
+ cl->me_client_id = dev->me_clients[i].client_id;
+ cl->state = MEI_FILE_CONNECTING;
+ }
+
+ dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n",
+ cl->me_client_id);
+ dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n",
+ dev->me_clients[i].props.protocol_version);
+ dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n",
+ dev->me_clients[i].props.max_msg_length);
+
+ /* if we're connecting to amthi client then we will use the
+ * existing connection
+ */
+ if (uuid_le_cmp(data->in_client_uuid, mei_amthi_guid) == 0) {
+ dev_dbg(&dev->pdev->dev, "FW Client is amthi\n");
+ if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) {
+ rets = -ENODEV;
+ goto end;
+ }
+ clear_bit(cl->host_client_id, dev->host_clients_map);
+ mei_cl_unlink(cl);
+
+ kfree(cl);
+ cl = NULL;
+ file->private_data = &dev->iamthif_cl;
+
+ client = &data->out_client_properties;
+ client->max_msg_length =
+ dev->me_clients[i].props.max_msg_length;
+ client->protocol_version =
+ dev->me_clients[i].props.protocol_version;
+ rets = dev->iamthif_cl.status;
+
+ goto end;
+ }
+
+ if (cl->state != MEI_FILE_CONNECTING) {
+ rets = -ENODEV;
+ goto end;
+ }
+
+
+ /* prepare the output buffer */
+ client = &data->out_client_properties;
+ client->max_msg_length = dev->me_clients[i].props.max_msg_length;
+ client->protocol_version = dev->me_clients[i].props.protocol_version;
+ dev_dbg(&dev->pdev->dev, "Can connect?\n");
+
+
+ rets = mei_cl_connect(cl, file);
+
+end:
+ dev_dbg(&dev->pdev->dev, "free connect cb memory.");
+ return rets;
+}
+
/**
* mei_ioctl - the IOCTL function
@@ -610,6 +707,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
rets = -EFAULT;
goto out;
}
+
rets = mei_ioctl_connect_client(file, connect_data);
/* if all is ok, copying the data back to user. */
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 5a1ac9a..f3da153 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -341,11 +341,6 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id);
void mei_timer(struct work_struct *work);
/*
- * MEI input output function prototype
- */
-int mei_ioctl_connect_client(struct file *file,
- struct mei_connect_client_data *data);
-/*
* AMTHIF - AMT Host Interface Functions
*/
void mei_amthif_reset_params(struct mei_device *dev);
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 05/21] mei: move watchdog prototypes to mei_dev.h from interface.h
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (3 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 04/21] mei: implement mei_cl_connect function Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 06/21] mei: rename interface to hw-me Tomas Winkler
` (15 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
interface.h contains lower layer functionality
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/interface.h | 20 --------------------
drivers/misc/mei/mei_dev.h | 17 +++++++++++++++++
2 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h
index 01d1ef5..73bef54 100644
--- a/drivers/misc/mei/interface.h
+++ b/drivers/misc/mei/interface.h
@@ -49,24 +49,4 @@ static inline unsigned char mei_data2slots(size_t length)
int mei_count_full_read_slots(struct mei_device *dev);
-
-
-
-
-int mei_wd_send(struct mei_device *dev);
-int mei_wd_stop(struct mei_device *dev);
-int mei_wd_host_init(struct mei_device *dev);
-/*
- * mei_watchdog_register - Registering watchdog interface
- * once we got connection to the WD Client
- * @dev - mei device
- */
-void mei_watchdog_register(struct mei_device *dev);
-/*
- * mei_watchdog_unregister - Unregistering watchdog interface
- * @dev - mei device
- */
-void mei_watchdog_unregister(struct mei_device *dev);
-
-
#endif /* _MEI_INTERFACE_H_ */
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index f3da153..d41177b 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -371,6 +371,23 @@ int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
struct mei_device *dev, struct mei_msg_hdr *mei_hdr);
int mei_amthif_irq_read(struct mei_device *dev, s32 *slots);
+
+int mei_wd_send(struct mei_device *dev);
+int mei_wd_stop(struct mei_device *dev);
+int mei_wd_host_init(struct mei_device *dev);
+/*
+ * mei_watchdog_register - Registering watchdog interface
+ * once we got connection to the WD Client
+ * @dev - mei device
+ */
+void mei_watchdog_register(struct mei_device *dev);
+/*
+ * mei_watchdog_unregister - Unregistering watchdog interface
+ * @dev - mei device
+ */
+void mei_watchdog_unregister(struct mei_device *dev);
+
+
/*
* Register Access Function
*/
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 06/21] mei: rename interface to hw-me
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (4 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 05/21] mei: move watchdog prototypes to mei_dev.h from interface.h Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 07/21] mei: drop read_pending member form struct mei_cl Tomas Winkler
` (14 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
Rename hw-me.h to hw-me-regs.h as this file
contains only register definitions.
Files hw-me.[ch] now contains ME hw dependant
functionality
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/Makefile | 2 +-
drivers/misc/mei/amthif.c | 2 +-
drivers/misc/mei/client.c | 1 -
drivers/misc/mei/hbm.c | 2 +-
drivers/misc/mei/hw-me-regs.h | 167 ++++++++++++++++++++++++++
drivers/misc/mei/{interface.c => hw-me.c} | 2 +-
drivers/misc/mei/hw-me.h | 181 +++++-----------------------
drivers/misc/mei/init.c | 1 -
drivers/misc/mei/interface.h | 52 --------
drivers/misc/mei/interrupt.c | 2 +-
drivers/misc/mei/main.c | 2 +-
drivers/misc/mei/mei_dev.h | 2 +-
drivers/misc/mei/wd.c | 2 +-
13 files changed, 208 insertions(+), 210 deletions(-)
create mode 100644 drivers/misc/mei/hw-me-regs.h
rename drivers/misc/mei/{interface.c => hw-me.c} (99%)
delete mode 100644 drivers/misc/mei/interface.h
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index 67f543a..9f71933 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_INTEL_MEI) += mei.o
mei-objs := init.o
mei-objs += hbm.o
mei-objs += interrupt.o
-mei-objs += interface.o
+mei-objs += hw-me.o
mei-objs += main.o
mei-objs += amthif.o
mei-objs += wd.o
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index cbc9c4e..adc4120 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -35,7 +35,7 @@
#include "mei_dev.h"
#include "hbm.h"
-#include "interface.h"
+#include "hw-me.h"
#include "client.h"
const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac,
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index cc3e76c..e2e9cb7 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -23,7 +23,6 @@
#include "mei_dev.h"
#include "hbm.h"
-#include "interface.h"
#include "client.h"
/**
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 9956aaf..f0c3fc4 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -21,7 +21,7 @@
#include "mei_dev.h"
#include "hbm.h"
-#include "interface.h"
+#include "hw-me.h"
/**
* mei_hbm_cl_hdr - construct client hbm header
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
new file mode 100644
index 0000000..6a203b6
--- /dev/null
+++ b/drivers/misc/mei/hw-me-regs.h
@@ -0,0 +1,167 @@
+/******************************************************************************
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Intel MEI Interface Header
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation.
+ * linux-mei@linux.intel.com
+ * http://www.intel.com
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#ifndef _MEI_HW_MEI_REGS_H_
+#define _MEI_HW_MEI_REGS_H_
+
+/*
+ * MEI device IDs
+ */
+#define MEI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */
+#define MEI_DEV_ID_82G35 0x2984 /* 82G35 Express */
+#define MEI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */
+#define MEI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */
+
+#define MEI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */
+#define MEI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */
+
+#define MEI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */
+#define MEI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */
+#define MEI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */
+#define MEI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */
+#define MEI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */
+
+#define MEI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */
+#define MEI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */
+#define MEI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */
+#define MEI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */
+#define MEI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */
+
+#define MEI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */
+#define MEI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */
+#define MEI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */
+#define MEI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */
+
+#define MEI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */
+#define MEI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */
+#define MEI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */
+#define MEI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */
+
+#define MEI_DEV_ID_IBXPK_1 0x3B64 /* Calpella */
+#define MEI_DEV_ID_IBXPK_2 0x3B65 /* Calpella */
+
+#define MEI_DEV_ID_CPT_1 0x1C3A /* Couger Point */
+#define MEI_DEV_ID_PBG_1 0x1D3A /* C600/X79 Patsburg */
+
+#define MEI_DEV_ID_PPT_1 0x1E3A /* Panther Point */
+#define MEI_DEV_ID_PPT_2 0x1CBA /* Panther Point */
+#define MEI_DEV_ID_PPT_3 0x1DBA /* Panther Point */
+
+#define MEI_DEV_ID_LPT 0x8C3A /* Lynx Point */
+#define MEI_DEV_ID_LPT_LP 0x9C3A /* Lynx Point LP */
+/*
+ * MEI HW Section
+ */
+
+/* MEI registers */
+/* H_CB_WW - Host Circular Buffer (CB) Write Window register */
+#define H_CB_WW 0
+/* H_CSR - Host Control Status register */
+#define H_CSR 4
+/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */
+#define ME_CB_RW 8
+/* ME_CSR_HA - ME Control Status Host Access register (read only) */
+#define ME_CSR_HA 0xC
+
+
+/* register bits of H_CSR (Host Control Status register) */
+/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */
+#define H_CBD 0xFF000000
+/* Host Circular Buffer Write Pointer */
+#define H_CBWP 0x00FF0000
+/* Host Circular Buffer Read Pointer */
+#define H_CBRP 0x0000FF00
+/* Host Reset */
+#define H_RST 0x00000010
+/* Host Ready */
+#define H_RDY 0x00000008
+/* Host Interrupt Generate */
+#define H_IG 0x00000004
+/* Host Interrupt Status */
+#define H_IS 0x00000002
+/* Host Interrupt Enable */
+#define H_IE 0x00000001
+
+
+/* register bits of ME_CSR_HA (ME Control Status Host Access register) */
+/* ME CB (Circular Buffer) Depth HRA (Host Read Access) - host read only
+access to ME_CBD */
+#define ME_CBD_HRA 0xFF000000
+/* ME CB Write Pointer HRA - host read only access to ME_CBWP */
+#define ME_CBWP_HRA 0x00FF0000
+/* ME CB Read Pointer HRA - host read only access to ME_CBRP */
+#define ME_CBRP_HRA 0x0000FF00
+/* ME Reset HRA - host read only access to ME_RST */
+#define ME_RST_HRA 0x00000010
+/* ME Ready HRA - host read only access to ME_RDY */
+#define ME_RDY_HRA 0x00000008
+/* ME Interrupt Generate HRA - host read only access to ME_IG */
+#define ME_IG_HRA 0x00000004
+/* ME Interrupt Status HRA - host read only access to ME_IS */
+#define ME_IS_HRA 0x00000002
+/* ME Interrupt Enable HRA - host read only access to ME_IE */
+#define ME_IE_HRA 0x00000001
+
+#endif /* _MEI_HW_MEI_REGS_H_ */
diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/hw-me.c
similarity index 99%
rename from drivers/misc/mei/interface.c
rename to drivers/misc/mei/hw-me.c
index 3cb0cff..4e6b657 100644
--- a/drivers/misc/mei/interface.c
+++ b/drivers/misc/mei/hw-me.c
@@ -18,7 +18,7 @@
#include <linux/mei.h>
#include "mei_dev.h"
-#include "interface.h"
+#include "hw-me.h"
/**
* mei_reg_read - Reads 32bit data from the mei device
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
index a42b2a2..73bef54 100644
--- a/drivers/misc/mei/hw-me.h
+++ b/drivers/misc/mei/hw-me.h
@@ -1,167 +1,52 @@
-/******************************************************************************
- * Intel Management Engine Interface (Intel MEI) Linux driver
- * Intel MEI Interface Header
- *
- * This file is provided under a dual BSD/GPLv2 license. When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- * Intel Corporation.
- * linux-mei@linux.intel.com
- * http://www.intel.com
- *
- * BSD LICENSE
- *
- * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
- * All rights reserved.
+/*
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2012, Intel Corporation.
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
*
- *****************************************************************************/
-#ifndef _MEI_HW_MEI_H_
-#define _MEI_HW_MEI_H_
-
-/*
- * MEI device IDs
*/
-#define MEI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */
-#define MEI_DEV_ID_82G35 0x2984 /* 82G35 Express */
-#define MEI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */
-#define MEI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */
-
-#define MEI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */
-#define MEI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */
-#define MEI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */
-#define MEI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */
-#define MEI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */
-#define MEI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */
-#define MEI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */
-#define MEI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */
-#define MEI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */
-#define MEI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */
-#define MEI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */
-#define MEI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */
-#define MEI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */
-#define MEI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */
-#define MEI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */
-#define MEI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */
+#ifndef _MEI_INTERFACE_H_
+#define _MEI_INTERFACE_H_
-#define MEI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */
-#define MEI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */
-#define MEI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */
-#define MEI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */
+#include <linux/mei.h>
+#include "mei_dev.h"
-#define MEI_DEV_ID_IBXPK_1 0x3B64 /* Calpella */
-#define MEI_DEV_ID_IBXPK_2 0x3B65 /* Calpella */
-#define MEI_DEV_ID_CPT_1 0x1C3A /* Couger Point */
-#define MEI_DEV_ID_PBG_1 0x1D3A /* C600/X79 Patsburg */
-#define MEI_DEV_ID_PPT_1 0x1E3A /* Panther Point */
-#define MEI_DEV_ID_PPT_2 0x1CBA /* Panther Point */
-#define MEI_DEV_ID_PPT_3 0x1DBA /* Panther Point */
+void mei_read_slots(struct mei_device *dev,
+ unsigned char *buffer,
+ unsigned long buffer_length);
-#define MEI_DEV_ID_LPT 0x8C3A /* Lynx Point */
-#define MEI_DEV_ID_LPT_LP 0x9C3A /* Lynx Point LP */
-/*
- * MEI HW Section
- */
+int mei_write_message(struct mei_device *dev,
+ struct mei_msg_hdr *header,
+ unsigned char *buf);
-/* MEI registers */
-/* H_CB_WW - Host Circular Buffer (CB) Write Window register */
-#define H_CB_WW 0
-/* H_CSR - Host Control Status register */
-#define H_CSR 4
-/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */
-#define ME_CB_RW 8
-/* ME_CSR_HA - ME Control Status Host Access register (read only) */
-#define ME_CSR_HA 0xC
+bool mei_hbuf_is_empty(struct mei_device *dev);
+int mei_hbuf_empty_slots(struct mei_device *dev);
-/* register bits of H_CSR (Host Control Status register) */
-/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */
-#define H_CBD 0xFF000000
-/* Host Circular Buffer Write Pointer */
-#define H_CBWP 0x00FF0000
-/* Host Circular Buffer Read Pointer */
-#define H_CBRP 0x0000FF00
-/* Host Reset */
-#define H_RST 0x00000010
-/* Host Ready */
-#define H_RDY 0x00000008
-/* Host Interrupt Generate */
-#define H_IG 0x00000004
-/* Host Interrupt Status */
-#define H_IS 0x00000002
-/* Host Interrupt Enable */
-#define H_IE 0x00000001
+static inline size_t mei_hbuf_max_data(const struct mei_device *dev)
+{
+ return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr);
+}
+/* get slots (dwords) from a message length + header (bytes) */
+static inline unsigned char mei_data2slots(size_t length)
+{
+ return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
+}
-/* register bits of ME_CSR_HA (ME Control Status Host Access register) */
-/* ME CB (Circular Buffer) Depth HRA (Host Read Access) - host read only
-access to ME_CBD */
-#define ME_CBD_HRA 0xFF000000
-/* ME CB Write Pointer HRA - host read only access to ME_CBWP */
-#define ME_CBWP_HRA 0x00FF0000
-/* ME CB Read Pointer HRA - host read only access to ME_CBRP */
-#define ME_CBRP_HRA 0x0000FF00
-/* ME Reset HRA - host read only access to ME_RST */
-#define ME_RST_HRA 0x00000010
-/* ME Ready HRA - host read only access to ME_RDY */
-#define ME_RDY_HRA 0x00000008
-/* ME Interrupt Generate HRA - host read only access to ME_IG */
-#define ME_IG_HRA 0x00000004
-/* ME Interrupt Status HRA - host read only access to ME_IS */
-#define ME_IS_HRA 0x00000002
-/* ME Interrupt Enable HRA - host read only access to ME_IE */
-#define ME_IE_HRA 0x00000001
+int mei_count_full_read_slots(struct mei_device *dev);
-#endif /* _MEI_HW_MEI_H_ */
+#endif /* _MEI_INTERFACE_H_ */
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 7028dbd..88407df 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -22,7 +22,6 @@
#include <linux/mei.h>
#include "mei_dev.h"
-#include "interface.h"
#include "client.h"
const char *mei_dev_state_str(int state)
diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h
deleted file mode 100644
index 73bef54..0000000
--- a/drivers/misc/mei/interface.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- * Intel Management Engine Interface (Intel MEI) Linux driver
- * Copyright (c) 2003-2012, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-
-
-#ifndef _MEI_INTERFACE_H_
-#define _MEI_INTERFACE_H_
-
-#include <linux/mei.h>
-#include "mei_dev.h"
-
-
-
-void mei_read_slots(struct mei_device *dev,
- unsigned char *buffer,
- unsigned long buffer_length);
-
-int mei_write_message(struct mei_device *dev,
- struct mei_msg_hdr *header,
- unsigned char *buf);
-
-bool mei_hbuf_is_empty(struct mei_device *dev);
-
-int mei_hbuf_empty_slots(struct mei_device *dev);
-
-static inline size_t mei_hbuf_max_data(const struct mei_device *dev)
-{
- return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr);
-}
-
-/* get slots (dwords) from a message length + header (bytes) */
-static inline unsigned char mei_data2slots(size_t length)
-{
- return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
-}
-
-int mei_count_full_read_slots(struct mei_device *dev);
-
-#endif /* _MEI_INTERFACE_H_ */
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 0a141af..d1ef926 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -25,7 +25,7 @@
#include "mei_dev.h"
#include "hbm.h"
-#include "interface.h"
+#include "hw-me.h"
#include "client.h"
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 8d3c134..e31ade3 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -40,7 +40,7 @@
#include <linux/mei.h>
#include "mei_dev.h"
-#include "interface.h"
+#include "hw-me.h"
#include "client.h"
/* AMT device is a singleton on the platform */
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index d41177b..87b1f6a 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -23,7 +23,7 @@
#include <linux/mei.h>
#include "hw.h"
-#include "hw-me.h"
+#include "hw-me-regs.h"
/*
* watch dog definition
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index 5ad5225..bfcbcc8 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -25,7 +25,7 @@
#include "mei_dev.h"
#include "hbm.h"
-#include "interface.h"
+#include "hw-me.h"
#include "client.h"
static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 };
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 07/21] mei: drop read_pending member form struct mei_cl
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (5 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 06/21] mei: rename interface to hw-me Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 08/21] mei: move me client storage allocation to hbm.c Tomas Winkler
` (13 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
read_pending never changes, it is a leftover from the old code.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/client.c | 2 +-
drivers/misc/mei/main.c | 4 +---
drivers/misc/mei/mei_dev.h | 1 -
3 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index e2e9cb7..231eda2 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -631,7 +631,7 @@ int mei_cl_read_start(struct mei_cl *cl)
if (dev->dev_state != MEI_DEV_ENABLED)
return -ENODEV;
- if (cl->read_pending || cl->read_cb) {
+ if (cl->read_cb) {
dev_dbg(&dev->pdev->dev, "read is pending.\n");
return -EBUSY;
}
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index e31ade3..5c7c855 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -380,7 +380,6 @@ free:
mei_io_cb_free(cb);
cl->reading_state = MEI_IDLE;
cl->read_cb = NULL;
- cl->read_pending = 0;
out:
dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets);
mutex_unlock(&dev->device_lock);
@@ -462,9 +461,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
write_cb = NULL;
cl->reading_state = MEI_IDLE;
cl->read_cb = NULL;
- cl->read_pending = 0;
}
- } else if (cl->reading_state == MEI_IDLE && !cl->read_pending)
+ } else if (cl->reading_state == MEI_IDLE)
*offset = 0;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 87b1f6a..11ff875 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -199,7 +199,6 @@ struct mei_cl {
wait_queue_head_t tx_wait;
wait_queue_head_t rx_wait;
wait_queue_head_t wait;
- int read_pending;
int status;
/* ID of client connected */
u8 host_client_id;
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 08/21] mei: move me client storage allocation to hbm.c
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (6 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 07/21] mei: drop read_pending member form struct mei_cl Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 09/21] mei: mei_dev.h - remove prototypes of dropped functions Tomas Winkler
` (12 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
rename function to mei_me_cl_allocate to match the current
names convention: mei_hbm_me_cl_allocate
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hbm.c | 39 ++++++++++++++++++++++++++++++++++++++-
drivers/misc/mei/init.c | 39 ---------------------------------------
drivers/misc/mei/mei_dev.h | 1 -
3 files changed, 38 insertions(+), 41 deletions(-)
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index f0c3fc4..fb9e63b 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -24,6 +24,43 @@
#include "hw-me.h"
/**
+ * mei_hbm_me_cl_allocate - allocates storage for me clients
+ *
+ * @dev: the device structure
+ *
+ * returns none.
+ */
+static void mei_hbm_me_cl_allocate(struct mei_device *dev)
+{
+ struct mei_me_client *clients;
+ int b;
+
+ /* count how many ME clients we have */
+ for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX)
+ dev->me_clients_num++;
+
+ if (dev->me_clients_num <= 0)
+ return;
+
+ kfree(dev->me_clients);
+ dev->me_clients = NULL;
+
+ dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n",
+ dev->me_clients_num * sizeof(struct mei_me_client));
+ /* allocate storage for ME clients representation */
+ clients = kcalloc(dev->me_clients_num,
+ sizeof(struct mei_me_client), GFP_KERNEL);
+ if (!clients) {
+ dev_err(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
+ dev->dev_state = MEI_DEV_RESETING;
+ mei_reset(dev, 1);
+ return;
+ }
+ dev->me_clients = clients;
+ return;
+}
+
+/**
* mei_hbm_cl_hdr - construct client hbm header
* @cl: - client
* @hbm_cmd: host bus message command
@@ -593,7 +630,7 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
dev->init_clients_timer = 0;
dev->me_client_presentation_num = 0;
dev->me_client_index = 0;
- mei_allocate_me_clients_storage(dev);
+ mei_hbm_me_cl_allocate(dev);
dev->init_clients_state =
MEI_CLIENT_PROPERTIES_MESSAGE;
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 88407df..636639f 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -278,44 +278,5 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
}
-/**
- * allocate_me_clients_storage - allocates storage for me clients
- *
- * @dev: the device structure
- *
- * returns none.
- */
-void mei_allocate_me_clients_storage(struct mei_device *dev)
-{
- struct mei_me_client *clients;
- int b;
-
- /* count how many ME clients we have */
- for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX)
- dev->me_clients_num++;
-
- if (dev->me_clients_num <= 0)
- return ;
-
-
- if (dev->me_clients != NULL) {
- kfree(dev->me_clients);
- dev->me_clients = NULL;
- }
- dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n",
- dev->me_clients_num * sizeof(struct mei_me_client));
- /* allocate storage for ME clients representation */
- clients = kcalloc(dev->me_clients_num,
- sizeof(struct mei_me_client), GFP_KERNEL);
- if (!clients) {
- dev_dbg(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
- dev->dev_state = MEI_DEV_RESETING;
- mei_reset(dev, 1);
- return ;
- }
- dev->me_clients = clients;
- return ;
-}
-
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 11ff875..d07d81f 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -328,7 +328,6 @@ void mei_reset(struct mei_device *dev, int interrupts);
int mei_hw_init(struct mei_device *dev);
int mei_task_initialize_clients(void *data);
int mei_initialize_clients(struct mei_device *dev);
-void mei_allocate_me_clients_storage(struct mei_device *dev);
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 09/21] mei: mei_dev.h - remove prototypes of dropped functions
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (7 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 08/21] mei: move me client storage allocation to hbm.c Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 10/21] mei: rename remaining amthi strings to amthif Tomas Winkler
` (11 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
mei_task_initialize_clients and mei_initialize_clients
are no longer among us
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/mei_dev.h | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index d07d81f..681c0ee 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -326,10 +326,6 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
struct mei_device *mei_device_init(struct pci_dev *pdev);
void mei_reset(struct mei_device *dev, int interrupts);
int mei_hw_init(struct mei_device *dev);
-int mei_task_initialize_clients(void *data);
-int mei_initialize_clients(struct mei_device *dev);
-
-
/*
* MEI interrupt functions prototype
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 10/21] mei: rename remaining amthi strings to amthif
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (8 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 09/21] mei: mei_dev.h - remove prototypes of dropped functions Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 11/21] mei: normalize me host client linking routines Tomas Winkler
` (10 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
the only real thing that left was mei_amthi_guid
the rest was in the strings and comments
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/amthif.c | 62 ++++++++++++++++++++++----------------------
drivers/misc/mei/client.c | 2 +-
drivers/misc/mei/main.c | 6 ++--
drivers/misc/mei/mei_dev.h | 2 +-
4 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index adc4120..64a9bfa 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -38,9 +38,9 @@
#include "hw-me.h"
#include "client.h"
-const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac,
- 0xa8, 0x46, 0xe0, 0xff, 0x65,
- 0x81, 0x4c);
+const uuid_le mei_amthif_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d,
+ 0xac, 0xa8, 0x46, 0xe0,
+ 0xff, 0x65, 0x81, 0x4c);
/**
* mei_amthif_reset_params - initializes mei device iamthif
@@ -73,9 +73,9 @@ void mei_amthif_host_init(struct mei_device *dev)
mei_cl_init(&dev->iamthif_cl, dev);
dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
- /* find ME amthi client */
+ /* find ME amthif client */
i = mei_cl_link_me(&dev->iamthif_cl,
- &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
+ &mei_amthif_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
if (i < 0) {
dev_info(&dev->pdev->dev, "failed to find iamthif client.\n");
return;
@@ -169,10 +169,10 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id);
if (i < 0) {
- dev_dbg(&dev->pdev->dev, "amthi client not found.\n");
+ dev_dbg(&dev->pdev->dev, "amthif client not found.\n");
return -ENODEV;
}
- dev_dbg(&dev->pdev->dev, "checking amthi data\n");
+ dev_dbg(&dev->pdev->dev, "checking amthif data\n");
cb = mei_amthif_find_read_list_entry(dev, file);
/* Check for if we can block or not*/
@@ -180,7 +180,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
return -EAGAIN;
- dev_dbg(&dev->pdev->dev, "waiting for amthi data\n");
+ dev_dbg(&dev->pdev->dev, "waiting for amthif data\n");
while (cb == NULL) {
/* unlock the Mutex */
mutex_unlock(&dev->device_lock);
@@ -198,17 +198,17 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
}
- dev_dbg(&dev->pdev->dev, "Got amthi data\n");
+ dev_dbg(&dev->pdev->dev, "Got amthif data\n");
dev->iamthif_timer = 0;
if (cb) {
timeout = cb->read_time +
mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
- dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n",
+ dev_dbg(&dev->pdev->dev, "amthif timeout = %lud\n",
timeout);
if (time_after(jiffies, timeout)) {
- dev_dbg(&dev->pdev->dev, "amthi Time out\n");
+ dev_dbg(&dev->pdev->dev, "amthif Time out\n");
/* 15 sec for the message has expired */
list_del(&cb->list);
rets = -ETIMEDOUT;
@@ -228,9 +228,9 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
* remove message from deletion list
*/
- dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n",
+ dev_dbg(&dev->pdev->dev, "amthif cb->response_buffer size - %d\n",
cb->response_buffer.size);
- dev_dbg(&dev->pdev->dev, "amthi cb->buf_idx - %lu\n", cb->buf_idx);
+ dev_dbg(&dev->pdev->dev, "amthif cb->buf_idx - %lu\n", cb->buf_idx);
/* length is being turncated to PAGE_SIZE, however,
* the buf_idx may point beyond */
@@ -246,7 +246,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
}
}
free:
- dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n");
+ dev_dbg(&dev->pdev->dev, "free amthif cb memory.\n");
*offset = 0;
mei_io_cb_free(cb);
out:
@@ -270,7 +270,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
if (!dev || !cb)
return -ENODEV;
- dev_dbg(&dev->pdev->dev, "write data to amthi client.\n");
+ dev_dbg(&dev->pdev->dev, "write data to amthif client.\n");
dev->iamthif_state = MEI_IAMTHIF_WRITING;
dev->iamthif_current_cb = cb;
@@ -309,12 +309,12 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
return -ENODEV;
dev->iamthif_flow_control_pending = true;
dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
- dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n");
+ dev_dbg(&dev->pdev->dev, "add amthif cb to write waiting list\n");
dev->iamthif_current_cb = cb;
dev->iamthif_file_object = cb->file_object;
list_add_tail(&cb->list, &dev->write_waiting_list.list);
} else {
- dev_dbg(&dev->pdev->dev, "message does not complete, so add amthi cb to write list.\n");
+ dev_dbg(&dev->pdev->dev, "message does not complete, so add amthif cb to write list.\n");
list_add_tail(&cb->list, &dev->write_list.list);
}
} else {
@@ -383,7 +383,7 @@ void mei_amthif_run_next_cmd(struct mei_device *dev)
dev->iamthif_timer = 0;
dev->iamthif_file_object = NULL;
- dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n");
+ dev_dbg(&dev->pdev->dev, "complete amthif cmd_list cb.\n");
list_for_each_entry_safe(pos, next, &dev->amthif_cmd_list.list, list) {
list_del(&pos->list);
@@ -392,7 +392,7 @@ void mei_amthif_run_next_cmd(struct mei_device *dev)
status = mei_amthif_send_cmd(dev, pos);
if (status) {
dev_dbg(&dev->pdev->dev,
- "amthi write failed status = %d\n",
+ "amthif write failed status = %d\n",
status);
return;
}
@@ -412,7 +412,7 @@ unsigned int mei_amthif_poll(struct mei_device *dev,
if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE &&
dev->iamthif_file_object == file) {
mask |= (POLLIN | POLLRDNORM);
- dev_dbg(&dev->pdev->dev, "run next amthi cb\n");
+ dev_dbg(&dev->pdev->dev, "run next amthif cb\n");
mei_amthif_run_next_cmd(dev);
}
return mask;
@@ -478,7 +478,7 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
dev->iamthif_flow_control_pending = true;
- /* save iamthif cb sent to amthi client */
+ /* save iamthif cb sent to amthif client */
cb->buf_idx = dev->iamthif_msg_buf_index;
dev->iamthif_current_cb = cb;
@@ -491,11 +491,11 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
/**
* mei_amthif_irq_read_message - read routine after ISR to
- * handle the read amthi message
+ * handle the read amthif message
*
* @complete_list: An instance of our list structure
* @dev: the device structure
- * @mei_hdr: header of amthi message
+ * @mei_hdr: header of amthif message
*
* returns 0 on success, <0 on failure.
*/
@@ -519,10 +519,10 @@ int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
return 0;
dev_dbg(&dev->pdev->dev,
- "amthi_message_buffer_index =%d\n",
+ "amthif_message_buffer_index =%d\n",
mei_hdr->length);
- dev_dbg(&dev->pdev->dev, "completed amthi read.\n ");
+ dev_dbg(&dev->pdev->dev, "completed amthif read.\n ");
if (!dev->iamthif_current_cb)
return -ENODEV;
@@ -537,8 +537,8 @@ int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
cb->read_time = jiffies;
if (dev->iamthif_ioctl && cb->cl == &dev->iamthif_cl) {
/* found the iamthif cb */
- dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n ");
- dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n ");
+ dev_dbg(&dev->pdev->dev, "complete the amthif read cb.\n ");
+ dev_dbg(&dev->pdev->dev, "add the amthif read cb to complete.\n ");
list_add_tail(&cb->list, &complete_list->list);
}
return 0;
@@ -590,7 +590,7 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
dev->iamthif_msg_buf,
dev->iamthif_msg_buf_index);
list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list);
- dev_dbg(&dev->pdev->dev, "amthi read completed\n");
+ dev_dbg(&dev->pdev->dev, "amthif read completed\n");
dev->iamthif_timer = jiffies;
dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
dev->iamthif_timer);
@@ -598,7 +598,7 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
mei_amthif_run_next_cmd(dev);
}
- dev_dbg(&dev->pdev->dev, "completing amthi call back.\n");
+ dev_dbg(&dev->pdev->dev, "completing amthif call back.\n");
wake_up_interruptible(&dev->iamthif_cl.wait);
}
@@ -704,11 +704,11 @@ int mei_amthif_release(struct mei_device *dev, struct file *file)
if (dev->iamthif_file_object == file &&
dev->iamthif_state != MEI_IAMTHIF_IDLE) {
- dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n",
+ dev_dbg(&dev->pdev->dev, "amthif canceled iamthif state %d\n",
dev->iamthif_state);
dev->iamthif_canceled = true;
if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) {
- dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n");
+ dev_dbg(&dev->pdev->dev, "run next amthif iamthif cb\n");
mei_amthif_run_next_cmd(dev);
}
}
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 231eda2..8103d94 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -345,7 +345,7 @@ void mei_host_client_init(struct work_struct *work)
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))
+ if (!uuid_le_cmp(client_props->protocol_name, mei_amthif_guid))
mei_amthif_host_init(dev);
else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid))
mei_wd_host_init(dev);
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 5c7c855..d5d1a59 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -497,7 +497,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
if (rets) {
dev_err(&dev->pdev->dev,
- "amthi write failed with status = %d\n", rets);
+ "amthif write failed with status = %d\n", rets);
goto err;
}
mutex_unlock(&dev->device_lock);
@@ -611,10 +611,10 @@ static int mei_ioctl_connect_client(struct file *file,
dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n",
dev->me_clients[i].props.max_msg_length);
- /* if we're connecting to amthi client then we will use the
+ /* if we're connecting to amthif client then we will use the
* existing connection
*/
- if (uuid_le_cmp(data->in_client_uuid, mei_amthi_guid) == 0) {
+ if (uuid_le_cmp(data->in_client_uuid, mei_amthif_guid) == 0) {
dev_dbg(&dev->pdev->dev, "FW Client is amthi\n");
if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) {
rets = -ENODEV;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 681c0ee..285e8e0 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -46,7 +46,7 @@
/*
* AMTHI Client UUID
*/
-extern const uuid_le mei_amthi_guid;
+extern const uuid_le mei_amthif_guid;
/*
* Watchdog Client UUID
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 11/21] mei: normalize me host client linking routines
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (9 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 10/21] mei: rename remaining amthi strings to amthif Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 12/21] mei: move MEI_IAMTHIF_IDLE to amthif host init function Tomas Winkler
` (9 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
In order we can use the same code pattern for in-kernel
and user space host clients we replace mei_cl_link_to_me
with mei_cl_link function.
We then have to keep me client lookupout of the new link function.
The unlinking cannot be yet symetric due to amthif connection
handling
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/amthif.c | 42 +++++++++++++++++++++-------------
drivers/misc/mei/client.c | 53 ++++++++++++++++++++++++-------------------
drivers/misc/mei/client.h | 2 +-
drivers/misc/mei/init.c | 4 +++
drivers/misc/mei/main.c | 27 +++++++---------------
drivers/misc/mei/mei_dev.h | 10 ++++----
drivers/misc/mei/wd.c | 35 +++++++++++++++++++----------
7 files changed, 98 insertions(+), 75 deletions(-)
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 64a9bfa..88e6aa0 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -65,22 +65,22 @@ void mei_amthif_reset_params(struct mei_device *dev)
* @dev: the device structure
*
*/
-void mei_amthif_host_init(struct mei_device *dev)
+int mei_amthif_host_init(struct mei_device *dev)
{
- int i;
+ struct mei_cl *cl = &dev->iamthif_cl;
unsigned char *msg_buf;
+ int ret, i;
- mei_cl_init(&dev->iamthif_cl, dev);
- dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
+ mei_cl_init(cl, dev);
- /* find ME amthif client */
- i = mei_cl_link_me(&dev->iamthif_cl,
- &mei_amthif_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
+ i = mei_me_cl_by_uuid(dev, &mei_amthif_guid);
if (i < 0) {
- dev_info(&dev->pdev->dev, "failed to find iamthif client.\n");
- return;
+ dev_info(&dev->pdev->dev, "amthif: failed to find the client\n");
+ return -ENOENT;
}
+ cl->me_client_id = dev->me_clients[i].client_id;
+
/* Assign iamthif_mtu to the value received from ME */
dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length;
@@ -94,19 +94,29 @@ void mei_amthif_host_init(struct mei_device *dev)
msg_buf = kcalloc(dev->iamthif_mtu,
sizeof(unsigned char), GFP_KERNEL);
if (!msg_buf) {
- dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n");
- return;
+ dev_err(&dev->pdev->dev, "amthif: memory allocation for ME message buffer failed.\n");
+ return -ENOMEM;
}
dev->iamthif_msg_buf = msg_buf;
- if (mei_hbm_cl_connect_req(dev, &dev->iamthif_cl)) {
- dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n");
- dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
- dev->iamthif_cl.host_client_id = 0;
+ ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID);
+
+ if (ret < 0) {
+ dev_err(&dev->pdev->dev, "amthif: failed link client\n");
+ return -ENOENT;
+ }
+
+ cl->state = MEI_FILE_CONNECTING;
+
+ if (mei_hbm_cl_connect_req(dev, cl)) {
+ dev_dbg(&dev->pdev->dev, "amthif: Failed to connect to ME client\n");
+ cl->state = MEI_FILE_DISCONNECTED;
+ cl->host_client_id = 0;
} else {
- dev->iamthif_cl.timer_count = MEI_CONNECT_TIMEOUT;
+ cl->timer_count = MEI_CONNECT_TIMEOUT;
}
+ return 0;
}
/**
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 8103d94..d566dd8 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -258,54 +258,61 @@ struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl)
return NULL;
}
-
-/**
- * mei_me_cl_link - create link between host and me clinet and add
- * me_cl to the list
- *
- * @cl: link between me and host client assocated with opened file descriptor
- * @uuid: uuid of ME client
- * @client_id: id of the host client
+/** mei_cl_link: allocte host id in the host map
*
- * returns ME client index if ME client
+ * @cl - host client
+ * @id - fixed host id or -1 for genereting one
+ * returns 0 on success
* -EINVAL on incorrect values
* -ENONET if client not found
*/
-int mei_cl_link_me(struct mei_cl *cl, const uuid_le *uuid, u8 host_cl_id)
+int mei_cl_link(struct mei_cl *cl, int id)
{
struct mei_device *dev;
- int i;
- if (WARN_ON(!cl || !cl->dev || !uuid))
+ if (WARN_ON(!cl || !cl->dev))
return -EINVAL;
dev = cl->dev;
- /* check for valid client id */
- i = mei_me_cl_by_uuid(dev, uuid);
- if (i >= 0) {
- cl->me_client_id = dev->me_clients[i].client_id;
- cl->state = MEI_FILE_CONNECTING;
- cl->host_client_id = host_cl_id;
+ /* If Id is not asigned get one*/
+ if (id == MEI_HOST_CLIENT_ID_ANY)
+ id = find_first_zero_bit(dev->host_clients_map,
+ MEI_CLIENTS_MAX);
- list_add_tail(&cl->link, &dev->file_list);
- return (u8)i;
+ if (id >= MEI_CLIENTS_MAX) {
+ dev_err(&dev->pdev->dev, "id exceded %d", MEI_CLIENTS_MAX) ;
+ return -ENOENT;
}
- return -ENOENT;
+ dev->open_handle_count++;
+
+ cl->host_client_id = id;
+ list_add_tail(&cl->link, &dev->file_list);
+
+ set_bit(id, dev->host_clients_map);
+
+ cl->state = MEI_FILE_INITIALIZING;
+
+ dev_dbg(&dev->pdev->dev, "link cl host id = %d\n", cl->host_client_id);
+ return 0;
}
+
/**
* mei_cl_unlink - remove me_cl from the list
*
* @dev: the device structure
- * @host_client_id: host client id to be removed
*/
int mei_cl_unlink(struct mei_cl *cl)
{
struct mei_device *dev;
struct mei_cl *pos, *next;
- if (WARN_ON(!cl || !cl->dev))
+ /* don't shout on error exit path */
+ if (!cl)
+ return 0;
+
+ if (WARN_ON(!cl->dev))
return -EINVAL;
dev = cl->dev;
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index 8dfd052..240a1f3 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -55,7 +55,7 @@ struct mei_cl *mei_cl_allocate(struct mei_device *dev);
void mei_cl_init(struct mei_cl *cl, struct mei_device *dev);
-int mei_cl_link_me(struct mei_cl *cl, const uuid_le *uuid, u8 host_cl_id);
+int mei_cl_link(struct mei_cl *cl, int id);
int mei_cl_unlink(struct mei_cl *cl);
int mei_cl_flush_queues(struct mei_cl *cl);
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 636639f..9e4011e 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -242,7 +242,11 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
/* remove entry if already in list */
dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n");
mei_cl_unlink(&dev->wd_cl);
+ if (dev->open_handle_count > 0)
+ dev->open_handle_count--;
mei_cl_unlink(&dev->iamthif_cl);
+ if (dev->open_handle_count > 0)
+ dev->open_handle_count--;
mei_amthif_reset_params(dev);
memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index d5d1a59..ec5fd7a 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -103,7 +103,6 @@ static int mei_open(struct inode *inode, struct file *file)
{
struct mei_cl *cl;
struct mei_device *dev;
- unsigned long cl_id;
int err;
err = -ENODEV;
@@ -133,24 +132,9 @@ static int mei_open(struct inode *inode, struct file *file)
goto out_unlock;
}
- cl_id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX);
- if (cl_id >= MEI_CLIENTS_MAX) {
- dev_err(&dev->pdev->dev, "client_id exceded %d",
- MEI_CLIENTS_MAX) ;
+ err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY);
+ if (err)
goto out_unlock;
- }
-
- cl->host_client_id = cl_id;
-
- dev_dbg(&dev->pdev->dev, "client_id = %d\n", cl->host_client_id);
-
- dev->open_handle_count++;
-
- list_add_tail(&cl->link, &dev->file_list);
-
- set_bit(cl->host_client_id, dev->host_clients_map);
- cl->state = MEI_FILE_INITIALIZING;
- cl->sm_state = 0;
file->private_data = cl;
mutex_unlock(&dev->device_lock);
@@ -209,6 +193,7 @@ static int mei_release(struct inode *inode, struct file *file)
}
mei_cl_unlink(cl);
+
/* free read cb */
cb = NULL;
if (cl->read_cb) {
@@ -991,7 +976,13 @@ static void mei_remove(struct pci_dev *pdev)
/* remove entry if already in list */
dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
+
+ if (dev->open_handle_count > 0)
+ dev->open_handle_count--;
mei_cl_unlink(&dev->wd_cl);
+
+ if (dev->open_handle_count > 0)
+ dev->open_handle_count--;
mei_cl_unlink(&dev->iamthif_cl);
dev->iamthif_current_cb = NULL;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 285e8e0..dcd7a44 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -67,16 +67,16 @@ extern const u8 mei_wd_state_independence_msg[3][4];
* Number of File descriptors/handles
* that can be opened to the driver.
*
- * Limit to 253: 256 Total Clients
+ * Limit to 255: 256 Total Clients
* minus internal client for MEI Bus Messags
- * minus internal client for AMTHI
- * minus internal client for Watchdog
*/
-#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 3)
+#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1)
/*
* Internal Clients Number
*/
+#define MEI_HOST_CLIENT_ID_ANY (-1)
+#define MEI_HBM_HOST_CLIENT_ID 0 /* not used, just for documentation */
#define MEI_WD_HOST_CLIENT_ID 1
#define MEI_IAMTHIF_HOST_CLIENT_ID 2
@@ -339,7 +339,7 @@ void mei_timer(struct work_struct *work);
*/
void mei_amthif_reset_params(struct mei_device *dev);
-void mei_amthif_host_init(struct mei_device *dev);
+int mei_amthif_host_init(struct mei_device *dev);
int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb);
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index bfcbcc8..77b3820 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -64,30 +64,41 @@ static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout)
*/
int mei_wd_host_init(struct mei_device *dev)
{
- int id;
- mei_cl_init(&dev->wd_cl, dev);
+ struct mei_cl *cl = &dev->wd_cl;
+ int i;
+ int ret;
+
+ mei_cl_init(cl, dev);
- /* look for WD client and connect to it */
- dev->wd_cl.state = MEI_FILE_DISCONNECTED;
dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT;
dev->wd_state = MEI_WD_IDLE;
- /* Connect WD ME client to the host client */
- id = mei_cl_link_me(&dev->wd_cl,
- &mei_wd_guid, MEI_WD_HOST_CLIENT_ID);
- if (id < 0) {
+ /* check for valid client id */
+ i = mei_me_cl_by_uuid(dev, &mei_wd_guid);
+ if (i < 0) {
dev_info(&dev->pdev->dev, "wd: failed to find the client\n");
return -ENOENT;
}
- if (mei_hbm_cl_connect_req(dev, &dev->wd_cl)) {
+ cl->me_client_id = dev->me_clients[i].client_id;
+
+ ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID);
+
+ if (ret < 0) {
+ dev_info(&dev->pdev->dev, "wd: failed link client\n");
+ return -ENOENT;
+ }
+
+ cl->state = MEI_FILE_CONNECTING;
+
+ if (mei_hbm_cl_connect_req(dev, cl)) {
dev_err(&dev->pdev->dev, "wd: failed to connect to the client\n");
- dev->wd_cl.state = MEI_FILE_DISCONNECTED;
- dev->wd_cl.host_client_id = 0;
+ cl->state = MEI_FILE_DISCONNECTED;
+ cl->host_client_id = 0;
return -EIO;
}
- dev->wd_cl.timer_count = MEI_CONNECT_TIMEOUT;
+ cl->timer_count = MEI_CONNECT_TIMEOUT;
return 0;
}
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 12/21] mei: move MEI_IAMTHIF_IDLE to amthif host init function
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (10 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 11/21] mei: normalize me host client linking routines Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 13/21] mei: hw-me.c fix kernel doc Tomas Winkler
` (8 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
Since the amthif state is not examined until amthif is connected
we can safely move it to the amthif host init function
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/amthif.c | 2 ++
drivers/misc/mei/init.c | 1 -
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 88e6aa0..7199e83 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -71,6 +71,8 @@ int mei_amthif_host_init(struct mei_device *dev)
unsigned char *msg_buf;
int ret, i;
+ dev->iamthif_state = MEI_IAMTHIF_IDLE;
+
mei_cl_init(cl, dev);
i = mei_me_cl_by_uuid(dev, &mei_amthif_guid);
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 9e4011e..70fad4e 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -68,7 +68,6 @@ struct mei_device *mei_device_init(struct pci_dev *pdev)
init_waitqueue_head(&dev->wait_recvd_msg);
init_waitqueue_head(&dev->wait_stop_wd);
dev->dev_state = MEI_DEV_INITIALIZING;
- dev->iamthif_state = MEI_IAMTHIF_IDLE;
mei_io_list_init(&dev->read_list);
mei_io_list_init(&dev->write_list);
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 13/21] mei: hw-me.c fix kernel doc
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (11 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 12/21] mei: move MEI_IAMTHIF_IDLE to amthif host init function Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 14/21] mei: remove write only need_reset member of struct mei_device Tomas Winkler
` (7 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
Fix the kernel doc for the functions in hw-me.c
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hw-me.c | 27 ++++++++++++++++++---------
1 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 4e6b657..1e82e33 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -49,17 +49,13 @@ static inline void mei_reg_write(const struct mei_device *dev,
}
/**
- * mei_hcsr_read - Reads 32bit data from the host CSR
+ * mei_mecbrw_read - Reads 32bit data from ME circular buffer
+ * read window register
*
* @dev: the device structure
*
- * returns the byte read.
+ * returns ME_CB_RW register value (u32)
*/
-u32 mei_hcsr_read(const struct mei_device *dev)
-{
- return mei_reg_read(dev, H_CSR);
-}
-
u32 mei_mecbrw_read(const struct mei_device *dev)
{
return mei_reg_read(dev, ME_CB_RW);
@@ -77,13 +73,26 @@ u32 mei_mecsr_read(const struct mei_device *dev)
}
/**
- * mei_set_csr_register - writes H_CSR register to the mei device,
+ * mei_hcsr_read - Reads 32bit data from the host CSR
+ *
+ * @dev: the device structure
+ *
+ * returns H_CSR register value (u32)
+ */
+u32 mei_hcsr_read(const struct mei_device *dev)
+{
+ return mei_reg_read(dev, H_CSR);
+}
+
+/**
+ * mei_hcsr_set - writes H_CSR register to the mei device,
* and ignores the H_IS bit for it is write-one-to-zero.
*
* @dev: the device structure
*/
void mei_hcsr_set(struct mei_device *dev)
{
+
if ((dev->host_hw_state & H_IS) == H_IS)
dev->host_hw_state &= ~H_IS;
mei_reg_write(dev, H_CSR, dev->host_hw_state);
@@ -91,7 +100,7 @@ void mei_hcsr_set(struct mei_device *dev)
}
/**
- * mei_enable_interrupts - clear and stop interrupts
+ * mei_clear_interrupts - clear and stop interrupts
*
* @dev: the device structure
*/
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 14/21] mei: remove write only need_reset member of struct mei_device
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (12 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 13/21] mei: hw-me.c fix kernel doc Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 15/21] mei: remove mei_csr_clear_his prototype Tomas Winkler
` (6 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
need_reset is not used anymore
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/init.c | 6 +-----
drivers/misc/mei/mei_dev.h | 1 -
2 files changed, 1 insertions(+), 6 deletions(-)
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 70fad4e..2391832 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -199,10 +199,8 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
struct mei_cl_cb *cb_next = NULL;
bool unexpected;
- if (dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
- dev->need_reset = true;
+ if (dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET)
return;
- }
unexpected = (dev->dev_state != MEI_DEV_INITIALIZING &&
dev->dev_state != MEI_DEV_DISABLED &&
@@ -224,8 +222,6 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
dev_dbg(&dev->pdev->dev, "currently saved host_hw_state = 0x%08x.\n",
dev->host_hw_state);
- dev->need_reset = false;
-
if (dev->dev_state != MEI_DEV_INITIALIZING) {
if (dev->dev_state != MEI_DEV_DISABLED &&
dev->dev_state != MEI_DEV_POWER_DOWN)
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index dcd7a44..e42db31 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -260,7 +260,6 @@ struct mei_device {
enum mei_dev_state dev_state;
enum mei_init_clients_states init_clients_state;
u16 init_clients_timer;
- bool need_reset;
unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */
u32 rd_msg_hdr;
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 15/21] mei: remove mei_csr_clear_his prototype
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (13 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 14/21] mei: remove write only need_reset member of struct mei_device Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 16/21] mei: don't use cached value for hcsr in mei_hw_reset Tomas Winkler
` (5 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
The function mei_csr_clear_his is not implemented
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/mei_dev.h | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index e42db31..88fa194 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -386,11 +386,10 @@ void mei_watchdog_unregister(struct mei_device *dev);
*/
u32 mei_hcsr_read(const struct mei_device *dev);
+void mei_hcsr_set(struct mei_device *dev);
u32 mei_mecsr_read(const struct mei_device *dev);
u32 mei_mecbrw_read(const struct mei_device *dev);
-void mei_hcsr_set(struct mei_device *dev);
-void mei_csr_clear_his(struct mei_device *dev);
void mei_clear_interrupts(struct mei_device *dev);
void mei_enable_interrupts(struct mei_device *dev);
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 16/21] mei: don't use cached value for hcsr in mei_hw_reset
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (14 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 15/21] mei: remove mei_csr_clear_his prototype Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 17/21] mei: use non cached hcsr for interrupt enablement Tomas Winkler
` (4 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
Open code mei_hw_reset to avoid using cached hcsr.
Using cached hcsr can cause unwanted side effects.
Move mei_hw_restet function to hw-me.c as it is hw dependent
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hw-me.c | 35 +++++++++++++++++++++++++++++++++++
drivers/misc/mei/init.c | 28 ----------------------------
drivers/misc/mei/mei_dev.h | 1 +
3 files changed, 36 insertions(+), 28 deletions(-)
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 1e82e33..ec4ab89 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -132,6 +132,41 @@ void mei_disable_interrupts(struct mei_device *dev)
mei_hcsr_set(dev);
}
+/**
+ * mei_hw_reset - resets fw via mei csr register.
+ *
+ * @dev: the device structure
+ * @interrupts_enabled: if interrupt should be enabled after reset.
+ */
+void mei_hw_reset(struct mei_device *dev, bool intr_enable)
+{
+ u32 hcsr = mei_hcsr_read(dev);
+
+ dev_dbg(&dev->pdev->dev, "before reset HCSR = 0x%08x.\n", hcsr);
+
+ hcsr |= (H_RST | H_IG);
+
+ if (intr_enable)
+ hcsr |= H_IE;
+ else
+ hcsr &= ~H_IE;
+
+ hcsr &= ~H_IS;
+
+ mei_reg_write(dev, H_CSR, hcsr);
+ hcsr = mei_hcsr_read(dev);
+
+ hcsr &= ~H_RST;
+ hcsr |= H_IG;
+ hcsr &= ~H_IS;
+
+ mei_reg_write(dev, H_CSR, hcsr);
+
+ hcsr = mei_hcsr_read(dev);
+
+ dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", hcsr);
+}
+
/**
* mei_interrupt_quick_handler - The ISR of the MEI device
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 2391832..5c2054d 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -170,22 +170,6 @@ out:
}
/**
- * mei_hw_reset - resets fw via mei csr register.
- *
- * @dev: the device structure
- * @interrupts_enabled: if interrupt should be enabled after reset.
- */
-static void mei_hw_reset(struct mei_device *dev, int interrupts_enabled)
-{
- dev->host_hw_state |= (H_RST | H_IG);
-
- if (interrupts_enabled)
- mei_enable_interrupts(dev);
- else
- mei_disable_interrupts(dev);
-}
-
-/**
* mei_reset - resets host and fw.
*
* @dev: the device structure
@@ -207,20 +191,8 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
dev->dev_state != MEI_DEV_POWER_DOWN &&
dev->dev_state != MEI_DEV_POWER_UP);
- dev->host_hw_state = mei_hcsr_read(dev);
-
- dev_dbg(&dev->pdev->dev, "before reset host_hw_state = 0x%08x.\n",
- dev->host_hw_state);
-
mei_hw_reset(dev, interrupts_enabled);
- dev->host_hw_state &= ~H_RST;
- dev->host_hw_state |= H_IG;
-
- mei_hcsr_set(dev);
-
- dev_dbg(&dev->pdev->dev, "currently saved host_hw_state = 0x%08x.\n",
- dev->host_hw_state);
if (dev->dev_state != MEI_DEV_INITIALIZING) {
if (dev->dev_state != MEI_DEV_DISABLED &&
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 88fa194..8692ac8 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -385,6 +385,7 @@ void mei_watchdog_unregister(struct mei_device *dev);
* Register Access Function
*/
+void mei_hw_reset(struct mei_device *dev, bool intr_enable);
u32 mei_hcsr_read(const struct mei_device *dev);
void mei_hcsr_set(struct mei_device *dev);
u32 mei_mecsr_read(const struct mei_device *dev);
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 17/21] mei: use non cached hcsr for interrupt enablement
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (15 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 16/21] mei: don't use cached value for hcsr in mei_hw_reset Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 18/21] mei: abstract host and device readieness Tomas Winkler
` (3 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hw-me.c | 17 +++++++++++------
drivers/misc/mei/interrupt.c | 2 +-
drivers/misc/mei/main.c | 2 --
3 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index ec4ab89..ed61659 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -106,8 +106,9 @@ void mei_hcsr_set(struct mei_device *dev)
*/
void mei_clear_interrupts(struct mei_device *dev)
{
- if ((dev->host_hw_state & H_IS) == H_IS)
- mei_reg_write(dev, H_CSR, dev->host_hw_state);
+ u32 hcsr = mei_hcsr_read(dev);
+ if ((hcsr & H_IS) == H_IS)
+ mei_reg_write(dev, H_CSR, hcsr);
}
/**
@@ -117,8 +118,10 @@ void mei_clear_interrupts(struct mei_device *dev)
*/
void mei_enable_interrupts(struct mei_device *dev)
{
- dev->host_hw_state |= H_IE;
- mei_hcsr_set(dev);
+ u32 hcsr = mei_hcsr_read(dev);
+ hcsr |= H_IE;
+ hcsr &= ~H_IS;
+ mei_reg_write(dev, H_CSR, hcsr);
}
/**
@@ -128,8 +131,10 @@ void mei_enable_interrupts(struct mei_device *dev)
*/
void mei_disable_interrupts(struct mei_device *dev)
{
- dev->host_hw_state &= ~H_IE;
- mei_hcsr_set(dev);
+ u32 hcsr = mei_hcsr_read(dev);
+ hcsr &= ~H_IE;
+ hcsr &= ~H_IS;
+ mei_reg_write(dev, H_CSR, hcsr);
}
/**
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index d1ef926..d7e1b79 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -691,7 +691,6 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
/* initialize our complete list */
mutex_lock(&dev->device_lock);
mei_io_list_init(&complete_list);
- dev->host_hw_state = mei_hcsr_read(dev);
/* Ack the interrupt here
* In case of MSI we don't go through the quick handler */
@@ -710,6 +709,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
+ dev->host_hw_state = mei_hcsr_read(dev);
/* check if we need to start the dev */
if ((dev->host_hw_state & H_RDY) == 0) {
if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) {
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index ec5fd7a..f72bb77 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -915,8 +915,6 @@ static int mei_probe(struct pci_dev *pdev,
return 0;
release_irq:
- /* disable interrupts */
- dev->host_hw_state = mei_hcsr_read(dev);
mei_disable_interrupts(dev);
flush_scheduled_work();
free_irq(pdev->irq, dev);
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 18/21] mei: abstract host and device readieness
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (16 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 17/21] mei: use non cached hcsr for interrupt enablement Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 19/21] mei: reenable mei_hcsr_set abstraction Tomas Winkler
` (2 subsequent siblings)
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
Add mei_host_set_ready function to enable the device
and is_ready function to query the host and me readiness
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hw-me.c | 35 ++++++++++++++++++++++++++++++++++-
drivers/misc/mei/init.c | 14 ++++++--------
drivers/misc/mei/interrupt.c | 19 ++++++++++---------
drivers/misc/mei/mei_dev.h | 4 ++++
4 files changed, 54 insertions(+), 18 deletions(-)
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index ed61659..49b558d 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -172,6 +172,39 @@ void mei_hw_reset(struct mei_device *dev, bool intr_enable)
dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", hcsr);
}
+/**
+ * mei_host_set_ready - enable device
+ *
+ * @dev - mei device
+ * returns bool
+ */
+
+void mei_host_set_ready(struct mei_device *dev)
+{
+ dev->host_hw_state |= H_IE | H_IG | H_RDY;
+ mei_hcsr_set(dev);
+}
+/**
+ * mei_host_is_ready - check whether the host has turned ready
+ *
+ * @dev - mei device
+ * returns bool
+ */
+bool mei_host_is_ready(struct mei_device *dev)
+{
+ return (dev->host_hw_state & H_RDY) == H_RDY;
+}
+
+/**
+ * mei_me_is_ready - check whether the me has turned ready
+ *
+ * @dev - mei device
+ * returns bool
+ */
+bool mei_me_is_ready(struct mei_device *dev)
+{
+ return (dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA;
+}
/**
* mei_interrupt_quick_handler - The ISR of the MEI device
@@ -290,7 +323,7 @@ int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header,
dev->host_hw_state |= H_IG;
mei_hcsr_set(dev);
dev->me_hw_state = mei_mecsr_read(dev);
- if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA)
+ if (!mei_me_is_ready(dev))
return -EIO;
return 0;
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 5c2054d..d0ee02a 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -131,18 +131,18 @@ int mei_hw_init(struct mei_device *dev)
goto out;
}
- if (!(((dev->host_hw_state & H_RDY) == H_RDY) &&
- ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) {
+ if (!(mei_host_is_ready(dev) && mei_me_is_ready(dev))) {
dev->dev_state = MEI_DEV_DISABLED;
+
dev_dbg(&dev->pdev->dev,
"host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
dev->host_hw_state, dev->me_hw_state);
- if (!(dev->host_hw_state & H_RDY))
- dev_dbg(&dev->pdev->dev, "host turn off H_RDY.\n");
+ if (!mei_host_is_ready(dev))
+ dev_dbg(&dev->pdev->dev, "host is not ready.\n");
- if (!(dev->me_hw_state & ME_RDY_HRA))
- dev_dbg(&dev->pdev->dev, "ME turn off ME_RDY.\n");
+ if (!mei_me_is_ready(dev))
+ dev_dbg(&dev->pdev->dev, "ME is not ready.\n");
dev_err(&dev->pdev->dev, "link layer initialization failed.\n");
ret = -ENODEV;
@@ -159,9 +159,7 @@ int mei_hw_init(struct mei_device *dev)
dev->recvd_msg = false;
dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
dev->host_hw_state, dev->me_hw_state);
- dev_dbg(&dev->pdev->dev, "ME turn on ME_RDY and host turn on H_RDY.\n");
dev_dbg(&dev->pdev->dev, "link layer has been established.\n");
- dev_dbg(&dev->pdev->dev, "MEI start success.\n");
ret = 0;
out:
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index d7e1b79..27374b6 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -700,7 +700,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
dev->me_hw_state = mei_mecsr_read(dev);
/* check if ME wants a reset */
- if ((dev->me_hw_state & ME_RDY_HRA) == 0 &&
+ if (!mei_me_is_ready(dev) &&
dev->dev_state != MEI_DEV_RESETING &&
dev->dev_state != MEI_DEV_INITIALIZING) {
dev_dbg(&dev->pdev->dev, "FW not ready.\n");
@@ -711,16 +711,17 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
dev->host_hw_state = mei_hcsr_read(dev);
/* check if we need to start the dev */
- if ((dev->host_hw_state & H_RDY) == 0) {
- if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) {
+ if (!mei_host_is_ready(dev)) {
+ if (mei_me_is_ready(dev)) {
dev_dbg(&dev->pdev->dev, "we need to start the dev.\n");
- dev->host_hw_state |= (H_IE | H_IG | H_RDY);
- mei_hcsr_set(dev);
- dev->dev_state = MEI_DEV_INIT_CLIENTS;
+
+ mei_host_set_ready(dev);
+
dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n");
- /* link is established
- * start sending messages.
- */
+ /* link is established * start sending messages. */
+
+ dev->dev_state = MEI_DEV_INIT_CLIENTS;
+
mei_hbm_start_req(dev);
mutex_unlock(&dev->device_lock);
return IRQ_HANDLED;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 8692ac8..7b43659 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -396,6 +396,10 @@ void mei_clear_interrupts(struct mei_device *dev);
void mei_enable_interrupts(struct mei_device *dev);
void mei_disable_interrupts(struct mei_device *dev);
+void mei_host_set_ready(struct mei_device *dev);
+bool mei_host_is_ready(struct mei_device *dev);
+bool mei_me_is_ready(struct mei_device *dev);
+
#define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d comp=%1d"
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 19/21] mei: reenable mei_hcsr_set abstraction
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (17 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 18/21] mei: abstract host and device readieness Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 20/21] mei: make host csr and me csr internal to hw-me Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 21/21] mei: move work initialization to mei_device_init Tomas Winkler
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
Now when mei_hcsr_set is local to hw-me.c
we can benefit form the fact that it wraps
H_IS removal from the host csr.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hw-me.c | 38 +++++++++++++++-----------------------
drivers/misc/mei/mei_dev.h | 1 -
2 files changed, 15 insertions(+), 24 deletions(-)
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 49b558d..3190027 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -90,13 +90,10 @@ u32 mei_hcsr_read(const struct mei_device *dev)
*
* @dev: the device structure
*/
-void mei_hcsr_set(struct mei_device *dev)
+static inline void mei_hcsr_set(struct mei_device *dev, u32 hcsr)
{
-
- if ((dev->host_hw_state & H_IS) == H_IS)
- dev->host_hw_state &= ~H_IS;
- mei_reg_write(dev, H_CSR, dev->host_hw_state);
- dev->host_hw_state = mei_hcsr_read(dev);
+ hcsr &= ~H_IS;
+ mei_reg_write(dev, H_CSR, hcsr);
}
/**
@@ -120,8 +117,7 @@ void mei_enable_interrupts(struct mei_device *dev)
{
u32 hcsr = mei_hcsr_read(dev);
hcsr |= H_IE;
- hcsr &= ~H_IS;
- mei_reg_write(dev, H_CSR, hcsr);
+ mei_hcsr_set(dev, hcsr);
}
/**
@@ -133,8 +129,7 @@ void mei_disable_interrupts(struct mei_device *dev)
{
u32 hcsr = mei_hcsr_read(dev);
hcsr &= ~H_IE;
- hcsr &= ~H_IS;
- mei_reg_write(dev, H_CSR, hcsr);
+ mei_hcsr_set(dev, hcsr);
}
/**
@@ -156,16 +151,12 @@ void mei_hw_reset(struct mei_device *dev, bool intr_enable)
else
hcsr &= ~H_IE;
- hcsr &= ~H_IS;
-
- mei_reg_write(dev, H_CSR, hcsr);
- hcsr = mei_hcsr_read(dev);
+ mei_hcsr_set(dev, hcsr);
+ hcsr = mei_hcsr_read(dev) | H_IG;
hcsr &= ~H_RST;
- hcsr |= H_IG;
- hcsr &= ~H_IS;
- mei_reg_write(dev, H_CSR, hcsr);
+ mei_hcsr_set(dev, hcsr);
hcsr = mei_hcsr_read(dev);
@@ -182,7 +173,7 @@ void mei_hw_reset(struct mei_device *dev, bool intr_enable)
void mei_host_set_ready(struct mei_device *dev)
{
dev->host_hw_state |= H_IE | H_IG | H_RDY;
- mei_hcsr_set(dev);
+ mei_hcsr_set(dev, dev->host_hw_state);
}
/**
* mei_host_is_ready - check whether the host has turned ready
@@ -295,6 +286,7 @@ int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header,
unsigned long rem, dw_cnt;
unsigned long length = header->length;
u32 *reg_buf = (u32 *)buf;
+ u32 hcsr;
int i;
int empty_slots;
@@ -319,9 +311,8 @@ int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header,
mei_reg_write(dev, H_CB_WW, reg);
}
- dev->host_hw_state = mei_hcsr_read(dev);
- dev->host_hw_state |= H_IG;
- mei_hcsr_set(dev);
+ hcsr = mei_hcsr_read(dev) | H_IG;
+ mei_hcsr_set(dev, hcsr);
dev->me_hw_state = mei_mecsr_read(dev);
if (!mei_me_is_ready(dev))
return -EIO;
@@ -366,6 +357,7 @@ void mei_read_slots(struct mei_device *dev, unsigned char *buffer,
unsigned long buffer_length)
{
u32 *reg_buf = (u32 *)buffer;
+ u32 hcsr;
for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32))
*reg_buf++ = mei_mecbrw_read(dev);
@@ -375,7 +367,7 @@ void mei_read_slots(struct mei_device *dev, unsigned char *buffer,
memcpy(reg_buf, ®, buffer_length);
}
- dev->host_hw_state |= H_IG;
- mei_hcsr_set(dev);
+ hcsr = mei_hcsr_read(dev) | H_IG;
+ mei_hcsr_set(dev, hcsr);
}
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 7b43659..ae4c5ff 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -387,7 +387,6 @@ void mei_watchdog_unregister(struct mei_device *dev);
void mei_hw_reset(struct mei_device *dev, bool intr_enable);
u32 mei_hcsr_read(const struct mei_device *dev);
-void mei_hcsr_set(struct mei_device *dev);
u32 mei_mecsr_read(const struct mei_device *dev);
u32 mei_mecbrw_read(const struct mei_device *dev);
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 20/21] mei: make host csr and me csr internal to hw-me
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (18 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 19/21] mei: reenable mei_hcsr_set abstraction Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
2013-01-08 21:07 ` [char-misc-next 21/21] mei: move work initialization to mei_device_init Tomas Winkler
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
Move csr reading into me hardware functional calls.
Since we gave up on registers caching we remove some of the unnecessary
queries in mei_hw_init ane mei_reset functions.
We add mei_hw_config function to wrap up host buffer depth configuration.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/hw-me.c | 19 ++++++++++--
drivers/misc/mei/init.c | 63 ++++++++++++-----------------------------
drivers/misc/mei/interrupt.c | 4 --
drivers/misc/mei/mei_dev.h | 4 +-
4 files changed, 37 insertions(+), 53 deletions(-)
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 3190027..93a2a56 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -67,7 +67,7 @@ u32 mei_mecbrw_read(const struct mei_device *dev)
*
* returns ME_CSR_HA register value (u32)
*/
-u32 mei_mecsr_read(const struct mei_device *dev)
+static inline u32 mei_mecsr_read(const struct mei_device *dev)
{
return mei_reg_read(dev, ME_CSR_HA);
}
@@ -79,7 +79,7 @@ u32 mei_mecsr_read(const struct mei_device *dev)
*
* returns H_CSR register value (u32)
*/
-u32 mei_hcsr_read(const struct mei_device *dev)
+static inline u32 mei_hcsr_read(const struct mei_device *dev)
{
return mei_reg_read(dev, H_CSR);
}
@@ -96,6 +96,18 @@ static inline void mei_hcsr_set(struct mei_device *dev, u32 hcsr)
mei_reg_write(dev, H_CSR, hcsr);
}
+
+/**
+ * me_hw_config - configure hw dependent settings
+ *
+ * @dev: mei device
+ */
+void mei_hw_config(struct mei_device *dev)
+{
+ u32 hcsr = mei_hcsr_read(dev);
+ /* Doesn't change in runtime */
+ dev->hbuf_depth = (hcsr & H_CBD) >> 24;
+}
/**
* mei_clear_interrupts - clear and stop interrupts
*
@@ -183,6 +195,7 @@ void mei_host_set_ready(struct mei_device *dev)
*/
bool mei_host_is_ready(struct mei_device *dev)
{
+ dev->host_hw_state = mei_hcsr_read(dev);
return (dev->host_hw_state & H_RDY) == H_RDY;
}
@@ -194,6 +207,7 @@ bool mei_host_is_ready(struct mei_device *dev)
*/
bool mei_me_is_ready(struct mei_device *dev)
{
+ dev->me_hw_state = mei_mecsr_read(dev);
return (dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA;
}
@@ -313,7 +327,6 @@ int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header,
hcsr = mei_hcsr_read(dev) | H_IG;
mei_hcsr_set(dev, hcsr);
- dev->me_hw_state = mei_mecsr_read(dev);
if (!mei_me_is_ready(dev))
return -EIO;
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index d0ee02a..98a7fc1 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -89,82 +89,64 @@ struct mei_device *mei_device_init(struct pci_dev *pdev)
*/
int mei_hw_init(struct mei_device *dev)
{
- int err = 0;
- int ret;
+ int ret = 0;
mutex_lock(&dev->device_lock);
- dev->host_hw_state = mei_hcsr_read(dev);
- dev->me_hw_state = mei_mecsr_read(dev);
- dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, mestate = 0x%08x.\n",
- dev->host_hw_state, dev->me_hw_state);
-
/* acknowledge interrupt and stop interupts */
mei_clear_interrupts(dev);
- /* Doesn't change in runtime */
- dev->hbuf_depth = (dev->host_hw_state & H_CBD) >> 24;
+ mei_hw_config(dev);
dev->recvd_msg = false;
dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n");
mei_reset(dev, 1);
- dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
- dev->host_hw_state, dev->me_hw_state);
-
/* wait for ME to turn on ME_RDY */
if (!dev->recvd_msg) {
mutex_unlock(&dev->device_lock);
- err = wait_event_interruptible_timeout(dev->wait_recvd_msg,
+ ret = wait_event_interruptible_timeout(dev->wait_recvd_msg,
dev->recvd_msg,
mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT));
mutex_lock(&dev->device_lock);
}
- if (err <= 0 && !dev->recvd_msg) {
+ if (ret <= 0 && !dev->recvd_msg) {
dev->dev_state = MEI_DEV_DISABLED;
dev_dbg(&dev->pdev->dev,
"wait_event_interruptible_timeout failed"
"on wait for ME to turn on ME_RDY.\n");
- ret = -ENODEV;
- goto out;
+ goto err;
}
- if (!(mei_host_is_ready(dev) && mei_me_is_ready(dev))) {
- dev->dev_state = MEI_DEV_DISABLED;
-
- dev_dbg(&dev->pdev->dev,
- "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
- dev->host_hw_state, dev->me_hw_state);
-
- if (!mei_host_is_ready(dev))
- dev_dbg(&dev->pdev->dev, "host is not ready.\n");
- if (!mei_me_is_ready(dev))
- dev_dbg(&dev->pdev->dev, "ME is not ready.\n");
+ if (!mei_host_is_ready(dev)) {
+ dev_err(&dev->pdev->dev, "host is not ready.\n");
+ goto err;
+ }
- dev_err(&dev->pdev->dev, "link layer initialization failed.\n");
- ret = -ENODEV;
- goto out;
+ if (!mei_me_is_ready(dev)) {
+ dev_err(&dev->pdev->dev, "ME is not ready.\n");
+ goto err;
}
if (dev->version.major_version != HBM_MAJOR_VERSION ||
dev->version.minor_version != HBM_MINOR_VERSION) {
dev_dbg(&dev->pdev->dev, "MEI start failed.\n");
- ret = -ENODEV;
- goto out;
+ goto err;
}
dev->recvd_msg = false;
- dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
- dev->host_hw_state, dev->me_hw_state);
dev_dbg(&dev->pdev->dev, "link layer has been established.\n");
- ret = 0;
-out:
mutex_unlock(&dev->device_lock);
- return ret;
+ return 0;
+err:
+ dev_err(&dev->pdev->dev, "link layer initialization failed.\n");
+ dev->dev_state = MEI_DEV_DISABLED;
+ mutex_unlock(&dev->device_lock);
+ return -ENODEV;
}
/**
@@ -221,13 +203,6 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
dev->rd_msg_hdr = 0;
dev->wd_pending = false;
- /* update the state of the registers after reset */
- dev->host_hw_state = mei_hcsr_read(dev);
- dev->me_hw_state = mei_mecsr_read(dev);
-
- dev_dbg(&dev->pdev->dev, "after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
- dev->host_hw_state, dev->me_hw_state);
-
if (unexpected)
dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
mei_dev_state_str(dev->dev_state));
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 27374b6..b04ed9b 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -697,8 +697,6 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
if (pci_dev_msi_enabled(dev->pdev))
mei_clear_interrupts(dev);
- dev->me_hw_state = mei_mecsr_read(dev);
-
/* check if ME wants a reset */
if (!mei_me_is_ready(dev) &&
dev->dev_state != MEI_DEV_RESETING &&
@@ -709,7 +707,6 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
- dev->host_hw_state = mei_hcsr_read(dev);
/* check if we need to start the dev */
if (!mei_host_is_ready(dev)) {
if (mei_me_is_ready(dev)) {
@@ -746,7 +743,6 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
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);
dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev);
bus_message_received = false;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index ae4c5ff..d6589d0 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -385,12 +385,12 @@ void mei_watchdog_unregister(struct mei_device *dev);
* Register Access Function
*/
+void mei_hw_config(struct mei_device *dev);
void mei_hw_reset(struct mei_device *dev, bool intr_enable);
-u32 mei_hcsr_read(const struct mei_device *dev);
-u32 mei_mecsr_read(const struct mei_device *dev);
u32 mei_mecbrw_read(const struct mei_device *dev);
+
void mei_clear_interrupts(struct mei_device *dev);
void mei_enable_interrupts(struct mei_device *dev);
void mei_disable_interrupts(struct mei_device *dev);
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [char-misc-next 21/21] mei: move work initialization to mei_device_init
2013-01-08 21:07 [char-misc-next 00/21] MEI restructuring Tomas Winkler
` (19 preceding siblings ...)
2013-01-08 21:07 ` [char-misc-next 20/21] mei: make host csr and me csr internal to hw-me Tomas Winkler
@ 2013-01-08 21:07 ` Tomas Winkler
20 siblings, 0 replies; 22+ messages in thread
From: Tomas Winkler @ 2013-01-08 21:07 UTC (permalink / raw)
To: gregkh; +Cc: arnd, alan, linux-kernel, Tomas Winkler
Let mei_device_init initialize all the software constructs.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/init.c | 4 ++++
drivers/misc/mei/main.c | 2 --
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 98a7fc1..5d08db5 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -76,6 +76,10 @@ struct mei_device *mei_device_init(struct pci_dev *pdev)
mei_io_list_init(&dev->ctrl_rd_list);
mei_io_list_init(&dev->amthif_cmd_list);
mei_io_list_init(&dev->amthif_rd_complete_list);
+
+ INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
+ INIT_WORK(&dev->init_work, mei_host_client_init);
+
dev->pdev = pdev;
return dev;
}
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index f72bb77..123c663 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -889,8 +889,6 @@ static int mei_probe(struct pci_dev *pdev,
pdev->irq);
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");
--
1.7.4.4
^ permalink raw reply [flat|nested] 22+ messages in thread