aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2013-04-19 15:01:34 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-19 16:38:38 -0400
commit6e0f180fd8b47fa0884177a142e41a86117edc23 (patch)
tree23544f67bc004732f8dc5841c5c74f0274a20918 /drivers/misc
parent5ceb46e25d727f198c1efe281d19653962a51931 (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.c124
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}
84EXPORT_SYMBOL_GPL(mei_irq_compl_handler); 84EXPORT_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 */
94static 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 */
93static int _mei_irq_thread_state_ok(struct mei_cl *cl, 109static 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 */
112static int mei_irq_thread_read_client_message(struct mei_cl_cb *complete_list, 125static 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
158quit:
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;