hbm.c (d6c36a475fccfca05fd05362c98e49f6dd07721c) | hbm.c (9b0d5efc421ac79d9a6d97c681eff93288093784) |
---|---|
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. --- 109 unchanged lines hidden (view full) --- 118 } 119 cl->timer_count = 0; 120 121 return true; 122 } 123 return false; 124} 125 | 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. --- 109 unchanged lines hidden (view full) --- 118 } 119 cl->timer_count = 0; 120 121 return true; 122 } 123 return false; 124} 125 |
126int mei_hbm_start_wait(struct mei_device *dev) 127{ 128 int ret; 129 if (dev->hbm_state > MEI_HBM_START) 130 return 0; 131 132 mutex_unlock(&dev->device_lock); 133 ret = wait_event_interruptible_timeout(dev->wait_recvd_msg, 134 dev->hbm_state == MEI_HBM_IDLE || 135 dev->hbm_state > MEI_HBM_START, 136 mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT)); 137 mutex_lock(&dev->device_lock); 138 139 if (ret <= 0 && (dev->hbm_state <= MEI_HBM_START)) { 140 dev->hbm_state = MEI_HBM_IDLE; 141 dev_err(&dev->pdev->dev, "wating for mei start failed\n"); 142 return -ETIMEDOUT; 143 } 144 return 0; 145} 146 |
|
126/** 127 * mei_hbm_start_req - sends start request message. 128 * 129 * @dev: the device structure 130 */ | 147/** 148 * mei_hbm_start_req - sends start request message. 149 * 150 * @dev: the device structure 151 */ |
131void mei_hbm_start_req(struct mei_device *dev) | 152int mei_hbm_start_req(struct mei_device *dev) |
132{ 133 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 134 struct hbm_host_version_request *start_req; 135 const size_t len = sizeof(struct hbm_host_version_request); 136 137 mei_hbm_hdr(mei_hdr, len); 138 139 /* host start message */ 140 start_req = (struct hbm_host_version_request *)dev->wr_msg.data; 141 memset(start_req, 0, len); 142 start_req->hbm_cmd = HOST_START_REQ_CMD; 143 start_req->host_version.major_version = HBM_MAJOR_VERSION; 144 start_req->host_version.minor_version = HBM_MINOR_VERSION; 145 | 153{ 154 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; 155 struct hbm_host_version_request *start_req; 156 const size_t len = sizeof(struct hbm_host_version_request); 157 158 mei_hbm_hdr(mei_hdr, len); 159 160 /* host start message */ 161 start_req = (struct hbm_host_version_request *)dev->wr_msg.data; 162 memset(start_req, 0, len); 163 start_req->hbm_cmd = HOST_START_REQ_CMD; 164 start_req->host_version.major_version = HBM_MAJOR_VERSION; 165 start_req->host_version.minor_version = HBM_MINOR_VERSION; 166 |
146 dev->recvd_msg = false; | 167 dev->hbm_state = MEI_HBM_IDLE; |
147 if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { 148 dev_err(&dev->pdev->dev, "version message writet failed\n"); 149 dev->dev_state = MEI_DEV_RESETING; 150 mei_reset(dev, 1); | 168 if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { 169 dev_err(&dev->pdev->dev, "version message writet failed\n"); 170 dev->dev_state = MEI_DEV_RESETING; 171 mei_reset(dev, 1); |
172 return -ENODEV; |
|
151 } | 173 } |
152 dev->init_clients_state = MEI_START_MESSAGE; | 174 dev->hbm_state = MEI_HBM_START; |
153 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; | 175 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; |
154 return ; | 176 return 0; |
155} 156 | 177} 178 |
157/** | 179/* |
158 * mei_hbm_enum_clients_req - sends enumeration client request message. 159 * 160 * @dev: the device structure 161 * 162 * returns none. 163 */ 164static void mei_hbm_enum_clients_req(struct mei_device *dev) 165{ --- 7 unchanged lines hidden (view full) --- 173 memset(enum_req, 0, len); 174 enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; 175 176 if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { 177 dev->dev_state = MEI_DEV_RESETING; 178 dev_err(&dev->pdev->dev, "enumeration request write failed.\n"); 179 mei_reset(dev, 1); 180 } | 180 * mei_hbm_enum_clients_req - sends enumeration client request message. 181 * 182 * @dev: the device structure 183 * 184 * returns none. 185 */ 186static void mei_hbm_enum_clients_req(struct mei_device *dev) 187{ --- 7 unchanged lines hidden (view full) --- 195 memset(enum_req, 0, len); 196 enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; 197 198 if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { 199 dev->dev_state = MEI_DEV_RESETING; 200 dev_err(&dev->pdev->dev, "enumeration request write failed.\n"); 201 mei_reset(dev, 1); 202 } |
181 dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE; | 203 dev->hbm_state = MEI_HBM_ENUM_CLIENTS; |
182 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 183 return; 184} 185 186/** 187 * mei_hbm_prop_requsest - request property for a single client 188 * 189 * @dev: the device structure --- 13 unchanged lines hidden (view full) --- 203 204 client_num = dev->me_client_presentation_num; 205 206 next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, 207 dev->me_client_index); 208 209 /* We got all client properties */ 210 if (next_client_index == MEI_CLIENTS_MAX) { | 204 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 205 return; 206} 207 208/** 209 * mei_hbm_prop_requsest - request property for a single client 210 * 211 * @dev: the device structure --- 13 unchanged lines hidden (view full) --- 225 226 client_num = dev->me_client_presentation_num; 227 228 next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, 229 dev->me_client_index); 230 231 /* We got all client properties */ 232 if (next_client_index == MEI_CLIENTS_MAX) { |
233 dev->hbm_state = MEI_HBM_STARTED; |
|
211 schedule_work(&dev->init_work); 212 213 return 0; 214 } 215 216 dev->me_clients[client_num].client_id = next_client_index; 217 dev->me_clients[client_num].mei_flow_ctrl_creds = 0; 218 --- 318 unchanged lines hidden (view full) --- 537 538 switch (mei_msg->hbm_cmd) { 539 case HOST_START_RES_CMD: 540 version_res = (struct hbm_host_version_response *)mei_msg; 541 if (!version_res->host_version_supported) { 542 dev->version = version_res->me_max_version; 543 dev_dbg(&dev->pdev->dev, "version mismatch.\n"); 544 | 234 schedule_work(&dev->init_work); 235 236 return 0; 237 } 238 239 dev->me_clients[client_num].client_id = next_client_index; 240 dev->me_clients[client_num].mei_flow_ctrl_creds = 0; 241 --- 318 unchanged lines hidden (view full) --- 560 561 switch (mei_msg->hbm_cmd) { 562 case HOST_START_RES_CMD: 563 version_res = (struct hbm_host_version_response *)mei_msg; 564 if (!version_res->host_version_supported) { 565 dev->version = version_res->me_max_version; 566 dev_dbg(&dev->pdev->dev, "version mismatch.\n"); 567 |
568 dev->hbm_state = MEI_HBM_STOP; |
|
545 mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr, 546 dev->wr_msg.data); 547 mei_write_message(dev, &dev->wr_msg.hdr, 548 dev->wr_msg.data); | 569 mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr, 570 dev->wr_msg.data); 571 mei_write_message(dev, &dev->wr_msg.hdr, 572 dev->wr_msg.data); |
573 |
|
549 return; 550 } 551 552 dev->version.major_version = HBM_MAJOR_VERSION; 553 dev->version.minor_version = HBM_MINOR_VERSION; 554 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && | 574 return; 575 } 576 577 dev->version.major_version = HBM_MAJOR_VERSION; 578 dev->version.minor_version = HBM_MINOR_VERSION; 579 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && |
555 dev->init_clients_state == MEI_START_MESSAGE) { | 580 dev->hbm_state == MEI_HBM_START) { |
556 dev->init_clients_timer = 0; 557 mei_hbm_enum_clients_req(dev); 558 } else { | 581 dev->init_clients_timer = 0; 582 mei_hbm_enum_clients_req(dev); 583 } else { |
559 dev->recvd_msg = false; | |
560 dev_err(&dev->pdev->dev, "reset: wrong host start response\n"); 561 mei_reset(dev, 1); 562 return; 563 } 564 | 584 dev_err(&dev->pdev->dev, "reset: wrong host start response\n"); 585 mei_reset(dev, 1); 586 return; 587 } 588 |
565 dev->recvd_msg = true; | 589 wake_up_interruptible(&dev->wait_recvd_msg); |
566 dev_dbg(&dev->pdev->dev, "host start response message received.\n"); 567 break; 568 569 case CLIENT_CONNECT_RES_CMD: 570 connect_res = (struct hbm_client_connect_response *) mei_msg; 571 mei_hbm_cl_connect_res(dev, connect_res); 572 dev_dbg(&dev->pdev->dev, "client connect response message received.\n"); 573 wake_up(&dev->wait_recvd_msg); --- 24 unchanged lines hidden (view full) --- 598 599 if (me_client->client_id != props_res->address) { 600 dev_err(&dev->pdev->dev, "reset: host properties response address mismatch\n"); 601 mei_reset(dev, 1); 602 return; 603 } 604 605 if (dev->dev_state != MEI_DEV_INIT_CLIENTS || | 590 dev_dbg(&dev->pdev->dev, "host start response message received.\n"); 591 break; 592 593 case CLIENT_CONNECT_RES_CMD: 594 connect_res = (struct hbm_client_connect_response *) mei_msg; 595 mei_hbm_cl_connect_res(dev, connect_res); 596 dev_dbg(&dev->pdev->dev, "client connect response message received.\n"); 597 wake_up(&dev->wait_recvd_msg); --- 24 unchanged lines hidden (view full) --- 622 623 if (me_client->client_id != props_res->address) { 624 dev_err(&dev->pdev->dev, "reset: host properties response address mismatch\n"); 625 mei_reset(dev, 1); 626 return; 627 } 628 629 if (dev->dev_state != MEI_DEV_INIT_CLIENTS || |
606 dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) { | 630 dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) { |
607 dev_err(&dev->pdev->dev, "reset: unexpected properties response\n"); 608 mei_reset(dev, 1); 609 610 return; 611 } 612 613 me_client->props = props_res->client_properties; 614 dev->me_client_index++; 615 dev->me_client_presentation_num++; 616 617 /* request property for the next client */ 618 mei_hbm_prop_req(dev); 619 620 break; 621 622 case HOST_ENUM_RES_CMD: 623 enum_res = (struct hbm_host_enum_response *) mei_msg; 624 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); 625 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && | 631 dev_err(&dev->pdev->dev, "reset: unexpected properties response\n"); 632 mei_reset(dev, 1); 633 634 return; 635 } 636 637 me_client->props = props_res->client_properties; 638 dev->me_client_index++; 639 dev->me_client_presentation_num++; 640 641 /* request property for the next client */ 642 mei_hbm_prop_req(dev); 643 644 break; 645 646 case HOST_ENUM_RES_CMD: 647 enum_res = (struct hbm_host_enum_response *) mei_msg; 648 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); 649 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && |
626 dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) { | 650 dev->hbm_state == MEI_HBM_ENUM_CLIENTS) { |
627 dev->init_clients_timer = 0; 628 dev->me_client_presentation_num = 0; 629 dev->me_client_index = 0; 630 mei_hbm_me_cl_allocate(dev); | 651 dev->init_clients_timer = 0; 652 dev->me_client_presentation_num = 0; 653 dev->me_client_index = 0; 654 mei_hbm_me_cl_allocate(dev); |
631 dev->init_clients_state = 632 MEI_CLIENT_PROPERTIES_MESSAGE; | 655 dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES; |
633 634 /* first property reqeust */ 635 mei_hbm_prop_req(dev); 636 } else { 637 dev_err(&dev->pdev->dev, "reset: unexpected enumeration response hbm.\n"); 638 mei_reset(dev, 1); 639 return; 640 } 641 break; 642 643 case HOST_STOP_RES_CMD: | 656 657 /* first property reqeust */ 658 mei_hbm_prop_req(dev); 659 } else { 660 dev_err(&dev->pdev->dev, "reset: unexpected enumeration response hbm.\n"); 661 mei_reset(dev, 1); 662 return; 663 } 664 break; 665 666 case HOST_STOP_RES_CMD: |
667 668 if (dev->hbm_state != MEI_HBM_STOP) 669 dev_err(&dev->pdev->dev, "unexpected stop response hbm.\n"); |
|
644 dev->dev_state = MEI_DEV_DISABLED; 645 dev_info(&dev->pdev->dev, "reset: FW stop response.\n"); 646 mei_reset(dev, 1); 647 break; 648 649 case CLIENT_DISCONNECT_REQ_CMD: 650 /* search for client */ 651 disconnect_req = (struct hbm_client_connect_request *)mei_msg; 652 mei_hbm_fw_disconnect_req(dev, disconnect_req); 653 break; 654 655 case ME_STOP_REQ_CMD: 656 | 670 dev->dev_state = MEI_DEV_DISABLED; 671 dev_info(&dev->pdev->dev, "reset: FW stop response.\n"); 672 mei_reset(dev, 1); 673 break; 674 675 case CLIENT_DISCONNECT_REQ_CMD: 676 /* search for client */ 677 disconnect_req = (struct hbm_client_connect_request *)mei_msg; 678 mei_hbm_fw_disconnect_req(dev, disconnect_req); 679 break; 680 681 case ME_STOP_REQ_CMD: 682 |
683 dev->hbm_state = MEI_HBM_STOP; |
|
657 mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr, 658 dev->wr_ext_msg.data); 659 break; 660 default: 661 BUG(); 662 break; 663 664 } 665} 666 | 684 mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr, 685 dev->wr_ext_msg.data); 686 break; 687 default: 688 BUG(); 689 break; 690 691 } 692} 693 |