From: Matt Domsch <Matt_Domsch@dell.com>

Currently, the x86/x86_64 real-mode kernel setup code reads and stores the
mbr_signature (4 bytes in the MBR at offset 440 decimal) for BIOS int13h
device 80h only.  This is useful, but not as useful as if we stored such
signatures for all int13h devices.  Think OS installer wanting to set up md
software RAID across several BIOS disks.

Patch below against 2.6.7 allows the storing of the mbr_signature for the
first 16 BIOS int13h devices, and exports them via
/sys/firmware/edd/int13_dev8x/mbr_signature as before.

This also merges the three EXPORT_SYMBOLs that setup.c exported for edd.c's
use into one.

Signed-off-by: Matt Domsch <Matt_Domsch@dell.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/Documentation/i386/zero-page.txt |    7 +
 25-akpm/arch/i386/boot/edd.S             |   35 ++++++---
 25-akpm/arch/i386/kernel/setup.c         |   17 ++--
 25-akpm/arch/x86_64/kernel/setup.c       |   19 ++---
 25-akpm/drivers/firmware/edd.c           |  113 +++++++++++++++++--------------
 25-akpm/include/asm-i386/setup.h         |    3 
 25-akpm/include/linux/edd.h              |   31 +++++---
 7 files changed, 128 insertions(+), 97 deletions(-)

diff -puN arch/i386/boot/edd.S~edd-store-mbr_signature-on-first-16-int13-devices arch/i386/boot/edd.S
--- 25/arch/i386/boot/edd.S~edd-store-mbr_signature-on-first-16-int13-devices	2004-06-28 13:33:34.496195464 -0700
+++ 25-akpm/arch/i386/boot/edd.S	2004-06-28 13:33:34.510193336 -0700
@@ -4,7 +4,7 @@
  * conformant to T13 Committee www.t13.org
  *   projects 1572D, 1484D, 1386D, 1226DT
  * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
- *	and Andrew Wilks <Andrew_Wilks@dell.com> September 2003
+ *	and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
  * legacy CHS retreival by Patrick J. LoPresti <patl@users.sourceforge.net>
  *      March 2004
  */
@@ -12,28 +12,39 @@
 #include <linux/edd.h>
 
 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-# Read the first sector of device 80h and store the 4-byte signature
+# Read the first sector of each BIOS disk device and store the 4-byte signature
+edd_mbr_sig_start:
+	movb	$0, (EDD_MBR_SIG_NR_BUF)	# zero value at EDD_MBR_SIG_NR_BUF
+	movb	$0x80, %dl			# from device 80
+	movw	$EDD_MBR_SIG_BUF, %bx		# store buffer ptr in bx
+edd_mbr_sig_read:
 	movl	$0xFFFFFFFF, %eax
-	movl	%eax, (DISK80_SIG_BUFFER)	# assume failure
+	movl	%eax, (%bx)			# assume failure
+	pushw	%bx
 	movb	$READ_SECTORS, %ah
 	movb	$1, %al				# read 1 sector
-	movb	$0x80, %dl			# from device 80
 	movb	$0, %dh				# at head 0
 	movw	$1, %cx				# cylinder 0, sector 0
 	pushw	%es
 	pushw	%ds
 	popw	%es
-	movw	$EDDBUF, %bx
-	pushw   %dx             # work around buggy BIOSes
+    	movw	$EDDBUF, %bx			# disk's data goes into EDDBUF
+	pushw	%dx             # work around buggy BIOSes
 	stc                     # work around buggy BIOSes
-	int     $0x13
+	int	$0x13
 	sti                     # work around buggy BIOSes
-	popw    %dx
-	jc	disk_sig_done
-	movl	(EDDBUF+MBR_SIG_OFFSET), %eax
-	movl	%eax, (DISK80_SIG_BUFFER)	# store success
-disk_sig_done:
+	popw	%dx
 	popw	%es
