diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-12-04 03:58:56 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-12-04 03:58:56 +0000 |
commit | 1d67e90f19a7acfd9a05dc59678e7d0c5090bd0d (patch) | |
tree | 357efc7b93f8f5102110d20d293f41360ec212fc /drivers/pci | |
parent | aea27b2e18d69af87e673972246e66657b4fa274 (diff) |
Merge with Linux 2.3.21.
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/Makefile | 6 | ||||
-rw-r--r-- | drivers/pci/devlist.h | 4 | ||||
-rw-r--r-- | drivers/pci/helper.c | 69 | ||||
-rw-r--r-- | drivers/pci/pci.c | 93 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 4 | ||||
-rw-r--r-- | drivers/pci/setup.c | 10 |
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 &= ~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 &= ~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 |