aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2013-01-08 16:07:22 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-08 19:40:46 -0500
commit781d0d89224bbbc438c2c0360cfd4822bb35d280 (patch)
treeccda09fa57cd18a9f875bf46d0ce35b925cd9219 /drivers/misc/mei
parent1a1aca42c989051dce34d49b4e04a25dafe01d74 (diff)
mei: normalize me host client linking routines
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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r--drivers/misc/mei/amthif.c42
-rw-r--r--drivers/misc/mei/client.c53
-rw-r--r--drivers/misc/mei/client.h2
-rw-r--r--drivers/misc/mei/init.c4
-rw-r--r--drivers/misc/mei/main.c27
-rw-r--r--drivers/misc/mei/mei_dev.h10
-rw-r--r--drivers/misc/mei/wd.c35
7 files changed, 98 insertions, 75 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 64a9bfa5ad20..88e6aa0f6b4e 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)
65 * @dev: the device structure 65 * @dev: the device structure
66 * 66 *
67 */ 67 */
68void mei_amthif_host_init(struct mei_device *dev) 68int mei_amthif_host_init(struct mei_device *dev)
69{ 69{
70 int i; 70 struct mei_cl *cl = &dev->iamthif_cl;
71 unsigned char *msg_buf; 71 unsigned char *msg_buf;
72 int ret, i;
72 73
73 mei_cl_init(&dev->iamthif_cl, dev); 74 mei_cl_init(cl, dev);
74 dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
75 75
76 /* find ME amthif client */ 76 i = mei_me_cl_by_uuid(dev, &mei_amthif_guid);
77 i = mei_cl_link_me(&dev->iamthif_cl,
78 &mei_amthif_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
79 if (i < 0) { 77 if (i < 0) {
80 dev_info(&dev->pdev->dev, "failed to find iamthif client.\n"); 78 dev_info(&dev->pdev->dev, "amthif: failed to find the client\n");
81 return; 79 return -ENOENT;
82 } 80 }
83 81
82 cl->me_client_id = dev->me_clients[i].client_id;
83
84 /* Assign iamthif_mtu to the value received from ME */ 84 /* Assign iamthif_mtu to the value received from ME */
85 85
86 dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length; 86 dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length;
@@ -94,19 +94,29 @@ void mei_amthif_host_init(struct mei_device *dev)
94 msg_buf = kcalloc(dev->iamthif_mtu, 94 msg_buf = kcalloc(dev->iamthif_mtu,
95 sizeof(unsigned char), GFP_KERNEL); 95 sizeof(unsigned char), GFP_KERNEL);
96 if (!msg_buf) { 96 if (!msg_buf) {
97 dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n"); 97 dev_err(&dev->pdev->dev, "amthif: memory allocation for ME message buffer failed.\n");
98 return; 98 return -ENOMEM;
99 } 99 }
100 100
101 dev->iamthif_msg_buf = msg_buf; 101 dev->iamthif_msg_buf = msg_buf;
102 102
103 if (mei_hbm_cl_connect_req(dev, &dev->iamthif_cl)) { 103 ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID);
104 dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n"); 104
105 dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; 105 if (ret < 0) {
106 dev->iamthif_cl.host_client_id = 0; 106 dev_err(&dev->pdev->dev, "amthif: failed link client\n");
107 return -ENOENT;
108 }
109
110 cl->state = MEI_FILE_CONNECTING;
111
112 if (mei_hbm_cl_connect_req(dev, cl)) {
113 dev_dbg(&dev->pdev->dev, "amthif: Failed to connect to ME client\n");
114 cl->state = MEI_FILE_DISCONNECTED;
115 cl->host_client_id = 0;
107 } else { 116 } else {
108 dev->iamthif_cl.timer_count = MEI_CONNECT_TIMEOUT; 117 cl->timer_count = MEI_CONNECT_TIMEOUT;
109 } 118 }
119 return 0;
110} 120}
111 121
112/** 122/**
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 8103d94facb8..d566dd880eb0 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)
258 return NULL; 258 return NULL;
259} 259}
260 260
261 261/** mei_cl_link: allocte host id in the host map
262/**
263 * mei_me_cl_link - create link between host and me clinet and add
264 * me_cl to the list
265 *
266 * @cl: link between me and host client assocated with opened file descriptor
267 * @uuid: uuid of ME client
268 * @client_id: id of the host client
269 * 262 *
270 * returns ME client index if ME client 263 * @cl - host client
264 * @id - fixed host id or -1 for genereting one
265 * returns 0 on success
271 * -EINVAL on incorrect values 266 * -EINVAL on incorrect values
272 * -ENONET if client not found 267 * -ENONET if client not found
273 */ 268 */
274int mei_cl_link_me(struct mei_cl *cl, const uuid_le *uuid, u8 host_cl_id) 269int mei_cl_link(struct mei_cl *cl, int id)
275{ 270{
276 struct mei_device *dev; 271 struct mei_device *dev;
277 int i;
278 272
279 if (WARN_ON(!cl || !cl->dev || !uuid)) 273 if (WARN_ON(!cl || !cl->dev))
280 return -EINVAL; 274 return -EINVAL;
281 275
282 dev = cl->dev; 276 dev = cl->dev;
283 277
284 /* check for valid client id */ 278 /* If Id is not asigned get one*/
285 i = mei_me_cl_by_uuid(dev, uuid); 279 if (id == MEI_HOST_CLIENT_ID_ANY)
286 if (i >= 0) { 280 id = find_first_zero_bit(dev->host_clients_map,
287 cl->me_client_id = dev->me_clients[i].client_id; 281 MEI_CLIENTS_MAX);
288 cl->state = MEI_FILE_CONNECTING;
289 cl->host_client_id = host_cl_id;
290 282
291 list_add_tail(&cl->link, &dev->file_list); 283 if (id >= MEI_CLIENTS_MAX) {
292 return (u8)i; 284 dev_err(&dev->pdev->dev, "id exceded %d", MEI_CLIENTS_MAX) ;
285 return -ENOENT;
293 } 286 }
294 287
295 return -ENOENT; 288 dev->open_handle_count++;
289
290 cl->host_client_id = id;
291 list_add_tail(&cl->link, &dev->file_list);
292
293 set_bit(id, dev->host_clients_map);
294
295 cl->state = MEI_FILE_INITIALIZING;
296
297 dev_dbg(&dev->pdev->dev, "link cl host id = %d\n", cl->host_client_id);
298 return 0;
296} 299}
300
297/** 301/**
298 * mei_cl_unlink - remove me_cl from the list 302 * mei_cl_unlink - remove me_cl from the list
299 * 303 *
300 * @dev: the device structure 304 * @dev: the device structure
301 * @host_client_id: host client id to be removed
302 */ 305 */
303int mei_cl_unlink(struct mei_cl *cl) 306int mei_cl_unlink(struct mei_cl *cl)
304{ 307{
305 struct mei_device *dev; 308 struct mei_device *dev;
306 struct mei_cl *pos, *next; 309 struct mei_cl *pos, *next;
307 310
308 if (WARN_ON(!cl || !cl->dev)) 311 /* don't shout on error exit path */
312 if (!cl)
313 return 0;
314
315 if (WARN_ON(!cl->dev))
309 return -EINVAL; 316 return -EINVAL;
310 317
311 dev = cl->dev; 318 dev = cl->dev;
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index 8dfd052dd0e6..240a1f321342 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);
55void mei_cl_init(struct mei_cl *cl, struct mei_device *dev); 55void mei_cl_init(struct mei_cl *cl, struct mei_device *dev);
56 56
57 57
58int mei_cl_link_me(struct mei_cl *cl, const uuid_le *uuid, u8 host_cl_id); 58int mei_cl_link(struct mei_cl *cl, int id);
59int mei_cl_unlink(struct mei_cl *cl); 59int mei_cl_unlink(struct mei_cl *cl);
60 60
61int mei_cl_flush_queues(struct mei_cl *cl); 61int mei_cl_flush_queues(struct mei_cl *cl);
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 636639fbfc0a..9e4011ef8508 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)
242 /* remove entry if already in list */ 242 /* remove entry if already in list */
243 dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n"); 243 dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n");
244 mei_cl_unlink(&dev->wd_cl); 244 mei_cl_unlink(&dev->wd_cl);
245 if (dev->open_handle_count > 0)
246 dev->open_handle_count--;
245 mei_cl_unlink(&dev->iamthif_cl); 247 mei_cl_unlink(&dev->iamthif_cl);
248 if (dev->open_handle_count > 0)
249 dev->open_handle_count--;
246 250
247 mei_amthif_reset_params(dev); 251 mei_amthif_reset_params(dev);
248 memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg)); 252 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 d5d1a5957d5f..ec5fd7a0e289 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)
103{ 103{
104 struct mei_cl *cl; 104 struct mei_cl *cl;
105 struct mei_device *dev; 105 struct mei_device *dev;
106 unsigned long cl_id;
107 int err; 106 int err;
108 107
109 err = -ENODEV; 108 err = -ENODEV;
@@ -133,24 +132,9 @@ static int mei_open(struct inode *inode, struct file *file)
133 goto out_unlock; 132 goto out_unlock;
134 } 133 }
135 134
136 cl_id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX); 135 err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY);
137 if (cl_id >= MEI_CLIENTS_MAX) { 136 if (err)
138 dev_err(&dev->pdev->dev, "client_id exceded %d",
139 MEI_CLIENTS_MAX) ;
140 goto out_unlock; 137 goto out_unlock;
141 }
142
143 cl->host_client_id = cl_id;
144
145 dev_dbg(&dev->pdev->dev, "client_id = %d\n", cl->host_client_id);
146
147 dev->open_handle_count++;
148
149 list_add_tail(&cl->link, &dev->file_list);
150
151 set_bit(cl->host_client_id, dev->host_clients_map);
152 cl->state = MEI_FILE_INITIALIZING;
153 cl->sm_state = 0;
154 138
155 file->private_data = cl; 139 file->private_data = cl;
156 mutex_unlock(&dev->device_lock); 140 mutex_unlock(&dev->device_lock);
@@ -209,6 +193,7 @@ static int mei_release(struct inode *inode, struct file *file)
209 } 193 }
210 mei_cl_unlink(cl); 194 mei_cl_unlink(cl);
211 195
196
212 /* free read cb */ 197 /* free read cb */
213 cb = NULL; 198 cb = NULL;
214 if (cl->read_cb) { 199 if (cl->read_cb) {
@@ -991,7 +976,13 @@ static void mei_remove(struct pci_dev *pdev)
991 976
992 /* remove entry if already in list */ 977 /* remove entry if already in list */
993 dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n"); 978 dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
979
980 if (dev->open_handle_count > 0)
981 dev->open_handle_count--;
994 mei_cl_unlink(&dev->wd_cl); 982 mei_cl_unlink(&dev->wd_cl);
983
984 if (dev->open_handle_count > 0)
985 dev->open_handle_count--;
995 mei_cl_unlink(&dev->iamthif_cl); 986 mei_cl_unlink(&dev->iamthif_cl);
996 987
997 dev->iamthif_current_cb = NULL; 988 dev->iamthif_current_cb = NULL;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 285e8e01d429..dcd7a44a806e 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];
67 * Number of File descriptors/handles 67 * Number of File descriptors/handles
68 * that can be opened to the driver. 68 * that can be opened to the driver.
69 * 69 *
70 * Limit to 253: 256 Total Clients 70 * Limit to 255: 256 Total Clients
71 * minus internal client for MEI Bus Messags 71 * minus internal client for MEI Bus Messags
72 * minus internal client for AMTHI
73 * minus internal client for Watchdog
74 */ 72 */
75#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 3) 73#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1)
76 74
77/* 75/*
78 * Internal Clients Number 76 * Internal Clients Number
79 */ 77 */
78#define MEI_HOST_CLIENT_ID_ANY (-1)
79#define MEI_HBM_HOST_CLIENT_ID 0 /* not used, just for documentation */
80#define MEI_WD_HOST_CLIENT_ID 1 80#define MEI_WD_HOST_CLIENT_ID 1
81#define MEI_IAMTHIF_HOST_CLIENT_ID 2 81#define MEI_IAMTHIF_HOST_CLIENT_ID 2
82 82
@@ -339,7 +339,7 @@ void mei_timer(struct work_struct *work);
339 */ 339 */
340void mei_amthif_reset_params(struct mei_device *dev); 340void mei_amthif_reset_params(struct mei_device *dev);
341 341
342void mei_amthif_host_init(struct mei_device *dev); 342int mei_amthif_host_init(struct mei_device *dev);
343 343
344int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb); 344int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb);
345 345
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index bfcbcc8c028b..77b3820380b0 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)
64 */ 64 */
65int mei_wd_host_init(struct mei_device *dev) 65int mei_wd_host_init(struct mei_device *dev)
66{ 66{
67 int id; 67 struct mei_cl *cl = &dev->wd_cl;
68 mei_cl_init(&dev->wd_cl, dev); 68 int i;
69 int ret;
70
71 mei_cl_init(cl, dev);
69 72
70 /* look for WD client and connect to it */
71 dev->wd_cl.state = MEI_FILE_DISCONNECTED;
72 dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT; 73 dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT;
73 dev->wd_state = MEI_WD_IDLE; 74 dev->wd_state = MEI_WD_IDLE;
74 75
75 /* Connect WD ME client to the host client */
76 id = mei_cl_link_me(&dev->wd_cl,
77 &mei_wd_guid, MEI_WD_HOST_CLIENT_ID);
78 76
79 if (id < 0) { 77 /* check for valid client id */
78 i = mei_me_cl_by_uuid(dev, &mei_wd_guid);
79 if (i < 0) {
80 dev_info(&dev->pdev->dev, "wd: failed to find the client\n"); 80 dev_info(&dev->pdev->dev, "wd: failed to find the client\n");
81 return -ENOENT; 81 return -ENOENT;
82 } 82 }
83 83
84 if (mei_hbm_cl_connect_req(dev, &dev->wd_cl)) { 84 cl->me_client_id = dev->me_clients[i].client_id;
85
86 ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID);
87
88 if (ret < 0) {
89 dev_info(&dev->pdev->dev, "wd: failed link client\n");
90 return -ENOENT;
91 }
92
93 cl->state = MEI_FILE_CONNECTING;
94
95 if (mei_hbm_cl_connect_req(dev, cl)) {
85 dev_err(&dev->pdev->dev, "wd: failed to connect to the client\n"); 96 dev_err(&dev->pdev->dev, "wd: failed to connect to the client\n");
86 dev->wd_cl.state = MEI_FILE_DISCONNECTED; 97 cl->state = MEI_FILE_DISCONNECTED;
87 dev->wd_cl.host_client_id = 0; 98 cl->host_client_id = 0;
88 return -EIO; 99 return -EIO;
89 } 100 }
90 dev->wd_cl.timer_count = MEI_CONNECT_TIMEOUT; 101 cl->timer_count = MEI_CONNECT_TIMEOUT;
91 102
92 return 0; 103 return 0;
93} 104}