+	popw	%bx
+	jc	edd_mbr_sig_done		# on failure, we're done.
+	movl	(EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR
+	movl	%eax, (%bx)			# store success
+	incb	(EDD_MBR_SIG_NR_BUF)		# note that we stored something
+	incb	%dl				# increment to next device
+	addw	$4, %bx				# increment sig buffer ptr
+	cmpb	$EDD_MBR_SIG_MAX, (EDD_MBR_SIG_NR_BUF)	# Out of space?
+	jb	edd_mbr_sig_read		# keep looping
+edd_mbr_sig_done:
 
 # Do the BIOS Enhanced Disk Drive calls
 # This consists of two calls:
diff -puN arch/i386/kernel/setup.c~edd-store-mbr_signature-on-first-16-int13-devices arch/i386/kernel/setup.c
--- 25/arch/i386/kernel/setup.c~edd-store-mbr_signature-on-first-16-int13-devices	2004-06-28 13:33:34.498195160 -0700
+++ 25-akpm/arch/i386/kernel/setup.c	2004-06-28 13:33:34.511193184 -0700
@@ -628,13 +628,9 @@ static int __init copy_e820_map(struct e
 }
 
 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-unsigned char eddnr;
-struct edd_info edd[EDDMAXNR];
-unsigned int edd_disk80_sig;
+struct edd edd;
 #ifdef CONFIG_EDD_MODULE
-EXPORT_SYMBOL(eddnr);
 EXPORT_SYMBOL(edd);
-EXPORT_SYMBOL(edd_disk80_sig);
 #endif
 /**
  * copy_edd() - Copy the BIOS EDD information
@@ -643,12 +639,15 @@ EXPORT_SYMBOL(edd_disk80_sig);
  */
 static inline void copy_edd(void)
 {
-     eddnr = EDD_NR;
-     memcpy(edd, EDD_BUF, sizeof(edd));
-     edd_disk80_sig = DISK80_SIGNATURE;
+     memcpy(edd.mbr_signature, EDD_MBR_SIGNATURE, sizeof(edd.mbr_signature));
+     memcpy(edd.edd_info, EDD_BUF, sizeof(edd.edd_info));
+     edd.mbr_signature_nr = EDD_MBR_SIG_NR;
+     edd.edd_info_nr = EDD_NR;
 }
 #else
-#define copy_edd() do {} while (0)
+static inline void copy_edd(void)
+{
+}
 #endif
 
 /*
diff -puN arch/x86_64/kernel/setup.c~edd-store-mbr_signature-on-first-16-int13-devices arch/x86_64/kernel/setup.c
--- 25/arch/x86_64/kernel/setup.c~edd-store-mbr_signature-on-first-16-int13-devices	2004-06-28 13:33:34.500194856 -0700
+++ 25-akpm/arch/x86_64/kernel/setup.c	2004-06-28 13:33:34.512193032 -0700
@@ -401,27 +401,26 @@ static int __init noreplacement_setup(ch
 __setup("noreplacement", noreplacement_setup); 
 
 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-unsigned char eddnr;
-struct edd_info edd[EDDMAXNR];
-unsigned int edd_disk80_sig;
+struct edd edd;
 #ifdef CONFIG_EDD_MODULE
-EXPORT_SYMBOL(eddnr);
 EXPORT_SYMBOL(edd);
-EXPORT_SYMBOL(edd_disk80_sig);
 #endif
 /**
  * copy_edd() - Copy the BIOS EDD information
- *              from empty_zero_page into a safe place.
+ *              from boot_params into a safe place.
  *
  */
 static inline void copy_edd(void)
 {
-     eddnr = EDD_NR;
-     memcpy(edd, EDD_BUF, sizeof(edd));
-     edd_disk80_sig = DISK80_SIGNATURE;
+     memcpy(edd.mbr_signature, EDD_MBR_SIGNATURE, sizeof(edd.mbr_signature));
+     memcpy(edd.edd_info, EDD_BUF, sizeof(edd.edd_info));
+     edd.mbr_signature_nr = EDD_MBR_SIG_NR;
+     edd.edd_info_nr = EDD_NR;
 }
 #else
-#define copy_edd() do {} while (0)
+static inline void copy_edd(void)
+{
+}
 #endif
 
 void __init setup_arch(char **cmdline_p)
diff -puN Documentation/i386/zero-page.txt~edd-store-mbr_signature-on-first-16-int13-devices Documentation/i386/zero-page.txt
--- 25/Documentation/i386/zero-page.txt~edd-store-mbr_signature-on-first-16-int13-devices	2004-06-28 13:33:34.501194704 -0700
+++ 25-akpm/Documentation/i386/zero-page.txt	2004-06-28 13:33:34.509193488 -0700
@@ -38,6 +38,7 @@ Offset	Type		Description
 0x1e0	unsigned long	ALT_MEM_K, alternative mem check, in Kb
 0x1e8	char		number of entries in E820MAP (below)
 0x1e9	unsigned char	number of entries in EDDBUF (below)
+0x1ea	unsigned char	number of entries in EDD_MBR_SIG_BUFFER (below)
 0x1f1	char		size of setup.S, number of sectors
 0x1f2	unsigned short	MOUNT_ROOT_RDONLY (if !=0)
 0x1f4	unsigned short	size of compressed kernel-part in the
@@ -72,7 +73,7 @@ Offset	Type		Description
 0x21c	unsigned long	INITRD_SIZE, size in bytes of ramdisk image
 0x220	4 bytes		(setup.S)
 0x224	unsigned short	setup.S heap end pointer
-0x2cc	4 bytes		DISK80_SIG_BUFFER (setup.S)
+0x290 - 0x2cf		EDD_MBR_SIG_BUFFER (edd.S)
 0x2d0 - 0x600		E820MAP
-0x600 - 0x7ff		EDDBUF (setup.S) for disk signature read sector
-0x600 - 0x7eb		EDDBUF (setup.S) for edd data
+0x600 - 0x7ff		EDDBUF (edd.S) for disk signature read sector
+0x600 - 0x7eb		EDDBUF (edd.S) for edd data
diff -puN drivers/firmware/edd.c~edd-store-mbr_signature-on-first-16-int13-devices drivers/firmware/edd.c
--- 25/drivers/firmware/edd.c~edd-store-mbr_signature-on-first-16-int13-devices	2004-06-28 13:33:34.503194400 -0700
+++ 25-akpm/drivers/firmware/edd.c	2004-06-28 13:33:34.514192728 -0700
@@ -2,7 +2,7 @@
  * linux/arch/i386/kernel/edd.c
  *  Copyright (C) 2002, 2003, 2004 Dell Inc.
  *  by Matt Domsch <Matt_Domsch@dell.com>
- *  disk80 signature by Matt Domsch, Andrew Wilks, and Sandeep K. Shandilya
+ *  disk signature by Matt Domsch, Andrew Wilks, and Sandeep K. Shandilya
  *  legacy CHS by Patrick J. LoPresti <patl@users.sourceforge.net>
  *
  * BIOS Enhanced Disk Drive Services (EDD)
@@ -43,8 +43,8 @@
 #include <linux/blkdev.h>
 #include <linux/edd.h>
 
-#define EDD_VERSION "0.15"
-#define EDD_DATE    "2004-May-17"
+#define EDD_VERSION "0.16"
+#define EDD_DATE    "2004-Jun-25"
 
 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
 MODULE_DESCRIPTION("sysfs interface to BIOS EDD information");
@@ -54,6 +54,8 @@ MODULE_VERSION(EDD_VERSION);
 #define left (PAGE_SIZE - (p - buf) - 1)
 
 struct edd_device {
+	unsigned int index;
+	unsigned int mbr_signature;
 	struct edd_info *info;
 	struct kobject kobj;
 };
@@ -77,6 +79,18 @@ struct edd_attribute edd_attr_##_name = 
 	.test	= _test,				\
 };
 
