Commit dc93275150da9542f500fbd3d0515eecfefba7f6
Exists in
master
and in
7 other branches
Merge branch 'stable/broadcom.ibft' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/ibft-2.6
* 'stable/broadcom.ibft' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/ibft-2.6: iscsi_ibft: search for broadcom specific ibft sign (v2)
Showing 1 changed file Side-by-side Diff
drivers/firmware/iscsi_ibft_find.c
... | ... | @@ -42,7 +42,20 @@ |
42 | 42 | struct acpi_table_ibft *ibft_addr; |
43 | 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 | 59 | #define IBFT_SIGN_LEN 4 |
47 | 60 | #define IBFT_START 0x80000 /* 512kB */ |
48 | 61 | #define IBFT_END 0x100000 /* 1MB */ |
... | ... | @@ -62,6 +75,7 @@ |
62 | 75 | unsigned long pos; |
63 | 76 | unsigned int len = 0; |
64 | 77 | void *virt; |
78 | + int i; | |
65 | 79 | |
66 | 80 | for (pos = IBFT_START; pos < IBFT_END; pos += 16) { |
67 | 81 | /* The table can't be inside the VGA BIOS reserved space, |
68 | 82 | |
... | ... | @@ -69,18 +83,23 @@ |
69 | 83 | if (pos == VGA_MEM) |
70 | 84 | pos += VGA_SIZE; |
71 | 85 | virt = isa_bus_to_virt(pos); |
72 | - if (memcmp(virt, IBFT_SIGN, IBFT_SIGN_LEN) == 0) { | |
73 | - unsigned long *addr = | |
74 | - (unsigned long *)isa_bus_to_virt(pos + 4); | |
75 | - len = *addr; | |
76 | - /* if the length of the table extends past 1M, | |
77 | - * the table cannot be valid. */ | |
78 | - if (pos + len <= (IBFT_END-1)) { | |
79 | - ibft_addr = (struct acpi_table_ibft *)virt; | |
80 | - break; | |
86 | + | |
87 | + for (i = 0; i < ARRAY_SIZE(ibft_signs); i++) { | |
88 | + if (memcmp(virt, ibft_signs[i].sign, IBFT_SIGN_LEN) == | |
89 | + 0) { | |
90 | + unsigned long *addr = | |
91 | + (unsigned long *)isa_bus_to_virt(pos + 4); | |
92 | + len = *addr; | |
93 | + /* if the length of the table extends past 1M, | |
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 | 103 | return len; |
85 | 104 | } |
86 | 105 | /* |
87 | 106 | |
... | ... | @@ -89,18 +108,12 @@ |
89 | 108 | */ |
90 | 109 | unsigned long __init find_ibft_region(unsigned long *sizep) |
91 | 110 | { |
92 | - | |
111 | + int i; | |
93 | 112 | ibft_addr = NULL; |
94 | 113 | |
95 | 114 | #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_SIGN, acpi_find_ibft); | |
115 | + for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) | |
116 | + acpi_table_parse(ibft_signs[i].sign, acpi_find_ibft); | |
104 | 117 | #endif /* CONFIG_ACPI */ |
105 | 118 | |
106 | 119 | /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will |