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/pci.h> 19 #include <linux/kthread.h> 20 #include <linux/interrupt.h> 21 #include <linux/fs.h> 22 #include <linux/jiffies.h> 23 24 #include "mei_dev.h" 25 #include <linux/mei.h> 26 #include "hw.h" 27 #include "interface.h" 28 29 30 /** 31 * mei_interrupt_quick_handler - The ISR of the MEI device 32 * 33 * @irq: The irq number 34 * @dev_id: pointer to the device structure 35 * 36 * returns irqreturn_t 37 */ 38 irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id) 39 { 40 struct mei_device *dev = (struct mei_device *) dev_id; 41 u32 csr_reg = mei_hcsr_read(dev); 42 43 if ((csr_reg & H_IS) != H_IS) 44 return IRQ_NONE; 45 46 /* clear H_IS bit in H_CSR */ 47 mei_reg_write(dev, H_CSR, csr_reg); 48 49 return IRQ_WAKE_THREAD; 50 } 51 52 /** 53 * _mei_cmpl - processes completed operation. 54 * 55 * @cl: private data of the file object. 56 * @cb_pos: callback block. 57 */ 58 static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos) 59 { 60 if (cb_pos->fop_type == MEI_FOP_WRITE) { 61 mei_io_cb_free(cb_pos); 62 cb_pos = NULL; 63 cl->writing_state = MEI_WRITE_COMPLETE; 64 if (waitqueue_active(&cl->tx_wait)) 65 wake_up_interruptible(&cl->tx_wait); 66 67 } else if (cb_pos->fop_type == MEI_FOP_READ && 68 MEI_READING == cl->reading_state) { 69 cl->reading_state = MEI_READ_COMPLETE; 70 if (waitqueue_active(&cl->rx_wait)) 71 wake_up_interruptible(&cl->rx_wait); 72 73 } 74 } 75 76 /** 77 * _mei_irq_thread_state_ok - checks if mei header matches file private data 78 * 79 * @cl: private data of the file object 80 * @mei_hdr: header of mei client message 81 * 82 * returns !=0 if matches, 0 if no match. 83 */ 84 static int _mei_irq_thread_state_ok(struct mei_cl *cl, 85 struct mei_msg_hdr *mei_hdr) 86 { 87 return (cl->host_client_id == mei_hdr->host_addr && 88 cl->me_client_id == mei_hdr->me_addr && 89 cl->state == MEI_FILE_CONNECTED && 90 MEI_READ_COMPLETE != cl->reading_state); 91 } 92 93 /** 94 * mei_irq_thread_read_client_message - bottom half read routine after ISR to 95 * handle the read mei client message data processing. 96 * 97 * @complete_list: An instance of our list structure 98 * @dev: the device structure 99 * @mei_hdr: header of mei client message 100 * 101 * returns 0 on success, <0 on failure. 102 */ 103 static int mei_irq_thread_read_client_message(struct mei_cl_cb *complete_list, 104 struct mei_device *dev, 105 struct mei_msg_hdr *mei_hdr) 106 { 107 struct mei_cl *cl; 108 struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; 109 unsigned char *buffer = NULL; 110 111 dev_dbg(&dev->pdev->dev, "start client msg\n"); 112 if (list_empty(&dev->read_list.list)) 113 goto quit; 114 115 list_for_each_entry_safe(cb_pos, cb_next, &dev->read_list.list, list) { 116 cl = cb_pos->cl; 117 if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) { 118 cl->reading_state = MEI_READING; 119 buffer = cb_pos->response_buffer.data + cb_pos->buf_idx; 120 121 if (cb_pos->response_buffer.size < 122 mei_hdr->length + cb_pos->buf_idx) { 123 dev_dbg(&dev->pdev->dev, "message overflow.\n"); 124 list_del(&cb_pos->list); 125 return -ENOMEM; 126 } 127 if (buffer) 128 mei_read_slots(dev, buffer, mei_hdr->length); 129 130 cb_pos->buf_idx += mei_hdr->length; 131 if (mei_hdr->msg_complete) { 132 cl->status = 0; 133 list_del(&cb_pos->list); 134 dev_dbg(&dev->pdev->dev, 135 "completed read H cl = %d, ME cl = %d, length = %lu\n", 136 cl->host_client_id, 137 cl->me_client_id, 138 cb_pos->buf_idx); 139 140 list_add_tail(&cb_pos->list, 141 &complete_list->list); 142 } 143 144 break; 145 } 146 147 } 148 149 quit: 150 dev_dbg(&dev->pdev->dev, "message read\n"); 151 if (!buffer) { 152 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); 153 dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n", 154 *(u32 *) dev->rd_msg_buf); 155 } 156 157 return 0; 158 } 159 160 /** 161 * _mei_irq_thread_close - processes close related operation. 162 * 163 * @dev: the device structure. 164 * @slots: free slots. 165 * @cb_pos: callback block. 166 * @cl: private data of the file object. 167 * @cmpl_list: complete list. 168 * 169 * returns 0, OK; otherwise, error. 170 */ 171 static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, 172 struct mei_cl_cb *cb_pos, 173 struct mei_cl *cl, 174 struct mei_cl_cb *cmpl_list) 175 { 176 if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + 177 sizeof(struct hbm_client_connect_request))) 178 return -EBADMSG; 179 180 *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); 181 182 if (mei_disconnect(dev, cl)) { 183 cl->status = 0; 184 cb_pos->buf_idx = 0; 185 list_move_tail(&cb_pos->list, &cmpl_list->list); 186 return -EMSGSIZE; 187 } else { 188 cl->state = MEI_FILE_DISCONNECTING; 189 cl->status = 0; 190 cb_pos->buf_idx = 0; 191 list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list); 192 cl->timer_count = MEI_CONNECT_TIMEOUT; 193 } 194 195 return 0; 196 } 197 198 /** 199 * is_treat_specially_client - checks if the message belongs 200 * to the file private data. 201 * 202 * @cl: private data of the file object 203 * @rs: connect response bus message 204 * 205 */ 206 static bool is_treat_specially_client(struct mei_cl *cl, 207 struct hbm_client_connect_response *rs) 208 { 209 210 if (cl->host_client_id == rs->host_addr && 211 cl->me_client_id == rs->me_addr) { 212 if (!rs->status) { 213 cl->state = MEI_FILE_CONNECTED; 214 cl->status = 0; 215 216 } else { 217 cl->state = MEI_FILE_DISCONNECTED; 218 cl->status = -ENODEV; 219 } 220 cl->timer_count = 0; 221 222 return true; 223 } 224 return false; 225 } 226 227 /** 228 * mei_client_connect_response - connects to response irq routine 229 * 230 * @dev: the device structure 231 * @rs: connect response bus message 232 */ 233 static void mei_client_connect_response(struct mei_device *dev, 234 struct hbm_client_connect_response *rs) 235 { 236 237 struct mei_cl *cl; 238 struct mei_cl_cb *pos = NULL, *next = NULL; 239 240 dev_dbg(&dev->pdev->dev, 241 "connect_response:\n" 242 "ME Client = %d\n" 243 "Host Client = %d\n" 244 "Status = %d\n", 245 rs->me_addr, 246 rs->host_addr, 247 rs->status); 248 249 /* if WD or iamthif client treat specially */ 250 251 if (is_treat_specially_client(&(dev->wd_cl), rs)) { 252 dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n"); 253 mei_watchdog_register(dev); 254 255 return; 256 } 257 258 if (is_treat_specially_client(&(dev->iamthif_cl), rs)) { 259 dev->iamthif_state = MEI_IAMTHIF_IDLE; 260 return; 261 } 262 list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) { 263 264 cl = pos->cl; 265 if (!cl) { 266 list_del(&pos->list); 267 return; 268 } 269 if (pos->fop_type == MEI_FOP_IOCTL) { 270 if (is_treat_specially_client(cl, rs)) { 271 list_del(&pos->list); 272 cl->status = 0; 273 cl->timer_count = 0; 274 break; 275 } 276 } 277 } 278 } 279 280 /** 281 * mei_client_disconnect_response - disconnects from response irq routine 282 * 283 * @dev: the device structure 284 * @rs: disconnect response bus message 285 */ 286 static void mei_client_disconnect_response(struct mei_device *dev, 287 struct hbm_client_connect_response *rs) 288 { 289 struct mei_cl *cl; 290 struct mei_cl_cb *pos = NULL, *next = NULL; 291 292 dev_dbg(&dev->pdev->dev, 293 "disconnect_response:\n" 294 "ME Client = %d\n" 295 "Host Client = %d\n" 296 "Status = %d\n", 297 rs->me_addr, 298 rs->host_addr, 299 rs->status); 300 301 list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) { 302 cl = pos->cl; 303 304 if (!cl) { 305 list_del(&pos->list); 306 return; 307 } 308 309 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n"); 310 if (cl->host_client_id == rs->host_addr && 311 cl->me_client_id == rs->me_addr) { 312 313 list_del(&pos->list); 314 if (!rs->status) 315 cl->state = MEI_FILE_DISCONNECTED; 316 317 cl->status = 0; 318 cl->timer_count = 0; 319 break; 320 } 321 } 322 } 323 324 /** 325 * same_flow_addr - tells if they have the same address. 326 * 327 * @file: private data of the file object. 328 * @flow: flow control. 329 * 330 * returns !=0, same; 0,not. 331 */ 332 static int same_flow_addr(struct mei_cl *cl, struct hbm_flow_control *flow) 333 { 334 return (cl->host_client_id == flow->host_addr && 335 cl->me_client_id == flow->me_addr); 336 } 337 338 /** 339 * add_single_flow_creds - adds single buffer credentials. 340 * 341 * @file: private data ot the file object. 342 * @flow: flow control. 343 */ 344 static void add_single_flow_creds(struct mei_device *dev, 345 struct hbm_flow_control *flow) 346 { 347 struct mei_me_client *client; 348 int i; 349 350 for (i = 0; i < dev->me_clients_num; i++) { 351 client = &dev->me_clients[i]; 352 if (client && flow->me_addr == client->client_id) { 353 if (client->props.single_recv_buf) { 354 client->mei_flow_ctrl_creds++; 355 dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n", 356 flow->me_addr); 357 dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n", 358 client->mei_flow_ctrl_creds); 359 } else { 360 BUG(); /* error in flow control */ 361 } 362 } 363 } 364 } 365 366 /** 367 * mei_client_flow_control_response - flow control response irq routine 368 * 369 * @dev: the device structure 370 * @flow_control: flow control response bus message 371 */ 372 static void mei_client_flow_control_response(struct mei_device *dev, 373 struct hbm_flow_control *flow_control) 374 { 375 struct mei_cl *cl_pos = NULL; 376 struct mei_cl *cl_next = NULL; 377 378 if (!flow_control->host_addr) { 379 /* single receive buffer */ 380 add_single_flow_creds(dev, flow_control); 381 } else { 382 /* normal connection */ 383 list_for_each_entry_safe(cl_pos, cl_next, 384 &dev->file_list, link) { 385 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in file_list\n"); 386 387 dev_dbg(&dev->pdev->dev, "cl of host client %d ME client %d.\n", 388 cl_pos->host_client_id, 389 cl_pos->me_client_id); 390 dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n", 391 flow_control->host_addr, 392 flow_control->me_addr); 393 if (same_flow_addr(cl_pos, flow_control)) { 394 dev_dbg(&dev->pdev->dev, "recv ctrl msg for host %d ME %d.\n", 395 flow_control->host_addr, 396 flow_control->me_addr); 397 cl_pos->mei_flow_ctrl_creds++; 398 dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n", 399 cl_pos->mei_flow_ctrl_creds); 400 break; 401 } 402 } 403 } 404 } 405 406 /** 407 * same_disconn_addr - tells if they have the same address 408 * 409 * @file: private data of the file object. 410 * @disconn: disconnection request. 411 * 412 * returns !=0, same; 0,not. 413 */ 414 static int same_disconn_addr(struct mei_cl *cl, 415 struct hbm_client_connect_request *req) 416 { 417 return (cl->host_client_id == req->host_addr && 418 cl->me_client_id == req->me_addr); 419 } 420 421 /** 422 * mei_client_disconnect_request - disconnects from request irq routine 423 * 424 * @dev: the device structure. 425 * @disconnect_req: disconnect request bus message. 426 */ 427 static void mei_client_disconnect_request(struct mei_device *dev, 428 struct hbm_client_connect_request *disconnect_req) 429 { 430 struct hbm_client_connect_response *disconnect_res; 431 struct mei_cl *pos, *next; 432 const size_t len = sizeof(struct hbm_client_connect_response); 433 434 list_for_each_entry_safe(pos, next, &dev->file_list, link) { 435 if (same_disconn_addr(pos, disconnect_req)) { 436 dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n", 437 disconnect_req->host_addr, 438 disconnect_req->me_addr); 439 pos->state = MEI_FILE_DISCONNECTED; 440 pos->timer_count = 0; 441 if (pos == &dev->wd_cl) 442 dev->wd_pending = false; 443 else if (pos == &dev->iamthif_cl) 444 dev->iamthif_timer = 0; 445 446 /* prepare disconnect response */ 447 (void)mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len); 448 disconnect_res = 449 (struct hbm_client_connect_response *) 450 &dev->wr_ext_msg.data; 451 disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD; 452 disconnect_res->host_addr = pos->host_client_id; 453 disconnect_res->me_addr = pos->me_client_id; 454 disconnect_res->status = 0; 455 break; 456 } 457 } 458 } 459 460 /** 461 * mei_irq_thread_read_bus_message - bottom half read routine after ISR to 462 * handle the read bus message cmd processing. 463 * 464 * @dev: the device structure 465 * @mei_hdr: header of bus message 466 */ 467 static void mei_irq_thread_read_bus_message(struct mei_device *dev, 468 struct mei_msg_hdr *mei_hdr) 469 { 470 struct mei_bus_message *mei_msg; 471 struct mei_me_client *me_client; 472 struct hbm_host_version_response *version_res; 473 struct hbm_client_connect_response *connect_res; 474 struct hbm_client_connect_response *disconnect_res; 475 struct hbm_client_connect_request *disconnect_req; 476 struct hbm_flow_control *flow_control; 477 struct hbm_props_response *props_res; 478 struct hbm_host_enum_response *enum_res; 479 struct hbm_host_stop_request *stop_req; 480 481 /* read the message to our buffer */ 482 BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf)); 483 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); 484 mei_msg = (struct mei_bus_message *)dev->rd_msg_buf; 485 486 switch (mei_msg->hbm_cmd) { 487 case HOST_START_RES_CMD: 488 version_res = (struct hbm_host_version_response *) mei_msg; 489 if (version_res->host_version_supported) { 490 dev->version.major_version = HBM_MAJOR_VERSION; 491 dev->version.minor_version = HBM_MINOR_VERSION; 492 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 493 dev->init_clients_state == MEI_START_MESSAGE) { 494 dev->init_clients_timer = 0; 495 mei_host_enum_clients_message(dev); 496 } else { 497 dev->recvd_msg = false; 498 dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n"); 499 mei_reset(dev, 1); 500 return; 501 } 502 } else { 503 u32 *buf = dev->wr_msg_buf; 504 const size_t len = sizeof(struct hbm_host_stop_request); 505 506 dev->version = version_res->me_max_version; 507 508 /* send stop message */ 509 mei_hdr = mei_hbm_hdr(&buf[0], len); 510 stop_req = (struct hbm_host_stop_request *)&buf[1]; 511 memset(stop_req, 0, len); 512 stop_req->hbm_cmd = HOST_STOP_REQ_CMD; 513 stop_req->reason = DRIVER_STOP_REQUEST; 514 515 mei_write_message(dev, mei_hdr, 516 (unsigned char *)stop_req, len); 517 dev_dbg(&dev->pdev->dev, "version mismatch.\n"); 518 return; 519 } 520 521 dev->recvd_msg = true; 522 dev_dbg(&dev->pdev->dev, "host start response message received.\n"); 523 break; 524 525 case CLIENT_CONNECT_RES_CMD: 526 connect_res = (struct hbm_client_connect_response *) mei_msg; 527 mei_client_connect_response(dev, connect_res); 528 dev_dbg(&dev->pdev->dev, "client connect response message received.\n"); 529 wake_up(&dev->wait_recvd_msg); 530 break; 531 532 case CLIENT_DISCONNECT_RES_CMD: 533 disconnect_res = (struct hbm_client_connect_response *) mei_msg; 534 mei_client_disconnect_response(dev, disconnect_res); 535 dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n"); 536 wake_up(&dev->wait_recvd_msg); 537 break; 538 539 case MEI_FLOW_CONTROL_CMD: 540 flow_control = (struct hbm_flow_control *) mei_msg; 541 mei_client_flow_control_response(dev, flow_control); 542 dev_dbg(&dev->pdev->dev, "client flow control response message received.\n"); 543 break; 544 545 case HOST_CLIENT_PROPERTIES_RES_CMD: 546 props_res = (struct hbm_props_response *)mei_msg; 547 me_client = &dev->me_clients[dev->me_client_presentation_num]; 548 549 if (props_res->status || !dev->me_clients) { 550 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n"); 551 mei_reset(dev, 1); 552 return; 553 } 554 555 if (me_client->client_id != props_res->address) { 556 dev_err(&dev->pdev->dev, 557 "Host client properties reply mismatch\n"); 558 mei_reset(dev, 1); 559 560 return; 561 } 562 563 if (dev->dev_state != MEI_DEV_INIT_CLIENTS || 564 dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) { 565 dev_err(&dev->pdev->dev, 566 "Unexpected client properties reply\n"); 567 mei_reset(dev, 1); 568 569 return; 570 } 571 572 me_client->props = props_res->client_properties; 573 dev->me_client_index++; 574 dev->me_client_presentation_num++; 575 576 mei_host_client_enumerate(dev); 577 578 break; 579 580 case HOST_ENUM_RES_CMD: 581 enum_res = (struct hbm_host_enum_response *) mei_msg; 582 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); 583 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 584 dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) { 585 dev->init_clients_timer = 0; 586 dev->me_client_presentation_num = 0; 587 dev->me_client_index = 0; 588 mei_allocate_me_clients_storage(dev); 589 dev->init_clients_state = 590 MEI_CLIENT_PROPERTIES_MESSAGE; 591 592 mei_host_client_enumerate(dev); 593 } else { 594 dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n"); 595 mei_reset(dev, 1); 596 return; 597 } 598 break; 599 600 case HOST_STOP_RES_CMD: 601 dev->dev_state = MEI_DEV_DISABLED; 602 dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n"); 603 mei_reset(dev, 1); 604 break; 605 606 case CLIENT_DISCONNECT_REQ_CMD: 607 /* search for client */ 608 disconnect_req = (struct hbm_client_connect_request *)mei_msg; 609 mei_client_disconnect_request(dev, disconnect_req); 610 break; 611 612 case ME_STOP_REQ_CMD: 613 { 614 /* prepare stop request: sent in next interrupt event */ 615 616 const size_t len = sizeof(struct hbm_host_stop_request); 617 618 mei_hdr = mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len); 619 stop_req = (struct hbm_host_stop_request *)&dev->wr_ext_msg.data; 620 memset(stop_req, 0, len); 621 stop_req->hbm_cmd = HOST_STOP_REQ_CMD; 622 stop_req->reason = DRIVER_STOP_REQUEST; 623 break; 624 } 625 default: 626 BUG(); 627 break; 628 629 } 630 } 631 632 633 /** 634 * _mei_hb_read - processes read related operation. 635 * 636 * @dev: the device structure. 637 * @slots: free slots. 638 * @cb_pos: callback block. 639 * @cl: private data of the file object. 640 * @cmpl_list: complete list. 641 * 642 * returns 0, OK; otherwise, error. 643 */ 644 static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, 645 struct mei_cl_cb *cb_pos, 646 struct mei_cl *cl, 647 struct mei_cl_cb *cmpl_list) 648 { 649 if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + 650 sizeof(struct hbm_flow_control))) { 651 /* return the cancel routine */ 652 list_del(&cb_pos->list); 653 return -EBADMSG; 654 } 655 656 *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); 657 658 if (mei_send_flow_control(dev, cl)) { 659 cl->status = -ENODEV; 660 cb_pos->buf_idx = 0; 661 list_move_tail(&cb_pos->list, &cmpl_list->list); 662 return -ENODEV; 663 } 664 list_move_tail(&cb_pos->list, &dev->read_list.list); 665 666 return 0; 667 } 668 669 670 /** 671 * _mei_irq_thread_ioctl - processes ioctl related operation. 672 * 673 * @dev: the device structure. 674 * @slots: free slots. 675 * @cb_pos: callback block. 676 * @cl: private data of the file object. 677 * @cmpl_list: complete list. 678 * 679 * returns 0, OK; otherwise, error. 680 */ 681 static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, 682 struct mei_cl_cb *cb_pos, 683 struct mei_cl *cl, 684 struct mei_cl_cb *cmpl_list) 685 { 686 if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + 687 sizeof(struct hbm_client_connect_request))) { 688 /* return the cancel routine */ 689 list_del(&cb_pos->list); 690 return -EBADMSG; 691 } 692 693 cl->state = MEI_FILE_CONNECTING; 694 *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); 695 if (mei_connect(dev, cl)) { 696 cl->status = -ENODEV; 697 cb_pos->buf_idx = 0; 698 list_del(&cb_pos->list); 699 return -ENODEV; 700 } else { 701 list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list); 702 cl->timer_count = MEI_CONNECT_TIMEOUT; 703 } 704 return 0; 705 } 706 707 /** 708 * mei_irq_thread_write_complete - write messages to device. 709 * 710 * @dev: the device structure. 711 * @slots: free slots. 712 * @cb: callback block. 713 * @cmpl_list: complete list. 714 * 715 * returns 0, OK; otherwise, error. 716 */ 717 static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots, 718 struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) 719 { 720 struct mei_msg_hdr *mei_hdr; 721 struct mei_cl *cl = cb->cl; 722 size_t len = cb->request_buffer.size - cb->buf_idx; 723 size_t msg_slots = mei_data2slots(len); 724 725 mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; 726 mei_hdr->host_addr = cl->host_client_id; 727 mei_hdr->me_addr = cl->me_client_id; 728 mei_hdr->reserved = 0; 729 730 if (*slots >= msg_slots) { 731 mei_hdr->length = len; 732 mei_hdr->msg_complete = 1; 733 /* Split the message only if we can write the whole host buffer */ 734 } else if (*slots == dev->hbuf_depth) { 735 msg_slots = *slots; 736 len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); 737 mei_hdr->length = len; 738 mei_hdr->msg_complete = 0; 739 } else { 740 /* wait for next time the host buffer is empty */ 741 return 0; 742 } 743 744 dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n", 745 cb->request_buffer.size, cb->buf_idx); 746 dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n", 747 mei_hdr->length, mei_hdr->msg_complete); 748 749 *slots -= msg_slots; 750 if (mei_write_message(dev, mei_hdr, 751 cb->request_buffer.data + cb->buf_idx, len)) { 752 cl->status = -ENODEV; 753 list_move_tail(&cb->list, &cmpl_list->list); 754 return -ENODEV; 755 } 756 757 if (mei_flow_ctrl_reduce(dev, cl)) 758 return -ENODEV; 759 760 cl->status = 0; 761 cb->buf_idx += mei_hdr->length; 762 if (mei_hdr->msg_complete) 763 list_move_tail(&cb->list, &dev->write_waiting_list.list); 764 765 return 0; 766 } 767 768 /** 769 * mei_irq_thread_read_handler - bottom half read routine after ISR to 770 * handle the read processing. 771 * 772 * @cmpl_list: An instance of our list structure 773 * @dev: the device structure 774 * @slots: slots to read. 775 * 776 * returns 0 on success, <0 on failure. 777 */ 778 static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list, 779 struct mei_device *dev, 780 s32 *slots) 781 { 782 struct mei_msg_hdr *mei_hdr; 783 struct mei_cl *cl_pos = NULL; 784 struct mei_cl *cl_next = NULL; 785 int ret = 0; 786 787 if (!dev->rd_msg_hdr) { 788 dev->rd_msg_hdr = mei_mecbrw_read(dev); 789 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); 790 (*slots)--; 791 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); 792 } 793 mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr; 794 dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length); 795 796 if (mei_hdr->reserved || !dev->rd_msg_hdr) { 797 dev_dbg(&dev->pdev->dev, "corrupted message header.\n"); 798 ret = -EBADMSG; 799 goto end; 800 } 801 802 if (mei_hdr->host_addr || mei_hdr->me_addr) { 803 list_for_each_entry_safe(cl_pos, cl_next, 804 &dev->file_list, link) { 805 dev_dbg(&dev->pdev->dev, 806 "list_for_each_entry_safe read host" 807 " client = %d, ME client = %d\n", 808 cl_pos->host_client_id, 809 cl_pos->me_client_id); 810 if (cl_pos->host_client_id == mei_hdr->host_addr && 811 cl_pos->me_client_id == mei_hdr->me_addr) 812 break; 813 } 814 815 if (&cl_pos->link == &dev->file_list) { 816 dev_dbg(&dev->pdev->dev, "corrupted message header\n"); 817 ret = -EBADMSG; 818 goto end; 819 } 820 } 821 if (((*slots) * sizeof(u32)) < mei_hdr->length) { 822 dev_dbg(&dev->pdev->dev, 823 "we can't read the message slots =%08x.\n", 824 *slots); 825 /* we can't read the message */ 826 ret = -ERANGE; 827 goto end; 828 } 829 830 /* decide where to read the message too */ 831 if (!mei_hdr->host_addr) { 832 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n"); 833 mei_irq_thread_read_bus_message(dev, mei_hdr); 834 dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n"); 835 } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && 836 (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && 837 (dev->iamthif_state == MEI_IAMTHIF_READING)) { 838 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); 839 dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", 840 mei_hdr->length); 841 842 ret = mei_amthif_irq_read_message(cmpl_list, dev, mei_hdr); 843 if (ret) 844 goto end; 845 846 } else { 847 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n"); 848 ret = mei_irq_thread_read_client_message(cmpl_list, 849 dev, mei_hdr); 850 if (ret) 851 goto end; 852 853 } 854 855 /* reset the number of slots and header */ 856 *slots = mei_count_full_read_slots(dev); 857 dev->rd_msg_hdr = 0; 858 859 if (*slots == -EOVERFLOW) { 860 /* overflow - reset */ 861 dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n"); 862 /* set the event since message has been read */ 863 ret = -ERANGE; 864 goto end; 865 } 866 end: 867 return ret; 868 } 869 870 871 /** 872 * mei_irq_thread_write_handler - bottom half write routine after 873 * ISR to handle the write processing. 874 * 875 * @dev: the device structure 876 * @cmpl_list: An instance of our list structure 877 * 878 * returns 0 on success, <0 on failure. 879 */ 880 static int mei_irq_thread_write_handler(struct mei_device *dev, 881 struct mei_cl_cb *cmpl_list) 882 { 883 884 struct mei_cl *cl; 885 struct mei_cl_cb *pos = NULL, *next = NULL; 886 struct mei_cl_cb *list; 887 s32 slots; 888 int ret; 889 890 if (!mei_hbuf_is_empty(dev)) { 891 dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); 892 return 0; 893 } 894 slots = mei_hbuf_empty_slots(dev); 895 if (slots <= 0) 896 return -EMSGSIZE; 897 898 /* complete all waiting for write CB */ 899 dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n"); 900 901 list = &dev->write_waiting_list; 902 list_for_each_entry_safe(pos, next, &list->list, list) { 903 cl = pos->cl; 904 if (cl == NULL) 905 continue; 906 907 cl->status = 0; 908 list_del(&pos->list); 909 if (MEI_WRITING == cl->writing_state && 910 pos->fop_type == MEI_FOP_WRITE && 911 cl != &dev->iamthif_cl) { 912 dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n"); 913 cl->writing_state = MEI_WRITE_COMPLETE; 914 list_add_tail(&pos->list, &cmpl_list->list); 915 } 916 if (cl == &dev->iamthif_cl) { 917 dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n"); 918 if (dev->iamthif_flow_control_pending) { 919 ret = mei_amthif_irq_read(dev, &slots); 920 if (ret) 921 return ret; 922 } 923 } 924 } 925 926 if (dev->wd_state == MEI_WD_STOPPING) { 927 dev->wd_state = MEI_WD_IDLE; 928 wake_up_interruptible(&dev->wait_stop_wd); 929 } 930 931 if (dev->wr_ext_msg.hdr.length) { 932 mei_write_message(dev, &dev->wr_ext_msg.hdr, 933 dev->wr_ext_msg.data, dev->wr_ext_msg.hdr.length); 934 slots -= mei_data2slots(dev->wr_ext_msg.hdr.length); 935 dev->wr_ext_msg.hdr.length = 0; 936 } 937 if (dev->dev_state == MEI_DEV_ENABLED) { 938 if (dev->wd_pending && 939 mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { 940 if (mei_wd_send(dev)) 941 dev_dbg(&dev->pdev->dev, "wd send failed.\n"); 942 else if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) 943 return -ENODEV; 944 945 dev->wd_pending = false; 946 947 if (dev->wd_state == MEI_WD_RUNNING) 948 slots -= mei_data2slots(MEI_WD_START_MSG_SIZE); 949 else 950 slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE); 951 } 952 } 953 954 /* complete control write list CB */ 955 dev_dbg(&dev->pdev->dev, "complete control write list cb.\n"); 956 list_for_each_entry_safe(pos, next, &dev->ctrl_wr_list.list, list) { 957 cl = pos->cl; 958 if (!cl) { 959 list_del(&pos->list); 960 return -ENODEV; 961 } 962 switch (pos->fop_type) { 963 case MEI_FOP_CLOSE: 964 /* send disconnect message */ 965 ret = _mei_irq_thread_close(dev, &slots, pos, 966 cl, cmpl_list); 967 if (ret) 968 return ret; 969 970 break; 971 case MEI_FOP_READ: 972 /* send flow control message */ 973 ret = _mei_irq_thread_read(dev, &slots, pos, 974 cl, cmpl_list); 975 if (ret) 976 return ret; 977 978 break; 979 case MEI_FOP_IOCTL: 980 /* connect message */ 981 if (mei_other_client_is_connecting(dev, cl)) 982 continue; 983 ret = _mei_irq_thread_ioctl(dev, &slots, pos, 984 cl, cmpl_list); 985 if (ret) 986 return ret; 987 988 break; 989 990 default: 991 BUG(); 992 } 993 994 } 995 /* complete write list CB */ 996 dev_dbg(&dev->pdev->dev, "complete write list cb.\n"); 997 list_for_each_entry_safe(pos, next, &dev->write_list.list, list) { 998 cl = pos->cl; 999 if (cl == NULL) 1000 continue; 1001 if (mei_flow_ctrl_creds(dev, cl) <= 0) { 1002 dev_dbg(&dev->pdev->dev, 1003 "No flow control credentials for client %d, not sending.\n", 1004 cl->host_client_id); 1005 continue; 1006 } 1007 1008 if (cl == &dev->iamthif_cl) 1009 ret = mei_amthif_irq_write_complete(dev, &slots, 1010 pos, cmpl_list); 1011 else 1012 ret = mei_irq_thread_write_complete(dev, &slots, pos, 1013 cmpl_list); 1014 if (ret) 1015 return ret; 1016 1017 } 1018 return 0; 1019 } 1020 1021 1022 1023 /** 1024 * mei_timer - timer function. 1025 * 1026 * @work: pointer to the work_struct structure 1027 * 1028 * NOTE: This function is called by timer interrupt work 1029 */ 1030 void mei_timer(struct work_struct *work) 1031 { 1032 unsigned long timeout; 1033 struct mei_cl *cl_pos = NULL; 1034 struct mei_cl *cl_next = NULL; 1035 struct mei_cl_cb *cb_pos = NULL; 1036 struct mei_cl_cb *cb_next = NULL; 1037 1038 struct mei_device *dev = container_of(work, 1039 struct mei_device, timer_work.work); 1040 1041 1042 mutex_lock(&dev->device_lock); 1043 if (dev->dev_state != MEI_DEV_ENABLED) { 1044 if (dev->dev_state == MEI_DEV_INIT_CLIENTS) { 1045 if (dev->init_clients_timer) { 1046 if (--dev->init_clients_timer == 0) { 1047 dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n", 1048 dev->init_clients_state); 1049 mei_reset(dev, 1); 1050 } 1051 } 1052 } 1053 goto out; 1054 } 1055 /*** connect/disconnect timeouts ***/ 1056 list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { 1057 if (cl_pos->timer_count) { 1058 if (--cl_pos->timer_count == 0) { 1059 dev_dbg(&dev->pdev->dev, "HECI reset due to connect/disconnect timeout.\n"); 1060 mei_reset(dev, 1); 1061 goto out; 1062 } 1063 } 1064 } 1065 1066 if (dev->iamthif_stall_timer) { 1067 if (--dev->iamthif_stall_timer == 0) { 1068 dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n"); 1069 mei_reset(dev, 1); 1070 dev->iamthif_msg_buf_size = 0; 1071 dev->iamthif_msg_buf_index = 0; 1072 dev->iamthif_canceled = false; 1073 dev->iamthif_ioctl = true; 1074 dev->iamthif_state = MEI_IAMTHIF_IDLE; 1075 dev->iamthif_timer = 0; 1076 1077 mei_io_cb_free(dev->iamthif_current_cb); 1078 dev->iamthif_current_cb = NULL; 1079 1080 dev->iamthif_file_object = NULL; 1081 mei_amthif_run_next_cmd(dev); 1082 } 1083 } 1084 1085 if (dev->iamthif_timer) { 1086 1087 timeout = dev->iamthif_timer + 1088 mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER); 1089 1090 dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", 1091 dev->iamthif_timer); 1092 dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout); 1093 dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies); 1094 if (time_after(jiffies, timeout)) { 1095 /* 1096 * User didn't read the AMTHI data on time (15sec) 1097 * freeing AMTHI for other requests 1098 */ 1099 1100 dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n"); 1101 1102 list_for_each_entry_safe(cb_pos, cb_next, 1103 &dev->amthif_rd_complete_list.list, list) { 1104 1105 cl_pos = cb_pos->file_object->private_data; 1106 1107 /* Finding the AMTHI entry. */ 1108 if (cl_pos == &dev->iamthif_cl) 1109 list_del(&cb_pos->list); 1110 } 1111 mei_io_cb_free(dev->iamthif_current_cb); 1112 dev->iamthif_current_cb = NULL; 1113 1114 dev->iamthif_file_object->private_data = NULL; 1115 dev->iamthif_file_object = NULL; 1116 dev->iamthif_timer = 0; 1117 mei_amthif_run_next_cmd(dev); 1118 1119 } 1120 } 1121 out: 1122 schedule_delayed_work(&dev->timer_work, 2 * HZ); 1123 mutex_unlock(&dev->device_lock); 1124 } 1125 1126 /** 1127 * mei_interrupt_thread_handler - function called after ISR to handle the interrupt 1128 * processing. 1129 * 1130 * @irq: The irq number 1131 * @dev_id: pointer to the device structure 1132 * 1133 * returns irqreturn_t 1134 * 1135 */ 1136 irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) 1137 { 1138 struct mei_device *dev = (struct mei_device *) dev_id; 1139 struct mei_cl_cb complete_list; 1140 struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; 1141 struct mei_cl *cl; 1142 s32 slots; 1143 int rets; 1144 bool bus_message_received; 1145 1146 1147 dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n"); 1148 /* initialize our complete list */ 1149 mutex_lock(&dev->device_lock); 1150 mei_io_list_init(&complete_list); 1151 dev->host_hw_state = mei_hcsr_read(dev); 1152 1153 /* Ack the interrupt here 1154 * In case of MSI we don't go through the quick handler */ 1155 if (pci_dev_msi_enabled(dev->pdev)) 1156 mei_reg_write(dev, H_CSR, dev->host_hw_state); 1157 1158 dev->me_hw_state = mei_mecsr_read(dev); 1159 1160 /* check if ME wants a reset */ 1161 if ((dev->me_hw_state & ME_RDY_HRA) == 0 && 1162 dev->dev_state != MEI_DEV_RESETING && 1163 dev->dev_state != MEI_DEV_INITIALIZING) { 1164 dev_dbg(&dev->pdev->dev, "FW not ready.\n"); 1165 mei_reset(dev, 1); 1166 mutex_unlock(&dev->device_lock); 1167 return IRQ_HANDLED; 1168 } 1169 1170 /* check if we need to start the dev */ 1171 if ((dev->host_hw_state & H_RDY) == 0) { 1172 if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) { 1173 dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); 1174 dev->host_hw_state |= (H_IE | H_IG | H_RDY); 1175 mei_hcsr_set(dev); 1176 dev->dev_state = MEI_DEV_INIT_CLIENTS; 1177 dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); 1178 /* link is established 1179 * start sending messages. 1180 */ 1181 mei_host_start_message(dev); 1182 mutex_unlock(&dev->device_lock); 1183 return IRQ_HANDLED; 1184 } else { 1185 dev_dbg(&dev->pdev->dev, "FW not ready.\n"); 1186 mutex_unlock(&dev->device_lock); 1187 return IRQ_HANDLED; 1188 } 1189 } 1190 /* check slots available for reading */ 1191 slots = mei_count_full_read_slots(dev); 1192 while (slots > 0) { 1193 /* we have urgent data to send so break the read */ 1194 if (dev->wr_ext_msg.hdr.length) 1195 break; 1196 dev_dbg(&dev->pdev->dev, "slots =%08x\n", slots); 1197 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n"); 1198 rets = mei_irq_thread_read_handler(&complete_list, dev, &slots); 1199 if (rets) 1200 goto end; 1201 } 1202 rets = mei_irq_thread_write_handler(dev, &complete_list); 1203 end: 1204 dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); 1205 dev->host_hw_state = mei_hcsr_read(dev); 1206 dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); 1207 1208 bus_message_received = false; 1209 if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) { 1210 dev_dbg(&dev->pdev->dev, "received waiting bus message\n"); 1211 bus_message_received = true; 1212 } 1213 mutex_unlock(&dev->device_lock); 1214 if (bus_message_received) { 1215 dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n"); 1216 wake_up_interruptible(&dev->wait_recvd_msg); 1217 bus_message_received = false; 1218 } 1219 if (list_empty(&complete_list.list)) 1220 return IRQ_HANDLED; 1221 1222 1223 list_for_each_entry_safe(cb_pos, cb_next, &complete_list.list, list) { 1224 cl = cb_pos->cl; 1225 list_del(&cb_pos->list); 1226 if (cl) { 1227 if (cl != &dev->iamthif_cl) { 1228 dev_dbg(&dev->pdev->dev, "completing call back.\n"); 1229 _mei_cmpl(cl, cb_pos); 1230 cb_pos = NULL; 1231 } else if (cl == &dev->iamthif_cl) { 1232 mei_amthif_complete(dev, cb_pos); 1233 } 1234 } 1235 } 1236 return IRQ_HANDLED; 1237 } 1238