aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2012-11-18 08:13:20 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-11-21 15:43:58 -0500
commitc1174c0edf546805a0ebc10d5d6154edbb56e1cf (patch)
treef1cc9084b89fa8965db5759d84e3094967575b3a /drivers/misc/mei
parentbe9d87a790765bcc85d8bdab8a9be31cf7457b28 (diff)
mei: Simplify the ME client enumeration code
After enumerating all ME clients we call the client init functions for all matching UUIDs from a separate context. This remove the hackish cascading client initialisation process that was interleaving properties and connection command replies. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r--drivers/misc/mei/init.c99
-rw-r--r--drivers/misc/mei/interrupt.c75
-rw-r--r--drivers/misc/mei/main.c2
-rw-r--r--drivers/misc/mei/mei_dev.h5
4 files changed, 95 insertions, 86 deletions
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 49600d6e3726..a54cd5567ca2 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -423,54 +423,87 @@ void mei_allocate_me_clients_storage(struct mei_device *dev)
423 dev->me_clients = clients; 423 dev->me_clients = clients;
424 return ; 424 return ;
425} 425}
426/** 426
427 * host_client_properties - reads properties for client 427void mei_host_client_init(struct work_struct *work)
428 * 428{
429 * @dev: the device structure 429 struct mei_device *dev = container_of(work,
430 * 430 struct mei_device, init_work);
431 * returns: 431 struct mei_client_properties *client_props;
432 * < 0 - Error. 432 int i;
433 * = 0 - no more clients. 433
434 * = 1 - still have clients to send properties request. 434 mutex_lock(&dev->device_lock);
435 */ 435
436int mei_host_client_properties(struct mei_device *dev) 436 bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
437 dev->open_handle_count = 0;
438
439 /*
440 * Reserving the first three client IDs
441 * 0: Reserved for MEI Bus Message communications
442 * 1: Reserved for Watchdog
443 * 2: Reserved for AMTHI
444 */
445 bitmap_set(dev->host_clients_map, 0, 3);
446
447 for (i = 0; i < dev->me_clients_num; i++) {
448 client_props = &dev->me_clients[i].props;
449
450 if (!uuid_le_cmp(client_props->protocol_name, mei_amthi_guid))
451 mei_amthif_host_init(dev);
452 else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid))
453 mei_wd_host_init(dev);
454 }
455
456 dev->dev_state = MEI_DEV_ENABLED;
457
458 mutex_unlock(&dev->device_lock);
459}
460
461int mei_host_client_enumerate(struct mei_device *dev)
437{ 462{
438 463
439 struct mei_msg_hdr *mei_hdr; 464 struct mei_msg_hdr *mei_hdr;
440 struct hbm_props_request *prop_req; 465 struct hbm_props_request *prop_req;
441 const size_t len = sizeof(struct hbm_props_request); 466 const size_t len = sizeof(struct hbm_props_request);
467 unsigned long next_client_index;
468 u8 client_num;
442 469
443 int b;
444 u8 client_num = dev->me_client_presentation_num;
445 470
446 prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1]; 471 client_num = dev->me_client_presentation_num;
447 472
448 b = dev->me_client_index; 473 next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX,
449 b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b); 474 dev->me_client_index);
450 if (b < MEI_CLIENTS_MAX) {
451 dev->me_clients[client_num].client_id = b;
452 dev->me_clients[client_num].mei_flow_ctrl_creds = 0;
453 mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
454 475
476 /* We got all client properties */
477 if (next_client_index == MEI_CLIENTS_MAX) {
478 schedule_work(&dev->init_work);
455 479
456 memset(prop_req, 0, sizeof(struct hbm_props_request)); 480 return 0;
481 }
457 482
458 prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; 483 dev->me_clients[client_num].client_id = next_client_index;
459 prop_req->address = b; 484 dev->me_clients[client_num].mei_flow_ctrl_creds = 0;
485
486 mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
487 prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1];
488
489 memset(prop_req, 0, sizeof(struct hbm_props_request));
460 490
461 if (mei_write_message(dev, mei_hdr,
462 (unsigned char *)prop_req, len)) {
463 dev->dev_state = MEI_DEV_RESETING;
464 dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
465 mei_reset(dev, 1);
466 return -EIO;
467 }
468 491
469 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 492 prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
470 dev->me_client_index = b; 493 prop_req->address = next_client_index;
471 return 1; 494
495 if (mei_write_message(dev, mei_hdr, (unsigned char *) prop_req,
496 mei_hdr->length)) {
497 dev->dev_state = MEI_DEV_RESETING;
498 dev_err(&dev->pdev->dev, "Properties request command failed\n");
499 mei_reset(dev, 1);
500
501 return -EIO;
472 } 502 }
473 503
504 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
505 dev->me_client_index = next_client_index;
506
474 return 0; 507 return 0;
475} 508}
476 509
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index e5aa0ed3b8eb..04fa2134615e 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -252,8 +252,6 @@ static void mei_client_connect_response(struct mei_device *dev,
252 dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n"); 252 dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
253 mei_watchdog_register(dev); 253 mei_watchdog_register(dev);
254 254
255 /* next step in the state maching */
256 mei_amthif_host_init(dev);
257 return; 255 return;
258 } 256 }
259 257
@@ -470,6 +468,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
470 struct mei_msg_hdr *mei_hdr) 468 struct mei_msg_hdr *mei_hdr)
471{ 469{
472 struct mei_bus_message *mei_msg; 470 struct mei_bus_message *mei_msg;
471 struct mei_me_client *me_client;
473 struct hbm_host_version_response *version_res; 472 struct hbm_host_version_response *version_res;
474 struct hbm_client_connect_response *connect_res; 473 struct hbm_client_connect_response *connect_res;
475 struct hbm_client_connect_response *disconnect_res; 474 struct hbm_client_connect_response *disconnect_res;
@@ -478,8 +477,6 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
478 struct hbm_props_response *props_res; 477 struct hbm_props_response *props_res;
479 struct hbm_host_enum_response *enum_res; 478 struct hbm_host_enum_response *enum_res;
480 struct hbm_host_stop_request *stop_req; 479 struct hbm_host_stop_request *stop_req;
481 int res;
482
483 480
484 /* read the message to our buffer */ 481 /* read the message to our buffer */
485 BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf)); 482 BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf));
@@ -547,64 +544,37 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
547 544
548 case HOST_CLIENT_PROPERTIES_RES_CMD: 545 case HOST_CLIENT_PROPERTIES_RES_CMD:
549 props_res = (struct hbm_props_response *)mei_msg; 546 props_res = (struct hbm_props_response *)mei_msg;
547 me_client = &dev->me_clients[dev->me_client_presentation_num];
548
550 if (props_res->status || !dev->me_clients) { 549 if (props_res->status || !dev->me_clients) {
551 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n"); 550 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n");
552 mei_reset(dev, 1); 551 mei_reset(dev, 1);
553 return; 552 return;
554 } 553 }
555 if (dev->me_clients[dev->me_client_presentation_num]
556 .client_id == props_res->address) {
557 554
558 dev->me_clients[dev->me_client_presentation_num].props 555 if (me_client->client_id != props_res->address) {
559 = props_res->client_properties; 556 dev_err(&dev->pdev->dev,
557 "Host client properties reply mismatch\n");
558 mei_reset(dev, 1);
560 559
561 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 560 return;
562 dev->init_clients_state == 561 }
563 MEI_CLIENT_PROPERTIES_MESSAGE) {
564 dev->me_client_index++;
565 dev->me_client_presentation_num++;
566
567 /** Send Client Properties request **/
568 res = mei_host_client_properties(dev);
569 if (res < 0) {
570 dev_dbg(&dev->pdev->dev, "mei_host_client_properties() failed");
571 return;
572 } else if (!res) {
573 /*
574 * No more clients to send to.
575 * Clear Map for indicating now ME clients
576 * with associated host client
577 */
578 bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
579 dev->open_handle_count = 0;
580
581 /*
582 * Reserving the first three client IDs
583 * Client Id 0 - Reserved for MEI Bus Message communications
584 * Client Id 1 - Reserved for Watchdog
585 * Client ID 2 - Reserved for AMTHI
586 */
587 bitmap_set(dev->host_clients_map, 0, 3);
588 dev->dev_state = MEI_DEV_ENABLED;
589
590 /* if wd initialization fails, initialization the AMTHI client,
591 * otherwise the AMTHI client will be initialized after the WD client connect response
592 * will be received
593 */
594 if (mei_wd_host_init(dev))
595 mei_amthif_host_init(dev);
596 }
597 562
598 } else { 563 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
599 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message"); 564 dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) {
600 mei_reset(dev, 1); 565 dev_err(&dev->pdev->dev,
601 return; 566 "Unexpected client properties reply\n");
602 }
603 } else {
604 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message for wrong client ID\n");
605 mei_reset(dev, 1); 567 mei_reset(dev, 1);
568
606 return; 569 return;
607 } 570 }
571
572 me_client->props = props_res->client_properties;
573 dev->me_client_index++;
574 dev->me_client_presentation_num++;
575
576 mei_host_client_enumerate(dev);
577
608 break; 578 break;
609 579
610 case HOST_ENUM_RES_CMD: 580 case HOST_ENUM_RES_CMD:
@@ -618,7 +588,8 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
618 mei_allocate_me_clients_storage(dev); 588 mei_allocate_me_clients_storage(dev);
619 dev->init_clients_state = 589 dev->init_clients_state =
620 MEI_CLIENT_PROPERTIES_MESSAGE; 590 MEI_CLIENT_PROPERTIES_MESSAGE;
621 mei_host_client_properties(dev); 591
592 mei_host_client_enumerate(dev);
622 } else { 593 } else {
623 dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n"); 594 dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n");
624 mei_reset(dev, 1); 595 mei_reset(dev, 1);
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 251aafff5492..7c9c381e5c9a 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -829,6 +829,8 @@ static int __devinit mei_probe(struct pci_dev *pdev,
829 goto disable_msi; 829 goto disable_msi;
830 } 830 }
831 INIT_DELAYED_WORK(&dev->timer_work, mei_timer); 831 INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
832 INIT_WORK(&dev->init_work, mei_host_client_init);
833
832 if (mei_hw_init(dev)) { 834 if (mei_hw_init(dev)) {
833 dev_err(&pdev->dev, "init hw failure.\n"); 835 dev_err(&pdev->dev, "init hw failure.\n");
834 err = -ENODEV; 836 err = -ENODEV;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 17d00aae74e6..25da04549d04 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -287,6 +287,8 @@ struct mei_device {
287 bool iamthif_flow_control_pending; 287 bool iamthif_flow_control_pending;
288 bool iamthif_ioctl; 288 bool iamthif_ioctl;
289 bool iamthif_canceled; 289 bool iamthif_canceled;
290
291 struct work_struct init_work;
290}; 292};
291 293
292static inline unsigned long mei_secs_to_jiffies(unsigned long sec) 294static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
@@ -363,7 +365,8 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
363 */ 365 */
364void mei_host_start_message(struct mei_device *dev); 366void mei_host_start_message(struct mei_device *dev);
365void mei_host_enum_clients_message(struct mei_device *dev); 367void mei_host_enum_clients_message(struct mei_device *dev);
366int mei_host_client_properties(struct mei_device *dev); 368int mei_host_client_enumerate(struct mei_device *dev);
369void mei_host_client_init(struct work_struct *work);
367 370
368/* 371/*
369 * MEI interrupt functions prototype 372 * MEI interrupt functions prototype