From 464f04c9e9b3b1c4f5ffb89c51d8ba2a2034c846 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sat, 6 Sep 2008 12:40:21 +0400 Subject: x86: fix ghost EDD devices in /sys again > This is regression but old enough. Apparently I had for whatever reasons > EDD turned off till recently. This is 2.6.27-rc5 just in case. > > In 2006 I fixed ghost devices due to buggy BIOS: > > http://marc.info/?l=linux-kernel&m=114087765422490&w=2 > > Later edd.S has been rewritten in C, and apparently this patch has been > lost: > > {pts/1}% ls /sys/firmware/edd > int13_dev80/ int13_dev84/ int13_dev88/ int13_dev8c/ > int13_dev81/ int13_dev85/ int13_dev89/ int13_dev8d/ > int13_dev82/ int13_dev86/ int13_dev8a/ int13_dev8e/ > int13_dev83/ int13_dev87/ int13_dev8b/ int13_dev8f/ > > But I have just a single disk. This is the same system BTW. Some BIOSes do not always set CF on error before return from int13. The patch adds additional check for status being zero (AH == 0). This was fixed for edd.S in http://marc.info/?l=linux-kernel&m=114087765422490&w=2, but lost again when edd.S was rewritten in C. Signed-off-by: Andrey Borzenkov Signed-off-by: Ingo Molnar --- arch/x86/boot/edd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/x86/boot/edd.c') diff --git a/arch/x86/boot/edd.c b/arch/x86/boot/edd.c index d93cbc6464d..bf4ae6ff518 100644 --- a/arch/x86/boot/edd.c +++ b/arch/x86/boot/edd.c @@ -32,7 +32,9 @@ static int read_mbr(u8 devno, void *buf) : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx) : : "esi", "edi", "memory"); - return -(u8)ax; /* 0 or -1 */ + /* Some BIOSes do not set carry flag on error but still return + * error in AH. The condition below is expected to catch both */ + return -!!ax; /* 0 or -1 */ } static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig) -- cgit v1.2.2 From 6cdcdb99cf7c2e1835fc5b471864d21161c3e679 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Fri, 3 Oct 2008 21:08:49 +0400 Subject: x86 setup: fix ghost entries under /sys/firmware/edd take 3 Some BIOSes do not indicate error when trying to read from non- existing device. Zero buffer before reading and check that we possibly have valid MBR by looking for MBR magic. This was fixed in different way for edd.S in http://marc.info/?l=linux-kernel&m=114087765422490&w=2, but lost again when edd.S was rewritten in C. Signed-off-by: Andrey Borzenkov < arvidjaar@mail.ru> Signed-off-by: H. Peter Anvin --- arch/x86/boot/edd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch/x86/boot/edd.c') diff --git a/arch/x86/boot/edd.c b/arch/x86/boot/edd.c index bf4ae6ff518..067e28cd3c5 100644 --- a/arch/x86/boot/edd.c +++ b/arch/x86/boot/edd.c @@ -43,6 +43,7 @@ static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig) char *mbrbuf_ptr, *mbrbuf_end; u32 buf_base, mbr_base; extern char _end[]; + u16 mbr_magic; sector_size = ei->params.bytes_per_sector; if (!sector_size) @@ -60,11 +61,15 @@ static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig) if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr) return -1; + memset(mbrbuf_ptr, 0, sector_size); if (read_mbr(devno, mbrbuf_ptr)) return -1; *mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET]; - return 0; + mbr_magic = *(u16 *)&mbrbuf_ptr[510]; + + /* check for valid MBR magic */ + return mbr_magic == 0xAA55 ? 0 : -1; } static int get_edd_info(u8 devno, struct edd_info *ei) -- cgit v1.2.2 From 98920dc3d1113b883cbc73e3293446d3525c6042 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 3 Oct 2008 10:22:33 -0700 Subject: Revert "x86: fix ghost EDD devices in /sys again" This reverts commit 464f04c9e9b3b1c4f5ffb89c51d8ba2a2034c846. Obsoleted by commit 6cdcdb99cf7c2e1835fc5b471864d21161c3e679. Signed-off-by: H. Peter Anvin --- arch/x86/boot/edd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/x86/boot/edd.c') diff --git a/arch/x86/boot/edd.c b/arch/x86/boot/edd.c index 067e28cd3c5..1aae8f3e5ca 100644 --- a/arch/x86/boot/edd.c +++ b/arch/x86/boot/edd.c @@ -32,9 +32,7 @@ static int read_mbr(u8 devno, void *buf) : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx) : : "esi", "edi", "memory"); - /* Some BIOSes do not set carry flag on error but still return - * error in AH. The condition below is expected to catch both */ - return -!!ax; /* 0 or -1 */ + return -(u8)ax; /* 0 or -1 */ } static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig) -- cgit v1.2.2