aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/interrupt.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2014-02-19 10:35:48 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-28 18:15:57 -0500
commit9d098192c3d45ab6dd90ae87d649950a9ef70ccb (patch)
treea0f48fbc9a60e411cd499a22ac013f85fbb0aeeb /drivers/misc/mei/interrupt.c
parent6aae48ff18f2fcfb533d2b448ecae16d1de006c1 (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.c78
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 */
173static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, 172static 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 */
209static int mei_cl_irq_close(struct mei_cl *cl, struct mei_cl_cb *cb, 207static 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 */
250static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, 247static 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 */
291static int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, 284static 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 }