Re: Weird PCI problem

Gerard Roudier (groudier@club-internet.fr)
Sat, 17 Apr 1999 10:12:06 +0200 (MET DST)


Somebody suggested a possible PCI BIOS bug and 2.0 kernel being victimized
by this PCI BIOS bug. Note that the 2.0.3X kernels I have ever used didn't
rely on PCI BIOS for configuration access, for _reasons_. I use the
current diff against 2.0.36 on my machines (this is pretty well an hack
and shouldn't work that well on PCI-bogused hardware):

--- bios32.c.orig Sun Oct 19 18:47:21 1997
+++ bios32.c Sat Mar 13 17:48:19 1999
@@ -870,6 +870,16 @@
unsigned char sum;
int i, length;

+
+ /*
+ * We should always prefer direct methods against BIOS based ones.
+ * So, if any direct method is available, we want to go with it
+ * and just ignore the PCI BIOS.
+ */
+ access_pci = check_direct_pci();
+ if (access_pci)
+ goto end;
+
/*
* Follow the standard procedure for locating the BIOS32 Service
* directory by scanning the permissible address range from
@@ -910,5 +920,6 @@
if (bios32_entry && check_pcibios())
access_pci = &pci_bios_access;
#endif
+end:
return memory_start;
}

If we assume that the hardware is correct (as your testings seem to
demonstrate), then it may well be the PCI BIOS trying to be clever by
caching PCI configuration accesses and being just wrong at behaving with
hardwired bits.

Gérard.

On Fri, 16 Apr 1999, Linux Lists wrote:

>
> On Thu, 15 Apr 1999, Gerard Roudier wrote:
> >
> > Could it be possible that bit 0 is just writable for this base address
> > register. You can verify that by hacking appropriately the Cyclades driver
> > in its detection routine. You may try for example:
> >
> > - Read the value of the offending base address reg. and save it.
> > - Write 1 to that base address reg., then read it and print the value.
> > - Write 0 to that base address, then read it and print the value.
> > - Restore the value of that base address.
>
> Ok, did that in a machine where the Cyclom-Y board is assigned the proper
> address (i.e., the address type it has requested):
>
>
> - Before:
>
> pcibios_read_config_dword(cyy_bus, cyy_dev_fn,
> PCI_BASE_ADDRESS_2,
> (unsigned int *) &cy_pci_addr2);
>
> - After:
>
> pcibios_read_config_dword(cyy_bus, cyy_dev_fn,
> PCI_BASE_ADDRESS_2,
> (unsigned int *) &cy_pci_addr2);
> printk("got 0x%lx ; ", cy_pci_addr2);
> cy_pci_addr_tmp = cy_pci_addr2;
> cy_pci_addr2 |= 0x01;
> pcibios_write_config_dword(cyy_bus, cyy_dev_fn,
> PCI_BASE_ADDRESS_2,
> cy_pci_addr2);
> printk("wrote 0x%lx ; ", cy_pci_addr2);
> pcibios_read_config_dword(cyy_bus, cyy_dev_fn,
> PCI_BASE_ADDRESS_2,
> (unsigned int *) &cy_pci_addr2);
> printk("got 0x%lx\n", cy_pci_addr2);
> cy_pci_addr2 = 0xffffffff;
> pcibios_write_config_dword(cyy_bus, cyy_dev_fn,
> PCI_BASE_ADDRESS_2,
> cy_pci_addr2);
> printk("wrote 0x%lx ; ", cy_pci_addr2);
> pcibios_read_config_dword(cyy_bus, cyy_dev_fn,
> PCI_BASE_ADDRESS_2,
> (unsigned int *) &cy_pci_addr2);
> printk("got 0x%lx\n", cy_pci_addr2);
> pcibios_write_config_dword(cyy_bus, cyy_dev_fn,
> PCI_BASE_ADDRESS_2,
> cy_pci_addr_tmp);
>
> pcibios_read_config_dword(cyy_bus, cyy_dev_fn,
> PCI_BASE_ADDRESS_2,
> (unsigned int *) &cy_pci_addr2);
>
> Results:
>
> Cyclades driver 2.1.2.1 1999/04/08 16:17:18
> built Apr 16 1999 14:52:03
> got 0xe0310000 ; wrote 0xe0310001 ; got 0xe0310000
> wrote 0xffffffff ; got 0xffffc000
> Cyclom-Y/PCI #1: 0x2e88000-0x2e8bfff, IRQ15, 16 channels starting from
> port 0.
>
> That has shown that, at least by using the Linux kernel PCI interface
> commands (pcibios_read/write_config), I'm not able to change that bit.
> Furthermore, it has shown that I can't write to the last 14 bits [13-0] of
> the base address register.
>
> Again, this was done in a machine where the Cyclom-Y board is assigned the
> proper address (i.e., the address type it has requested). Do you think
> that this test would yell a different result if run on the "deffective"
> system ??
>
> Regards,
> Ivan
>
>
>

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/