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; |