Commit 2ce208e5 authored by Ivan Kokshaysky's avatar Ivan Kokshaysky Committed by Linus Torvalds

[PATCH] PCI: setup-xx fixes

Don't disable PCI devices before changing the BARs, as discussed
recently.  Disabling PCI_COMMAND_MASTER bit is an obvious bug.

Further, pdev_enable_device() is a leftover from very old (2.0, I guess)
alpha PCI code.  It's used in pci_assign_unassigned_resources() to
enable *every* PCI device in the system.  So, if we have two graphic
cards on the same bus, both with legacy VGA IO...  oops.

Actually, only alpha relied on that due to the lack of
pcibios_enable_device (which has been already fixed).
parent 9dd405aa
......@@ -48,23 +48,10 @@ pbus_assign_resources_sorted(struct pci_bus *bus)
for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
struct pci_dev *dev = pci_dev_b(ln);
u16 class = dev->class >> 8;
u16 cmd;
/* First, disable the device to avoid side
effects of possibly overlapping I/O and
memory ranges.
Leave VGA enabled - for obvious reason. :-)
Same with all sorts of bridges - they may
have VGA behind them. */
if (class == PCI_CLASS_DISPLAY_VGA
|| class == PCI_CLASS_NOT_DEFINED_VGA)
found_vga = 1;
else if (class >> 8 != PCI_BASE_CLASS_BRIDGE) {
pci_read_config_word(dev, PCI_COMMAND, &cmd);
cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY
| PCI_COMMAND_MASTER);
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
pdev_sort_resources(dev, &head);
}
......@@ -387,7 +374,6 @@ void __init
pci_assign_unassigned_resources(void)
{
struct list_head *ln;
struct pci_dev *dev;
/* Depth first, calculate sizes and alignments of all
subordinate buses. */
......@@ -396,8 +382,4 @@ pci_assign_unassigned_resources(void)
/* Depth last, allocate resources and update the hardware. */
for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next)
pci_bus_assign_resources(pci_bus_b(ln));
pci_for_each_dev(dev) {
pdev_enable_device(dev);
}
}
......@@ -183,57 +183,3 @@ pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
}
}
}
void __init
pdev_enable_device(struct pci_dev *dev)
{
u32 reg;
u16 cmd;
int i;
DBGC((KERN_ERR "PCI enable device: (%s)\n", dev->name));
pci_read_config_word(dev, PCI_COMMAND, &cmd);
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
struct resource *res = &dev->resource[i];
if (res->flags & IORESOURCE_IO)
cmd |= PCI_COMMAND_IO;
else if (res->flags & IORESOURCE_MEM)
cmd |= PCI_COMMAND_MEMORY;
}
/* Special case, disable the ROM. Several devices act funny
(ie. do not respond to memory space writes) when it is left
enabled. A good example are QlogicISP adapters. */
if (dev->rom_base_reg) {
pci_read_config_dword(dev, dev->rom_base_reg, &reg);
reg &= ~PCI_ROM_ADDRESS_ENABLE;
pci_write_config_dword(dev, dev->rom_base_reg, reg);
dev->resource[PCI_ROM_RESOURCE].flags &= ~PCI_ROM_ADDRESS_ENABLE;
}
/* All of these (may) have I/O scattered all around and may not
use I/O base address registers at all. So we just have to
always enable IO to these devices. */
if ((dev->class >> 8) == PCI_CLASS_NOT_DEFINED
|| (dev->class >> 8) == PCI_CLASS_NOT_DEFINED_VGA
|| (dev->class >> 8) == PCI_CLASS_STORAGE_IDE
|| (dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
cmd |= PCI_COMMAND_IO;
}
/* Do not enable bus mastering. A device could corrupt
* system memory by DMAing before a driver is ready for it. */
/* Set the cache line and default latency (32). */
pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
(32 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
/* Enable the appropriate bits in the PCI command register. */
pci_write_config_word(dev, PCI_COMMAND, cmd);
DBGC((KERN_ERR " cmd reg 0x%x\n", cmd));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment