summaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-12-04 03:58:56 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-12-04 03:58:56 +0000
commit1d67e90f19a7acfd9a05dc59678e7d0c5090bd0d (patch)
tree357efc7b93f8f5102110d20d293f41360ec212fc /drivers/pci
parentaea27b2e18d69af87e673972246e66657b4fa274 (diff)
Merge with Linux 2.3.21.
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/Makefile6
-rw-r--r--drivers/pci/devlist.h4
-rw-r--r--drivers/pci/helper.c69
-rw-r--r--drivers/pci/pci.c93
-rw-r--r--drivers/pci/quirks.c4
-rw-r--r--drivers/pci/setup.c10
6 files changed, 115 insertions, 71 deletions
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 45197e4c3..0503f4af1 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -25,6 +25,10 @@ ifdef CONFIG_PROC_FS
L_OBJS += proc.o
endif
-L_OBJS += compat.o quirks.o names.o syscall.o setup.o
+L_OBJS += compat.o quirks.o names.o helper.o
+
+ifndef CONFIG_X86
+L_OBJS += syscall.o setup.o
+endif
include $(TOPDIR)/Rules.make
diff --git a/drivers/pci/devlist.h b/drivers/pci/devlist.h
index f0a86af6d..3b4cce5ce 100644
--- a/drivers/pci/devlist.h
+++ b/drivers/pci/devlist.h
@@ -989,6 +989,10 @@ VENDOR( ATRONICS, "Atronics" )
DEVICE( ATRONICS, ATRONICS_2015, "IDE-2015PL")
ENDVENDOR()
+VENDOR( EXSYS, "Exsys" )
+ DEVICE( EXSYS, EXSYS_4014, "EX-4014")
+ENDVENDOR()
+
VENDOR( TIGERJET, "TigerJet" )
DEVICE( TIGERJET, TIGERJET_300, "Tiger300 ISDN")
ENDVENDOR()
diff --git a/drivers/pci/helper.c b/drivers/pci/helper.c
new file mode 100644
index 000000000..928cec4b5
--- /dev/null
+++ b/drivers/pci/helper.c
@@ -0,0 +1,69 @@
+/*
+ * $Id$
+ *
+ * drivers/pci/helper.c
+ *
+ * Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
+ * This software is free. See the file COPYING for licensing details.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+
+int pci_simple_probe (struct pci_simple_probe_entry *list, size_t match_limit,
+ pci_simple_probe_callback cb, void *drvr_data)
+{
+ struct pci_dev *dev;
+ struct pci_simple_probe_entry *ent;
+ size_t matches = 0;
+ unsigned short vendor, device;
+ int rc;
+
+ if (!list || !cb)
+ return -1;
+
+ dev = pci_find_device (PCI_ANY_ID, PCI_ANY_ID, NULL);
+ while (dev) {
+ ent = list;
+ while (ent->vendor && ent->device) {
+ vendor = ent->vendor;
+ device = ent->device;
+
+ if (((vendor != 0xFFFF) &&
+ (vendor != dev->vendor)) ||
+ ((device != 0xFFFF) &&
+ (device != dev->device))) {
+ ent++;
+ continue;
+ }
+
+ if (((ent->subsys_vendor) &&
+ (ent->subsys_vendor != dev->subsystem_vendor)) ||
+ ((ent->subsys_device) &&
+ (ent->subsys_device != dev->subsystem_device))) {
+ ent++;
+ continue;
+ }
+
+ rc = (* cb) (dev, matches, ent, drvr_data);
+ if (rc < 0)
+ return rc;
+
+ matches++;
+
+ if (match_limit && match_limit == matches)
+ return matches;
+
+ ent++;
+ }
+
+ dev = pci_find_device (PCI_ANY_ID, PCI_ANY_ID, dev);
+ }
+
+ return matches;
+}
+
+
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 51c229c25..5cf991521 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -17,7 +17,6 @@
#include <linux/malloc.h>
#include <linux/ioport.h>
-#include <asm/pci.h>
#include <asm/page.h>
#undef DEBUG
@@ -125,26 +124,20 @@ pci_find_parent_resource(struct pci_dev *dev, struct resource *res)
int i;
struct resource *best = NULL;
- while (bus) {
- for(i=0; i<4; i++) {
- struct resource *r = bus->resource[i];
- if (!r)
- continue;
- if (res->start && !(res->start >= r->start && res->end <= r->end))
- continue; /* Not contained */
- if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM))
- continue; /* Wrong type */
- if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH))
- return r; /* Exact match */
- if ((res->flags & IORESOURCE_PREFETCH) && !(r->flags & IORESOURCE_PREFETCH))
- best = r; /* Approximating prefetchable by non-prefetchable */
- }
- if (best)
- return best;
- bus = bus->parent;
+ for(i=0; i<4; i++) {
+ struct resource *r = bus->resource[i];
+ if (!r)
+ continue;
+ if (res->start && !(res->start >= r->start && res->end <= r->end))
+ continue; /* Not contained */
+ if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM))
+ continue; /* Wrong type */
+ if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH))
+ return r; /* Exact match */
+ if ((res->flags & IORESOURCE_PREFETCH) && !(r->flags & IORESOURCE_PREFETCH))
+ best = r; /* Approximating prefetchable by non-prefetchable */
}
- printk(KERN_ERR "PCI: Bug: Parent resource not found!\n");
- return NULL;
+ return best;
}
@@ -193,47 +186,18 @@ pci_set_master(struct pci_dev *dev)
pci_read_config_word(dev, PCI_COMMAND, &cmd);
if (! (cmd & PCI_COMMAND_MASTER)) {
- printk("PCI: Enabling bus mastering for device %s\n", dev->name);
+ printk("PCI: Enabling bus mastering for device %s\n", dev->slot_name);
cmd |= PCI_COMMAND_MASTER;
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
if (lat < 16) {
- printk("PCI: Increasing latency timer of device %s to 64\n", dev->name);
+ printk("PCI: Increasing latency timer of device %s to 64\n", dev->slot_name);
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
}
}
/*
- * Assign new address to PCI resource. We hope our resource information
- * is complete. On the PC, we don't re-assign resources unless we are
- * forced to do so or the driver asks us to.
- *
- * Expects start=0, end=size-1, flags=resource type.
- */
-int __init pci_assign_resource(struct pci_dev *dev, int i)
-{
- struct resource *r = &dev->resource[i];
- struct resource *pr = pci_find_parent_resource(dev, r);
- unsigned long size = r->end + 1;
-
- if (!pr)
- return -EINVAL;
- if (r->flags & IORESOURCE_IO) {
- if (size > 0x100)
- return -EFBIG;
- if (allocate_resource(pr, r, size, 0x1000, ~0, 1024))
- return -EBUSY;
- } else {
- if (allocate_resource(pr, r, size, 0x10000000, ~0, size))
- return -EBUSY;
- }
- if (i < 6)
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4*i, r->start);
- return 0;
-}
-
-/*
* Translate the low bits of the PCI base
* to the resource type
*/
@@ -296,7 +260,7 @@ void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
res->end = res->start + (((unsigned long) ~l) << 32);
#else
if (l) {
- printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", dev->name);
+ printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", dev->slot_name);
res->start = 0;
res->flags = 0;
continue;
@@ -305,6 +269,7 @@ void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
}
}
if (rom) {
+ dev->rom_base_reg = rom;
res = &dev->resource[PCI_ROM_RESOURCE];
pci_read_config_dword(dev, rom, &l);
pci_write_config_dword(dev, rom, ~PCI_ROM_ADDRESS_ENABLE);
@@ -324,8 +289,9 @@ void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
-void __init pci_read_bridge_bases(struct pci_dev *dev, struct pci_bus *child)
+void __init pci_read_bridge_bases(struct pci_bus *child)
{
+ struct pci_dev *dev = child->self;
u8 io_base_lo, io_limit_lo;
u16 mem_base_lo, mem_limit_lo, io_base_hi, io_limit_hi;
u32 mem_base_hi, mem_limit_hi;
@@ -333,6 +299,9 @@ void __init pci_read_bridge_bases(struct pci_dev *dev, struct pci_bus *child)
struct resource *res;
int i;
+ if (!dev) /* It's a host bus, nothing to read */
+ return;
+
for(i=0; i<3; i++)
child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
@@ -425,31 +394,27 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
dev_cache = NULL;
dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff;
- sprintf(dev->name, "%02x:%02x.%d", bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ sprintf(dev->slot_name, "%02x:%02x.%d", bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
pci_name_device(dev);
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
class >>= 8; /* upper 3 bytes */
dev->class = class;
class >>= 8;
- dev->hdr_type = hdr_type;
+ dev->hdr_type = hdr_type & 0x7f;
- switch (hdr_type & 0x7f) { /* header type */
+ switch (dev->hdr_type) { /* header type */
case PCI_HEADER_TYPE_NORMAL: /* standard header */
if (class == PCI_CLASS_BRIDGE_PCI)
goto bad;
/*
- * If the card generates interrupts, read IRQ number
- * (some architectures change it during pcibios_fixup())
+ * Read interrupt line and base address registers.
+ * The architecture-dependent code can tweak these, of course.
*/
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq);
if (irq)
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
dev->irq = irq;
- /*
- * read base address registers, again pcibios_fixup() can
- * tweak these
- */
pci_read_bases(dev, 6, PCI_ROM_ADDRESS);
pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &dev->subsystem_vendor);
pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device);
@@ -468,8 +433,8 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
break;
default: /* unknown header */
bad:
- printk(KERN_ERR "PCI: %02x:%02x [%04x/%04x/%06x] has unknown header type %02x, ignoring.\n",
- bus->number, dev->devfn, dev->vendor, dev->device, class, hdr_type);
+ printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n",
+ dev->slot_name, hdr_type);
continue;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index ec8fcb7a8..d25a0ed29 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -31,7 +31,7 @@ static void __init quirk_passive_release(struct pci_dev *dev)
while ((d = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
pci_read_config_byte(d, 0x82, &dlc);
if (!(dlc & 1<<1)) {
- printk("PCI: PIIX3: Enabling Passive Release on %s\n", d->name);
+ printk("PCI: PIIX3: Enabling Passive Release on %s\n", d->slot_name);
dlc |= 1<<1;
pci_write_config_byte(d, 0x82, dlc);
}
@@ -99,7 +99,7 @@ static void pci_do_fixups(struct pci_dev *dev, int pass, struct pci_fixup *f)
(f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
(f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
#ifdef DEBUG
- printk("PCI: Calling quirk %p for %s\n", f->hook, dev->name);
+ printk("PCI: Calling quirk %p for %s\n", f->hook, dev->slot_name);
#endif
f->hook(dev);
}
diff --git a/drivers/pci/setup.c b/drivers/pci/setup.c
index 53bf9f582..9c752d0de 100644
--- a/drivers/pci/setup.c
+++ b/drivers/pci/setup.c
@@ -16,7 +16,6 @@
#include <linux/ioport.h>
#include <asm/cache.h>
-#include <asm/pci.h>
#define DEBUG_CONFIG 0
@@ -108,9 +107,12 @@ pdev_assign_unassigned_resources(struct pci_dev *dev, u32 min_io, u32 min_mem)
(ie. do not respond to memory space writes) when it is left
enabled. A good example are QlogicISP adapters. */
- pci_read_config_dword(dev, PCI_ROM_ADDRESS, &reg);
- reg &= ~PCI_ROM_ADDRESS_ENABLE;
- pci_write_config_dword(dev, PCI_ROM_ADDRESS, reg);
+ 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