diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/firmware/iscsi_ibft_find.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c index 2192456dfd68..f032e446fc11 100644 --- a/drivers/firmware/iscsi_ibft_find.c +++ b/drivers/firmware/iscsi_ibft_find.c | |||
@@ -42,7 +42,20 @@ | |||
42 | struct acpi_table_ibft *ibft_addr; | 42 | struct acpi_table_ibft *ibft_addr; |
43 | EXPORT_SYMBOL_GPL(ibft_addr); | 43 | EXPORT_SYMBOL_GPL(ibft_addr); |
44 | 44 | ||
45 | #define IBFT_SIGN "iBFT" | 45 | static const struct { |
46 | char *sign; | ||
47 | } ibft_signs[] = { | ||
48 | #ifdef CONFIG_ACPI | ||
49 | /* | ||
50 | * One spec says "IBFT", the other says "iBFT". We have to check | ||
51 | * for both. | ||
52 | */ | ||
53 | { ACPI_SIG_IBFT }, | ||
54 | #endif | ||
55 | { "iBFT" }, | ||
56 | { "BIFT" }, /* Broadcom iSCSI Offload */ | ||
57 | }; | ||
58 | |||
46 | #define IBFT_SIGN_LEN 4 | 59 | #define IBFT_SIGN_LEN 4 |
47 | #define IBFT_START 0x80000 /* 512kB */ | 60 | #define IBFT_START 0x80000 /* 512kB */ |
48 | #define IBFT_END 0x100000 /* 1MB */ | 61 | #define IBFT_END 0x100000 /* 1MB */ |
@@ -62,6 +75,7 @@ static int __init find_ibft_in_mem(void) | |||
62 | unsigned long pos; | 75 | unsigned long pos; |
63 | unsigned int len = 0; | 76 | unsigned int len = 0; |
64 | void *virt; | 77 | void *virt; |
78 | int i; | ||
65 | 79 | ||
66 | for (pos = IBFT_START; pos < IBFT_END; pos += 16) { | 80 | for (pos = IBFT_START; pos < IBFT_END; pos += 16) { |
67 | /* The table can't be inside the VGA BIOS reserved space, | 81 | /* The table can't be inside the VGA BIOS reserved space, |
@@ -69,18 +83,23 @@ static int __init find_ibft_in_mem(void) | |||
69 | if (pos == VGA_MEM) | 83 | if (pos == VGA_MEM) |
70 | pos += VGA_SIZE; | 84 | pos += VGA_SIZE; |
71 | virt = isa_bus_to_virt(pos); | 85 | virt = isa_bus_to_virt(pos); |
72 | if (memcmp(virt, IBFT_SIGN, IBFT_SIGN_LEN) == 0) { | 86 | |
73 | unsigned long *addr = | 87 | for (i = 0; i < ARRAY_SIZE(ibft_signs); i++) { |
74 | (unsigned long *)isa_bus_to_virt(pos + 4); | 88 | if (memcmp(virt, ibft_signs[i].sign, IBFT_SIGN_LEN) == |
75 | len = *addr; | 89 | 0) { |
76 | /* if the length of the table extends past 1M, | 90 | unsigned long *addr = |
77 | * the table cannot be valid. */ | 91 | (unsigned long *)isa_bus_to_virt(pos + 4); |
78 | if (pos + len <= (IBFT_END-1)) { | 92 | len = *addr; |
79 | ibft_addr = (struct acpi_table_ibft *)virt; | 93 | /* if the length of the table extends past 1M, |
80 | break; | 94 | * the table cannot be valid. */ |
95 | if (pos + len <= (IBFT_END-1)) { | ||
96 | ibft_addr = (struct acpi_table_ibft *)virt; | ||
97 | goto done; | ||
98 | } | ||
81 | } | 99 | } |
82 | } | 100 | } |
83 | } | 101 | } |
102 | done: | ||
84 | return len; | 103 | return len; |
85 | } | 104 | } |
86 | /* | 105 | /* |
@@ -89,18 +108,12 @@ static int __init find_ibft_in_mem(void) | |||
89 | */ | 108 | */ |
90 | unsigned long __init find_ibft_region(unsigned long *sizep) | 109 | unsigned long __init find_ibft_region(unsigned long *sizep) |
91 | { | 110 | { |
92 | 111 | int i; | |
93 | ibft_addr = NULL; | 112 | ibft_addr = NULL; |
94 | 113 | ||
95 | #ifdef CONFIG_ACPI | 114 | #ifdef CONFIG_ACPI |
96 | /* | 115 | for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) |
97 | * One spec says "IBFT", the other says "iBFT". We have to check | 116 | acpi_table_parse(ibft_signs[i].sign, acpi_find_ibft); |
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_SIGN, acpi_find_ibft); | ||
104 | #endif /* CONFIG_ACPI */ | 117 | #endif /* CONFIG_ACPI */ |
105 | 118 | ||
106 | /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will | 119 | /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will |