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