PCI reboots (patch!)

Joe Pranevich (joepran@telerama.lm.com)
Wed, 19 Nov 1997 01:30:57 -0500


Hello again,

In response to the problem that I posted about earlier, I have assembled
a patch that solves the problem on my machine. (Thanks to Alan for
reminding me that sometimes the brute force method is the only method.)

I have recently revealed some mail that would lead me to believe that
this problem is on several (rare?) versions of the Award Modular BIOS
(and whatever name it used to go by, WinBIOS?) This patch checks *only*
for my exact version of the BIOS for my machine. If you are experiencing
simular problems to the ones that I have described, I will add a check
for it in my patch and we can see if it helps you.

This isn't a great patch, it does not meet all of the specifications
that I described in my previous post and is for testing *only* I will
add support for PCI direct access and whatever, later. But, if you have
a suggestion as to how I can better handle these things or if I'm not
following the standard Linux naming conventions, please tell me and I'll
have it fixed before I begin to think seriously about sending my patch
to a higher power.

This patch is against 2.1.65 (latest?) and should be easily ported to
2.0, I'll do that when I finalize things. Any problems or complaints,
mail me. (If you get the notifiation message that your BIOS is buggy and
you have had no problems before, that's a pretty good indication of a
problem.)

Thanks,

Joe Pranevich

diff -ruN linux-2.1/arch/i386/kernel/bios32.c
linux-play/arch/i386/kernel/bios32.c
--- linux-2.1/arch/i386/kernel/bios32.c Sat Sep 6 13:43:49 1997
+++ linux-play/arch/i386/kernel/bios32.c Wed Nov 19 01:05:50 1997
@@ -78,6 +78,8 @@
#include <asm/system.h>
#include <asm/io.h>

+#define AWARD_VERSION_BASE 0x000fe0c1
+
/*
* Generic PCI access -- indirect calls according to detected HW.
*/
@@ -822,6 +824,36 @@
* Try to find PCI BIOS.
*/

+static struct pci_access *pci_bug_detect(
+ struct pci_access *pci_struct)
+{
+ /* What this piece of code attempts to do is to detect
*
+ * any bioses that are known to have bugs in their pci *
+ * code. Whenever possible, we should substitute *
+ * working code (maybe defaulting to direct access if *
+ * that is known to work) If not, we can use the stub *
+ * functions. If we cannot do *anything* with this BIOS *
+ * then just turn the whole thing off. */
+
+ /* I do not know of any other way to determine BIOS *
+ * version and name than to scan for its unique strings */
+
+ /* This really needs to be generalized. Please help! */
+
+ char biosstring[9];
+
+ biosstring[8] = (char) 0;
+ memcpy(biosstring, __va(AWARD_VERSION_BASE), 8);
+
+ if (!strcmp("ATA0820B", biosstring))
+ {
+ printk("PCI: Possibly Buggy BIOS Version Detected
(ATA0820B)\n");
+ printk("PCI: Disabling Some Options\n");
+ pci_struct->find_device = (void *) pci_stub;
+ }
+ return pci_struct;
+}
+
__initfunc(static struct pci_access *pci_find_bios(void))
{
union bios32 *check;
@@ -865,7 +897,7 @@
printk ("PCI: BIOS32 Service Directory entry at
0x%lx\n", bios32_entry);
bios32_indirect.address = bios32_entry +
PAGE_OFFSET;
if (check_pcibios())
- return &pci_bios_access;
+ return pci_bug_detect(&pci_bios_access);
}
break; /* Hopefully more than one BIOS32 cannot
happen... */