diff options
author | Len Brown <len.brown@intel.com> | 2012-03-30 16:12:23 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2012-03-30 16:14:02 -0400 |
commit | 73f05330497b98c45d157b7d0c60673798bb4c3b (patch) | |
tree | 67fc16c0f55c482882aea49eaa1d8d95b23722e0 /drivers/acpi/apei/apei-base.c | |
parent | 1a05e4678724c4a5fe7b9e4e208b616dfe8c3a32 (diff) | |
parent | 8cdde126aa60ced0d63ff137378e09dd01dfadda (diff) |
Merge branch 'apei' into release
Conflicts:
drivers/acpi/apei/apei-base.c
This was a conflict between
15afae604651d4e17652d2ffb56f5e36f991cfef
(CPI, APEI: Fix incorrect APEI register bit width check and usage)
and
653f4b538f66d37db560e0f56af08117136d29b7
(ACPICA: Expand OSL memory read/write interfaces to 64 bits)
The former changed a parameter in the call to acpi_os_read_memory64()
and the later replaced all calls to acpi_os_read_memory64()
with calls to acpi_os_read_memory().
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/apei/apei-base.c')
-rw-r--r-- | drivers/acpi/apei/apei-base.c | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index ca773683d87e..5577762daee1 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -558,33 +558,48 @@ void apei_resources_release(struct apei_resources *resources) | |||
558 | } | 558 | } |
559 | EXPORT_SYMBOL_GPL(apei_resources_release); | 559 | EXPORT_SYMBOL_GPL(apei_resources_release); |
560 | 560 | ||
561 | static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr) | 561 | static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr, |
562 | u32 *access_bit_width) | ||
562 | { | 563 | { |
563 | u32 width, space_id; | 564 | u32 bit_width, bit_offset, access_size_code, space_id; |
564 | 565 | ||
565 | width = reg->bit_width; | 566 | bit_width = reg->bit_width; |
567 | bit_offset = reg->bit_offset; | ||
568 | access_size_code = reg->access_width; | ||
566 | space_id = reg->space_id; | 569 | space_id = reg->space_id; |
567 | /* Handle possible alignment issues */ | 570 | /* Handle possible alignment issues */ |
568 | memcpy(paddr, ®->address, sizeof(*paddr)); | 571 | memcpy(paddr, ®->address, sizeof(*paddr)); |
569 | if (!*paddr) { | 572 | if (!*paddr) { |
570 | pr_warning(FW_BUG APEI_PFX | 573 | pr_warning(FW_BUG APEI_PFX |
571 | "Invalid physical address in GAR [0x%llx/%u/%u]\n", | 574 | "Invalid physical address in GAR [0x%llx/%u/%u/%u/%u]\n", |
572 | *paddr, width, space_id); | 575 | *paddr, bit_width, bit_offset, access_size_code, |
576 | space_id); | ||
573 | return -EINVAL; | 577 | return -EINVAL; |
574 | } | 578 | } |
575 | 579 | ||
576 | if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) { | 580 | if (access_size_code < 1 || access_size_code > 4) { |
577 | pr_warning(FW_BUG APEI_PFX | 581 | pr_warning(FW_BUG APEI_PFX |
578 | "Invalid bit width in GAR [0x%llx/%u/%u]\n", | 582 | "Invalid access size code in GAR [0x%llx/%u/%u/%u/%u]\n", |
579 | *paddr, width, space_id); | 583 | *paddr, bit_width, bit_offset, access_size_code, |
584 | space_id); | ||
585 | return -EINVAL; | ||
586 | } | ||
587 | *access_bit_width = 1UL << (access_size_code + 2); | ||
588 | |||
589 | if ((bit_width + bit_offset) > *access_bit_width) { | ||
590 | pr_warning(FW_BUG APEI_PFX | ||
591 | "Invalid bit width + offset in GAR [0x%llx/%u/%u/%u/%u]\n", | ||
592 | *paddr, bit_width, bit_offset, access_size_code, | ||
593 | space_id); | ||
580 | return -EINVAL; | 594 | return -EINVAL; |
581 | } | 595 | } |
582 | 596 | ||
583 | if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY && | 597 | if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY && |
584 | space_id != ACPI_ADR_SPACE_SYSTEM_IO) { | 598 | space_id != ACPI_ADR_SPACE_SYSTEM_IO) { |
585 | pr_warning(FW_BUG APEI_PFX | 599 | pr_warning(FW_BUG APEI_PFX |
586 | "Invalid address space type in GAR [0x%llx/%u/%u]\n", | 600 | "Invalid address space type in GAR [0x%llx/%u/%u/%u/%u]\n", |
587 | *paddr, width, space_id); | 601 | *paddr, bit_width, bit_offset, access_size_code, |
602 | space_id); | ||
588 | return -EINVAL; | 603 | return -EINVAL; |
589 | } | 604 | } |
590 | 605 | ||
@@ -595,23 +610,25 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr) | |||
595 | int apei_read(u64 *val, struct acpi_generic_address *reg) | 610 | int apei_read(u64 *val, struct acpi_generic_address *reg) |
596 | { | 611 | { |
597 | int rc; | 612 | int rc; |
613 | u32 access_bit_width; | ||
598 | u64 address; | 614 | u64 address; |
599 | acpi_status status; | 615 | acpi_status status; |
600 | 616 | ||
601 | rc = apei_check_gar(reg, &address); | 617 | rc = apei_check_gar(reg, &address, &access_bit_width); |
602 | if (rc) | 618 | if (rc) |
603 | return rc; | 619 | return rc; |
604 | 620 | ||
605 | *val = 0; | 621 | *val = 0; |
606 | switch(reg->space_id) { | 622 | switch(reg->space_id) { |
607 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 623 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
608 | status = acpi_os_read_memory((acpi_physical_address) | 624 | status = acpi_os_read_memory((acpi_physical_address) address, |
609 | address, val, reg->bit_width); | 625 | val, access_bit_width); |
610 | if (ACPI_FAILURE(status)) | 626 | if (ACPI_FAILURE(status)) |
611 | return -EIO; | 627 | return -EIO; |
612 | break; | 628 | break; |
613 | case ACPI_ADR_SPACE_SYSTEM_IO: | 629 | case ACPI_ADR_SPACE_SYSTEM_IO: |
614 | status = acpi_os_read_port(address, (u32 *)val, reg->bit_width); | 630 | status = acpi_os_read_port(address, (u32 *)val, |
631 | access_bit_width); | ||
615 | if (ACPI_FAILURE(status)) | 632 | if (ACPI_FAILURE(status)) |
616 | return -EIO; | 633 | return -EIO; |
617 | break; | 634 | break; |
@@ -627,22 +644,23 @@ EXPORT_SYMBOL_GPL(apei_read); | |||
627 | int apei_write(u64 val, struct acpi_generic_address *reg) | 644 | int apei_write(u64 val, struct acpi_generic_address *reg) |
628 | { | 645 | { |
629 | int rc; | 646 | int rc; |
647 | u32 access_bit_width; | ||
630 | u64 address; | 648 | u64 address; |
631 | acpi_status status; | 649 | acpi_status status; |
632 | 650 | ||
633 | rc = apei_check_gar(reg, &address); | 651 | rc = apei_check_gar(reg, &address, &access_bit_width); |
634 | if (rc) | 652 | if (rc) |
635 | return rc; | 653 | return rc; |
636 | 654 | ||
637 | switch (reg->space_id) { | 655 | switch (reg->space_id) { |
638 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 656 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
639 | status = acpi_os_write_memory((acpi_physical_address) | 657 | status = acpi_os_write_memory((acpi_physical_address) address, |
640 | address, val, reg->bit_width); | 658 | val, access_bit_width); |
641 | if (ACPI_FAILURE(status)) | 659 | if (ACPI_FAILURE(status)) |
642 | return -EIO; | 660 | return -EIO; |
643 | break; | 661 | break; |
644 | case ACPI_ADR_SPACE_SYSTEM_IO: | 662 | case ACPI_ADR_SPACE_SYSTEM_IO: |
645 | status = acpi_os_write_port(address, val, reg->bit_width); | 663 | status = acpi_os_write_port(address, val, access_bit_width); |
646 | if (ACPI_FAILURE(status)) | 664 | if (ACPI_FAILURE(status)) |
647 | return -EIO; | 665 | return -EIO; |
648 | break; | 666 | break; |
@@ -661,23 +679,24 @@ static int collect_res_callback(struct apei_exec_context *ctx, | |||
661 | struct apei_resources *resources = data; | 679 | struct apei_resources *resources = data; |
662 | struct acpi_generic_address *reg = &entry->register_region; | 680 | struct acpi_generic_address *reg = &entry->register_region; |
663 | u8 ins = entry->instruction; | 681 | u8 ins = entry->instruction; |
682 | u32 access_bit_width; | ||
664 | u64 paddr; | 683 | u64 paddr; |
665 | int rc; | 684 | int rc; |
666 | 685 | ||
667 | if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)) | 686 | if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)) |
668 | return 0; | 687 | return 0; |
669 | 688 | ||
670 | rc = apei_check_gar(reg, &paddr); | 689 | rc = apei_check_gar(reg, &paddr, &access_bit_width); |
671 | if (rc) | 690 | if (rc) |
672 | return rc; | 691 | return rc; |
673 | 692 | ||
674 | switch (reg->space_id) { | 693 | switch (reg->space_id) { |
675 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 694 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
676 | return apei_res_add(&resources->iomem, paddr, | 695 | return apei_res_add(&resources->iomem, paddr, |
677 | reg->bit_width / 8); | 696 | access_bit_width / 8); |
678 | case ACPI_ADR_SPACE_SYSTEM_IO: | 697 | case ACPI_ADR_SPACE_SYSTEM_IO: |
679 | return apei_res_add(&resources->ioport, paddr, | 698 | return apei_res_add(&resources->ioport, paddr, |
680 | reg->bit_width / 8); | 699 | access_bit_width / 8); |
681 | default: | 700 | default: |
682 | return -EINVAL; | 701 | return -EINVAL; |
683 | } | 702 | } |