diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2014-02-19 10:35:48 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-28 18:15:57 -0500 |
commit | 9d098192c3d45ab6dd90ae87d649950a9ef70ccb (patch) | |
tree | a0f48fbc9a60e411cd499a22ac013f85fbb0aeeb /drivers/misc/mei/interrupt.c | |
parent | 6aae48ff18f2fcfb533d2b448ecae16d1de006c1 (diff) |
mei: revamp writing slot counting
Since txe use doorbell and not circular buffer
we have to cheat in write slot counting, txe always consume all the
slots upon write. In order for it to work we need to track
slots using mei_hbuf_empty_slots() instead of tracking it in mei layer
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei/interrupt.c')
-rw-r--r-- | drivers/misc/mei/interrupt.c | 78 |
1 files changed, 30 insertions, 48 deletions
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index aed03efa72f4..e6151e2dac48 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c | |||
@@ -165,25 +165,24 @@ static int mei_cl_irq_read_msg(struct mei_device *dev, | |||
165 | * | 165 | * |
166 | * @cl: client | 166 | * @cl: client |
167 | * @cb: callback block. | 167 | * @cb: callback block. |
168 | * @slots: free slots. | ||
169 | * @cmpl_list: complete list. | 168 | * @cmpl_list: complete list. |
170 | * | 169 | * |
171 | * returns 0, OK; otherwise, error. | 170 | * returns 0, OK; otherwise, error. |
172 | */ | 171 | */ |
173 | static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, | 172 | static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, |
174 | s32 *slots, struct mei_cl_cb *cmpl_list) | 173 | struct mei_cl_cb *cmpl_list) |
175 | { | 174 | { |
176 | struct mei_device *dev = cl->dev; | 175 | struct mei_device *dev = cl->dev; |
176 | u32 msg_slots; | ||
177 | int slots; | ||
177 | int ret; | 178 | int ret; |
178 | 179 | ||
179 | u32 msg_slots = | 180 | slots = mei_hbuf_empty_slots(dev); |
180 | mei_data2slots(sizeof(struct hbm_client_connect_response)); | 181 | msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_response)); |
181 | 182 | ||
182 | if (*slots < msg_slots) | 183 | if (slots < msg_slots) |
183 | return -EMSGSIZE; | 184 | return -EMSGSIZE; |
184 | 185 | ||
185 | *slots -= msg_slots; | ||
186 | |||
187 | ret = mei_hbm_cl_disconnect_rsp(dev, cl); | 186 | ret = mei_hbm_cl_disconnect_rsp(dev, cl); |
188 | 187 | ||
189 | cl->state = MEI_FILE_DISCONNECTED; | 188 | cl->state = MEI_FILE_DISCONNECTED; |
@@ -201,24 +200,23 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, | |||
201 | * | 200 | * |
202 | * @cl: client | 201 | * @cl: client |
203 | * @cb: callback block. | 202 | * @cb: callback block. |
204 | * @slots: free slots. | ||
205 | * @cmpl_list: complete list. | 203 | * @cmpl_list: complete list. |
206 | * | 204 | * |
207 | * returns 0, OK; otherwise, error. | 205 | * returns 0, OK; otherwise, error. |
208 | */ | 206 | */ |
209 | static int mei_cl_irq_close(struct mei_cl *cl, struct mei_cl_cb *cb, | 207 | static int mei_cl_irq_close(struct mei_cl *cl, struct mei_cl_cb *cb, |
210 | s32 *slots, struct mei_cl_cb *cmpl_list) | 208 | struct mei_cl_cb *cmpl_list) |
211 | { | 209 | { |
212 | struct mei_device *dev = cl->dev; | 210 | struct mei_device *dev = cl->dev; |
211 | u32 msg_slots; | ||
212 | int slots; | ||
213 | 213 | ||
214 | u32 msg_slots = | 214 | msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request)); |
215 | mei_data2slots(sizeof(struct hbm_client_connect_request)); | 215 | slots = mei_hbuf_empty_slots(dev); |
216 | 216 | ||
217 | if (*slots < msg_slots) | 217 | if (slots < msg_slots) |
218 | return -EMSGSIZE; | 218 | return -EMSGSIZE; |
219 | 219 | ||
220 | *slots -= msg_slots; | ||
221 | |||
222 | if (mei_hbm_cl_disconnect_req(dev, cl)) { | 220 | if (mei_hbm_cl_disconnect_req(dev, cl)) { |
223 | cl->status = 0; | 221 | cl->status = 0; |
224 | cb->buf_idx = 0; | 222 | cb->buf_idx = 0; |
@@ -242,27 +240,23 @@ static int mei_cl_irq_close(struct mei_cl *cl, struct mei_cl_cb *cb, | |||
242 | * | 240 | * |
243 | * @cl: client | 241 | * @cl: client |
244 | * @cb: callback block. | 242 | * @cb: callback block. |
245 | * @slots: free slots. | ||
246 | * @cmpl_list: complete list. | 243 | * @cmpl_list: complete list. |
247 | * | 244 | * |
248 | * returns 0, OK; otherwise, error. | 245 | * returns 0, OK; otherwise, error. |
249 | */ | 246 | */ |
250 | static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, | 247 | static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, |
251 | s32 *slots, struct mei_cl_cb *cmpl_list) | 248 | struct mei_cl_cb *cmpl_list) |
252 | { | 249 | { |
253 | struct mei_device *dev = cl->dev; | 250 | struct mei_device *dev = cl->dev; |
254 | u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control)); | 251 | u32 msg_slots; |
255 | 252 | int slots; | |
256 | int ret; | 253 | int ret; |
257 | 254 | ||
255 | msg_slots = mei_data2slots(sizeof(struct hbm_flow_control)); | ||
256 | slots = mei_hbuf_empty_slots(dev); | ||
258 | 257 | ||
259 | if (*slots < msg_slots) { | 258 | if (slots < msg_slots) |
260 | /* return the cancel routine */ | ||
261 | list_del(&cb->list); | ||
262 | return -EMSGSIZE; | 259 | return -EMSGSIZE; |
263 | } | ||
264 | |||
265 | *slots -= msg_slots; | ||
266 | 260 | ||
267 | ret = mei_hbm_cl_flow_control_req(dev, cl); | 261 | ret = mei_hbm_cl_flow_control_req(dev, cl); |
268 | if (ret) { | 262 | if (ret) { |
@@ -283,30 +277,26 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, | |||
283 | * | 277 | * |
284 | * @cl: client | 278 | * @cl: client |
285 | * @cb: callback block. | 279 | * @cb: callback block. |
286 | * @slots: free slots. | ||
287 | * @cmpl_list: complete list. | 280 | * @cmpl_list: complete list. |
288 | * | 281 | * |
289 | * returns 0, OK; otherwise, error. | 282 | * returns 0, OK; otherwise, error. |
290 | */ | 283 | */ |
291 | static int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, | 284 | static int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, |
292 | s32 *slots, struct mei_cl_cb *cmpl_list) | 285 | struct mei_cl_cb *cmpl_list) |
293 | { | 286 | { |
294 | struct mei_device *dev = cl->dev; | 287 | struct mei_device *dev = cl->dev; |
288 | u32 msg_slots; | ||
289 | int slots; | ||
295 | int ret; | 290 | int ret; |
296 | 291 | ||
297 | u32 msg_slots = | 292 | msg_slots = mei_data2slots(sizeof(struct hbm_client_connect_request)); |
298 | mei_data2slots(sizeof(struct hbm_client_connect_request)); | 293 | slots = mei_hbuf_empty_slots(dev); |
299 | 294 | ||
300 | if (mei_cl_is_other_connecting(cl)) | 295 | if (mei_cl_is_other_connecting(cl)) |
301 | return 0; | 296 | return 0; |
302 | 297 | ||
303 | if (*slots < msg_slots) { | 298 | if (slots < msg_slots) |
304 | /* return the cancel routine */ | ||
305 | list_del(&cb->list); | ||
306 | return -EMSGSIZE; | 299 | return -EMSGSIZE; |
307 | } | ||
308 | |||
309 | *slots -= msg_slots; | ||
310 | 300 | ||
311 | cl->state = MEI_FILE_CONNECTING; | 301 | cl->state = MEI_FILE_CONNECTING; |
312 | 302 | ||
@@ -494,13 +484,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) | |||
494 | dev_dbg(&dev->pdev->dev, "wd send failed.\n"); | 484 | dev_dbg(&dev->pdev->dev, "wd send failed.\n"); |
495 | else if (mei_cl_flow_ctrl_reduce(&dev->wd_cl)) | 485 | else if (mei_cl_flow_ctrl_reduce(&dev->wd_cl)) |
496 | return -ENODEV; | 486 | return -ENODEV; |
497 | |||
498 | dev->wd_pending = false; | 487 | dev->wd_pending = false; |
499 | |||
500 | if (dev->wd_state == MEI_WD_RUNNING) | ||
501 | slots -= mei_data2slots(MEI_WD_START_MSG_SIZE); | ||
502 | else | ||
503 | slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE); | ||
504 | } | 488 | } |
505 | } | 489 | } |
506 | 490 | ||
@@ -515,28 +499,28 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) | |||
515 | switch (cb->fop_type) { | 499 | switch (cb->fop_type) { |
516 | case MEI_FOP_CLOSE: | 500 | case MEI_FOP_CLOSE: |
517 | /* send disconnect message */ | 501 | /* send disconnect message */ |
518 | ret = mei_cl_irq_close(cl, cb, &slots, cmpl_list); | 502 | ret = mei_cl_irq_close(cl, cb, cmpl_list); |
519 | if (ret) | 503 | if (ret) |
520 | return ret; | 504 | return ret; |
521 | 505 | ||
522 | break; | 506 | break; |
523 | case MEI_FOP_READ: | 507 | case MEI_FOP_READ: |
524 | /* send flow control message */ | 508 | /* send flow control message */ |
525 | ret = mei_cl_irq_read(cl, cb, &slots, cmpl_list); | 509 | ret = mei_cl_irq_read(cl, cb, cmpl_list); |
526 | if (ret) | 510 | if (ret) |
527 | return ret; | 511 | return ret; |
528 | 512 | ||
529 | break; | 513 | break; |
530 | case MEI_FOP_CONNECT: | 514 | case MEI_FOP_CONNECT: |
531 | /* connect message */ | 515 | /* connect message */ |
532 | ret = mei_cl_irq_connect(cl, cb, &slots, cmpl_list); | 516 | ret = mei_cl_irq_connect(cl, cb, cmpl_list); |
533 | if (ret) | 517 | if (ret) |
534 | return ret; | 518 | return ret; |
535 | 519 | ||
536 | break; | 520 | break; |
537 | case MEI_FOP_DISCONNECT_RSP: | 521 | case MEI_FOP_DISCONNECT_RSP: |
538 | /* send disconnect resp */ | 522 | /* send disconnect resp */ |
539 | ret = mei_cl_irq_disconnect_rsp(cl, cb, &slots, cmpl_list); | 523 | ret = mei_cl_irq_disconnect_rsp(cl, cb, cmpl_list); |
540 | if (ret) | 524 | if (ret) |
541 | return ret; | 525 | return ret; |
542 | default: | 526 | default: |
@@ -551,11 +535,9 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) | |||
551 | if (cl == NULL) | 535 | if (cl == NULL) |
552 | continue; | 536 | continue; |
553 | if (cl == &dev->iamthif_cl) | 537 | if (cl == &dev->iamthif_cl) |
554 | ret = mei_amthif_irq_write_complete(cl, cb, | 538 | ret = mei_amthif_irq_write(cl, cb, cmpl_list); |
555 | &slots, cmpl_list); | ||
556 | else | 539 | else |
557 | ret = mei_cl_irq_write_complete(cl, cb, | 540 | ret = mei_cl_irq_write(cl, cb, cmpl_list); |
558 | &slots, cmpl_list); | ||
559 | if (ret) | 541 | if (ret) |
560 | return ret; | 542 | return ret; |
561 | } | 543 | } |