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 #include <linux/export.h> 18 #include <linux/pci.h> 19 #include <linux/sched.h> 20 #include <linux/wait.h> 21 #include <linux/mei.h> 22 #include <linux/pm_runtime.h> 23 24 #include "mei_dev.h" 25 #include "hbm.h" 26 #include "client.h" 27 28 static const char *mei_cl_conn_status_str(enum mei_cl_connect_status status) 29 { 30 #define MEI_CL_CS(status) case MEI_CL_CONN_##status: return #status 31 switch (status) { 32 MEI_CL_CS(SUCCESS); 33 MEI_CL_CS(NOT_FOUND); 34 MEI_CL_CS(ALREADY_STARTED); 35 MEI_CL_CS(OUT_OF_RESOURCES); 36 MEI_CL_CS(MESSAGE_SMALL); 37 default: return "unknown"; 38 } 39 #undef MEI_CL_CCS 40 } 41 42 /** 43 * mei_cl_conn_status_to_errno - convert client connect response 44 * status to error code 45 * 46 * @status: client connect response status 47 * 48 * returns corresponding error code 49 */ 50 static int mei_cl_conn_status_to_errno(enum mei_cl_connect_status status) 51 { 52 switch (status) { 53 case MEI_CL_CONN_SUCCESS: return 0; 54 case MEI_CL_CONN_NOT_FOUND: return -ENOTTY; 55 case MEI_CL_CONN_ALREADY_STARTED: return -EBUSY; 56 case MEI_CL_CONN_OUT_OF_RESOURCES: return -EBUSY; 57 case MEI_CL_CONN_MESSAGE_SMALL: return -EINVAL; 58 default: return -EINVAL; 59 } 60 } 61 62 /** 63 * mei_hbm_idle - set hbm to idle state 64 * 65 * @dev: the device structure 66 */ 67 void mei_hbm_idle(struct mei_device *dev) 68 { 69 dev->init_clients_timer = 0; 70 dev->hbm_state = MEI_HBM_IDLE; 71 } 72 73 /** 74 * mei_hbm_reset - reset hbm counters and book keeping data structurs 75 * 76 * @dev: the device structure 77 */ 78 void mei_hbm_reset(struct mei_device *dev) 79 { 80 dev->me_clients_num = 0; 81 dev->me_client_presentation_num = 0; 82 dev->me_client_index = 0; 83 84 kfree(dev->me_clients); 85 dev->me_clients = NULL; 86 87 mei_hbm_idle(dev); 88 } 89 90 /** 91 * mei_hbm_me_cl_allocate - allocates storage for me clients 92 * 93 * @dev: the device structure 94 * 95 * returns 0 on success -ENOMEM on allocation failure 96 */ 97 static int mei_hbm_me_cl_allocate(struct mei_device *dev) 98 { 99 struct mei_me_client *clients; 100 int b; 101 102 mei_hbm_reset(dev); 103 104 /* count how many ME clients we have */ 105 for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX) 106 dev->me_clients_num++; 107 108 if (dev->me_clients_num == 0) 109 return 0; 110 111 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%ld.\n", 112 dev->me_clients_num * sizeof(struct mei_me_client)); 113 /* allocate storage for ME clients representation */ 114 clients = kcalloc(dev->me_clients_num, 115 sizeof(struct mei_me_client), GFP_KERNEL); 116 if (!clients) { 117 dev_err(&dev->pdev->dev, "memory allocation for ME clients failed.\n"); 118 return -ENOMEM; 119 } 120 dev->me_clients = clients; 121 return 0; 122 } 123 124 /** 125 * mei_hbm_cl_hdr - construct client hbm header 126 * 127 * @cl: - client 128 * @hbm_cmd: host bus message command 129 * @buf: buffer for cl header 130 * @len: buffer length 131 */ 132 static inline 133 void mei_hbm_cl_hdr(struct mei_cl *cl, u8 hbm_cmd, void *buf, size_t len) 134 { 135 struct mei_hbm_cl_cmd *cmd = buf; 136 137 memset(cmd, 0, len); 138 139 cmd->hbm_cmd = hbm_cmd; 140 cmd->host_addr = cl->host_client_id; 141 cmd->me_addr = cl->me_client_id; 142 } 143 144 /** 145 * mei_hbm_cl_addr_equal - tells if they have the same address 146 * 147 * @cl: - client 148 * @buf: buffer with cl header 149 * 150 * returns true if addresses are the same 151 */ 152 static inline 153 bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf) 154 { 155 struct mei_hbm_cl_cmd *cmd = buf; 156 return cl->host_client_id == cmd->host_addr && 157 cl->me_client_id == cmd->me_addr; 158 } 159 160 161 int mei_hbm_start_wait(struct mei_device *dev) 162 { 163 int ret; 164 if (dev->hbm_state > MEI_HBM_START) 165 return 0; 166 167 mutex_unlock(&dev->device_lock); 168 ret = wait_event_interruptible_timeout(dev->wait_recvd_msg, 169 dev->hbm_state == MEI_HBM_IDLE || 170 dev->hbm_state >= MEI_HBM_STARTED, 171 mei_secs_to_jiffies(MEI_HBM_TIMEOUT)); 172 mutex_lock(&dev->device_lock); 173 174 if (ret <= 0 && (dev->hbm_state <= MEI_HBM_START)) { 175 dev->hbm_state = MEI_HBM_IDLE; 176 dev_err(&dev->pdev->dev, "waiting for mei start failed\n"); 177 return -ETIME; 178 } 179 return 0; 180 } 181 182 /** 183 * mei_hbm_start_req - sends start request message. 184 * 185 * @dev: the device structure 186 * 187 * returns 0 on success and < 0 on failure 188 */ 189 int mei_hbm_start_req(struct mei_device *dev) 190 { 191 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 192 struct hbm_host_version_request *start_req; 193 const size_t len = sizeof(struct hbm_host_version_request); 194 int ret; 195 196 mei_hbm_hdr(mei_hdr, len); 197 198 /* host start message */ 199 start_req = (struct hbm_host_version_request *)dev->wr_msg.data; 200 memset(start_req, 0, len); 201 start_req->hbm_cmd = HOST_START_REQ_CMD; 202 start_req->host_version.major_version = HBM_MAJOR_VERSION; 203 start_req->host_version.minor_version = HBM_MINOR_VERSION; 204 205 dev->hbm_state = MEI_HBM_IDLE; 206 ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); 207 if (ret) { 208 dev_err(&dev->pdev->dev, "version message write failed: ret = %d\n", 209 ret); 210 return ret; 211 } 212 213 dev->hbm_state = MEI_HBM_START; 214 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 215 return 0; 216 } 217 218 /* 219 * mei_hbm_enum_clients_req - sends enumeration client request message. 220 * 221 * @dev: the device structure 222 * 223 * returns 0 on success and < 0 on failure 224 */ 225 static int mei_hbm_enum_clients_req(struct mei_device *dev) 226 { 227 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 228 struct hbm_host_enum_request *enum_req; 229 const size_t len = sizeof(struct hbm_host_enum_request); 230 int ret; 231 232 /* enumerate clients */ 233 mei_hbm_hdr(mei_hdr, len); 234 235 enum_req = (struct hbm_host_enum_request *)dev->wr_msg.data; 236 memset(enum_req, 0, len); 237 enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; 238 239 ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); 240 if (ret) { 241 dev_err(&dev->pdev->dev, "enumeration request write failed: ret = %d.\n", 242 ret); 243 return ret; 244 } 245 dev->hbm_state = MEI_HBM_ENUM_CLIENTS; 246 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 247 return 0; 248 } 249 250 /** 251 * mei_hbm_prop_req - request property for a single client 252 * 253 * @dev: the device structure 254 * 255 * returns 0 on success and < 0 on failure 256 */ 257 258 static int mei_hbm_prop_req(struct mei_device *dev) 259 { 260 261 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 262 struct hbm_props_request *prop_req; 263 const size_t len = sizeof(struct hbm_props_request); 264 unsigned long next_client_index; 265 unsigned long client_num; 266 int ret; 267 268 client_num = dev->me_client_presentation_num; 269 270 next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, 271 dev->me_client_index); 272 273 /* We got all client properties */ 274 if (next_client_index == MEI_CLIENTS_MAX) { 275 dev->hbm_state = MEI_HBM_STARTED; 276 schedule_work(&dev->init_work); 277 278 return 0; 279 } 280 281 dev->me_clients[client_num].client_id = next_client_index; 282 dev->me_clients[client_num].mei_flow_ctrl_creds = 0; 283 284 mei_hbm_hdr(mei_hdr, len); 285 prop_req = (struct hbm_props_request *)dev->wr_msg.data; 286 287 memset(prop_req, 0, sizeof(struct hbm_props_request)); 288 289 290 prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; 291 prop_req->address = next_client_index; 292 293 ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); 294 if (ret) { 295 dev_err(&dev->pdev->dev, "properties request write failed: ret = %d\n", 296 ret); 297 return ret; 298 } 299 300 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 301 dev->me_client_index = next_client_index; 302 303 return 0; 304 } 305 306 /* 307 * mei_hbm_pg - sends pg command 308 * 309 * @dev: the device structure 310 * @pg_cmd: the pg command code 311 * 312 * This function returns -EIO on write failure 313 */ 314 int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd) 315 { 316 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 317 struct hbm_power_gate *req; 318 const size_t len = sizeof(struct hbm_power_gate); 319 int ret; 320 321 mei_hbm_hdr(mei_hdr, len); 322 323 req = (struct hbm_power_gate *)dev->wr_msg.data; 324 memset(req, 0, len); 325 req->hbm_cmd = pg_cmd; 326 327 ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); 328 if (ret) 329 dev_err(&dev->pdev->dev, "power gate command write failed.\n"); 330 return ret; 331 } 332 EXPORT_SYMBOL_GPL(mei_hbm_pg); 333 334 /** 335 * mei_hbm_stop_req - send stop request message 336 * 337 * @dev - mei device 338 * @cl: client info 339 * 340 * This function returns -EIO on write failure 341 */ 342 static int mei_hbm_stop_req(struct mei_device *dev) 343 { 344 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 345 struct hbm_host_stop_request *req = 346 (struct hbm_host_stop_request *)dev->wr_msg.data; 347 const size_t len = sizeof(struct hbm_host_stop_request); 348 349 mei_hbm_hdr(mei_hdr, len); 350 351 memset(req, 0, len); 352 req->hbm_cmd = HOST_STOP_REQ_CMD; 353 req->reason = DRIVER_STOP_REQUEST; 354 355 return mei_write_message(dev, mei_hdr, dev->wr_msg.data); 356 } 357 358 /** 359 * mei_hbm_cl_flow_control_req - sends flow control request. 360 * 361 * @dev: the device structure 362 * @cl: client info 363 * 364 * This function returns -EIO on write failure 365 */ 366 int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl) 367 { 368 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 369 const size_t len = sizeof(struct hbm_flow_control); 370 371 mei_hbm_hdr(mei_hdr, len); 372 mei_hbm_cl_hdr(cl, MEI_FLOW_CONTROL_CMD, dev->wr_msg.data, len); 373 374 cl_dbg(dev, cl, "sending flow control\n"); 375 376 return mei_write_message(dev, mei_hdr, dev->wr_msg.data); 377 } 378 379 /** 380 * mei_hbm_add_single_flow_creds - adds single buffer credentials. 381 * 382 * @dev: the device structure 383 * @flow: flow control. 384 * 385 * return 0 on success, < 0 otherwise 386 */ 387 static int mei_hbm_add_single_flow_creds(struct mei_device *dev, 388 struct hbm_flow_control *flow) 389 { 390 struct mei_me_client *me_cl; 391 int id; 392 393 id = mei_me_cl_by_id(dev, flow->me_addr); 394 if (id < 0) { 395 dev_err(&dev->pdev->dev, "no such me client %d\n", 396 flow->me_addr); 397 return id; 398 } 399 400 me_cl = &dev->me_clients[id]; 401 if (me_cl->props.single_recv_buf) { 402 me_cl->mei_flow_ctrl_creds++; 403 dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n", 404 flow->me_addr); 405 dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n", 406 me_cl->mei_flow_ctrl_creds); 407 } else { 408 BUG(); /* error in flow control */ 409 } 410 411 return 0; 412 } 413 414 /** 415 * mei_hbm_cl_flow_control_res - flow control response from me 416 * 417 * @dev: the device structure 418 * @flow_control: flow control response bus message 419 */ 420 static void mei_hbm_cl_flow_control_res(struct mei_device *dev, 421 struct hbm_flow_control *flow_control) 422 { 423 struct mei_cl *cl; 424 425 if (!flow_control->host_addr) { 426 /* single receive buffer */ 427 mei_hbm_add_single_flow_creds(dev, flow_control); 428 return; 429 } 430 431 /* normal connection */ 432 list_for_each_entry(cl, &dev->file_list, link) { 433 if (mei_hbm_cl_addr_equal(cl, flow_control)) { 434 cl->mei_flow_ctrl_creds++; 435 dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n", 436 flow_control->host_addr, flow_control->me_addr); 437 dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n", 438 cl->mei_flow_ctrl_creds); 439 break; 440 } 441 } 442 } 443 444 445 /** 446 * mei_hbm_cl_disconnect_req - sends disconnect message to fw. 447 * 448 * @dev: the device structure 449 * @cl: a client to disconnect from 450 * 451 * This function returns -EIO on write failure 452 */ 453 int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl) 454 { 455 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 456 const size_t len = sizeof(struct hbm_client_connect_request); 457 458 mei_hbm_hdr(mei_hdr, len); 459 mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_REQ_CMD, dev->wr_msg.data, len); 460 461 return mei_write_message(dev, mei_hdr, dev->wr_msg.data); 462 } 463 464 /** 465 * mei_hbm_cl_disconnect_rsp - sends disconnect respose to the FW 466 * 467 * @dev: the device structure 468 * @cl: a client to disconnect from 469 * 470 * This function returns -EIO on write failure 471 */ 472 int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl) 473 { 474 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 475 const size_t len = sizeof(struct hbm_client_connect_response); 476 477 mei_hbm_hdr(mei_hdr, len); 478 mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_RES_CMD, dev->wr_msg.data, len); 479 480 return mei_write_message(dev, mei_hdr, dev->wr_msg.data); 481 } 482 483 /** 484 * mei_hbm_cl_disconnect_res - disconnect response from ME 485 * 486 * @dev: the device structure 487 * @rs: disconnect response bus message 488 */ 489 static void mei_hbm_cl_disconnect_res(struct mei_device *dev, 490 struct hbm_client_connect_response *rs) 491 { 492 struct mei_cl *cl; 493 struct mei_cl_cb *cb, *next; 494 495 dev_dbg(&dev->pdev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n", 496 rs->me_addr, rs->host_addr, rs->status); 497 498 list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) { 499 cl = cb->cl; 500 501 /* this should not happen */ 502 if (WARN_ON(!cl)) { 503 list_del(&cb->list); 504 return; 505 } 506 507 if (mei_hbm_cl_addr_equal(cl, rs)) { 508 list_del(&cb->list); 509 if (rs->status == MEI_CL_DISCONN_SUCCESS) 510 cl->state = MEI_FILE_DISCONNECTED; 511 512 cl->status = 0; 513 cl->timer_count = 0; 514 break; 515 } 516 } 517 } 518 519 /** 520 * mei_hbm_cl_connect_req - send connection request to specific me client 521 * 522 * @dev: the device structure 523 * @cl: a client to connect to 524 * 525 * returns -EIO on write failure 526 */ 527 int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl) 528 { 529 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 530 const size_t len = sizeof(struct hbm_client_connect_request); 531 532 mei_hbm_hdr(mei_hdr, len); 533 mei_hbm_cl_hdr(cl, CLIENT_CONNECT_REQ_CMD, dev->wr_msg.data, len); 534 535 return mei_write_message(dev, mei_hdr, dev->wr_msg.data); 536 } 537 538 /** 539 * mei_hbm_cl_connect_res - connect response from the ME 540 * 541 * @dev: the device structure 542 * @rs: connect response bus message 543 */ 544 static void mei_hbm_cl_connect_res(struct mei_device *dev, 545 struct hbm_client_connect_response *rs) 546 { 547 548 struct mei_cl *cl; 549 struct mei_cl_cb *cb, *next; 550 551 dev_dbg(&dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n", 552 rs->me_addr, rs->host_addr, 553 mei_cl_conn_status_str(rs->status)); 554 555 cl = NULL; 556 557 list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) { 558 559 cl = cb->cl; 560 /* this should not happen */ 561 if (WARN_ON(!cl)) { 562 list_del_init(&cb->list); 563 continue; 564 } 565 566 if (cb->fop_type != MEI_FOP_CONNECT) 567 continue; 568 569 if (mei_hbm_cl_addr_equal(cl, rs)) { 570 list_del(&cb->list); 571 break; 572 } 573 } 574 575 if (!cl) 576 return; 577 578 cl->timer_count = 0; 579 if (rs->status == MEI_CL_CONN_SUCCESS) 580 cl->state = MEI_FILE_CONNECTED; 581 else 582 cl->state = MEI_FILE_DISCONNECTED; 583 cl->status = mei_cl_conn_status_to_errno(rs->status); 584 } 585 586 587 /** 588 * mei_hbm_fw_disconnect_req - disconnect request initiated by ME firmware 589 * host sends disconnect response 590 * 591 * @dev: the device structure. 592 * @disconnect_req: disconnect request bus message from the me 593 * 594 * returns -ENOMEM on allocation failure 595 */ 596 static int mei_hbm_fw_disconnect_req(struct mei_device *dev, 597 struct hbm_client_connect_request *disconnect_req) 598 { 599 struct mei_cl *cl; 600 struct mei_cl_cb *cb; 601 602 list_for_each_entry(cl, &dev->file_list, link) { 603 if (mei_hbm_cl_addr_equal(cl, disconnect_req)) { 604 dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n", 605 disconnect_req->host_addr, 606 disconnect_req->me_addr); 607 cl->state = MEI_FILE_DISCONNECTED; 608 cl->timer_count = 0; 609 610 cb = mei_io_cb_init(cl, NULL); 611 if (!cb) 612 return -ENOMEM; 613 cb->fop_type = MEI_FOP_DISCONNECT_RSP; 614 cl_dbg(dev, cl, "add disconnect response as first\n"); 615 list_add(&cb->list, &dev->ctrl_wr_list.list); 616 617 break; 618 } 619 } 620 return 0; 621 } 622 623 624 /** 625 * mei_hbm_version_is_supported - checks whether the driver can 626 * support the hbm version of the device 627 * 628 * @dev: the device structure 629 * returns true if driver can support hbm version of the device 630 */ 631 bool mei_hbm_version_is_supported(struct mei_device *dev) 632 { 633 return (dev->version.major_version < HBM_MAJOR_VERSION) || 634 (dev->version.major_version == HBM_MAJOR_VERSION && 635 dev->version.minor_version <= HBM_MINOR_VERSION); 636 } 637 638 /** 639 * mei_hbm_dispatch - bottom half read routine after ISR to 640 * handle the read bus message cmd processing. 641 * 642 * @dev: the device structure 643 * @mei_hdr: header of bus message 644 * 645 * returns 0 on success and < 0 on failure 646 */ 647 int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) 648 { 649 struct mei_bus_message *mei_msg; 650 struct mei_me_client *me_client; 651 struct hbm_host_version_response *version_res; 652 struct hbm_client_connect_response *connect_res; 653 struct hbm_client_connect_response *disconnect_res; 654 struct hbm_client_connect_request *disconnect_req; 655 struct hbm_flow_control *flow_control; 656 struct hbm_props_response *props_res; 657 struct hbm_host_enum_response *enum_res; 658 659 /* read the message to our buffer */ 660 BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf)); 661 mei_read_slots(dev, dev->rd_msg_buf, hdr->length); 662 mei_msg = (struct mei_bus_message *)dev->rd_msg_buf; 663 664 /* ignore spurious message and prevent reset nesting 665 * hbm is put to idle during system reset 666 */ 667 if (dev->hbm_state == MEI_HBM_IDLE) { 668 dev_dbg(&dev->pdev->dev, "hbm: state is idle ignore spurious messages\n"); 669 return 0; 670 } 671 672 switch (mei_msg->hbm_cmd) { 673 case HOST_START_RES_CMD: 674 dev_dbg(&dev->pdev->dev, "hbm: start: response message received.\n"); 675 676 dev->init_clients_timer = 0; 677 678 version_res = (struct hbm_host_version_response *)mei_msg; 679 680 dev_dbg(&dev->pdev->dev, "HBM VERSION: DRIVER=%02d:%02d DEVICE=%02d:%02d\n", 681 HBM_MAJOR_VERSION, HBM_MINOR_VERSION, 682 version_res->me_max_version.major_version, 683 version_res->me_max_version.minor_version); 684 685 if (version_res->host_version_supported) { 686 dev->version.major_version = HBM_MAJOR_VERSION; 687 dev->version.minor_version = HBM_MINOR_VERSION; 688 } else { 689 dev->version.major_version = 690 version_res->me_max_version.major_version; 691 dev->version.minor_version = 692 version_res->me_max_version.minor_version; 693 } 694 695 if (!mei_hbm_version_is_supported(dev)) { 696 dev_warn(&dev->pdev->dev, "hbm: start: version mismatch - stopping the driver.\n"); 697 698 dev->hbm_state = MEI_HBM_STOPPED; 699 if (mei_hbm_stop_req(dev)) { 700 dev_err(&dev->pdev->dev, "hbm: start: failed to send stop request\n"); 701 return -EIO; 702 } 703 break; 704 } 705 706 if (dev->dev_state != MEI_DEV_INIT_CLIENTS || 707 dev->hbm_state != MEI_HBM_START) { 708 dev_err(&dev->pdev->dev, "hbm: start: state mismatch, [%d, %d]\n", 709 dev->dev_state, dev->hbm_state); 710 return -EPROTO; 711 } 712 713 dev->hbm_state = MEI_HBM_STARTED; 714 715 if (mei_hbm_enum_clients_req(dev)) { 716 dev_err(&dev->pdev->dev, "hbm: start: failed to send enumeration request\n"); 717 return -EIO; 718 } 719 720 wake_up_interruptible(&dev->wait_recvd_msg); 721 break; 722 723 case CLIENT_CONNECT_RES_CMD: 724 dev_dbg(&dev->pdev->dev, "hbm: client connect response: message received.\n"); 725 726 connect_res = (struct hbm_client_connect_response *) mei_msg; 727 mei_hbm_cl_connect_res(dev, connect_res); 728 wake_up(&dev->wait_recvd_msg); 729 break; 730 731 case CLIENT_DISCONNECT_RES_CMD: 732 dev_dbg(&dev->pdev->dev, "hbm: client disconnect response: message received.\n"); 733 734 disconnect_res = (struct hbm_client_connect_response *) mei_msg; 735 mei_hbm_cl_disconnect_res(dev, disconnect_res); 736 wake_up(&dev->wait_recvd_msg); 737 break; 738 739 case MEI_FLOW_CONTROL_CMD: 740 dev_dbg(&dev->pdev->dev, "hbm: client flow control response: message received.\n"); 741 742 flow_control = (struct hbm_flow_control *) mei_msg; 743 mei_hbm_cl_flow_control_res(dev, flow_control); 744 break; 745 746 case MEI_PG_ISOLATION_ENTRY_RES_CMD: 747 dev_dbg(&dev->pdev->dev, "power gate isolation entry response received\n"); 748 dev->pg_event = MEI_PG_EVENT_RECEIVED; 749 if (waitqueue_active(&dev->wait_pg)) 750 wake_up(&dev->wait_pg); 751 break; 752 753 case MEI_PG_ISOLATION_EXIT_REQ_CMD: 754 dev_dbg(&dev->pdev->dev, "power gate isolation exit request received\n"); 755 dev->pg_event = MEI_PG_EVENT_RECEIVED; 756 if (waitqueue_active(&dev->wait_pg)) 757 wake_up(&dev->wait_pg); 758 else 759 /* 760 * If the driver is not waiting on this then 761 * this is HW initiated exit from PG. 762 * Start runtime pm resume sequence to exit from PG. 763 */ 764 pm_request_resume(&dev->pdev->dev); 765 break; 766 767 case HOST_CLIENT_PROPERTIES_RES_CMD: 768 dev_dbg(&dev->pdev->dev, "hbm: properties response: message received.\n"); 769 770 dev->init_clients_timer = 0; 771 772 if (dev->me_clients == NULL) { 773 dev_err(&dev->pdev->dev, "hbm: properties response: mei_clients not allocated\n"); 774 return -EPROTO; 775 } 776 777 props_res = (struct hbm_props_response *)mei_msg; 778 me_client = &dev->me_clients[dev->me_client_presentation_num]; 779 780 if (props_res->status) { 781 dev_err(&dev->pdev->dev, "hbm: properties response: wrong status = %d\n", 782 props_res->status); 783 return -EPROTO; 784 } 785 786 if (me_client->client_id != props_res->address) { 787 dev_err(&dev->pdev->dev, "hbm: properties response: address mismatch %d ?= %d\n", 788 me_client->client_id, props_res->address); 789 return -EPROTO; 790 } 791 792 if (dev->dev_state != MEI_DEV_INIT_CLIENTS || 793 dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) { 794 dev_err(&dev->pdev->dev, "hbm: properties response: state mismatch, [%d, %d]\n", 795 dev->dev_state, dev->hbm_state); 796 return -EPROTO; 797 } 798 799 me_client->props = props_res->client_properties; 800 dev->me_client_index++; 801 dev->me_client_presentation_num++; 802 803 /* request property for the next client */ 804 if (mei_hbm_prop_req(dev)) 805 return -EIO; 806 807 break; 808 809 case HOST_ENUM_RES_CMD: 810 dev_dbg(&dev->pdev->dev, "hbm: enumeration response: message received\n"); 811 812 dev->init_clients_timer = 0; 813 814 enum_res = (struct hbm_host_enum_response *) mei_msg; 815 BUILD_BUG_ON(sizeof(dev->me_clients_map) 816 < sizeof(enum_res->valid_addresses)); 817 memcpy(dev->me_clients_map, enum_res->valid_addresses, 818 sizeof(enum_res->valid_addresses)); 819 820 if (dev->dev_state != MEI_DEV_INIT_CLIENTS || 821 dev->hbm_state != MEI_HBM_ENUM_CLIENTS) { 822 dev_err(&dev->pdev->dev, "hbm: enumeration response: state mismatch, [%d, %d]\n", 823 dev->dev_state, dev->hbm_state); 824 return -EPROTO; 825 } 826 827 if (mei_hbm_me_cl_allocate(dev)) { 828 dev_err(&dev->pdev->dev, "hbm: enumeration response: cannot allocate clients array\n"); 829 return -ENOMEM; 830 } 831 832 dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES; 833 834 /* first property request */ 835 if (mei_hbm_prop_req(dev)) 836 return -EIO; 837 838 break; 839 840 case HOST_STOP_RES_CMD: 841 dev_dbg(&dev->pdev->dev, "hbm: stop response: message received\n"); 842 843 dev->init_clients_timer = 0; 844 845 if (dev->hbm_state != MEI_HBM_STOPPED) { 846 dev_err(&dev->pdev->dev, "hbm: stop response: state mismatch, [%d, %d]\n", 847 dev->dev_state, dev->hbm_state); 848 return -EPROTO; 849 } 850 851 dev->dev_state = MEI_DEV_POWER_DOWN; 852 dev_info(&dev->pdev->dev, "hbm: stop response: resetting.\n"); 853 /* force the reset */ 854 return -EPROTO; 855 break; 856 857 case CLIENT_DISCONNECT_REQ_CMD: 858 dev_dbg(&dev->pdev->dev, "hbm: disconnect request: message received\n"); 859 860 disconnect_req = (struct hbm_client_connect_request *)mei_msg; 861 mei_hbm_fw_disconnect_req(dev, disconnect_req); 862 break; 863 864 case ME_STOP_REQ_CMD: 865 dev_dbg(&dev->pdev->dev, "hbm: stop request: message received\n"); 866 dev->hbm_state = MEI_HBM_STOPPED; 867 if (mei_hbm_stop_req(dev)) { 868 dev_err(&dev->pdev->dev, "hbm: start: failed to send stop request\n"); 869 return -EIO; 870 } 871 break; 872 default: 873 BUG(); 874 break; 875 876 } 877 return 0; 878 } 879 880