patch-2.3.36 linux/drivers/pci/pci.c
Next file: linux/drivers/pcmcia/Config.in
Previous file: linux/drivers/pci/names.c
Back to the patch index
Back to the overall index
- Lines: 141
- Date:
Mon Jan 3 12:18:01 2000
- Orig file:
v2.3.35/linux/drivers/pci/pci.c
- Orig date:
Wed Dec 29 13:13:16 1999
diff -u --recursive --new-file v2.3.35/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
@@ -269,7 +269,7 @@
return IORESOURCE_MEM;
}
-static void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
+static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
{
unsigned int pos, reg, next;
u32 l, sz, tmp;
@@ -447,6 +447,7 @@
*/
static int __init pci_scan_cardbus(struct pci_bus *bus, struct pci_dev *dev, int busnr)
{
+ int i;
unsigned short cr;
unsigned int buses;
struct pci_bus *child;
@@ -455,7 +456,14 @@
* Insert it into the tree of buses.
*/
child = pci_add_new_bus(bus, dev, ++busnr);
- child->subordinate = busnr;
+
+ for (i = 0; i < 4; i++)
+ child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
+
+ /*
+ * Maybe we'll have another bus behind this one?
+ */
+ child->subordinate = ++busnr;
sprintf(child->name, "PCI CardBus #%02x", child->number);
/*
@@ -566,7 +574,7 @@
* Read interrupt line and base address registers.
* The architecture-dependent code can tweak these, of course.
*/
-static void __init pci_read_irq(struct pci_dev *dev)
+static void pci_read_irq(struct pci_dev *dev)
{
unsigned char irq;
@@ -577,31 +585,15 @@
}
/*
- * Read the config data for a PCI device, sanity-check it
- * and fill in the dev structure...
+ * Fill in class and map information of a device
*/
-static struct pci_dev * __init pci_scan_device(struct pci_dev *temp)
+int pci_setup_device(struct pci_dev * dev)
{
- struct pci_dev *dev;
- u32 l, class;
+ u32 class;
- if (pci_read_config_dword(temp, PCI_VENDOR_ID, &l))
- return NULL;
-
- /* some broken boards return 0 or ~0 if a slot is empty: */
- if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000)
- return NULL;
-
- dev = kmalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return NULL;
-
- memcpy(dev, temp, sizeof(*dev));
- dev->vendor = l & 0xffff;
- dev->device = (l >> 16) & 0xffff;
sprintf(dev->slot_name, "%02x:%02x.%d", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
- pci_name_device(dev);
-
+ sprintf(dev->name, "PCI device %04x:%04x", dev->vendor, dev->device);
+
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
class >>= 8; /* upper 3 bytes */
dev->class = class;
@@ -635,8 +627,7 @@
default: /* unknown header */
printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n",
dev->slot_name, dev->hdr_type);
- kfree(dev);
- return NULL;
+ return -1;
bad:
printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n",
@@ -645,6 +636,36 @@
}
/* We found a fine healthy device, go go go... */
+ return 0;
+}
+
+/*
+ * Read the config data for a PCI device, sanity-check it
+ * and fill in the dev structure...
+ */
+static struct pci_dev * __init pci_scan_device(struct pci_dev *temp)
+{
+ struct pci_dev *dev;
+ u32 l;
+
+ if (pci_read_config_dword(temp, PCI_VENDOR_ID, &l))
+ return NULL;
+
+ /* some broken boards return 0 or ~0 if a slot is empty: */
+ if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000)
+ return NULL;
+
+ dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ memcpy(dev, temp, sizeof(*dev));
+ dev->vendor = l & 0xffff;
+ dev->device = (l >> 16) & 0xffff;
+ if (pci_setup_device(dev) < 0) {
+ kfree(dev);
+ dev = NULL;
+ }
return dev;
}
@@ -667,12 +688,13 @@
dev = pci_scan_device(temp);
if (!dev)
continue;
+ pci_name_device(dev);
if (!func) {
is_multi = hdr_type & 0x80;
first_dev = dev;
}
- DBG("PCI: %02x:%02x [%04x/%04x] %06x %02x\n", bus->number, dev->devfn, dev->vendor, dev->device, class, hdr_type);
+ DBG("PCI: %02x:%02x [%04x/%04x] %06x %02x\n", bus->number, dev->devfn, dev->vendor, dev->device, dev->class, hdr_type);
/*
* Put it into the global PCI device chain. It's used to
FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen (who was at: [email protected])