summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2011-04-14 23:50:57 -0400
committerKonrad Rzeszutek Wilk <konrad@kernel.org>2011-04-14 23:53:09 -0400
commit140363500ddadad0c09cb512cc0c96a4d3efa053 (patch)
tree00c392b4c2082bc3420bcde31f4ed91792e90c58
parent3c0eee3fe6a3a1c745379547c7e7c904aa64f6d5 (diff)
downloadop-kernel-dev-140363500ddadad0c09cb512cc0c96a4d3efa053.zip
op-kernel-dev-140363500ddadad0c09cb512cc0c96a4d3efa053.tar.gz
iscsi_ibft: search for broadcom specific ibft sign (v2)
Broadcom iscsi offload firmware uses a non standard ibft sign of "BIFT". When we added support for boot, the anaconda team and I were using older firmware (I guess 4 years old), so boot does not work on current cards. This patch modifies the ibft search code to search for "BIFT" along with the other possible values. Broadcom has tested the patch and reported it works with their firmware. Mike has tested Chelsio and Intel cards. [v2: - Add ACPI_SIG_IBFT to ibft_signs - replace break with goto in find_ibft_in_mem innner loop.] Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: Peter Jones <pjones@redhat.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad@kernel.org>
-rw-r--r--drivers/firmware/iscsi_ibft_find.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c
index 2192456..f032e44 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -42,7 +42,20 @@
struct acpi_table_ibft *ibft_addr;
EXPORT_SYMBOL_GPL(ibft_addr);
-#define IBFT_SIGN "iBFT"
+static const struct {
+ char *sign;
+} ibft_signs[] = {
+#ifdef CONFIG_ACPI
+ /*
+ * One spec says "IBFT", the other says "iBFT". We have to check
+ * for both.
+ */
+ { ACPI_SIG_IBFT },
+#endif
+ { "iBFT" },
+ { "BIFT" }, /* Broadcom iSCSI Offload */
+};
+
#define IBFT_SIGN_LEN 4
#define IBFT_START 0x80000 /* 512kB */
#define IBFT_END 0x100000 /* 1MB */
@@ -62,6 +75,7 @@ static int __init find_ibft_in_mem(void)
unsigned long pos;
unsigned int len = 0;
void *virt;
+ int i;
for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
/* The table can't be inside the VGA BIOS reserved space,
@@ -69,18 +83,23 @@ static int __init find_ibft_in_mem(void)
if (pos == VGA_MEM)
pos += VGA_SIZE;
virt = isa_bus_to_virt(pos);
- if (memcmp(virt, IBFT_SIGN, IBFT_SIGN_LEN) == 0) {
- unsigned long *addr =
- (unsigned long *)isa_bus_to_virt(pos + 4);
- len = *addr;
- /* if the length of the table extends past 1M,
- * the table cannot be valid. */
- if (pos + len <= (IBFT_END-1)) {
- ibft_addr = (struct acpi_table_ibft *)virt;
- break;
+
+ for (i = 0; i < ARRAY_SIZE(ibft_signs); i++) {
+ if (memcmp(virt, ibft_signs[i].sign, IBFT_SIGN_LEN) ==
+ 0) {
+ unsigned long *addr =
+ (unsigned long *)isa_bus_to_virt(pos + 4);
+ len = *addr;
+ /* if the length of the table extends past 1M,
+ * the table cannot be valid. */
+ if (pos + len <= (IBFT_END-1)) {
+ ibft_addr = (struct acpi_table_ibft *)virt;
+ goto done;
+ }
}
}
}
+done:
return len;
}
/*
@@ -89,18 +108,12 @@ static int __init find_ibft_in_mem(void)
*/
unsigned long __init find_ibft_region(unsigned long *sizep)
{
-
+ int i;
ibft_addr = NULL;
#ifdef CONFIG_ACPI
- /*
- * One spec says "IBFT", the other says "iBFT". We have to check
- * for both.
- */
- if (!ibft_addr)
- acpi_table_parse(ACPI_SIG_IBFT, acpi_find_ibft);
- if (!ibft_addr)
- acpi_table_parse(IBFT_SIGN, acpi_find_ibft);
+ for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++)
+ acpi_table_parse(ibft_signs[i].sign, acpi_find_ibft);
#endif /* CONFIG_ACPI */
/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
OpenPOWER on IntegriCloud