diff options
author | imp <imp@FreeBSD.org> | 2009-03-14 14:08:53 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2009-03-14 14:08:53 +0000 |
commit | 7bee476191f8a8a09b2ebed07d8f73a317e87df5 (patch) | |
tree | a805c609d7511738b01c81fb444c087a6502ed3b /sys/dev/pci | |
parent | f25b21ac98dbffc3d1acd140518821747cfa758e (diff) | |
download | FreeBSD-src-7bee476191f8a8a09b2ebed07d8f73a317e87df5.zip FreeBSD-src-7bee476191f8a8a09b2ebed07d8f73a317e87df5.tar.gz |
Two fixes:
(1) Fix pcib_read/write_config prototypes.
(2) When contrainting a resource request for a 'subtractive' bridge,
it is important to select a range outside the base/limit
registers, since those are the only values known to not
possibly work. On my HP laptop, the base bridge excludes I/O
ports 0xa000-0xafff, however that was the range we were passing
up the tree. Instead, when a range spans the "hole" we now
arbitrarily pick the range just above the hole to allocate from.
All of my rl and xl cards, at a minimum, started working again on this
laptop with those fixes.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/pci_pci.c | 28 | ||||
-rw-r--r-- | sys/dev/pci/pcib_private.h | 4 |
2 files changed, 14 insertions, 18 deletions
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c index 4e1c8ef..9372157 100644 --- a/sys/dev/pci/pci_pci.c +++ b/sys/dev/pci/pci_pci.c @@ -413,12 +413,12 @@ pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, } } else { ok = 1; -#if 1 - if (start < sc->iobase && end > sc->iolimit) { - start = sc->iobase; - end = sc->iolimit; - } -#endif + /* + * If we overlap with the subtractive range, then + * pick the upper range to use. + */ + if (start < sc->iolimit && end > sc->iobase) + start = sc->iolimit + 1; } if (end < start) { device_printf(dev, "ioport: end (%lx) < start (%lx)\n", @@ -479,16 +479,12 @@ pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, } else if (!ok) { ok = 1; /* subtractive bridge: always ok */ if (pcib_is_nonprefetch_open(sc)) { - if (start < sc->membase && end > sc->memlimit) { - start = sc->membase; - end = sc->memlimit; - } + if (start < sc->memlimit && end > sc->membase) + start = sc->memlimit + 1; } if (pcib_is_prefetch_open(sc)) { - if (start < sc->pmembase && end > sc->pmemlimit) { - start = sc->pmembase; - end = sc->pmemlimit; - } + if (start < sc->pmemlimit && end > sc->pmembase) + start = sc->pmemlimit + 1; } } if (end < start) { @@ -536,13 +532,13 @@ pcib_maxslots(device_t dev) * Since we are a child of a PCI bus, its parent must support the pcib interface. */ uint32_t -pcib_read_config(device_t dev, int b, int s, int f, int reg, int width) +pcib_read_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, int width) { return(PCIB_READ_CONFIG(device_get_parent(device_get_parent(dev)), b, s, f, reg, width)); } void -pcib_write_config(device_t dev, int b, int s, int f, int reg, uint32_t val, int width) +pcib_write_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, uint32_t val, int width) { PCIB_WRITE_CONFIG(device_get_parent(device_get_parent(dev)), b, s, f, reg, val, width); } diff --git a/sys/dev/pci/pcib_private.h b/sys/dev/pci/pcib_private.h index 6159839..c7d6818 100644 --- a/sys/dev/pci/pcib_private.h +++ b/sys/dev/pci/pcib_private.h @@ -74,8 +74,8 @@ int pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value); struct resource *pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags); int pcib_maxslots(device_t dev); -uint32_t pcib_read_config(device_t dev, int b, int s, int f, int reg, int width); -void pcib_write_config(device_t dev, int b, int s, int f, int reg, uint32_t val, int width); +uint32_t pcib_read_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, int width); +void pcib_write_config(device_t dev, u_int b, u_int s, u_int f, u_int reg, uint32_t val, int width); int pcib_route_interrupt(device_t pcib, device_t dev, int pin); int pcib_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs); int pcib_release_msi(device_t pcib, device_t dev, int count, int *irqs); |