+static int
+edd_has_mbr_signature(struct edd_device *edev)
+{
+	return edev->index < min_t(unsigned char, edd.mbr_signature_nr, EDD_MBR_SIG_MAX);
+}
+
+static int
+edd_has_edd_info(struct edd_device *edev)
+{
+	return edev->index < min_t(unsigned char, edd.edd_info_nr, EDDMAXNR);
+}
+
 static inline struct edd_info *
 edd_dev_get_info(struct edd_device *edev)
 {
@@ -84,9 +98,13 @@ edd_dev_get_info(struct edd_device *edev
 }
 
 static inline void
-edd_dev_set_info(struct edd_device *edev, struct edd_info *info)
+edd_dev_set_info(struct edd_device *edev, int i)
 {
-	edev->info = info;
+	edev->index = i;
+	if (edd_has_mbr_signature(edev))
+		edev->mbr_signature = edd.mbr_signature[i];
+	if (edd_has_edd_info(edev))
+		edev->info = &edd.edd_info[i];
 }
 
 #define to_edd_attr(_attr) container_of(_attr,struct edd_attribute,attr)
@@ -256,10 +274,10 @@ edd_show_version(struct edd_device *edev
 }
 
 static ssize_t
-edd_show_disk80_sig(struct edd_device *edev, char *buf)
+edd_show_mbr_signature(struct edd_device *edev, char *buf)
 {
 	char *p = buf;
-	p += scnprintf(p, left, "0x%08x\n", edd_disk80_sig);
+	p += scnprintf(p, left, "0x%08x\n", edev->mbr_signature);
 	return (p - buf);
 }
 
@@ -440,10 +458,10 @@ edd_has_legacy_max_cylinder(struct edd_d
 {
 	struct edd_info *info;
 	if (!edev)
-		return -EINVAL;
+		return 0;
 	info = edd_dev_get_info(edev);
 	if (!info)
-		return -EINVAL;
+		return 0;
 	return info->legacy_max_cylinder > 0;
 }
 
@@ -452,10 +470,10 @@ edd_has_legacy_max_head(struct edd_devic
 {
 	struct edd_info *info;
 	if (!edev)
-		return -EINVAL;
+		return 0;
 	info = edd_dev_get_info(edev);
 	if (!info)
-		return -EINVAL;
+		return 0;
 	return info->legacy_max_head > 0;
 }
 
@@ -464,10 +482,10 @@ edd_has_legacy_sectors_per_track(struct 
 {
 	struct edd_info *info;
 	if (!edev)
-		return -EINVAL;
+		return 0;
 	info = edd_dev_get_info(edev);
 	if (!info)
-		return -EINVAL;
+		return 0;
 	return info->legacy_sectors_per_track > 0;
 }
 
@@ -476,10 +494,10 @@ edd_has_default_cylinders(struct edd_dev
 {
 	struct edd_info *info;
 	if (!edev)
-		return -EINVAL;
+		return 0;
 	info = edd_dev_get_info(edev);
 	if (!info)
-		return -EINVAL;
+		return 0;
 	return info->params.num_default_cylinders > 0;
 }
 
@@ -488,10 +506,10 @@ edd_has_default_heads(struct edd_device 
 {
 	struct edd_info *info;
 	if (!edev)
-		return -EINVAL;
+		return 0;
 	info = edd_dev_get_info(edev);
 	if (!info)
-		return -EINVAL;
+		return 0;
 	return info->params.num_default_heads > 0;
 }
 
@@ -500,10 +518,10 @@ edd_has_default_sectors_per_track(struct
 {
 	struct edd_info *info;
 	if (!edev)
-		return -EINVAL;
+		return 0;
 	info = edd_dev_get_info(edev);
 	if (!info)
-		return -EINVAL;
+		return 0;
 	return info->params.sectors_per_track > 0;
 }
 
@@ -538,23 +556,12 @@ edd_has_edd30(struct edd_device *edev)
 	return 1;
 }
 
-static int
-edd_has_disk80_sig(struct edd_device *edev)
-{
-	struct edd_info *info;
-	if (!edev)
-		return 0;
-	info = edd_dev_get_info(edev);
-	if (!info)
-		return 0;
-	return info->device == 0x80;
-}
 
-static EDD_DEVICE_ATTR(raw_data, 0444, edd_show_raw_data, NULL);
-static EDD_DEVICE_ATTR(version, 0444, edd_show_version, NULL);
-static EDD_DEVICE_ATTR(extensions, 0444, edd_show_extensions, NULL);
-static EDD_DEVICE_ATTR(info_flags, 0444, edd_show_info_flags, NULL);
-static EDD_DEVICE_ATTR(sectors, 0444, edd_show_sectors, NULL);
+static EDD_DEVICE_ATTR(raw_data, 0444, edd_show_raw_data, edd_has_edd_info);
+static EDD_DEVICE_ATTR(version, 0444, edd_show_version, edd_has_edd_info);
+static EDD_DEVICE_ATTR(extensions, 0444, edd_show_extensions, edd_has_edd_info);
+static EDD_DEVICE_ATTR(info_flags, 0444, edd_show_info_flags, edd_has_edd_info);
+static EDD_DEVICE_ATTR(sectors, 0444, edd_show_sectors, edd_has_edd_info);
 static EDD_DEVICE_ATTR(legacy_max_cylinder, 0444,
                        edd_show_legacy_max_cylinder,
 		       edd_has_legacy_max_cylinder);
@@ -572,23 +579,23 @@ static EDD_DEVICE_ATTR(default_sectors_p
 		       edd_has_default_sectors_per_track);
 static EDD_DEVICE_ATTR(interface, 0444, edd_show_interface, edd_has_edd30);
 static EDD_DEVICE_ATTR(host_bus, 0444, edd_show_host_bus, edd_has_edd30);
-static EDD_DEVICE_ATTR(mbr_signature, 0444, edd_show_disk80_sig, edd_has_disk80_sig);
+static EDD_DEVICE_ATTR(mbr_signature, 0444, edd_show_mbr_signature, edd_has_mbr_signature);
 
 
 /* These are default attributes that are added for every edd
- * device discovered.
+ * device discovered.  There are none.
  */
 static struct attribute * def_attrs[] = {
-	&edd_attr_raw_data.attr,
-	&edd_attr_version.attr,
-	&edd_attr_extensions.attr,
-	&edd_attr_info_flags.attr,
-	&edd_attr_sectors.attr,
 	NULL,
 };
 
 /* These attributes are conditional and only added for some devices. */
 static struct edd_attribute * edd_attrs[] = {
+	&edd_attr_raw_data,
+	&edd_attr_version,
+	&edd_attr_extensions,
+	&edd_attr_info_flags,
+	&edd_attr_sectors,
 	&edd_attr_legacy_max_cylinder,
 	&edd_attr_legacy_max_head,
 	&edd_attr_legacy_sectors_per_track,
@@ -709,9 +716,9 @@ edd_device_register(struct edd_device *e
 	if (!edev)
 		return 1;
 	memset(edev, 0, sizeof (*edev));
-	edd_dev_set_info(edev, &edd[i]);
+	edd_dev_set_info(edev, i);
 	kobject_set_name(&edev->kobj, "int13_dev%02x",
-			 edd[i].device);
+			 0x80 + i);
 	kobj_set_kset_s(edev,edd_subsys);
 	error = kobject_register(&edev->kobj);
 	if (!error)
@@ -719,11 +726,15 @@ edd_device_register(struct edd_device *e
 	return error;
 }
 
+static inline int edd_num_devices(void)
+{
+	return min_t(unsigned char,
+		     max_t(unsigned char, edd.edd_info_nr, edd.mbr_signature_nr),
+		     max_t(unsigned char, EDD_MBR_SIG_MAX, EDDMAXNR));
+}
+
 /**
  * edd_init() - creates sysfs tree of EDD data
- *
- * This assumes that eddnr and edd were
- * assigned in setup.c already.
  */
 static int __init
 edd_init(void)
@@ -733,9 +744,9 @@ edd_init(void)
 	struct edd_device *edev;
 
 	printk(KERN_INFO "BIOS EDD facility v%s %s, %d devices found\n",
-	       EDD_VERSION, EDD_DATE, eddnr);
+	       EDD_VERSION, EDD_DATE, edd_num_devices());
 
-	if (!eddnr) {
+	if (!edd_num_devices()) {
 		printk(KERN_INFO "EDD information not available.\n");
 		return 1;
 	}
@@ -744,7 +755,7 @@ edd_init(void)
 	if (rc)
 		return rc;
 
-	for (i = 0; i < eddnr && i < EDDMAXNR && !rc; i++) {
+	for (i = 0; i < edd_num_devices() && !rc; i++) {
 		edev = kmalloc(sizeof (*edev), GFP_KERNEL);
 		if (!edev)
 			return -ENOMEM;
@@ -768,7 +779,7 @@ edd_exit(void)
 	int i;
 	struct edd_device *edev;
 
-	for (i = 0; i < eddnr && i < EDDMAXNR; i++) {
+	for (i = 0; i < edd_num_devices(); i++) {
 		if ((edev = edd_devices[i]))
 			edd_device_unregister(edev);
 	}
diff -puN include/asm-i386/setup.h~edd-store-mbr_signature-on-first-16-int13-devices include/asm-i386/setup.h
--- 25/include/asm-i386/setup.h~edd-store-mbr_signature-on-first-16-int13-devices	2004-06-28 13:33:34.504194248 -0700
+++ 25-akpm/include/asm-i386/setup.h	2004-06-28 13:33:34.514192728 -0700
@@ -56,8 +56,9 @@ extern unsigned char boot_params[PARAM_S
 #define INITRD_START (*(unsigned long *) (PARAM+0x218))
 #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
 #define EDID_INFO   (*(struct edid_info *) (PARAM+0x440))
-#define DISK80_SIGNATURE (*(unsigned int*) (PARAM+DISK80_SIG_BUFFER))
 #define EDD_NR     (*(unsigned char *) (PARAM+EDDNR))
+#define EDD_MBR_SIG_NR (*(unsigned char *) (PARAM+EDD_MBR_SIG_NR_BUF))
+#define EDD_MBR_SIGNATURE ((unsigned int *) (PARAM+EDD_MBR_SIG_BUF))
 #define EDD_BUF     ((struct edd_info *) (PARAM+EDDBUF))
 
 #endif /* __ASSEMBLY__ */
diff -puN include/linux/edd.h~edd-store-mbr_signature-on-first-16-int13-devices include/linux/edd.h
--- 25/include/linux/edd.h~edd-store-mbr_signature-on-first-16-int13-devices	2004-06-28 13:33:34.506193944 -0700
+++ 25-akpm/include/linux/edd.h	2004-06-28 13:33:34.515192576 -0700
@@ -1,6 +1,6 @@
 /*
  * linux/include/linux/edd.h
- *  Copyright (C) 2002, 2003 Dell Inc.
+ *  Copyright (C) 2002, 2003, 2004 Dell Inc.
  *  by Matt Domsch <Matt_Domsch@dell.com>
  *
  * structures and definitions for the int 13h, ax={41,48}h
@@ -9,8 +9,8 @@
  * available at http://www.t13.org/docs2002/d1572r0.pdf.  It is
  * very similar to D1484 Revision 3 http://www.t13.org/docs2002/d1484r3.pdf
  *
- * In a nutshell, arch/{i386,x86_64}/boot/setup.S populates a scratch table
- * in the empty_zero_block that contains a list of BIOS-enumerated
+ * In a nutshell, arch/{i386,x86_64}/boot/setup.S populates a scratch
+ * table in the boot_params that contains a list of BIOS-enumerated
  * boot devices.
  * In arch/{i386,x86_64}/kernel/setup.c, this information is
  * transferred into the edd structure, and in drivers/firmware/edd.c, that
@@ -31,8 +31,8 @@
 #define _LINUX_EDD_H
 
 #define EDDNR 0x1e9		/* addr of number of edd_info structs at EDDBUF
-				   in empty_zero_block - treat this as 1 byte  */
-#define EDDBUF	0x600		/* addr of edd_info structs in empty_zero_block */
+				   in boot_params - treat this as 1 byte  */
+#define EDDBUF	0x600		/* addr of edd_info structs in boot_params */
 #define EDDMAXNR 6		/* number of edd_info structs starting at EDDBUF  */
 #define EDDEXTSIZE 8		/* change these if you muck with the structures */
 #define EDDPARMSIZE 74
@@ -42,9 +42,13 @@
 #define EDDMAGIC1 0x55AA
 #define EDDMAGIC2 0xAA55
 
-#define READ_SECTORS 0x02
-#define MBR_SIG_OFFSET 0x1B8
-#define DISK80_SIG_BUFFER 0x2cc
+
+#define READ_SECTORS 0x02         /* int13 AH=0x02 is READ_SECTORS command */
+#define EDD_MBR_SIG_OFFSET 0x1B8  /* offset of signature in the MBR */
+#define EDD_MBR_SIG_BUF    0x290  /* addr in boot params */
+#define EDD_MBR_SIG_MAX 16        /* max number of signatures to store */
+#define EDD_MBR_SIG_NR_BUF 0x1ea  /* addr of number of MBR signtaures at EDD_MBR_SIG_BUF
+				     in boot_params - treat this as 1 byte  */
 #ifndef __ASSEMBLY__
 
 #define EDD_EXT_FIXED_DISK_ACCESS           (1 << 0)
@@ -172,9 +176,14 @@ struct edd_info {
 	struct edd_device_params params;
 } __attribute__ ((packed));
 
-extern struct edd_info edd[EDDMAXNR];
-extern unsigned char eddnr;
-extern unsigned int edd_disk80_sig;
+struct edd {
+	unsigned int mbr_signature[EDD_MBR_SIG_MAX];
+	struct edd_info edd_info[EDDMAXNR];
+	unsigned char mbr_signature_nr;
+	unsigned char edd_info_nr;
+};
+
+extern struct edd edd;
 
 #endif				/*!__ASSEMBLY__ */
 
_