svn commit: r237797 - stable/9/sys/dev/pci
John Baldwin
jhb at FreeBSD.org
Fri Jun 29 16:29:38 UTC 2012
Author: jhb
Date: Fri Jun 29 16:29:38 2012
New Revision: 237797
URL: http://svn.freebsd.org/changeset/base/237797
Log:
MFC 237008,237271,237272,237673:
- Fix a couple of bugs that prevented windows in PCI-PCI bridges from
growing "downward" (moving the start address down). First, an off by
one error caused the end address to be moved down an extra alignment
chunk unnecessarily. Second, when aligning the new candidate starting
address, the wrong bits were masked off.
- Add a 'wmask' variable to hold the expression '(1ul << w->step) - 1' in
pcib_grow_window().
- For subtractively decoding bridges, don't try to grow windows but pass
the request up the tree in order to be on the safe side. Growing windows
in this case would mean to switch resources to positive decoding and
it's unclear how to correctly handle this. At least with ALi/ULi M5249
PCI-PCI bridges, this also just doesn't work out of the box.
Modified:
stable/9/sys/dev/pci/pci_pci.c
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/amd64/include/xen/ (props changed)
stable/9/sys/boot/ (props changed)
stable/9/sys/boot/i386/efi/ (props changed)
stable/9/sys/boot/ia64/efi/ (props changed)
stable/9/sys/boot/ia64/ski/ (props changed)
stable/9/sys/boot/powerpc/boot1.chrp/ (props changed)
stable/9/sys/boot/powerpc/ofw/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/contrib/dev/acpica/ (props changed)
stable/9/sys/contrib/octeon-sdk/ (props changed)
stable/9/sys/contrib/pf/ (props changed)
stable/9/sys/contrib/x86emu/ (props changed)
stable/9/sys/dev/ (props changed)
stable/9/sys/dev/e1000/ (props changed)
stable/9/sys/dev/isp/ (props changed)
stable/9/sys/dev/ixgbe/ (props changed)
stable/9/sys/fs/ (props changed)
stable/9/sys/fs/ntfs/ (props changed)
stable/9/sys/modules/ (props changed)
Modified: stable/9/sys/dev/pci/pci_pci.c
==============================================================================
--- stable/9/sys/dev/pci/pci_pci.c Fri Jun 29 16:06:06 2012 (r237796)
+++ stable/9/sys/dev/pci/pci_pci.c Fri Jun 29 16:29:38 2012 (r237797)
@@ -815,7 +815,7 @@ static int
pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type,
u_long start, u_long end, u_long count, u_int flags)
{
- u_long align, start_free, end_free, front, back;
+ u_long align, start_free, end_free, front, back, wmask;
int error, rid;
/*
@@ -828,6 +828,7 @@ pcib_grow_window(struct pcib_softc *sc,
end = w->rman.rm_end;
if (start + count - 1 > end || start + count < start)
return (EINVAL);
+ wmask = (1ul << w->step) - 1;
/*
* If there is no resource at all, just try to allocate enough
@@ -838,8 +839,8 @@ pcib_grow_window(struct pcib_softc *sc,
flags &= ~RF_ALIGNMENT_MASK;
flags |= RF_ALIGNMENT_LOG2(w->step);
}
- start &= ~((1ul << w->step) - 1);
- end |= ((1ul << w->step) - 1);
+ start &= ~wmask;
+ end |= wmask;
count = roundup2(count, 1ul << w->step);
rid = w->reg;
w->res = bus_alloc_resource(sc->dev, type, &rid, start, end,
@@ -893,9 +894,9 @@ pcib_grow_window(struct pcib_softc *sc,
if (start < rman_get_start(w->res)) {
if (rman_first_free_region(&w->rman, &start_free, &end_free) !=
0 || start_free != rman_get_start(w->res))
- end_free = rman_get_start(w->res) - 1;
+ end_free = rman_get_start(w->res);
if (end_free > end)
- end_free = end;
+ end_free = end + 1;
/* Move end_free down until it is properly aligned. */
end_free &= ~(align - 1);
@@ -913,7 +914,7 @@ pcib_grow_window(struct pcib_softc *sc,
if (bootverbose)
printf("\tfront candidate range: %#lx-%#lx\n",
front, end_free);
- front &= (1ul << w->step) - 1;
+ front &= ~wmask;
front = rman_get_start(w->res) - front;
} else
front = 0;
@@ -941,7 +942,7 @@ pcib_grow_window(struct pcib_softc *sc,
if (bootverbose)
printf("\tback candidate range: %#lx-%#lx\n",
start_free, back);
- back = roundup2(back + 1, 1ul << w->step) - 1;
+ back |= wmask;
back -= rman_get_end(w->res);
} else
back = 0;
@@ -1000,10 +1001,8 @@ updatewin:
/* Save the new window. */
w->base = rman_get_start(w->res);
w->limit = rman_get_end(w->res);
- KASSERT((w->base & ((1ul << w->step) - 1)) == 0,
- ("start address is not aligned"));
- KASSERT((w->limit & ((1ul << w->step) - 1)) == (1ul << w->step) - 1,
- ("end address is not aligned"));
+ KASSERT((w->base & wmask) == 0, ("start address is not aligned"));
+ KASSERT((w->limit & wmask) == wmask, ("end address is not aligned"));
pcib_write_windows(sc, w->mask);
return (0);
}
@@ -1039,7 +1038,7 @@ pcib_alloc_resource(device_t dev, device
case SYS_RES_IOPORT:
r = pcib_suballoc_resource(sc, &sc->io, child, type, rid, start,
end, count, flags);
- if (r != NULL)
+ if (r != NULL || (sc->flags & PCIB_SUBTRACTIVE) != 0)
break;
if (pcib_grow_window(sc, &sc->io, type, start, end, count,
flags) == 0)
@@ -1063,7 +1062,7 @@ pcib_alloc_resource(device_t dev, device
}
r = pcib_suballoc_resource(sc, &sc->mem, child, type, rid,
start, end, count, flags);
- if (r != NULL)
+ if (r != NULL || (sc->flags & PCIB_SUBTRACTIVE) != 0)
break;
if (flags & RF_PREFETCHABLE) {
if (pcib_grow_window(sc, &sc->pmem, type, start, end,
More information about the svn-src-stable
mailing list