Jelajahi Sumber

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>
Mike Christie 14 tahun lalu
induk
melakukan
140363500d
1 mengubah file dengan 32 tambahan dan 19 penghapusan
  1. 32 19
      drivers/firmware/iscsi_ibft_find.c

+ 32 - 19
drivers/firmware/iscsi_ibft_find.c

@@ -42,7 +42,20 @@
 struct acpi_table_ibft *ibft_addr;
 struct acpi_table_ibft *ibft_addr;
 EXPORT_SYMBOL_GPL(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_SIGN_LEN 4
 #define IBFT_START 0x80000 /* 512kB */
 #define IBFT_START 0x80000 /* 512kB */
 #define IBFT_END 0x100000 /* 1MB */
 #define IBFT_END 0x100000 /* 1MB */
@@ -62,6 +75,7 @@ static int __init find_ibft_in_mem(void)
 	unsigned long pos;
 	unsigned long pos;
 	unsigned int len = 0;
 	unsigned int len = 0;
 	void *virt;
 	void *virt;
+	int i;
 
 
 	for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
 	for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
 		/* The table can't be inside the VGA BIOS reserved space,
 		/* 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)
 		if (pos == VGA_MEM)
 			pos += VGA_SIZE;
 			pos += VGA_SIZE;
 		virt = isa_bus_to_virt(pos);
 		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;
 	return len;
 }
 }
 /*
 /*
@@ -89,18 +108,12 @@ static int __init find_ibft_in_mem(void)
  */
  */
 unsigned long __init find_ibft_region(unsigned long *sizep)
 unsigned long __init find_ibft_region(unsigned long *sizep)
 {
 {
-
+	int i;
 	ibft_addr = NULL;
 	ibft_addr = NULL;
 
 
 #ifdef CONFIG_ACPI
 #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 */
 #endif /* CONFIG_ACPI */
 
 
 	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
 	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will