diff options
| author | Alexander Usyskin <alexander.usyskin@intel.com> | 2014-02-17 08:13:20 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-18 13:05:07 -0500 |
| commit | 285e2996655b7bbfb5eb83076a7d7e6f03e2f5c2 (patch) | |
| tree | 2c90567eed399090fd5c41cd6ae88eeaef6246da | |
| parent | 487056932d372cc4f6c636f21a928d6667b151d7 (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>
| -rw-r--r-- | drivers/misc/mei/client.c | 13 | ||||
| -rw-r--r-- | drivers/misc/mei/hbm.c | 67 | ||||
| -rw-r--r-- | drivers/misc/mei/hw.h | 16 | ||||
| -rw-r--r-- | drivers/misc/mei/main.c | 2 |
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 | ||
| 26 | static 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 | */ | ||
| 48 | static 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 | */ |
| 92 | enum client_connect_status_types { | 92 | enum 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 | */ |
| 103 | enum client_disconnect_status_types { | 103 | enum 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 | ||
