Skip to contentSkip to conversation

iBFT features.

GIT PULL New Konrad Rzeszutek Wilk 1 participant 5 messages Apr 16, 2010 iSCSI boot firmware table (iBFT) driver

lore
Share & tools
lore

Konrad Rzeszutek Wilk

author maintainer
#0 lore raw

The iBFT firmware driver has seen some action this last month. Here is a short primer on what it is:
The iBFT is an equivalant to the Boot Flag, except that its geared towards iSCSI and hence requires much more information (such as the IP of target, passwords, which device to login, etc). iBFT is a data structure populated by the BIOS or the NIC to contain this so that the OS can read it and login to the iSCSI and present the boot device to the initrd for mounting / FS.

There has been two big features added in:

1) Updated to support the 1.03 of the spec:
ftp://ftp.software.ibm.com/systems/support/bladecenter/iscsi_boot_firmware_table_v1.03.pdf

2) Split in two modules: one presentation that exports SysFS entries and the other that actually contains the iBFT data. The presentation driver paves the road for iSCSI hardware drivers (QLogic iSCSI HBA for example) to present the boot information they contain via this SysFS interface as they don't put the data in iBFT format.

Please pull the 'for-linus' branch of
git://git.kernel.org/pub/scm/linux/kernel/git/konrad/ibft-2.6.git for-linus

Thank you!

Konrad Rzeszutek Wilk (1):
ibft: For UEFI machines actually do scan ACPI for iBFT.

Mike Christie (2):
ibft: separate ibft parsing from sysfs interface
ibft: convert iscsi_ibft module to iscsi boot lib

Peter Jones (1):
ibft: Update iBFT handling for v1.03 of the spec.

 drivers/firmware/Kconfig            |    9 +
 drivers/firmware/Makefile           |    1 +
 drivers/firmware/iscsi_boot_sysfs.c |  481 +++++++++++++++++++++++
 drivers/firmware/iscsi_ibft.c       |  726 +++++++++++++----------------------
 drivers/firmware/iscsi_ibft_find.c  |   55 ++-
 include/linux/iscsi_boot_sysfs.h    |  123 ++++++
 include/linux/iscsi_ibft.h          |   12 +-
 7 files changed, 923 insertions(+), 484 deletions(-)
author maintainer
#1 lore raw

PATCH 1/4 ibft: Update iBFT handling for v1.03 of the spec.

From: Peter Jones <[email protected]>

- 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.

Author: Peter Jones <[email protected]>

---
 drivers/firmware/iscsi_ibft.c      |   30 ++++++++++++++++++------------
 drivers/firmware/iscsi_ibft_find.c |   34 +++++++++++++++++++++++++++++-----
 include/linux/iscsi_ibft.h         |   12 ++----------
 3 files changed, 49 insertions(+), 27 deletions(-)
drivers/firmware/iscsi_ibft.c +18 -12
index ed2801c..b3ab24f 100644
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2007 Red Hat, Inc.
+ *  Copyright 2007-2010 Red Hat, Inc.
  *  by Peter Jones <[email protected]>
  *  Copyright 2008 IBM, Inc.
  *  by Konrad Rzeszutek <[email protected]>
@@ -19,6 +19,9 @@
  *
  * Changelog:
  *
+ *  06 Jan 2010 - Peter Jones <[email protected]>
+ *    New changelog entries are in the git log from now on.  Not here.
+ *
  *  14 Mar 2008 - Konrad Rzeszutek <[email protected]>
  *    Updated comments and copyrights. (v0.4.9)
  *
@@ -78,9 +81,10 @@
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/types.h>
+#include <linux/acpi.h>
 
-#define IBFT_ISCSI_VERSION "0.4.9"
-#define IBFT_ISCSI_DATE "2008-Mar-14"
+#define IBFT_ISCSI_VERSION "0.5.0"
+#define IBFT_ISCSI_DATE "2010-Feb-25"
 
 MODULE_AUTHOR("Peter Jones <[email protected]> and \
 Konrad Rzeszutek <[email protected]>");
