1 /* 2 * 3 * Intel Management Engine Interface (Intel MEI) Linux driver 4 * Copyright (c) 2003-2012, Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 */ 16 17 18 #include <linux/export.h> 19 #include <linux/pci.h> 20 #include <linux/kthread.h> 21 #include <linux/interrupt.h> 22 #include <linux/fs.h> 23 #include <linux/jiffies.h> 24 25 #include <linux/mei.h> 26 27 #include "mei_dev.h" 28 #include "hbm.h" 29 #include "hw-me.h" 30 #include "client.h" 31 32 33 /** 34 * mei_irq_compl_handler - dispatch complete handelers 35 * for the completed callbacks 36 * 37 * @dev - mei device 38 * @compl_list - list of completed cbs 39 */ 40 void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *compl_list) 41 { 42 struct mei_cl_cb *cb, *next; 43 struct mei_cl *cl; 44 45 list_for_each_entry_safe(cb, next, &compl_list->list, list) { 46 cl = cb->cl; 47 list_del(&cb->list); 48 if (!cl) 49 continue; 50 51 dev_dbg(&dev->pdev->dev, "completing call back.\n"); 52 if (cl == &dev->iamthif_cl) 53 mei_amthif_complete(dev, cb); 54 else 55 mei_cl_complete(cl, cb); 56 } 57 } 58 EXPORT_SYMBOL_GPL(mei_irq_compl_handler); 59 60 /** 61 * mei_cl_hbm_equal - check if hbm is addressed to the client 62 * 63 * @cl: host client 64 * @mei_hdr: header of mei client message 65 * 66 * returns true if matches, false otherwise 67 */ 68 static inline int mei_cl_hbm_equal(struct mei_cl *cl, 69 struct mei_msg_hdr *mei_hdr) 70 { 71 return cl->host_client_id == mei_hdr->host_addr && 72 cl->me_client_id == mei_hdr->me_addr; 73 } 74 /** 75 * mei_cl_is_reading - checks if the client 76 is the one to read this message 77 * 78 * @cl: mei client 79 * @mei_hdr: header of mei message 80 * 81 * returns true on match and false otherwise 82 */ 83 static bool mei_cl_is_reading(struct mei_cl *cl, struct mei_msg_hdr *mei_hdr) 84 { 85 return mei_cl_hbm_equal(cl, mei_hdr) && 86 cl->state == MEI_FILE_CONNECTED && 87 cl->reading_state != MEI_READ_COMPLETE; 88 } 89 90 /** 91 * mei_irq_read_client_message - process client message 92 * 93 * @dev: the device structure 94 * @mei_hdr: header of mei client message 95 * @complete_list: An instance of our list structure 96 * 97 * returns 0 on success, <0 on failure. 98 */ 99 static int mei_cl_irq_read_msg(struct mei_device *dev, 100 struct mei_msg_hdr *mei_hdr, 101 struct mei_cl_cb *complete_list) 102 { 103 struct mei_cl *cl; 104 struct mei_cl_cb *cb, *next; 105 unsigned char *buffer = NULL; 106 107 list_for_each_entry_safe(cb, next, &dev->read_list.list, list) { 108 cl = cb->cl; 109 if (!cl || !mei_cl_is_reading(cl, mei_hdr)) 110 continue; 111 112 cl->reading_state = MEI_READING; 113 114 if (cb->response_buffer.size == 0 || 115 cb->response_buffer.data == NULL) { 116 dev_err(&dev->pdev->dev, "response buffer is not allocated.\n"); 117 list_del(&cb->list); 118 return -ENOMEM; 119 } 120 121 if (cb->response_buffer.size < mei_hdr->length + cb->buf_idx) { 122 dev_dbg(&dev->pdev->dev, "message overflow. size %d len %d idx %ld\n", 123 cb->response_buffer.size, 124 mei_hdr->length, cb->buf_idx); 125 buffer = krealloc(cb->response_buffer.data, 126 mei_hdr->length + cb->buf_idx, 127 GFP_KERNEL); 128 129 if (!buffer) { 130 dev_err(&dev->pdev->dev, "allocation failed.\n"); 131 list_del(&cb->list); 132 return -ENOMEM; 133 } 134 cb->response_buffer.data = buffer; 135 cb->response_buffer.size = 136 mei_hdr->length + cb->buf_idx; 137 } 138 139 buffer = cb->response_buffer.data + cb->buf_idx; 140 mei_read_slots(dev, buffer, mei_hdr->length); 141 142 cb->buf_idx += mei_hdr->length; 143 if (mei_hdr->msg_complete) { 144 cl->status = 0; 145 list_del(&cb->list); 146 dev_dbg(&dev->pdev->dev, "completed read H cl = %d, ME cl = %d, length = %lu\n", 147 cl->host_client_id, 148 cl->me_client_id, 149 cb->buf_idx); 150 list_add_tail(&cb->list, &complete_list->list); 151 } 152 break; 153 } 154 155 dev_dbg(&dev->pdev->dev, "message read\n"); 156 if (!buffer) { 157 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); 158 dev_dbg(&dev->pdev->dev, "discarding message " MEI_HDR_FMT "\n", 159 MEI_HDR_PRM(mei_hdr)); 160 } 161 162 return 0; 163 } 164 165 /** 166 * mei_cl_irq_close - processes close related operation from 167 * interrupt thread context - send disconnect request 168 * 169 * @cl: client 170 * @cb: callback block. 171 * @slots: free slots. 172 * @cmpl_list: complete list. 173 * 174 * returns 0, OK; otherwise, error. 175 */ 176 static int mei_cl_irq_close(struct mei_cl *cl, struct mei_cl_cb *cb, 177 s32 *slots, struct mei_cl_cb *cmpl_list) 178 { 179 struct mei_device *dev = cl->dev; 180 181 u32 msg_slots = 182 mei_data2slots(sizeof(struct hbm_client_connect_request)); 183 184 if (*slots < msg_slots) 185 return -EMSGSIZE; 186 187 *slots -= msg_slots; 188 189 if (mei_hbm_cl_disconnect_req(dev, cl)) { 190 cl->status = 0; 191 cb->buf_idx = 0; 192 list_move_tail(&cb->list, &cmpl_list->list); 193 return -EIO; 194 } 195 196 cl->state = MEI_FILE_DISCONNECTING; 197 cl->status = 0; 198 cb->buf_idx = 0; 199 list_move_tail(&cb->list, &dev->ctrl_rd_list.list); 200 cl->timer_count = MEI_CONNECT_TIMEOUT; 201 202 return 0; 203 } 204 205 206 /** 207 * mei_cl_irq_close - processes client read related operation from the 208 * interrupt thread context - request for flow control credits 209 * 210 * @cl: client 211 * @cb: callback block. 212 * @slots: free slots. 213 * @cmpl_list: complete list. 214 * 215 * returns 0, OK; otherwise, error. 216 */ 217 static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, 218 s32 *slots, struct mei_cl_cb *cmpl_list) 219 { 220 struct mei_device *dev = cl->dev; 221 222 u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control)); 223 224 if (*slots < msg_slots) { 225 /* return the cancel routine */ 226 list_del(&cb->list); 227 return -EMSGSIZE; 228 } 229 230 *slots -= msg_slots; 231 232 if (mei_hbm_cl_flow_control_req(dev, cl)) { 233 cl->status = -ENODEV; 234 cb->buf_idx = 0; 235 list_move_tail(&cb->list, &cmpl_list->list); 236 return -ENODEV; 237 } 238 list_move_tail(&cb->list, &dev->read_list.list); 239 240 return 0; 241 } 242 243 244 /** 245 * mei_cl_irq_ioctl - processes client ioctl related operation from the 246 * interrupt thread context - send connection request 247 * 248 * @cl: client 249 * @cb: callback block. 250 * @slots: free slots. 251 * @cmpl_list: complete list. 252 * 253 * returns 0, OK; otherwise, error. 254 */ 255 static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb, 256 s32 *slots, struct mei_cl_cb *cmpl_list) 257 { 258 struct mei_device *dev = cl->dev; 259 260 u32 msg_slots = 261 mei_data2slots(sizeof(struct hbm_client_connect_request)); 262 263 if (*slots < msg_slots) { 264 /* return the cancel routine */ 265 list_del(&cb->list); 266 return -EMSGSIZE; 267 } 268 269 *slots -= msg_slots; 270 271 cl->state = MEI_FILE_CONNECTING; 272 273 if (mei_hbm_cl_connect_req(dev, cl)) { 274 cl->status = -ENODEV; 275 cb->buf_idx = 0; 276 list_del(&cb->list); 277 return -ENODEV; 278 } 279 280 list_move_tail(&cb->list, &dev->ctrl_rd_list.list); 281 cl->timer_count = MEI_CONNECT_TIMEOUT; 282 return 0; 283 } 284 285 286 /** 287 * mei_irq_read_handler - bottom half read routine after ISR to 288 * handle the read processing. 289 * 290 * @dev: the device structure 291 * @cmpl_list: An instance of our list structure 292 * @slots: slots to read. 293 * 294 * returns 0 on success, <0 on failure. 295 */ 296 int mei_irq_read_handler(struct mei_device *dev, 297 struct mei_cl_cb *cmpl_list, s32 *slots) 298 { 299 struct mei_msg_hdr *mei_hdr; 300 struct mei_cl *cl_pos = NULL; 301 struct mei_cl *cl_next = NULL; 302 int ret = 0; 303 304 if (!dev->rd_msg_hdr) { 305 dev->rd_msg_hdr = mei_read_hdr(dev); 306 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); 307 (*slots)--; 308 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); 309 } 310 mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr; 311 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); 312 313 if (mei_hdr->reserved || !dev->rd_msg_hdr) { 314 dev_dbg(&dev->pdev->dev, "corrupted message header.\n"); 315 ret = -EBADMSG; 316 goto end; 317 } 318 319 if (mei_hdr->host_addr || mei_hdr->me_addr) { 320 list_for_each_entry_safe(cl_pos, cl_next, 321 &dev->file_list, link) { 322 dev_dbg(&dev->pdev->dev, 323 "list_for_each_entry_safe read host" 324 " client = %d, ME client = %d\n", 325 cl_pos->host_client_id, 326 cl_pos->me_client_id); 327 if (mei_cl_hbm_equal(cl_pos, mei_hdr)) 328 break; 329 } 330 331 if (&cl_pos->link == &dev->file_list) { 332 dev_dbg(&dev->pdev->dev, "corrupted message header\n"); 333 ret = -EBADMSG; 334 goto end; 335 } 336 } 337 if (((*slots) * sizeof(u32)) < mei_hdr->length) { 338 dev_err(&dev->pdev->dev, 339 "we can't read the message slots =%08x.\n", 340 *slots); 341 /* we can't read the message */ 342 ret = -ERANGE; 343 goto end; 344 } 345 346 /* decide where to read the message too */ 347 if (!mei_hdr->host_addr) { 348 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n"); 349 mei_hbm_dispatch(dev, mei_hdr); 350 dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n"); 351 } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && 352 (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && 353 (dev->iamthif_state == MEI_IAMTHIF_READING)) { 354 355 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); 356 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); 357 358 ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list); 359 if (ret) 360 goto end; 361 } else { 362 dev_dbg(&dev->pdev->dev, "call mei_cl_irq_read_msg.\n"); 363 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); 364 ret = mei_cl_irq_read_msg(dev, mei_hdr, cmpl_list); 365 if (ret) 366 goto end; 367 } 368 369 /* reset the number of slots and header */ 370 *slots = mei_count_full_read_slots(dev); 371 dev->rd_msg_hdr = 0; 372 373 if (*slots == -EOVERFLOW) { 374 /* overflow - reset */ 375 dev_err(&dev->pdev->dev, "resetting due to slots overflow.\n"); 376 /* set the event since message has been read */ 377 ret = -ERANGE; 378 goto end; 379 } 380 end: 381 return ret; 382 } 383 EXPORT_SYMBOL_GPL(mei_irq_read_handler); 384 385 386 /** 387 * mei_irq_write_handler - dispatch write requests 388 * after irq received 389 * 390 * @dev: the device structure 391 * @cmpl_list: An instance of our list structure 392 * 393 * returns 0 on success, <0 on failure. 394 */ 395 int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) 396 { 397 398 struct mei_cl *cl; 399 struct mei_cl_cb *cb, *next; 400 struct mei_cl_cb *list; 401 s32 slots; 402 int ret; 403 404 if (!mei_hbuf_is_ready(dev)) { 405 dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); 406 return 0; 407 } 408 slots = mei_hbuf_empty_slots(dev); 409 if (slots <= 0) 410 return -EMSGSIZE; 411 412 /* complete all waiting for write CB */ 413 dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n"); 414 415 list = &dev->write_waiting_list; 416 list_for_each_entry_safe(cb, next, &list->list, list) { 417 cl = cb->cl; 418 if (cl == NULL) 419 continue; 420 421 cl->status = 0; 422 list_del(&cb->list); 423 if (MEI_WRITING == cl->writing_state && 424 cb->fop_type == MEI_FOP_WRITE && 425 cl != &dev->iamthif_cl) { 426 dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n"); 427 cl->writing_state = MEI_WRITE_COMPLETE; 428 list_add_tail(&cb->list, &cmpl_list->list); 429 } 430 if (cl == &dev->iamthif_cl) { 431 dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n"); 432 if (dev->iamthif_flow_control_pending) { 433 ret = mei_amthif_irq_read(dev, &slots); 434 if (ret) 435 return ret; 436 } 437 } 438 } 439 440 if (dev->wd_state == MEI_WD_STOPPING) { 441 dev->wd_state = MEI_WD_IDLE; 442 wake_up_interruptible(&dev->wait_stop_wd); 443 } 444 445 if (dev->wr_ext_msg.hdr.length) { 446 mei_write_message(dev, &dev->wr_ext_msg.hdr, 447 dev->wr_ext_msg.data); 448 slots -= mei_data2slots(dev->wr_ext_msg.hdr.length); 449 dev->wr_ext_msg.hdr.length = 0; 450 } 451 if (dev->dev_state == MEI_DEV_ENABLED) { 452 if (dev->wd_pending && 453 mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) { 454 if (mei_wd_send(dev)) 455 dev_dbg(&dev->pdev->dev, "wd send failed.\n"); 456 else if (mei_cl_flow_ctrl_reduce(&dev->wd_cl)) 457 return -ENODEV; 458 459 dev->wd_pending = false; 460 461 if (dev->wd_state == MEI_WD_RUNNING) 462 slots -= mei_data2slots(MEI_WD_START_MSG_SIZE); 463 else 464 slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE); 465 } 466 } 467 468 /* complete control write list CB */ 469 dev_dbg(&dev->pdev->dev, "complete control write list cb.\n"); 470 list_for_each_entry_safe(cb, next, &dev->ctrl_wr_list.list, list) { 471 cl = cb->cl; 472 if (!cl) { 473 list_del(&cb->list); 474 return -ENODEV; 475 } 476 switch (cb->fop_type) { 477 case MEI_FOP_CLOSE: 478 /* send disconnect message */ 479 ret = mei_cl_irq_close(cl, cb, &slots, cmpl_list); 480 if (ret) 481 return ret; 482 483 break; 484 case MEI_FOP_READ: 485 /* send flow control message */ 486 ret = mei_cl_irq_read(cl, cb, &slots, cmpl_list); 487 if (ret) 488 return ret; 489 490 break; 491 case MEI_FOP_IOCTL: 492 /* connect message */ 493 if (mei_cl_is_other_connecting(cl)) 494 continue; 495 ret = mei_cl_irq_ioctl(cl, cb, &slots, cmpl_list); 496 if (ret) 497 return ret; 498 499 break; 500 501 default: 502 BUG(); 503 } 504 505 } 506 /* complete write list CB */ 507 dev_dbg(&dev->pdev->dev, "complete write list cb.\n"); 508 list_for_each_entry_safe(cb, next, &dev->write_list.list, list) { 509 cl = cb->cl; 510 if (cl == NULL) 511 continue; 512 if (mei_cl_flow_ctrl_creds(cl) <= 0) { 513 dev_dbg(&dev->pdev->dev, 514 "No flow control credentials for client %d, not sending.\n", 515 cl->host_client_id); 516 continue; 517 } 518 519 if (cl == &dev->iamthif_cl) 520 ret = mei_amthif_irq_write_complete(cl, cb, 521 &slots, cmpl_list); 522 else 523 ret = mei_cl_irq_write_complete(cl, cb, 524 &slots, cmpl_list); 525 if (ret) 526 return ret; 527 } 528 return 0; 529 } 530 EXPORT_SYMBOL_GPL(mei_irq_write_handler); 531 532 533 534 /** 535 * mei_timer - timer function. 536 * 537 * @work: pointer to the work_struct structure 538 * 539 * NOTE: This function is called by timer interrupt work 540 */ 541 void mei_timer(struct work_struct *work) 542 { 543 unsigned long timeout; 544 struct mei_cl *cl_pos = NULL; 545 struct mei_cl *cl_next = NULL; 546 struct mei_cl_cb *cb_pos = NULL; 547 struct mei_cl_cb *cb_next = NULL; 548 549 struct mei_device *dev = container_of(work, 550 struct mei_device, timer_work.work); 551 552 553 mutex_lock(&dev->device_lock); 554 if (dev->dev_state != MEI_DEV_ENABLED) { 555 if (dev->dev_state == MEI_DEV_INIT_CLIENTS) { 556 if (dev->init_clients_timer) { 557 if (--dev->init_clients_timer == 0) { 558 dev_err(&dev->pdev->dev, "reset: init clients timeout hbm_state = %d.\n", 559 dev->hbm_state); 560 mei_reset(dev, 1); 561 } 562 } 563 } 564 goto out; 565 } 566 /*** connect/disconnect timeouts ***/ 567 list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { 568 if (cl_pos->timer_count) { 569 if (--cl_pos->timer_count == 0) { 570 dev_err(&dev->pdev->dev, "reset: connect/disconnect timeout.\n"); 571 mei_reset(dev, 1); 572 goto out; 573 } 574 } 575 } 576 577 if (dev->iamthif_stall_timer) { 578 if (--dev->iamthif_stall_timer == 0) { 579 dev_err(&dev->pdev->dev, "reset: amthif hanged.\n"); 580 mei_reset(dev, 1); 581 dev->iamthif_msg_buf_size = 0; 582 dev->iamthif_msg_buf_index = 0; 583 dev->iamthif_canceled = false; 584 dev->iamthif_ioctl = true; 585 dev->iamthif_state = MEI_IAMTHIF_IDLE; 586 dev->iamthif_timer = 0; 587 588 mei_io_cb_free(dev->iamthif_current_cb); 589 dev->iamthif_current_cb = NULL; 590 591 dev->iamthif_file_object = NULL; 592 mei_amthif_run_next_cmd(dev); 593 } 594 } 595 596 if (dev->iamthif_timer) { 597 598 timeout = dev->iamthif_timer + 599 mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER); 600 601 dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", 602 dev->iamthif_timer); 603 dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout); 604 dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies); 605 if (time_after(jiffies, timeout)) { 606 /* 607 * User didn't read the AMTHI data on time (15sec) 608 * freeing AMTHI for other requests 609 */ 610 611 dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n"); 612 613 list_for_each_entry_safe(cb_pos, cb_next, 614 &dev->amthif_rd_complete_list.list, list) { 615 616 cl_pos = cb_pos->file_object->private_data; 617 618 /* Finding the AMTHI entry. */ 619 if (cl_pos == &dev->iamthif_cl) 620 list_del(&cb_pos->list); 621 } 622 mei_io_cb_free(dev->iamthif_current_cb); 623 dev->iamthif_current_cb = NULL; 624 625 dev->iamthif_file_object->private_data = NULL; 626 dev->iamthif_file_object = NULL; 627 dev->iamthif_timer = 0; 628 mei_amthif_run_next_cmd(dev); 629 630 } 631 } 632 out: 633 schedule_delayed_work(&dev->timer_work, 2 * HZ); 634 mutex_unlock(&dev->device_lock); 635 } 636 637