diff options
author | Alexander Usyskin <alexander.usyskin@intel.com> | 2016-05-09 00:07:47 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-06-11 01:09:41 -0400 |
commit | c0ff9019ee64101fda8f19338da799fda8217e14 (patch) | |
tree | ca3a5ce68a37f9742f4c09f002938ee5fe3b9eb9 | |
parent | dc1392727e32a5e467c13365e56e292e50ee084c (diff) |
mei: drop wr_msg from the mei_dev structure
The control messages are usually small, around 8 bytes, and can be
allocated on the stack.
Using on stack allocation allows us to drop 'wr_msg' a rather large
buffer reserved in the mei_dev structure and relax contention
of this device global buffer.
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/misc/mei/hbm.c | 137 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 10 |
2 files changed, 68 insertions, 79 deletions
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 5aa606c8a827..085f3aafe6fa 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c | |||
@@ -132,6 +132,7 @@ static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length) | |||
132 | hdr->length = length; | 132 | hdr->length = length; |
133 | hdr->msg_complete = 1; | 133 | hdr->msg_complete = 1; |
134 | hdr->reserved = 0; | 134 | hdr->reserved = 0; |
135 | hdr->internal = 0; | ||
135 | } | 136 | } |
136 | 137 | ||
137 | /** | 138 | /** |
@@ -165,15 +166,15 @@ void mei_hbm_cl_hdr(struct mei_cl *cl, u8 hbm_cmd, void *buf, size_t len) | |||
165 | * Return: 0 on success, <0 on failure. | 166 | * Return: 0 on success, <0 on failure. |
166 | */ | 167 | */ |
167 | static inline | 168 | static inline |
168 | int mei_hbm_cl_write(struct mei_device *dev, | 169 | int mei_hbm_cl_write(struct mei_device *dev, struct mei_cl *cl, |
169 | struct mei_cl *cl, u8 hbm_cmd, size_t len) | 170 | u8 hbm_cmd, u8 *buf, size_t len) |
170 | { | 171 | { |
171 | struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; | 172 | struct mei_msg_hdr mei_hdr; |
172 | 173 | ||
173 | mei_hbm_hdr(mei_hdr, len); | 174 | mei_hbm_hdr(&mei_hdr, len); |
174 | mei_hbm_cl_hdr(cl, hbm_cmd, dev->wr_msg.data, len); | 175 | mei_hbm_cl_hdr(cl, hbm_cmd, buf, len); |
175 | 176 | ||
176 | return mei_write_message(dev, mei_hdr, dev->wr_msg.data); | 177 | return mei_write_message(dev, &mei_hdr, buf); |
177 | } | 178 | } |
178 | 179 | ||
179 | /** | 180 | /** |
@@ -250,24 +251,23 @@ int mei_hbm_start_wait(struct mei_device *dev) | |||
250 | */ | 251 | */ |
251 | int mei_hbm_start_req(struct mei_device *dev) | 252 | int mei_hbm_start_req(struct mei_device *dev) |
252 | { | 253 | { |
253 | struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; | 254 | struct mei_msg_hdr mei_hdr; |
254 | struct hbm_host_version_request *start_req; | 255 | struct hbm_host_version_request start_req; |
255 | const size_t len = sizeof(struct hbm_host_version_request); | 256 | const size_t len = sizeof(struct hbm_host_version_request); |
256 | int ret; | 257 | int ret; |
257 | 258 | ||
258 | mei_hbm_reset(dev); | 259 | mei_hbm_reset(dev); |
259 | 260 | ||
260 | mei_hbm_hdr(mei_hdr, len); | 261 | mei_hbm_hdr(&mei_hdr, len); |
261 | 262 | ||
262 | /* host start message */ | 263 | /* host start message */ |
263 | start_req = (struct hbm_host_version_request *)dev->wr_msg.data; | 264 | memset(&start_req, 0, len); |
264 | memset(start_req, 0, len); | 265 | start_req.hbm_cmd = HOST_START_REQ_CMD; |
265 | start_req->hbm_cmd = HOST_START_REQ_CMD; | 266 | start_req.host_version.major_version = HBM_MAJOR_VERSION; |
266 | start_req->host_version.major_version = HBM_MAJOR_VERSION; | 267 | start_req.host_version.minor_version = HBM_MINOR_VERSION; |
267 | start_req->host_version.minor_version = HBM_MINOR_VERSION; | ||
268 | 268 | ||
269 | dev->hbm_state = MEI_HBM_IDLE; | 269 | dev->hbm_state = MEI_HBM_IDLE; |
270 | ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); | 270 | ret = mei_write_message(dev, &mei_hdr, &start_req); |
271 | if (ret) { | 271 | if (ret) { |
272 | dev_err(dev->dev, "version message write failed: ret = %d\n", | 272 | dev_err(dev->dev, "version message write failed: ret = %d\n", |
273 | ret); | 273 | ret); |
@@ -288,23 +288,22 @@ int mei_hbm_start_req(struct mei_device *dev) | |||
288 | */ | 288 | */ |
289 | static int mei_hbm_enum_clients_req(struct mei_device *dev) | 289 | static int mei_hbm_enum_clients_req(struct mei_device *dev) |
290 | { | 290 | { |
291 | struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; | 291 | struct mei_msg_hdr mei_hdr; |
292 | struct hbm_host_enum_request *enum_req; | 292 | struct hbm_host_enum_request enum_req; |
293 | const size_t len = sizeof(struct hbm_host_enum_request); | 293 | const size_t len = sizeof(struct hbm_host_enum_request); |
294 | int ret; | 294 | int ret; |
295 | 295 | ||
296 | /* enumerate clients */ | 296 | /* enumerate clients */ |
297 | mei_hbm_hdr(mei_hdr, len); | 297 | mei_hbm_hdr(&mei_hdr, len); |
298 | 298 | ||
299 | enum_req = (struct hbm_host_enum_request *)dev->wr_msg.data; | 299 | memset(&enum_req, 0, len); |
300 | memset(enum_req, 0, len); | 300 | enum_req.hbm_cmd = HOST_ENUM_REQ_CMD; |
301 | enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; | 301 | enum_req.flags |= dev->hbm_f_dc_supported ? |
302 | enum_req->flags |= dev->hbm_f_dc_supported ? | 302 | MEI_HBM_ENUM_F_ALLOW_ADD : 0; |
303 | MEI_HBM_ENUM_F_ALLOW_ADD : 0; | 303 | enum_req.flags |= dev->hbm_f_ie_supported ? |
304 | enum_req->flags |= dev->hbm_f_ie_supported ? | 304 | MEI_HBM_ENUM_F_IMMEDIATE_ENUM : 0; |
305 | MEI_HBM_ENUM_F_IMMEDIATE_ENUM : 0; | ||
306 | 305 | ||
307 | ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); | 306 | ret = mei_write_message(dev, &mei_hdr, &enum_req); |
308 | if (ret) { | 307 | if (ret) { |
309 | dev_err(dev->dev, "enumeration request write failed: ret = %d.\n", | 308 | dev_err(dev->dev, "enumeration request write failed: ret = %d.\n", |
310 | ret); | 309 | ret); |
@@ -358,23 +357,21 @@ static int mei_hbm_me_cl_add(struct mei_device *dev, | |||
358 | */ | 357 | */ |
359 | static int mei_hbm_add_cl_resp(struct mei_device *dev, u8 addr, u8 status) | 358 | static int mei_hbm_add_cl_resp(struct mei_device *dev, u8 addr, u8 status) |
360 | { | 359 | { |
361 | struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; | 360 | struct mei_msg_hdr mei_hdr; |
362 | struct hbm_add_client_response *resp; | 361 | struct hbm_add_client_response resp; |
363 | const size_t len = sizeof(struct hbm_add_client_response); | 362 | const size_t len = sizeof(struct hbm_add_client_response); |
364 | int ret; | 363 | int ret; |
365 | 364 | ||
366 | dev_dbg(dev->dev, "adding client response\n"); | 365 | dev_dbg(dev->dev, "adding client response\n"); |
367 | 366 | ||
368 | resp = (struct hbm_add_client_response *)dev->wr_msg.data; | 367 | mei_hbm_hdr(&mei_hdr, len); |
369 | 368 | ||
370 | mei_hbm_hdr(mei_hdr, len); | 369 | memset(&resp, 0, sizeof(struct hbm_add_client_response)); |
371 | memset(resp, 0, sizeof(struct hbm_add_client_response)); | 370 | resp.hbm_cmd = MEI_HBM_ADD_CLIENT_RES_CMD; |
371 | resp.me_addr = addr; | ||
372 | resp.status = status; | ||
372 | 373 | ||
373 | resp->hbm_cmd = MEI_HBM_ADD_CLIENT_RES_CMD; | 374 | ret = mei_write_message(dev, &mei_hdr, &resp); |
374 | resp->me_addr = addr; | ||
375 | resp->status = status; | ||
376 | |||
377 | ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); | ||
378 | if (ret) | 375 | if (ret) |
379 | dev_err(dev->dev, "add client response write failed: ret = %d\n", | 376 | dev_err(dev->dev, "add client response write failed: ret = %d\n", |
380 | ret); | 377 | ret); |
@@ -421,18 +418,17 @@ int mei_hbm_cl_notify_req(struct mei_device *dev, | |||
421 | struct mei_cl *cl, u8 start) | 418 | struct mei_cl *cl, u8 start) |
422 | { | 419 | { |
423 | 420 | ||
424 | struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; | 421 | struct mei_msg_hdr mei_hdr; |
425 | struct hbm_notification_request *req; | 422 | struct hbm_notification_request req; |
426 | const size_t len = sizeof(struct hbm_notification_request); | 423 | const size_t len = sizeof(struct hbm_notification_request); |
427 | int ret; | 424 | int ret; |
428 | 425 | ||
429 | mei_hbm_hdr(mei_hdr, len); | 426 | mei_hbm_hdr(&mei_hdr, len); |
430 | mei_hbm_cl_hdr(cl, MEI_HBM_NOTIFY_REQ_CMD, dev->wr_msg.data, len); | 427 | mei_hbm_cl_hdr(cl, MEI_HBM_NOTIFY_REQ_CMD, &req, len); |
431 | 428 | ||
432 | req = (struct hbm_notification_request *)dev->wr_msg.data; | 429 | req.start = start; |
433 | req->start = start; | ||
434 | 430 | ||
435 | ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); | 431 | ret = mei_write_message(dev, &mei_hdr, &req); |
436 | if (ret) | 432 | if (ret) |
437 | dev_err(dev->dev, "notify request failed: ret = %d\n", ret); | 433 | dev_err(dev->dev, "notify request failed: ret = %d\n", ret); |
438 | 434 | ||
@@ -534,8 +530,8 @@ static void mei_hbm_cl_notify(struct mei_device *dev, | |||
534 | */ | 530 | */ |
535 | static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx) | 531 | static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx) |
536 | { | 532 | { |
537 | struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; | 533 | struct mei_msg_hdr mei_hdr; |
538 | struct hbm_props_request *prop_req; | 534 | struct hbm_props_request prop_req; |
539 | const size_t len = sizeof(struct hbm_props_request); | 535 | const size_t len = sizeof(struct hbm_props_request); |
540 | unsigned long addr; | 536 | unsigned long addr; |
541 | int ret; | 537 | int ret; |
@@ -550,15 +546,14 @@ static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx) | |||
550 | return 0; | 546 | return 0; |
551 | } | 547 | } |
552 | 548 | ||
553 | mei_hbm_hdr(mei_hdr, len); | 549 | mei_hbm_hdr(&mei_hdr, len); |
554 | prop_req = (struct hbm_props_request *)dev->wr_msg.data; | ||
555 | 550 | ||
556 | memset(prop_req, 0, sizeof(struct hbm_props_request)); | 551 | memset(&prop_req, 0, sizeof(struct hbm_props_request)); |
557 | 552 | ||
558 | prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; | 553 | prop_req.hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; |
559 | prop_req->me_addr = addr; | 554 | prop_req.me_addr = addr; |
560 | 555 | ||
561 | ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); | 556 | ret = mei_write_message(dev, &mei_hdr, &prop_req); |
562 | if (ret) { | 557 | if (ret) { |
563 | dev_err(dev->dev, "properties request write failed: ret = %d\n", | 558 | dev_err(dev->dev, "properties request write failed: ret = %d\n", |
564 | ret); | 559 | ret); |
@@ -581,21 +576,20 @@ static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx) | |||
581 | */ | 576 | */ |
582 | int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd) | 577 | int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd) |
583 | { | 578 | { |
584 | struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; | 579 | struct mei_msg_hdr mei_hdr; |
585 | struct hbm_power_gate *req; | 580 | struct hbm_power_gate req; |
586 | const size_t len = sizeof(struct hbm_power_gate); | 581 | const size_t len = sizeof(struct hbm_power_gate); |
587 | int ret; | 582 | int ret; |
588 | 583 | ||
589 | if (!dev->hbm_f_pg_supported) | 584 | if (!dev->hbm_f_pg_supported) |
590 | return -EOPNOTSUPP; | 585 | return -EOPNOTSUPP; |
591 | 586 | ||
592 | mei_hbm_hdr(mei_hdr, len); | 587 | mei_hbm_hdr(&mei_hdr, len); |
593 | 588 | ||
594 | req = (struct hbm_power_gate *)dev->wr_msg.data; | 589 | memset(&req, 0, len); |
595 | memset(req, 0, len); | 590 | req.hbm_cmd = pg_cmd; |
596 | req->hbm_cmd = pg_cmd; | ||
597 | 591 | ||
598 | ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); | 592 | ret = mei_write_message(dev, &mei_hdr, &req); |
599 | if (ret) | 593 | if (ret) |
600 | dev_err(dev->dev, "power gate command write failed.\n"); | 594 | dev_err(dev->dev, "power gate command write failed.\n"); |
601 | return ret; | 595 | return ret; |
@@ -611,18 +605,17 @@ EXPORT_SYMBOL_GPL(mei_hbm_pg); | |||
611 | */ | 605 | */ |
612 | static int mei_hbm_stop_req(struct mei_device *dev) | 606 | static int mei_hbm_stop_req(struct mei_device *dev) |
613 | { | 607 | { |
614 | struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; | 608 | struct mei_msg_hdr mei_hdr; |
615 | struct hbm_host_stop_request *req = | 609 | struct hbm_host_stop_request req; |
616 | (struct hbm_host_stop_request *)dev->wr_msg.data; | ||
617 | const size_t len = sizeof(struct hbm_host_stop_request); | 610 | const size_t len = sizeof(struct hbm_host_stop_request); |
618 | 611 | ||
619 | mei_hbm_hdr(mei_hdr, len); | 612 | mei_hbm_hdr(&mei_hdr, len); |
620 | 613 | ||
621 | memset(req, 0, len); | 614 | memset(&req, 0, len); |
622 | req->hbm_cmd = HOST_STOP_REQ_CMD; | 615 | req.hbm_cmd = HOST_STOP_REQ_CMD; |
623 | req->reason = DRIVER_STOP_REQUEST; | 616 | req.reason = DRIVER_STOP_REQUEST; |
624 | 617 | ||
625 | return mei_write_message(dev, mei_hdr, dev->wr_msg.data); | 618 | return mei_write_message(dev, &mei_hdr, &req); |
626 | } | 619 | } |
627 | 620 | ||
628 | /** | 621 | /** |
@@ -636,9 +629,10 @@ static int mei_hbm_stop_req(struct mei_device *dev) | |||
636 | int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl) | 629 | int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl) |
637 | { | 630 | { |
638 | const size_t len = sizeof(struct hbm_flow_control); | 631 | const size_t len = sizeof(struct hbm_flow_control); |
632 | u8 buf[len]; | ||
639 | 633 | ||
640 | cl_dbg(dev, cl, "sending flow control\n"); | 634 | cl_dbg(dev, cl, "sending flow control\n"); |
641 | return mei_hbm_cl_write(dev, cl, MEI_FLOW_CONTROL_CMD, len); | 635 | return mei_hbm_cl_write(dev, cl, MEI_FLOW_CONTROL_CMD, buf, len); |
642 | } | 636 | } |
643 | 637 | ||
644 | /** | 638 | /** |
@@ -714,8 +708,9 @@ static void mei_hbm_cl_flow_control_res(struct mei_device *dev, | |||
714 | int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl) | 708 | int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl) |
715 | { | 709 | { |
716 | const size_t len = sizeof(struct hbm_client_connect_request); | 710 | const size_t len = sizeof(struct hbm_client_connect_request); |
711 | u8 buf[len]; | ||
717 | 712 | ||
718 | return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_REQ_CMD, len); | 713 | return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_REQ_CMD, buf, len); |
719 | } | 714 | } |
720 | 715 | ||
721 | /** | 716 | /** |
@@ -729,8 +724,9 @@ int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl) | |||
729 | int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl) | 724 | int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl) |
730 | { | 725 | { |
731 | const size_t len = sizeof(struct hbm_client_connect_response); | 726 | const size_t len = sizeof(struct hbm_client_connect_response); |
727 | u8 buf[len]; | ||
732 | 728 | ||
733 | return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_RES_CMD, len); | 729 | return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_RES_CMD, buf, len); |
734 | } | 730 | } |
735 | 731 | ||
736 | /** | 732 | /** |
@@ -765,8 +761,9 @@ static void mei_hbm_cl_disconnect_res(struct mei_device *dev, struct mei_cl *cl, | |||
765 | int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl) | 761 | int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl) |
766 | { | 762 | { |
767 | const size_t len = sizeof(struct hbm_client_connect_request); | 763 | const size_t len = sizeof(struct hbm_client_connect_request); |
764 | u8 buf[len]; | ||
768 | 765 | ||
769 | return mei_hbm_cl_write(dev, cl, CLIENT_CONNECT_REQ_CMD, len); | 766 | return mei_hbm_cl_write(dev, cl, CLIENT_CONNECT_REQ_CMD, buf, len); |
770 | } | 767 | } |
771 | 768 | ||
772 | /** | 769 | /** |
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index c9e01021eadf..e5e32503d4bc 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h | |||
@@ -382,7 +382,6 @@ const char *mei_pg_state_str(enum mei_pg_state state); | |||
382 | * | 382 | * |
383 | * @hbuf_depth : depth of hardware host/write buffer is slots | 383 | * @hbuf_depth : depth of hardware host/write buffer is slots |
384 | * @hbuf_is_ready : query if the host host/write buffer is ready | 384 | * @hbuf_is_ready : query if the host host/write buffer is ready |
385 | * @wr_msg : the buffer for hbm control messages | ||
386 | * | 385 | * |
387 | * @version : HBM protocol version in use | 386 | * @version : HBM protocol version in use |
388 | * @hbm_f_pg_supported : hbm feature pgi protocol | 387 | * @hbm_f_pg_supported : hbm feature pgi protocol |
@@ -467,12 +466,6 @@ struct mei_device { | |||
467 | u8 hbuf_depth; | 466 | u8 hbuf_depth; |
468 | bool hbuf_is_ready; | 467 | bool hbuf_is_ready; |
469 | 468 | ||
470 | /* used for control messages */ | ||
471 | struct { | ||
472 | struct mei_msg_hdr hdr; | ||
473 | unsigned char data[128]; | ||
474 | } wr_msg; | ||
475 | |||
476 | struct hbm_version version; | 469 | struct hbm_version version; |
477 | unsigned int hbm_f_pg_supported:1; | 470 | unsigned int hbm_f_pg_supported:1; |
478 | unsigned int hbm_f_dc_supported:1; | 471 | unsigned int hbm_f_dc_supported:1; |
@@ -670,8 +663,7 @@ static inline size_t mei_hbuf_max_len(const struct mei_device *dev) | |||
670 | } | 663 | } |
671 | 664 | ||
672 | static inline int mei_write_message(struct mei_device *dev, | 665 | static inline int mei_write_message(struct mei_device *dev, |
673 | struct mei_msg_hdr *hdr, | 666 | struct mei_msg_hdr *hdr, void *buf) |
674 | unsigned char *buf) | ||
675 | { | 667 | { |
676 | return dev->ops->write(dev, hdr, buf); | 668 | return dev->ops->write(dev, hdr, buf); |
677 | } | 669 | } |