@@ -238,7 +242,7 @@ static const char *ibft_initiator_properties[] =
  */
 
 struct ibft_kobject {
-	struct ibft_table_header *header;
+	struct acpi_table_ibft *header;
 	union {
 		struct ibft_initiator *initiator;
 		struct ibft_nic *nic;
@@ -536,12 +540,13 @@ static int __init ibft_check_device(void)
 	u8 *pos;
 	u8 csum = 0;
 
-	len = ibft_addr->length;
+	len = ibft_addr->header.length;
 
 	/* Sanity checking of iBFT. */
-	if (ibft_addr->revision != 1) {
+	if (ibft_addr->header.revision != 1) {
 		printk(KERN_ERR "iBFT module supports only revision 1, " \
-				"while this is %d.\n", ibft_addr->revision);
+				"while this is %d.\n",
+				ibft_addr->header.revision);
 		return -ENOENT;
 	}
 	for (pos = (u8 *)ibft_addr; pos < (u8 *)ibft_addr + len; pos++)
@@ -558,7 +563,7 @@ static int __init ibft_check_device(void)
 /*
  * Helper function for ibft_register_kobjects.
  */
-static int __init ibft_create_kobject(struct ibft_table_header *header,
+static int __init ibft_create_kobject(struct acpi_table_ibft *header,
 				       struct ibft_hdr *hdr,
 				       struct list_head *list)
 {
@@ -596,7 +601,7 @@ static int __init ibft_create_kobject(struct ibft_table_header *header,
 	default:
 		printk(KERN_ERR "iBFT has unknown structure type (%d). " \
 				"Report this bug to %.6s!\n", hdr->id,
-				header->oem_id);
+				header->header.oem_id);
 		rc = 1;
 		break;
 	}
@@ -649,7 +654,7 @@ out_invalid_struct:
  * found add them on the passed-in list. We do not support the other
  * fields at this point, so they are skipped.
  */
-static int __init ibft_register_kobjects(struct ibft_table_header *header,
+static int __init ibft_register_kobjects(struct acpi_table_ibft *header,
 					  struct list_head *list)
 {
 	struct ibft_control *control = NULL;
@@ -660,7 +665,7 @@ static int __init ibft_register_kobjects(struct ibft_table_header *header,
 
 	control = (void *)header + sizeof(*header);
 	end = (void *)control + control->hdr.length;
-	eot_offset = (void *)header + header->length - (void *)control;
+	eot_offset = (void *)header + header->header.length - (void *)control;
 	rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control,
 			     sizeof(*control));
 
@@ -672,7 +677,8 @@ static int __init ibft_register_kobjects(struct ibft_table_header *header,
 	}
 	for (ptr = &control->initiator_off; ptr < end; ptr += sizeof(u16)) {
 		offset = *(u16 *)ptr;
-		if (offset && offset < header->length && offset < eot_offset) {
+		if (offset && offset < header->header.length &&
+						offset < eot_offset) {
 			rc = ibft_create_kobject(header,
 						 (void *)header + offset,
 						 list);
drivers/firmware/iscsi_ibft_find.c +29 -5
index d6470ef..8f4d157 100644
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2007 Red Hat, Inc.
+ *  Copyright 2007-2010 Red Hat, Inc.
  *  by Peter Jones <[email protected]>
  *  Copyright 2007 IBM, Inc.
  *  by Konrad Rzeszutek <[email protected]>
@@ -22,6 +22,7 @@
 #include <linux/blkdev.h>
 #include <linux/ctype.h>
 #include <linux/device.h>
+#include <linux/efi.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/limits.h>
@@ -30,13 +31,14 @@
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/types.h>
+#include <linux/acpi.h>
 
 #include <asm/mmzone.h>
 
 /*
  * Physical location of iSCSI Boot Format Table.
  */
-struct ibft_table_header *ibft_addr;
+struct acpi_table_ibft *ibft_addr;
 EXPORT_SYMBOL_GPL(ibft_addr);
 
 #define IBFT_SIGN "iBFT"
@@ -46,6 +48,13 @@ EXPORT_SYMBOL_GPL(ibft_addr);
 #define VGA_MEM 0xA0000 /* VGA buffer */
 #define VGA_SIZE 0x20000 /* 128kB */
 
+#ifdef CONFIG_ACPI
+static int __init acpi_find_ibft(struct acpi_table_header *header)
+{
+	ibft_addr = (struct acpi_table_ibft *)header;
+	return 0;
+}
+#endif /* CONFIG_ACPI */
 
 /*
  * Routine used to find the iSCSI Boot Format Table. The logical
@@ -59,6 +68,11 @@ unsigned long __init find_ibft_region(unsigned long *sizep)
 
 	ibft_addr = NULL;
 
+	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
+	 * only use ACPI for this */
+	if (efi_enabled)
+		return 0;
+
 	for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
 		/* The table can't be inside the VGA BIOS reserved space,
 		 * so skip that area */
@@ -72,14 +86,24 @@ unsigned long __init find_ibft_region(unsigned long *sizep)
 			/* if the length of the table extends past 1M,
 			 * the table cannot be valid. */
 			if (pos + len <= (IBFT_END-1)) {
-				ibft_addr = (struct ibft_table_header *)virt;
+				ibft_addr = (struct acpi_table_ibft *)virt;
 				break;
 			}
 		}
 	}
+#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", acpi_find_ibft);
+#endif /* CONFIG_ACPI */
 	if (ibft_addr) {
-		*sizep = PAGE_ALIGN(len);
-		return pos;
+		*sizep = PAGE_ALIGN(ibft_addr->header.length);
+		return (u64)isa_virt_to_bus(ibft_addr);
 	}
 
 	*sizep = 0;
include/linux/iscsi_ibft.h +2 -10
index d2e4042..8ba7e5b 100644
@@ -21,21 +21,13 @@
 #ifndef ISCSI_IBFT_H
 #define ISCSI_IBFT_H
 
-struct ibft_table_header {
-	char signature[4];
-	u32 length;
-	u8 revision;
-	u8 checksum;
-	char oem_id[6];
-	char oem_table_id[8];
-	char reserved[24];
-} __attribute__((__packed__));
+#include <acpi/acpi.h>
 
 /*
  * Logical location of iSCSI Boot Format Table.
  * If the value is NULL there is no iBFT on the machine.
  */
-extern struct ibft_table_header *ibft_addr;
+extern struct acpi_table_ibft *ibft_addr;
 
 /*
  * Routine used to find and reserve the iSCSI Boot Format Table. The
Signature · 1 line
1.7.0.5
author maintainer
#2 lore raw

PATCH 2/4 ibft: For UEFI machines actually do scan ACPI for iBFT.

In reply to Konrad Rzeszutek Wilk

For machines with IBFT 1.03 do scan the ACPI table for 'iBFT' or for 'IBFT'. If the machine is in UEFI mode, only do the ACPI table scan. For all other machines (pre IBFT 1.03) do a memory scan if not found in the ACPI tables.

Author: Konrad Rzeszutek Wilk <[email protected]>

---
 drivers/firmware/iscsi_ibft_find.c |   31 +++++++++++++++++++------------
 1 files changed, 19 insertions(+), 12 deletions(-)
drivers/firmware/iscsi_ibft_find.c +19 -12
index 8f4d157..0bc3fae 100644
@@ -56,23 +56,12 @@ static int __init acpi_find_ibft(struct acpi_table_header *header)
 }
 #endif /* CONFIG_ACPI */
 
-/*
- * Routine used to find the iSCSI Boot Format Table. The logical
- * kernel address is set in the ibft_addr global variable.
- */
-unsigned long __init find_ibft_region(unsigned long *sizep)
+static int __init find_ibft_mem_scan(void)
 {
 	unsigned long pos;
 	unsigned int len = 0;
 	void *virt;
 
-	ibft_addr = NULL;
-
-	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
-	 * only use ACPI for this */
-	if (efi_enabled)
-		return 0;
-
 	for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
 		/* The table can't be inside the VGA BIOS reserved space,
 		 * so skip that area */
@@ -91,6 +80,17 @@ unsigned long __init find_ibft_region(unsigned long *sizep)
 			}
 		}
 	}
+	return len;
+}
+/*
+ * Routine used to find the iSCSI Boot Format Table. The logical
+ * kernel address is set in the ibft_addr global variable.
+ */
+unsigned long __init find_ibft_region(unsigned long *sizep)
+{
+
+	ibft_addr = NULL;
+
 #ifdef CONFIG_ACPI
 	/*
 	 * One spec says "IBFT", the other says "iBFT". We have to check
@@ -101,6 +101,13 @@ unsigned long __init find_ibft_region(unsigned long *sizep)
 	if (!ibft_addr)
 		acpi_table_parse("iBFT", acpi_find_ibft);
 #endif /* CONFIG_ACPI */
+
+	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
+	 * only use ACPI for this */
+
+	if (!ibft_addr && !efi_enabled)
+		find_ibft_mem_scan();
+
 	if (ibft_addr) {
 		*sizep = PAGE_ALIGN(ibft_addr->header.length);
 		return (u64)isa_virt_to_bus(ibft_addr);
Signature · 1 line
1.7.0.5
author maintainer
#3 lore raw

PATCH 3/4 ibft: separate ibft parsing from sysfs interface

In reply to Konrad Rzeszutek Wilk

From: Mike Christie <[email protected]>

Not all iscsi drivers support ibft. For drivers like be2iscsi that do not but are bootable through a vendor firmware specific format/process this patch moves the sysfs interface from the ibft code to a lib module. This then allows userspace tools to search for iscsi boot info in a common place and in a common format.

ibft iscsi boot info is exported in the same place as it was
before: /sys/firmware/ibft.

vendor/fw boot info gets export in /sys/firmware/iscsi_bootX, where X is the scsi host number of the HBA. Underneath these parent dirs, the target, ethernet, and initiator dirs are the same as they were before.

---
 drivers/firmware/Kconfig            |    8 +
 drivers/firmware/Makefile           |    1 +
 drivers/firmware/iscsi_boot_sysfs.c |  481 +++++++++++++++++++++++++++++++++++
 include/linux/iscsi_boot_sysfs.h    |  123 +++++++++
 4 files changed, 613 insertions(+), 0 deletions(-)
 create mode 100644 drivers/firmware/iscsi_boot_sysfs.c
 create mode 100644 include/linux/iscsi_boot_sysfs.h
drivers/firmware/Kconfig +8 -0
index 1b03ba1..571d218 100644
@@ -122,6 +122,14 @@ config ISCSI_IBFT_FIND
 	  is necessary for iSCSI Boot Firmware Table Attributes module to work
 	  properly.
 
+config ISCSI_BOOT_SYSFS
+	tristate "iSCSI Boot Sysfs Interface"
+	default	n
+	help
+	  This option enables support for exposing iSCSI boot information
+	  via sysfs to userspace. If you wish to export this information,
+	  say Y. Otherwise, say N.
+
 config ISCSI_IBFT
 	tristate "iSCSI Boot Firmware Table Attributes module"
 	depends on ISCSI_IBFT_FIND
drivers/firmware/Makefile +1 -0
index 1c3c173..5fe7e16 100644
@@ -10,4 +10,5 @@ obj-$(CONFIG_DCDBAS)		+= dcdbas.o
 obj-$(CONFIG_DMIID)		+= dmi-id.o
 obj-$(CONFIG_ISCSI_IBFT_FIND)	+= iscsi_ibft_find.o
 obj-$(CONFIG_ISCSI_IBFT)	+= iscsi_ibft.o
+obj-$(CONFIG_ISCSI_BOOT_SYSFS)	+= iscsi_boot_sysfs.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)	+= memmap.o
drivers/firmware/iscsi_boot_sysfs.c new file +481 -0

481 lines not on this page · raw message

include/linux/iscsi_boot_sysfs.h new file +123 -0

123 lines not on this page · raw message

Signature · 1 line
1.7.0.5
author maintainer
#4 lore raw

PATCH 4/4 ibft: convert iscsi_ibft module to iscsi boot lib

In reply to Konrad Rzeszutek Wilk

From: Mike Christie <[email protected]>

This patch just converts the iscsi_ibft module to the iscsi boot sysfs lib module.

---
 drivers/firmware/Kconfig      |    1 +
 drivers/firmware/iscsi_ibft.c |  698 +++++++++++++++--------------------------
 2 files changed, 248 insertions(+), 451 deletions(-)
drivers/firmware/Kconfig +1 -0
index 571d218..a6c670b 100644
@@ -132,6 +132,7 @@ config ISCSI_BOOT_SYSFS
 
 config ISCSI_IBFT
 	tristate "iSCSI Boot Firmware Table Attributes module"
+	select ISCSI_BOOT_SYSFS
 	depends on ISCSI_IBFT_FIND
 	default	n
 	help
drivers/firmware/iscsi_ibft.c +247 -451

933 lines not on this page · raw message

Signature · 1 line
1.7.0.5