Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Samuel Ortiz and committed by
Greg Kroah-Hartman
c1174c0e be9d87a7

+97 -88
+66 -33
drivers/misc/mei/init.c
··· 423 423 dev->me_clients = clients; 424 424 return ; 425 425 } 426 - /** 427 - * host_client_properties - reads properties for client 428 - * 429 - * @dev: the device structure 430 - * 431 - * returns: 432 - * < 0 - Error. 433 - * = 0 - no more clients. 434 - * = 1 - still have clients to send properties request. 435 - */ 436 - int mei_host_client_properties(struct mei_device *dev) 426 + 427 + void mei_host_client_init(struct work_struct *work) 428 + { 429 + struct mei_device *dev = container_of(work, 430 + struct mei_device, init_work); 431 + struct mei_client_properties *client_props; 432 + int i; 433 + 434 + mutex_lock(&dev->device_lock); 435 + 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 + 461 + int mei_host_client_enumerate(struct mei_device *dev) 437 462 { 438 463 439 464 struct mei_msg_hdr *mei_hdr; 440 465 struct hbm_props_request *prop_req; 441 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 471 + client_num = dev->me_client_presentation_num; 472 + 473 + next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, 474 + dev->me_client_index); 475 + 476 + /* We got all client properties */ 477 + if (next_client_index == MEI_CLIENTS_MAX) { 478 + schedule_work(&dev->init_work); 479 + 480 + return 0; 481 + } 482 + 483 + dev->me_clients[client_num].client_id = next_client_index; 484 + dev->me_clients[client_num].mei_flow_ctrl_creds = 0; 485 + 486 + mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); 446 487 prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1]; 447 488 448 - b = dev->me_client_index; 449 - b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b); 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); 489 + memset(prop_req, 0, sizeof(struct hbm_props_request)); 454 490 455 491 456 - memset(prop_req, 0, sizeof(struct hbm_props_request)); 492 + prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; 493 + prop_req->address = next_client_index; 457 494 458 - prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; 459 - prop_req->address = b; 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); 460 500 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 - 469 - dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 470 - dev->me_client_index = b; 471 - return 1; 501 + return -EIO; 472 502 } 503 + 504 + dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 505 + dev->me_client_index = next_client_index; 473 506 474 507 return 0; 475 508 }
+25 -54
drivers/misc/mei/interrupt.c
··· 252 252 dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n"); 253 253 mei_watchdog_register(dev); 254 254 255 - /* next step in the state maching */ 256 - mei_amthif_host_init(dev); 257 255 return; 258 256 } 259 257 ··· 468 470 struct mei_msg_hdr *mei_hdr) 469 471 { 470 472 struct mei_bus_message *mei_msg; 473 + struct mei_me_client *me_client; 471 474 struct hbm_host_version_response *version_res; 472 475 struct hbm_client_connect_response *connect_res; 473 476 struct hbm_client_connect_response *disconnect_res; ··· 477 478 struct hbm_props_response *props_res; 478 479 struct hbm_host_enum_response *enum_res; 479 480 struct hbm_host_stop_request *stop_req; 480 - int res; 481 - 482 481 483 482 /* read the message to our buffer */ 484 483 BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf)); ··· 544 547 545 548 case HOST_CLIENT_PROPERTIES_RES_CMD: 546 549 props_res = (struct hbm_props_response *)mei_msg; 550 + me_client = &dev->me_clients[dev->me_client_presentation_num]; 551 + 547 552 if (props_res->status || !dev->me_clients) { 548 553 dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n"); 549 554 mei_reset(dev, 1); 550 555 return; 551 556 } 552 - if (dev->me_clients[dev->me_client_presentation_num] 553 - .client_id == props_res->address) { 554 557 555 - dev->me_clients[dev->me_client_presentation_num].props 556 - = props_res->client_properties; 557 - 558 - if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 559 - dev->init_clients_state == 560 - MEI_CLIENT_PROPERTIES_MESSAGE) { 561 - dev->me_client_index++; 562 - dev->me_client_presentation_num++; 563 - 564 - /** Send Client Properties request **/ 565 - res = mei_host_client_properties(dev); 566 - if (res < 0) { 567 - dev_dbg(&dev->pdev->dev, "mei_host_client_properties() failed"); 568 - return; 569 - } else if (!res) { 570 - /* 571 - * No more clients to send to. 572 - * Clear Map for indicating now ME clients 573 - * with associated host client 574 - */ 575 - bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX); 576 - dev->open_handle_count = 0; 577 - 578 - /* 579 - * Reserving the first three client IDs 580 - * Client Id 0 - Reserved for MEI Bus Message communications 581 - * Client Id 1 - Reserved for Watchdog 582 - * Client ID 2 - Reserved for AMTHI 583 - */ 584 - bitmap_set(dev->host_clients_map, 0, 3); 585 - dev->dev_state = MEI_DEV_ENABLED; 586 - 587 - /* if wd initialization fails, initialization the AMTHI client, 588 - * otherwise the AMTHI client will be initialized after the WD client connect response 589 - * will be received 590 - */ 591 - if (mei_wd_host_init(dev)) 592 - mei_amthif_host_init(dev); 593 - } 594 - 595 - } else { 596 - dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message"); 597 - mei_reset(dev, 1); 598 - return; 599 - } 600 - } else { 601 - dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message for wrong client ID\n"); 558 + if (me_client->client_id != props_res->address) { 559 + dev_err(&dev->pdev->dev, 560 + "Host client properties reply mismatch\n"); 602 561 mei_reset(dev, 1); 562 + 603 563 return; 604 564 } 565 + 566 + if (dev->dev_state != MEI_DEV_INIT_CLIENTS || 567 + dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) { 568 + dev_err(&dev->pdev->dev, 569 + "Unexpected client properties reply\n"); 570 + mei_reset(dev, 1); 571 + 572 + return; 573 + } 574 + 575 + me_client->props = props_res->client_properties; 576 + dev->me_client_index++; 577 + dev->me_client_presentation_num++; 578 + 579 + mei_host_client_enumerate(dev); 580 + 605 581 break; 606 582 607 583 case HOST_ENUM_RES_CMD: ··· 588 618 mei_allocate_me_clients_storage(dev); 589 619 dev->init_clients_state = 590 620 MEI_CLIENT_PROPERTIES_MESSAGE; 591 - mei_host_client_properties(dev); 621 + 622 + mei_host_client_enumerate(dev); 592 623 } else { 593 624 dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n"); 594 625 mei_reset(dev, 1);
+2
drivers/misc/mei/main.c
··· 829 829 goto disable_msi; 830 830 } 831 831 INIT_DELAYED_WORK(&dev->timer_work, mei_timer); 832 + INIT_WORK(&dev->init_work, mei_host_client_init); 833 + 832 834 if (mei_hw_init(dev)) { 833 835 dev_err(&pdev->dev, "init hw failure.\n"); 834 836 err = -ENODEV;
+4 -1
drivers/misc/mei/mei_dev.h
··· 287 287 bool iamthif_flow_control_pending; 288 288 bool iamthif_ioctl; 289 289 bool iamthif_canceled; 290 + 291 + struct work_struct init_work; 290 292 }; 291 293 292 294 static inline unsigned long mei_secs_to_jiffies(unsigned long sec) ··· 365 363 */ 366 364 void mei_host_start_message(struct mei_device *dev); 367 365 void mei_host_enum_clients_message(struct mei_device *dev); 368 - int mei_host_client_properties(struct mei_device *dev); 366 + int mei_host_client_enumerate(struct mei_device *dev); 367 + void mei_host_client_init(struct work_struct *work); 369 368 370 369 /* 371 370 * MEI interrupt functions prototype