Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Jun 2012 16:29:38 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r237797 - stable/9/sys/dev/pci
Message-ID:  <201206291629.q5TGTcGc056429@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206291629.q5TGTcGc056429>