diff options
author | Peter Jones <pjones@redhat.com> | 2010-02-25 15:37:17 -0500 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad@kernel.org> | 2010-05-11 13:02:23 -0400 |
commit | 4e639fdf0d0d745648aa62228ab8a0d9c03a563f (patch) | |
tree | c6cb611ffc6f3e17e10ca3f39ac00f0e39b1ee4b /drivers/firmware/iscsi_ibft_find.c | |
parent | 94b849aaf6e22ab7bf54b0d0377a882d4892396d (diff) |
ibft: Update iBFT handling for v1.03 of the spec.
- Use struct acpi_table_ibft instead of struct ibft_table_header
- Don't do reserve_ibft_region() on UEFI machines (section 1.4.3.1)
- If ibft_addr isn't initialized when ibft_init() is called, check for
ACPI-based tables.
- Fix compiler error when CONFIG_ACPI is not defined.
Signed-off-by: Konrad Rzeszutek Wilk <konrad@kernel.org>
Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Diffstat (limited to 'drivers/firmware/iscsi_ibft_find.c')
-rw-r--r-- | drivers/firmware/iscsi_ibft_find.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c index d6470ef36e4a..dd85555d3296 100644 --- a/drivers/firmware/iscsi_ibft_find.c +++ b/drivers/firmware/iscsi_ibft_find.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2007 Red Hat, Inc. | 2 | * Copyright 2007-2010 Red Hat, Inc. |
3 | * by Peter Jones <pjones@redhat.com> | 3 | * by Peter Jones <pjones@redhat.com> |
4 | * Copyright 2007 IBM, Inc. | 4 | * Copyright 2007 IBM, Inc. |
5 | * by Konrad Rzeszutek <konradr@linux.vnet.ibm.com> | 5 | * by Konrad Rzeszutek <konradr@linux.vnet.ibm.com> |
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
23 | #include <linux/ctype.h> | 23 | #include <linux/ctype.h> |
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
25 | #include <linux/efi.h> | ||
25 | #include <linux/err.h> | 26 | #include <linux/err.h> |
26 | #include <linux/init.h> | 27 | #include <linux/init.h> |
27 | #include <linux/limits.h> | 28 | #include <linux/limits.h> |
@@ -30,13 +31,15 @@ | |||
30 | #include <linux/stat.h> | 31 | #include <linux/stat.h> |
31 | #include <linux/string.h> | 32 | #include <linux/string.h> |
32 | #include <linux/types.h> | 33 | #include <linux/types.h> |
34 | #include <linux/acpi.h> | ||
35 | #include <linux/iscsi_ibft.h> | ||
33 | 36 | ||
34 | #include <asm/mmzone.h> | 37 | #include <asm/mmzone.h> |
35 | 38 | ||
36 | /* | 39 | /* |
37 | * Physical location of iSCSI Boot Format Table. | 40 | * Physical location of iSCSI Boot Format Table. |
38 | */ | 41 | */ |
39 | struct ibft_table_header *ibft_addr; | 42 | struct acpi_table_ibft *ibft_addr; |
40 | EXPORT_SYMBOL_GPL(ibft_addr); | 43 | EXPORT_SYMBOL_GPL(ibft_addr); |
41 | 44 | ||
42 | #define IBFT_SIGN "iBFT" | 45 | #define IBFT_SIGN "iBFT" |
@@ -46,6 +49,13 @@ EXPORT_SYMBOL_GPL(ibft_addr); | |||
46 | #define VGA_MEM 0xA0000 /* VGA buffer */ | 49 | #define VGA_MEM 0xA0000 /* VGA buffer */ |
47 | #define VGA_SIZE 0x20000 /* 128kB */ | 50 | #define VGA_SIZE 0x20000 /* 128kB */ |
48 | 51 | ||
52 | #ifdef CONFIG_ACPI | ||
53 | static int __init acpi_find_ibft(struct acpi_table_header *header) | ||
54 | { | ||
55 | ibft_addr = (struct acpi_table_ibft *)header; | ||
56 | return 0; | ||
57 | } | ||
58 | #endif /* CONFIG_ACPI */ | ||
49 | 59 | ||
50 | /* | 60 | /* |
51 | * Routine used to find the iSCSI Boot Format Table. The logical | 61 | * Routine used to find the iSCSI Boot Format Table. The logical |
@@ -59,6 +69,11 @@ unsigned long __init find_ibft_region(unsigned long *sizep) | |||
59 | 69 | ||
60 | ibft_addr = NULL; | 70 | ibft_addr = NULL; |
61 | 71 | ||
72 | /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will | ||
73 | * only use ACPI for this */ | ||
74 | if (efi_enabled) | ||
75 | return 0; | ||
76 | |||
62 | for (pos = IBFT_START; pos < IBFT_END; pos += 16) { | 77 | for (pos = IBFT_START; pos < IBFT_END; pos += 16) { |
63 | /* The table can't be inside the VGA BIOS reserved space, | 78 | /* The table can't be inside the VGA BIOS reserved space, |
64 | * so skip that area */ | 79 | * so skip that area */ |
@@ -72,14 +87,24 @@ unsigned long __init find_ibft_region(unsigned long *sizep) | |||
72 | /* if the length of the table extends past 1M, | 87 | /* if the length of the table extends past 1M, |
73 | * the table cannot be valid. */ | 88 | * the table cannot be valid. */ |
74 | if (pos + len <= (IBFT_END-1)) { | 89 | if (pos + len <= (IBFT_END-1)) { |
75 | ibft_addr = (struct ibft_table_header *)virt; | 90 | ibft_addr = (struct acpi_table_ibft *)virt; |
76 | break; | 91 | break; |
77 | } | 92 | } |
78 | } | 93 | } |
79 | } | 94 | } |
95 | #ifdef CONFIG_ACPI | ||
96 | /* | ||
97 | * One spec says "IBFT", the other says "iBFT". We have to check | ||
98 | * for both. | ||
99 | */ | ||
100 | if (!ibft_addr) | ||
101 | acpi_table_parse(ACPI_SIG_IBFT, acpi_find_ibft); | ||
102 | if (!ibft_addr) | ||
103 | acpi_table_parse("iBFT", acpi_find_ibft); | ||
104 | #endif /* CONFIG_ACPI */ | ||
80 | if (ibft_addr) { | 105 | if (ibft_addr) { |
81 | *sizep = PAGE_ALIGN(len); | 106 | *sizep = PAGE_ALIGN(ibft_addr->header.length); |
82 | return pos; | 107 | return (u64)isa_virt_to_bus(ibft_addr); |
83 | } | 108 | } |
84 | 109 | ||
85 | *sizep = 0; | 110 | *sizep = 0; |