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->major_file_operations == MEI_WRITE) { 61 mei_free_cb_private(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->major_file_operations == MEI_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_cmpl_iamthif - processes completed iamthif operation. 78 * 79 * @dev: the device structure. 80 * @cb_pos: callback block. 81 */ 82 static void _mei_cmpl_iamthif(struct mei_device *dev, struct mei_cl_cb *cb_pos) 83 { 84 if (dev->iamthif_canceled != 1) { 85 dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE; 86 dev->iamthif_stall_timer = 0; 87 memcpy(cb_pos->response_buffer.data, 88 dev->iamthif_msg_buf, 89 dev->iamthif_msg_buf_index); 90 list_add_tail(&cb_pos->cb_list, 91 &dev->amthi_read_complete_list.mei_cb.cb_list); 92 dev_dbg(&dev->pdev->dev, "amthi read completed.\n"); 93 dev->iamthif_timer = jiffies; 94 dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", 95 dev->iamthif_timer); 96 } else { 97 mei_run_next_iamthif_cmd(dev); 98 } 99 100 dev_dbg(&dev->pdev->dev, "completing amthi call back.\n"); 101 wake_up_interruptible(&dev->iamthif_cl.wait); 102 } 103 104 105 /** 106 * mei_irq_thread_read_amthi_message - bottom half read routine after ISR to 107 * handle the read amthi message data processing. 108 * 109 * @complete_list: An instance of our list structure 110 * @dev: the device structure 111 * @mei_hdr: header of amthi message 112 * 113 * returns 0 on success, <0 on failure. 114 */ 115 static int mei_irq_thread_read_amthi_message(struct mei_io_list *complete_list, 116 struct mei_device *dev, 117 struct mei_msg_hdr *mei_hdr) 118 { 119 struct mei_cl *cl; 120 struct mei_cl_cb *cb; 121 unsigned char *buffer; 122 123 BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id); 124 BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING); 125 126 buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index; 127 BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length); 128 129 mei_read_slots(dev, buffer, mei_hdr->length); 130 131 dev->iamthif_msg_buf_index += mei_hdr->length; 132 133 if (!mei_hdr->msg_complete) 134 return 0; 135 136 dev_dbg(&dev->pdev->dev, 137 "amthi_message_buffer_index =%d\n", 138 mei_hdr->length); 139 140 dev_dbg(&dev->pdev->dev, "completed amthi read.\n "); 141 if (!dev->iamthif_current_cb) 142 return -ENODEV; 143 144 cb = dev->iamthif_current_cb; 145 dev->iamthif_current_cb = NULL; 146 147 cl = (struct mei_cl *)cb->file_private; 148 if (!cl) 149 return -ENODEV; 150 151 dev->iamthif_stall_timer = 0; 152 cb->information = dev->iamthif_msg_buf_index; 153 cb->read_time = jiffies; 154 if (dev->iamthif_ioctl && cl == &dev->iamthif_cl) { 155 /* found the iamthif cb */ 156 dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n "); 157 dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n "); 158 list_add_tail(&cb->cb_list, 159 &complete_list->mei_cb.cb_list); 160 } 161 return 0; 162 } 163 164 /** 165 * _mei_irq_thread_state_ok - checks if mei header matches file private data 166 * 167 * @cl: private data of the file object 168 * @mei_hdr: header of mei client message 169 * 170 * returns !=0 if matches, 0 if no match. 171 */ 172 static int _mei_irq_thread_state_ok(struct mei_cl *cl, 173 struct mei_msg_hdr *mei_hdr) 174 { 175 return (cl->host_client_id == mei_hdr->host_addr && 176 cl->me_client_id == mei_hdr->me_addr && 177 cl->state == MEI_FILE_CONNECTED && 178 MEI_READ_COMPLETE != cl->reading_state); 179 } 180 181 /** 182 * mei_irq_thread_read_client_message - bottom half read routine after ISR to 183 * handle the read mei client message data processing. 184 * 185 * @complete_list: An instance of our list structure 186 * @dev: the device structure 187 * @mei_hdr: header of mei client message 188 * 189 * returns 0 on success, <0 on failure. 190 */ 191 static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, 192 struct mei_device *dev, 193 struct mei_msg_hdr *mei_hdr) 194 { 195 struct mei_cl *cl; 196 struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; 197 unsigned char *buffer = NULL; 198 199 dev_dbg(&dev->pdev->dev, "start client msg\n"); 200 if (list_empty(&dev->read_list.mei_cb.cb_list)) 201 goto quit; 202 203 list_for_each_entry_safe(cb_pos, cb_next, 204 &dev->read_list.mei_cb.cb_list, cb_list) { 205 cl = (struct mei_cl *)cb_pos->file_private; 206 if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) { 207 cl->reading_state = MEI_READING; 208 buffer = cb_pos->response_buffer.data + cb_pos->information; 209 210 if (cb_pos->response_buffer.size < 211 mei_hdr->length + cb_pos->information) { 212 dev_dbg(&dev->pdev->dev, "message overflow.\n"); 213 list_del(&cb_pos->cb_list); 214 return -ENOMEM; 215 } 216 if (buffer) 217 mei_read_slots(dev, buffer, mei_hdr->length); 218 219 cb_pos->information += mei_hdr->length; 220 if (mei_hdr->msg_complete) { 221 cl->status = 0; 222 list_del(&cb_pos->cb_list); 223 dev_dbg(&dev->pdev->dev, 224 "completed read H cl = %d, ME cl = %d, length = %lu\n", 225 cl->host_client_id, 226 cl->me_client_id, 227 cb_pos->information); 228 list_add_tail(&cb_pos->cb_list, 229 &complete_list->mei_cb.cb_list); 230 } 231 232 break; 233 } 234 235 } 236 237 quit: 238 dev_dbg(&dev->pdev->dev, "message read\n"); 239 if (!buffer) { 240 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); 241 dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n", 242 *(u32 *) dev->rd_msg_buf); 243 } 244 245 return 0; 246 } 247 248 /** 249 * _mei_irq_thread_iamthif_read - prepares to read iamthif data. 250 * 251 * @dev: the device structure. 252 * @slots: free slots. 253 * 254 * returns 0, OK; otherwise, error. 255 */ 256 static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots) 257 { 258 259 if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr) 260 + sizeof(struct hbm_flow_control))) { 261 return -EMSGSIZE; 262 } 263 *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); 264 if (mei_send_flow_control(dev, &dev->iamthif_cl)) { 265 dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); 266 return -EIO; 267 } 268 269 dev_dbg(&dev->pdev->dev, "iamthif flow control success\n"); 270 dev->iamthif_state = MEI_IAMTHIF_READING; 271 dev->iamthif_flow_control_pending = false; 272 dev->iamthif_msg_buf_index = 0; 273 dev->iamthif_msg_buf_size = 0; 274 dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER; 275 dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); 276 return 0; 277 } 278 279 /** 280 * _mei_irq_thread_close - processes close related operation. 281 * 282 * @dev: the device structure. 283 * @slots: free slots. 284 * @cb_pos: callback block. 285 * @cl: private data of the file object. 286 * @cmpl_list: complete list. 287 * 288 * returns 0, OK; otherwise, error. 289 */ 290 static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, 291 struct mei_cl_cb *cb_pos, 292 struct mei_cl *cl, 293 struct mei_io_list *cmpl_list) 294 { 295 if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + 296 sizeof(struct hbm_client_disconnect_request))) 297 return -EBADMSG; 298 299 *slots -= mei_data2slots(sizeof(struct hbm_client_disconnect_request)); 300 301 if (mei_disconnect(dev, cl)) { 302 cl->status = 0; 303 cb_pos->information = 0; 304 list_move_tail(&cb_pos->cb_list, 305 &cmpl_list->mei_cb.cb_list); 306 return -EMSGSIZE; 307 } else { 308 cl->state = MEI_FILE_DISCONNECTING; 309 cl->status = 0; 310 cb_pos->information = 0; 311 list_move_tail(&cb_pos->cb_list, 312 &dev->ctrl_rd_list.mei_cb.cb_list); 313 cl->timer_count = MEI_CONNECT_TIMEOUT; 314 } 315 316 return 0; 317 } 318 319 /** 320 * is_treat_specially_client - checks if the message belongs 321 * to the file private data. 322 * 323 * @cl: private data of the file object 324 * @rs: connect response bus message 325 * 326 */ 327 static bool is_treat_specially_client(struct mei_cl *cl, 328 struct hbm_client_connect_response *rs) 329 { 330 331 if (cl->host_client_id == rs->host_addr && 332 cl->me_client_id == rs->me_addr) { 333 if (!rs->status) { 334 cl->state = MEI_FILE_CONNECTED; 335 cl->status = 0; 336 337 } else { 338 cl->state = MEI_FILE_DISCONNECTED; 339 cl->status = -ENODEV; 340 } 341 cl->timer_count = 0; 342 343 return true; 344 } 345 return false; 346 } 347 348 /** 349 * mei_client_connect_response - connects to response irq routine 350 * 351 * @dev: the device structure 352 * @rs: connect response bus message 353 */ 354 static void mei_client_connect_response(struct mei_device *dev, 355 struct hbm_client_connect_response *rs) 356 { 357 358 struct mei_cl *cl; 359 struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; 360 361 dev_dbg(&dev->pdev->dev, 362 "connect_response:\n" 363 "ME Client = %d\n" 364 "Host Client = %d\n" 365 "Status = %d\n", 366 rs->me_addr, 367 rs->host_addr, 368 rs->status); 369 370 /* if WD or iamthif client treat specially */ 371 372 if (is_treat_specially_client(&(dev->wd_cl), rs)) { 373 dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n"); 374 mei_watchdog_register(dev); 375 376 /* next step in the state maching */ 377 mei_host_init_iamthif(dev); 378 return; 379 } 380 381 if (is_treat_specially_client(&(dev->iamthif_cl), rs)) { 382 dev->iamthif_state = MEI_IAMTHIF_IDLE; 383 return; 384 } 385 list_for_each_entry_safe(cb_pos, cb_next, 386 &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) { 387 388 cl = (struct mei_cl *)cb_pos->file_private; 389 if (!cl) { 390 list_del(&cb_pos->cb_list); 391 return; 392 } 393 if (MEI_IOCTL == cb_pos->major_file_operations) { 394 if (is_treat_specially_client(cl, rs)) { 395 list_del(&cb_pos->cb_list); 396 cl->status = 0; 397 cl->timer_count = 0; 398 break; 399 } 400 } 401 } 402 } 403 404 /** 405 * mei_client_disconnect_response - disconnects from response irq routine 406 * 407 * @dev: the device structure 408 * @rs: disconnect response bus message 409 */ 410 static void mei_client_disconnect_response(struct mei_device *dev, 411 struct hbm_client_connect_response *rs) 412 { 413 struct mei_cl *cl; 414 struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; 415 416 dev_dbg(&dev->pdev->dev, 417 "disconnect_response:\n" 418 "ME Client = %d\n" 419 "Host Client = %d\n" 420 "Status = %d\n", 421 rs->me_addr, 422 rs->host_addr, 423 rs->status); 424 425 list_for_each_entry_safe(cb_pos, cb_next, 426 &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) { 427 cl = (struct mei_cl *)cb_pos->file_private; 428 429 if (!cl) { 430 list_del(&cb_pos->cb_list); 431 return; 432 } 433 434 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n"); 435 if (cl->host_client_id == rs->host_addr && 436 cl->me_client_id == rs->me_addr) { 437 438 list_del(&cb_pos->cb_list); 439 if (!rs->status) 440 cl->state = MEI_FILE_DISCONNECTED; 441 442 cl->status = 0; 443 cl->timer_count = 0; 444 break; 445 } 446 } 447 } 448 449 /** 450 * same_flow_addr - tells if they have the same address. 451 * 452 * @file: private data of the file object. 453 * @flow: flow control. 454 * 455 * returns !=0, same; 0,not. 456 */ 457 static int same_flow_addr(struct mei_cl *cl, struct hbm_flow_control *flow) 458 { 459 return (cl->host_client_id == flow->host_addr && 460 cl->me_client_id == flow->me_addr); 461 } 462 463 /** 464 * add_single_flow_creds - adds single buffer credentials. 465 * 466 * @file: private data ot the file object. 467 * @flow: flow control. 468 */ 469 static void add_single_flow_creds(struct mei_device *dev, 470 struct hbm_flow_control *flow) 471 { 472 struct mei_me_client *client; 473 int i; 474 475 for (i = 0; i < dev->me_clients_num; i++) { 476 client = &dev->me_clients[i]; 477 if (client && flow->me_addr == client->client_id) { 478 if (client->props.single_recv_buf) { 479 client->mei_flow_ctrl_creds++; 480 dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n", 481 flow->me_addr); 482 dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n", 483 client->mei_flow_ctrl_creds); 484 } else { 485 BUG(); /* error in flow control */ 486 } 487 } 488 } 489 } 490 491 /** 492 * mei_client_flow_control_response - flow control response irq routine 493 * 494 * @dev: the device structure 495 * @flow_control: flow control response bus message 496 */ 497 static void mei_client_flow_control_response(struct mei_device *dev, 498 struct hbm_flow_control *flow_control) 499 { 500 struct mei_cl *cl_pos = NULL; 501 struct mei_cl *cl_next = NULL; 502 503 if (!flow_control->host_addr) { 504 /* single receive buffer */ 505 add_single_flow_creds(dev, flow_control); 506 } else { 507 /* normal connection */ 508 list_for_each_entry_safe(cl_pos, cl_next, 509 &dev->file_list, link) { 510 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in file_list\n"); 511 512 dev_dbg(&dev->pdev->dev, "cl of host client %d ME client %d.\n", 513 cl_pos->host_client_id, 514 cl_pos->me_client_id); 515 dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n", 516 flow_control->host_addr, 517 flow_control->me_addr); 518 if (same_flow_addr(cl_pos, flow_control)) { 519 dev_dbg(&dev->pdev->dev, "recv ctrl msg for host %d ME %d.\n", 520 flow_control->host_addr, 521 flow_control->me_addr); 522 cl_pos->mei_flow_ctrl_creds++; 523 dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n", 524 cl_pos->mei_flow_ctrl_creds); 525 break; 526 } 527 } 528 } 529 } 530 531 /** 532 * same_disconn_addr - tells if they have the same address 533 * 534 * @file: private data of the file object. 535 * @disconn: disconnection request. 536 * 537 * returns !=0, same; 0,not. 538 */ 539 static int same_disconn_addr(struct mei_cl *cl, 540 struct hbm_client_disconnect_request *disconn) 541 { 542 return (cl->host_client_id == disconn->host_addr && 543 cl->me_client_id == disconn->me_addr); 544 } 545 546 /** 547 * mei_client_disconnect_request - disconnects from request irq routine 548 * 549 * @dev: the device structure. 550 * @disconnect_req: disconnect request bus message. 551 */ 552 static void mei_client_disconnect_request(struct mei_device *dev, 553 struct hbm_client_disconnect_request *disconnect_req) 554 { 555 struct mei_msg_hdr *mei_hdr; 556 struct hbm_client_connect_response *disconnect_res; 557 struct mei_cl *cl_pos = NULL; 558 struct mei_cl *cl_next = NULL; 559 560 list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { 561 if (same_disconn_addr(cl_pos, disconnect_req)) { 562 dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n", 563 disconnect_req->host_addr, 564 disconnect_req->me_addr); 565 cl_pos->state = MEI_FILE_DISCONNECTED; 566 cl_pos->timer_count = 0; 567 if (cl_pos == &dev->wd_cl) 568 dev->wd_pending = false; 569 else if (cl_pos == &dev->iamthif_cl) 570 dev->iamthif_timer = 0; 571 572 /* prepare disconnect response */ 573 mei_hdr = 574 (struct mei_msg_hdr *) &dev->ext_msg_buf[0]; 575 mei_hdr->host_addr = 0; 576 mei_hdr->me_addr = 0; 577 mei_hdr->length = 578 sizeof(struct hbm_client_connect_response); 579 mei_hdr->msg_complete = 1; 580 mei_hdr->reserved = 0; 581 582 disconnect_res = 583 (struct hbm_client_connect_response *) 584 &dev->ext_msg_buf[1]; 585 disconnect_res->host_addr = cl_pos->host_client_id; 586 disconnect_res->me_addr = cl_pos->me_client_id; 587 disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD; 588 disconnect_res->status = 0; 589 dev->extra_write_index = 2; 590 break; 591 } 592 } 593 } 594 595 596 /** 597 * mei_irq_thread_read_bus_message - bottom half read routine after ISR to 598 * handle the read bus message cmd processing. 599 * 600 * @dev: the device structure 601 * @mei_hdr: header of bus message 602 */ 603 static void mei_irq_thread_read_bus_message(struct mei_device *dev, 604 struct mei_msg_hdr *mei_hdr) 605 { 606 struct mei_bus_message *mei_msg; 607 struct hbm_host_version_response *version_res; 608 struct hbm_client_connect_response *connect_res; 609 struct hbm_client_connect_response *disconnect_res; 610 struct hbm_flow_control *flow_control; 611 struct hbm_props_response *props_res; 612 struct hbm_host_enum_response *enum_res; 613 struct hbm_client_disconnect_request *disconnect_req; 614 struct hbm_host_stop_request *host_stop_req; 615 int res; 616 617 618 /* read the message to our buffer */ 619 BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf)); 620 mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); 621 mei_msg = (struct mei_bus_message *)dev->rd_msg_buf; 622 623 switch (mei_msg->hbm_cmd) { 624 case HOST_START_RES_CMD: 625 version_res = (struct hbm_host_version_response *) mei_msg; 626 if (version_res->host_version_supported) { 627 dev->version.major_version = HBM_MAJOR_VERSION; 628 dev->version.minor_version = HBM_MINOR_VERSION; 629 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 630 dev->init_clients_state == MEI_START_MESSAGE) { 631 dev->init_clients_timer = 0; 632 mei_host_enum_clients_message(dev); 633 } else { 634 dev->recvd_msg = false; 635 dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n"); 636 mei_reset(dev, 1); 637 return; 638 } 639 } else { 640 dev->version = version_res->me_max_version; 641 /* send stop message */ 642 mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; 643 mei_hdr->host_addr = 0; 644 mei_hdr->me_addr = 0; 645 mei_hdr->length = sizeof(struct hbm_host_stop_request); 646 mei_hdr->msg_complete = 1; 647 mei_hdr->reserved = 0; 648 649 host_stop_req = (struct hbm_host_stop_request *) 650 &dev->wr_msg_buf[1]; 651 652 memset(host_stop_req, 653 0, 654 sizeof(struct hbm_host_stop_request)); 655 host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD; 656 host_stop_req->reason = DRIVER_STOP_REQUEST; 657 mei_write_message(dev, mei_hdr, 658 (unsigned char *) (host_stop_req), 659 mei_hdr->length); 660 dev_dbg(&dev->pdev->dev, "version mismatch.\n"); 661 return; 662 } 663 664 dev->recvd_msg = true; 665 dev_dbg(&dev->pdev->dev, "host start response message received.\n"); 666 break; 667 668 case CLIENT_CONNECT_RES_CMD: 669 connect_res = 670 (struct hbm_client_connect_response *) mei_msg; 671 mei_client_connect_response(dev, connect_res); 672 dev_dbg(&dev->pdev->dev, "client connect response message received.\n"); 673 wake_up(&dev->wait_recvd_msg); 674 break; 675 676 case CLIENT_DISCONNECT_RES_CMD: 677 disconnect_res = 678 (struct hbm_client_connect_response *) mei_msg; 679 mei_client_disconnect_response(dev, disconnect_res); 680 dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n"); 681 wake_up(&dev->wait_recvd_msg); 682 break; 683 684 case MEI_FLOW_CONTROL_CMD: 685 flow_control = (struct hbm_flow_control *) mei_msg; 686 mei_client_flow_control_response(dev, flow_control); 687 dev_dbg(&dev->pdev->dev, "client flow control response message received.\n"); 688 break; 689 690 case HOST_CLIENT_PROPERTIES_RES_CMD: 691 props_res = (struct hbm_props_response *)mei_msg; 692 if (props_res->status || !dev->me_clients) { 693 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n"); 694 mei_reset(dev, 1); 695 return; 696 } 697 if (dev->me_clients[dev->me_client_presentation_num] 698 .client_id == props_res->address) { 699 700 dev->me_clients[dev->me_client_presentation_num].props 701 = props_res->client_properties; 702 703 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 704 dev->init_clients_state == 705 MEI_CLIENT_PROPERTIES_MESSAGE) { 706 dev->me_client_index++; 707 dev->me_client_presentation_num++; 708 709 /** Send Client Properties request **/ 710 res = mei_host_client_properties(dev); 711 if (res < 0) { 712 dev_dbg(&dev->pdev->dev, "mei_host_client_properties() failed"); 713 return; 714 } else if (!res) { 715 /* 716 * No more clients to send to. 717 * Clear Map for indicating now ME clients 718 * with associated host client 719 */ 720 bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX); 721 dev->open_handle_count = 0; 722 723 /* 724 * Reserving the first three client IDs 725 * Client Id 0 - Reserved for MEI Bus Message communications 726 * Client Id 1 - Reserved for Watchdog 727 * Client ID 2 - Reserved for AMTHI 728 */ 729 bitmap_set(dev->host_clients_map, 0, 3); 730 dev->dev_state = MEI_DEV_ENABLED; 731 732 /* if wd initialization fails, initialization the AMTHI client, 733 * otherwise the AMTHI client will be initialized after the WD client connect response 734 * will be received 735 */ 736 if (mei_wd_host_init(dev)) 737 mei_host_init_iamthif(dev); 738 } 739 740 } else { 741 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message"); 742 mei_reset(dev, 1); 743 return; 744 } 745 } else { 746 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message for wrong client ID\n"); 747 mei_reset(dev, 1); 748 return; 749 } 750 break; 751 752 case HOST_ENUM_RES_CMD: 753 enum_res = (struct hbm_host_enum_response *) mei_msg; 754 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); 755 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 756 dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) { 757 dev->init_clients_timer = 0; 758 dev->me_client_presentation_num = 0; 759 dev->me_client_index = 0; 760 mei_allocate_me_clients_storage(dev); 761 dev->init_clients_state = 762 MEI_CLIENT_PROPERTIES_MESSAGE; 763 mei_host_client_properties(dev); 764 } else { 765 dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n"); 766 mei_reset(dev, 1); 767 return; 768 } 769 break; 770 771 case HOST_STOP_RES_CMD: 772 dev->dev_state = MEI_DEV_DISABLED; 773 dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n"); 774 mei_reset(dev, 1); 775 break; 776 777 case CLIENT_DISCONNECT_REQ_CMD: 778 /* search for client */ 779 disconnect_req = 780 (struct hbm_client_disconnect_request *) mei_msg; 781 mei_client_disconnect_request(dev, disconnect_req); 782 break; 783 784 case ME_STOP_REQ_CMD: 785 /* prepare stop request */ 786 mei_hdr = (struct mei_msg_hdr *) &dev->ext_msg_buf[0]; 787 mei_hdr->host_addr = 0; 788 mei_hdr->me_addr = 0; 789 mei_hdr->length = sizeof(struct hbm_host_stop_request); 790 mei_hdr->msg_complete = 1; 791 mei_hdr->reserved = 0; 792 host_stop_req = 793 (struct hbm_host_stop_request *) &dev->ext_msg_buf[1]; 794 memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request)); 795 host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD; 796 host_stop_req->reason = DRIVER_STOP_REQUEST; 797 host_stop_req->reserved[0] = 0; 798 host_stop_req->reserved[1] = 0; 799 dev->extra_write_index = 2; 800 break; 801 802 default: 803 BUG(); 804 break; 805 806 } 807 } 808 809 810 /** 811 * _mei_hb_read - processes read related operation. 812 * 813 * @dev: the device structure. 814 * @slots: free slots. 815 * @cb_pos: callback block. 816 * @cl: private data of the file object. 817 * @cmpl_list: complete list. 818 * 819 * returns 0, OK; otherwise, error. 820 */ 821 static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, 822 struct mei_cl_cb *cb_pos, 823 struct mei_cl *cl, 824 struct mei_io_list *cmpl_list) 825 { 826 if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + 827 sizeof(struct hbm_flow_control))) { 828 /* return the cancel routine */ 829 list_del(&cb_pos->cb_list); 830 return -EBADMSG; 831 } 832 833 *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); 834 835 if (mei_send_flow_control(dev, cl)) { 836 cl->status = -ENODEV; 837 cb_pos->information = 0; 838 list_move_tail(&cb_pos->cb_list, &cmpl_list->mei_cb.cb_list); 839 return -ENODEV; 840 } 841 list_move_tail(&cb_pos->cb_list, &dev->read_list.mei_cb.cb_list); 842 843 return 0; 844 } 845 846 847 /** 848 * _mei_irq_thread_ioctl - processes ioctl related operation. 849 * 850 * @dev: the device structure. 851 * @slots: free slots. 852 * @cb_pos: callback block. 853 * @cl: private data of the file object. 854 * @cmpl_list: complete list. 855 * 856 * returns 0, OK; otherwise, error. 857 */ 858 static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, 859 struct mei_cl_cb *cb_pos, 860 struct mei_cl *cl, 861 struct mei_io_list *cmpl_list) 862 { 863 if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + 864 sizeof(struct hbm_client_connect_request))) { 865 /* return the cancel routine */ 866 list_del(&cb_pos->cb_list); 867 return -EBADMSG; 868 } 869 870 cl->state = MEI_FILE_CONNECTING; 871 *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); 872 if (mei_connect(dev, cl)) { 873 cl->status = -ENODEV; 874 cb_pos->information = 0; 875 list_del(&cb_pos->cb_list); 876 return -ENODEV; 877 } else { 878 list_move_tail(&cb_pos->cb_list, 879 &dev->ctrl_rd_list.mei_cb.cb_list); 880 cl->timer_count = MEI_CONNECT_TIMEOUT; 881 } 882 return 0; 883 } 884 885 /** 886 * _mei_irq_thread_cmpl - processes completed and no-iamthif operation. 887 * 888 * @dev: the device structure. 889 * @slots: free slots. 890 * @cb_pos: callback block. 891 * @cl: private data of the file object. 892 * @cmpl_list: complete list. 893 * 894 * returns 0, OK; otherwise, error. 895 */ 896 static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, 897 struct mei_cl_cb *cb_pos, 898 struct mei_cl *cl, 899 struct mei_io_list *cmpl_list) 900 { 901 struct mei_msg_hdr *mei_hdr; 902 903 if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + 904 (cb_pos->request_buffer.size - 905 cb_pos->information))) { 906 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; 907 mei_hdr->host_addr = cl->host_client_id; 908 mei_hdr->me_addr = cl->me_client_id; 909 mei_hdr->length = cb_pos->request_buffer.size - 910 cb_pos->information; 911 mei_hdr->msg_complete = 1; 912 mei_hdr->reserved = 0; 913 dev_dbg(&dev->pdev->dev, "cb_pos->request_buffer.size =%d" 914 "mei_hdr->msg_complete = %d\n", 915 cb_pos->request_buffer.size, 916 mei_hdr->msg_complete); 917 dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n", 918 cb_pos->information); 919 dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", 920 mei_hdr->length); 921 *slots -= mei_data2slots(mei_hdr->length); 922 if (mei_write_message(dev, mei_hdr, 923 (unsigned char *) 924 (cb_pos->request_buffer.data + 925 cb_pos->information), 926 mei_hdr->length)) { 927 cl->status = -ENODEV; 928 list_move_tail(&cb_pos->cb_list, 929 &cmpl_list->mei_cb.cb_list); 930 return -ENODEV; 931 } else { 932 if (mei_flow_ctrl_reduce(dev, cl)) 933 return -ENODEV; 934 cl->status = 0; 935 cb_pos->information += mei_hdr->length; 936 list_move_tail(&cb_pos->cb_list, 937 &dev->write_waiting_list.mei_cb.cb_list); 938 } 939 } else if (*slots == dev->hbuf_depth) { 940 /* buffer is still empty */ 941 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; 942 mei_hdr->host_addr = cl->host_client_id; 943 mei_hdr->me_addr = cl->me_client_id; 944 mei_hdr->length = 945 (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); 946 mei_hdr->msg_complete = 0; 947 mei_hdr->reserved = 0; 948 *slots -= mei_data2slots(mei_hdr->length); 949 if (mei_write_message(dev, mei_hdr, 950 (unsigned char *) 951 (cb_pos->request_buffer.data + 952 cb_pos->information), 953 mei_hdr->length)) { 954 cl->status = -ENODEV; 955 list_move_tail(&cb_pos->cb_list, 956 &cmpl_list->mei_cb.cb_list); 957 return -ENODEV; 958 } else { 959 cb_pos->information += mei_hdr->length; 960 dev_dbg(&dev->pdev->dev, 961 "cb_pos->request_buffer.size =%d" 962 " mei_hdr->msg_complete = %d\n", 963 cb_pos->request_buffer.size, 964 mei_hdr->msg_complete); 965 dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n", 966 cb_pos->information); 967 dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", 968 mei_hdr->length); 969 } 970 return -EMSGSIZE; 971 } else { 972 return -EBADMSG; 973 } 974 975 return 0; 976 } 977 978 /** 979 * _mei_irq_thread_cmpl_iamthif - processes completed iamthif operation. 980 * 981 * @dev: the device structure. 982 * @slots: free slots. 983 * @cb_pos: callback block. 984 * @cl: private data of the file object. 985 * @cmpl_list: complete list. 986 * 987 * returns 0, OK; otherwise, error. 988 */ 989 static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, 990 struct mei_cl_cb *cb_pos, 991 struct mei_cl *cl, 992 struct mei_io_list *cmpl_list) 993 { 994 struct mei_msg_hdr *mei_hdr; 995 996 if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + 997 dev->iamthif_msg_buf_size - 998 dev->iamthif_msg_buf_index)) { 999 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; 1000 mei_hdr->host_addr = cl->host_client_id; 1001 mei_hdr->me_addr = cl->me_client_id; 1002 mei_hdr->length = dev->iamthif_msg_buf_size - 1003 dev->iamthif_msg_buf_index; 1004 mei_hdr->msg_complete = 1; 1005 mei_hdr->reserved = 0; 1006 1007 *slots -= mei_data2slots(mei_hdr->length); 1008 1009 if (mei_write_message(dev, mei_hdr, 1010 (dev->iamthif_msg_buf + 1011 dev->iamthif_msg_buf_index), 1012 mei_hdr->length)) { 1013 dev->iamthif_state = MEI_IAMTHIF_IDLE; 1014 cl->status = -ENODEV; 1015 list_del(&cb_pos->cb_list); 1016 return -ENODEV; 1017 } else { 1018 if (mei_flow_ctrl_reduce(dev, cl)) 1019 return -ENODEV; 1020 dev->iamthif_msg_buf_index += mei_hdr->length; 1021 cb_pos->information = dev->iamthif_msg_buf_index; 1022 cl->status = 0; 1023 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; 1024 dev->iamthif_flow_control_pending = true; 1025 /* save iamthif cb sent to amthi client */ 1026 dev->iamthif_current_cb = cb_pos; 1027 list_move_tail(&cb_pos->cb_list, 1028 &dev->write_waiting_list.mei_cb.cb_list); 1029 1030 } 1031 } else if (*slots == dev->hbuf_depth) { 1032 /* buffer is still empty */ 1033 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; 1034 mei_hdr->host_addr = cl->host_client_id; 1035 mei_hdr->me_addr = cl->me_client_id; 1036 mei_hdr->length = 1037 (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); 1038 mei_hdr->msg_complete = 0; 1039 mei_hdr->reserved = 0; 1040 1041 *slots -= mei_data2slots(mei_hdr->length); 1042 1043 if (mei_write_message(dev, mei_hdr, 1044 (dev->iamthif_msg_buf + 1045 dev->iamthif_msg_buf_index), 1046 mei_hdr->length)) { 1047 cl->status = -ENODEV; 1048 list_del(&cb_pos->cb_list); 1049 } else { 1050 dev->iamthif_msg_buf_index += mei_hdr->length; 1051 } 1052 return -EMSGSIZE; 1053 } else { 1054 return -EBADMSG; 1055 } 1056 1057 return 0; 1058 } 1059 1060 /** 1061 * mei_irq_thread_read_handler - bottom half read routine after ISR to 1062 * handle the read processing. 1063 * 1064 * @cmpl_list: An instance of our list structure 1065 * @dev: the device structure 1066 * @slots: slots to read. 1067 * 1068 * returns 0 on success, <0 on failure. 1069 */ 1070 static int mei_irq_thread_read_handler(struct mei_io_list *cmpl_list, 1071 struct mei_device *dev, 1072 s32 *slots) 1073 { 1074 struct mei_msg_hdr *mei_hdr; 1075 struct mei_cl *cl_pos = NULL; 1076 struct mei_cl *cl_next = NULL; 1077 int ret = 0; 1078 1079 if (!dev->rd_msg_hdr) { 1080 dev->rd_msg_hdr = mei_mecbrw_read(dev); 1081 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); 1082 (*slots)--; 1083 dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); 1084 } 1085 mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr; 1086 dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length); 1087 1088 if (mei_hdr->reserved || !dev->rd_msg_hdr) { 1089 dev_dbg(&dev->pdev->dev, "corrupted message header.\n"); 1090 ret = -EBADMSG; 1091 goto end; 1092 } 1093 1094 if (mei_hdr->host_addr || mei_hdr->me_addr) { 1095 list_for_each_entry_safe(cl_pos, cl_next, 1096 &dev->file_list, link) { 1097 dev_dbg(&dev->pdev->dev, 1098 "list_for_each_entry_safe read host" 1099 " client = %d, ME client = %d\n", 1100 cl_pos->host_client_id, 1101 cl_pos->me_client_id); 1102 if (cl_pos->host_client_id == mei_hdr->host_addr && 1103 cl_pos->me_client_id == mei_hdr->me_addr) 1104 break; 1105 } 1106 1107 if (&cl_pos->link == &dev->file_list) { 1108 dev_dbg(&dev->pdev->dev, "corrupted message header\n"); 1109 ret = -EBADMSG; 1110 goto end; 1111 } 1112 } 1113 if (((*slots) * sizeof(u32)) < mei_hdr->length) { 1114 dev_dbg(&dev->pdev->dev, 1115 "we can't read the message slots =%08x.\n", 1116 *slots); 1117 /* we can't read the message */ 1118 ret = -ERANGE; 1119 goto end; 1120 } 1121 1122 /* decide where to read the message too */ 1123 if (!mei_hdr->host_addr) { 1124 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n"); 1125 mei_irq_thread_read_bus_message(dev, mei_hdr); 1126 dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n"); 1127 } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && 1128 (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && 1129 (dev->iamthif_state == MEI_IAMTHIF_READING)) { 1130 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); 1131 dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", 1132 mei_hdr->length); 1133 ret = mei_irq_thread_read_amthi_message(cmpl_list, 1134 dev, mei_hdr); 1135 if (ret) 1136 goto end; 1137 1138 } else { 1139 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n"); 1140 ret = mei_irq_thread_read_client_message(cmpl_list, 1141 dev, mei_hdr); 1142 if (ret) 1143 goto end; 1144 1145 } 1146 1147 /* reset the number of slots and header */ 1148 *slots = mei_count_full_read_slots(dev); 1149 dev->rd_msg_hdr = 0; 1150 1151 if (*slots == -EOVERFLOW) { 1152 /* overflow - reset */ 1153 dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n"); 1154 /* set the event since message has been read */ 1155 ret = -ERANGE; 1156 goto end; 1157 } 1158 end: 1159 return ret; 1160 } 1161 1162 1163 /** 1164 * mei_irq_thread_write_handler - bottom half write routine after 1165 * ISR to handle the write processing. 1166 * 1167 * @cmpl_list: An instance of our list structure 1168 * @dev: the device structure 1169 * @slots: slots to write. 1170 * 1171 * returns 0 on success, <0 on failure. 1172 */ 1173 static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, 1174 struct mei_device *dev, 1175 s32 *slots) 1176 { 1177 1178 struct mei_cl *cl; 1179 struct mei_cl_cb *pos = NULL, *next = NULL; 1180 struct mei_io_list *list; 1181 int ret; 1182 1183 if (!mei_hbuf_is_empty(dev)) { 1184 dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); 1185 return 0; 1186 } 1187 *slots = mei_hbuf_empty_slots(dev); 1188 if (*slots <= 0) 1189 return -EMSGSIZE; 1190 1191 /* complete all waiting for write CB */ 1192 dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n"); 1193 1194 list = &dev->write_waiting_list; 1195 list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) { 1196 cl = (struct mei_cl *)pos->file_private; 1197 if (cl == NULL) 1198 continue; 1199 1200 cl->status = 0; 1201 list_del(&pos->cb_list); 1202 if (MEI_WRITING == cl->writing_state && 1203 (pos->major_file_operations == MEI_WRITE) && 1204 (cl != &dev->iamthif_cl)) { 1205 dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n"); 1206 cl->writing_state = MEI_WRITE_COMPLETE; 1207 list_add_tail(&pos->cb_list, 1208 &cmpl_list->mei_cb.cb_list); 1209 } 1210 if (cl == &dev->iamthif_cl) { 1211 dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n"); 1212 if (dev->iamthif_flow_control_pending) { 1213 ret = _mei_irq_thread_iamthif_read(dev, slots); 1214 if (ret) 1215 return ret; 1216 } 1217 } 1218 } 1219 1220 if (dev->wd_state == MEI_WD_STOPPING) { 1221 dev->wd_state = MEI_WD_IDLE; 1222 wake_up_interruptible(&dev->wait_stop_wd); 1223 } 1224 1225 if (dev->extra_write_index) { 1226 dev_dbg(&dev->pdev->dev, "extra_write_index =%d.\n", 1227 dev->extra_write_index); 1228 mei_write_message(dev, 1229 (struct mei_msg_hdr *) &dev->ext_msg_buf[0], 1230 (unsigned char *) &dev->ext_msg_buf[1], 1231 (dev->extra_write_index - 1) * sizeof(u32)); 1232 *slots -= dev->extra_write_index; 1233 dev->extra_write_index = 0; 1234 } 1235 if (dev->dev_state == MEI_DEV_ENABLED) { 1236 if (dev->wd_pending && 1237 mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { 1238 if (mei_wd_send(dev)) 1239 dev_dbg(&dev->pdev->dev, "wd send failed.\n"); 1240 else if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) 1241 return -ENODEV; 1242 1243 dev->wd_pending = false; 1244 1245 if (dev->wd_state == MEI_WD_RUNNING) 1246 *slots -= mei_data2slots(MEI_WD_START_MSG_SIZE); 1247 else 1248 *slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE); 1249 } 1250 } 1251 1252 /* complete control write list CB */ 1253 dev_dbg(&dev->pdev->dev, "complete control write list cb.\n"); 1254 list_for_each_entry_safe(pos, next, 1255 &dev->ctrl_wr_list.mei_cb.cb_list, cb_list) { 1256 cl = (struct mei_cl *) pos->file_private; 1257 if (!cl) { 1258 list_del(&pos->cb_list); 1259 return -ENODEV; 1260 } 1261 switch (pos->major_file_operations) { 1262 case MEI_CLOSE: 1263 /* send disconnect message */ 1264 ret = _mei_irq_thread_close(dev, slots, pos, cl, cmpl_list); 1265 if (ret) 1266 return ret; 1267 1268 break; 1269 case MEI_READ: 1270 /* send flow control message */ 1271 ret = _mei_irq_thread_read(dev, slots, pos, cl, cmpl_list); 1272 if (ret) 1273 return ret; 1274 1275 break; 1276 case MEI_IOCTL: 1277 /* connect message */ 1278 if (mei_other_client_is_connecting(dev, cl)) 1279 continue; 1280 ret = _mei_irq_thread_ioctl(dev, slots, pos, cl, cmpl_list); 1281 if (ret) 1282 return ret; 1283 1284 break; 1285 1286 default: 1287 BUG(); 1288 } 1289 1290 } 1291 /* complete write list CB */ 1292 dev_dbg(&dev->pdev->dev, "complete write list cb.\n"); 1293 list_for_each_entry_safe(pos, next, 1294 &dev->write_list.mei_cb.cb_list, cb_list) { 1295 cl = (struct mei_cl *)pos->file_private; 1296 if (cl == NULL) 1297 continue; 1298 1299 if (cl != &dev->iamthif_cl) { 1300 if (mei_flow_ctrl_creds(dev, cl) <= 0) { 1301 dev_dbg(&dev->pdev->dev, 1302 "No flow control credentials for client %d, not sending.\n", 1303 cl->host_client_id); 1304 continue; 1305 } 1306 ret = _mei_irq_thread_cmpl(dev, slots, pos, 1307 cl, cmpl_list); 1308 if (ret) 1309 return ret; 1310 1311 } else if (cl == &dev->iamthif_cl) { 1312 /* IAMTHIF IOCTL */ 1313 dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n"); 1314 if (mei_flow_ctrl_creds(dev, cl) <= 0) { 1315 dev_dbg(&dev->pdev->dev, 1316 "No flow control credentials for amthi client %d.\n", 1317 cl->host_client_id); 1318 continue; 1319 } 1320 ret = _mei_irq_thread_cmpl_iamthif(dev, slots, pos, 1321 cl, cmpl_list); 1322 if (ret) 1323 return ret; 1324 1325 } 1326 1327 } 1328 return 0; 1329 } 1330 1331 1332 1333 /** 1334 * mei_timer - timer function. 1335 * 1336 * @work: pointer to the work_struct structure 1337 * 1338 * NOTE: This function is called by timer interrupt work 1339 */ 1340 void mei_timer(struct work_struct *work) 1341 { 1342 unsigned long timeout; 1343 struct mei_cl *cl_pos = NULL; 1344 struct mei_cl *cl_next = NULL; 1345 struct list_head *amthi_complete_list = NULL; 1346 struct mei_cl_cb *cb_pos = NULL; 1347 struct mei_cl_cb *cb_next = NULL; 1348 1349 struct mei_device *dev = container_of(work, 1350 struct mei_device, timer_work.work); 1351 1352 1353 mutex_lock(&dev->device_lock); 1354 if (dev->dev_state != MEI_DEV_ENABLED) { 1355 if (dev->dev_state == MEI_DEV_INIT_CLIENTS) { 1356 if (dev->init_clients_timer) { 1357 if (--dev->init_clients_timer == 0) { 1358 dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n", 1359 dev->init_clients_state); 1360 mei_reset(dev, 1); 1361 } 1362 } 1363 } 1364 goto out; 1365 } 1366 /*** connect/disconnect timeouts ***/ 1367 list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { 1368 if (cl_pos->timer_count) { 1369 if (--cl_pos->timer_count == 0) { 1370 dev_dbg(&dev->pdev->dev, "HECI reset due to connect/disconnect timeout.\n"); 1371 mei_reset(dev, 1); 1372 goto out; 1373 } 1374 } 1375 } 1376 1377 if (dev->iamthif_stall_timer) { 1378 if (--dev->iamthif_stall_timer == 0) { 1379 dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n"); 1380 mei_reset(dev, 1); 1381 dev->iamthif_msg_buf_size = 0; 1382 dev->iamthif_msg_buf_index = 0; 1383 dev->iamthif_canceled = false; 1384 dev->iamthif_ioctl = true; 1385 dev->iamthif_state = MEI_IAMTHIF_IDLE; 1386 dev->iamthif_timer = 0; 1387 1388 if (dev->iamthif_current_cb) 1389 mei_free_cb_private(dev->iamthif_current_cb); 1390 1391 dev->iamthif_file_object = NULL; 1392 dev->iamthif_current_cb = NULL; 1393 mei_run_next_iamthif_cmd(dev); 1394 } 1395 } 1396 1397 if (dev->iamthif_timer) { 1398 1399 timeout = dev->iamthif_timer + 1400 msecs_to_jiffies(IAMTHIF_READ_TIMER); 1401 1402 dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", 1403 dev->iamthif_timer); 1404 dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout); 1405 dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies); 1406 if (time_after(jiffies, timeout)) { 1407 /* 1408 * User didn't read the AMTHI data on time (15sec) 1409 * freeing AMTHI for other requests 1410 */ 1411 1412 dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n"); 1413 1414 amthi_complete_list = &dev->amthi_read_complete_list. 1415 mei_cb.cb_list; 1416 1417 list_for_each_entry_safe(cb_pos, cb_next, amthi_complete_list, cb_list) { 1418 1419 cl_pos = cb_pos->file_object->private_data; 1420 1421 /* Finding the AMTHI entry. */ 1422 if (cl_pos == &dev->iamthif_cl) 1423 list_del(&cb_pos->cb_list); 1424 } 1425 if (dev->iamthif_current_cb) 1426 mei_free_cb_private(dev->iamthif_current_cb); 1427 1428 dev->iamthif_file_object->private_data = NULL; 1429 dev->iamthif_file_object = NULL; 1430 dev->iamthif_current_cb = NULL; 1431 dev->iamthif_timer = 0; 1432 mei_run_next_iamthif_cmd(dev); 1433 1434 } 1435 } 1436 out: 1437 schedule_delayed_work(&dev->timer_work, 2 * HZ); 1438 mutex_unlock(&dev->device_lock); 1439 } 1440 1441 /** 1442 * mei_interrupt_thread_handler - function called after ISR to handle the interrupt 1443 * processing. 1444 * 1445 * @irq: The irq number 1446 * @dev_id: pointer to the device structure 1447 * 1448 * returns irqreturn_t 1449 * 1450 */ 1451 irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) 1452 { 1453 struct mei_device *dev = (struct mei_device *) dev_id; 1454 struct mei_io_list complete_list; 1455 struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; 1456 struct mei_cl *cl; 1457 s32 slots; 1458 int rets; 1459 bool bus_message_received; 1460 1461 1462 dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n"); 1463 /* initialize our complete list */ 1464 mutex_lock(&dev->device_lock); 1465 mei_io_list_init(&complete_list); 1466 dev->host_hw_state = mei_hcsr_read(dev); 1467 1468 /* Ack the interrupt here 1469 * In case of MSI we don't go through the quick handler */ 1470 if (pci_dev_msi_enabled(dev->pdev)) 1471 mei_reg_write(dev, H_CSR, dev->host_hw_state); 1472 1473 dev->me_hw_state = mei_mecsr_read(dev); 1474 1475 /* check if ME wants a reset */ 1476 if ((dev->me_hw_state & ME_RDY_HRA) == 0 && 1477 dev->dev_state != MEI_DEV_RESETING && 1478 dev->dev_state != MEI_DEV_INITIALIZING) { 1479 dev_dbg(&dev->pdev->dev, "FW not ready.\n"); 1480 mei_reset(dev, 1); 1481 mutex_unlock(&dev->device_lock); 1482 return IRQ_HANDLED; 1483 } 1484 1485 /* check if we need to start the dev */ 1486 if ((dev->host_hw_state & H_RDY) == 0) { 1487 if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) { 1488 dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); 1489 dev->host_hw_state |= (H_IE | H_IG | H_RDY); 1490 mei_hcsr_set(dev); 1491 dev->dev_state = MEI_DEV_INIT_CLIENTS; 1492 dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); 1493 /* link is established 1494 * start sending messages. 1495 */ 1496 mei_host_start_message(dev); 1497 mutex_unlock(&dev->device_lock); 1498 return IRQ_HANDLED; 1499 } else { 1500 dev_dbg(&dev->pdev->dev, "FW not ready.\n"); 1501 mutex_unlock(&dev->device_lock); 1502 return IRQ_HANDLED; 1503 } 1504 } 1505 /* check slots available for reading */ 1506 slots = mei_count_full_read_slots(dev); 1507 dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n", 1508 slots, dev->extra_write_index); 1509 while (slots > 0 && !dev->extra_write_index) { 1510 dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n", 1511 slots, dev->extra_write_index); 1512 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n"); 1513 rets = mei_irq_thread_read_handler(&complete_list, dev, &slots); 1514 if (rets) 1515 goto end; 1516 } 1517 rets = mei_irq_thread_write_handler(&complete_list, dev, &slots); 1518 end: 1519 dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); 1520 dev->host_hw_state = mei_hcsr_read(dev); 1521 dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); 1522 1523 bus_message_received = false; 1524 if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) { 1525 dev_dbg(&dev->pdev->dev, "received waiting bus message\n"); 1526 bus_message_received = true; 1527 } 1528 mutex_unlock(&dev->device_lock); 1529 if (bus_message_received) { 1530 dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n"); 1531 wake_up_interruptible(&dev->wait_recvd_msg); 1532 bus_message_received = false; 1533 } 1534 if (list_empty(&complete_list.mei_cb.cb_list)) 1535 return IRQ_HANDLED; 1536 1537 1538 list_for_each_entry_safe(cb_pos, cb_next, 1539 &complete_list.mei_cb.cb_list, cb_list) { 1540 cl = (struct mei_cl *)cb_pos->file_private; 1541 list_del(&cb_pos->cb_list); 1542 if (cl) { 1543 if (cl != &dev->iamthif_cl) { 1544 dev_dbg(&dev->pdev->dev, "completing call back.\n"); 1545 _mei_cmpl(cl, cb_pos); 1546 cb_pos = NULL; 1547 } else if (cl == &dev->iamthif_cl) { 1548 _mei_cmpl_iamthif(dev, cb_pos); 1549 } 1550 } 1551 } 1552 return IRQ_HANDLED; 1553 } 1554