aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei
diff options
context:
space:
mode:
authorAlexander Usyskin <alexander.usyskin@intel.com>2014-02-17 08:13:20 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-18 13:05:07 -0500
commit285e2996655b7bbfb5eb83076a7d7e6f03e2f5c2 (patch)
tree2c90567eed399090fd5c41cd6ae88eeaef6246da /drivers/misc/mei
parent487056932d372cc4f6c636f21a928d6667b151d7 (diff)
mei: hbm: revamp client connect and disconnection status
1. Return -ENOTTY on client connect if the requested client was not found on the enumeration list or the client was internally disabled, in the later case FW will return NOT_FOUND. 2. Return -EBUSY if the client cannot be connected because of resource contention 3. Change response status enum to have MEI_CL_ prefix 4. Add function to translate response status to a string for more readable logging Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r--drivers/misc/mei/client.c13
-rw-r--r--drivers/misc/mei/hbm.c67
-rw-r--r--drivers/misc/mei/hw.h16
-rw-r--r--drivers/misc/mei/main.c2
4 files changed, 59 insertions, 39 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 9ac72f1ea6b9..8afba0534779 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -521,18 +521,19 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
521 } 521 }
522 522
523 mutex_unlock(&dev->device_lock); 523 mutex_unlock(&dev->device_lock);
524 rets = wait_event_timeout(dev->wait_recvd_msg, 524 wait_event_timeout(dev->wait_recvd_msg,
525 (cl->state == MEI_FILE_CONNECTED || 525 (cl->state == MEI_FILE_CONNECTED ||
526 cl->state == MEI_FILE_DISCONNECTED), 526 cl->state == MEI_FILE_DISCONNECTED),
527 mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); 527 mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
528 mutex_lock(&dev->device_lock); 528 mutex_lock(&dev->device_lock);
529 529
530 if (cl->state != MEI_FILE_CONNECTED) { 530 if (cl->state != MEI_FILE_CONNECTED) {
531 rets = -EFAULT; 531 /* something went really wrong */
532 if (!cl->status)
533 cl->status = -EFAULT;
532 534
533 mei_io_list_flush(&dev->ctrl_rd_list, cl); 535 mei_io_list_flush(&dev->ctrl_rd_list, cl);
534 mei_io_list_flush(&dev->ctrl_wr_list, cl); 536 mei_io_list_flush(&dev->ctrl_wr_list, cl);
535 goto out;
536 } 537 }
537 538
538 rets = cl->status; 539 rets = cl->status;
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index d3fcb23bb081..d360e9a5a1a5 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -23,6 +23,40 @@
23#include "hbm.h" 23#include "hbm.h"
24#include "hw-me.h" 24#include "hw-me.h"
25 25
26static const char *mei_cl_conn_status_str(enum mei_cl_connect_status status)
27{
28#define MEI_CL_CS(status) case MEI_CL_CONN_##status: return #status
29 switch (status) {
30 MEI_CL_CS(SUCCESS);
31 MEI_CL_CS(NOT_FOUND);
32 MEI_CL_CS(ALREADY_STARTED);
33 MEI_CL_CS(OUT_OF_RESOURCES);
34 MEI_CL_CS(MESSAGE_SMALL);
35 default: return "unknown";
36 }
37#undef MEI_CL_CCS
38}
39
40/**
41 * mei_cl_conn_status_to_errno - convert client connect response
42 * status to error code
43 *
44 * @status: client connect response status
45 *
46 * returns corresponding error code
47 */
48static int mei_cl_conn_status_to_errno(enum mei_cl_connect_status status)
49{
50 switch (status) {
51 case MEI_CL_CONN_SUCCESS: return 0;
52 case MEI_CL_CONN_NOT_FOUND: return -ENOTTY;
53 case MEI_CL_CONN_ALREADY_STARTED: return -EBUSY;
54 case MEI_CL_CONN_OUT_OF_RESOURCES: return -EBUSY;
55 case MEI_CL_CONN_MESSAGE_SMALL: return -EINVAL;
56 default: return -EINVAL;
57 }
58}
59
26/** 60/**
27 * mei_hbm_me_cl_allocate - allocates storage for me clients 61 * mei_hbm_me_cl_allocate - allocates storage for me clients
28 * 62 *
@@ -111,14 +145,11 @@ static bool is_treat_specially_client(struct mei_cl *cl,
111 struct hbm_client_connect_response *rs) 145 struct hbm_client_connect_response *rs)
112{ 146{
113 if (mei_hbm_cl_addr_equal(cl, rs)) { 147 if (mei_hbm_cl_addr_equal(cl, rs)) {
114 if (!rs->status) { 148 if (rs->status == MEI_CL_CONN_SUCCESS)
115 cl->state = MEI_FILE_CONNECTED; 149 cl->state = MEI_FILE_CONNECTED;
116 cl->status = 0; 150 else
117
118 } else {
119 cl->state = MEI_FILE_DISCONNECTED; 151 cl->state = MEI_FILE_DISCONNECTED;
120 cl->status = -ENODEV; 152 cl->status = mei_cl_conn_status_to_errno(rs->status);
121 }
122 cl->timer_count = 0; 153 cl->timer_count = 0;
123 154
124 return true; 155 return true;
@@ -438,14 +469,8 @@ static void mei_hbm_cl_disconnect_res(struct mei_device *dev,
438 struct mei_cl *cl; 469 struct mei_cl *cl;
439 struct mei_cl_cb *pos = NULL, *next = NULL; 470 struct mei_cl_cb *pos = NULL, *next = NULL;
440 471
441 dev_dbg(&dev->pdev->dev, 472 dev_dbg(&dev->pdev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n",
442 "disconnect_response:\n" 473 rs->me_addr, rs->host_addr, rs->status);
443 "ME Client = %d\n"
444 "Host Client = %d\n"
445 "Status = %d\n",
446 rs->me_addr,
447 rs->host_addr,
448 rs->status);
449 474
450 list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) { 475 list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
451 cl = pos->cl; 476 cl = pos->cl;
@@ -458,7 +483,7 @@ static void mei_hbm_cl_disconnect_res(struct mei_device *dev,
458 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n"); 483 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
459 if (mei_hbm_cl_addr_equal(cl, rs)) { 484 if (mei_hbm_cl_addr_equal(cl, rs)) {
460 list_del(&pos->list); 485 list_del(&pos->list);
461 if (!rs->status) 486 if (rs->status == MEI_CL_DISCONN_SUCCESS)
462 cl->state = MEI_FILE_DISCONNECTED; 487 cl->state = MEI_FILE_DISCONNECTED;
463 488
464 cl->status = 0; 489 cl->status = 0;
@@ -500,14 +525,9 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev,
500 struct mei_cl *cl; 525 struct mei_cl *cl;
501 struct mei_cl_cb *pos = NULL, *next = NULL; 526 struct mei_cl_cb *pos = NULL, *next = NULL;
502 527
503 dev_dbg(&dev->pdev->dev, 528 dev_dbg(&dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n",
504 "connect_response:\n" 529 rs->me_addr, rs->host_addr,
505 "ME Client = %d\n" 530 mei_cl_conn_status_str(rs->status));
506 "Host Client = %d\n"
507 "Status = %d\n",
508 rs->me_addr,
509 rs->host_addr,
510 rs->status);
511 531
512 /* if WD or iamthif client treat specially */ 532 /* if WD or iamthif client treat specially */
513 533
@@ -532,7 +552,6 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev,
532 if (pos->fop_type == MEI_FOP_CONNECT) { 552 if (pos->fop_type == MEI_FOP_CONNECT) {
533 if (is_treat_specially_client(cl, rs)) { 553 if (is_treat_specially_client(cl, rs)) {
534 list_del(&pos->list); 554 list_del(&pos->list);
535 cl->status = 0;
536 cl->timer_count = 0; 555 cl->timer_count = 0;
537 break; 556 break;
538 } 557 }
diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h
index e06779d4413e..6b476ab49b2e 100644
--- a/drivers/misc/mei/hw.h
+++ b/drivers/misc/mei/hw.h
@@ -89,19 +89,19 @@ enum mei_stop_reason_types {
89 * Client Connect Status 89 * Client Connect Status
90 * used by hbm_client_connect_response.status 90 * used by hbm_client_connect_response.status
91 */ 91 */
92enum client_connect_status_types { 92enum mei_cl_connect_status {
93 CCS_SUCCESS = 0x00, 93 MEI_CL_CONN_SUCCESS = 0x00,
94 CCS_NOT_FOUND = 0x01, 94 MEI_CL_CONN_NOT_FOUND = 0x01,
95 CCS_ALREADY_STARTED = 0x02, 95 MEI_CL_CONN_ALREADY_STARTED = 0x02,
96 CCS_OUT_OF_RESOURCES = 0x03, 96 MEI_CL_CONN_OUT_OF_RESOURCES = 0x03,
97 CCS_MESSAGE_SMALL = 0x04 97 MEI_CL_CONN_MESSAGE_SMALL = 0x04
98}; 98};
99 99
100/* 100/*
101 * Client Disconnect Status 101 * Client Disconnect Status
102 */ 102 */
103enum client_disconnect_status_types { 103enum mei_cl_disconnect_status {
104 CDS_SUCCESS = 0x00 104 MEI_CL_DISCONN_SUCCESS = 0x00
105}; 105};
106 106
107/* 107/*
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 5424f8ff3f7f..434242bada89 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -471,7 +471,7 @@ static int mei_ioctl_connect_client(struct file *file,
471 if (i < 0 || dev->me_clients[i].props.fixed_address) { 471 if (i < 0 || dev->me_clients[i].props.fixed_address) {
472 dev_dbg(&dev->pdev->dev, "Cannot connect to FW Client UUID = %pUl\n", 472 dev_dbg(&dev->pdev->dev, "Cannot connect to FW Client UUID = %pUl\n",
473 &data->in_client_uuid); 473 &data->in_client_uuid);
474 rets = -ENODEV; 474 rets = -ENOTTY;
475 goto end; 475 goto end;
476 } 476 }
477 477