Commit ebe7808b authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/gregkh/linux/pci-2.5

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents f921e208 c2b73f42
...@@ -196,21 +196,35 @@ static struct pci_ops pci_direct_conf2 = { ...@@ -196,21 +196,35 @@ static struct pci_ops pci_direct_conf2 = {
static int __devinit pci_sanity_check(struct pci_ops *o) static int __devinit pci_sanity_check(struct pci_ops *o)
{ {
u32 x = 0; u32 x = 0;
struct pci_bus bus; /* Fake bus and device */ int retval = 0;
struct pci_dev dev; struct pci_bus *bus; /* Fake bus and device */
struct pci_dev *dev;
if (pci_probe & PCI_NO_CHECKS) if (pci_probe & PCI_NO_CHECKS)
return 1; return 1;
bus.number = 0;
dev.bus = &bus; bus = kmalloc(sizeof(*bus), GFP_ATOMIC);
for(dev.devfn=0; dev.devfn < 0x100; dev.devfn++) dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
if ((!o->read(&bus, dev.devfn, PCI_CLASS_DEVICE, 2, &x) && if (!bus || !dev) {
printk(KERN_ERR "Out of memory in %s\n", __FUNCTION__);
goto exit;
}
bus->number = 0;
dev->bus = bus;
for(dev->devfn=0; dev->devfn < 0x100; dev->devfn++)
if ((!o->read(bus, dev->devfn, PCI_CLASS_DEVICE, 2, &x) &&
(x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) || (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) ||
(!o->read(&bus, dev.devfn, PCI_VENDOR_ID, 2, &x) && (!o->read(bus, dev->devfn, PCI_VENDOR_ID, 2, &x) &&
(x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ))) (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ))) {
return 1; retval = 1;
goto exit;
}
DBG("PCI: Sanity check failed\n"); DBG("PCI: Sanity check failed\n");
return 0; exit:
kfree(dev);
kfree(bus);
return retval;
} }
static int __init pci_direct_init(void) static int __init pci_direct_init(void)
......
...@@ -12,28 +12,39 @@ ...@@ -12,28 +12,39 @@
static void __devinit pcibios_fixup_peer_bridges(void) static void __devinit pcibios_fixup_peer_bridges(void)
{ {
int n; int n;
struct pci_bus bus; struct pci_bus *bus;
struct pci_dev dev; struct pci_dev *dev;
u16 l; u16 l;
if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff) if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
return; return;
DBG("PCI: Peer bridge fixup\n"); DBG("PCI: Peer bridge fixup\n");
bus = kmalloc(sizeof(*bus), GFP_ATOMIC);
dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
if (!bus || !dev) {
printk(KERN_ERR "Out of memory in %s\n", __FUNCTION__);
goto exit;
}
for (n=0; n <= pcibios_last_bus; n++) { for (n=0; n <= pcibios_last_bus; n++) {
if (pci_bus_exists(&pci_root_buses, n)) if (pci_bus_exists(&pci_root_buses, n))
continue; continue;
bus.number = n; bus->number = n;
bus.ops = pci_root_ops; bus->ops = pci_root_ops;
dev.bus = &bus; dev->bus = bus;
for(dev.devfn=0; dev.devfn<256; dev.devfn += 8) for (dev->devfn=0; dev->devfn<256; dev->devfn += 8)
if (!pci_read_config_word(&dev, PCI_VENDOR_ID, &l) && if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
l != 0x0000 && l != 0xffff) { l != 0x0000 && l != 0xffff) {
DBG("Found device at %02x:%02x [%04x]\n", n, dev.devfn, l); DBG("Found device at %02x:%02x [%04x]\n", n, dev->devfn, l);
printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n); printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
pci_scan_bus(n, pci_root_ops, NULL); pci_scan_bus(n, pci_root_ops, NULL);
break; break;
} }
} }
exit:
kfree(dev);
kfree(bus);
} }
static int __init pci_legacy_init(void) static int __init pci_legacy_init(void)
......
...@@ -505,23 +505,30 @@ unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) ...@@ -505,23 +505,30 @@ unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
{ {
unsigned int devfn, max, pass; unsigned int devfn, max, pass;
struct list_head *ln; struct list_head *ln;
struct pci_dev *dev, dev0; struct pci_dev *dev;
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
printk(KERN_ERR "Out of memory in %s\n", __FUNCTION__);
return 0;
}
DBG("Scanning bus %02x\n", bus->number); DBG("Scanning bus %02x\n", bus->number);
max = bus->secondary; max = bus->secondary;
/* Create a device template */ /* Create a device template */
memset(&dev0, 0, sizeof(dev0)); memset(dev, 0, sizeof(*dev));
dev0.bus = bus; dev->bus = bus;
dev0.sysdata = bus->sysdata; dev->sysdata = bus->sysdata;
dev0.dev.parent = bus->dev; dev->dev.parent = bus->dev;
dev0.dev.bus = &pci_bus_type; dev->dev.bus = &pci_bus_type;
/* Go find them, Rover! */ /* Go find them, Rover! */
for (devfn = 0; devfn < 0x100; devfn += 8) { for (devfn = 0; devfn < 0x100; devfn += 8) {
dev0.devfn = devfn; dev->devfn = devfn;
pci_scan_slot(&dev0); pci_scan_slot(dev);
} }
kfree(dev);
/* /*
* After performing arch-dependent fixup of the bus, look behind * After performing arch-dependent fixup of the bus, look behind
...@@ -549,10 +556,9 @@ unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) ...@@ -549,10 +556,9 @@ unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
int __devinit pci_bus_exists(const struct list_head *list, int nr) int __devinit pci_bus_exists(const struct list_head *list, int nr)
{ {
const struct list_head *l; const struct pci_bus *b;
for(l=list->next; l != list; l = l->next) { list_for_each_entry(b, list, node) {
const struct pci_bus *b = pci_bus_b(l);
if (b->number == nr || pci_bus_exists(&b->children, nr)) if (b->number == nr || pci_bus_exists(&b->children, nr))
return 1; return 1;
} }
......
...@@ -39,14 +39,13 @@ ...@@ -39,14 +39,13 @@
static int __devinit static int __devinit
pbus_assign_resources_sorted(struct pci_bus *bus) pbus_assign_resources_sorted(struct pci_bus *bus)
{ {
struct list_head *ln; struct pci_dev *dev;
struct resource *res; struct resource *res;
struct resource_list head, *list, *tmp; struct resource_list head, *list, *tmp;
int idx, found_vga = 0; int idx, found_vga = 0;
head.next = NULL; head.next = NULL;
for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) { list_for_each_entry(dev, &bus->devices, bus_list) {
struct pci_dev *dev = pci_dev_b(ln);
u16 class = dev->class >> 8; u16 class = dev->class >> 8;
if (class == PCI_CLASS_DISPLAY_VGA if (class == PCI_CLASS_DISPLAY_VGA
...@@ -201,15 +200,14 @@ pci_bridge_check_ranges(struct pci_bus *bus) ...@@ -201,15 +200,14 @@ pci_bridge_check_ranges(struct pci_bus *bus)
static void __devinit static void __devinit
pbus_size_io(struct pci_bus *bus) pbus_size_io(struct pci_bus *bus)
{ {
struct list_head *ln; struct pci_dev *dev;
struct resource *b_res = bus->resource[0]; struct resource *b_res = bus->resource[0];
unsigned long size = 0, size1 = 0; unsigned long size = 0, size1 = 0;
if (!(b_res->flags & IORESOURCE_IO)) if (!(b_res->flags & IORESOURCE_IO))
return; return;
for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) { list_for_each_entry(dev, &bus->devices, bus_list) {
struct pci_dev *dev = pci_dev_b(ln);
int i; int i;
for (i = 0; i < PCI_NUM_RESOURCES; i++) { for (i = 0; i < PCI_NUM_RESOURCES; i++) {
...@@ -250,7 +248,7 @@ pbus_size_io(struct pci_bus *bus) ...@@ -250,7 +248,7 @@ pbus_size_io(struct pci_bus *bus)
static void __devinit static void __devinit
pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
{ {
struct list_head *ln; struct pci_dev *dev;
unsigned long min_align, align, size; unsigned long min_align, align, size;
unsigned long aligns[12]; /* Alignments from 1Mb to 2Gb */ unsigned long aligns[12]; /* Alignments from 1Mb to 2Gb */
int order, max_order; int order, max_order;
...@@ -261,8 +259,7 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) ...@@ -261,8 +259,7 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
max_order = 0; max_order = 0;
size = 0; size = 0;
for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) { list_for_each_entry(dev, &bus->devices, bus_list) {
struct pci_dev *dev = pci_dev_b(ln);
int i; int i;
for (i = 0; i < PCI_NUM_RESOURCES; i++) { for (i = 0; i < PCI_NUM_RESOURCES; i++) {
...@@ -322,11 +319,12 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) ...@@ -322,11 +319,12 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
void __devinit void __devinit
pci_bus_size_bridges(struct pci_bus *bus) pci_bus_size_bridges(struct pci_bus *bus)
{ {
struct list_head *ln; struct pci_bus *b;
unsigned long mask, type; unsigned long mask, type;
for (ln=bus->children.next; ln != &bus->children; ln=ln->next) list_for_each_entry(b, &bus->children, node) {
pci_bus_size_bridges(pci_bus_b(ln)); pci_bus_size_bridges(b);
}
/* The root bus? */ /* The root bus? */
if (!bus->self) if (!bus->self)
...@@ -350,20 +348,16 @@ EXPORT_SYMBOL(pci_bus_size_bridges); ...@@ -350,20 +348,16 @@ EXPORT_SYMBOL(pci_bus_size_bridges);
void __devinit void __devinit
pci_bus_assign_resources(struct pci_bus *bus) pci_bus_assign_resources(struct pci_bus *bus)
{ {
struct list_head *ln; struct pci_bus *b;
int found_vga = pbus_assign_resources_sorted(bus); int found_vga = pbus_assign_resources_sorted(bus);
if (found_vga) { if (found_vga) {
struct pci_bus *b;
/* Propagate presence of the VGA to upstream bridges */ /* Propagate presence of the VGA to upstream bridges */
for (b = bus; b->parent; b = b->parent) { for (b = bus; b->parent; b = b->parent) {
b->resource[0]->flags |= IORESOURCE_BUS_HAS_VGA; b->resource[0]->flags |= IORESOURCE_BUS_HAS_VGA;
} }
} }
for (ln=bus->children.next; ln != &bus->children; ln=ln->next) { list_for_each_entry(b, &bus->children, node) {
struct pci_bus *b = pci_bus_b(ln);
pci_bus_assign_resources(b); pci_bus_assign_resources(b);
pci_setup_bridge(b); pci_setup_bridge(b);
} }
......
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