While sizing BARs, devices are temporarily assigned ranges
that may conflict with other things in the system, like IOSAPICs.
Here's a detailed description of a hang that results from leaving
device decoding enabled while sizing the BARs:
https://lists.linuxia64.org/archives//linux-ia64/2002-April/003302.html
This patch applies to current 2.4 BitKeeper.
--- linux-2.4/drivers/pci/pci.c 2002-12-16 10:44:21.000000000 -0700
+++ testing/drivers/pci/pci.c 2002-12-16 17:22:26.000000000 -0700
@@ -1058,8 +1058,14 @@
{
unsigned int pos, reg, next;
u32 l, sz;
+ u16 cmd;
struct resource *res;
+ /* Disable I/O & memory decoding while we size the BARs. */
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_write_config_word(dev, PCI_COMMAND,
+ cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
+
for(pos=0; pos<howmany; pos = next) {
next = pos+1;
res = &dev->resource[pos];
@@ -1131,6 +1137,8 @@
res->end = res->start + (unsigned long) sz;
}
}
+
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
}
void __devinit pci_read_bridge_bases(struct pci_bus *child)
On Mon, Dec 16, 2002 at 05:41:53PM -0700, Bjorn Helgaas wrote:
> + /* Disable I/O & memory decoding while we size the BARs. */
> + pci_read_config_word(dev, PCI_COMMAND, &cmd);
> + pci_write_config_word(dev, PCI_COMMAND,
> + cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
It's fatal for certain x86 northbridges, that's why the code was
removed 2 years ago.
Maybe it would be ok with this modification:
pci_read_config_word(dev, PCI_COMMAND, &cmd);
/* Don't touch northbridges or devices with devfn 0:0 */
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_HOST && dev->devfn)
pci_write_config_word(dev, PCI_COMMAND,
cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
Ivan.
On Tue, 17 Dec 2002, Ivan Kokshaysky wrote:
> On Mon, Dec 16, 2002 at 05:41:53PM -0700, Bjorn Helgaas wrote:
> > + /* Disable I/O & memory decoding while we size the BARs. */
> > + pci_read_config_word(dev, PCI_COMMAND, &cmd);
> > + pci_write_config_word(dev, PCI_COMMAND,
> > + cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
>
> It's fatal for certain x86 northbridges, that's why the code was
> removed 2 years ago.
>
> Maybe it would be ok with this modification:
>
> pci_read_config_word(dev, PCI_COMMAND, &cmd);
> /* Don't touch northbridges or devices with devfn 0:0 */
> if ((dev->class >> 8) != PCI_CLASS_BRIDGE_HOST && dev->devfn)
> pci_write_config_word(dev, PCI_COMMAND,
> cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
Ok, I've reverted this one.