aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r--drivers/misc/mei/Kconfig15
-rw-r--r--drivers/misc/mei/Makefile6
-rw-r--r--drivers/misc/mei/amthif.c164
-rw-r--r--drivers/misc/mei/client.c729
-rw-r--r--drivers/misc/mei/client.h102
-rw-r--r--drivers/misc/mei/hbm.c669
-rw-r--r--drivers/misc/mei/hbm.h39
-rw-r--r--drivers/misc/mei/hw-me-regs.h167
-rw-r--r--drivers/misc/mei/hw-me.c576
-rw-r--r--drivers/misc/mei/hw-me.h48
-rw-r--r--drivers/misc/mei/hw.h125
-rw-r--r--drivers/misc/mei/init.c572
-rw-r--r--drivers/misc/mei/interface.c388
-rw-r--r--drivers/misc/mei/interface.h81
-rw-r--r--drivers/misc/mei/interrupt.c656
-rw-r--r--drivers/misc/mei/iorw.c366
-rw-r--r--drivers/misc/mei/main.c536
-rw-r--r--drivers/misc/mei/mei_dev.h350
-rw-r--r--drivers/misc/mei/pci-me.c396
-rw-r--r--drivers/misc/mei/wd.c77
20 files changed, 3290 insertions, 2772 deletions
diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index 5a79ccde2fdf..d21b4d006a55 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -1,11 +1,22 @@
1config INTEL_MEI 1config INTEL_MEI
2 tristate "Intel Management Engine Interface (Intel MEI)" 2 tristate "Intel Management Engine Interface"
3 depends on X86 && PCI && WATCHDOG_CORE 3 depends on X86 && PCI && WATCHDOG_CORE
4 help 4 help
5 The Intel Management Engine (Intel ME) provides Manageability, 5 The Intel Management Engine (Intel ME) provides Manageability,
6 Security and Media services for system containing Intel chipsets. 6 Security and Media services for system containing Intel chipsets.
7 if selected /dev/mei misc device will be created. 7 if selected /dev/mei misc device will be created.
8 8
9 For more information see
10 <http://software.intel.com/en-us/manageability/>
11
12config INTEL_MEI_ME
13 bool "ME Enabled Intel Chipsets"
14 depends on INTEL_MEI
15 depends on X86 && PCI && WATCHDOG_CORE
16 default y
17 help
18 MEI support for ME Enabled Intel chipsets.
19
9 Supported Chipsets are: 20 Supported Chipsets are:
10 7 Series Chipset Family 21 7 Series Chipset Family
11 6 Series Chipset Family 22 6 Series Chipset Family
@@ -24,5 +35,3 @@ config INTEL_MEI
24 82Q33 Express 35 82Q33 Express
25 82X38/X48 Express 36 82X38/X48 Express
26 37
27 For more information see
28 <http://software.intel.com/en-us/manageability/>
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index 0017842e166c..040af6c7b147 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -4,9 +4,11 @@
4# 4#
5obj-$(CONFIG_INTEL_MEI) += mei.o 5obj-$(CONFIG_INTEL_MEI) += mei.o
6mei-objs := init.o 6mei-objs := init.o
7mei-objs += hbm.o
7mei-objs += interrupt.o 8mei-objs += interrupt.o
8mei-objs += interface.o 9mei-objs += client.o
9mei-objs += iorw.o
10mei-objs += main.o 10mei-objs += main.o
11mei-objs += amthif.o 11mei-objs += amthif.o
12mei-objs += wd.o 12mei-objs += wd.o
13mei-$(CONFIG_INTEL_MEI_ME) += pci-me.o
14mei-$(CONFIG_INTEL_MEI_ME) += hw-me.o
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index e40ffd9502d1..c86d7e3839a4 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -31,15 +31,16 @@
31#include <linux/jiffies.h> 31#include <linux/jiffies.h>
32#include <linux/uaccess.h> 32#include <linux/uaccess.h>
33 33
34#include <linux/mei.h>
34 35
35#include "mei_dev.h" 36#include "mei_dev.h"
36#include "hw.h" 37#include "hbm.h"
37#include <linux/mei.h> 38#include "hw-me.h"
38#include "interface.h" 39#include "client.h"
39 40
40const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, 41const uuid_le mei_amthif_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d,
41 0xa8, 0x46, 0xe0, 0xff, 0x65, 42 0xac, 0xa8, 0x46, 0xe0,
42 0x81, 0x4c); 43 0xff, 0x65, 0x81, 0x4c);
43 44
44/** 45/**
45 * mei_amthif_reset_params - initializes mei device iamthif 46 * mei_amthif_reset_params - initializes mei device iamthif
@@ -64,22 +65,24 @@ void mei_amthif_reset_params(struct mei_device *dev)
64 * @dev: the device structure 65 * @dev: the device structure
65 * 66 *
66 */ 67 */
67void mei_amthif_host_init(struct mei_device *dev) 68int mei_amthif_host_init(struct mei_device *dev)
68{ 69{
69 int i; 70 struct mei_cl *cl = &dev->iamthif_cl;
70 unsigned char *msg_buf; 71 unsigned char *msg_buf;
72 int ret, i;
73
74 dev->iamthif_state = MEI_IAMTHIF_IDLE;
71 75
72 mei_cl_init(&dev->iamthif_cl, dev); 76 mei_cl_init(cl, dev);
73 dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
74 77
75 /* find ME amthi client */ 78 i = mei_me_cl_by_uuid(dev, &mei_amthif_guid);
76 i = mei_me_cl_link(dev, &dev->iamthif_cl,
77 &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
78 if (i < 0) { 79 if (i < 0) {
79 dev_info(&dev->pdev->dev, "failed to find iamthif client.\n"); 80 dev_info(&dev->pdev->dev, "amthif: failed to find the client\n");
80 return; 81 return -ENOENT;
81 } 82 }
82 83
84 cl->me_client_id = dev->me_clients[i].client_id;
85
83 /* Assign iamthif_mtu to the value received from ME */ 86 /* Assign iamthif_mtu to the value received from ME */
84 87
85 dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length; 88 dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length;
@@ -93,19 +96,29 @@ void mei_amthif_host_init(struct mei_device *dev)
93 msg_buf = kcalloc(dev->iamthif_mtu, 96 msg_buf = kcalloc(dev->iamthif_mtu,
94 sizeof(unsigned char), GFP_KERNEL); 97 sizeof(unsigned char), GFP_KERNEL);
95 if (!msg_buf) { 98 if (!msg_buf) {
96 dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n"); 99 dev_err(&dev->pdev->dev, "amthif: memory allocation for ME message buffer failed.\n");
97 return; 100 return -ENOMEM;
98 } 101 }
99 102
100 dev->iamthif_msg_buf = msg_buf; 103 dev->iamthif_msg_buf = msg_buf;
101 104
102 if (mei_connect(dev, &dev->iamthif_cl)) { 105 ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID);
103 dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n"); 106
104 dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; 107 if (ret < 0) {
105 dev->iamthif_cl.host_client_id = 0; 108 dev_err(&dev->pdev->dev, "amthif: failed link client\n");
109 return -ENOENT;
110 }
111
112 cl->state = MEI_FILE_CONNECTING;
113
114 if (mei_hbm_cl_connect_req(dev, cl)) {
115 dev_dbg(&dev->pdev->dev, "amthif: Failed to connect to ME client\n");
116 cl->state = MEI_FILE_DISCONNECTED;
117 cl->host_client_id = 0;
106 } else { 118 } else {
107 dev->iamthif_cl.timer_count = MEI_CONNECT_TIMEOUT; 119 cl->timer_count = MEI_CONNECT_TIMEOUT;
108 } 120 }
121 return 0;
109} 122}
110 123
111/** 124/**
@@ -168,10 +181,10 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
168 i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id); 181 i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id);
169 182
170 if (i < 0) { 183 if (i < 0) {
171 dev_dbg(&dev->pdev->dev, "amthi client not found.\n"); 184 dev_dbg(&dev->pdev->dev, "amthif client not found.\n");
172 return -ENODEV; 185 return -ENODEV;
173 } 186 }
174 dev_dbg(&dev->pdev->dev, "checking amthi data\n"); 187 dev_dbg(&dev->pdev->dev, "checking amthif data\n");
175 cb = mei_amthif_find_read_list_entry(dev, file); 188 cb = mei_amthif_find_read_list_entry(dev, file);
176 189
177 /* Check for if we can block or not*/ 190 /* Check for if we can block or not*/
@@ -179,7 +192,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
179 return -EAGAIN; 192 return -EAGAIN;
180 193
181 194
182 dev_dbg(&dev->pdev->dev, "waiting for amthi data\n"); 195 dev_dbg(&dev->pdev->dev, "waiting for amthif data\n");
183 while (cb == NULL) { 196 while (cb == NULL) {
184 /* unlock the Mutex */ 197 /* unlock the Mutex */
185 mutex_unlock(&dev->device_lock); 198 mutex_unlock(&dev->device_lock);
@@ -197,17 +210,17 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
197 } 210 }
198 211
199 212
200 dev_dbg(&dev->pdev->dev, "Got amthi data\n"); 213 dev_dbg(&dev->pdev->dev, "Got amthif data\n");
201 dev->iamthif_timer = 0; 214 dev->iamthif_timer = 0;
202 215
203 if (cb) { 216 if (cb) {
204 timeout = cb->read_time + 217 timeout = cb->read_time +
205 mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER); 218 mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
206 dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n", 219 dev_dbg(&dev->pdev->dev, "amthif timeout = %lud\n",
207 timeout); 220 timeout);
208 221
209 if (time_after(jiffies, timeout)) { 222 if (time_after(jiffies, timeout)) {
210 dev_dbg(&dev->pdev->dev, "amthi Time out\n"); 223 dev_dbg(&dev->pdev->dev, "amthif Time out\n");
211 /* 15 sec for the message has expired */ 224 /* 15 sec for the message has expired */
212 list_del(&cb->list); 225 list_del(&cb->list);
213 rets = -ETIMEDOUT; 226 rets = -ETIMEDOUT;
@@ -227,9 +240,9 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
227 * remove message from deletion list 240 * remove message from deletion list
228 */ 241 */
229 242
230 dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n", 243 dev_dbg(&dev->pdev->dev, "amthif cb->response_buffer size - %d\n",
231 cb->response_buffer.size); 244 cb->response_buffer.size);
232 dev_dbg(&dev->pdev->dev, "amthi cb->buf_idx - %lu\n", cb->buf_idx); 245 dev_dbg(&dev->pdev->dev, "amthif cb->buf_idx - %lu\n", cb->buf_idx);
233 246
234 /* length is being turncated to PAGE_SIZE, however, 247 /* length is being turncated to PAGE_SIZE, however,
235 * the buf_idx may point beyond */ 248 * the buf_idx may point beyond */
@@ -245,7 +258,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
245 } 258 }
246 } 259 }
247free: 260free:
248 dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n"); 261 dev_dbg(&dev->pdev->dev, "free amthif cb memory.\n");
249 *offset = 0; 262 *offset = 0;
250 mei_io_cb_free(cb); 263 mei_io_cb_free(cb);
251out: 264out:
@@ -269,7 +282,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
269 if (!dev || !cb) 282 if (!dev || !cb)
270 return -ENODEV; 283 return -ENODEV;
271 284
272 dev_dbg(&dev->pdev->dev, "write data to amthi client.\n"); 285 dev_dbg(&dev->pdev->dev, "write data to amthif client.\n");
273 286
274 dev->iamthif_state = MEI_IAMTHIF_WRITING; 287 dev->iamthif_state = MEI_IAMTHIF_WRITING;
275 dev->iamthif_current_cb = cb; 288 dev->iamthif_current_cb = cb;
@@ -280,15 +293,15 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
280 memcpy(dev->iamthif_msg_buf, cb->request_buffer.data, 293 memcpy(dev->iamthif_msg_buf, cb->request_buffer.data,
281 cb->request_buffer.size); 294 cb->request_buffer.size);
282 295
283 ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl); 296 ret = mei_cl_flow_ctrl_creds(&dev->iamthif_cl);
284 if (ret < 0) 297 if (ret < 0)
285 return ret; 298 return ret;
286 299
287 if (ret && dev->mei_host_buffer_is_empty) { 300 if (ret && dev->hbuf_is_ready) {
288 ret = 0; 301 ret = 0;
289 dev->mei_host_buffer_is_empty = false; 302 dev->hbuf_is_ready = false;
290 if (cb->request_buffer.size > mei_hbuf_max_data(dev)) { 303 if (cb->request_buffer.size > mei_hbuf_max_len(dev)) {
291 mei_hdr.length = mei_hbuf_max_data(dev); 304 mei_hdr.length = mei_hbuf_max_len(dev);
292 mei_hdr.msg_complete = 0; 305 mei_hdr.msg_complete = 0;
293 } else { 306 } else {
294 mei_hdr.length = cb->request_buffer.size; 307 mei_hdr.length = cb->request_buffer.size;
@@ -300,25 +313,24 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
300 mei_hdr.reserved = 0; 313 mei_hdr.reserved = 0;
301 dev->iamthif_msg_buf_index += mei_hdr.length; 314 dev->iamthif_msg_buf_index += mei_hdr.length;
302 if (mei_write_message(dev, &mei_hdr, 315 if (mei_write_message(dev, &mei_hdr,
303 (unsigned char *)(dev->iamthif_msg_buf), 316 (unsigned char *)dev->iamthif_msg_buf))
304 mei_hdr.length))
305 return -ENODEV; 317 return -ENODEV;
306 318
307 if (mei_hdr.msg_complete) { 319 if (mei_hdr.msg_complete) {
308 if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl)) 320 if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl))
309 return -ENODEV; 321 return -ENODEV;
310 dev->iamthif_flow_control_pending = true; 322 dev->iamthif_flow_control_pending = true;
311 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; 323 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
312 dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n"); 324 dev_dbg(&dev->pdev->dev, "add amthif cb to write waiting list\n");
313 dev->iamthif_current_cb = cb; 325 dev->iamthif_current_cb = cb;
314 dev->iamthif_file_object = cb->file_object; 326 dev->iamthif_file_object = cb->file_object;
315 list_add_tail(&cb->list, &dev->write_waiting_list.list); 327 list_add_tail(&cb->list, &dev->write_waiting_list.list);
316 } else { 328 } else {
317 dev_dbg(&dev->pdev->dev, "message does not complete, so add amthi cb to write list.\n"); 329 dev_dbg(&dev->pdev->dev, "message does not complete, so add amthif cb to write list.\n");
318 list_add_tail(&cb->list, &dev->write_list.list); 330 list_add_tail(&cb->list, &dev->write_list.list);
319 } 331 }
320 } else { 332 } else {
321 if (!(dev->mei_host_buffer_is_empty)) 333 if (!dev->hbuf_is_ready)
322 dev_dbg(&dev->pdev->dev, "host buffer is not empty"); 334 dev_dbg(&dev->pdev->dev, "host buffer is not empty");
323 335
324 dev_dbg(&dev->pdev->dev, "No flow control credentials, so add iamthif cb to write list.\n"); 336 dev_dbg(&dev->pdev->dev, "No flow control credentials, so add iamthif cb to write list.\n");
@@ -383,7 +395,7 @@ void mei_amthif_run_next_cmd(struct mei_device *dev)
383 dev->iamthif_timer = 0; 395 dev->iamthif_timer = 0;
384 dev->iamthif_file_object = NULL; 396 dev->iamthif_file_object = NULL;
385 397
386 dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n"); 398 dev_dbg(&dev->pdev->dev, "complete amthif cmd_list cb.\n");
387 399
388 list_for_each_entry_safe(pos, next, &dev->amthif_cmd_list.list, list) { 400 list_for_each_entry_safe(pos, next, &dev->amthif_cmd_list.list, list) {
389 list_del(&pos->list); 401 list_del(&pos->list);
@@ -392,7 +404,7 @@ void mei_amthif_run_next_cmd(struct mei_device *dev)
392 status = mei_amthif_send_cmd(dev, pos); 404 status = mei_amthif_send_cmd(dev, pos);
393 if (status) { 405 if (status) {
394 dev_dbg(&dev->pdev->dev, 406 dev_dbg(&dev->pdev->dev,
395 "amthi write failed status = %d\n", 407 "amthif write failed status = %d\n",
396 status); 408 status);
397 return; 409 return;
398 } 410 }
@@ -412,7 +424,7 @@ unsigned int mei_amthif_poll(struct mei_device *dev,
412 if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && 424 if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE &&
413 dev->iamthif_file_object == file) { 425 dev->iamthif_file_object == file) {
414 mask |= (POLLIN | POLLRDNORM); 426 mask |= (POLLIN | POLLRDNORM);
415 dev_dbg(&dev->pdev->dev, "run next amthi cb\n"); 427 dev_dbg(&dev->pdev->dev, "run next amthif cb\n");
416 mei_amthif_run_next_cmd(dev); 428 mei_amthif_run_next_cmd(dev);
417 } 429 }
418 return mask; 430 return mask;
@@ -434,54 +446,51 @@ unsigned int mei_amthif_poll(struct mei_device *dev,
434int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, 446int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
435 struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) 447 struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
436{ 448{
437 struct mei_msg_hdr *mei_hdr; 449 struct mei_msg_hdr mei_hdr;
438 struct mei_cl *cl = cb->cl; 450 struct mei_cl *cl = cb->cl;
439 size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index; 451 size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
440 size_t msg_slots = mei_data2slots(len); 452 size_t msg_slots = mei_data2slots(len);
441 453
442 mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; 454 mei_hdr.host_addr = cl->host_client_id;
443 mei_hdr->host_addr = cl->host_client_id; 455 mei_hdr.me_addr = cl->me_client_id;
444 mei_hdr->me_addr = cl->me_client_id; 456 mei_hdr.reserved = 0;
445 mei_hdr->reserved = 0;
446 457
447 if (*slots >= msg_slots) { 458 if (*slots >= msg_slots) {
448 mei_hdr->length = len; 459 mei_hdr.length = len;
449 mei_hdr->msg_complete = 1; 460 mei_hdr.msg_complete = 1;
450 /* Split the message only if we can write the whole host buffer */ 461 /* Split the message only if we can write the whole host buffer */
451 } else if (*slots == dev->hbuf_depth) { 462 } else if (*slots == dev->hbuf_depth) {
452 msg_slots = *slots; 463 msg_slots = *slots;
453 len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); 464 len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
454 mei_hdr->length = len; 465 mei_hdr.length = len;
455 mei_hdr->msg_complete = 0; 466 mei_hdr.msg_complete = 0;
456 } else { 467 } else {
457 /* wait for next time the host buffer is empty */ 468 /* wait for next time the host buffer is empty */
458 return 0; 469 return 0;
459 } 470 }
460 471
461 dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n", 472 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
462 mei_hdr->length, mei_hdr->msg_complete);
463 473
464 *slots -= msg_slots; 474 *slots -= msg_slots;
465 if (mei_write_message(dev, mei_hdr, 475 if (mei_write_message(dev, &mei_hdr,
466 dev->iamthif_msg_buf + dev->iamthif_msg_buf_index, 476 dev->iamthif_msg_buf + dev->iamthif_msg_buf_index)) {
467 mei_hdr->length)) {
468 dev->iamthif_state = MEI_IAMTHIF_IDLE; 477 dev->iamthif_state = MEI_IAMTHIF_IDLE;
469 cl->status = -ENODEV; 478 cl->status = -ENODEV;
470 list_del(&cb->list); 479 list_del(&cb->list);
471 return -ENODEV; 480 return -ENODEV;
472 } 481 }
473 482
474 if (mei_flow_ctrl_reduce(dev, cl)) 483 if (mei_cl_flow_ctrl_reduce(cl))
475 return -ENODEV; 484 return -ENODEV;
476 485
477 dev->iamthif_msg_buf_index += mei_hdr->length; 486 dev->iamthif_msg_buf_index += mei_hdr.length;
478 cl->status = 0; 487 cl->status = 0;
479 488
480 if (mei_hdr->msg_complete) { 489 if (mei_hdr.msg_complete) {
481 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; 490 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
482 dev->iamthif_flow_control_pending = true; 491 dev->iamthif_flow_control_pending = true;
483 492
484 /* save iamthif cb sent to amthi client */ 493 /* save iamthif cb sent to amthif client */
485 cb->buf_idx = dev->iamthif_msg_buf_index; 494 cb->buf_idx = dev->iamthif_msg_buf_index;
486 dev->iamthif_current_cb = cb; 495 dev->iamthif_current_cb = cb;
487 496
@@ -494,11 +503,11 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
494 503
495/** 504/**
496 * mei_amthif_irq_read_message - read routine after ISR to 505 * mei_amthif_irq_read_message - read routine after ISR to
497 * handle the read amthi message 506 * handle the read amthif message
498 * 507 *
499 * @complete_list: An instance of our list structure 508 * @complete_list: An instance of our list structure
500 * @dev: the device structure 509 * @dev: the device structure
501 * @mei_hdr: header of amthi message 510 * @mei_hdr: header of amthif message
502 * 511 *
503 * returns 0 on success, <0 on failure. 512 * returns 0 on success, <0 on failure.
504 */ 513 */
@@ -522,10 +531,10 @@ int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
522 return 0; 531 return 0;
523 532
524 dev_dbg(&dev->pdev->dev, 533 dev_dbg(&dev->pdev->dev,
525 "amthi_message_buffer_index =%d\n", 534 "amthif_message_buffer_index =%d\n",
526 mei_hdr->length); 535 mei_hdr->length);
527 536
528 dev_dbg(&dev->pdev->dev, "completed amthi read.\n "); 537 dev_dbg(&dev->pdev->dev, "completed amthif read.\n ");
529 if (!dev->iamthif_current_cb) 538 if (!dev->iamthif_current_cb)
530 return -ENODEV; 539 return -ENODEV;
531 540
@@ -540,8 +549,8 @@ int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
540 cb->read_time = jiffies; 549 cb->read_time = jiffies;
541 if (dev->iamthif_ioctl && cb->cl == &dev->iamthif_cl) { 550 if (dev->iamthif_ioctl && cb->cl == &dev->iamthif_cl) {
542 /* found the iamthif cb */ 551 /* found the iamthif cb */
543 dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n "); 552 dev_dbg(&dev->pdev->dev, "complete the amthif read cb.\n ");
544 dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n "); 553 dev_dbg(&dev->pdev->dev, "add the amthif read cb to complete.\n ");
545 list_add_tail(&cb->list, &complete_list->list); 554 list_add_tail(&cb->list, &complete_list->list);
546 } 555 }
547 return 0; 556 return 0;
@@ -563,7 +572,7 @@ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots)
563 return -EMSGSIZE; 572 return -EMSGSIZE;
564 } 573 }
565 *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); 574 *slots -= mei_data2slots(sizeof(struct hbm_flow_control));
566 if (mei_send_flow_control(dev, &dev->iamthif_cl)) { 575 if (mei_hbm_cl_flow_control_req(dev, &dev->iamthif_cl)) {
567 dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); 576 dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n");
568 return -EIO; 577 return -EIO;
569 } 578 }
@@ -574,7 +583,7 @@ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots)
574 dev->iamthif_msg_buf_index = 0; 583 dev->iamthif_msg_buf_index = 0;
575 dev->iamthif_msg_buf_size = 0; 584 dev->iamthif_msg_buf_size = 0;
576 dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER; 585 dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER;
577 dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); 586 dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
578 return 0; 587 return 0;
579} 588}
580 589
@@ -593,7 +602,7 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
593 dev->iamthif_msg_buf, 602 dev->iamthif_msg_buf,
594 dev->iamthif_msg_buf_index); 603 dev->iamthif_msg_buf_index);
595 list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list); 604 list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list);
596 dev_dbg(&dev->pdev->dev, "amthi read completed\n"); 605 dev_dbg(&dev->pdev->dev, "amthif read completed\n");
597 dev->iamthif_timer = jiffies; 606 dev->iamthif_timer = jiffies;
598 dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", 607 dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
599 dev->iamthif_timer); 608 dev->iamthif_timer);
@@ -601,7 +610,7 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
601 mei_amthif_run_next_cmd(dev); 610 mei_amthif_run_next_cmd(dev);
602 } 611 }
603 612
604 dev_dbg(&dev->pdev->dev, "completing amthi call back.\n"); 613 dev_dbg(&dev->pdev->dev, "completing amthif call back.\n");
605 wake_up_interruptible(&dev->iamthif_cl.wait); 614 wake_up_interruptible(&dev->iamthif_cl.wait);
606} 615}
607 616
@@ -635,7 +644,8 @@ static bool mei_clear_list(struct mei_device *dev,
635 if (dev->iamthif_current_cb == cb_pos) { 644 if (dev->iamthif_current_cb == cb_pos) {
636 dev->iamthif_current_cb = NULL; 645 dev->iamthif_current_cb = NULL;
637 /* send flow control to iamthif client */ 646 /* send flow control to iamthif client */
638 mei_send_flow_control(dev, &dev->iamthif_cl); 647 mei_hbm_cl_flow_control_req(dev,
648 &dev->iamthif_cl);
639 } 649 }
640 /* free all allocated buffers */ 650 /* free all allocated buffers */
641 mei_io_cb_free(cb_pos); 651 mei_io_cb_free(cb_pos);
@@ -706,11 +716,11 @@ int mei_amthif_release(struct mei_device *dev, struct file *file)
706 if (dev->iamthif_file_object == file && 716 if (dev->iamthif_file_object == file &&
707 dev->iamthif_state != MEI_IAMTHIF_IDLE) { 717 dev->iamthif_state != MEI_IAMTHIF_IDLE) {
708 718
709 dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n", 719 dev_dbg(&dev->pdev->dev, "amthif canceled iamthif state %d\n",
710 dev->iamthif_state); 720 dev->iamthif_state);
711 dev->iamthif_canceled = true; 721 dev->iamthif_canceled = true;
712 if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) { 722 if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) {
713 dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n"); 723 dev_dbg(&dev->pdev->dev, "run next amthif iamthif cb\n");
714 mei_amthif_run_next_cmd(dev); 724 mei_amthif_run_next_cmd(dev);
715 } 725 }
716 } 726 }
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
new file mode 100644
index 000000000000..1569afe935de
--- /dev/null
+++ b/drivers/misc/mei/client.c
@@ -0,0 +1,729 @@
1/*
2 *
3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 */
16
17#include <linux/pci.h>
18#include <linux/sched.h>
19#include <linux/wait.h>
20#include <linux/delay.h>
21
22#include <linux/mei.h>
23
24#include "mei_dev.h"
25#include "hbm.h"
26#include "client.h"
27
28/**
29 * mei_me_cl_by_uuid - locate index of me client
30 *
31 * @dev: mei device
32 * returns me client index or -ENOENT if not found
33 */
34int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *uuid)
35{
36 int i, res = -ENOENT;
37
38 for (i = 0; i < dev->me_clients_num; ++i)
39 if (uuid_le_cmp(*uuid,
40 dev->me_clients[i].props.protocol_name) == 0) {
41 res = i;
42 break;
43 }
44
45 return res;
46}
47
48
49/**
50 * mei_me_cl_by_id return index to me_clients for client_id
51 *
52 * @dev: the device structure
53 * @client_id: me client id
54 *
55 * Locking: called under "dev->device_lock" lock
56 *
57 * returns index on success, -ENOENT on failure.
58 */
59
60int mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
61{
62 int i;
63 for (i = 0; i < dev->me_clients_num; i++)
64 if (dev->me_clients[i].client_id == client_id)
65 break;
66 if (WARN_ON(dev->me_clients[i].client_id != client_id))
67 return -ENOENT;
68
69 if (i == dev->me_clients_num)
70 return -ENOENT;
71
72 return i;
73}
74
75
76/**
77 * mei_io_list_flush - removes list entry belonging to cl.
78 *
79 * @list: An instance of our list structure
80 * @cl: host client
81 */
82void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
83{
84 struct mei_cl_cb *cb;
85 struct mei_cl_cb *next;
86
87 list_for_each_entry_safe(cb, next, &list->list, list) {
88 if (cb->cl && mei_cl_cmp_id(cl, cb->cl))
89 list_del(&cb->list);
90 }
91}
92
93/**
94 * mei_io_cb_free - free mei_cb_private related memory
95 *
96 * @cb: mei callback struct
97 */
98void mei_io_cb_free(struct mei_cl_cb *cb)
99{
100 if (cb == NULL)
101 return;
102
103 kfree(cb->request_buffer.data);
104 kfree(cb->response_buffer.data);
105 kfree(cb);
106}
107
108/**
109 * mei_io_cb_init - allocate and initialize io callback
110 *
111 * @cl - mei client
112 * @file: pointer to file structure
113 *
114 * returns mei_cl_cb pointer or NULL;
115 */
116struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp)
117{
118 struct mei_cl_cb *cb;
119
120 cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
121 if (!cb)
122 return NULL;
123
124 mei_io_list_init(cb);
125
126 cb->file_object = fp;
127 cb->cl = cl;
128 cb->buf_idx = 0;
129 return cb;
130}
131
132/**
133 * mei_io_cb_alloc_req_buf - allocate request buffer
134 *
135 * @cb - io callback structure
136 * @size: size of the buffer
137 *
138 * returns 0 on success
139 * -EINVAL if cb is NULL
140 * -ENOMEM if allocation failed
141 */
142int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length)
143{
144 if (!cb)
145 return -EINVAL;
146
147 if (length == 0)
148 return 0;
149
150 cb->request_buffer.data = kmalloc(length, GFP_KERNEL);
151 if (!cb->request_buffer.data)
152 return -ENOMEM;
153 cb->request_buffer.size = length;
154 return 0;
155}
156/**
157 * mei_io_cb_alloc_req_buf - allocate respose buffer
158 *
159 * @cb - io callback structure
160 * @size: size of the buffer
161 *
162 * returns 0 on success
163 * -EINVAL if cb is NULL
164 * -ENOMEM if allocation failed
165 */
166int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length)
167{
168 if (!cb)
169 return -EINVAL;
170
171 if (length == 0)
172 return 0;
173
174 cb->response_buffer.data = kmalloc(length, GFP_KERNEL);
175 if (!cb->response_buffer.data)
176 return -ENOMEM;
177 cb->response_buffer.size = length;
178 return 0;
179}
180
181
182
183/**
184 * mei_cl_flush_queues - flushes queue lists belonging to cl.
185 *
186 * @dev: the device structure
187 * @cl: host client
188 */
189int mei_cl_flush_queues(struct mei_cl *cl)
190{
191 if (WARN_ON(!cl || !cl->dev))
192 return -EINVAL;
193
194 dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n");
195 mei_io_list_flush(&cl->dev->read_list, cl);
196 mei_io_list_flush(&cl->dev->write_list, cl);
197 mei_io_list_flush(&cl->dev->write_waiting_list, cl);
198 mei_io_list_flush(&cl->dev->ctrl_wr_list, cl);
199 mei_io_list_flush(&cl->dev->ctrl_rd_list, cl);
200 mei_io_list_flush(&cl->dev->amthif_cmd_list, cl);
201 mei_io_list_flush(&cl->dev->amthif_rd_complete_list, cl);
202 return 0;
203}
204
205
206/**
207 * mei_cl_init - initializes intialize cl.
208 *
209 * @cl: host client to be initialized
210 * @dev: mei device
211 */
212void mei_cl_init(struct mei_cl *cl, struct mei_device *dev)
213{
214 memset(cl, 0, sizeof(struct mei_cl));
215 init_waitqueue_head(&cl->wait);
216 init_waitqueue_head(&cl->rx_wait);
217 init_waitqueue_head(&cl->tx_wait);
218 INIT_LIST_HEAD(&cl->link);
219 cl->reading_state = MEI_IDLE;
220 cl->writing_state = MEI_IDLE;
221 cl->dev = dev;
222}
223
224/**
225 * mei_cl_allocate - allocates cl structure and sets it up.
226 *
227 * @dev: mei device
228 * returns The allocated file or NULL on failure
229 */
230struct mei_cl *mei_cl_allocate(struct mei_device *dev)
231{
232 struct mei_cl *cl;
233
234 cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL);
235 if (!cl)
236 return NULL;
237
238 mei_cl_init(cl, dev);
239
240 return cl;
241}
242
243/**
244 * mei_cl_find_read_cb - find this cl's callback in the read list
245 *
246 * @dev: device structure
247 * returns cb on success, NULL on error
248 */
249struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl)
250{
251 struct mei_device *dev = cl->dev;
252 struct mei_cl_cb *cb = NULL;
253 struct mei_cl_cb *next = NULL;
254
255 list_for_each_entry_safe(cb, next, &dev->read_list.list, list)
256 if (mei_cl_cmp_id(cl, cb->cl))
257 return cb;
258 return NULL;
259}
260
261/** mei_cl_link: allocte host id in the host map
262 *
263 * @cl - host client
264 * @id - fixed host id or -1 for genereting one
265 * returns 0 on success
266 * -EINVAL on incorrect values
267 * -ENONET if client not found
268 */
269int mei_cl_link(struct mei_cl *cl, int id)
270{
271 struct mei_device *dev;
272
273 if (WARN_ON(!cl || !cl->dev))
274 return -EINVAL;
275
276 dev = cl->dev;
277
278 /* If Id is not asigned get one*/
279 if (id == MEI_HOST_CLIENT_ID_ANY)
280 id = find_first_zero_bit(dev->host_clients_map,
281 MEI_CLIENTS_MAX);
282
283 if (id >= MEI_CLIENTS_MAX) {
284 dev_err(&dev->pdev->dev, "id exceded %d", MEI_CLIENTS_MAX) ;
285 return -ENOENT;
286 }
287
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;
299}
300
301/**
302 * mei_cl_unlink - remove me_cl from the list
303 *
304 * @dev: the device structure
305 */
306int mei_cl_unlink(struct mei_cl *cl)
307{
308 struct mei_device *dev;
309 struct mei_cl *pos, *next;
310
311 /* don't shout on error exit path */
312 if (!cl)
313 return 0;
314
315 /* wd and amthif might not be initialized */
316 if (!cl->dev)
317 return 0;
318
319 dev = cl->dev;
320
321 list_for_each_entry_safe(pos, next, &dev->file_list, link) {
322 if (cl->host_client_id == pos->host_client_id) {
323 dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n",
324 pos->host_client_id, pos->me_client_id);
325 list_del_init(&pos->link);
326 break;
327 }
328 }
329 return 0;
330}
331
332
333void mei_host_client_init(struct work_struct *work)
334{
335 struct mei_device *dev = container_of(work,
336 struct mei_device, init_work);
337 struct mei_client_properties *client_props;
338 int i;
339
340 mutex_lock(&dev->device_lock);
341
342 bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
343 dev->open_handle_count = 0;
344
345 /*
346 * Reserving the first three client IDs
347 * 0: Reserved for MEI Bus Message communications
348 * 1: Reserved for Watchdog
349 * 2: Reserved for AMTHI
350 */
351 bitmap_set(dev->host_clients_map, 0, 3);
352
353 for (i = 0; i < dev->me_clients_num; i++) {
354 client_props = &dev->me_clients[i].props;
355
356 if (!uuid_le_cmp(client_props->protocol_name, mei_amthif_guid))
357 mei_amthif_host_init(dev);
358 else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid))
359 mei_wd_host_init(dev);
360 }
361
362 dev->dev_state = MEI_DEV_ENABLED;
363
364 mutex_unlock(&dev->device_lock);
365}
366
367
368/**
369 * mei_cl_disconnect - disconnect host clinet form the me one
370 *
371 * @cl: host client
372 *
373 * Locking: called under "dev->device_lock" lock
374 *
375 * returns 0 on success, <0 on failure.
376 */
377int mei_cl_disconnect(struct mei_cl *cl)
378{
379 struct mei_device *dev;
380 struct mei_cl_cb *cb;
381 int rets, err;
382
383 if (WARN_ON(!cl || !cl->dev))
384 return -ENODEV;
385
386 dev = cl->dev;
387
388 if (cl->state != MEI_FILE_DISCONNECTING)
389 return 0;
390
391 cb = mei_io_cb_init(cl, NULL);
392 if (!cb)
393 return -ENOMEM;
394
395 cb->fop_type = MEI_FOP_CLOSE;
396 if (dev->hbuf_is_ready) {
397 dev->hbuf_is_ready = false;
398 if (mei_hbm_cl_disconnect_req(dev, cl)) {
399 rets = -ENODEV;
400 dev_err(&dev->pdev->dev, "failed to disconnect.\n");
401 goto free;
402 }
403 mdelay(10); /* Wait for hardware disconnection ready */
404 list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
405 } else {
406 dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n");
407 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
408
409 }
410 mutex_unlock(&dev->device_lock);
411
412 err = wait_event_timeout(dev->wait_recvd_msg,
413 MEI_FILE_DISCONNECTED == cl->state,
414 mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
415
416 mutex_lock(&dev->device_lock);
417 if (MEI_FILE_DISCONNECTED == cl->state) {
418 rets = 0;
419 dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n");
420 } else {
421 rets = -ENODEV;
422 if (MEI_FILE_DISCONNECTED != cl->state)
423 dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n");
424
425 if (err)
426 dev_dbg(&dev->pdev->dev,
427 "wait failed disconnect err=%08x\n",
428 err);
429
430 dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n");
431 }
432
433 mei_io_list_flush(&dev->ctrl_rd_list, cl);
434 mei_io_list_flush(&dev->ctrl_wr_list, cl);
435free:
436 mei_io_cb_free(cb);
437 return rets;
438}
439
440
441/**
442 * mei_cl_is_other_connecting - checks if other
443 * client with the same me client id is connecting
444 *
445 * @cl: private data of the file object
446 *
447 * returns ture if other client is connected, 0 - otherwise.
448 */
449bool mei_cl_is_other_connecting(struct mei_cl *cl)
450{
451 struct mei_device *dev;
452 struct mei_cl *pos;
453 struct mei_cl *next;
454
455 if (WARN_ON(!cl || !cl->dev))
456 return false;
457
458 dev = cl->dev;
459
460 list_for_each_entry_safe(pos, next, &dev->file_list, link) {
461 if ((pos->state == MEI_FILE_CONNECTING) &&
462 (pos != cl) && cl->me_client_id == pos->me_client_id)
463 return true;
464
465 }
466
467 return false;
468}
469
470/**
471 * mei_cl_connect - connect host clinet to the me one
472 *
473 * @cl: host client
474 *
475 * Locking: called under "dev->device_lock" lock
476 *
477 * returns 0 on success, <0 on failure.
478 */
479int mei_cl_connect(struct mei_cl *cl, struct file *file)
480{
481 struct mei_device *dev;
482 struct mei_cl_cb *cb;
483 long timeout = mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT);
484 int rets;
485
486 if (WARN_ON(!cl || !cl->dev))
487 return -ENODEV;
488
489 dev = cl->dev;
490
491 cb = mei_io_cb_init(cl, file);
492 if (!cb) {
493 rets = -ENOMEM;
494 goto out;
495 }
496
497 cb->fop_type = MEI_FOP_IOCTL;
498
499 if (dev->hbuf_is_ready && !mei_cl_is_other_connecting(cl)) {
500 dev->hbuf_is_ready = false;
501
502 if (mei_hbm_cl_connect_req(dev, cl)) {
503 rets = -ENODEV;
504 goto out;
505 }
506 cl->timer_count = MEI_CONNECT_TIMEOUT;
507 list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
508 } else {
509 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
510 }
511
512 mutex_unlock(&dev->device_lock);
513 rets = wait_event_timeout(dev->wait_recvd_msg,
514 (cl->state == MEI_FILE_CONNECTED ||
515 cl->state == MEI_FILE_DISCONNECTED),
516 timeout * HZ);
517 mutex_lock(&dev->device_lock);
518
519 if (cl->state != MEI_FILE_CONNECTED) {
520 rets = -EFAULT;
521
522 mei_io_list_flush(&dev->ctrl_rd_list, cl);
523 mei_io_list_flush(&dev->ctrl_wr_list, cl);
524 goto out;
525 }
526
527 rets = cl->status;
528
529out:
530 mei_io_cb_free(cb);
531 return rets;
532}
533
534/**
535 * mei_cl_flow_ctrl_creds - checks flow_control credits for cl.
536 *
537 * @dev: the device structure
538 * @cl: private data of the file object
539 *
540 * returns 1 if mei_flow_ctrl_creds >0, 0 - otherwise.
541 * -ENOENT if mei_cl is not present
542 * -EINVAL if single_recv_buf == 0
543 */
544int mei_cl_flow_ctrl_creds(struct mei_cl *cl)
545{
546 struct mei_device *dev;
547 int i;
548
549 if (WARN_ON(!cl || !cl->dev))
550 return -EINVAL;
551
552 dev = cl->dev;
553
554 if (!dev->me_clients_num)
555 return 0;
556
557 if (cl->mei_flow_ctrl_creds > 0)
558 return 1;
559
560 for (i = 0; i < dev->me_clients_num; i++) {
561 struct mei_me_client *me_cl = &dev->me_clients[i];
562 if (me_cl->client_id == cl->me_client_id) {
563 if (me_cl->mei_flow_ctrl_creds) {
564 if (WARN_ON(me_cl->props.single_recv_buf == 0))
565 return -EINVAL;
566 return 1;
567 } else {
568 return 0;
569 }
570 }
571 }
572 return -ENOENT;
573}
574
575/**
576 * mei_cl_flow_ctrl_reduce - reduces flow_control.
577 *
578 * @dev: the device structure
579 * @cl: private data of the file object
580 * @returns
581 * 0 on success
582 * -ENOENT when me client is not found
583 * -EINVAL when ctrl credits are <= 0
584 */
585int mei_cl_flow_ctrl_reduce(struct mei_cl *cl)
586{
587 struct mei_device *dev;
588 int i;
589
590 if (WARN_ON(!cl || !cl->dev))
591 return -EINVAL;
592
593 dev = cl->dev;
594
595 if (!dev->me_clients_num)
596 return -ENOENT;
597
598 for (i = 0; i < dev->me_clients_num; i++) {
599 struct mei_me_client *me_cl = &dev->me_clients[i];
600 if (me_cl->client_id == cl->me_client_id) {
601 if (me_cl->props.single_recv_buf != 0) {
602 if (WARN_ON(me_cl->mei_flow_ctrl_creds <= 0))
603 return -EINVAL;
604 dev->me_clients[i].mei_flow_ctrl_creds--;
605 } else {
606 if (WARN_ON(cl->mei_flow_ctrl_creds <= 0))
607 return -EINVAL;
608 cl->mei_flow_ctrl_creds--;
609 }
610 return 0;
611 }
612 }
613 return -ENOENT;
614}
615
616/**
617 * mei_cl_start_read - the start read client message function.
618 *
619 * @cl: host client
620 *
621 * returns 0 on success, <0 on failure.
622 */
623int mei_cl_read_start(struct mei_cl *cl)
624{
625 struct mei_device *dev;
626 struct mei_cl_cb *cb;
627 int rets;
628 int i;
629
630 if (WARN_ON(!cl || !cl->dev))
631 return -ENODEV;
632
633 dev = cl->dev;
634
635 if (cl->state != MEI_FILE_CONNECTED)
636 return -ENODEV;
637
638 if (dev->dev_state != MEI_DEV_ENABLED)
639 return -ENODEV;
640
641 if (cl->read_cb) {
642 dev_dbg(&dev->pdev->dev, "read is pending.\n");
643 return -EBUSY;
644 }
645 i = mei_me_cl_by_id(dev, cl->me_client_id);
646 if (i < 0) {
647 dev_err(&dev->pdev->dev, "no such me client %d\n",
648 cl->me_client_id);
649 return -ENODEV;
650 }
651
652 cb = mei_io_cb_init(cl, NULL);
653 if (!cb)
654 return -ENOMEM;
655
656 rets = mei_io_cb_alloc_resp_buf(cb,
657 dev->me_clients[i].props.max_msg_length);
658 if (rets)
659 goto err;
660
661 cb->fop_type = MEI_FOP_READ;
662 cl->read_cb = cb;
663 if (dev->hbuf_is_ready) {
664 dev->hbuf_is_ready = false;
665 if (mei_hbm_cl_flow_control_req(dev, cl)) {
666 rets = -ENODEV;
667 goto err;
668 }
669 list_add_tail(&cb->list, &dev->read_list.list);
670 } else {
671 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
672 }
673 return rets;
674err:
675 mei_io_cb_free(cb);
676 return rets;
677}
678
679/**
680 * mei_cl_all_disconnect - disconnect forcefully all connected clients
681 *
682 * @dev - mei device
683 */
684
685void mei_cl_all_disconnect(struct mei_device *dev)
686{
687 struct mei_cl *cl, *next;
688
689 list_for_each_entry_safe(cl, next, &dev->file_list, link) {
690 cl->state = MEI_FILE_DISCONNECTED;
691 cl->mei_flow_ctrl_creds = 0;
692 cl->read_cb = NULL;
693 cl->timer_count = 0;
694 }
695}
696
697
698/**
699 * mei_cl_all_read_wakeup - wake up all readings so they can be interrupted
700 *
701 * @dev - mei device
702 */
703void mei_cl_all_read_wakeup(struct mei_device *dev)
704{
705 struct mei_cl *cl, *next;
706 list_for_each_entry_safe(cl, next, &dev->file_list, link) {
707 if (waitqueue_active(&cl->rx_wait)) {
708 dev_dbg(&dev->pdev->dev, "Waking up client!\n");
709 wake_up_interruptible(&cl->rx_wait);
710 }
711 }
712}
713
714/**
715 * mei_cl_all_write_clear - clear all pending writes
716
717 * @dev - mei device
718 */
719void mei_cl_all_write_clear(struct mei_device *dev)
720{
721 struct mei_cl_cb *cb, *next;
722
723 list_for_each_entry_safe(cb, next, &dev->write_list.list, list) {
724 list_del(&cb->list);
725 mei_io_cb_free(cb);
726 }
727}
728
729
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
new file mode 100644
index 000000000000..214b2397ec3e
--- /dev/null
+++ b/drivers/misc/mei/client.h
@@ -0,0 +1,102 @@
1/*
2 *
3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 */
16
17#ifndef _MEI_CLIENT_H_
18#define _MEI_CLIENT_H_
19
20#include <linux/types.h>
21#include <linux/watchdog.h>
22#include <linux/poll.h>
23#include <linux/mei.h>
24
25#include "mei_dev.h"
26
27int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid);
28int mei_me_cl_by_id(struct mei_device *dev, u8 client_id);
29
30/*
31 * MEI IO Functions
32 */
33struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp);
34void mei_io_cb_free(struct mei_cl_cb *priv_cb);
35int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length);
36int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length);
37
38
39/**
40 * mei_io_list_init - Sets up a queue list.
41 *
42 * @list: An instance cl callback structure
43 */
44static inline void mei_io_list_init(struct mei_cl_cb *list)
45{
46 INIT_LIST_HEAD(&list->list);
47}
48void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl);
49
50/*
51 * MEI Host Client Functions
52 */
53
54struct mei_cl *mei_cl_allocate(struct mei_device *dev);
55void mei_cl_init(struct mei_cl *cl, struct mei_device *dev);
56
57
58int mei_cl_link(struct mei_cl *cl, int id);
59int mei_cl_unlink(struct mei_cl *cl);
60
61int mei_cl_flush_queues(struct mei_cl *cl);
62struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl);
63
64/**
65 * mei_cl_cmp_id - tells if file private data have same id
66 *
67 * @fe1: private data of 1. file object
68 * @fe2: private data of 2. file object
69 *
70 * returns true - if ids are the same and not NULL
71 */
72static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
73 const struct mei_cl *cl2)
74{
75 return cl1 && cl2 &&
76 (cl1->host_client_id == cl2->host_client_id) &&
77 (cl1->me_client_id == cl2->me_client_id);
78}
79
80
81int mei_cl_flow_ctrl_creds(struct mei_cl *cl);
82
83int mei_cl_flow_ctrl_reduce(struct mei_cl *cl);
84/*
85 * MEI input output function prototype
86 */
87bool mei_cl_is_other_connecting(struct mei_cl *cl);
88int mei_cl_disconnect(struct mei_cl *cl);
89
90int mei_cl_read_start(struct mei_cl *cl);
91
92int mei_cl_connect(struct mei_cl *cl, struct file *file);
93
94void mei_host_client_init(struct work_struct *work);
95
96
97void mei_cl_all_disconnect(struct mei_device *dev);
98void mei_cl_all_read_wakeup(struct mei_device *dev);
99void mei_cl_all_write_clear(struct mei_device *dev);
100
101
102#endif /* _MEI_CLIENT_H_ */
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
new file mode 100644
index 000000000000..fb9e63ba3bb1
--- /dev/null
+++ b/drivers/misc/mei/hbm.c
@@ -0,0 +1,669 @@
1/*
2 *
3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 */
16
17#include <linux/pci.h>
18#include <linux/sched.h>
19#include <linux/wait.h>
20#include <linux/mei.h>
21
22#include "mei_dev.h"
23#include "hbm.h"
24#include "hw-me.h"
25
26/**
27 * mei_hbm_me_cl_allocate - allocates storage for me clients
28 *
29 * @dev: the device structure
30 *
31 * returns none.
32 */
33static void mei_hbm_me_cl_allocate(struct mei_device *dev)
34{
35 struct mei_me_client *clients;
36 int b;
37
38 /* count how many ME clients we have */
39 for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX)
40 dev->me_clients_num++;
41
42 if (dev->me_clients_num <= 0)
43 return;
44
45 kfree(dev->me_clients);
46 dev->me_clients = NULL;
47
48 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n",
49 dev->me_clients_num * sizeof(struct mei_me_client));
50 /* allocate storage for ME clients representation */
51 clients = kcalloc(dev->me_clients_num,
52 sizeof(struct mei_me_client), GFP_KERNEL);
53 if (!clients) {
54 dev_err(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
55 dev->dev_state = MEI_DEV_RESETING;
56 mei_reset(dev, 1);
57 return;
58 }
59 dev->me_clients = clients;
60 return;
61}
62
63/**
64 * mei_hbm_cl_hdr - construct client hbm header
65 * @cl: - client
66 * @hbm_cmd: host bus message command
67 * @buf: buffer for cl header
68 * @len: buffer length
69 */
70static inline
71void mei_hbm_cl_hdr(struct mei_cl *cl, u8 hbm_cmd, void *buf, size_t len)
72{
73 struct mei_hbm_cl_cmd *cmd = buf;
74
75 memset(cmd, 0, len);
76
77 cmd->hbm_cmd = hbm_cmd;
78 cmd->host_addr = cl->host_client_id;
79 cmd->me_addr = cl->me_client_id;
80}
81
82/**
83 * same_disconn_addr - tells if they have the same address
84 *
85 * @file: private data of the file object.
86 * @disconn: disconnection request.
87 *
88 * returns true if addres are same
89 */
90static inline
91bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf)
92{
93 struct mei_hbm_cl_cmd *cmd = buf;
94 return cl->host_client_id == cmd->host_addr &&
95 cl->me_client_id == cmd->me_addr;
96}
97
98
99/**
100 * is_treat_specially_client - checks if the message belongs
101 * to the file private data.
102 *
103 * @cl: private data of the file object
104 * @rs: connect response bus message
105 *
106 */
107static bool is_treat_specially_client(struct mei_cl *cl,
108 struct hbm_client_connect_response *rs)
109{
110 if (mei_hbm_cl_addr_equal(cl, rs)) {
111 if (!rs->status) {
112 cl->state = MEI_FILE_CONNECTED;
113 cl->status = 0;
114
115 } else {
116 cl->state = MEI_FILE_DISCONNECTED;
117 cl->status = -ENODEV;
118 }
119 cl->timer_count = 0;
120
121 return true;
122 }
123 return false;
124}
125
126/**
127 * mei_hbm_start_req - sends start request message.
128 *
129 * @dev: the device structure
130 */
131void mei_hbm_start_req(struct mei_device *dev)
132{
133 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
134 struct hbm_host_version_request *start_req;
135 const size_t len = sizeof(struct hbm_host_version_request);
136
137 mei_hbm_hdr(mei_hdr, len);
138
139 /* host start message */
140 start_req = (struct hbm_host_version_request *)dev->wr_msg.data;
141 memset(start_req, 0, len);
142 start_req->hbm_cmd = HOST_START_REQ_CMD;
143 start_req->host_version.major_version = HBM_MAJOR_VERSION;
144 start_req->host_version.minor_version = HBM_MINOR_VERSION;
145
146 dev->recvd_msg = false;
147 if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
148 dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n");
149 dev->dev_state = MEI_DEV_RESETING;
150 mei_reset(dev, 1);
151 }
152 dev->init_clients_state = MEI_START_MESSAGE;
153 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
154 return ;
155}
156
157/**
158 * mei_hbm_enum_clients_req - sends enumeration client request message.
159 *
160 * @dev: the device structure
161 *
162 * returns none.
163 */
164static void mei_hbm_enum_clients_req(struct mei_device *dev)
165{
166 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
167 struct hbm_host_enum_request *enum_req;
168 const size_t len = sizeof(struct hbm_host_enum_request);
169 /* enumerate clients */
170 mei_hbm_hdr(mei_hdr, len);
171
172 enum_req = (struct hbm_host_enum_request *)dev->wr_msg.data;
173 memset(enum_req, 0, len);
174 enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
175
176 if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
177 dev->dev_state = MEI_DEV_RESETING;
178 dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
179 mei_reset(dev, 1);
180 }
181 dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE;
182 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
183 return;
184}
185
186/**
187 * mei_hbm_prop_requsest - request property for a single client
188 *
189 * @dev: the device structure
190 *
191 * returns none.
192 */
193
194static int mei_hbm_prop_req(struct mei_device *dev)
195{
196
197 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
198 struct hbm_props_request *prop_req;
199 const size_t len = sizeof(struct hbm_props_request);
200 unsigned long next_client_index;
201 u8 client_num;
202
203
204 client_num = dev->me_client_presentation_num;
205
206 next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX,
207 dev->me_client_index);
208
209 /* We got all client properties */
210 if (next_client_index == MEI_CLIENTS_MAX) {
211 schedule_work(&dev->init_work);
212
213 return 0;
214 }
215
216 dev->me_clients[client_num].client_id = next_client_index;
217 dev->me_clients[client_num].mei_flow_ctrl_creds = 0;
218
219 mei_hbm_hdr(mei_hdr, len);
220 prop_req = (struct hbm_props_request *)dev->wr_msg.data;
221
222 memset(prop_req, 0, sizeof(struct hbm_props_request));
223
224
225 prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
226 prop_req->address = next_client_index;
227
228 if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
229 dev->dev_state = MEI_DEV_RESETING;
230 dev_err(&dev->pdev->dev, "Properties request command failed\n");
231 mei_reset(dev, 1);
232
233 return -EIO;
234 }
235
236 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
237 dev->me_client_index = next_client_index;
238
239 return 0;
240}
241
242/**
243 * mei_hbm_stop_req_prepare - perpare stop request message
244 *
245 * @dev - mei device
246 * @mei_hdr - mei message header
247 * @data - hbm message body buffer
248 */
249static void mei_hbm_stop_req_prepare(struct mei_device *dev,
250 struct mei_msg_hdr *mei_hdr, unsigned char *data)
251{
252 struct hbm_host_stop_request *req =
253 (struct hbm_host_stop_request *)data;
254 const size_t len = sizeof(struct hbm_host_stop_request);
255
256 mei_hbm_hdr(mei_hdr, len);
257
258 memset(req, 0, len);
259 req->hbm_cmd = HOST_STOP_REQ_CMD;
260 req->reason = DRIVER_STOP_REQUEST;
261}
262
263/**
264 * mei_hbm_cl_flow_control_req - sends flow control requst.
265 *
266 * @dev: the device structure
267 * @cl: client info
268 *
269 * This function returns -EIO on write failure
270 */
271int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl)
272{
273 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
274 const size_t len = sizeof(struct hbm_flow_control);
275
276 mei_hbm_hdr(mei_hdr, len);
277 mei_hbm_cl_hdr(cl, MEI_FLOW_CONTROL_CMD, dev->wr_msg.data, len);
278
279 dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n",
280 cl->host_client_id, cl->me_client_id);
281
282 return mei_write_message(dev, mei_hdr, dev->wr_msg.data);
283}
284
285/**
286 * add_single_flow_creds - adds single buffer credentials.
287 *
288 * @file: private data ot the file object.
289 * @flow: flow control.
290 */
291static void mei_hbm_add_single_flow_creds(struct mei_device *dev,
292 struct hbm_flow_control *flow)
293{
294 struct mei_me_client *client;
295 int i;
296
297 for (i = 0; i < dev->me_clients_num; i++) {
298 client = &dev->me_clients[i];
299 if (client && flow->me_addr == client->client_id) {
300 if (client->props.single_recv_buf) {
301 client->mei_flow_ctrl_creds++;
302 dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n",
303 flow->me_addr);
304 dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n",
305 client->mei_flow_ctrl_creds);
306 } else {
307 BUG(); /* error in flow control */
308 }
309 }
310 }
311}
312
313/**
314 * mei_hbm_cl_flow_control_res - flow control response from me
315 *
316 * @dev: the device structure
317 * @flow_control: flow control response bus message
318 */
319static void mei_hbm_cl_flow_control_res(struct mei_device *dev,
320 struct hbm_flow_control *flow_control)
321{
322 struct mei_cl *cl = NULL;
323 struct mei_cl *next = NULL;
324
325 if (!flow_control->host_addr) {
326 /* single receive buffer */
327 mei_hbm_add_single_flow_creds(dev, flow_control);
328 return;
329 }
330
331 /* normal connection */
332 list_for_each_entry_safe(cl, next, &dev->file_list, link) {
333 if (mei_hbm_cl_addr_equal(cl, flow_control)) {
334 cl->mei_flow_ctrl_creds++;
335 dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n",
336 flow_control->host_addr, flow_control->me_addr);
337 dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n",
338 cl->mei_flow_ctrl_creds);
339 break;
340 }
341 }
342}
343
344
345/**
346 * mei_hbm_cl_disconnect_req - sends disconnect message to fw.
347 *
348 * @dev: the device structure
349 * @cl: a client to disconnect from
350 *
351 * This function returns -EIO on write failure
352 */
353int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl)
354{
355 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
356 const size_t len = sizeof(struct hbm_client_connect_request);
357
358 mei_hbm_hdr(mei_hdr, len);
359 mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_REQ_CMD, dev->wr_msg.data, len);
360
361 return mei_write_message(dev, mei_hdr, dev->wr_msg.data);
362}
363
364/**
365 * mei_hbm_cl_disconnect_res - disconnect response from ME
366 *
367 * @dev: the device structure
368 * @rs: disconnect response bus message
369 */
370static void mei_hbm_cl_disconnect_res(struct mei_device *dev,
371 struct hbm_client_connect_response *rs)
372{
373 struct mei_cl *cl;
374 struct mei_cl_cb *pos = NULL, *next = NULL;
375
376 dev_dbg(&dev->pdev->dev,
377 "disconnect_response:\n"
378 "ME Client = %d\n"
379 "Host Client = %d\n"
380 "Status = %d\n",
381 rs->me_addr,
382 rs->host_addr,
383 rs->status);
384
385 list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
386 cl = pos->cl;
387
388 if (!cl) {
389 list_del(&pos->list);
390 return;
391 }
392
393 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
394 if (mei_hbm_cl_addr_equal(cl, rs)) {
395 list_del(&pos->list);
396 if (!rs->status)
397 cl->state = MEI_FILE_DISCONNECTED;
398
399 cl->status = 0;
400 cl->timer_count = 0;
401 break;
402 }
403 }
404}
405
406/**
407 * mei_hbm_cl_connect_req - send connection request to specific me client
408 *
409 * @dev: the device structure
410 * @cl: a client to connect to
411 *
412 * returns -EIO on write failure
413 */
414int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl)
415{
416 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
417 const size_t len = sizeof(struct hbm_client_connect_request);
418
419 mei_hbm_hdr(mei_hdr, len);
420 mei_hbm_cl_hdr(cl, CLIENT_CONNECT_REQ_CMD, dev->wr_msg.data, len);
421
422 return mei_write_message(dev, mei_hdr, dev->wr_msg.data);
423}
424
425/**
426 * mei_hbm_cl_connect_res - connect resposne from the ME
427 *
428 * @dev: the device structure
429 * @rs: connect response bus message
430 */
431static void mei_hbm_cl_connect_res(struct mei_device *dev,
432 struct hbm_client_connect_response *rs)
433{
434
435 struct mei_cl *cl;
436 struct mei_cl_cb *pos = NULL, *next = NULL;
437
438 dev_dbg(&dev->pdev->dev,
439 "connect_response:\n"
440 "ME Client = %d\n"
441 "Host Client = %d\n"
442 "Status = %d\n",
443 rs->me_addr,
444 rs->host_addr,
445 rs->status);
446
447 /* if WD or iamthif client treat specially */
448
449 if (is_treat_specially_client(&dev->wd_cl, rs)) {
450 dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
451 mei_watchdog_register(dev);
452
453 return;
454 }
455
456 if (is_treat_specially_client(&dev->iamthif_cl, rs)) {
457 dev->iamthif_state = MEI_IAMTHIF_IDLE;
458 return;
459 }
460 list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
461
462 cl = pos->cl;
463 if (!cl) {
464 list_del(&pos->list);
465 return;
466 }
467 if (pos->fop_type == MEI_FOP_IOCTL) {
468 if (is_treat_specially_client(cl, rs)) {
469 list_del(&pos->list);
470 cl->status = 0;
471 cl->timer_count = 0;
472 break;
473 }
474 }
475 }
476}
477
478
479/**
480 * mei_client_disconnect_request - disconnect request initiated by me
481 * host sends disoconnect response
482 *
483 * @dev: the device structure.
484 * @disconnect_req: disconnect request bus message from the me
485 */
486static void mei_hbm_fw_disconnect_req(struct mei_device *dev,
487 struct hbm_client_connect_request *disconnect_req)
488{
489 struct mei_cl *cl, *next;
490 const size_t len = sizeof(struct hbm_client_connect_response);
491
492 list_for_each_entry_safe(cl, next, &dev->file_list, link) {
493 if (mei_hbm_cl_addr_equal(cl, disconnect_req)) {
494 dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n",
495 disconnect_req->host_addr,
496 disconnect_req->me_addr);
497 cl->state = MEI_FILE_DISCONNECTED;
498 cl->timer_count = 0;
499 if (cl == &dev->wd_cl)
500 dev->wd_pending = false;
501 else if (cl == &dev->iamthif_cl)
502 dev->iamthif_timer = 0;
503
504 /* prepare disconnect response */
505 mei_hbm_hdr(&dev->wr_ext_msg.hdr, len);
506 mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_RES_CMD,
507 dev->wr_ext_msg.data, len);
508 break;
509 }
510 }
511}
512
513
514/**
515 * mei_hbm_dispatch - bottom half read routine after ISR to
516 * handle the read bus message cmd processing.
517 *
518 * @dev: the device structure
519 * @mei_hdr: header of bus message
520 */
521void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
522{
523 struct mei_bus_message *mei_msg;
524 struct mei_me_client *me_client;
525 struct hbm_host_version_response *version_res;
526 struct hbm_client_connect_response *connect_res;
527 struct hbm_client_connect_response *disconnect_res;
528 struct hbm_client_connect_request *disconnect_req;
529 struct hbm_flow_control *flow_control;
530 struct hbm_props_response *props_res;
531 struct hbm_host_enum_response *enum_res;
532
533 /* read the message to our buffer */
534 BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf));
535 mei_read_slots(dev, dev->rd_msg_buf, hdr->length);
536 mei_msg = (struct mei_bus_message *)dev->rd_msg_buf;
537
538 switch (mei_msg->hbm_cmd) {
539 case HOST_START_RES_CMD:
540 version_res = (struct hbm_host_version_response *)mei_msg;
541 if (!version_res->host_version_supported) {
542 dev->version = version_res->me_max_version;
543 dev_dbg(&dev->pdev->dev, "version mismatch.\n");
544
545 mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr,
546 dev->wr_msg.data);
547 mei_write_message(dev, &dev->wr_msg.hdr,
548 dev->wr_msg.data);
549 return;
550 }
551
552 dev->version.major_version = HBM_MAJOR_VERSION;
553 dev->version.minor_version = HBM_MINOR_VERSION;
554 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
555 dev->init_clients_state == MEI_START_MESSAGE) {
556 dev->init_clients_timer = 0;
557 mei_hbm_enum_clients_req(dev);
558 } else {
559 dev->recvd_msg = false;
560 dev_dbg(&dev->pdev->dev, "reset due to received hbm: host start\n");
561 mei_reset(dev, 1);
562 return;
563 }
564
565 dev->recvd_msg = true;
566 dev_dbg(&dev->pdev->dev, "host start response message received.\n");
567 break;
568
569 case CLIENT_CONNECT_RES_CMD:
570 connect_res = (struct hbm_client_connect_response *) mei_msg;
571 mei_hbm_cl_connect_res(dev, connect_res);
572 dev_dbg(&dev->pdev->dev, "client connect response message received.\n");
573 wake_up(&dev->wait_recvd_msg);
574 break;
575
576 case CLIENT_DISCONNECT_RES_CMD:
577 disconnect_res = (struct hbm_client_connect_response *) mei_msg;
578 mei_hbm_cl_disconnect_res(dev, disconnect_res);
579 dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n");
580 wake_up(&dev->wait_recvd_msg);
581 break;
582
583 case MEI_FLOW_CONTROL_CMD:
584 flow_control = (struct hbm_flow_control *) mei_msg;
585 mei_hbm_cl_flow_control_res(dev, flow_control);
586 dev_dbg(&dev->pdev->dev, "client flow control response message received.\n");
587 break;
588
589 case HOST_CLIENT_PROPERTIES_RES_CMD:
590 props_res = (struct hbm_props_response *)mei_msg;
591 me_client = &dev->me_clients[dev->me_client_presentation_num];
592
593 if (props_res->status || !dev->me_clients) {
594 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n");
595 mei_reset(dev, 1);
596 return;
597 }
598
599 if (me_client->client_id != props_res->address) {
600 dev_err(&dev->pdev->dev,
601 "Host client properties reply mismatch\n");
602 mei_reset(dev, 1);
603
604 return;
605 }
606
607 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
608 dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) {
609 dev_err(&dev->pdev->dev,
610 "Unexpected client properties reply\n");
611 mei_reset(dev, 1);
612
613 return;
614 }
615
616 me_client->props = props_res->client_properties;
617 dev->me_client_index++;
618 dev->me_client_presentation_num++;
619
620 /* request property for the next client */
621 mei_hbm_prop_req(dev);
622
623 break;
624
625 case HOST_ENUM_RES_CMD:
626 enum_res = (struct hbm_host_enum_response *) mei_msg;
627 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
628 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
629 dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) {
630 dev->init_clients_timer = 0;
631 dev->me_client_presentation_num = 0;
632 dev->me_client_index = 0;
633 mei_hbm_me_cl_allocate(dev);
634 dev->init_clients_state =
635 MEI_CLIENT_PROPERTIES_MESSAGE;
636
637 /* first property reqeust */
638 mei_hbm_prop_req(dev);
639 } else {
640 dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n");
641 mei_reset(dev, 1);
642 return;
643 }
644 break;
645
646 case HOST_STOP_RES_CMD:
647 dev->dev_state = MEI_DEV_DISABLED;
648 dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n");
649 mei_reset(dev, 1);
650 break;
651
652 case CLIENT_DISCONNECT_REQ_CMD:
653 /* search for client */
654 disconnect_req = (struct hbm_client_connect_request *)mei_msg;
655 mei_hbm_fw_disconnect_req(dev, disconnect_req);
656 break;
657
658 case ME_STOP_REQ_CMD:
659
660 mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr,
661 dev->wr_ext_msg.data);
662 break;
663 default:
664 BUG();
665 break;
666
667 }
668}
669
diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h
new file mode 100644
index 000000000000..b552afbaf85c
--- /dev/null
+++ b/drivers/misc/mei/hbm.h
@@ -0,0 +1,39 @@
1/*
2 *
3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 */
16
17#ifndef _MEI_HBM_H_
18#define _MEI_HBM_H_
19
20void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr);
21
22static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length)
23{
24 hdr->host_addr = 0;
25 hdr->me_addr = 0;
26 hdr->length = length;
27 hdr->msg_complete = 1;
28 hdr->reserved = 0;
29}
30
31void mei_hbm_start_req(struct mei_device *dev);
32
33int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl);
34int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl);
35int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl);
36
37
38#endif /* _MEI_HBM_H_ */
39
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
new file mode 100644
index 000000000000..6a203b6e8346
--- /dev/null
+++ b/drivers/misc/mei/hw-me-regs.h
@@ -0,0 +1,167 @@
1/******************************************************************************
2 * Intel Management Engine Interface (Intel MEI) Linux driver
3 * Intel MEI Interface Header
4 *
5 * This file is provided under a dual BSD/GPLv2 license. When using or
6 * redistributing this file, you may do so under either license.
7 *
8 * GPL LICENSE SUMMARY
9 *
10 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of version 2 of the GNU General Public License as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
24 * USA
25 *
26 * The full GNU General Public License is included in this distribution
27 * in the file called LICENSE.GPL.
28 *
29 * Contact Information:
30 * Intel Corporation.
31 * linux-mei@linux.intel.com
32 * http://www.intel.com
33 *
34 * BSD LICENSE
35 *
36 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
37 * All rights reserved.
38 *
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions
41 * are met:
42 *
43 * * Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * * Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in
47 * the documentation and/or other materials provided with the
48 * distribution.
49 * * Neither the name Intel Corporation nor the names of its
50 * contributors may be used to endorse or promote products derived
51 * from this software without specific prior written permission.
52 *
53 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
54 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
55 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
56 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
57 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
58 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
59 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
63 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 *
65 *****************************************************************************/
66#ifndef _MEI_HW_MEI_REGS_H_
67#define _MEI_HW_MEI_REGS_H_
68
69/*
70 * MEI device IDs
71 */
72#define MEI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */
73#define MEI_DEV_ID_82G35 0x2984 /* 82G35 Express */
74#define MEI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */
75#define MEI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */
76
77#define MEI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */
78#define MEI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */
79
80#define MEI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */
81#define MEI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */
82#define MEI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */
83#define MEI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */
84#define MEI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */
85
86#define MEI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */
87#define MEI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */
88#define MEI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */
89#define MEI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */
90#define MEI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */
91
92#define MEI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */
93#define MEI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */
94#define MEI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */
95#define MEI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */
96
97#define MEI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */
98#define MEI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */
99#define MEI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */
100#define MEI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */
101
102#define MEI_DEV_ID_IBXPK_1 0x3B64 /* Calpella */
103#define MEI_DEV_ID_IBXPK_2 0x3B65 /* Calpella */
104
105#define MEI_DEV_ID_CPT_1 0x1C3A /* Couger Point */
106#define MEI_DEV_ID_PBG_1 0x1D3A /* C600/X79 Patsburg */
107
108#define MEI_DEV_ID_PPT_1 0x1E3A /* Panther Point */
109#define MEI_DEV_ID_PPT_2 0x1CBA /* Panther Point */
110#define MEI_DEV_ID_PPT_3 0x1DBA /* Panther Point */
111
112#define MEI_DEV_ID_LPT 0x8C3A /* Lynx Point */
113#define MEI_DEV_ID_LPT_LP 0x9C3A /* Lynx Point LP */
114/*
115 * MEI HW Section
116 */
117
118/* MEI registers */
119/* H_CB_WW - Host Circular Buffer (CB) Write Window register */
120#define H_CB_WW 0
121/* H_CSR - Host Control Status register */
122#define H_CSR 4
123/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */
124#define ME_CB_RW 8
125/* ME_CSR_HA - ME Control Status Host Access register (read only) */
126#define ME_CSR_HA 0xC
127
128
129/* register bits of H_CSR (Host Control Status register) */
130/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */
131#define H_CBD 0xFF000000
132/* Host Circular Buffer Write Pointer */
133#define H_CBWP 0x00FF0000
134/* Host Circular Buffer Read Pointer */
135#define H_CBRP 0x0000FF00
136/* Host Reset */
137#define H_RST 0x00000010
138/* Host Ready */
139#define H_RDY 0x00000008
140/* Host Interrupt Generate */
141#define H_IG 0x00000004
142/* Host Interrupt Status */
143#define H_IS 0x00000002
144/* Host Interrupt Enable */
145#define H_IE 0x00000001
146
147
148/* register bits of ME_CSR_HA (ME Control Status Host Access register) */
149/* ME CB (Circular Buffer) Depth HRA (Host Read Access) - host read only
150access to ME_CBD */
151#define ME_CBD_HRA 0xFF000000
152/* ME CB Write Pointer HRA - host read only access to ME_CBWP */
153#define ME_CBWP_HRA 0x00FF0000
154/* ME CB Read Pointer HRA - host read only access to ME_CBRP */
155#define ME_CBRP_HRA 0x0000FF00
156/* ME Reset HRA - host read only access to ME_RST */
157#define ME_RST_HRA 0x00000010
158/* ME Ready HRA - host read only access to ME_RDY */
159#define ME_RDY_HRA 0x00000008
160/* ME Interrupt Generate HRA - host read only access to ME_IG */
161#define ME_IG_HRA 0x00000004
162/* ME Interrupt Status HRA - host read only access to ME_IS */
163#define ME_IS_HRA 0x00000002
164/* ME Interrupt Enable HRA - host read only access to ME_IE */
165#define ME_IE_HRA 0x00000001
166
167#endif /* _MEI_HW_MEI_REGS_H_ */
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
new file mode 100644
index 000000000000..45ea7185c003
--- /dev/null
+++ b/drivers/misc/mei/hw-me.c
@@ -0,0 +1,576 @@
1/*
2 *
3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 */
16
17#include <linux/pci.h>
18
19#include <linux/kthread.h>
20#include <linux/interrupt.h>
21
22#include "mei_dev.h"
23#include "hw-me.h"
24
25#include "hbm.h"
26
27
28/**
29 * mei_reg_read - Reads 32bit data from the mei device
30 *
31 * @dev: the device structure
32 * @offset: offset from which to read the data
33 *
34 * returns register value (u32)
35 */
36static inline u32 mei_reg_read(const struct mei_me_hw *hw,
37 unsigned long offset)
38{
39 return ioread32(hw->mem_addr + offset);
40}
41
42
43/**
44 * mei_reg_write - Writes 32bit data to the mei device
45 *
46 * @dev: the device structure
47 * @offset: offset from which to write the data
48 * @value: register value to write (u32)
49 */
50static inline void mei_reg_write(const struct mei_me_hw *hw,
51 unsigned long offset, u32 value)
52{
53 iowrite32(value, hw->mem_addr + offset);
54}
55
56/**
57 * mei_mecbrw_read - Reads 32bit data from ME circular buffer
58 * read window register
59 *
60 * @dev: the device structure
61 *
62 * returns ME_CB_RW register value (u32)
63 */
64static u32 mei_me_mecbrw_read(const struct mei_device *dev)
65{
66 return mei_reg_read(to_me_hw(dev), ME_CB_RW);
67}
68/**
69 * mei_mecsr_read - Reads 32bit data from the ME CSR
70 *
71 * @dev: the device structure
72 *
73 * returns ME_CSR_HA register value (u32)
74 */
75static inline u32 mei_mecsr_read(const struct mei_me_hw *hw)
76{
77 return mei_reg_read(hw, ME_CSR_HA);
78}
79
80/**
81 * mei_hcsr_read - Reads 32bit data from the host CSR
82 *
83 * @dev: the device structure
84 *
85 * returns H_CSR register value (u32)
86 */
87static inline u32 mei_hcsr_read(const struct mei_me_hw *hw)
88{
89 return mei_reg_read(hw, H_CSR);
90}
91
92/**
93 * mei_hcsr_set - writes H_CSR register to the mei device,
94 * and ignores the H_IS bit for it is write-one-to-zero.
95 *
96 * @dev: the device structure
97 */
98static inline void mei_hcsr_set(struct mei_me_hw *hw, u32 hcsr)
99{
100 hcsr &= ~H_IS;
101 mei_reg_write(hw, H_CSR, hcsr);
102}
103
104
105/**
106 * me_hw_config - configure hw dependent settings
107 *
108 * @dev: mei device
109 */
110static void mei_me_hw_config(struct mei_device *dev)
111{
112 u32 hcsr = mei_hcsr_read(to_me_hw(dev));
113 /* Doesn't change in runtime */
114 dev->hbuf_depth = (hcsr & H_CBD) >> 24;
115}
116/**
117 * mei_clear_interrupts - clear and stop interrupts
118 *
119 * @dev: the device structure
120 */
121static void mei_me_intr_clear(struct mei_device *dev)
122{
123 struct mei_me_hw *hw = to_me_hw(dev);
124 u32 hcsr = mei_hcsr_read(hw);
125 if ((hcsr & H_IS) == H_IS)
126 mei_reg_write(hw, H_CSR, hcsr);
127}
128/**
129 * mei_me_intr_enable - enables mei device interrupts
130 *
131 * @dev: the device structure
132 */
133static void mei_me_intr_enable(struct mei_device *dev)
134{
135 struct mei_me_hw *hw = to_me_hw(dev);
136 u32 hcsr = mei_hcsr_read(hw);
137 hcsr |= H_IE;
138 mei_hcsr_set(hw, hcsr);
139}
140
141/**
142 * mei_disable_interrupts - disables mei device interrupts
143 *
144 * @dev: the device structure
145 */
146static void mei_me_intr_disable(struct mei_device *dev)
147{
148 struct mei_me_hw *hw = to_me_hw(dev);
149 u32 hcsr = mei_hcsr_read(hw);
150 hcsr &= ~H_IE;
151 mei_hcsr_set(hw, hcsr);
152}
153
154/**
155 * mei_me_hw_reset - resets fw via mei csr register.
156 *
157 * @dev: the device structure
158 * @interrupts_enabled: if interrupt should be enabled after reset.
159 */
160static void mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
161{
162 struct mei_me_hw *hw = to_me_hw(dev);
163 u32 hcsr = mei_hcsr_read(hw);
164
165 dev_dbg(&dev->pdev->dev, "before reset HCSR = 0x%08x.\n", hcsr);
166
167 hcsr |= (H_RST | H_IG);
168
169 if (intr_enable)
170 hcsr |= H_IE;
171 else
172 hcsr &= ~H_IE;
173
174 mei_hcsr_set(hw, hcsr);
175
176 hcsr = mei_hcsr_read(hw) | H_IG;
177 hcsr &= ~H_RST;
178
179 mei_hcsr_set(hw, hcsr);
180
181 hcsr = mei_hcsr_read(hw);
182
183 dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", hcsr);
184}
185
186/**
187 * mei_me_host_set_ready - enable device
188 *
189 * @dev - mei device
190 * returns bool
191 */
192
193static void mei_me_host_set_ready(struct mei_device *dev)
194{
195 struct mei_me_hw *hw = to_me_hw(dev);
196 hw->host_hw_state |= H_IE | H_IG | H_RDY;
197 mei_hcsr_set(hw, hw->host_hw_state);
198}
199/**
200 * mei_me_host_is_ready - check whether the host has turned ready
201 *
202 * @dev - mei device
203 * returns bool
204 */
205static bool mei_me_host_is_ready(struct mei_device *dev)
206{
207 struct mei_me_hw *hw = to_me_hw(dev);
208 hw->host_hw_state = mei_hcsr_read(hw);
209 return (hw->host_hw_state & H_RDY) == H_RDY;
210}
211
212/**
213 * mei_me_hw_is_ready - check whether the me(hw) has turned ready
214 *
215 * @dev - mei device
216 * returns bool
217 */
218static bool mei_me_hw_is_ready(struct mei_device *dev)
219{
220 struct mei_me_hw *hw = to_me_hw(dev);
221 hw->me_hw_state = mei_mecsr_read(hw);
222 return (hw->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA;
223}
224
225/**
226 * mei_hbuf_filled_slots - gets number of device filled buffer slots
227 *
228 * @dev: the device structure
229 *
230 * returns number of filled slots
231 */
232static unsigned char mei_hbuf_filled_slots(struct mei_device *dev)
233{
234 struct mei_me_hw *hw = to_me_hw(dev);
235 char read_ptr, write_ptr;
236
237 hw->host_hw_state = mei_hcsr_read(hw);
238
239 read_ptr = (char) ((hw->host_hw_state & H_CBRP) >> 8);
240 write_ptr = (char) ((hw->host_hw_state & H_CBWP) >> 16);
241
242 return (unsigned char) (write_ptr - read_ptr);
243}
244
245/**
246 * mei_hbuf_is_empty - checks if host buffer is empty.
247 *
248 * @dev: the device structure
249 *
250 * returns true if empty, false - otherwise.
251 */
252static bool mei_me_hbuf_is_empty(struct mei_device *dev)
253{
254 return mei_hbuf_filled_slots(dev) == 0;
255}
256
257/**
258 * mei_me_hbuf_empty_slots - counts write empty slots.
259 *
260 * @dev: the device structure
261 *
262 * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count
263 */
264static int mei_me_hbuf_empty_slots(struct mei_device *dev)
265{
266 unsigned char filled_slots, empty_slots;
267
268 filled_slots = mei_hbuf_filled_slots(dev);
269 empty_slots = dev->hbuf_depth - filled_slots;
270
271 /* check for overflow */
272 if (filled_slots > dev->hbuf_depth)
273 return -EOVERFLOW;
274
275 return empty_slots;
276}
277
278static size_t mei_me_hbuf_max_len(const struct mei_device *dev)
279{
280 return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr);
281}
282
283
284/**
285 * mei_write_message - writes a message to mei device.
286 *
287 * @dev: the device structure
288 * @header: mei HECI header of message
289 * @buf: message payload will be written
290 *
291 * This function returns -EIO if write has failed
292 */
293static int mei_me_write_message(struct mei_device *dev,
294 struct mei_msg_hdr *header,
295 unsigned char *buf)
296{
297 struct mei_me_hw *hw = to_me_hw(dev);
298 unsigned long rem, dw_cnt;
299 unsigned long length = header->length;
300 u32 *reg_buf = (u32 *)buf;
301 u32 hcsr;
302 int i;
303 int empty_slots;
304
305 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header));
306
307 empty_slots = mei_hbuf_empty_slots(dev);
308 dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots);
309
310 dw_cnt = mei_data2slots(length);
311 if (empty_slots < 0 || dw_cnt > empty_slots)
312 return -EIO;
313
314 mei_reg_write(hw, H_CB_WW, *((u32 *) header));
315
316 for (i = 0; i < length / 4; i++)
317 mei_reg_write(hw, H_CB_WW, reg_buf[i]);
318
319 rem = length & 0x3;
320 if (rem > 0) {
321 u32 reg = 0;
322 memcpy(&reg, &buf[length - rem], rem);
323 mei_reg_write(hw, H_CB_WW, reg);
324 }
325
326 hcsr = mei_hcsr_read(hw) | H_IG;
327 mei_hcsr_set(hw, hcsr);
328 if (!mei_me_hw_is_ready(dev))
329 return -EIO;
330
331 return 0;
332}
333
334/**
335 * mei_me_count_full_read_slots - counts read full slots.
336 *
337 * @dev: the device structure
338 *
339 * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count
340 */
341static int mei_me_count_full_read_slots(struct mei_device *dev)
342{
343 struct mei_me_hw *hw = to_me_hw(dev);
344 char read_ptr, write_ptr;
345 unsigned char buffer_depth, filled_slots;
346
347 hw->me_hw_state = mei_mecsr_read(hw);
348 buffer_depth = (unsigned char)((hw->me_hw_state & ME_CBD_HRA) >> 24);
349 read_ptr = (char) ((hw->me_hw_state & ME_CBRP_HRA) >> 8);
350 write_ptr = (char) ((hw->me_hw_state & ME_CBWP_HRA) >> 16);
351 filled_slots = (unsigned char) (write_ptr - read_ptr);
352
353 /* check for overflow */
354 if (filled_slots > buffer_depth)
355 return -EOVERFLOW;
356
357 dev_dbg(&dev->pdev->dev, "filled_slots =%08x\n", filled_slots);
358 return (int)filled_slots;
359}
360
361/**
362 * mei_me_read_slots - reads a message from mei device.
363 *
364 * @dev: the device structure
365 * @buffer: message buffer will be written
366 * @buffer_length: message size will be read
367 */
368static int mei_me_read_slots(struct mei_device *dev, unsigned char *buffer,
369 unsigned long buffer_length)
370{
371 struct mei_me_hw *hw = to_me_hw(dev);
372 u32 *reg_buf = (u32 *)buffer;
373 u32 hcsr;
374
375 for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32))
376 *reg_buf++ = mei_me_mecbrw_read(dev);
377
378 if (buffer_length > 0) {
379 u32 reg = mei_me_mecbrw_read(dev);
380 memcpy(reg_buf, &reg, buffer_length);
381 }
382
383 hcsr = mei_hcsr_read(hw) | H_IG;
384 mei_hcsr_set(hw, hcsr);
385 return 0;
386}
387
388/**
389 * mei_me_irq_quick_handler - The ISR of the MEI device
390 *
391 * @irq: The irq number
392 * @dev_id: pointer to the device structure
393 *
394 * returns irqreturn_t
395 */
396
397irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id)
398{
399 struct mei_device *dev = (struct mei_device *) dev_id;
400 struct mei_me_hw *hw = to_me_hw(dev);
401 u32 csr_reg = mei_hcsr_read(hw);
402
403 if ((csr_reg & H_IS) != H_IS)
404 return IRQ_NONE;
405
406 /* clear H_IS bit in H_CSR */
407 mei_reg_write(hw, H_CSR, csr_reg);
408
409 return IRQ_WAKE_THREAD;
410}
411
412/**
413 * mei_me_irq_thread_handler - function called after ISR to handle the interrupt
414 * processing.
415 *
416 * @irq: The irq number
417 * @dev_id: pointer to the device structure
418 *
419 * returns irqreturn_t
420 *
421 */
422irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
423{
424 struct mei_device *dev = (struct mei_device *) dev_id;
425 struct mei_cl_cb complete_list;
426 struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
427 struct mei_cl *cl;
428 s32 slots;
429 int rets;
430 bool bus_message_received;
431
432
433 dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n");
434 /* initialize our complete list */
435 mutex_lock(&dev->device_lock);
436 mei_io_list_init(&complete_list);
437
438 /* Ack the interrupt here
439 * In case of MSI we don't go through the quick handler */
440 if (pci_dev_msi_enabled(dev->pdev))
441 mei_clear_interrupts(dev);
442
443 /* check if ME wants a reset */
444 if (!mei_hw_is_ready(dev) &&
445 dev->dev_state != MEI_DEV_RESETING &&
446 dev->dev_state != MEI_DEV_INITIALIZING) {
447 dev_dbg(&dev->pdev->dev, "FW not ready.\n");
448 mei_reset(dev, 1);
449 mutex_unlock(&dev->device_lock);
450 return IRQ_HANDLED;
451 }
452
453 /* check if we need to start the dev */
454 if (!mei_host_is_ready(dev)) {
455 if (mei_hw_is_ready(dev)) {
456 dev_dbg(&dev->pdev->dev, "we need to start the dev.\n");
457
458 mei_host_set_ready(dev);
459
460 dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n");
461 /* link is established * start sending messages. */
462
463 dev->dev_state = MEI_DEV_INIT_CLIENTS;
464
465 mei_hbm_start_req(dev);
466 mutex_unlock(&dev->device_lock);
467 return IRQ_HANDLED;
468 } else {
469 dev_dbg(&dev->pdev->dev, "FW not ready.\n");
470 mutex_unlock(&dev->device_lock);
471 return IRQ_HANDLED;
472 }
473 }
474 /* check slots available for reading */
475 slots = mei_count_full_read_slots(dev);
476 while (slots > 0) {
477 /* we have urgent data to send so break the read */
478 if (dev->wr_ext_msg.hdr.length)
479 break;
480 dev_dbg(&dev->pdev->dev, "slots =%08x\n", slots);
481 dev_dbg(&dev->pdev->dev, "call mei_irq_read_handler.\n");
482 rets = mei_irq_read_handler(dev, &complete_list, &slots);
483 if (rets)
484 goto end;
485 }
486 rets = mei_irq_write_handler(dev, &complete_list);
487end:
488 dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
489 dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
490
491 bus_message_received = false;
492 if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
493 dev_dbg(&dev->pdev->dev, "received waiting bus message\n");
494 bus_message_received = true;
495 }
496 mutex_unlock(&dev->device_lock);
497 if (bus_message_received) {
498 dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n");
499 wake_up_interruptible(&dev->wait_recvd_msg);
500 bus_message_received = false;
501 }
502 if (list_empty(&complete_list.list))
503 return IRQ_HANDLED;
504
505
506 list_for_each_entry_safe(cb_pos, cb_next, &complete_list.list, list) {
507 cl = cb_pos->cl;
508 list_del(&cb_pos->list);
509 if (cl) {
510 if (cl != &dev->iamthif_cl) {
511 dev_dbg(&dev->pdev->dev, "completing call back.\n");
512 mei_irq_complete_handler(cl, cb_pos);
513 cb_pos = NULL;
514 } else if (cl == &dev->iamthif_cl) {
515 mei_amthif_complete(dev, cb_pos);
516 }
517 }
518 }
519 return IRQ_HANDLED;
520}
521static const struct mei_hw_ops mei_me_hw_ops = {
522
523 .host_set_ready = mei_me_host_set_ready,
524 .host_is_ready = mei_me_host_is_ready,
525
526 .hw_is_ready = mei_me_hw_is_ready,
527 .hw_reset = mei_me_hw_reset,
528 .hw_config = mei_me_hw_config,
529
530 .intr_clear = mei_me_intr_clear,
531 .intr_enable = mei_me_intr_enable,
532 .intr_disable = mei_me_intr_disable,
533
534 .hbuf_free_slots = mei_me_hbuf_empty_slots,
535 .hbuf_is_ready = mei_me_hbuf_is_empty,
536 .hbuf_max_len = mei_me_hbuf_max_len,
537
538 .write = mei_me_write_message,
539
540 .rdbuf_full_slots = mei_me_count_full_read_slots,
541 .read_hdr = mei_me_mecbrw_read,
542 .read = mei_me_read_slots
543};
544
545/**
546 * init_mei_device - allocates and initializes the mei device structure
547 *
548 * @pdev: The pci device structure
549 *
550 * returns The mei_device_device pointer on success, NULL on failure.
551 */
552struct mei_device *mei_me_dev_init(struct pci_dev *pdev)
553{
554 struct mei_device *dev;
555
556 dev = kzalloc(sizeof(struct mei_device) +
557 sizeof(struct mei_me_hw), GFP_KERNEL);
558 if (!dev)
559 return NULL;
560
561 mei_device_init(dev);
562
563 INIT_LIST_HEAD(&dev->wd_cl.link);
564 INIT_LIST_HEAD(&dev->iamthif_cl.link);
565 mei_io_list_init(&dev->amthif_cmd_list);
566 mei_io_list_init(&dev->amthif_rd_complete_list);
567
568 INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
569 INIT_WORK(&dev->init_work, mei_host_client_init);
570
571 dev->ops = &mei_me_hw_ops;
572
573 dev->pdev = pdev;
574 return dev;
575}
576
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
new file mode 100644
index 000000000000..8518d3eeb838
--- /dev/null
+++ b/drivers/misc/mei/hw-me.h
@@ -0,0 +1,48 @@
1/*
2 *
3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 */
16
17
18
19#ifndef _MEI_INTERFACE_H_
20#define _MEI_INTERFACE_H_
21
22#include <linux/mei.h>
23#include "mei_dev.h"
24#include "client.h"
25
26struct mei_me_hw {
27 void __iomem *mem_addr;
28 /*
29 * hw states of host and fw(ME)
30 */
31 u32 host_hw_state;
32 u32 me_hw_state;
33};
34
35#define to_me_hw(dev) (struct mei_me_hw *)((dev)->hw)
36
37struct mei_device *mei_me_dev_init(struct pci_dev *pdev);
38
39/* get slots (dwords) from a message length + header (bytes) */
40static inline unsigned char mei_data2slots(size_t length)
41{
42 return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
43}
44
45irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id);
46irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id);
47
48#endif /* _MEI_INTERFACE_H_ */
diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h
index be8ca6b333ca..cb2f556b4252 100644
--- a/drivers/misc/mei/hw.h
+++ b/drivers/misc/mei/hw.h
@@ -31,109 +31,6 @@
31#define MEI_IAMTHIF_STALL_TIMER 12 /* HPS */ 31#define MEI_IAMTHIF_STALL_TIMER 12 /* HPS */
32#define MEI_IAMTHIF_READ_TIMER 10 /* HPS */ 32#define MEI_IAMTHIF_READ_TIMER 10 /* HPS */
33 33
34/*
35 * Internal Clients Number
36 */
37#define MEI_WD_HOST_CLIENT_ID 1
38#define MEI_IAMTHIF_HOST_CLIENT_ID 2
39
40/*
41 * MEI device IDs
42 */
43#define MEI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */
44#define MEI_DEV_ID_82G35 0x2984 /* 82G35 Express */
45#define MEI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */
46#define MEI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */
47
48#define MEI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */
49#define MEI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */
50
51#define MEI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */
52#define MEI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */
53#define MEI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */
54#define MEI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */
55#define MEI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */
56
57#define MEI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */
58#define MEI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */
59#define MEI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */
60#define MEI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */
61#define MEI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */
62
63#define MEI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */
64#define MEI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */
65#define MEI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */
66#define MEI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */
67
68#define MEI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */
69#define MEI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */
70#define MEI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */
71#define MEI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */
72
73#define MEI_DEV_ID_IBXPK_1 0x3B64 /* Calpella */
74#define MEI_DEV_ID_IBXPK_2 0x3B65 /* Calpella */
75
76#define MEI_DEV_ID_CPT_1 0x1C3A /* Couger Point */
77#define MEI_DEV_ID_PBG_1 0x1D3A /* C600/X79 Patsburg */
78
79#define MEI_DEV_ID_PPT_1 0x1E3A /* Panther Point */
80#define MEI_DEV_ID_PPT_2 0x1CBA /* Panther Point */
81#define MEI_DEV_ID_PPT_3 0x1DBA /* Panther Point */
82
83#define MEI_DEV_ID_LPT 0x8C3A /* Lynx Point */
84#define MEI_DEV_ID_LPT_LP 0x9C3A /* Lynx Point LP */
85/*
86 * MEI HW Section
87 */
88
89/* MEI registers */
90/* H_CB_WW - Host Circular Buffer (CB) Write Window register */
91#define H_CB_WW 0
92/* H_CSR - Host Control Status register */
93#define H_CSR 4
94/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */
95#define ME_CB_RW 8
96/* ME_CSR_HA - ME Control Status Host Access register (read only) */
97#define ME_CSR_HA 0xC
98
99
100/* register bits of H_CSR (Host Control Status register) */
101/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */
102#define H_CBD 0xFF000000
103/* Host Circular Buffer Write Pointer */
104#define H_CBWP 0x00FF0000
105/* Host Circular Buffer Read Pointer */
106#define H_CBRP 0x0000FF00
107/* Host Reset */
108#define H_RST 0x00000010
109/* Host Ready */
110#define H_RDY 0x00000008
111/* Host Interrupt Generate */
112#define H_IG 0x00000004
113/* Host Interrupt Status */
114#define H_IS 0x00000002
115/* Host Interrupt Enable */
116#define H_IE 0x00000001
117
118
119/* register bits of ME_CSR_HA (ME Control Status Host Access register) */
120/* ME CB (Circular Buffer) Depth HRA (Host Read Access) - host read only
121access to ME_CBD */
122#define ME_CBD_HRA 0xFF000000
123/* ME CB Write Pointer HRA - host read only access to ME_CBWP */
124#define ME_CBWP_HRA 0x00FF0000
125/* ME CB Read Pointer HRA - host read only access to ME_CBRP */
126#define ME_CBRP_HRA 0x0000FF00
127/* ME Reset HRA - host read only access to ME_RST */
128#define ME_RST_HRA 0x00000010
129/* ME Ready HRA - host read only access to ME_RDY */
130#define ME_RDY_HRA 0x00000008
131/* ME Interrupt Generate HRA - host read only access to ME_IG */
132#define ME_IG_HRA 0x00000004
133/* ME Interrupt Status HRA - host read only access to ME_IS */
134#define ME_IS_HRA 0x00000002
135/* ME Interrupt Enable HRA - host read only access to ME_IE */
136#define ME_IE_HRA 0x00000001
137 34
138/* 35/*
139 * MEI Version 36 * MEI Version
@@ -224,6 +121,22 @@ struct mei_bus_message {
224 u8 data[0]; 121 u8 data[0];
225} __packed; 122} __packed;
226 123
124/**
125 * struct hbm_cl_cmd - client specific host bus command
126 * CONNECT, DISCONNECT, and FlOW CONTROL
127 *
128 * @hbm_cmd - bus message command header
129 * @me_addr - address of the client in ME
130 * @host_addr - address of the client in the driver
131 * @data
132 */
133struct mei_hbm_cl_cmd {
134 u8 hbm_cmd;
135 u8 me_addr;
136 u8 host_addr;
137 u8 data;
138};
139
227struct hbm_version { 140struct hbm_version {
228 u8 minor_version; 141 u8 minor_version;
229 u8 major_version; 142 u8 major_version;
@@ -333,11 +246,5 @@ struct hbm_flow_control {
333 u8 reserved[MEI_FC_MESSAGE_RESERVED_LENGTH]; 246 u8 reserved[MEI_FC_MESSAGE_RESERVED_LENGTH];
334} __packed; 247} __packed;
335 248
336struct mei_me_client {
337 struct mei_client_properties props;
338 u8 client_id;
339 u8 mei_flow_ctrl_creds;
340} __packed;
341
342 249
343#endif 250#endif
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index a54cd5567ca2..6ec530168afb 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -19,11 +19,11 @@
19#include <linux/wait.h> 19#include <linux/wait.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21 21
22#include "mei_dev.h"
23#include "hw.h"
24#include "interface.h"
25#include <linux/mei.h> 22#include <linux/mei.h>
26 23
24#include "mei_dev.h"
25#include "client.h"
26
27const char *mei_dev_state_str(int state) 27const char *mei_dev_state_str(int state)
28{ 28{
29#define MEI_DEV_STATE(state) case MEI_DEV_##state: return #state 29#define MEI_DEV_STATE(state) case MEI_DEV_##state: return #state
@@ -42,84 +42,20 @@ const char *mei_dev_state_str(int state)
42#undef MEI_DEV_STATE 42#undef MEI_DEV_STATE
43} 43}
44 44
45 45void mei_device_init(struct mei_device *dev)
46
47/**
48 * mei_io_list_flush - removes list entry belonging to cl.
49 *
50 * @list: An instance of our list structure
51 * @cl: private data of the file object
52 */
53void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
54{
55 struct mei_cl_cb *pos;
56 struct mei_cl_cb *next;
57
58 list_for_each_entry_safe(pos, next, &list->list, list) {
59 if (pos->cl) {
60 if (mei_cl_cmp_id(cl, pos->cl))
61 list_del(&pos->list);
62 }
63 }
64}
65/**
66 * mei_cl_flush_queues - flushes queue lists belonging to cl.
67 *
68 * @dev: the device structure
69 * @cl: private data of the file object
70 */
71int mei_cl_flush_queues(struct mei_cl *cl)
72{ 46{
73 if (!cl || !cl->dev)
74 return -EINVAL;
75
76 dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n");
77 mei_io_list_flush(&cl->dev->read_list, cl);
78 mei_io_list_flush(&cl->dev->write_list, cl);
79 mei_io_list_flush(&cl->dev->write_waiting_list, cl);
80 mei_io_list_flush(&cl->dev->ctrl_wr_list, cl);
81 mei_io_list_flush(&cl->dev->ctrl_rd_list, cl);
82 mei_io_list_flush(&cl->dev->amthif_cmd_list, cl);
83 mei_io_list_flush(&cl->dev->amthif_rd_complete_list, cl);
84 return 0;
85}
86
87
88
89/**
90 * init_mei_device - allocates and initializes the mei device structure
91 *
92 * @pdev: The pci device structure
93 *
94 * returns The mei_device_device pointer on success, NULL on failure.
95 */
96struct mei_device *mei_device_init(struct pci_dev *pdev)
97{
98 struct mei_device *dev;
99
100 dev = kzalloc(sizeof(struct mei_device), GFP_KERNEL);
101 if (!dev)
102 return NULL;
103
104 /* setup our list array */ 47 /* setup our list array */
105 INIT_LIST_HEAD(&dev->file_list); 48 INIT_LIST_HEAD(&dev->file_list);
106 INIT_LIST_HEAD(&dev->wd_cl.link);
107 INIT_LIST_HEAD(&dev->iamthif_cl.link);
108 mutex_init(&dev->device_lock); 49 mutex_init(&dev->device_lock);
109 init_waitqueue_head(&dev->wait_recvd_msg); 50 init_waitqueue_head(&dev->wait_recvd_msg);
110 init_waitqueue_head(&dev->wait_stop_wd); 51 init_waitqueue_head(&dev->wait_stop_wd);
111 dev->dev_state = MEI_DEV_INITIALIZING; 52 dev->dev_state = MEI_DEV_INITIALIZING;
112 dev->iamthif_state = MEI_IAMTHIF_IDLE;
113 53
114 mei_io_list_init(&dev->read_list); 54 mei_io_list_init(&dev->read_list);
115 mei_io_list_init(&dev->write_list); 55 mei_io_list_init(&dev->write_list);
116 mei_io_list_init(&dev->write_waiting_list); 56 mei_io_list_init(&dev->write_waiting_list);
117 mei_io_list_init(&dev->ctrl_wr_list); 57 mei_io_list_init(&dev->ctrl_wr_list);
118 mei_io_list_init(&dev->ctrl_rd_list); 58 mei_io_list_init(&dev->ctrl_rd_list);
119 mei_io_list_init(&dev->amthif_cmd_list);
120 mei_io_list_init(&dev->amthif_rd_complete_list);
121 dev->pdev = pdev;
122 return dev;
123} 59}
124 60
125/** 61/**
@@ -131,101 +67,64 @@ struct mei_device *mei_device_init(struct pci_dev *pdev)
131 */ 67 */
132int mei_hw_init(struct mei_device *dev) 68int mei_hw_init(struct mei_device *dev)
133{ 69{
134 int err = 0; 70 int ret = 0;
135 int ret;
136 71
137 mutex_lock(&dev->device_lock); 72 mutex_lock(&dev->device_lock);
138 73
139 dev->host_hw_state = mei_hcsr_read(dev);
140 dev->me_hw_state = mei_mecsr_read(dev);
141 dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, mestate = 0x%08x.\n",
142 dev->host_hw_state, dev->me_hw_state);
143
144 /* acknowledge interrupt and stop interupts */ 74 /* acknowledge interrupt and stop interupts */
145 if ((dev->host_hw_state & H_IS) == H_IS) 75 mei_clear_interrupts(dev);
146 mei_reg_write(dev, H_CSR, dev->host_hw_state);
147 76
148 /* Doesn't change in runtime */ 77 mei_hw_config(dev);
149 dev->hbuf_depth = (dev->host_hw_state & H_CBD) >> 24;
150 78
151 dev->recvd_msg = false; 79 dev->recvd_msg = false;
152 dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); 80 dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n");
153 81
154 mei_reset(dev, 1); 82 mei_reset(dev, 1);
155 83
156 dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
157 dev->host_hw_state, dev->me_hw_state);
158
159 /* wait for ME to turn on ME_RDY */ 84 /* wait for ME to turn on ME_RDY */
160 if (!dev->recvd_msg) { 85 if (!dev->recvd_msg) {
161 mutex_unlock(&dev->device_lock); 86 mutex_unlock(&dev->device_lock);
162 err = wait_event_interruptible_timeout(dev->wait_recvd_msg, 87 ret = wait_event_interruptible_timeout(dev->wait_recvd_msg,
163 dev->recvd_msg, 88 dev->recvd_msg,
164 mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT)); 89 mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT));
165 mutex_lock(&dev->device_lock); 90 mutex_lock(&dev->device_lock);
166 } 91 }
167 92
168 if (err <= 0 && !dev->recvd_msg) { 93 if (ret <= 0 && !dev->recvd_msg) {
169 dev->dev_state = MEI_DEV_DISABLED; 94 dev->dev_state = MEI_DEV_DISABLED;
170 dev_dbg(&dev->pdev->dev, 95 dev_dbg(&dev->pdev->dev,
171 "wait_event_interruptible_timeout failed" 96 "wait_event_interruptible_timeout failed"
172 "on wait for ME to turn on ME_RDY.\n"); 97 "on wait for ME to turn on ME_RDY.\n");
173 ret = -ENODEV; 98 goto err;
174 goto out;
175 } 99 }
176 100
177 if (!(((dev->host_hw_state & H_RDY) == H_RDY) &&
178 ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) {
179 dev->dev_state = MEI_DEV_DISABLED;
180 dev_dbg(&dev->pdev->dev,
181 "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
182 dev->host_hw_state, dev->me_hw_state);
183
184 if (!(dev->host_hw_state & H_RDY))
185 dev_dbg(&dev->pdev->dev, "host turn off H_RDY.\n");
186 101
187 if (!(dev->me_hw_state & ME_RDY_HRA)) 102 if (!mei_host_is_ready(dev)) {
188 dev_dbg(&dev->pdev->dev, "ME turn off ME_RDY.\n"); 103 dev_err(&dev->pdev->dev, "host is not ready.\n");
104 goto err;
105 }
189 106
190 dev_err(&dev->pdev->dev, "link layer initialization failed.\n"); 107 if (!mei_hw_is_ready(dev)) {
191 ret = -ENODEV; 108 dev_err(&dev->pdev->dev, "ME is not ready.\n");
192 goto out; 109 goto err;
193 } 110 }
194 111
195 if (dev->version.major_version != HBM_MAJOR_VERSION || 112 if (dev->version.major_version != HBM_MAJOR_VERSION ||
196 dev->version.minor_version != HBM_MINOR_VERSION) { 113 dev->version.minor_version != HBM_MINOR_VERSION) {
197 dev_dbg(&dev->pdev->dev, "MEI start failed.\n"); 114 dev_dbg(&dev->pdev->dev, "MEI start failed.\n");
198 ret = -ENODEV; 115 goto err;
199 goto out;
200 } 116 }
201 117
202 dev->recvd_msg = false; 118 dev->recvd_msg = false;
203 dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
204 dev->host_hw_state, dev->me_hw_state);
205 dev_dbg(&dev->pdev->dev, "ME turn on ME_RDY and host turn on H_RDY.\n");
206 dev_dbg(&dev->pdev->dev, "link layer has been established.\n"); 119 dev_dbg(&dev->pdev->dev, "link layer has been established.\n");
207 dev_dbg(&dev->pdev->dev, "MEI start success.\n");
208 ret = 0;
209 120
210out:
211 mutex_unlock(&dev->device_lock); 121 mutex_unlock(&dev->device_lock);
212 return ret; 122 return 0;
213} 123err:
214 124 dev_err(&dev->pdev->dev, "link layer initialization failed.\n");
215/** 125 dev->dev_state = MEI_DEV_DISABLED;
216 * mei_hw_reset - resets fw via mei csr register. 126 mutex_unlock(&dev->device_lock);
217 * 127 return -ENODEV;
218 * @dev: the device structure
219 * @interrupts_enabled: if interrupt should be enabled after reset.
220 */
221static void mei_hw_reset(struct mei_device *dev, int interrupts_enabled)
222{
223 dev->host_hw_state |= (H_RST | H_IG);
224
225 if (interrupts_enabled)
226 mei_enable_interrupts(dev);
227 else
228 mei_disable_interrupts(dev);
229} 128}
230 129
231/** 130/**
@@ -236,56 +135,34 @@ static void mei_hw_reset(struct mei_device *dev, int interrupts_enabled)
236 */ 135 */
237void mei_reset(struct mei_device *dev, int interrupts_enabled) 136void mei_reset(struct mei_device *dev, int interrupts_enabled)
238{ 137{
239 struct mei_cl *cl_pos = NULL;
240 struct mei_cl *cl_next = NULL;
241 struct mei_cl_cb *cb_pos = NULL;
242 struct mei_cl_cb *cb_next = NULL;
243 bool unexpected; 138 bool unexpected;
244 139
245 if (dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) { 140 if (dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET)
246 dev->need_reset = true;
247 return; 141 return;
248 }
249 142
250 unexpected = (dev->dev_state != MEI_DEV_INITIALIZING && 143 unexpected = (dev->dev_state != MEI_DEV_INITIALIZING &&
251 dev->dev_state != MEI_DEV_DISABLED && 144 dev->dev_state != MEI_DEV_DISABLED &&
252 dev->dev_state != MEI_DEV_POWER_DOWN && 145 dev->dev_state != MEI_DEV_POWER_DOWN &&
253 dev->dev_state != MEI_DEV_POWER_UP); 146 dev->dev_state != MEI_DEV_POWER_UP);
254 147
255 dev->host_hw_state = mei_hcsr_read(dev);
256
257 dev_dbg(&dev->pdev->dev, "before reset host_hw_state = 0x%08x.\n",
258 dev->host_hw_state);
259
260 mei_hw_reset(dev, interrupts_enabled); 148 mei_hw_reset(dev, interrupts_enabled);
261 149
262 dev->host_hw_state &= ~H_RST;
263 dev->host_hw_state |= H_IG;
264
265 mei_hcsr_set(dev);
266
267 dev_dbg(&dev->pdev->dev, "currently saved host_hw_state = 0x%08x.\n",
268 dev->host_hw_state);
269
270 dev->need_reset = false;
271 150
272 if (dev->dev_state != MEI_DEV_INITIALIZING) { 151 if (dev->dev_state != MEI_DEV_INITIALIZING) {
273 if (dev->dev_state != MEI_DEV_DISABLED && 152 if (dev->dev_state != MEI_DEV_DISABLED &&
274 dev->dev_state != MEI_DEV_POWER_DOWN) 153 dev->dev_state != MEI_DEV_POWER_DOWN)
275 dev->dev_state = MEI_DEV_RESETING; 154 dev->dev_state = MEI_DEV_RESETING;
276 155
277 list_for_each_entry_safe(cl_pos, 156 mei_cl_all_disconnect(dev);
278 cl_next, &dev->file_list, link) { 157
279 cl_pos->state = MEI_FILE_DISCONNECTED;
280 cl_pos->mei_flow_ctrl_creds = 0;
281 cl_pos->read_cb = NULL;
282 cl_pos->timer_count = 0;
283 }
284 /* remove entry if already in list */ 158 /* remove entry if already in list */
285 dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n"); 159 dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n");
286 mei_me_cl_unlink(dev, &dev->wd_cl); 160 mei_cl_unlink(&dev->wd_cl);
287 161 if (dev->open_handle_count > 0)
288 mei_me_cl_unlink(dev, &dev->iamthif_cl); 162 dev->open_handle_count--;
163 mei_cl_unlink(&dev->iamthif_cl);
164 if (dev->open_handle_count > 0)
165 dev->open_handle_count--;
289 166
290 mei_amthif_reset_params(dev); 167 mei_amthif_reset_params(dev);
291 memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg)); 168 memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
@@ -295,392 +172,17 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
295 dev->rd_msg_hdr = 0; 172 dev->rd_msg_hdr = 0;
296 dev->wd_pending = false; 173 dev->wd_pending = false;
297 174
298 /* update the state of the registers after reset */
299 dev->host_hw_state = mei_hcsr_read(dev);
300 dev->me_hw_state = mei_mecsr_read(dev);
301
302 dev_dbg(&dev->pdev->dev, "after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
303 dev->host_hw_state, dev->me_hw_state);
304
305 if (unexpected) 175 if (unexpected)
306 dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n", 176 dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
307 mei_dev_state_str(dev->dev_state)); 177 mei_dev_state_str(dev->dev_state));
308 178
309 /* Wake up all readings so they can be interrupted */ 179 /* wake up all readings so they can be interrupted */
310 list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { 180 mei_cl_all_read_wakeup(dev);
311 if (waitqueue_active(&cl_pos->rx_wait)) {
312 dev_dbg(&dev->pdev->dev, "Waking up client!\n");
313 wake_up_interruptible(&cl_pos->rx_wait);
314 }
315 }
316 /* remove all waiting requests */
317 list_for_each_entry_safe(cb_pos, cb_next, &dev->write_list.list, list) {
318 list_del(&cb_pos->list);
319 mei_io_cb_free(cb_pos);
320 }
321}
322
323
324
325/**
326 * host_start_message - mei host sends start message.
327 *
328 * @dev: the device structure
329 *
330 * returns none.
331 */
332void mei_host_start_message(struct mei_device *dev)
333{
334 struct mei_msg_hdr *mei_hdr;
335 struct hbm_host_version_request *start_req;
336 const size_t len = sizeof(struct hbm_host_version_request);
337
338 mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
339
340 /* host start message */
341 start_req = (struct hbm_host_version_request *)&dev->wr_msg_buf[1];
342 memset(start_req, 0, len);
343 start_req->hbm_cmd = HOST_START_REQ_CMD;
344 start_req->host_version.major_version = HBM_MAJOR_VERSION;
345 start_req->host_version.minor_version = HBM_MINOR_VERSION;
346
347 dev->recvd_msg = false;
348 if (mei_write_message(dev, mei_hdr, (unsigned char *)start_req, len)) {
349 dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n");
350 dev->dev_state = MEI_DEV_RESETING;
351 mei_reset(dev, 1);
352 }
353 dev->init_clients_state = MEI_START_MESSAGE;
354 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
355 return ;
356}
357
358/**
359 * host_enum_clients_message - host sends enumeration client request message.
360 *
361 * @dev: the device structure
362 *
363 * returns none.
364 */
365void mei_host_enum_clients_message(struct mei_device *dev)
366{
367 struct mei_msg_hdr *mei_hdr;
368 struct hbm_host_enum_request *enum_req;
369 const size_t len = sizeof(struct hbm_host_enum_request);
370 /* enumerate clients */
371 mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
372
373 enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1];
374 memset(enum_req, 0, sizeof(struct hbm_host_enum_request));
375 enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
376
377 if (mei_write_message(dev, mei_hdr, (unsigned char *)enum_req, len)) {
378 dev->dev_state = MEI_DEV_RESETING;
379 dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
380 mei_reset(dev, 1);
381 }
382 dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE;
383 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
384 return;
385}
386
387
388/**
389 * allocate_me_clients_storage - allocates storage for me clients
390 *
391 * @dev: the device structure
392 *
393 * returns none.
394 */
395void mei_allocate_me_clients_storage(struct mei_device *dev)
396{
397 struct mei_me_client *clients;
398 int b;
399
400 /* count how many ME clients we have */
401 for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX)
402 dev->me_clients_num++;
403
404 if (dev->me_clients_num <= 0)
405 return ;
406
407
408 if (dev->me_clients != NULL) {
409 kfree(dev->me_clients);
410 dev->me_clients = NULL;
411 }
412 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n",
413 dev->me_clients_num * sizeof(struct mei_me_client));
414 /* allocate storage for ME clients representation */
415 clients = kcalloc(dev->me_clients_num,
416 sizeof(struct mei_me_client), GFP_KERNEL);
417 if (!clients) {
418 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
419 dev->dev_state = MEI_DEV_RESETING;
420 mei_reset(dev, 1);
421 return ;
422 }
423 dev->me_clients = clients;
424 return ;
425}
426
427void mei_host_client_init(struct work_struct *work)
428{
429 struct mei_device *dev = container_of(work,
430 struct mei_device, init_work);
431 struct mei_client_properties *client_props;
432 int i;
433
434 mutex_lock(&dev->device_lock);
435
436 bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
437 dev->open_handle_count = 0;
438
439 /*
440 * Reserving the first three client IDs
441 * 0: Reserved for MEI Bus Message communications
442 * 1: Reserved for Watchdog
443 * 2: Reserved for AMTHI
444 */
445 bitmap_set(dev->host_clients_map, 0, 3);
446
447 for (i = 0; i < dev->me_clients_num; i++) {
448 client_props = &dev->me_clients[i].props;
449
450 if (!uuid_le_cmp(client_props->protocol_name, mei_amthi_guid))
451 mei_amthif_host_init(dev);
452 else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid))
453 mei_wd_host_init(dev);
454 }
455
456 dev->dev_state = MEI_DEV_ENABLED;
457
458 mutex_unlock(&dev->device_lock);
459}
460
461int mei_host_client_enumerate(struct mei_device *dev)
462{
463
464 struct mei_msg_hdr *mei_hdr;
465 struct hbm_props_request *prop_req;
466 const size_t len = sizeof(struct hbm_props_request);
467 unsigned long next_client_index;
468 u8 client_num;
469
470
471 client_num = dev->me_client_presentation_num;
472
473 next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX,
474 dev->me_client_index);
475
476 /* We got all client properties */
477 if (next_client_index == MEI_CLIENTS_MAX) {
478 schedule_work(&dev->init_work);
479
480 return 0;
481 }
482
483 dev->me_clients[client_num].client_id = next_client_index;
484 dev->me_clients[client_num].mei_flow_ctrl_creds = 0;
485
486 mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
487 prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1];
488
489 memset(prop_req, 0, sizeof(struct hbm_props_request));
490
491
492 prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
493 prop_req->address = next_client_index;
494
495 if (mei_write_message(dev, mei_hdr, (unsigned char *) prop_req,
496 mei_hdr->length)) {
497 dev->dev_state = MEI_DEV_RESETING;
498 dev_err(&dev->pdev->dev, "Properties request command failed\n");
499 mei_reset(dev, 1);
500
501 return -EIO;
502 }
503
504 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
505 dev->me_client_index = next_client_index;
506
507 return 0;
508}
509
510/**
511 * mei_init_file_private - initializes private file structure.
512 *
513 * @priv: private file structure to be initialized
514 * @file: the file structure
515 */
516void mei_cl_init(struct mei_cl *priv, struct mei_device *dev)
517{
518 memset(priv, 0, sizeof(struct mei_cl));
519 init_waitqueue_head(&priv->wait);
520 init_waitqueue_head(&priv->rx_wait);
521 init_waitqueue_head(&priv->tx_wait);
522 INIT_LIST_HEAD(&priv->link);
523 priv->reading_state = MEI_IDLE;
524 priv->writing_state = MEI_IDLE;
525 priv->dev = dev;
526}
527
528int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid)
529{
530 int i, res = -ENOENT;
531
532 for (i = 0; i < dev->me_clients_num; ++i)
533 if (uuid_le_cmp(*cuuid,
534 dev->me_clients[i].props.protocol_name) == 0) {
535 res = i;
536 break;
537 }
538
539 return res;
540}
541
542
543/**
544 * mei_me_cl_link - create link between host and me clinet and add
545 * me_cl to the list
546 *
547 * @dev: the device structure
548 * @cl: link between me and host client assocated with opened file descriptor
549 * @cuuid: uuid of ME client
550 * @client_id: id of the host client
551 *
552 * returns ME client index if ME client
553 * -EINVAL on incorrect values
554 * -ENONET if client not found
555 */
556int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl,
557 const uuid_le *cuuid, u8 host_cl_id)
558{
559 int i;
560
561 if (!dev || !cl || !cuuid)
562 return -EINVAL;
563
564 /* check for valid client id */
565 i = mei_me_cl_by_uuid(dev, cuuid);
566 if (i >= 0) {
567 cl->me_client_id = dev->me_clients[i].client_id;
568 cl->state = MEI_FILE_CONNECTING;
569 cl->host_client_id = host_cl_id;
570
571 list_add_tail(&cl->link, &dev->file_list);
572 return (u8)i;
573 }
574
575 return -ENOENT;
576}
577/**
578 * mei_me_cl_unlink - remove me_cl from the list
579 *
580 * @dev: the device structure
581 * @host_client_id: host client id to be removed
582 */
583void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl)
584{
585 struct mei_cl *pos, *next;
586 list_for_each_entry_safe(pos, next, &dev->file_list, link) {
587 if (cl->host_client_id == pos->host_client_id) {
588 dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n",
589 pos->host_client_id, pos->me_client_id);
590 list_del_init(&pos->link);
591 break;
592 }
593 }
594}
595 181
596/** 182 /* remove all waiting requests */
597 * mei_alloc_file_private - allocates a private file structure and sets it up. 183 mei_cl_all_write_clear(dev);
598 * @file: the file structure
599 *
600 * returns The allocated file or NULL on failure
601 */
602struct mei_cl *mei_cl_allocate(struct mei_device *dev)
603{
604 struct mei_cl *cl;
605
606 cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL);
607 if (!cl)
608 return NULL;
609
610 mei_cl_init(cl, dev);
611
612 return cl;
613} 184}
614 185
615 186
616 187
617/**
618 * mei_disconnect_host_client - sends disconnect message to fw from host client.
619 *
620 * @dev: the device structure
621 * @cl: private data of the file object
622 *
623 * Locking: called under "dev->device_lock" lock
624 *
625 * returns 0 on success, <0 on failure.
626 */
627int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
628{
629 struct mei_cl_cb *cb;
630 int rets, err;
631
632 if (!dev || !cl)
633 return -ENODEV;
634
635 if (cl->state != MEI_FILE_DISCONNECTING)
636 return 0;
637
638 cb = mei_io_cb_init(cl, NULL);
639 if (!cb)
640 return -ENOMEM;
641
642 cb->fop_type = MEI_FOP_CLOSE;
643 if (dev->mei_host_buffer_is_empty) {
644 dev->mei_host_buffer_is_empty = false;
645 if (mei_disconnect(dev, cl)) {
646 rets = -ENODEV;
647 dev_dbg(&dev->pdev->dev, "failed to call mei_disconnect.\n");
648 goto free;
649 }
650 mdelay(10); /* Wait for hardware disconnection ready */
651 list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
652 } else {
653 dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n");
654 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
655
656 }
657 mutex_unlock(&dev->device_lock);
658
659 err = wait_event_timeout(dev->wait_recvd_msg,
660 MEI_FILE_DISCONNECTED == cl->state,
661 mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
662
663 mutex_lock(&dev->device_lock);
664 if (MEI_FILE_DISCONNECTED == cl->state) {
665 rets = 0;
666 dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n");
667 } else {
668 rets = -ENODEV;
669 if (MEI_FILE_DISCONNECTED != cl->state)
670 dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n");
671
672 if (err)
673 dev_dbg(&dev->pdev->dev,
674 "wait failed disconnect err=%08x\n",
675 err);
676
677 dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n");
678 }
679
680 mei_io_list_flush(&dev->ctrl_rd_list, cl);
681 mei_io_list_flush(&dev->ctrl_wr_list, cl);
682free:
683 mei_io_cb_free(cb);
684 return rets;
685}
686 188
diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c
deleted file mode 100644
index 8de854785960..000000000000
--- a/drivers/misc/mei/interface.c
+++ /dev/null
@@ -1,388 +0,0 @@
1/*
2 *
3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 */
16
17#include <linux/pci.h>
18#include "mei_dev.h"
19#include <linux/mei.h>
20#include "interface.h"
21
22
23
24/**
25 * mei_set_csr_register - writes H_CSR register to the mei device,
26 * and ignores the H_IS bit for it is write-one-to-zero.
27 *
28 * @dev: the device structure
29 */
30void mei_hcsr_set(struct mei_device *dev)
31{
32 if ((dev->host_hw_state & H_IS) == H_IS)
33 dev->host_hw_state &= ~H_IS;
34 mei_reg_write(dev, H_CSR, dev->host_hw_state);
35 dev->host_hw_state = mei_hcsr_read(dev);
36}
37
38/**
39 * mei_csr_enable_interrupts - enables mei device interrupts
40 *
41 * @dev: the device structure
42 */
43void mei_enable_interrupts(struct mei_device *dev)
44{
45 dev->host_hw_state |= H_IE;
46 mei_hcsr_set(dev);
47}
48
49/**
50 * mei_csr_disable_interrupts - disables mei device interrupts
51 *
52 * @dev: the device structure
53 */
54void mei_disable_interrupts(struct mei_device *dev)
55{
56 dev->host_hw_state &= ~H_IE;
57 mei_hcsr_set(dev);
58}
59
60/**
61 * mei_hbuf_filled_slots - gets number of device filled buffer slots
62 *
63 * @device: the device structure
64 *
65 * returns number of filled slots
66 */
67static unsigned char mei_hbuf_filled_slots(struct mei_device *dev)
68{
69 char read_ptr, write_ptr;
70
71 dev->host_hw_state = mei_hcsr_read(dev);
72
73 read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8);
74 write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16);
75
76 return (unsigned char) (write_ptr - read_ptr);
77}
78
79/**
80 * mei_hbuf_is_empty - checks if host buffer is empty.
81 *
82 * @dev: the device structure
83 *
84 * returns true if empty, false - otherwise.
85 */
86bool mei_hbuf_is_empty(struct mei_device *dev)
87{
88 return mei_hbuf_filled_slots(dev) == 0;
89}
90
91/**
92 * mei_hbuf_empty_slots - counts write empty slots.
93 *
94 * @dev: the device structure
95 *
96 * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count
97 */
98int mei_hbuf_empty_slots(struct mei_device *dev)
99{
100 unsigned char filled_slots, empty_slots;
101
102 filled_slots = mei_hbuf_filled_slots(dev);
103 empty_slots = dev->hbuf_depth - filled_slots;
104
105 /* check for overflow */
106 if (filled_slots > dev->hbuf_depth)
107 return -EOVERFLOW;
108
109 return empty_slots;
110}
111
112/**
113 * mei_write_message - writes a message to mei device.
114 *
115 * @dev: the device structure
116 * @header: header of message
117 * @write_buffer: message buffer will be written
118 * @write_length: message size will be written
119 *
120 * This function returns -EIO if write has failed
121 */
122int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header,
123 unsigned char *buf, unsigned long length)
124{
125 unsigned long rem, dw_cnt;
126 u32 *reg_buf = (u32 *)buf;
127 int i;
128 int empty_slots;
129
130
131 dev_dbg(&dev->pdev->dev,
132 "mei_write_message header=%08x.\n",
133 *((u32 *) header));
134
135 empty_slots = mei_hbuf_empty_slots(dev);
136 dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots);
137
138 dw_cnt = mei_data2slots(length);
139 if (empty_slots < 0 || dw_cnt > empty_slots)
140 return -EIO;
141
142 mei_reg_write(dev, H_CB_WW, *((u32 *) header));
143
144 for (i = 0; i < length / 4; i++)
145 mei_reg_write(dev, H_CB_WW, reg_buf[i]);
146
147 rem = length & 0x3;
148 if (rem > 0) {
149 u32 reg = 0;
150 memcpy(&reg, &buf[length - rem], rem);
151 mei_reg_write(dev, H_CB_WW, reg);
152 }
153
154 dev->host_hw_state = mei_hcsr_read(dev);
155 dev->host_hw_state |= H_IG;
156 mei_hcsr_set(dev);
157 dev->me_hw_state = mei_mecsr_read(dev);
158 if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA)
159 return -EIO;
160
161 return 0;
162}
163
164/**
165 * mei_count_full_read_slots - counts read full slots.
166 *
167 * @dev: the device structure
168 *
169 * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count
170 */
171int mei_count_full_read_slots(struct mei_device *dev)
172{
173 char read_ptr, write_ptr;
174 unsigned char buffer_depth, filled_slots;
175
176 dev->me_hw_state = mei_mecsr_read(dev);
177 buffer_depth = (unsigned char)((dev->me_hw_state & ME_CBD_HRA) >> 24);
178 read_ptr = (char) ((dev->me_hw_state & ME_CBRP_HRA) >> 8);
179 write_ptr = (char) ((dev->me_hw_state & ME_CBWP_HRA) >> 16);
180 filled_slots = (unsigned char) (write_ptr - read_ptr);
181
182 /* check for overflow */
183 if (filled_slots > buffer_depth)
184 return -EOVERFLOW;
185
186 dev_dbg(&dev->pdev->dev, "filled_slots =%08x\n", filled_slots);
187 return (int)filled_slots;
188}
189
190/**
191 * mei_read_slots - reads a message from mei device.
192 *
193 * @dev: the device structure
194 * @buffer: message buffer will be written
195 * @buffer_length: message size will be read
196 */
197void mei_read_slots(struct mei_device *dev, unsigned char *buffer,
198 unsigned long buffer_length)
199{
200 u32 *reg_buf = (u32 *)buffer;
201
202 for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32))
203 *reg_buf++ = mei_mecbrw_read(dev);
204
205 if (buffer_length > 0) {
206 u32 reg = mei_mecbrw_read(dev);
207 memcpy(reg_buf, &reg, buffer_length);
208 }
209
210 dev->host_hw_state |= H_IG;
211 mei_hcsr_set(dev);
212}
213
214/**
215 * mei_flow_ctrl_creds - checks flow_control credentials.
216 *
217 * @dev: the device structure
218 * @cl: private data of the file object
219 *
220 * returns 1 if mei_flow_ctrl_creds >0, 0 - otherwise.
221 * -ENOENT if mei_cl is not present
222 * -EINVAL if single_recv_buf == 0
223 */
224int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl)
225{
226 int i;
227
228 if (!dev->me_clients_num)
229 return 0;
230
231 if (cl->mei_flow_ctrl_creds > 0)
232 return 1;
233
234 for (i = 0; i < dev->me_clients_num; i++) {
235 struct mei_me_client *me_cl = &dev->me_clients[i];
236 if (me_cl->client_id == cl->me_client_id) {
237 if (me_cl->mei_flow_ctrl_creds) {
238 if (WARN_ON(me_cl->props.single_recv_buf == 0))
239 return -EINVAL;
240 return 1;
241 } else {
242 return 0;
243 }
244 }
245 }
246 return -ENOENT;
247}
248
249/**
250 * mei_flow_ctrl_reduce - reduces flow_control.
251 *
252 * @dev: the device structure
253 * @cl: private data of the file object
254 * @returns
255 * 0 on success
256 * -ENOENT when me client is not found
257 * -EINVAL when ctrl credits are <= 0
258 */
259int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl)
260{
261 int i;
262
263 if (!dev->me_clients_num)
264 return -ENOENT;
265
266 for (i = 0; i < dev->me_clients_num; i++) {
267 struct mei_me_client *me_cl = &dev->me_clients[i];
268 if (me_cl->client_id == cl->me_client_id) {
269 if (me_cl->props.single_recv_buf != 0) {
270 if (WARN_ON(me_cl->mei_flow_ctrl_creds <= 0))
271 return -EINVAL;
272 dev->me_clients[i].mei_flow_ctrl_creds--;
273 } else {
274 if (WARN_ON(cl->mei_flow_ctrl_creds <= 0))
275 return -EINVAL;
276 cl->mei_flow_ctrl_creds--;
277 }
278 return 0;
279 }
280 }
281 return -ENOENT;
282}
283
284/**
285 * mei_send_flow_control - sends flow control to fw.
286 *
287 * @dev: the device structure
288 * @cl: private data of the file object
289 *
290 * This function returns -EIO on write failure
291 */
292int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl)
293{
294 struct mei_msg_hdr *mei_hdr;
295 struct hbm_flow_control *flow_ctrl;
296 const size_t len = sizeof(struct hbm_flow_control);
297
298 mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
299
300 flow_ctrl = (struct hbm_flow_control *)&dev->wr_msg_buf[1];
301 memset(flow_ctrl, 0, len);
302 flow_ctrl->hbm_cmd = MEI_FLOW_CONTROL_CMD;
303 flow_ctrl->host_addr = cl->host_client_id;
304 flow_ctrl->me_addr = cl->me_client_id;
305 /* FIXME: reserved !? */
306 memset(flow_ctrl->reserved, 0, sizeof(flow_ctrl->reserved));
307 dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n",
308 cl->host_client_id, cl->me_client_id);
309
310 return mei_write_message(dev, mei_hdr,
311 (unsigned char *) flow_ctrl, len);
312}
313
314/**
315 * mei_other_client_is_connecting - checks if other
316 * client with the same client id is connected.
317 *
318 * @dev: the device structure
319 * @cl: private data of the file object
320 *
321 * returns 1 if other client is connected, 0 - otherwise.
322 */
323int mei_other_client_is_connecting(struct mei_device *dev,
324 struct mei_cl *cl)
325{
326 struct mei_cl *cl_pos = NULL;
327 struct mei_cl *cl_next = NULL;
328
329 list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
330 if ((cl_pos->state == MEI_FILE_CONNECTING) &&
331 (cl_pos != cl) &&
332 cl->me_client_id == cl_pos->me_client_id)
333 return 1;
334
335 }
336 return 0;
337}
338
339/**
340 * mei_disconnect - sends disconnect message to fw.
341 *
342 * @dev: the device structure
343 * @cl: private data of the file object
344 *
345 * This function returns -EIO on write failure
346 */
347int mei_disconnect(struct mei_device *dev, struct mei_cl *cl)
348{
349 struct mei_msg_hdr *mei_hdr;
350 struct hbm_client_connect_request *req;
351 const size_t len = sizeof(struct hbm_client_connect_request);
352
353 mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
354
355 req = (struct hbm_client_connect_request *)&dev->wr_msg_buf[1];
356 memset(req, 0, len);
357 req->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD;
358 req->host_addr = cl->host_client_id;
359 req->me_addr = cl->me_client_id;
360 req->reserved = 0;
361
362 return mei_write_message(dev, mei_hdr, (unsigned char *)req, len);
363}
364
365/**
366 * mei_connect - sends connect message to fw.
367 *
368 * @dev: the device structure
369 * @cl: private data of the file object
370 *
371 * This function returns -EIO on write failure
372 */
373int mei_connect(struct mei_device *dev, struct mei_cl *cl)
374{
375 struct mei_msg_hdr *mei_hdr;
376 struct hbm_client_connect_request *req;
377 const size_t len = sizeof(struct hbm_client_connect_request);
378
379 mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
380
381 req = (struct hbm_client_connect_request *) &dev->wr_msg_buf[1];
382 req->hbm_cmd = CLIENT_CONNECT_REQ_CMD;
383 req->host_addr = cl->host_client_id;
384 req->me_addr = cl->me_client_id;
385 req->reserved = 0;
386
387 return mei_write_message(dev, mei_hdr, (unsigned char *) req, len);
388}
diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h
deleted file mode 100644
index ec6c785a3961..000000000000
--- a/drivers/misc/mei/interface.h
+++ /dev/null
@@ -1,81 +0,0 @@
1/*
2 *
3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 */
16
17
18
19#ifndef _MEI_INTERFACE_H_
20#define _MEI_INTERFACE_H_
21
22#include <linux/mei.h>
23#include "mei_dev.h"
24
25
26
27void mei_read_slots(struct mei_device *dev,
28 unsigned char *buffer,
29 unsigned long buffer_length);
30
31int mei_write_message(struct mei_device *dev,
32 struct mei_msg_hdr *header,
33 unsigned char *write_buffer,
34 unsigned long write_length);
35
36bool mei_hbuf_is_empty(struct mei_device *dev);
37
38int mei_hbuf_empty_slots(struct mei_device *dev);
39
40static inline size_t mei_hbuf_max_data(const struct mei_device *dev)
41{
42 return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr);
43}
44
45/* get slots (dwords) from a message length + header (bytes) */
46static inline unsigned char mei_data2slots(size_t length)
47{
48 return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
49}
50
51int mei_count_full_read_slots(struct mei_device *dev);
52
53
54int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl);
55
56
57
58int mei_wd_send(struct mei_device *dev);
59int mei_wd_stop(struct mei_device *dev);
60int mei_wd_host_init(struct mei_device *dev);
61/*
62 * mei_watchdog_register - Registering watchdog interface
63 * once we got connection to the WD Client
64 * @dev - mei device
65 */
66void mei_watchdog_register(struct mei_device *dev);
67/*
68 * mei_watchdog_unregister - Unregistering watchdog interface
69 * @dev - mei device
70 */
71void mei_watchdog_unregister(struct mei_device *dev);
72
73int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl);
74
75int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl);
76
77int mei_disconnect(struct mei_device *dev, struct mei_cl *cl);
78int mei_other_client_is_connecting(struct mei_device *dev, struct mei_cl *cl);
79int mei_connect(struct mei_device *dev, struct mei_cl *cl);
80
81#endif /* _MEI_INTERFACE_H_ */
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 04fa2134615e..3535b2676c97 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -21,41 +21,21 @@
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/jiffies.h> 22#include <linux/jiffies.h>
23 23
24#include "mei_dev.h"
25#include <linux/mei.h> 24#include <linux/mei.h>
26#include "hw.h"
27#include "interface.h"
28
29
30/**
31 * mei_interrupt_quick_handler - The ISR of the MEI device
32 *
33 * @irq: The irq number
34 * @dev_id: pointer to the device structure
35 *
36 * returns irqreturn_t
37 */
38irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id)
39{
40 struct mei_device *dev = (struct mei_device *) dev_id;
41 u32 csr_reg = mei_hcsr_read(dev);
42
43 if ((csr_reg & H_IS) != H_IS)
44 return IRQ_NONE;
45 25
46 /* clear H_IS bit in H_CSR */ 26#include "mei_dev.h"
47 mei_reg_write(dev, H_CSR, csr_reg); 27#include "hbm.h"
28#include "hw-me.h"
29#include "client.h"
48 30
49 return IRQ_WAKE_THREAD;
50}
51 31
52/** 32/**
53 * _mei_cmpl - processes completed operation. 33 * mei_complete_handler - processes completed operation.
54 * 34 *
55 * @cl: private data of the file object. 35 * @cl: private data of the file object.
56 * @cb_pos: callback block. 36 * @cb_pos: callback block.
57 */ 37 */
58static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos) 38void mei_irq_complete_handler(struct mei_cl *cl, struct mei_cl_cb *cb_pos)
59{ 39{
60 if (cb_pos->fop_type == MEI_FOP_WRITE) { 40 if (cb_pos->fop_type == MEI_FOP_WRITE) {
61 mei_io_cb_free(cb_pos); 41 mei_io_cb_free(cb_pos);
@@ -150,8 +130,8 @@ quit:
150 dev_dbg(&dev->pdev->dev, "message read\n"); 130 dev_dbg(&dev->pdev->dev, "message read\n");
151 if (!buffer) { 131 if (!buffer) {
152 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); 132 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
153 dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n", 133 dev_dbg(&dev->pdev->dev, "discarding message " MEI_HDR_FMT "\n",
154 *(u32 *) dev->rd_msg_buf); 134 MEI_HDR_PRM(mei_hdr));
155 } 135 }
156 136
157 return 0; 137 return 0;
@@ -179,7 +159,7 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
179 159
180 *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); 160 *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request));
181 161
182 if (mei_disconnect(dev, cl)) { 162 if (mei_hbm_cl_disconnect_req(dev, cl)) {
183 cl->status = 0; 163 cl->status = 0;
184 cb_pos->buf_idx = 0; 164 cb_pos->buf_idx = 0;
185 list_move_tail(&cb_pos->list, &cmpl_list->list); 165 list_move_tail(&cb_pos->list, &cmpl_list->list);
@@ -195,440 +175,6 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
195 return 0; 175 return 0;
196} 176}
197 177
198/**
199 * is_treat_specially_client - checks if the message belongs
200 * to the file private data.
201 *
202 * @cl: private data of the file object
203 * @rs: connect response bus message
204 *
205 */
206static bool is_treat_specially_client(struct mei_cl *cl,
207 struct hbm_client_connect_response *rs)
208{
209
210 if (cl->host_client_id == rs->host_addr &&
211 cl->me_client_id == rs->me_addr) {
212 if (!rs->status) {
213 cl->state = MEI_FILE_CONNECTED;
214 cl->status = 0;
215
216 } else {
217 cl->state = MEI_FILE_DISCONNECTED;
218 cl->status = -ENODEV;
219 }
220 cl->timer_count = 0;
221
222 return true;
223 }
224 return false;
225}
226
227/**
228 * mei_client_connect_response - connects to response irq routine
229 *
230 * @dev: the device structure
231 * @rs: connect response bus message
232 */
233static void mei_client_connect_response(struct mei_device *dev,
234 struct hbm_client_connect_response *rs)
235{
236
237 struct mei_cl *cl;
238 struct mei_cl_cb *pos = NULL, *next = NULL;
239
240 dev_dbg(&dev->pdev->dev,
241 "connect_response:\n"
242 "ME Client = %d\n"
243 "Host Client = %d\n"
244 "Status = %d\n",
245 rs->me_addr,
246 rs->host_addr,
247 rs->status);
248
249 /* if WD or iamthif client treat specially */
250
251 if (is_treat_specially_client(&(dev->wd_cl), rs)) {
252 dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
253 mei_watchdog_register(dev);
254
255 return;
256 }
257
258 if (is_treat_specially_client(&(dev->iamthif_cl), rs)) {
259 dev->iamthif_state = MEI_IAMTHIF_IDLE;
260 return;
261 }
262 list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
263
264 cl = pos->cl;
265 if (!cl) {
266 list_del(&pos->list);
267 return;
268 }
269 if (pos->fop_type == MEI_FOP_IOCTL) {
270 if (is_treat_specially_client(cl, rs)) {
271 list_del(&pos->list);
272 cl->status = 0;
273 cl->timer_count = 0;
274 break;
275 }
276 }
277 }
278}
279
280/**
281 * mei_client_disconnect_response - disconnects from response irq routine
282 *
283 * @dev: the device structure
284 * @rs: disconnect response bus message
285 */
286static void mei_client_disconnect_response(struct mei_device *dev,
287 struct hbm_client_connect_response *rs)
288{
289 struct mei_cl *cl;
290 struct mei_cl_cb *pos = NULL, *next = NULL;
291
292 dev_dbg(&dev->pdev->dev,
293 "disconnect_response:\n"
294 "ME Client = %d\n"
295 "Host Client = %d\n"
296 "Status = %d\n",
297 rs->me_addr,
298 rs->host_addr,
299 rs->status);
300
301 list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
302 cl = pos->cl;
303
304 if (!cl) {
305 list_del(&pos->list);
306 return;
307 }
308
309 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
310 if (cl->host_client_id == rs->host_addr &&
311 cl->me_client_id == rs->me_addr) {
312
313 list_del(&pos->list);
314 if (!rs->status)
315 cl->state = MEI_FILE_DISCONNECTED;
316
317 cl->status = 0;
318 cl->timer_count = 0;
319 break;
320 }
321 }
322}
323
324/**
325 * same_flow_addr - tells if they have the same address.
326 *
327 * @file: private data of the file object.
328 * @flow: flow control.
329 *
330 * returns !=0, same; 0,not.
331 */
332static int same_flow_addr(struct mei_cl *cl, struct hbm_flow_control *flow)
333{
334 return (cl->host_client_id == flow->host_addr &&
335 cl->me_client_id == flow->me_addr);
336}
337
338/**
339 * add_single_flow_creds - adds single buffer credentials.
340 *
341 * @file: private data ot the file object.
342 * @flow: flow control.
343 */
344static void add_single_flow_creds(struct mei_device *dev,
345 struct hbm_flow_control *flow)
346{
347 struct mei_me_client *client;
348 int i;
349
350 for (i = 0; i < dev->me_clients_num; i++) {
351 client = &dev->me_clients[i];
352 if (client && flow->me_addr == client->client_id) {
353 if (client->props.single_recv_buf) {
354 client->mei_flow_ctrl_creds++;
355 dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n",
356 flow->me_addr);
357 dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n",
358 client->mei_flow_ctrl_creds);
359 } else {
360 BUG(); /* error in flow control */
361 }
362 }
363 }
364}
365
366/**
367 * mei_client_flow_control_response - flow control response irq routine
368 *
369 * @dev: the device structure
370 * @flow_control: flow control response bus message
371 */
372static void mei_client_flow_control_response(struct mei_device *dev,
373 struct hbm_flow_control *flow_control)
374{
375 struct mei_cl *cl_pos = NULL;
376 struct mei_cl *cl_next = NULL;
377
378 if (!flow_control->host_addr) {
379 /* single receive buffer */
380 add_single_flow_creds(dev, flow_control);
381 } else {
382 /* normal connection */
383 list_for_each_entry_safe(cl_pos, cl_next,
384 &dev->file_list, link) {
385 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in file_list\n");
386
387 dev_dbg(&dev->pdev->dev, "cl of host client %d ME client %d.\n",
388 cl_pos->host_client_id,
389 cl_pos->me_client_id);
390 dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n",
391 flow_control->host_addr,
392 flow_control->me_addr);
393 if (same_flow_addr(cl_pos, flow_control)) {
394 dev_dbg(&dev->pdev->dev, "recv ctrl msg for host %d ME %d.\n",
395 flow_control->host_addr,
396 flow_control->me_addr);
397 cl_pos->mei_flow_ctrl_creds++;
398 dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n",
399 cl_pos->mei_flow_ctrl_creds);
400 break;
401 }
402 }
403 }
404}
405
406/**
407 * same_disconn_addr - tells if they have the same address
408 *
409 * @file: private data of the file object.
410 * @disconn: disconnection request.
411 *
412 * returns !=0, same; 0,not.
413 */
414static int same_disconn_addr(struct mei_cl *cl,
415 struct hbm_client_connect_request *req)
416{
417 return (cl->host_client_id == req->host_addr &&
418 cl->me_client_id == req->me_addr);
419}
420
421/**
422 * mei_client_disconnect_request - disconnects from request irq routine
423 *
424 * @dev: the device structure.
425 * @disconnect_req: disconnect request bus message.
426 */
427static void mei_client_disconnect_request(struct mei_device *dev,
428 struct hbm_client_connect_request *disconnect_req)
429{
430 struct hbm_client_connect_response *disconnect_res;
431 struct mei_cl *pos, *next;
432 const size_t len = sizeof(struct hbm_client_connect_response);
433
434 list_for_each_entry_safe(pos, next, &dev->file_list, link) {
435 if (same_disconn_addr(pos, disconnect_req)) {
436 dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n",
437 disconnect_req->host_addr,
438 disconnect_req->me_addr);
439 pos->state = MEI_FILE_DISCONNECTED;
440 pos->timer_count = 0;
441 if (pos == &dev->wd_cl)
442 dev->wd_pending = false;
443 else if (pos == &dev->iamthif_cl)
444 dev->iamthif_timer = 0;
445
446 /* prepare disconnect response */
447 (void)mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len);
448 disconnect_res =
449 (struct hbm_client_connect_response *)
450 &dev->wr_ext_msg.data;
451 disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD;
452 disconnect_res->host_addr = pos->host_client_id;
453 disconnect_res->me_addr = pos->me_client_id;
454 disconnect_res->status = 0;
455 break;
456 }
457 }
458}
459
460/**
461 * mei_irq_thread_read_bus_message - bottom half read routine after ISR to
462 * handle the read bus message cmd processing.
463 *
464 * @dev: the device structure
465 * @mei_hdr: header of bus message
466 */
467static void mei_irq_thread_read_bus_message(struct mei_device *dev,
468 struct mei_msg_hdr *mei_hdr)
469{
470 struct mei_bus_message *mei_msg;
471 struct mei_me_client *me_client;
472 struct hbm_host_version_response *version_res;
473 struct hbm_client_connect_response *connect_res;
474 struct hbm_client_connect_response *disconnect_res;
475 struct hbm_client_connect_request *disconnect_req;
476 struct hbm_flow_control *flow_control;
477 struct hbm_props_response *props_res;
478 struct hbm_host_enum_response *enum_res;
479 struct hbm_host_stop_request *stop_req;
480
481 /* read the message to our buffer */
482 BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf));
483 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
484 mei_msg = (struct mei_bus_message *)dev->rd_msg_buf;
485
486 switch (mei_msg->hbm_cmd) {
487 case HOST_START_RES_CMD:
488 version_res = (struct hbm_host_version_response *) mei_msg;
489 if (version_res->host_version_supported) {
490 dev->version.major_version = HBM_MAJOR_VERSION;
491 dev->version.minor_version = HBM_MINOR_VERSION;
492 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
493 dev->init_clients_state == MEI_START_MESSAGE) {
494 dev->init_clients_timer = 0;
495 mei_host_enum_clients_message(dev);
496 } else {
497 dev->recvd_msg = false;
498 dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n");
499 mei_reset(dev, 1);
500 return;
501 }
502 } else {
503 u32 *buf = dev->wr_msg_buf;
504 const size_t len = sizeof(struct hbm_host_stop_request);
505
506 dev->version = version_res->me_max_version;
507
508 /* send stop message */
509 mei_hdr = mei_hbm_hdr(&buf[0], len);
510 stop_req = (struct hbm_host_stop_request *)&buf[1];
511 memset(stop_req, 0, len);
512 stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
513 stop_req->reason = DRIVER_STOP_REQUEST;
514
515 mei_write_message(dev, mei_hdr,
516 (unsigned char *)stop_req, len);
517 dev_dbg(&dev->pdev->dev, "version mismatch.\n");
518 return;
519 }
520
521 dev->recvd_msg = true;
522 dev_dbg(&dev->pdev->dev, "host start response message received.\n");
523 break;
524
525 case CLIENT_CONNECT_RES_CMD:
526 connect_res = (struct hbm_client_connect_response *) mei_msg;
527 mei_client_connect_response(dev, connect_res);
528 dev_dbg(&dev->pdev->dev, "client connect response message received.\n");
529 wake_up(&dev->wait_recvd_msg);
530 break;
531
532 case CLIENT_DISCONNECT_RES_CMD:
533 disconnect_res = (struct hbm_client_connect_response *) mei_msg;
534 mei_client_disconnect_response(dev, disconnect_res);
535 dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n");
536 wake_up(&dev->wait_recvd_msg);
537 break;
538
539 case MEI_FLOW_CONTROL_CMD:
540 flow_control = (struct hbm_flow_control *) mei_msg;
541 mei_client_flow_control_response(dev, flow_control);
542 dev_dbg(&dev->pdev->dev, "client flow control response message received.\n");
543 break;
544
545 case HOST_CLIENT_PROPERTIES_RES_CMD:
546 props_res = (struct hbm_props_response *)mei_msg;
547 me_client = &dev->me_clients[dev->me_client_presentation_num];
548
549 if (props_res->status || !dev->me_clients) {
550 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n");
551 mei_reset(dev, 1);
552 return;
553 }
554
555 if (me_client->client_id != props_res->address) {
556 dev_err(&dev->pdev->dev,
557 "Host client properties reply mismatch\n");
558 mei_reset(dev, 1);
559
560 return;
561 }
562
563 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
564 dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) {
565 dev_err(&dev->pdev->dev,
566 "Unexpected client properties reply\n");
567 mei_reset(dev, 1);
568
569 return;
570 }
571
572 me_client->props = props_res->client_properties;
573 dev->me_client_index++;
574 dev->me_client_presentation_num++;
575
576 mei_host_client_enumerate(dev);
577
578 break;
579
580 case HOST_ENUM_RES_CMD:
581 enum_res = (struct hbm_host_enum_response *) mei_msg;
582 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
583 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
584 dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) {
585 dev->init_clients_timer = 0;
586 dev->me_client_presentation_num = 0;
587 dev->me_client_index = 0;
588 mei_allocate_me_clients_storage(dev);
589 dev->init_clients_state =
590 MEI_CLIENT_PROPERTIES_MESSAGE;
591
592 mei_host_client_enumerate(dev);
593 } else {
594 dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n");
595 mei_reset(dev, 1);
596 return;
597 }
598 break;
599
600 case HOST_STOP_RES_CMD:
601 dev->dev_state = MEI_DEV_DISABLED;
602 dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n");
603 mei_reset(dev, 1);
604 break;
605
606 case CLIENT_DISCONNECT_REQ_CMD:
607 /* search for client */
608 disconnect_req = (struct hbm_client_connect_request *)mei_msg;
609 mei_client_disconnect_request(dev, disconnect_req);
610 break;
611
612 case ME_STOP_REQ_CMD:
613 {
614 /* prepare stop request: sent in next interrupt event */
615
616 const size_t len = sizeof(struct hbm_host_stop_request);
617
618 mei_hdr = mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len);
619 stop_req = (struct hbm_host_stop_request *)&dev->wr_ext_msg.data;
620 memset(stop_req, 0, len);
621 stop_req->hbm_cmd = HOST_STOP_REQ_CMD;
622 stop_req->reason = DRIVER_STOP_REQUEST;
623 break;
624 }
625 default:
626 BUG();
627 break;
628
629 }
630}
631
632 178
633/** 179/**
634 * _mei_hb_read - processes read related operation. 180 * _mei_hb_read - processes read related operation.
@@ -655,7 +201,7 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots,
655 201
656 *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); 202 *slots -= mei_data2slots(sizeof(struct hbm_flow_control));
657 203
658 if (mei_send_flow_control(dev, cl)) { 204 if (mei_hbm_cl_flow_control_req(dev, cl)) {
659 cl->status = -ENODEV; 205 cl->status = -ENODEV;
660 cb_pos->buf_idx = 0; 206 cb_pos->buf_idx = 0;
661 list_move_tail(&cb_pos->list, &cmpl_list->list); 207 list_move_tail(&cb_pos->list, &cmpl_list->list);
@@ -691,8 +237,8 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
691 } 237 }
692 238
693 cl->state = MEI_FILE_CONNECTING; 239 cl->state = MEI_FILE_CONNECTING;
694 *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); 240 *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request));
695 if (mei_connect(dev, cl)) { 241 if (mei_hbm_cl_connect_req(dev, cl)) {
696 cl->status = -ENODEV; 242 cl->status = -ENODEV;
697 cb_pos->buf_idx = 0; 243 cb_pos->buf_idx = 0;
698 list_del(&cb_pos->list); 244 list_del(&cb_pos->list);
@@ -717,25 +263,24 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
717static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots, 263static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots,
718 struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) 264 struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
719{ 265{
720 struct mei_msg_hdr *mei_hdr; 266 struct mei_msg_hdr mei_hdr;
721 struct mei_cl *cl = cb->cl; 267 struct mei_cl *cl = cb->cl;
722 size_t len = cb->request_buffer.size - cb->buf_idx; 268 size_t len = cb->request_buffer.size - cb->buf_idx;
723 size_t msg_slots = mei_data2slots(len); 269 size_t msg_slots = mei_data2slots(len);
724 270
725 mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; 271 mei_hdr.host_addr = cl->host_client_id;
726 mei_hdr->host_addr = cl->host_client_id; 272 mei_hdr.me_addr = cl->me_client_id;
727 mei_hdr->me_addr = cl->me_client_id; 273 mei_hdr.reserved = 0;
728 mei_hdr->reserved = 0;
729 274
730 if (*slots >= msg_slots) { 275 if (*slots >= msg_slots) {
731 mei_hdr->length = len; 276 mei_hdr.length = len;
732 mei_hdr->msg_complete = 1; 277 mei_hdr.msg_complete = 1;
733 /* Split the message only if we can write the whole host buffer */ 278 /* Split the message only if we can write the whole host buffer */
734 } else if (*slots == dev->hbuf_depth) { 279 } else if (*slots == dev->hbuf_depth) {
735 msg_slots = *slots; 280 msg_slots = *slots;
736 len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); 281 len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
737 mei_hdr->length = len; 282 mei_hdr.length = len;
738 mei_hdr->msg_complete = 0; 283 mei_hdr.msg_complete = 0;
739 } else { 284 } else {
740 /* wait for next time the host buffer is empty */ 285 /* wait for next time the host buffer is empty */
741 return 0; 286 return 0;
@@ -743,23 +288,22 @@ static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots,
743 288
744 dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n", 289 dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n",
745 cb->request_buffer.size, cb->buf_idx); 290 cb->request_buffer.size, cb->buf_idx);
746 dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n", 291 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
747 mei_hdr->length, mei_hdr->msg_complete);
748 292
749 *slots -= msg_slots; 293 *slots -= msg_slots;
750 if (mei_write_message(dev, mei_hdr, 294 if (mei_write_message(dev, &mei_hdr,
751 cb->request_buffer.data + cb->buf_idx, len)) { 295 cb->request_buffer.data + cb->buf_idx)) {
752 cl->status = -ENODEV; 296 cl->status = -ENODEV;
753 list_move_tail(&cb->list, &cmpl_list->list); 297 list_move_tail(&cb->list, &cmpl_list->list);
754 return -ENODEV; 298 return -ENODEV;
755 } 299 }
756 300
757 if (mei_flow_ctrl_reduce(dev, cl)) 301 if (mei_cl_flow_ctrl_reduce(cl))
758 return -ENODEV; 302 return -ENODEV;
759 303
760 cl->status = 0; 304 cl->status = 0;
761 cb->buf_idx += mei_hdr->length; 305 cb->buf_idx += mei_hdr.length;
762 if (mei_hdr->msg_complete) 306 if (mei_hdr.msg_complete)
763 list_move_tail(&cb->list, &dev->write_waiting_list.list); 307 list_move_tail(&cb->list, &dev->write_waiting_list.list);
764 308
765 return 0; 309 return 0;
@@ -769,15 +313,14 @@ static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots,
769 * mei_irq_thread_read_handler - bottom half read routine after ISR to 313 * mei_irq_thread_read_handler - bottom half read routine after ISR to
770 * handle the read processing. 314 * handle the read processing.
771 * 315 *
772 * @cmpl_list: An instance of our list structure
773 * @dev: the device structure 316 * @dev: the device structure
317 * @cmpl_list: An instance of our list structure
774 * @slots: slots to read. 318 * @slots: slots to read.
775 * 319 *
776 * returns 0 on success, <0 on failure. 320 * returns 0 on success, <0 on failure.
777 */ 321 */
778static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list, 322int mei_irq_read_handler(struct mei_device *dev,
779 struct mei_device *dev, 323 struct mei_cl_cb *cmpl_list, s32 *slots)
780 s32 *slots)
781{ 324{
782 struct mei_msg_hdr *mei_hdr; 325 struct mei_msg_hdr *mei_hdr;
783 struct mei_cl *cl_pos = NULL; 326 struct mei_cl *cl_pos = NULL;
@@ -785,13 +328,13 @@ static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list,
785 int ret = 0; 328 int ret = 0;
786 329
787 if (!dev->rd_msg_hdr) { 330 if (!dev->rd_msg_hdr) {
788 dev->rd_msg_hdr = mei_mecbrw_read(dev); 331 dev->rd_msg_hdr = mei_read_hdr(dev);
789 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); 332 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
790 (*slots)--; 333 (*slots)--;
791 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); 334 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
792 } 335 }
793 mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr; 336 mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr;
794 dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length); 337 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr));
795 338
796 if (mei_hdr->reserved || !dev->rd_msg_hdr) { 339 if (mei_hdr->reserved || !dev->rd_msg_hdr) {
797 dev_dbg(&dev->pdev->dev, "corrupted message header.\n"); 340 dev_dbg(&dev->pdev->dev, "corrupted message header.\n");
@@ -830,19 +373,18 @@ static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list,
830 /* decide where to read the message too */ 373 /* decide where to read the message too */
831 if (!mei_hdr->host_addr) { 374 if (!mei_hdr->host_addr) {
832 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n"); 375 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n");
833 mei_irq_thread_read_bus_message(dev, mei_hdr); 376 mei_hbm_dispatch(dev, mei_hdr);
834 dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n"); 377 dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n");
835 } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && 378 } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id &&
836 (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && 379 (MEI_FILE_CONNECTED == dev->iamthif_cl.state) &&
837 (dev->iamthif_state == MEI_IAMTHIF_READING)) { 380 (dev->iamthif_state == MEI_IAMTHIF_READING)) {
838 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); 381 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n");
839 dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", 382
840 mei_hdr->length); 383 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr));
841 384
842 ret = mei_amthif_irq_read_message(cmpl_list, dev, mei_hdr); 385 ret = mei_amthif_irq_read_message(cmpl_list, dev, mei_hdr);
843 if (ret) 386 if (ret)
844 goto end; 387 goto end;
845
846 } else { 388 } else {
847 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n"); 389 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n");
848 ret = mei_irq_thread_read_client_message(cmpl_list, 390 ret = mei_irq_thread_read_client_message(cmpl_list,
@@ -869,15 +411,15 @@ end:
869 411
870 412
871/** 413/**
872 * mei_irq_thread_write_handler - bottom half write routine after 414 * mei_irq_write_handler - dispatch write requests
873 * ISR to handle the write processing. 415 * after irq received
874 * 416 *
875 * @dev: the device structure 417 * @dev: the device structure
876 * @cmpl_list: An instance of our list structure 418 * @cmpl_list: An instance of our list structure
877 * 419 *
878 * returns 0 on success, <0 on failure. 420 * returns 0 on success, <0 on failure.
879 */ 421 */
880static int mei_irq_thread_write_handler(struct mei_device *dev, 422int mei_irq_write_handler(struct mei_device *dev,
881 struct mei_cl_cb *cmpl_list) 423 struct mei_cl_cb *cmpl_list)
882{ 424{
883 425
@@ -887,7 +429,7 @@ static int mei_irq_thread_write_handler(struct mei_device *dev,
887 s32 slots; 429 s32 slots;
888 int ret; 430 int ret;
889 431
890 if (!mei_hbuf_is_empty(dev)) { 432 if (!mei_hbuf_is_ready(dev)) {
891 dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); 433 dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n");
892 return 0; 434 return 0;
893 } 435 }
@@ -930,16 +472,16 @@ static int mei_irq_thread_write_handler(struct mei_device *dev,
930 472
931 if (dev->wr_ext_msg.hdr.length) { 473 if (dev->wr_ext_msg.hdr.length) {
932 mei_write_message(dev, &dev->wr_ext_msg.hdr, 474 mei_write_message(dev, &dev->wr_ext_msg.hdr,
933 dev->wr_ext_msg.data, dev->wr_ext_msg.hdr.length); 475 dev->wr_ext_msg.data);
934 slots -= mei_data2slots(dev->wr_ext_msg.hdr.length); 476 slots -= mei_data2slots(dev->wr_ext_msg.hdr.length);
935 dev->wr_ext_msg.hdr.length = 0; 477 dev->wr_ext_msg.hdr.length = 0;
936 } 478 }
937 if (dev->dev_state == MEI_DEV_ENABLED) { 479 if (dev->dev_state == MEI_DEV_ENABLED) {
938 if (dev->wd_pending && 480 if (dev->wd_pending &&
939 mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { 481 mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) {
940 if (mei_wd_send(dev)) 482 if (mei_wd_send(dev))
941 dev_dbg(&dev->pdev->dev, "wd send failed.\n"); 483 dev_dbg(&dev->pdev->dev, "wd send failed.\n");
942 else if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) 484 else if (mei_cl_flow_ctrl_reduce(&dev->wd_cl))
943 return -ENODEV; 485 return -ENODEV;
944 486
945 dev->wd_pending = false; 487 dev->wd_pending = false;
@@ -978,7 +520,7 @@ static int mei_irq_thread_write_handler(struct mei_device *dev,
978 break; 520 break;
979 case MEI_FOP_IOCTL: 521 case MEI_FOP_IOCTL:
980 /* connect message */ 522 /* connect message */
981 if (mei_other_client_is_connecting(dev, cl)) 523 if (mei_cl_is_other_connecting(cl))
982 continue; 524 continue;
983 ret = _mei_irq_thread_ioctl(dev, &slots, pos, 525 ret = _mei_irq_thread_ioctl(dev, &slots, pos,
984 cl, cmpl_list); 526 cl, cmpl_list);
@@ -998,7 +540,7 @@ static int mei_irq_thread_write_handler(struct mei_device *dev,
998 cl = pos->cl; 540 cl = pos->cl;
999 if (cl == NULL) 541 if (cl == NULL)
1000 continue; 542 continue;
1001 if (mei_flow_ctrl_creds(dev, cl) <= 0) { 543 if (mei_cl_flow_ctrl_creds(cl) <= 0) {
1002 dev_dbg(&dev->pdev->dev, 544 dev_dbg(&dev->pdev->dev,
1003 "No flow control credentials for client %d, not sending.\n", 545 "No flow control credentials for client %d, not sending.\n",
1004 cl->host_client_id); 546 cl->host_client_id);
@@ -1123,115 +665,3 @@ out:
1123 mutex_unlock(&dev->device_lock); 665 mutex_unlock(&dev->device_lock);
1124} 666}
1125 667
1126/**
1127 * mei_interrupt_thread_handler - function called after ISR to handle the interrupt
1128 * processing.
1129 *
1130 * @irq: The irq number
1131 * @dev_id: pointer to the device structure
1132 *
1133 * returns irqreturn_t
1134 *
1135 */
1136irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
1137{
1138 struct mei_device *dev = (struct mei_device *) dev_id;
1139 struct mei_cl_cb complete_list;
1140 struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
1141 struct mei_cl *cl;
1142 s32 slots;
1143 int rets;
1144 bool bus_message_received;
1145
1146
1147 dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n");
1148 /* initialize our complete list */
1149 mutex_lock(&dev->device_lock);
1150 mei_io_list_init(&complete_list);
1151 dev->host_hw_state = mei_hcsr_read(dev);
1152
1153 /* Ack the interrupt here
1154 * In case of MSI we don't go through the quick handler */
1155 if (pci_dev_msi_enabled(dev->pdev))
1156 mei_reg_write(dev, H_CSR, dev->host_hw_state);
1157
1158 dev->me_hw_state = mei_mecsr_read(dev);
1159
1160 /* check if ME wants a reset */
1161 if ((dev->me_hw_state & ME_RDY_HRA) == 0 &&
1162 dev->dev_state != MEI_DEV_RESETING &&
1163 dev->dev_state != MEI_DEV_INITIALIZING) {
1164 dev_dbg(&dev->pdev->dev, "FW not ready.\n");
1165 mei_reset(dev, 1);
1166 mutex_unlock(&dev->device_lock);
1167 return IRQ_HANDLED;
1168 }
1169
1170 /* check if we need to start the dev */
1171 if ((dev->host_hw_state & H_RDY) == 0) {
1172 if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) {
1173 dev_dbg(&dev->pdev->dev, "we need to start the dev.\n");
1174 dev->host_hw_state |= (H_IE | H_IG | H_RDY);
1175 mei_hcsr_set(dev);
1176 dev->dev_state = MEI_DEV_INIT_CLIENTS;
1177 dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n");
1178 /* link is established
1179 * start sending messages.
1180 */
1181 mei_host_start_message(dev);
1182 mutex_unlock(&dev->device_lock);
1183 return IRQ_HANDLED;
1184 } else {
1185 dev_dbg(&dev->pdev->dev, "FW not ready.\n");
1186 mutex_unlock(&dev->device_lock);
1187 return IRQ_HANDLED;
1188 }
1189 }
1190 /* check slots available for reading */
1191 slots = mei_count_full_read_slots(dev);
1192 while (slots > 0) {
1193 /* we have urgent data to send so break the read */
1194 if (dev->wr_ext_msg.hdr.length)
1195 break;
1196 dev_dbg(&dev->pdev->dev, "slots =%08x\n", slots);
1197 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n");
1198 rets = mei_irq_thread_read_handler(&complete_list, dev, &slots);
1199 if (rets)
1200 goto end;
1201 }
1202 rets = mei_irq_thread_write_handler(dev, &complete_list);
1203end:
1204 dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
1205 dev->host_hw_state = mei_hcsr_read(dev);
1206 dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev);
1207
1208 bus_message_received = false;
1209 if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
1210 dev_dbg(&dev->pdev->dev, "received waiting bus message\n");
1211 bus_message_received = true;
1212 }
1213 mutex_unlock(&dev->device_lock);
1214 if (bus_message_received) {
1215 dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n");
1216 wake_up_interruptible(&dev->wait_recvd_msg);
1217 bus_message_received = false;
1218 }
1219 if (list_empty(&complete_list.list))
1220 return IRQ_HANDLED;
1221
1222
1223 list_for_each_entry_safe(cb_pos, cb_next, &complete_list.list, list) {
1224 cl = cb_pos->cl;
1225 list_del(&cb_pos->list);
1226 if (cl) {
1227 if (cl != &dev->iamthif_cl) {
1228 dev_dbg(&dev->pdev->dev, "completing call back.\n");
1229 _mei_cmpl(cl, cb_pos);
1230 cb_pos = NULL;
1231 } else if (cl == &dev->iamthif_cl) {
1232 mei_amthif_complete(dev, cb_pos);
1233 }
1234 }
1235 }
1236 return IRQ_HANDLED;
1237}
diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c
deleted file mode 100644
index eb93a1b53b9b..000000000000
--- a/drivers/misc/mei/iorw.c
+++ /dev/null
@@ -1,366 +0,0 @@
1/*
2 *
3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 */
16
17
18#include <linux/kernel.h>
19#include <linux/fs.h>
20#include <linux/errno.h>
21#include <linux/types.h>
22#include <linux/fcntl.h>
23#include <linux/aio.h>
24#include <linux/pci.h>
25#include <linux/init.h>
26#include <linux/ioctl.h>
27#include <linux/cdev.h>
28#include <linux/list.h>
29#include <linux/delay.h>
30#include <linux/sched.h>
31#include <linux/uuid.h>
32#include <linux/jiffies.h>
33#include <linux/uaccess.h>
34
35
36#include "mei_dev.h"
37#include "hw.h"
38#include <linux/mei.h>
39#include "interface.h"
40
41/**
42 * mei_io_cb_free - free mei_cb_private related memory
43 *
44 * @cb: mei callback struct
45 */
46void mei_io_cb_free(struct mei_cl_cb *cb)
47{
48 if (cb == NULL)
49 return;
50
51 kfree(cb->request_buffer.data);
52 kfree(cb->response_buffer.data);
53 kfree(cb);
54}
55/**
56 * mei_io_cb_init - allocate and initialize io callback
57 *
58 * @cl - mei client
59 * @file: pointer to file structure
60 *
61 * returns mei_cl_cb pointer or NULL;
62 */
63struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp)
64{
65 struct mei_cl_cb *cb;
66
67 cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
68 if (!cb)
69 return NULL;
70
71 mei_io_list_init(cb);
72
73 cb->file_object = fp;
74 cb->cl = cl;
75 cb->buf_idx = 0;
76 return cb;
77}
78
79
80/**
81 * mei_io_cb_alloc_req_buf - allocate request buffer
82 *
83 * @cb - io callback structure
84 * @size: size of the buffer
85 *
86 * returns 0 on success
87 * -EINVAL if cb is NULL
88 * -ENOMEM if allocation failed
89 */
90int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length)
91{
92 if (!cb)
93 return -EINVAL;
94
95 if (length == 0)
96 return 0;
97
98 cb->request_buffer.data = kmalloc(length, GFP_KERNEL);
99 if (!cb->request_buffer.data)
100 return -ENOMEM;
101 cb->request_buffer.size = length;
102 return 0;
103}
104/**
105 * mei_io_cb_alloc_req_buf - allocate respose buffer
106 *
107 * @cb - io callback structure
108 * @size: size of the buffer
109 *
110 * returns 0 on success
111 * -EINVAL if cb is NULL
112 * -ENOMEM if allocation failed
113 */
114int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length)
115{
116 if (!cb)
117 return -EINVAL;
118
119 if (length == 0)
120 return 0;
121
122 cb->response_buffer.data = kmalloc(length, GFP_KERNEL);
123 if (!cb->response_buffer.data)
124 return -ENOMEM;
125 cb->response_buffer.size = length;
126 return 0;
127}
128
129
130/**
131 * mei_me_cl_by_id return index to me_clients for client_id
132 *
133 * @dev: the device structure
134 * @client_id: me client id
135 *
136 * Locking: called under "dev->device_lock" lock
137 *
138 * returns index on success, -ENOENT on failure.
139 */
140
141int mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
142{
143 int i;
144 for (i = 0; i < dev->me_clients_num; i++)
145 if (dev->me_clients[i].client_id == client_id)
146 break;
147 if (WARN_ON(dev->me_clients[i].client_id != client_id))
148 return -ENOENT;
149
150 if (i == dev->me_clients_num)
151 return -ENOENT;
152
153 return i;
154}
155
156/**
157 * mei_ioctl_connect_client - the connect to fw client IOCTL function
158 *
159 * @dev: the device structure
160 * @data: IOCTL connect data, input and output parameters
161 * @file: private data of the file object
162 *
163 * Locking: called under "dev->device_lock" lock
164 *
165 * returns 0 on success, <0 on failure.
166 */
167int mei_ioctl_connect_client(struct file *file,
168 struct mei_connect_client_data *data)
169{
170 struct mei_device *dev;
171 struct mei_cl_cb *cb;
172 struct mei_client *client;
173 struct mei_cl *cl;
174 long timeout = mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT);
175 int i;
176 int err;
177 int rets;
178
179 cl = file->private_data;
180 if (WARN_ON(!cl || !cl->dev))
181 return -ENODEV;
182
183 dev = cl->dev;
184
185 dev_dbg(&dev->pdev->dev, "mei_ioctl_connect_client() Entry\n");
186
187 /* buffered ioctl cb */
188 cb = mei_io_cb_init(cl, file);
189 if (!cb) {
190 rets = -ENOMEM;
191 goto end;
192 }
193
194 cb->fop_type = MEI_FOP_IOCTL;
195
196 if (dev->dev_state != MEI_DEV_ENABLED) {
197 rets = -ENODEV;
198 goto end;
199 }
200 if (cl->state != MEI_FILE_INITIALIZING &&
201 cl->state != MEI_FILE_DISCONNECTED) {
202 rets = -EBUSY;
203 goto end;
204 }
205
206 /* find ME client we're trying to connect to */
207 i = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
208 if (i >= 0 && !dev->me_clients[i].props.fixed_address) {
209 cl->me_client_id = dev->me_clients[i].client_id;
210 cl->state = MEI_FILE_CONNECTING;
211 }
212
213 dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n",
214 cl->me_client_id);
215 dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n",
216 dev->me_clients[i].props.protocol_version);
217 dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n",
218 dev->me_clients[i].props.max_msg_length);
219
220 /* if we're connecting to amthi client then we will use the
221 * existing connection
222 */
223 if (uuid_le_cmp(data->in_client_uuid, mei_amthi_guid) == 0) {
224 dev_dbg(&dev->pdev->dev, "FW Client is amthi\n");
225 if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) {
226 rets = -ENODEV;
227 goto end;
228 }
229 clear_bit(cl->host_client_id, dev->host_clients_map);
230 mei_me_cl_unlink(dev, cl);
231
232 kfree(cl);
233 cl = NULL;
234 file->private_data = &dev->iamthif_cl;
235
236 client = &data->out_client_properties;
237 client->max_msg_length =
238 dev->me_clients[i].props.max_msg_length;
239 client->protocol_version =
240 dev->me_clients[i].props.protocol_version;
241 rets = dev->iamthif_cl.status;
242
243 goto end;
244 }
245
246 if (cl->state != MEI_FILE_CONNECTING) {
247 rets = -ENODEV;
248 goto end;
249 }
250
251
252 /* prepare the output buffer */
253 client = &data->out_client_properties;
254 client->max_msg_length = dev->me_clients[i].props.max_msg_length;
255 client->protocol_version = dev->me_clients[i].props.protocol_version;
256 dev_dbg(&dev->pdev->dev, "Can connect?\n");
257 if (dev->mei_host_buffer_is_empty
258 && !mei_other_client_is_connecting(dev, cl)) {
259 dev_dbg(&dev->pdev->dev, "Sending Connect Message\n");
260 dev->mei_host_buffer_is_empty = false;
261 if (mei_connect(dev, cl)) {
262 dev_dbg(&dev->pdev->dev, "Sending connect message - failed\n");
263 rets = -ENODEV;
264 goto end;
265 } else {
266 dev_dbg(&dev->pdev->dev, "Sending connect message - succeeded\n");
267 cl->timer_count = MEI_CONNECT_TIMEOUT;
268 list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
269 }
270
271
272 } else {
273 dev_dbg(&dev->pdev->dev, "Queuing the connect request due to device busy\n");
274 dev_dbg(&dev->pdev->dev, "add connect cb to control write list.\n");
275 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
276 }
277 mutex_unlock(&dev->device_lock);
278 err = wait_event_timeout(dev->wait_recvd_msg,
279 (MEI_FILE_CONNECTED == cl->state ||
280 MEI_FILE_DISCONNECTED == cl->state), timeout);
281
282 mutex_lock(&dev->device_lock);
283 if (MEI_FILE_CONNECTED == cl->state) {
284 dev_dbg(&dev->pdev->dev, "successfully connected to FW client.\n");
285 rets = cl->status;
286 goto end;
287 } else {
288 dev_dbg(&dev->pdev->dev, "failed to connect to FW client.cl->state = %d.\n",
289 cl->state);
290 if (!err) {
291 dev_dbg(&dev->pdev->dev,
292 "wait_event_interruptible_timeout failed on client"
293 " connect message fw response message.\n");
294 }
295 rets = -EFAULT;
296
297 mei_io_list_flush(&dev->ctrl_rd_list, cl);
298 mei_io_list_flush(&dev->ctrl_wr_list, cl);
299 goto end;
300 }
301 rets = 0;
302end:
303 dev_dbg(&dev->pdev->dev, "free connect cb memory.");
304 mei_io_cb_free(cb);
305 return rets;
306}
307
308/**
309 * mei_start_read - the start read client message function.
310 *
311 * @dev: the device structure
312 * @if_num: minor number
313 * @cl: private data of the file object
314 *
315 * returns 0 on success, <0 on failure.
316 */
317int mei_start_read(struct mei_device *dev, struct mei_cl *cl)
318{
319 struct mei_cl_cb *cb;
320 int rets;
321 int i;
322
323 if (cl->state != MEI_FILE_CONNECTED)
324 return -ENODEV;
325
326 if (dev->dev_state != MEI_DEV_ENABLED)
327 return -ENODEV;
328
329 if (cl->read_pending || cl->read_cb) {
330 dev_dbg(&dev->pdev->dev, "read is pending.\n");
331 return -EBUSY;
332 }
333 i = mei_me_cl_by_id(dev, cl->me_client_id);
334 if (i < 0) {
335 dev_err(&dev->pdev->dev, "no such me client %d\n",
336 cl->me_client_id);
337 return -ENODEV;
338 }
339
340 cb = mei_io_cb_init(cl, NULL);
341 if (!cb)
342 return -ENOMEM;
343
344 rets = mei_io_cb_alloc_resp_buf(cb,
345 dev->me_clients[i].props.max_msg_length);
346 if (rets)
347 goto err;
348
349 cb->fop_type = MEI_FOP_READ;
350 cl->read_cb = cb;
351 if (dev->mei_host_buffer_is_empty) {
352 dev->mei_host_buffer_is_empty = false;
353 if (mei_send_flow_control(dev, cl)) {
354 rets = -ENODEV;
355 goto err;
356 }
357 list_add_tail(&cb->list, &dev->read_list.list);
358 } else {
359 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
360 }
361 return rets;
362err:
363 mei_io_cb_free(cb);
364 return rets;
365}
366
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 43fb52ff98ad..903f809b21f7 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -37,79 +37,11 @@
37#include <linux/interrupt.h> 37#include <linux/interrupt.h>
38#include <linux/miscdevice.h> 38#include <linux/miscdevice.h>
39 39
40#include "mei_dev.h"
41#include <linux/mei.h> 40#include <linux/mei.h>
42#include "interface.h"
43
44/* AMT device is a singleton on the platform */
45static struct pci_dev *mei_pdev;
46
47/* mei_pci_tbl - PCI Device ID Table */
48static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = {
49 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)},
50 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)},
51 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)},
52 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G965)},
53 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GM965)},
54 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GME965)},
55 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q35)},
56 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82G33)},
57 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q33)},
58 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82X38)},
59 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_3200)},
60 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_6)},
61 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_7)},
62 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_8)},
63 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_9)},
64 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_10)},
65 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_1)},
66 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_2)},
67 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_3)},
68 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_4)},
69 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_1)},
70 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_2)},
71 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_3)},
72 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_4)},
73 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_1)},
74 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_2)},
75 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_CPT_1)},
76 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PBG_1)},
77 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)},
78 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)},
79 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)},
80 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT)},
81 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)},
82
83 /* required last entry */
84 {0, }
85};
86
87MODULE_DEVICE_TABLE(pci, mei_pci_tbl);
88 41
89static DEFINE_MUTEX(mei_mutex); 42#include "mei_dev.h"
90 43#include "hw-me.h"
91 44#include "client.h"
92/**
93 * find_read_list_entry - find read list entry
94 *
95 * @dev: device structure
96 * @file: pointer to file structure
97 *
98 * returns cb on success, NULL on error
99 */
100static struct mei_cl_cb *find_read_list_entry(
101 struct mei_device *dev,
102 struct mei_cl *cl)
103{
104 struct mei_cl_cb *pos = NULL;
105 struct mei_cl_cb *next = NULL;
106
107 dev_dbg(&dev->pdev->dev, "remove read_list CB\n");
108 list_for_each_entry_safe(pos, next, &dev->read_list.list, list)
109 if (mei_cl_cmp_id(cl, pos->cl))
110 return pos;
111 return NULL;
112}
113 45
114/** 46/**
115 * mei_open - the open function 47 * mei_open - the open function
@@ -121,16 +53,20 @@ static struct mei_cl_cb *find_read_list_entry(
121 */ 53 */
122static int mei_open(struct inode *inode, struct file *file) 54static int mei_open(struct inode *inode, struct file *file)
123{ 55{
56 struct miscdevice *misc = file->private_data;
57 struct pci_dev *pdev;
124 struct mei_cl *cl; 58 struct mei_cl *cl;
125 struct mei_device *dev; 59 struct mei_device *dev;
126 unsigned long cl_id; 60
127 int err; 61 int err;
128 62
129 err = -ENODEV; 63 err = -ENODEV;
130 if (!mei_pdev) 64 if (!misc->parent)
131 goto out; 65 goto out;
132 66
133 dev = pci_get_drvdata(mei_pdev); 67 pdev = container_of(misc->parent, struct pci_dev, dev);
68
69 dev = pci_get_drvdata(pdev);
134 if (!dev) 70 if (!dev)
135 goto out; 71 goto out;
136 72
@@ -153,24 +89,9 @@ static int mei_open(struct inode *inode, struct file *file)
153 goto out_unlock; 89 goto out_unlock;
154 } 90 }
155 91
156 cl_id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX); 92 err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY);
157 if (cl_id >= MEI_CLIENTS_MAX) { 93 if (err)
158 dev_err(&dev->pdev->dev, "client_id exceded %d",
159 MEI_CLIENTS_MAX) ;
160 goto out_unlock; 94 goto out_unlock;
161 }
162
163 cl->host_client_id = cl_id;
164
165 dev_dbg(&dev->pdev->dev, "client_id = %d\n", cl->host_client_id);
166
167 dev->open_handle_count++;
168
169 list_add_tail(&cl->link, &dev->file_list);
170
171 set_bit(cl->host_client_id, dev->host_clients_map);
172 cl->state = MEI_FILE_INITIALIZING;
173 cl->sm_state = 0;
174 95
175 file->private_data = cl; 96 file->private_data = cl;
176 mutex_unlock(&dev->device_lock); 97 mutex_unlock(&dev->device_lock);
@@ -216,7 +137,7 @@ static int mei_release(struct inode *inode, struct file *file)
216 "ME client = %d\n", 137 "ME client = %d\n",
217 cl->host_client_id, 138 cl->host_client_id,
218 cl->me_client_id); 139 cl->me_client_id);
219 rets = mei_disconnect_host_client(dev, cl); 140 rets = mei_cl_disconnect(cl);
220 } 141 }
221 mei_cl_flush_queues(cl); 142 mei_cl_flush_queues(cl);
222 dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n", 143 dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n",
@@ -227,12 +148,13 @@ static int mei_release(struct inode *inode, struct file *file)
227 clear_bit(cl->host_client_id, dev->host_clients_map); 148 clear_bit(cl->host_client_id, dev->host_clients_map);
228 dev->open_handle_count--; 149 dev->open_handle_count--;
229 } 150 }
230 mei_me_cl_unlink(dev, cl); 151 mei_cl_unlink(cl);
152
231 153
232 /* free read cb */ 154 /* free read cb */
233 cb = NULL; 155 cb = NULL;
234 if (cl->read_cb) { 156 if (cl->read_cb) {
235 cb = find_read_list_entry(dev, cl); 157 cb = mei_cl_find_read_cb(cl);
236 /* Remove entry from read list */ 158 /* Remove entry from read list */
237 if (cb) 159 if (cb)
238 list_del(&cb->list); 160 list_del(&cb->list);
@@ -322,7 +244,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
322 goto out; 244 goto out;
323 } 245 }
324 246
325 err = mei_start_read(dev, cl); 247 err = mei_cl_read_start(cl);
326 if (err && err != -EBUSY) { 248 if (err && err != -EBUSY) {
327 dev_dbg(&dev->pdev->dev, 249 dev_dbg(&dev->pdev->dev,
328 "mei start read failure with status = %d\n", err); 250 "mei start read failure with status = %d\n", err);
@@ -393,14 +315,13 @@ copy_buffer:
393 goto out; 315 goto out;
394 316
395free: 317free:
396 cb_pos = find_read_list_entry(dev, cl); 318 cb_pos = mei_cl_find_read_cb(cl);
397 /* Remove entry from read list */ 319 /* Remove entry from read list */
398 if (cb_pos) 320 if (cb_pos)
399 list_del(&cb_pos->list); 321 list_del(&cb_pos->list);
400 mei_io_cb_free(cb); 322 mei_io_cb_free(cb);
401 cl->reading_state = MEI_IDLE; 323 cl->reading_state = MEI_IDLE;
402 cl->read_cb = NULL; 324 cl->read_cb = NULL;
403 cl->read_pending = 0;
404out: 325out:
405 dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets); 326 dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets);
406 mutex_unlock(&dev->device_lock); 327 mutex_unlock(&dev->device_lock);
@@ -475,16 +396,15 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
475 /* free entry used in read */ 396 /* free entry used in read */
476 if (cl->reading_state == MEI_READ_COMPLETE) { 397 if (cl->reading_state == MEI_READ_COMPLETE) {
477 *offset = 0; 398 *offset = 0;
478 write_cb = find_read_list_entry(dev, cl); 399 write_cb = mei_cl_find_read_cb(cl);
479 if (write_cb) { 400 if (write_cb) {
480 list_del(&write_cb->list); 401 list_del(&write_cb->list);
481 mei_io_cb_free(write_cb); 402 mei_io_cb_free(write_cb);
482 write_cb = NULL; 403 write_cb = NULL;
483 cl->reading_state = MEI_IDLE; 404 cl->reading_state = MEI_IDLE;
484 cl->read_cb = NULL; 405 cl->read_cb = NULL;
485 cl->read_pending = 0;
486 } 406 }
487 } else if (cl->reading_state == MEI_IDLE && !cl->read_pending) 407 } else if (cl->reading_state == MEI_IDLE)
488 *offset = 0; 408 *offset = 0;
489 409
490 410
@@ -519,7 +439,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
519 439
520 if (rets) { 440 if (rets) {
521 dev_err(&dev->pdev->dev, 441 dev_err(&dev->pdev->dev,
522 "amthi write failed with status = %d\n", rets); 442 "amthif write failed with status = %d\n", rets);
523 goto err; 443 goto err;
524 } 444 }
525 mutex_unlock(&dev->device_lock); 445 mutex_unlock(&dev->device_lock);
@@ -530,20 +450,20 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
530 450
531 dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", 451 dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n",
532 cl->host_client_id, cl->me_client_id); 452 cl->host_client_id, cl->me_client_id);
533 rets = mei_flow_ctrl_creds(dev, cl); 453 rets = mei_cl_flow_ctrl_creds(cl);
534 if (rets < 0) 454 if (rets < 0)
535 goto err; 455 goto err;
536 456
537 if (rets == 0 || dev->mei_host_buffer_is_empty == false) { 457 if (rets == 0 || !dev->hbuf_is_ready) {
538 write_cb->buf_idx = 0; 458 write_cb->buf_idx = 0;
539 mei_hdr.msg_complete = 0; 459 mei_hdr.msg_complete = 0;
540 cl->writing_state = MEI_WRITING; 460 cl->writing_state = MEI_WRITING;
541 goto out; 461 goto out;
542 } 462 }
543 463
544 dev->mei_host_buffer_is_empty = false; 464 dev->hbuf_is_ready = false;
545 if (length > mei_hbuf_max_data(dev)) { 465 if (length > mei_hbuf_max_len(dev)) {
546 mei_hdr.length = mei_hbuf_max_data(dev); 466 mei_hdr.length = mei_hbuf_max_len(dev);
547 mei_hdr.msg_complete = 0; 467 mei_hdr.msg_complete = 0;
548 } else { 468 } else {
549 mei_hdr.length = length; 469 mei_hdr.length = length;
@@ -552,10 +472,10 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
552 mei_hdr.host_addr = cl->host_client_id; 472 mei_hdr.host_addr = cl->host_client_id;
553 mei_hdr.me_addr = cl->me_client_id; 473 mei_hdr.me_addr = cl->me_client_id;
554 mei_hdr.reserved = 0; 474 mei_hdr.reserved = 0;
555 dev_dbg(&dev->pdev->dev, "call mei_write_message header=%08x.\n", 475
556 *((u32 *) &mei_hdr)); 476 dev_dbg(&dev->pdev->dev, "write " MEI_HDR_FMT "\n",
557 if (mei_write_message(dev, &mei_hdr, 477 MEI_HDR_PRM(&mei_hdr));
558 write_cb->request_buffer.data, mei_hdr.length)) { 478 if (mei_write_message(dev, &mei_hdr, write_cb->request_buffer.data)) {
559 rets = -ENODEV; 479 rets = -ENODEV;
560 goto err; 480 goto err;
561 } 481 }
@@ -564,7 +484,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
564 484
565out: 485out:
566 if (mei_hdr.msg_complete) { 486 if (mei_hdr.msg_complete) {
567 if (mei_flow_ctrl_reduce(dev, cl)) { 487 if (mei_cl_flow_ctrl_reduce(cl)) {
568 rets = -ENODEV; 488 rets = -ENODEV;
569 goto err; 489 goto err;
570 } 490 }
@@ -582,6 +502,103 @@ err:
582 return rets; 502 return rets;
583} 503}
584 504
505/**
506 * mei_ioctl_connect_client - the connect to fw client IOCTL function
507 *
508 * @dev: the device structure
509 * @data: IOCTL connect data, input and output parameters
510 * @file: private data of the file object
511 *
512 * Locking: called under "dev->device_lock" lock
513 *
514 * returns 0 on success, <0 on failure.
515 */
516static int mei_ioctl_connect_client(struct file *file,
517 struct mei_connect_client_data *data)
518{
519 struct mei_device *dev;
520 struct mei_client *client;
521 struct mei_cl *cl;
522 int i;
523 int rets;
524
525 cl = file->private_data;
526 if (WARN_ON(!cl || !cl->dev))
527 return -ENODEV;
528
529 dev = cl->dev;
530
531 if (dev->dev_state != MEI_DEV_ENABLED) {
532 rets = -ENODEV;
533 goto end;
534 }
535
536 if (cl->state != MEI_FILE_INITIALIZING &&
537 cl->state != MEI_FILE_DISCONNECTED) {
538 rets = -EBUSY;
539 goto end;
540 }
541
542 /* find ME client we're trying to connect to */
543 i = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
544 if (i >= 0 && !dev->me_clients[i].props.fixed_address) {
545 cl->me_client_id = dev->me_clients[i].client_id;
546 cl->state = MEI_FILE_CONNECTING;
547 }
548
549 dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n",
550 cl->me_client_id);
551 dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n",
552 dev->me_clients[i].props.protocol_version);
553 dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n",
554 dev->me_clients[i].props.max_msg_length);
555
556 /* if we're connecting to amthif client then we will use the
557 * existing connection
558 */
559 if (uuid_le_cmp(data->in_client_uuid, mei_amthif_guid) == 0) {
560 dev_dbg(&dev->pdev->dev, "FW Client is amthi\n");
561 if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) {
562 rets = -ENODEV;
563 goto end;
564 }
565 clear_bit(cl->host_client_id, dev->host_clients_map);
566 mei_cl_unlink(cl);
567
568 kfree(cl);
569 cl = NULL;
570 file->private_data = &dev->iamthif_cl;
571
572 client = &data->out_client_properties;
573 client->max_msg_length =
574 dev->me_clients[i].props.max_msg_length;
575 client->protocol_version =
576 dev->me_clients[i].props.protocol_version;
577 rets = dev->iamthif_cl.status;
578
579 goto end;
580 }
581
582 if (cl->state != MEI_FILE_CONNECTING) {
583 rets = -ENODEV;
584 goto end;
585 }
586
587
588 /* prepare the output buffer */
589 client = &data->out_client_properties;
590 client->max_msg_length = dev->me_clients[i].props.max_msg_length;
591 client->protocol_version = dev->me_clients[i].props.protocol_version;
592 dev_dbg(&dev->pdev->dev, "Can connect?\n");
593
594
595 rets = mei_cl_connect(cl, file);
596
597end:
598 dev_dbg(&dev->pdev->dev, "free connect cb memory.");
599 return rets;
600}
601
585 602
586/** 603/**
587 * mei_ioctl - the IOCTL function 604 * mei_ioctl - the IOCTL function
@@ -630,6 +647,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
630 rets = -EFAULT; 647 rets = -EFAULT;
631 goto out; 648 goto out;
632 } 649 }
650
633 rets = mei_ioctl_connect_client(file, connect_data); 651 rets = mei_ioctl_connect_client(file, connect_data);
634 652
635 /* if all is ok, copying the data back to user. */ 653 /* if all is ok, copying the data back to user. */
@@ -726,7 +744,6 @@ static const struct file_operations mei_fops = {
726 .llseek = no_llseek 744 .llseek = no_llseek
727}; 745};
728 746
729
730/* 747/*
731 * Misc Device Struct 748 * Misc Device Struct
732 */ 749 */
@@ -736,300 +753,17 @@ static struct miscdevice mei_misc_device = {
736 .minor = MISC_DYNAMIC_MINOR, 753 .minor = MISC_DYNAMIC_MINOR,
737}; 754};
738 755
739/** 756int mei_register(struct device *dev)
740 * mei_quirk_probe - probe for devices that doesn't valid ME interface
741 * @pdev: PCI device structure
742 * @ent: entry into pci_device_table
743 *
744 * returns true if ME Interface is valid, false otherwise
745 */
746static bool mei_quirk_probe(struct pci_dev *pdev,
747 const struct pci_device_id *ent)
748{ 757{
749 u32 reg; 758 mei_misc_device.parent = dev;
750 if (ent->device == MEI_DEV_ID_PBG_1) { 759 return misc_register(&mei_misc_device);
751 pci_read_config_dword(pdev, 0x48, &reg);
752 /* make sure that bit 9 is up and bit 10 is down */
753 if ((reg & 0x600) == 0x200) {
754 dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
755 return false;
756 }
757 }
758 return true;
759}
760/**
761 * mei_probe - Device Initialization Routine
762 *
763 * @pdev: PCI device structure
764 * @ent: entry in kcs_pci_tbl
765 *
766 * returns 0 on success, <0 on failure.
767 */
768static int mei_probe(struct pci_dev *pdev,
769 const struct pci_device_id *ent)
770{
771 struct mei_device *dev;
772 int err;
773
774 mutex_lock(&mei_mutex);
775
776 if (!mei_quirk_probe(pdev, ent)) {
777 err = -ENODEV;
778 goto end;
779 }
780
781 if (mei_pdev) {
782 err = -EEXIST;
783 goto end;
784 }
785 /* enable pci dev */
786 err = pci_enable_device(pdev);
787 if (err) {
788 dev_err(&pdev->dev, "failed to enable pci device.\n");
789 goto end;
790 }
791 /* set PCI host mastering */
792 pci_set_master(pdev);
793 /* pci request regions for mei driver */
794 err = pci_request_regions(pdev, KBUILD_MODNAME);
795 if (err) {
796 dev_err(&pdev->dev, "failed to get pci regions.\n");
797 goto disable_device;
798 }
799 /* allocates and initializes the mei dev structure */
800 dev = mei_device_init(pdev);
801 if (!dev) {
802 err = -ENOMEM;
803 goto release_regions;
804 }
805 /* mapping IO device memory */
806 dev->mem_addr = pci_iomap(pdev, 0, 0);
807 if (!dev->mem_addr) {
808 dev_err(&pdev->dev, "mapping I/O device memory failure.\n");
809 err = -ENOMEM;
810 goto free_device;
811 }
812 pci_enable_msi(pdev);
813
814 /* request and enable interrupt */
815 if (pci_dev_msi_enabled(pdev))
816 err = request_threaded_irq(pdev->irq,
817 NULL,
818 mei_interrupt_thread_handler,
819 IRQF_ONESHOT, KBUILD_MODNAME, dev);
820 else
821 err = request_threaded_irq(pdev->irq,
822 mei_interrupt_quick_handler,
823 mei_interrupt_thread_handler,
824 IRQF_SHARED, KBUILD_MODNAME, dev);
825
826 if (err) {
827 dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n",
828 pdev->irq);
829 goto disable_msi;
830 }
831 INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
832 INIT_WORK(&dev->init_work, mei_host_client_init);
833
834 if (mei_hw_init(dev)) {
835 dev_err(&pdev->dev, "init hw failure.\n");
836 err = -ENODEV;
837 goto release_irq;
838 }
839
840 err = misc_register(&mei_misc_device);
841 if (err)
842 goto release_irq;
843
844 mei_pdev = pdev;
845 pci_set_drvdata(pdev, dev);
846
847
848 schedule_delayed_work(&dev->timer_work, HZ);
849
850 mutex_unlock(&mei_mutex);
851
852 pr_debug("initialization successful.\n");
853
854 return 0;
855
856release_irq:
857 /* disable interrupts */
858 dev->host_hw_state = mei_hcsr_read(dev);
859 mei_disable_interrupts(dev);
860 flush_scheduled_work();
861 free_irq(pdev->irq, dev);
862disable_msi:
863 pci_disable_msi(pdev);
864 pci_iounmap(pdev, dev->mem_addr);
865free_device:
866 kfree(dev);
867release_regions:
868 pci_release_regions(pdev);
869disable_device:
870 pci_disable_device(pdev);
871end:
872 mutex_unlock(&mei_mutex);
873 dev_err(&pdev->dev, "initialization failed.\n");
874 return err;
875} 760}
876 761
877/** 762void mei_deregister(void)
878 * mei_remove - Device Removal Routine
879 *
880 * @pdev: PCI device structure
881 *
882 * mei_remove is called by the PCI subsystem to alert the driver
883 * that it should release a PCI device.
884 */
885static void mei_remove(struct pci_dev *pdev)
886{ 763{
887 struct mei_device *dev;
888
889 if (mei_pdev != pdev)
890 return;
891
892 dev = pci_get_drvdata(pdev);
893 if (!dev)
894 return;
895
896 mutex_lock(&dev->device_lock);
897
898 cancel_delayed_work(&dev->timer_work);
899
900 mei_wd_stop(dev);
901
902 mei_pdev = NULL;
903
904 if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) {
905 dev->iamthif_cl.state = MEI_FILE_DISCONNECTING;
906 mei_disconnect_host_client(dev, &dev->iamthif_cl);
907 }
908 if (dev->wd_cl.state == MEI_FILE_CONNECTED) {
909 dev->wd_cl.state = MEI_FILE_DISCONNECTING;
910 mei_disconnect_host_client(dev, &dev->wd_cl);
911 }
912
913 /* Unregistering watchdog device */
914 mei_watchdog_unregister(dev);
915
916 /* remove entry if already in list */
917 dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
918 mei_me_cl_unlink(dev, &dev->wd_cl);
919 mei_me_cl_unlink(dev, &dev->iamthif_cl);
920
921 dev->iamthif_current_cb = NULL;
922 dev->me_clients_num = 0;
923
924 mutex_unlock(&dev->device_lock);
925
926 flush_scheduled_work();
927
928 /* disable interrupts */
929 mei_disable_interrupts(dev);
930
931 free_irq(pdev->irq, dev);
932 pci_disable_msi(pdev);
933 pci_set_drvdata(pdev, NULL);
934
935 if (dev->mem_addr)
936 pci_iounmap(pdev, dev->mem_addr);
937
938 kfree(dev);
939
940 pci_release_regions(pdev);
941 pci_disable_device(pdev);
942
943 misc_deregister(&mei_misc_device); 764 misc_deregister(&mei_misc_device);
944} 765 mei_misc_device.parent = NULL;
945#ifdef CONFIG_PM
946static int mei_pci_suspend(struct device *device)
947{
948 struct pci_dev *pdev = to_pci_dev(device);
949 struct mei_device *dev = pci_get_drvdata(pdev);
950 int err;
951
952 if (!dev)
953 return -ENODEV;
954 mutex_lock(&dev->device_lock);
955
956 cancel_delayed_work(&dev->timer_work);
957
958 /* Stop watchdog if exists */
959 err = mei_wd_stop(dev);
960 /* Set new mei state */
961 if (dev->dev_state == MEI_DEV_ENABLED ||
962 dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
963 dev->dev_state = MEI_DEV_POWER_DOWN;
964 mei_reset(dev, 0);
965 }
966 mutex_unlock(&dev->device_lock);
967
968 free_irq(pdev->irq, dev);
969 pci_disable_msi(pdev);
970
971 return err;
972} 766}
973 767
974static int mei_pci_resume(struct device *device)
975{
976 struct pci_dev *pdev = to_pci_dev(device);
977 struct mei_device *dev;
978 int err;
979
980 dev = pci_get_drvdata(pdev);
981 if (!dev)
982 return -ENODEV;
983
984 pci_enable_msi(pdev);
985
986 /* request and enable interrupt */
987 if (pci_dev_msi_enabled(pdev))
988 err = request_threaded_irq(pdev->irq,
989 NULL,
990 mei_interrupt_thread_handler,
991 IRQF_ONESHOT, KBUILD_MODNAME, dev);
992 else
993 err = request_threaded_irq(pdev->irq,
994 mei_interrupt_quick_handler,
995 mei_interrupt_thread_handler,
996 IRQF_SHARED, KBUILD_MODNAME, dev);
997
998 if (err) {
999 dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n",
1000 pdev->irq);
1001 return err;
1002 }
1003
1004 mutex_lock(&dev->device_lock);
1005 dev->dev_state = MEI_DEV_POWER_UP;
1006 mei_reset(dev, 1);
1007 mutex_unlock(&dev->device_lock);
1008
1009 /* Start timer if stopped in suspend */
1010 schedule_delayed_work(&dev->timer_work, HZ);
1011
1012 return err;
1013}
1014static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume);
1015#define MEI_PM_OPS (&mei_pm_ops)
1016#else
1017#define MEI_PM_OPS NULL
1018#endif /* CONFIG_PM */
1019/*
1020 * PCI driver structure
1021 */
1022static struct pci_driver mei_driver = {
1023 .name = KBUILD_MODNAME,
1024 .id_table = mei_pci_tbl,
1025 .probe = mei_probe,
1026 .remove = mei_remove,
1027 .shutdown = mei_remove,
1028 .driver.pm = MEI_PM_OPS,
1029};
1030
1031module_pci_driver(mei_driver);
1032
1033MODULE_AUTHOR("Intel Corporation");
1034MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
1035MODULE_LICENSE("GPL v2"); 768MODULE_LICENSE("GPL v2");
769
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 25da04549d04..cb80166161f0 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -21,7 +21,9 @@
21#include <linux/watchdog.h> 21#include <linux/watchdog.h>
22#include <linux/poll.h> 22#include <linux/poll.h>
23#include <linux/mei.h> 23#include <linux/mei.h>
24
24#include "hw.h" 25#include "hw.h"
26#include "hw-me-regs.h"
25 27
26/* 28/*
27 * watch dog definition 29 * watch dog definition
@@ -44,7 +46,7 @@
44/* 46/*
45 * AMTHI Client UUID 47 * AMTHI Client UUID
46 */ 48 */
47extern const uuid_le mei_amthi_guid; 49extern const uuid_le mei_amthif_guid;
48 50
49/* 51/*
50 * Watchdog Client UUID 52 * Watchdog Client UUID
@@ -65,12 +67,18 @@ extern const u8 mei_wd_state_independence_msg[3][4];
65 * Number of File descriptors/handles 67 * Number of File descriptors/handles
66 * that can be opened to the driver. 68 * that can be opened to the driver.
67 * 69 *
68 * Limit to 253: 256 Total Clients 70 * Limit to 255: 256 Total Clients
69 * minus internal client for MEI Bus Messags 71 * minus internal client for MEI Bus Messags
70 * minus internal client for AMTHI
71 * minus internal client for Watchdog
72 */ 72 */
73#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 3) 73#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1)
74
75/*
76 * Internal Clients Number
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
81#define MEI_IAMTHIF_HOST_CLIENT_ID 2
74 82
75 83
76/* File state */ 84/* File state */
@@ -150,6 +158,19 @@ struct mei_message_data {
150 unsigned char *data; 158 unsigned char *data;
151}; 159};
152 160
161/**
162 * struct mei_me_client - representation of me (fw) client
163 *
164 * @props - client properties
165 * @client_id - me client id
166 * @mei_flow_ctrl_creds - flow control credits
167 */
168struct mei_me_client {
169 struct mei_client_properties props;
170 u8 client_id;
171 u8 mei_flow_ctrl_creds;
172};
173
153 174
154struct mei_cl; 175struct mei_cl;
155 176
@@ -178,7 +199,6 @@ struct mei_cl {
178 wait_queue_head_t tx_wait; 199 wait_queue_head_t tx_wait;
179 wait_queue_head_t rx_wait; 200 wait_queue_head_t rx_wait;
180 wait_queue_head_t wait; 201 wait_queue_head_t wait;
181 int read_pending;
182 int status; 202 int status;
183 /* ID of client connected */ 203 /* ID of client connected */
184 u8 host_client_id; 204 u8 host_client_id;
@@ -191,10 +211,67 @@ struct mei_cl {
191 struct mei_cl_cb *read_cb; 211 struct mei_cl_cb *read_cb;
192}; 212};
193 213
214/** struct mei_hw_ops
215 *
216 * @host_set_ready - notify FW that host side is ready
217 * @host_is_ready - query for host readiness
218
219 * @hw_is_ready - query if hw is ready
220 * @hw_reset - reset hw
221 * @hw_config - configure hw
222
223 * @intr_clear - clear pending interrupts
224 * @intr_enable - enable interrupts
225 * @intr_disable - disable interrupts
226
227 * @hbuf_free_slots - query for write buffer empty slots
228 * @hbuf_is_ready - query if write buffer is empty
229 * @hbuf_max_len - query for write buffer max len
230
231 * @write - write a message to FW
232
233 * @rdbuf_full_slots - query how many slots are filled
234
235 * @read_hdr - get first 4 bytes (header)
236 * @read - read a buffer from the FW
237 */
238struct mei_hw_ops {
239
240 void (*host_set_ready) (struct mei_device *dev);
241 bool (*host_is_ready) (struct mei_device *dev);
242
243 bool (*hw_is_ready) (struct mei_device *dev);
244 void (*hw_reset) (struct mei_device *dev, bool enable);
245 void (*hw_config) (struct mei_device *dev);
246
247 void (*intr_clear) (struct mei_device *dev);
248 void (*intr_enable) (struct mei_device *dev);
249 void (*intr_disable) (struct mei_device *dev);
250
251 int (*hbuf_free_slots) (struct mei_device *dev);
252 bool (*hbuf_is_ready) (struct mei_device *dev);
253 size_t (*hbuf_max_len) (const struct mei_device *dev);
254
255 int (*write)(struct mei_device *dev,
256 struct mei_msg_hdr *hdr,
257 unsigned char *buf);
258
259 int (*rdbuf_full_slots)(struct mei_device *dev);
260
261 u32 (*read_hdr)(const struct mei_device *dev);
262 int (*read) (struct mei_device *dev,
263 unsigned char *buf, unsigned long len);
264};
265
194/** 266/**
195 * struct mei_device - MEI private device struct 267 * struct mei_device - MEI private device struct
196 * @hbuf_depth - depth of host(write) buffer 268
197 * @wr_ext_msg - buffer for hbm control responses (set in read cycle) 269 * @mem_addr - mem mapped base register address
270
271 * @hbuf_depth - depth of hardware host/write buffer is slots
272 * @hbuf_is_ready - query if the host host/write buffer is ready
273 * @wr_msg - the buffer for hbm control messages
274 * @wr_ext_msg - the buffer for hbm control responses (set in read cycle)
198 */ 275 */
199struct mei_device { 276struct mei_device {
200 struct pci_dev *pdev; /* pointer to pci device struct */ 277 struct pci_dev *pdev; /* pointer to pci device struct */
@@ -213,24 +290,14 @@ struct mei_device {
213 */ 290 */
214 struct list_head file_list; 291 struct list_head file_list;
215 long open_handle_count; 292 long open_handle_count;
216 /* 293
217 * memory of device
218 */
219 unsigned int mem_base;
220 unsigned int mem_length;
221 void __iomem *mem_addr;
222 /* 294 /*
223 * lock for the device 295 * lock for the device
224 */ 296 */
225 struct mutex device_lock; /* device lock */ 297 struct mutex device_lock; /* device lock */
226 struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */ 298 struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */
227 bool recvd_msg; 299 bool recvd_msg;
228 /* 300
229 * hw states of host and fw(ME)
230 */
231 u32 host_hw_state;
232 u32 me_hw_state;
233 u8 hbuf_depth;
234 /* 301 /*
235 * waiting queue for receive message from FW 302 * waiting queue for receive message from FW
236 */ 303 */
@@ -243,11 +310,20 @@ struct mei_device {
243 enum mei_dev_state dev_state; 310 enum mei_dev_state dev_state;
244 enum mei_init_clients_states init_clients_state; 311 enum mei_init_clients_states init_clients_state;
245 u16 init_clients_timer; 312 u16 init_clients_timer;
246 bool need_reset;
247 313
248 unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ 314 unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */
249 u32 rd_msg_hdr; 315 u32 rd_msg_hdr;
250 u32 wr_msg_buf[128]; /* used for control messages */ 316
317 /* write buffer */
318 u8 hbuf_depth;
319 bool hbuf_is_ready;
320
321 /* used for control messages */
322 struct {
323 struct mei_msg_hdr hdr;
324 unsigned char data[128];
325 } wr_msg;
326
251 struct { 327 struct {
252 struct mei_msg_hdr hdr; 328 struct mei_msg_hdr hdr;
253 unsigned char data[4]; /* All HBM messages are 4 bytes */ 329 unsigned char data[4]; /* All HBM messages are 4 bytes */
@@ -261,7 +337,6 @@ struct mei_device {
261 u8 me_clients_num; 337 u8 me_clients_num;
262 u8 me_client_presentation_num; 338 u8 me_client_presentation_num;
263 u8 me_client_index; 339 u8 me_client_index;
264 bool mei_host_buffer_is_empty;
265 340
266 struct mei_cl wd_cl; 341 struct mei_cl wd_cl;
267 enum mei_wd_states wd_state; 342 enum mei_wd_states wd_state;
@@ -289,6 +364,9 @@ struct mei_device {
289 bool iamthif_canceled; 364 bool iamthif_canceled;
290 365
291 struct work_struct init_work; 366 struct work_struct init_work;
367
368 const struct mei_hw_ops *ops;
369 char hw[0] __aligned(sizeof(void *));
292}; 370};
293 371
294static inline unsigned long mei_secs_to_jiffies(unsigned long sec) 372static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
@@ -300,96 +378,28 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
300/* 378/*
301 * mei init function prototypes 379 * mei init function prototypes
302 */ 380 */
303struct mei_device *mei_device_init(struct pci_dev *pdev); 381void mei_device_init(struct mei_device *dev);
304void mei_reset(struct mei_device *dev, int interrupts); 382void mei_reset(struct mei_device *dev, int interrupts);
305int mei_hw_init(struct mei_device *dev); 383int mei_hw_init(struct mei_device *dev);
306int mei_task_initialize_clients(void *data);
307int mei_initialize_clients(struct mei_device *dev);
308int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl);
309void mei_allocate_me_clients_storage(struct mei_device *dev);
310
311
312int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl,
313 const uuid_le *cguid, u8 host_client_id);
314void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl);
315int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid);
316int mei_me_cl_by_id(struct mei_device *dev, u8 client_id);
317
318/*
319 * MEI IO Functions
320 */
321struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp);
322void mei_io_cb_free(struct mei_cl_cb *priv_cb);
323int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length);
324int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length);
325
326
327/**
328 * mei_io_list_init - Sets up a queue list.
329 *
330 * @list: An instance cl callback structure
331 */
332static inline void mei_io_list_init(struct mei_cl_cb *list)
333{
334 INIT_LIST_HEAD(&list->list);
335}
336void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl);
337
338/*
339 * MEI ME Client Functions
340 */
341
342struct mei_cl *mei_cl_allocate(struct mei_device *dev);
343void mei_cl_init(struct mei_cl *cl, struct mei_device *dev);
344int mei_cl_flush_queues(struct mei_cl *cl);
345/**
346 * mei_cl_cmp_id - tells if file private data have same id
347 *
348 * @fe1: private data of 1. file object
349 * @fe2: private data of 2. file object
350 *
351 * returns true - if ids are the same and not NULL
352 */
353static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
354 const struct mei_cl *cl2)
355{
356 return cl1 && cl2 &&
357 (cl1->host_client_id == cl2->host_client_id) &&
358 (cl1->me_client_id == cl2->me_client_id);
359}
360
361
362
363/*
364 * MEI Host Client Functions
365 */
366void mei_host_start_message(struct mei_device *dev);
367void mei_host_enum_clients_message(struct mei_device *dev);
368int mei_host_client_enumerate(struct mei_device *dev);
369void mei_host_client_init(struct work_struct *work);
370 384
371/* 385/*
372 * MEI interrupt functions prototype 386 * MEI interrupt functions prototype
373 */ 387 */
374irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id);
375irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id);
376void mei_timer(struct work_struct *work);
377 388
378/* 389void mei_timer(struct work_struct *work);
379 * MEI input output function prototype 390int mei_irq_read_handler(struct mei_device *dev,
380 */ 391 struct mei_cl_cb *cmpl_list, s32 *slots);
381int mei_ioctl_connect_client(struct file *file,
382 struct mei_connect_client_data *data);
383 392
384int mei_start_read(struct mei_device *dev, struct mei_cl *cl); 393int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list);
385 394
395void mei_irq_complete_handler(struct mei_cl *cl, struct mei_cl_cb *cb_pos);
386 396
387/* 397/*
388 * AMTHIF - AMT Host Interface Functions 398 * AMTHIF - AMT Host Interface Functions
389 */ 399 */
390void mei_amthif_reset_params(struct mei_device *dev); 400void mei_amthif_reset_params(struct mei_device *dev);
391 401
392void mei_amthif_host_init(struct mei_device *dev); 402int mei_amthif_host_init(struct mei_device *dev);
393 403
394int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb); 404int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb);
395 405
@@ -407,9 +417,6 @@ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
407void mei_amthif_run_next_cmd(struct mei_device *dev); 417void mei_amthif_run_next_cmd(struct mei_device *dev);
408 418
409 419
410int mei_amthif_read_message(struct mei_cl_cb *complete_list,
411 struct mei_device *dev, struct mei_msg_hdr *mei_hdr);
412
413int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, 420int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
414 struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list); 421 struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list);
415 422
@@ -418,92 +425,107 @@ int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
418 struct mei_device *dev, struct mei_msg_hdr *mei_hdr); 425 struct mei_device *dev, struct mei_msg_hdr *mei_hdr);
419int mei_amthif_irq_read(struct mei_device *dev, s32 *slots); 426int mei_amthif_irq_read(struct mei_device *dev, s32 *slots);
420 427
428
429int mei_wd_send(struct mei_device *dev);
430int mei_wd_stop(struct mei_device *dev);
431int mei_wd_host_init(struct mei_device *dev);
421/* 432/*
422 * Register Access Function 433 * mei_watchdog_register - Registering watchdog interface
434 * once we got connection to the WD Client
435 * @dev - mei device
436 */
437void mei_watchdog_register(struct mei_device *dev);
438/*
439 * mei_watchdog_unregister - Unregistering watchdog interface
440 * @dev - mei device
423 */ 441 */
442void mei_watchdog_unregister(struct mei_device *dev);
424 443
425/** 444/*
426 * mei_reg_read - Reads 32bit data from the mei device 445 * Register Access Function
427 *
428 * @dev: the device structure
429 * @offset: offset from which to read the data
430 *
431 * returns register value (u32)
432 */ 446 */
433static inline u32 mei_reg_read(const struct mei_device *dev, 447
434 unsigned long offset) 448static inline void mei_hw_config(struct mei_device *dev)
449{
450 dev->ops->hw_config(dev);
451}
452static inline void mei_hw_reset(struct mei_device *dev, bool enable)
435{ 453{
436 return ioread32(dev->mem_addr + offset); 454 dev->ops->hw_reset(dev, enable);
437} 455}
438 456
439/** 457static inline void mei_clear_interrupts(struct mei_device *dev)
440 * mei_reg_write - Writes 32bit data to the mei device
441 *
442 * @dev: the device structure
443 * @offset: offset from which to write the data
444 * @value: register value to write (u32)
445 */
446static inline void mei_reg_write(const struct mei_device *dev,
447 unsigned long offset, u32 value)
448{ 458{
449 iowrite32(value, dev->mem_addr + offset); 459 dev->ops->intr_clear(dev);
450} 460}
451 461
452/** 462static inline void mei_enable_interrupts(struct mei_device *dev)
453 * mei_hcsr_read - Reads 32bit data from the host CSR
454 *
455 * @dev: the device structure
456 *
457 * returns the byte read.
458 */
459static inline u32 mei_hcsr_read(const struct mei_device *dev)
460{ 463{
461 return mei_reg_read(dev, H_CSR); 464 dev->ops->intr_enable(dev);
462} 465}
463 466
464/** 467static inline void mei_disable_interrupts(struct mei_device *dev)
465 * mei_mecsr_read - Reads 32bit data from the ME CSR
466 *
467 * @dev: the device structure
468 *
469 * returns ME_CSR_HA register value (u32)
470 */
471static inline u32 mei_mecsr_read(const struct mei_device *dev)
472{ 468{
473 return mei_reg_read(dev, ME_CSR_HA); 469 dev->ops->intr_disable(dev);
474} 470}
475 471
476/** 472static inline void mei_host_set_ready(struct mei_device *dev)
477 * get_me_cb_rw - Reads 32bit data from the mei ME_CB_RW register
478 *
479 * @dev: the device structure
480 *
481 * returns ME_CB_RW register value (u32)
482 */
483static inline u32 mei_mecbrw_read(const struct mei_device *dev)
484{ 473{
485 return mei_reg_read(dev, ME_CB_RW); 474 dev->ops->host_set_ready(dev);
475}
476static inline bool mei_host_is_ready(struct mei_device *dev)
477{
478 return dev->ops->host_is_ready(dev);
479}
480static inline bool mei_hw_is_ready(struct mei_device *dev)
481{
482 return dev->ops->hw_is_ready(dev);
486} 483}
487 484
485static inline bool mei_hbuf_is_ready(struct mei_device *dev)
486{
487 return dev->ops->hbuf_is_ready(dev);
488}
488 489
489/* 490static inline int mei_hbuf_empty_slots(struct mei_device *dev)
490 * mei interface function prototypes 491{
491 */ 492 return dev->ops->hbuf_free_slots(dev);
492void mei_hcsr_set(struct mei_device *dev); 493}
493void mei_csr_clear_his(struct mei_device *dev); 494
495static inline size_t mei_hbuf_max_len(const struct mei_device *dev)
496{
497 return dev->ops->hbuf_max_len(dev);
498}
494 499
495void mei_enable_interrupts(struct mei_device *dev); 500static inline int mei_write_message(struct mei_device *dev,
496void mei_disable_interrupts(struct mei_device *dev); 501 struct mei_msg_hdr *hdr,
502 unsigned char *buf)
503{
504 return dev->ops->write(dev, hdr, buf);
505}
497 506
498static inline struct mei_msg_hdr *mei_hbm_hdr(u32 *buf, size_t length) 507static inline u32 mei_read_hdr(const struct mei_device *dev)
499{ 508{
500 struct mei_msg_hdr *hdr = (struct mei_msg_hdr *)buf; 509 return dev->ops->read_hdr(dev);
501 hdr->host_addr = 0;
502 hdr->me_addr = 0;
503 hdr->length = length;
504 hdr->msg_complete = 1;
505 hdr->reserved = 0;
506 return hdr;
507} 510}
508 511
512static inline void mei_read_slots(struct mei_device *dev,
513 unsigned char *buf, unsigned long len)
514{
515 dev->ops->read(dev, buf, len);
516}
517
518static inline int mei_count_full_read_slots(struct mei_device *dev)
519{
520 return dev->ops->rdbuf_full_slots(dev);
521}
522
523int mei_register(struct device *dev);
524void mei_deregister(void);
525
526#define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d comp=%1d"
527#define MEI_HDR_PRM(hdr) \
528 (hdr)->host_addr, (hdr)->me_addr, \
529 (hdr)->length, (hdr)->msg_complete
530
509#endif 531#endif
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
new file mode 100644
index 000000000000..b40ec0601ab0
--- /dev/null
+++ b/drivers/misc/mei/pci-me.c
@@ -0,0 +1,396 @@
1/*
2 *
3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 */
16
17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/kernel.h>
22#include <linux/device.h>
23#include <linux/fs.h>
24#include <linux/errno.h>
25#include <linux/types.h>
26#include <linux/fcntl.h>
27#include <linux/aio.h>
28#include <linux/pci.h>
29#include <linux/poll.h>
30#include <linux/init.h>
31#include <linux/ioctl.h>
32#include <linux/cdev.h>
33#include <linux/sched.h>
34#include <linux/uuid.h>
35#include <linux/compat.h>
36#include <linux/jiffies.h>
37#include <linux/interrupt.h>
38#include <linux/miscdevice.h>
39
40#include <linux/mei.h>
41
42#include "mei_dev.h"
43#include "hw-me.h"
44#include "client.h"
45
46/* AMT device is a singleton on the platform */
47static struct pci_dev *mei_pdev;
48
49/* mei_pci_tbl - PCI Device ID Table */
50static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = {
51 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)},
52 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)},
53 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)},
54 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G965)},
55 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GM965)},
56 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GME965)},
57 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q35)},
58 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82G33)},
59 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q33)},
60 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82X38)},
61 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_3200)},
62 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_6)},
63 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_7)},
64 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_8)},
65 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_9)},
66 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_10)},
67 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_1)},
68 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_2)},
69 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_3)},
70 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_4)},
71 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_1)},
72 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_2)},
73 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_3)},
74 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_4)},
75 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_1)},
76 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_2)},
77 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_CPT_1)},
78 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PBG_1)},
79 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)},
80 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)},
81 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)},
82 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT)},
83 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)},
84
85 /* required last entry */
86 {0, }
87};
88
89MODULE_DEVICE_TABLE(pci, mei_pci_tbl);
90
91static DEFINE_MUTEX(mei_mutex);
92
93/**
94 * mei_quirk_probe - probe for devices that doesn't valid ME interface
95 * @pdev: PCI device structure
96 * @ent: entry into pci_device_table
97 *
98 * returns true if ME Interface is valid, false otherwise
99 */
100static bool mei_quirk_probe(struct pci_dev *pdev,
101 const struct pci_device_id *ent)
102{
103 u32 reg;
104 if (ent->device == MEI_DEV_ID_PBG_1) {
105 pci_read_config_dword(pdev, 0x48, &reg);
106 /* make sure that bit 9 is up and bit 10 is down */
107 if ((reg & 0x600) == 0x200) {
108 dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
109 return false;
110 }
111 }
112 return true;
113}
114/**
115 * mei_probe - Device Initialization Routine
116 *
117 * @pdev: PCI device structure
118 * @ent: entry in kcs_pci_tbl
119 *
120 * returns 0 on success, <0 on failure.
121 */
122static int mei_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
123{
124 struct mei_device *dev;
125 struct mei_me_hw *hw;
126 int err;
127
128 mutex_lock(&mei_mutex);
129
130 if (!mei_quirk_probe(pdev, ent)) {
131 err = -ENODEV;
132 goto end;
133 }
134
135 if (mei_pdev) {
136 err = -EEXIST;
137 goto end;
138 }
139 /* enable pci dev */
140 err = pci_enable_device(pdev);
141 if (err) {
142 dev_err(&pdev->dev, "failed to enable pci device.\n");
143 goto end;
144 }
145 /* set PCI host mastering */
146 pci_set_master(pdev);
147 /* pci request regions for mei driver */
148 err = pci_request_regions(pdev, KBUILD_MODNAME);
149 if (err) {
150 dev_err(&pdev->dev, "failed to get pci regions.\n");
151 goto disable_device;
152 }
153 /* allocates and initializes the mei dev structure */
154 dev = mei_me_dev_init(pdev);
155 if (!dev) {
156 err = -ENOMEM;
157 goto release_regions;
158 }
159 hw = to_me_hw(dev);
160 /* mapping IO device memory */
161 hw->mem_addr = pci_iomap(pdev, 0, 0);
162 if (!hw->mem_addr) {
163 dev_err(&pdev->dev, "mapping I/O device memory failure.\n");
164 err = -ENOMEM;
165 goto free_device;
166 }
167 pci_enable_msi(pdev);
168
169 /* request and enable interrupt */
170 if (pci_dev_msi_enabled(pdev))
171 err = request_threaded_irq(pdev->irq,
172 NULL,
173 mei_me_irq_thread_handler,
174 IRQF_ONESHOT, KBUILD_MODNAME, dev);
175 else
176 err = request_threaded_irq(pdev->irq,
177 mei_me_irq_quick_handler,
178 mei_me_irq_thread_handler,
179 IRQF_SHARED, KBUILD_MODNAME, dev);
180
181 if (err) {
182 dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n",
183 pdev->irq);
184 goto disable_msi;
185 }
186
187 if (mei_hw_init(dev)) {
188 dev_err(&pdev->dev, "init hw failure.\n");
189 err = -ENODEV;
190 goto release_irq;
191 }
192
193 err = mei_register(&pdev->dev);
194 if (err)
195 goto release_irq;
196
197 mei_pdev = pdev;
198 pci_set_drvdata(pdev, dev);
199
200
201 schedule_delayed_work(&dev->timer_work, HZ);
202
203 mutex_unlock(&mei_mutex);
204
205 pr_debug("initialization successful.\n");
206
207 return 0;
208
209release_irq:
210 mei_disable_interrupts(dev);
211 flush_scheduled_work();
212 free_irq(pdev->irq, dev);
213disable_msi:
214 pci_disable_msi(pdev);
215 pci_iounmap(pdev, hw->mem_addr);
216free_device:
217 kfree(dev);
218release_regions:
219 pci_release_regions(pdev);
220disable_device:
221 pci_disable_device(pdev);
222end:
223 mutex_unlock(&mei_mutex);
224 dev_err(&pdev->dev, "initialization failed.\n");
225 return err;
226}
227
228/**
229 * mei_remove - Device Removal Routine
230 *
231 * @pdev: PCI device structure
232 *
233 * mei_remove is called by the PCI subsystem to alert the driver
234 * that it should release a PCI device.
235 */
236static void mei_remove(struct pci_dev *pdev)
237{
238 struct mei_device *dev;
239 struct mei_me_hw *hw;
240
241 if (mei_pdev != pdev)
242 return;
243
244 dev = pci_get_drvdata(pdev);
245 if (!dev)
246 return;
247
248 hw = to_me_hw(dev);
249
250 mutex_lock(&dev->device_lock);
251
252 cancel_delayed_work(&dev->timer_work);
253
254 mei_wd_stop(dev);
255
256 mei_pdev = NULL;
257
258 if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) {
259 dev->iamthif_cl.state = MEI_FILE_DISCONNECTING;
260 mei_cl_disconnect(&dev->iamthif_cl);
261 }
262 if (dev->wd_cl.state == MEI_FILE_CONNECTED) {
263 dev->wd_cl.state = MEI_FILE_DISCONNECTING;
264 mei_cl_disconnect(&dev->wd_cl);
265 }
266
267 /* Unregistering watchdog device */
268 mei_watchdog_unregister(dev);
269
270 /* remove entry if already in list */
271 dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
272
273 if (dev->open_handle_count > 0)
274 dev->open_handle_count--;
275 mei_cl_unlink(&dev->wd_cl);
276
277 if (dev->open_handle_count > 0)
278 dev->open_handle_count--;
279 mei_cl_unlink(&dev->iamthif_cl);
280
281 dev->iamthif_current_cb = NULL;
282 dev->me_clients_num = 0;
283
284 mutex_unlock(&dev->device_lock);
285
286 flush_scheduled_work();
287
288 /* disable interrupts */
289 mei_disable_interrupts(dev);
290
291 free_irq(pdev->irq, dev);
292 pci_disable_msi(pdev);
293 pci_set_drvdata(pdev, NULL);
294
295 if (hw->mem_addr)
296 pci_iounmap(pdev, hw->mem_addr);
297
298 kfree(dev);
299
300 pci_release_regions(pdev);
301 pci_disable_device(pdev);
302
303 mei_deregister();
304
305}
306#ifdef CONFIG_PM
307static int mei_pci_suspend(struct device *device)
308{
309 struct pci_dev *pdev = to_pci_dev(device);
310 struct mei_device *dev = pci_get_drvdata(pdev);
311 int err;
312
313 if (!dev)
314 return -ENODEV;
315 mutex_lock(&dev->device_lock);
316
317 cancel_delayed_work(&dev->timer_work);
318
319 /* Stop watchdog if exists */
320 err = mei_wd_stop(dev);
321 /* Set new mei state */
322 if (dev->dev_state == MEI_DEV_ENABLED ||
323 dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
324 dev->dev_state = MEI_DEV_POWER_DOWN;
325 mei_reset(dev, 0);
326 }
327 mutex_unlock(&dev->device_lock);
328
329 free_irq(pdev->irq, dev);
330 pci_disable_msi(pdev);
331
332 return err;
333}
334
335static int mei_pci_resume(struct device *device)
336{
337 struct pci_dev *pdev = to_pci_dev(device);
338 struct mei_device *dev;
339 int err;
340
341 dev = pci_get_drvdata(pdev);
342 if (!dev)
343 return -ENODEV;
344
345 pci_enable_msi(pdev);
346
347 /* request and enable interrupt */
348 if (pci_dev_msi_enabled(pdev))
349 err = request_threaded_irq(pdev->irq,
350 NULL,
351 mei_me_irq_thread_handler,
352 IRQF_ONESHOT, KBUILD_MODNAME, dev);
353 else
354 err = request_threaded_irq(pdev->irq,
355 mei_me_irq_quick_handler,
356 mei_me_irq_thread_handler,
357 IRQF_SHARED, KBUILD_MODNAME, dev);
358
359 if (err) {
360 dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n",
361 pdev->irq);
362 return err;
363 }
364
365 mutex_lock(&dev->device_lock);
366 dev->dev_state = MEI_DEV_POWER_UP;
367 mei_reset(dev, 1);
368 mutex_unlock(&dev->device_lock);
369
370 /* Start timer if stopped in suspend */
371 schedule_delayed_work(&dev->timer_work, HZ);
372
373 return err;
374}
375static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume);
376#define MEI_PM_OPS (&mei_pm_ops)
377#else
378#define MEI_PM_OPS NULL
379#endif /* CONFIG_PM */
380/*
381 * PCI driver structure
382 */
383static struct pci_driver mei_driver = {
384 .name = KBUILD_MODNAME,
385 .id_table = mei_pci_tbl,
386 .probe = mei_probe,
387 .remove = mei_remove,
388 .shutdown = mei_remove,
389 .driver.pm = MEI_PM_OPS,
390};
391
392module_pci_driver(mei_driver);
393
394MODULE_AUTHOR("Intel Corporation");
395MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
396MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index 9299a8c29a6f..2413247fc392 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -21,11 +21,13 @@
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/watchdog.h> 22#include <linux/watchdog.h>
23 23
24#include "mei_dev.h"
25#include "hw.h"
26#include "interface.h"
27#include <linux/mei.h> 24#include <linux/mei.h>
28 25
26#include "mei_dev.h"
27#include "hbm.h"
28#include "hw-me.h"
29#include "client.h"
30
29static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; 31static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 };
30static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; 32static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 };
31 33
@@ -62,30 +64,41 @@ static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout)
62 */ 64 */
63int mei_wd_host_init(struct mei_device *dev) 65int mei_wd_host_init(struct mei_device *dev)
64{ 66{
65 int id; 67 struct mei_cl *cl = &dev->wd_cl;
66 mei_cl_init(&dev->wd_cl, dev); 68 int i;
69 int ret;
70
71 mei_cl_init(cl, dev);
67 72
68 /* look for WD client and connect to it */
69 dev->wd_cl.state = MEI_FILE_DISCONNECTED;
70 dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT; 73 dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT;
71 dev->wd_state = MEI_WD_IDLE; 74 dev->wd_state = MEI_WD_IDLE;
72 75
73 /* Connect WD ME client to the host client */
74 id = mei_me_cl_link(dev, &dev->wd_cl,
75 &mei_wd_guid, MEI_WD_HOST_CLIENT_ID);
76 76
77 if (id < 0) { 77 /* check for valid client id */
78 i = mei_me_cl_by_uuid(dev, &mei_wd_guid);
79 if (i < 0) {
78 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");
79 return -ENOENT; 81 return -ENOENT;
80 } 82 }
81 83
82 if (mei_connect(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)) {
83 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");
84 dev->wd_cl.state = MEI_FILE_DISCONNECTED; 97 cl->state = MEI_FILE_DISCONNECTED;
85 dev->wd_cl.host_client_id = 0; 98 cl->host_client_id = 0;
86 return -EIO; 99 return -EIO;
87 } 100 }
88 dev->wd_cl.timer_count = MEI_CONNECT_TIMEOUT; 101 cl->timer_count = MEI_CONNECT_TIMEOUT;
89 102
90 return 0; 103 return 0;
91} 104}
@@ -101,22 +114,21 @@ int mei_wd_host_init(struct mei_device *dev)
101 */ 114 */
102int mei_wd_send(struct mei_device *dev) 115int mei_wd_send(struct mei_device *dev)
103{ 116{
104 struct mei_msg_hdr *mei_hdr; 117 struct mei_msg_hdr hdr;
105 118
106 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; 119 hdr.host_addr = dev->wd_cl.host_client_id;
107 mei_hdr->host_addr = dev->wd_cl.host_client_id; 120 hdr.me_addr = dev->wd_cl.me_client_id;
108 mei_hdr->me_addr = dev->wd_cl.me_client_id; 121 hdr.msg_complete = 1;
109 mei_hdr->msg_complete = 1; 122 hdr.reserved = 0;
110 mei_hdr->reserved = 0;
111 123
112 if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE)) 124 if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE))
113 mei_hdr->length = MEI_WD_START_MSG_SIZE; 125 hdr.length = MEI_WD_START_MSG_SIZE;
114 else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_HDR_SIZE)) 126 else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_HDR_SIZE))
115 mei_hdr->length = MEI_WD_STOP_MSG_SIZE; 127 hdr.length = MEI_WD_STOP_MSG_SIZE;
116 else 128 else
117 return -EINVAL; 129 return -EINVAL;
118 130
119 return mei_write_message(dev, mei_hdr, dev->wd_data, mei_hdr->length); 131 return mei_write_message(dev, &hdr, dev->wd_data);
120} 132}
121 133
122/** 134/**
@@ -141,16 +153,16 @@ int mei_wd_stop(struct mei_device *dev)
141 153
142 dev->wd_state = MEI_WD_STOPPING; 154 dev->wd_state = MEI_WD_STOPPING;
143 155
144 ret = mei_flow_ctrl_creds(dev, &dev->wd_cl); 156 ret = mei_cl_flow_ctrl_creds(&dev->wd_cl);
145 if (ret < 0) 157 if (ret < 0)
146 goto out; 158 goto out;
147 159
148 if (ret && dev->mei_host_buffer_is_empty) { 160 if (ret && dev->hbuf_is_ready) {
149 ret = 0; 161 ret = 0;
150 dev->mei_host_buffer_is_empty = false; 162 dev->hbuf_is_ready = false;
151 163
152 if (!mei_wd_send(dev)) { 164 if (!mei_wd_send(dev)) {
153 ret = mei_flow_ctrl_reduce(dev, &dev->wd_cl); 165 ret = mei_cl_flow_ctrl_reduce(&dev->wd_cl);
154 if (ret) 166 if (ret)
155 goto out; 167 goto out;
156 } else { 168 } else {
@@ -270,10 +282,9 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
270 dev->wd_state = MEI_WD_RUNNING; 282 dev->wd_state = MEI_WD_RUNNING;
271 283
272 /* Check if we can send the ping to HW*/ 284 /* Check if we can send the ping to HW*/
273 if (dev->mei_host_buffer_is_empty && 285 if (dev->hbuf_is_ready && mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) {
274 mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
275 286
276 dev->mei_host_buffer_is_empty = false; 287 dev->hbuf_is_ready = false;
277 dev_dbg(&dev->pdev->dev, "wd: sending ping\n"); 288 dev_dbg(&dev->pdev->dev, "wd: sending ping\n");
278 289
279 if (mei_wd_send(dev)) { 290 if (mei_wd_send(dev)) {
@@ -282,9 +293,9 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
282 goto end; 293 goto end;
283 } 294 }
284 295
285 if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) { 296 if (mei_cl_flow_ctrl_reduce(&dev->wd_cl)) {
286 dev_err(&dev->pdev->dev, 297 dev_err(&dev->pdev->dev,
287 "wd: mei_flow_ctrl_reduce() failed.\n"); 298 "wd: mei_cl_flow_ctrl_reduce() failed.\n");
288 ret = -EIO; 299 ret = -EIO;
289 goto end; 300 goto end;
290 } 301 }