diff options
| author | Tomas Winkler <tomas.winkler@intel.com> | 2013-04-19 15:01:34 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-04-19 16:38:38 -0400 |
| commit | 6e0f180fd8b47fa0884177a142e41a86117edc23 (patch) | |
| tree | 23544f67bc004732f8dc5841c5c74f0274a20918 /drivers/misc | |
| parent | 5ceb46e25d727f198c1efe281d19653962a51931 (diff) | |
mei: revamp mei_irq_read_client_message function
1. Rename the function and change parameters order,
so that first parameter is mei_device
2. Simplify the function code flow
3. Rename helper functions to more self descriptive names
4. Use helpers common functions where possible
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
| -rw-r--r-- | drivers/misc/mei/interrupt.c | 124 |
1 files changed, 66 insertions, 58 deletions
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 8e4db3d77e07..9bf64c06fa39 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c | |||
| @@ -82,80 +82,90 @@ void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *compl_list) | |||
| 82 | } | 82 | } |
| 83 | } | 83 | } |
| 84 | EXPORT_SYMBOL_GPL(mei_irq_compl_handler); | 84 | EXPORT_SYMBOL_GPL(mei_irq_compl_handler); |
| 85 | |||
| 85 | /** | 86 | /** |
| 86 | * _mei_irq_thread_state_ok - checks if mei header matches file private data | 87 | * mei_cl_hbm_equal - check if hbm is addressed to the client |
| 87 | * | 88 | * |
| 88 | * @cl: private data of the file object | 89 | * @cl: host client |
| 89 | * @mei_hdr: header of mei client message | 90 | * @mei_hdr: header of mei client message |
| 90 | * | 91 | * |
| 91 | * returns !=0 if matches, 0 if no match. | 92 | * returns true if matches, false otherwise |
| 93 | */ | ||
| 94 | static inline int mei_cl_hbm_equal(struct mei_cl *cl, | ||
| 95 | struct mei_msg_hdr *mei_hdr) | ||
| 96 | { | ||
| 97 | return cl->host_client_id == mei_hdr->host_addr && | ||
| 98 | cl->me_client_id == mei_hdr->me_addr; | ||
| 99 | } | ||
| 100 | /** | ||
| 101 | * mei_cl_is_reading - checks if the client | ||
| 102 | is the one to read this message | ||
| 103 | * | ||
| 104 | * @cl: mei client | ||
| 105 | * @mei_hdr: header of mei message | ||
| 106 | * | ||
| 107 | * returns true on match and false otherwise | ||
| 92 | */ | 108 | */ |
| 93 | static int _mei_irq_thread_state_ok(struct mei_cl *cl, | 109 | static bool mei_cl_is_reading(struct mei_cl *cl, struct mei_msg_hdr *mei_hdr) |
| 94 | struct mei_msg_hdr *mei_hdr) | ||
| 95 | { | 110 | { |
| 96 | return (cl->host_client_id == mei_hdr->host_addr && | 111 | return mei_cl_hbm_equal(cl, mei_hdr) && |
| 97 | cl->me_client_id == mei_hdr->me_addr && | ||
| 98 | cl->state == MEI_FILE_CONNECTED && | 112 | cl->state == MEI_FILE_CONNECTED && |
| 99 | MEI_READ_COMPLETE != cl->reading_state); | 113 | cl->reading_state != MEI_READ_COMPLETE; |
| 100 | } | 114 | } |
| 101 | 115 | ||
| 102 | /** | 116 | /** |
| 103 | * mei_irq_thread_read_client_message - bottom half read routine after ISR to | 117 | * mei_irq_read_client_message - process client message |
| 104 | * handle the read mei client message data processing. | ||
| 105 | * | 118 | * |
| 106 | * @complete_list: An instance of our list structure | ||
| 107 | * @dev: the device structure | 119 | * @dev: the device structure |
| 108 | * @mei_hdr: header of mei client message | 120 | * @mei_hdr: header of mei client message |
| 121 | * @complete_list: An instance of our list structure | ||
| 109 | * | 122 | * |
| 110 | * returns 0 on success, <0 on failure. | 123 | * returns 0 on success, <0 on failure. |
| 111 | */ | 124 | */ |
| 112 | static int mei_irq_thread_read_client_message(struct mei_cl_cb *complete_list, | 125 | static int mei_cl_irq_read_msg(struct mei_device *dev, |
| 113 | struct mei_device *dev, | 126 | struct mei_msg_hdr *mei_hdr, |
| 114 | struct mei_msg_hdr *mei_hdr) | 127 | struct mei_cl_cb *complete_list) |
| 115 | { | 128 | { |
| 116 | struct mei_cl *cl; | 129 | struct mei_cl *cl; |
| 117 | struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; | 130 | struct mei_cl_cb *cb, *next; |
| 118 | unsigned char *buffer = NULL; | 131 | unsigned char *buffer = NULL; |
| 119 | 132 | ||
| 120 | dev_dbg(&dev->pdev->dev, "start client msg\n"); | 133 | list_for_each_entry_safe(cb, next, &dev->read_list.list, list) { |
| 121 | if (list_empty(&dev->read_list.list)) | 134 | cl = cb->cl; |
| 122 | goto quit; | 135 | if (!cl || !mei_cl_is_reading(cl, mei_hdr)) |
| 123 | 136 | continue; | |
| 124 | list_for_each_entry_safe(cb_pos, cb_next, &dev->read_list.list, list) { | ||
| 125 | cl = cb_pos->cl; | ||
| 126 | if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) { | ||
| 127 | cl->reading_state = MEI_READING; | ||
| 128 | buffer = cb_pos->response_buffer.data + cb_pos->buf_idx; | ||
| 129 | |||
| 130 | if (cb_pos->response_buffer.size < | ||
| 131 | mei_hdr->length + cb_pos->buf_idx) { | ||
| 132 | dev_dbg(&dev->pdev->dev, "message overflow.\n"); | ||
| 133 | list_del(&cb_pos->list); | ||
| 134 | return -ENOMEM; | ||
| 135 | } | ||
| 136 | if (buffer) | ||
| 137 | mei_read_slots(dev, buffer, mei_hdr->length); | ||
| 138 | |||
| 139 | cb_pos->buf_idx += mei_hdr->length; | ||
| 140 | if (mei_hdr->msg_complete) { | ||
| 141 | cl->status = 0; | ||
| 142 | list_del(&cb_pos->list); | ||
| 143 | dev_dbg(&dev->pdev->dev, | ||
| 144 | "completed read H cl = %d, ME cl = %d, length = %lu\n", | ||
| 145 | cl->host_client_id, | ||
| 146 | cl->me_client_id, | ||
| 147 | cb_pos->buf_idx); | ||
| 148 | |||
| 149 | list_add_tail(&cb_pos->list, | ||
| 150 | &complete_list->list); | ||
| 151 | } | ||
| 152 | 137 | ||
| 153 | break; | 138 | cl->reading_state = MEI_READING; |
| 139 | |||
| 140 | if (cb->response_buffer.size == 0 || | ||
| 141 | cb->response_buffer.data == NULL) { | ||
| 142 | dev_err(&dev->pdev->dev, "response buffer is not allocated.\n"); | ||
| 143 | list_del(&cb->list); | ||
| 144 | return -ENOMEM; | ||
| 145 | } | ||
| 146 | |||
| 147 | if (cb->response_buffer.size < mei_hdr->length + cb->buf_idx) { | ||
| 148 | dev_warn(&dev->pdev->dev, "message overflow.\n"); | ||
| 149 | list_del(&cb->list); | ||
| 150 | return -ENOMEM; | ||
| 154 | } | 151 | } |
| 155 | 152 | ||
| 153 | buffer = cb->response_buffer.data + cb->buf_idx; | ||
| 154 | mei_read_slots(dev, buffer, mei_hdr->length); | ||
| 155 | |||
| 156 | cb->buf_idx += mei_hdr->length; | ||
| 157 | if (mei_hdr->msg_complete) { | ||
| 158 | cl->status = 0; | ||
| 159 | list_del(&cb->list); | ||
| 160 | dev_dbg(&dev->pdev->dev, "completed read H cl = %d, ME cl = %d, length = %lu\n", | ||
| 161 | cl->host_client_id, | ||
| 162 | cl->me_client_id, | ||
| 163 | cb->buf_idx); | ||
| 164 | list_add_tail(&cb->list, &complete_list->list); | ||
| 165 | } | ||
| 166 | break; | ||
| 156 | } | 167 | } |
| 157 | 168 | ||
| 158 | quit: | ||
| 159 | dev_dbg(&dev->pdev->dev, "message read\n"); | 169 | dev_dbg(&dev->pdev->dev, "message read\n"); |
| 160 | if (!buffer) { | 170 | if (!buffer) { |
| 161 | mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); | 171 | mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); |
| @@ -386,8 +396,7 @@ int mei_irq_read_handler(struct mei_device *dev, | |||
| 386 | " client = %d, ME client = %d\n", | 396 | " client = %d, ME client = %d\n", |
| 387 | cl_pos->host_client_id, | 397 | cl_pos->host_client_id, |
| 388 | cl_pos->me_client_id); | 398 | cl_pos->me_client_id); |
| 389 | if (cl_pos->host_client_id == mei_hdr->host_addr && | 399 | if (mei_cl_hbm_equal(cl_pos, mei_hdr)) |
| 390 | cl_pos->me_client_id == mei_hdr->me_addr) | ||
| 391 | break; | 400 | break; |
| 392 | } | 401 | } |
| 393 | 402 | ||
| @@ -398,7 +407,7 @@ int mei_irq_read_handler(struct mei_device *dev, | |||
| 398 | } | 407 | } |
| 399 | } | 408 | } |
| 400 | if (((*slots) * sizeof(u32)) < mei_hdr->length) { | 409 | if (((*slots) * sizeof(u32)) < mei_hdr->length) { |
| 401 | dev_dbg(&dev->pdev->dev, | 410 | dev_err(&dev->pdev->dev, |
| 402 | "we can't read the message slots =%08x.\n", | 411 | "we can't read the message slots =%08x.\n", |
| 403 | *slots); | 412 | *slots); |
| 404 | /* we can't read the message */ | 413 | /* we can't read the message */ |
| @@ -414,20 +423,19 @@ int mei_irq_read_handler(struct mei_device *dev, | |||
| 414 | } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && | 423 | } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && |
| 415 | (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && | 424 | (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && |
| 416 | (dev->iamthif_state == MEI_IAMTHIF_READING)) { | 425 | (dev->iamthif_state == MEI_IAMTHIF_READING)) { |
| 417 | dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); | ||
| 418 | 426 | ||
| 427 | dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); | ||
| 419 | dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); | 428 | dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); |
| 420 | 429 | ||
| 421 | ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list); | 430 | ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list); |
| 422 | if (ret) | 431 | if (ret) |
| 423 | goto end; | 432 | goto end; |
| 424 | } else { | 433 | } else { |
| 425 | dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n"); | 434 | dev_dbg(&dev->pdev->dev, "call mei_cl_irq_read_msg.\n"); |
| 426 | ret = mei_irq_thread_read_client_message(cmpl_list, | 435 | dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); |
| 427 | dev, mei_hdr); | 436 | ret = mei_cl_irq_read_msg(dev, mei_hdr, cmpl_list); |
| 428 | if (ret) | 437 | if (ret) |
| 429 | goto end; | 438 | goto end; |
| 430 | |||
| 431 | } | 439 | } |
| 432 | 440 | ||
| 433 | /* reset the number of slots and header */ | 441 | /* reset the number of slots and header */ |
| @@ -436,7 +444,7 @@ int mei_irq_read_handler(struct mei_device *dev, | |||
| 436 | 444 | ||
| 437 | if (*slots == -EOVERFLOW) { | 445 | if (*slots == -EOVERFLOW) { |
| 438 | /* overflow - reset */ | 446 | /* overflow - reset */ |
| 439 | dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n"); | 447 | dev_err(&dev->pdev->dev, "resetting due to slots overflow.\n"); |
| 440 | /* set the event since message has been read */ | 448 | /* set the event since message has been read */ |
| 441 | ret = -ERANGE; | 449 | ret = -ERANGE; |
| 442 | goto end; | 450 | goto end; |
