aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei/init.c')
-rw-r--r--drivers/misc/mei/init.c368
1 files changed, 149 insertions, 219 deletions
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 98f1430e3e14..a54cd5567ca2 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -43,21 +43,6 @@ const char *mei_dev_state_str(int state)
43} 43}
44 44
45 45
46const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac,
47 0xa8, 0x46, 0xe0, 0xff, 0x65,
48 0x81, 0x4c);
49
50/**
51 * mei_io_list_init - Sets up a queue list.
52 *
53 * @list: An instance io list structure
54 * @dev: the device structure
55 */
56void mei_io_list_init(struct mei_io_list *list)
57{
58 /* initialize our queue list */
59 INIT_LIST_HEAD(&list->mei_cb.cb_list);
60}
61 46
62/** 47/**
63 * mei_io_list_flush - removes list entry belonging to cl. 48 * mei_io_list_flush - removes list entry belonging to cl.
@@ -65,17 +50,15 @@ void mei_io_list_init(struct mei_io_list *list)
65 * @list: An instance of our list structure 50 * @list: An instance of our list structure
66 * @cl: private data of the file object 51 * @cl: private data of the file object
67 */ 52 */
68void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl) 53void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
69{ 54{
70 struct mei_cl_cb *pos; 55 struct mei_cl_cb *pos;
71 struct mei_cl_cb *next; 56 struct mei_cl_cb *next;
72 57
73 list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) { 58 list_for_each_entry_safe(pos, next, &list->list, list) {
74 if (pos->file_private) { 59 if (pos->cl) {
75 struct mei_cl *cl_tmp; 60 if (mei_cl_cmp_id(cl, pos->cl))
76 cl_tmp = (struct mei_cl *)pos->file_private; 61 list_del(&pos->list);
77 if (mei_cl_cmp_id(cl, cl_tmp))
78 list_del(&pos->cb_list);
79 } 62 }
80 } 63 }
81} 64}
@@ -96,31 +79,14 @@ int mei_cl_flush_queues(struct mei_cl *cl)
96 mei_io_list_flush(&cl->dev->write_waiting_list, cl); 79 mei_io_list_flush(&cl->dev->write_waiting_list, cl);
97 mei_io_list_flush(&cl->dev->ctrl_wr_list, cl); 80 mei_io_list_flush(&cl->dev->ctrl_wr_list, cl);
98 mei_io_list_flush(&cl->dev->ctrl_rd_list, cl); 81 mei_io_list_flush(&cl->dev->ctrl_rd_list, cl);
99 mei_io_list_flush(&cl->dev->amthi_cmd_list, cl); 82 mei_io_list_flush(&cl->dev->amthif_cmd_list, cl);
100 mei_io_list_flush(&cl->dev->amthi_read_complete_list, cl); 83 mei_io_list_flush(&cl->dev->amthif_rd_complete_list, cl);
101 return 0; 84 return 0;
102} 85}
103 86
104 87
105 88
106/** 89/**
107 * mei_reset_iamthif_params - initializes mei device iamthif
108 *
109 * @dev: the device structure
110 */
111static void mei_reset_iamthif_params(struct mei_device *dev)
112{
113 /* reset iamthif parameters. */
114 dev->iamthif_current_cb = NULL;
115 dev->iamthif_msg_buf_size = 0;
116 dev->iamthif_msg_buf_index = 0;
117 dev->iamthif_canceled = false;
118 dev->iamthif_ioctl = false;
119 dev->iamthif_state = MEI_IAMTHIF_IDLE;
120 dev->iamthif_timer = 0;
121}
122
123/**
124 * init_mei_device - allocates and initializes the mei device structure 90 * init_mei_device - allocates and initializes the mei device structure
125 * 91 *
126 * @pdev: The pci device structure 92 * @pdev: The pci device structure
@@ -144,16 +110,14 @@ struct mei_device *mei_device_init(struct pci_dev *pdev)
144 init_waitqueue_head(&dev->wait_stop_wd); 110 init_waitqueue_head(&dev->wait_stop_wd);
145 dev->dev_state = MEI_DEV_INITIALIZING; 111 dev->dev_state = MEI_DEV_INITIALIZING;
146 dev->iamthif_state = MEI_IAMTHIF_IDLE; 112 dev->iamthif_state = MEI_IAMTHIF_IDLE;
147 dev->wd_interface_reg = false;
148
149 113
150 mei_io_list_init(&dev->read_list); 114 mei_io_list_init(&dev->read_list);
151 mei_io_list_init(&dev->write_list); 115 mei_io_list_init(&dev->write_list);
152 mei_io_list_init(&dev->write_waiting_list); 116 mei_io_list_init(&dev->write_waiting_list);
153 mei_io_list_init(&dev->ctrl_wr_list); 117 mei_io_list_init(&dev->ctrl_wr_list);
154 mei_io_list_init(&dev->ctrl_rd_list); 118 mei_io_list_init(&dev->ctrl_rd_list);
155 mei_io_list_init(&dev->amthi_cmd_list); 119 mei_io_list_init(&dev->amthif_cmd_list);
156 mei_io_list_init(&dev->amthi_read_complete_list); 120 mei_io_list_init(&dev->amthif_rd_complete_list);
157 dev->pdev = pdev; 121 dev->pdev = pdev;
158 return dev; 122 return dev;
159} 123}
@@ -196,7 +160,8 @@ int mei_hw_init(struct mei_device *dev)
196 if (!dev->recvd_msg) { 160 if (!dev->recvd_msg) {
197 mutex_unlock(&dev->device_lock); 161 mutex_unlock(&dev->device_lock);
198 err = wait_event_interruptible_timeout(dev->wait_recvd_msg, 162 err = wait_event_interruptible_timeout(dev->wait_recvd_msg,
199 dev->recvd_msg, MEI_INTEROP_TIMEOUT); 163 dev->recvd_msg,
164 mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT));
200 mutex_lock(&dev->device_lock); 165 mutex_lock(&dev->device_lock);
201 } 166 }
202 167
@@ -317,15 +282,13 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
317 cl_pos->timer_count = 0; 282 cl_pos->timer_count = 0;
318 } 283 }
319 /* remove entry if already in list */ 284 /* remove entry if already in list */
320 dev_dbg(&dev->pdev->dev, "list del iamthif and wd file list.\n"); 285 dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n");
321 mei_remove_client_from_file_list(dev, 286 mei_me_cl_unlink(dev, &dev->wd_cl);
322 dev->wd_cl.host_client_id);
323 287
324 mei_remove_client_from_file_list(dev, 288 mei_me_cl_unlink(dev, &dev->iamthif_cl);
325 dev->iamthif_cl.host_client_id);
326 289
327 mei_reset_iamthif_params(dev); 290 mei_amthif_reset_params(dev);
328 dev->extra_write_index = 0; 291 memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
329 } 292 }
330 293
331 dev->me_clients_num = 0; 294 dev->me_clients_num = 0;
@@ -351,10 +314,9 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
351 } 314 }
352 } 315 }
353 /* remove all waiting requests */ 316 /* remove all waiting requests */
354 list_for_each_entry_safe(cb_pos, cb_next, 317 list_for_each_entry_safe(cb_pos, cb_next, &dev->write_list.list, list) {
355 &dev->write_list.mei_cb.cb_list, cb_list) { 318 list_del(&cb_pos->list);
356 list_del(&cb_pos->cb_list); 319 mei_io_cb_free(cb_pos);
357 mei_free_cb_private(cb_pos);
358 } 320 }
359} 321}
360 322
@@ -370,31 +332,26 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
370void mei_host_start_message(struct mei_device *dev) 332void mei_host_start_message(struct mei_device *dev)
371{ 333{
372 struct mei_msg_hdr *mei_hdr; 334 struct mei_msg_hdr *mei_hdr;
373 struct hbm_host_version_request *host_start_req; 335 struct hbm_host_version_request *start_req;
336 const size_t len = sizeof(struct hbm_host_version_request);
337
338 mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
374 339
375 /* host start message */ 340 /* host start message */
376 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; 341 start_req = (struct hbm_host_version_request *)&dev->wr_msg_buf[1];
377 mei_hdr->host_addr = 0; 342 memset(start_req, 0, len);
378 mei_hdr->me_addr = 0; 343 start_req->hbm_cmd = HOST_START_REQ_CMD;
379 mei_hdr->length = sizeof(struct hbm_host_version_request); 344 start_req->host_version.major_version = HBM_MAJOR_VERSION;
380 mei_hdr->msg_complete = 1; 345 start_req->host_version.minor_version = HBM_MINOR_VERSION;
381 mei_hdr->reserved = 0; 346
382
383 host_start_req =
384 (struct hbm_host_version_request *) &dev->wr_msg_buf[1];
385 memset(host_start_req, 0, sizeof(struct hbm_host_version_request));
386 host_start_req->hbm_cmd = HOST_START_REQ_CMD;
387 host_start_req->host_version.major_version = HBM_MAJOR_VERSION;
388 host_start_req->host_version.minor_version = HBM_MINOR_VERSION;
389 dev->recvd_msg = false; 347 dev->recvd_msg = false;
390 if (mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req, 348 if (mei_write_message(dev, mei_hdr, (unsigned char *)start_req, len)) {
391 mei_hdr->length)) {
392 dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n"); 349 dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n");
393 dev->dev_state = MEI_DEV_RESETING; 350 dev->dev_state = MEI_DEV_RESETING;
394 mei_reset(dev, 1); 351 mei_reset(dev, 1);
395 } 352 }
396 dev->init_clients_state = MEI_START_MESSAGE; 353 dev->init_clients_state = MEI_START_MESSAGE;
397 dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; 354 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
398 return ; 355 return ;
399} 356}
400 357
@@ -408,26 +365,22 @@ void mei_host_start_message(struct mei_device *dev)
408void mei_host_enum_clients_message(struct mei_device *dev) 365void mei_host_enum_clients_message(struct mei_device *dev)
409{ 366{
410 struct mei_msg_hdr *mei_hdr; 367 struct mei_msg_hdr *mei_hdr;
411 struct hbm_host_enum_request *host_enum_req; 368 struct hbm_host_enum_request *enum_req;
412 mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; 369 const size_t len = sizeof(struct hbm_host_enum_request);
413 /* enumerate clients */ 370 /* enumerate clients */
414 mei_hdr->host_addr = 0; 371 mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len);
415 mei_hdr->me_addr = 0; 372
416 mei_hdr->length = sizeof(struct hbm_host_enum_request); 373 enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1];
417 mei_hdr->msg_complete = 1; 374 memset(enum_req, 0, sizeof(struct hbm_host_enum_request));
418 mei_hdr->reserved = 0; 375 enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
419 376
420 host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1]; 377 if (mei_write_message(dev, mei_hdr, (unsigned char *)enum_req, len)) {
421 memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request));
422 host_enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
423 if (mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req,
424 mei_hdr->length)) {
425 dev->dev_state = MEI_DEV_RESETING; 378 dev->dev_state = MEI_DEV_RESETING;
426 dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); 379 dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
427 mei_reset(dev, 1); 380 mei_reset(dev, 1);
428 } 381 }
429 dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE; 382 dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE;
430 dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; 383 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
431 return; 384 return;
432} 385}
433 386
@@ -470,56 +423,87 @@ void mei_allocate_me_clients_storage(struct mei_device *dev)
470 dev->me_clients = clients; 423 dev->me_clients = clients;
471 return ; 424 return ;
472} 425}
473/** 426
474 * host_client_properties - reads properties for client 427void mei_host_client_init(struct work_struct *work)
475 *
476 * @dev: the device structure
477 *
478 * returns:
479 * < 0 - Error.
480 * = 0 - no more clients.
481 * = 1 - still have clients to send properties request.
482 */
483int mei_host_client_properties(struct mei_device *dev)
484{ 428{
485 struct mei_msg_hdr *mei_header; 429 struct mei_device *dev = container_of(work,
486 struct hbm_props_request *host_cli_req; 430 struct mei_device, init_work);
487 int b; 431 struct mei_client_properties *client_props;
488 u8 client_num = dev->me_client_presentation_num; 432 int i;
489 433
490 b = dev->me_client_index; 434 mutex_lock(&dev->device_lock);
491 b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b); 435
492 if (b < MEI_CLIENTS_MAX) { 436 bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
493 dev->me_clients[client_num].client_id = b; 437 dev->open_handle_count = 0;
494 dev->me_clients[client_num].mei_flow_ctrl_creds = 0; 438
495 mei_header = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; 439 /*
496 mei_header->host_addr = 0; 440 * Reserving the first three client IDs
497 mei_header->me_addr = 0; 441 * 0: Reserved for MEI Bus Message communications
498 mei_header->length = sizeof(struct hbm_props_request); 442 * 1: Reserved for Watchdog
499 mei_header->msg_complete = 1; 443 * 2: Reserved for AMTHI
500 mei_header->reserved = 0; 444 */
501 445 bitmap_set(dev->host_clients_map, 0, 3);
502 host_cli_req = (struct hbm_props_request *)&dev->wr_msg_buf[1]; 446
503 447 for (i = 0; i < dev->me_clients_num; i++) {
504 memset(host_cli_req, 0, sizeof(struct hbm_props_request)); 448 client_props = &dev->me_clients[i].props;
505 449
506 host_cli_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; 450 if (!uuid_le_cmp(client_props->protocol_name, mei_amthi_guid))
507 host_cli_req->address = b; 451 mei_amthif_host_init(dev);
508 452 else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid))
509 if (mei_write_message(dev, mei_header, 453 mei_wd_host_init(dev);
510 (unsigned char *)host_cli_req, 454 }
511 mei_header->length)) { 455
512 dev->dev_state = MEI_DEV_RESETING; 456 dev->dev_state = MEI_DEV_ENABLED;
513 dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
514 mei_reset(dev, 1);
515 return -EIO;
516 }
517 457
518 dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; 458 mutex_unlock(&dev->device_lock);
519 dev->me_client_index = b; 459}
520 return 1; 460
461int mei_host_client_enumerate(struct mei_device *dev)
462{
463
464 struct mei_msg_hdr *mei_hdr;
465 struct hbm_props_request *prop_req;
466 const size_t len = sizeof(struct hbm_props_request);
467 unsigned long next_client_index;
468 u8 client_num;
469
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;
521 } 481 }
522 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);
487 prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1];
488
489 memset(prop_req, 0, sizeof(struct hbm_props_request));
490
491
492 prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
493 prop_req->address = next_client_index;
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;
502 }
503
504 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
505 dev->me_client_index = next_client_index;
506
523 return 0; 507 return 0;
524} 508}
525 509
@@ -557,17 +541,20 @@ int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid)
557 541
558 542
559/** 543/**
560 * mei_me_cl_update_filext - searches for ME client guid 544 * mei_me_cl_link - create link between host and me clinet and add
561 * sets client_id in mei_file_private if found 545 * me_cl to the list
546 *
562 * @dev: the device structure 547 * @dev: the device structure
563 * @cl: private file structure to set client_id in 548 * @cl: link between me and host client assocated with opened file descriptor
564 * @cuuid: searched uuid of ME client 549 * @cuuid: uuid of ME client
565 * @client_id: id of host client to be set in file private structure 550 * @client_id: id of the host client
566 * 551 *
567 * returns ME client index 552 * returns ME client index if ME client
553 * -EINVAL on incorrect values
554 * -ENONET if client not found
568 */ 555 */
569int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl, 556int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl,
570 const uuid_le *cuuid, u8 host_cl_id) 557 const uuid_le *cuuid, u8 host_cl_id)
571{ 558{
572 int i; 559 int i;
573 560
@@ -587,54 +574,22 @@ int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl,
587 574
588 return -ENOENT; 575 return -ENOENT;
589} 576}
590
591/** 577/**
592 * host_init_iamthif - mei initialization iamthif client. 578 * mei_me_cl_unlink - remove me_cl from the list
593 * 579 *
594 * @dev: the device structure 580 * @dev: the device structure
595 * 581 * @host_client_id: host client id to be removed
596 */ 582 */
597void mei_host_init_iamthif(struct mei_device *dev) 583void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl)
598{ 584{
599 int i; 585 struct mei_cl *pos, *next;
600 unsigned char *msg_buf; 586 list_for_each_entry_safe(pos, next, &dev->file_list, link) {
601 587 if (cl->host_client_id == pos->host_client_id) {
602 mei_cl_init(&dev->iamthif_cl, dev); 588 dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n",
603 dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; 589 pos->host_client_id, pos->me_client_id);
604 590 list_del_init(&pos->link);
605 /* find ME amthi client */ 591 break;
606 i = mei_me_cl_update_filext(dev, &dev->iamthif_cl, 592 }
607 &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
608 if (i < 0) {
609 dev_dbg(&dev->pdev->dev, "failed to find iamthif client.\n");
610 return;
611 }
612
613 /* Assign iamthif_mtu to the value received from ME */
614
615 dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length;
616 dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n",
617 dev->me_clients[i].props.max_msg_length);
618
619 kfree(dev->iamthif_msg_buf);
620 dev->iamthif_msg_buf = NULL;
621
622 /* allocate storage for ME message buffer */
623 msg_buf = kcalloc(dev->iamthif_mtu,
624 sizeof(unsigned char), GFP_KERNEL);
625 if (!msg_buf) {
626 dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n");
627 return;
628 }
629
630 dev->iamthif_msg_buf = msg_buf;
631
632 if (mei_connect(dev, &dev->iamthif_cl)) {
633 dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n");
634 dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
635 dev->iamthif_cl.host_client_id = 0;
636 } else {
637 dev->iamthif_cl.timer_count = CONNECT_TIMEOUT;
638 } 593 }
639} 594}
640 595
@@ -671,9 +626,8 @@ struct mei_cl *mei_cl_allocate(struct mei_device *dev)
671 */ 626 */
672int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) 627int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
673{ 628{
674 int rets, err;
675 long timeout = 15; /* 15 seconds */
676 struct mei_cl_cb *cb; 629 struct mei_cl_cb *cb;
630 int rets, err;
677 631
678 if (!dev || !cl) 632 if (!dev || !cl)
679 return -ENODEV; 633 return -ENODEV;
@@ -681,13 +635,11 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
681 if (cl->state != MEI_FILE_DISCONNECTING) 635 if (cl->state != MEI_FILE_DISCONNECTING)
682 return 0; 636 return 0;
683 637
684 cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); 638 cb = mei_io_cb_init(cl, NULL);
685 if (!cb) 639 if (!cb)
686 return -ENOMEM; 640 return -ENOMEM;
687 641
688 INIT_LIST_HEAD(&cb->cb_list); 642 cb->fop_type = MEI_FOP_CLOSE;
689 cb->file_private = cl;
690 cb->major_file_operations = MEI_CLOSE;
691 if (dev->mei_host_buffer_is_empty) { 643 if (dev->mei_host_buffer_is_empty) {
692 dev->mei_host_buffer_is_empty = false; 644 dev->mei_host_buffer_is_empty = false;
693 if (mei_disconnect(dev, cl)) { 645 if (mei_disconnect(dev, cl)) {
@@ -696,17 +648,17 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
696 goto free; 648 goto free;
697 } 649 }
698 mdelay(10); /* Wait for hardware disconnection ready */ 650 mdelay(10); /* Wait for hardware disconnection ready */
699 list_add_tail(&cb->cb_list, &dev->ctrl_rd_list.mei_cb.cb_list); 651 list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
700 } else { 652 } else {
701 dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n"); 653 dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n");
702 list_add_tail(&cb->cb_list, 654 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
703 &dev->ctrl_wr_list.mei_cb.cb_list); 655
704 } 656 }
705 mutex_unlock(&dev->device_lock); 657 mutex_unlock(&dev->device_lock);
706 658
707 err = wait_event_timeout(dev->wait_recvd_msg, 659 err = wait_event_timeout(dev->wait_recvd_msg,
708 (MEI_FILE_DISCONNECTED == cl->state), 660 MEI_FILE_DISCONNECTED == cl->state,
709 timeout * HZ); 661 mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
710 662
711 mutex_lock(&dev->device_lock); 663 mutex_lock(&dev->device_lock);
712 if (MEI_FILE_DISCONNECTED == cl->state) { 664 if (MEI_FILE_DISCONNECTED == cl->state) {
@@ -728,29 +680,7 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
728 mei_io_list_flush(&dev->ctrl_rd_list, cl); 680 mei_io_list_flush(&dev->ctrl_rd_list, cl);
729 mei_io_list_flush(&dev->ctrl_wr_list, cl); 681 mei_io_list_flush(&dev->ctrl_wr_list, cl);
730free: 682free:
731 mei_free_cb_private(cb); 683 mei_io_cb_free(cb);
732 return rets; 684 return rets;
733} 685}
734 686
735/**
736 * mei_remove_client_from_file_list -
737 * removes file private data from device file list
738 *
739 * @dev: the device structure
740 * @host_client_id: host client id to be removed
741 */
742void mei_remove_client_from_file_list(struct mei_device *dev,
743 u8 host_client_id)
744{
745 struct mei_cl *cl_pos = NULL;
746 struct mei_cl *cl_next = NULL;
747 list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
748 if (host_client_id == cl_pos->host_client_id) {
749 dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n",
750 cl_pos->host_client_id,
751 cl_pos->me_client_id);
752 list_del_init(&cl_pos->link);
753 break;
754 }
755 }
756}