aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2014-08-21 07:29:13 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-09-24 01:57:48 -0400
commit5ca2d3882d60c040285d0b45df731e11f5da7c64 (patch)
tree1c66e2f92e47ed378b512034cbc4c2e22eaaddc2 /drivers/misc
parentd320832f64666089a06778782e42fac29abd7bf7 (diff)
mei: use list for me clients book keeping
To support dynamic addition/remove of clients it is more convenient to use list instead of static array Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/mei/client.c34
-rw-r--r--drivers/misc/mei/debugfs.c19
-rw-r--r--drivers/misc/mei/hbm.c116
-rw-r--r--drivers/misc/mei/init.c1
-rw-r--r--drivers/misc/mei/mei_dev.h4
5 files changed, 71 insertions, 103 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index a20e6e9422f8..244b54692b48 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -38,12 +38,11 @@
38struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev, 38struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev,
39 const uuid_le *uuid) 39 const uuid_le *uuid)
40{ 40{
41 int i; 41 struct mei_me_client *me_cl;
42 42
43 for (i = 0; i < dev->me_clients_num; ++i) 43 list_for_each_entry(me_cl, &dev->me_clients, list)
44 if (uuid_le_cmp(*uuid, 44 if (uuid_le_cmp(*uuid, me_cl->props.protocol_name) == 0)
45 dev->me_clients[i].props.protocol_name) == 0) 45 return me_cl;
46 return &dev->me_clients[i];
47 46
48 return NULL; 47 return NULL;
49} 48}
@@ -62,12 +61,12 @@ struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev,
62 61
63struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id) 62struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
64{ 63{
65 int i;
66 64
67 for (i = 0; i < dev->me_clients_num; i++) 65 struct mei_me_client *me_cl;
68 if (dev->me_clients[i].client_id == client_id)
69 return &dev->me_clients[i];
70 66
67 list_for_each_entry(me_cl, &dev->me_clients, list)
68 if (me_cl->client_id == client_id)
69 return me_cl;
71 return NULL; 70 return NULL;
72} 71}
73 72
@@ -396,19 +395,19 @@ void mei_host_client_init(struct work_struct *work)
396{ 395{
397 struct mei_device *dev = container_of(work, 396 struct mei_device *dev = container_of(work,
398 struct mei_device, init_work); 397 struct mei_device, init_work);
399 struct mei_client_properties *client_props; 398 struct mei_me_client *me_cl;
400 int i; 399 struct mei_client_properties *props;
401 400
402 mutex_lock(&dev->device_lock); 401 mutex_lock(&dev->device_lock);
403 402
404 for (i = 0; i < dev->me_clients_num; i++) { 403 list_for_each_entry(me_cl, &dev->me_clients, list) {
405 client_props = &dev->me_clients[i].props; 404 props = &me_cl->props;
406 405
407 if (!uuid_le_cmp(client_props->protocol_name, mei_amthif_guid)) 406 if (!uuid_le_cmp(props->protocol_name, mei_amthif_guid))
408 mei_amthif_host_init(dev); 407 mei_amthif_host_init(dev);
409 else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid)) 408 else if (!uuid_le_cmp(props->protocol_name, mei_wd_guid))
410 mei_wd_host_init(dev); 409 mei_wd_host_init(dev);
411 else if (!uuid_le_cmp(client_props->protocol_name, mei_nfc_guid)) 410 else if (!uuid_le_cmp(props->protocol_name, mei_nfc_guid))
412 mei_nfc_host_init(dev); 411 mei_nfc_host_init(dev);
413 412
414 } 413 }
@@ -653,9 +652,6 @@ int mei_cl_flow_ctrl_creds(struct mei_cl *cl)
653 652
654 dev = cl->dev; 653 dev = cl->dev;
655 654
656 if (!dev->me_clients_num)
657 return 0;
658
659 if (cl->mei_flow_ctrl_creds > 0) 655 if (cl->mei_flow_ctrl_creds > 0)
660 return 1; 656 return 1;
661 657
diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c
index ced5b777c70f..3b032881622d 100644
--- a/drivers/misc/mei/debugfs.c
+++ b/drivers/misc/mei/debugfs.c
@@ -28,10 +28,10 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf,
28 size_t cnt, loff_t *ppos) 28 size_t cnt, loff_t *ppos)
29{ 29{
30 struct mei_device *dev = fp->private_data; 30 struct mei_device *dev = fp->private_data;
31 struct mei_me_client *cl; 31 struct mei_me_client *me_cl;
32 const size_t bufsz = 1024; 32 const size_t bufsz = 1024;
33 char *buf = kzalloc(bufsz, GFP_KERNEL); 33 char *buf = kzalloc(bufsz, GFP_KERNEL);
34 int i; 34 int i = 0;
35 int pos = 0; 35 int pos = 0;
36 int ret; 36 int ret;
37 37
@@ -47,20 +47,19 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf,
47 if (dev->dev_state != MEI_DEV_ENABLED) 47 if (dev->dev_state != MEI_DEV_ENABLED)
48 goto out; 48 goto out;
49 49
50 for (i = 0; i < dev->me_clients_num; i++) { 50 list_for_each_entry(me_cl, &dev->me_clients, list) {
51 cl = &dev->me_clients[i];
52 51
53 /* skip me clients that cannot be connected */ 52 /* skip me clients that cannot be connected */
54 if (cl->props.max_number_of_connections == 0) 53 if (me_cl->props.max_number_of_connections == 0)
55 continue; 54 continue;
56 55
57 pos += scnprintf(buf + pos, bufsz - pos, 56 pos += scnprintf(buf + pos, bufsz - pos,
58 "%2d|%2d|%4d|%pUl|%3d|%7d|\n", 57 "%2d|%2d|%4d|%pUl|%3d|%7d|\n",
59 i, cl->client_id, 58 i++, me_cl->client_id,
60 cl->props.fixed_address, 59 me_cl->props.fixed_address,
61 &cl->props.protocol_name, 60 &me_cl->props.protocol_name,
62 cl->props.max_number_of_connections, 61 me_cl->props.max_number_of_connections,
63 cl->props.max_msg_length); 62 me_cl->props.max_msg_length);
64 } 63 }
65out: 64out:
66 mutex_unlock(&dev->device_lock); 65 mutex_unlock(&dev->device_lock);
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 0b21675967f9..45659de14186 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -77,51 +77,20 @@ void mei_hbm_idle(struct mei_device *dev)
77 */ 77 */
78void mei_hbm_reset(struct mei_device *dev) 78void mei_hbm_reset(struct mei_device *dev)
79{ 79{
80 dev->me_clients_num = 0; 80 struct mei_me_client *me_cl, *next;
81
81 dev->me_client_presentation_num = 0; 82 dev->me_client_presentation_num = 0;
82 dev->me_client_index = 0; 83 dev->me_client_index = 0;
83 84
84 kfree(dev->me_clients); 85 list_for_each_entry_safe(me_cl, next, &dev->me_clients, list) {
85 dev->me_clients = NULL; 86 list_del(&me_cl->list);
87 kfree(me_cl);
88 }
86 89
87 mei_hbm_idle(dev); 90 mei_hbm_idle(dev);
88} 91}
89 92
90/** 93/**
91 * mei_hbm_me_cl_allocate - allocates storage for me clients
92 *
93 * @dev: the device structure
94 *
95 * returns 0 on success -ENOMEM on allocation failure
96 */
97static int mei_hbm_me_cl_allocate(struct mei_device *dev)
98{
99 struct mei_me_client *clients;
100 int b;
101
102 mei_hbm_reset(dev);
103
104 /* count how many ME clients we have */
105 for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX)
106 dev->me_clients_num++;
107
108 if (dev->me_clients_num == 0)
109 return 0;
110
111 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%ld.\n",
112 dev->me_clients_num * sizeof(struct mei_me_client));
113 /* allocate storage for ME clients representation */
114 clients = kcalloc(dev->me_clients_num,
115 sizeof(struct mei_me_client), GFP_KERNEL);
116 if (!clients) {
117 dev_err(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
118 return -ENOMEM;
119 }
120 dev->me_clients = clients;
121 return 0;
122}
123
124/**
125 * mei_hbm_cl_hdr - construct client hbm header 94 * mei_hbm_cl_hdr - construct client hbm header
126 * 95 *
127 * @cl: client 96 * @cl: client
@@ -213,6 +182,8 @@ int mei_hbm_start_req(struct mei_device *dev)
213 const size_t len = sizeof(struct hbm_host_version_request); 182 const size_t len = sizeof(struct hbm_host_version_request);
214 int ret; 183 int ret;
215 184
185 mei_hbm_reset(dev);
186
216 mei_hbm_hdr(mei_hdr, len); 187 mei_hbm_hdr(mei_hdr, len);
217 188
218 /* host start message */ 189 /* host start message */
@@ -267,6 +238,32 @@ static int mei_hbm_enum_clients_req(struct mei_device *dev)
267 return 0; 238 return 0;
268} 239}
269 240
241/*
242 * mei_hbm_me_cl_add - add new me client to the list
243 *
244 * @dev: the device structure
245 * @res: hbm property response
246 *
247 * returns 0 on success and -ENOMEM on allocation failure
248 */
249
250static int mei_hbm_me_cl_add(struct mei_device *dev,
251 struct hbm_props_response *res)
252{
253 struct mei_me_client *me_cl;
254
255 me_cl = kzalloc(sizeof(struct mei_me_client), GFP_KERNEL);
256 if (!me_cl)
257 return -ENOMEM;
258
259 me_cl->props = res->client_properties;
260 me_cl->client_id = res->me_addr;
261 me_cl->mei_flow_ctrl_creds = 0;
262
263 list_add(&me_cl->list, &dev->me_clients);
264 return 0;
265}
266
270/** 267/**
271 * mei_hbm_prop_req - request property for a single client 268 * mei_hbm_prop_req - request property for a single client
272 * 269 *
@@ -282,11 +279,8 @@ static int mei_hbm_prop_req(struct mei_device *dev)
282 struct hbm_props_request *prop_req; 279 struct hbm_props_request *prop_req;
283 const size_t len = sizeof(struct hbm_props_request); 280 const size_t len = sizeof(struct hbm_props_request);
284 unsigned long next_client_index; 281 unsigned long next_client_index;
285 unsigned long client_num;
286 int ret; 282 int ret;
287 283
288 client_num = dev->me_client_presentation_num;
289
290 next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, 284 next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX,
291 dev->me_client_index); 285 dev->me_client_index);
292 286
@@ -298,15 +292,11 @@ static int mei_hbm_prop_req(struct mei_device *dev)
298 return 0; 292 return 0;
299 } 293 }
300 294
301 dev->me_clients[client_num].client_id = next_client_index;
302 dev->me_clients[client_num].mei_flow_ctrl_creds = 0;
303
304 mei_hbm_hdr(mei_hdr, len); 295 mei_hbm_hdr(mei_hdr, len);
305 prop_req = (struct hbm_props_request *)dev->wr_msg.data; 296 prop_req = (struct hbm_props_request *)dev->wr_msg.data;
306 297
307 memset(prop_req, 0, sizeof(struct hbm_props_request)); 298 memset(prop_req, 0, sizeof(struct hbm_props_request));
308 299
309
310 prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; 300 prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
311 prop_req->me_addr = next_client_index; 301 prop_req->me_addr = next_client_index;
312 302
@@ -441,11 +431,10 @@ static void mei_hbm_cl_flow_control_res(struct mei_device *dev,
441 list_for_each_entry(cl, &dev->file_list, link) { 431 list_for_each_entry(cl, &dev->file_list, link) {
442 if (mei_hbm_cl_addr_equal(cl, flow_control)) { 432 if (mei_hbm_cl_addr_equal(cl, flow_control)) {
443 cl->mei_flow_ctrl_creds++; 433 cl->mei_flow_ctrl_creds++;
444 dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n", 434 dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d creds %d.\n",
445 flow_control->host_addr, flow_control->me_addr); 435 flow_control->host_addr, flow_control->me_addr,
446 dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n", 436 cl->mei_flow_ctrl_creds);
447 cl->mei_flow_ctrl_creds); 437 break;
448 break;
449 } 438 }
450 } 439 }
451} 440}
@@ -641,7 +630,6 @@ bool mei_hbm_version_is_supported(struct mei_device *dev)
641int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) 630int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
642{ 631{
643 struct mei_bus_message *mei_msg; 632 struct mei_bus_message *mei_msg;
644 struct mei_me_client *me_client;
645 struct hbm_host_version_response *version_res; 633 struct hbm_host_version_response *version_res;
646 struct hbm_client_connect_response *connect_res; 634 struct hbm_client_connect_response *connect_res;
647 struct hbm_client_connect_response *disconnect_res; 635 struct hbm_client_connect_response *disconnect_res;
@@ -763,13 +751,14 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
763 751
764 dev->init_clients_timer = 0; 752 dev->init_clients_timer = 0;
765 753
766 if (dev->me_clients == NULL) { 754 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
767 dev_err(&dev->pdev->dev, "hbm: properties response: mei_clients not allocated\n"); 755 dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
756 dev_err(&dev->pdev->dev, "hbm: properties response: state mismatch, [%d, %d]\n",
757 dev->dev_state, dev->hbm_state);
768 return -EPROTO; 758 return -EPROTO;
769 } 759 }
770 760
771 props_res = (struct hbm_props_response *)mei_msg; 761 props_res = (struct hbm_props_response *)mei_msg;
772 me_client = &dev->me_clients[dev->me_client_presentation_num];
773 762
774 if (props_res->status) { 763 if (props_res->status) {
775 dev_err(&dev->pdev->dev, "hbm: properties response: wrong status = %d\n", 764 dev_err(&dev->pdev->dev, "hbm: properties response: wrong status = %d\n",
@@ -777,20 +766,8 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
777 return -EPROTO; 766 return -EPROTO;
778 } 767 }
779 768
780 if (me_client->client_id != props_res->me_addr) { 769 mei_hbm_me_cl_add(dev, props_res);
781 dev_err(&dev->pdev->dev, "hbm: properties response: address mismatch %d ?= %d\n",
782 me_client->client_id, props_res->me_addr);
783 return -EPROTO;
784 }
785 770
786 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
787 dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
788 dev_err(&dev->pdev->dev, "hbm: properties response: state mismatch, [%d, %d]\n",
789 dev->dev_state, dev->hbm_state);
790 return -EPROTO;
791 }
792
793 me_client->props = props_res->client_properties;
794 dev->me_client_index++; 771 dev->me_client_index++;
795 dev->me_client_presentation_num++; 772 dev->me_client_presentation_num++;
796 773
@@ -809,7 +786,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
809 BUILD_BUG_ON(sizeof(dev->me_clients_map) 786 BUILD_BUG_ON(sizeof(dev->me_clients_map)
810 < sizeof(enum_res->valid_addresses)); 787 < sizeof(enum_res->valid_addresses));
811 memcpy(dev->me_clients_map, enum_res->valid_addresses, 788 memcpy(dev->me_clients_map, enum_res->valid_addresses,
812 sizeof(enum_res->valid_addresses)); 789 sizeof(enum_res->valid_addresses));
813 790
814 if (dev->dev_state != MEI_DEV_INIT_CLIENTS || 791 if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
815 dev->hbm_state != MEI_HBM_ENUM_CLIENTS) { 792 dev->hbm_state != MEI_HBM_ENUM_CLIENTS) {
@@ -818,11 +795,6 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
818 return -EPROTO; 795 return -EPROTO;
819 } 796 }
820 797
821 if (mei_hbm_me_cl_allocate(dev)) {
822 dev_err(&dev->pdev->dev, "hbm: enumeration response: cannot allocate clients array\n");
823 return -ENOMEM;
824 }
825
826 dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES; 798 dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES;
827 799
828 /* first property request */ 800 /* first property request */
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 006929222481..73ccbb65d4ff 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -356,6 +356,7 @@ void mei_device_init(struct mei_device *dev, const struct mei_cfg *cfg)
356 /* setup our list array */ 356 /* setup our list array */
357 INIT_LIST_HEAD(&dev->file_list); 357 INIT_LIST_HEAD(&dev->file_list);
358 INIT_LIST_HEAD(&dev->device_list); 358 INIT_LIST_HEAD(&dev->device_list);
359 INIT_LIST_HEAD(&dev->me_clients);
359 mutex_init(&dev->device_lock); 360 mutex_init(&dev->device_lock);
360 init_waitqueue_head(&dev->wait_hw_ready); 361 init_waitqueue_head(&dev->wait_hw_ready);
361 init_waitqueue_head(&dev->wait_pg); 362 init_waitqueue_head(&dev->wait_pg);
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 0b0d6135543b..76d8aa30e90d 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -175,6 +175,7 @@ struct mei_fw_status {
175 * @mei_flow_ctrl_creds - flow control credits 175 * @mei_flow_ctrl_creds - flow control credits
176 */ 176 */
177struct mei_me_client { 177struct mei_me_client {
178 struct list_head list;
178 struct mei_client_properties props; 179 struct mei_client_properties props;
179 u8 client_id; 180 u8 client_id;
180 u8 mei_flow_ctrl_creds; 181 u8 mei_flow_ctrl_creds;
@@ -478,10 +479,9 @@ struct mei_device {
478 479
479 struct hbm_version version; 480 struct hbm_version version;
480 481
481 struct mei_me_client *me_clients; /* Note: memory has to be allocated */ 482 struct list_head me_clients;
482 DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); 483 DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX);
483 DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); 484 DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX);
484 unsigned long me_clients_num;
485 unsigned long me_client_presentation_num; 485 unsigned long me_client_presentation_num;
486 unsigned long me_client_index; 486 unsigned long me_client_index;
487 487