Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 31 Aug 2010 00:16:31 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r212040 - stable/7/sys/pci
Message-ID:  <201008310016.o7V0GVEf012547@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Tue Aug 31 00:16:30 2010
New Revision: 212040
URL: http://svn.freebsd.org/changeset/base/212040

Log:
  MFC r211648:
    It seems some newer RTL8139 controllers provides only memory space
    register mapping. I'm not sure whether it comes from the fact that
    controllers live behind certain PCI brdge(PLX PCI 6152 33BC) and
    the bridge has some issues in handling I/O space register mapping.
    Unfortunately it's not possible to narrow down to an exact
    controller that shows this issue because RealTek used the same PCI
    device/revision id again. In theory, it's possible to check parent
    PCI bridge device and change rl(4) to use memory space register
    mapping if the parent PCI bridge is PLX PCI 6152. But I didn't try
    to do that and we wouldn't get much benefit with added complexity.
  
    Blindly switching to use memory space register mapping for rl(4)
    may make most old controllers not to work. At least, I don't want
    to take potential risk from such change. So use I/O space register
    mapping by default but give users chance to override it via a
    tunable. The tunable to use memory space register mapping would be
    given by adding the following line to /boot/loader.conf file.
  
    dev.rl.%d.prefer_iomap="0"
  
    This change makes P811B quad-port work with this tunable.

Modified:
  stable/7/sys/pci/if_rl.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/pci/if_rl.c
==============================================================================
--- stable/7/sys/pci/if_rl.c	Tue Aug 31 00:15:20 2010	(r212039)
+++ stable/7/sys/pci/if_rl.c	Tue Aug 31 00:16:30 2010	(r212040)
@@ -125,16 +125,6 @@ MODULE_DEPEND(rl, miibus, 1, 1, 1);
 /* "device miibus" required.  See GENERIC if you get errors here. */
 #include "miibus_if.h"
 
-/*
- * Default to using PIO access for this driver. On SMP systems,
- * there appear to be problems with memory mapped mode: it looks like
- * doing too many memory mapped access back to back in rapid succession
- * can hang the bus. I'm inclined to blame this on crummy design/construction
- * on the part of RealTek. Memory mapped mode does appear to work on
- * uniprocessor systems though.
- */
-#define RL_USEIOSPACE
-
 #include <pci/if_rlreg.h>
 
 /*
@@ -225,14 +215,6 @@ static void rl_watchdog(struct rl_softc 
 static void rl_setwol(struct rl_softc *);
 static void rl_clrwol(struct rl_softc *);
 
-#ifdef RL_USEIOSPACE
-#define RL_RES			SYS_RES_IOPORT
-#define RL_RID			RL_PCI_LOIO
-#else
-#define RL_RES			SYS_RES_MEMORY
-#define RL_RID			RL_PCI_LOMEM
-#endif
-
 static device_method_t rl_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		rl_probe),
@@ -806,7 +788,7 @@ rl_attach(device_t dev)
 	struct sysctl_ctx_list	*ctx;
 	struct sysctl_oid_list	*children;
 	int			error = 0, hwrev, i, pmc, rid;
-	int			unit;
+	int			prefer_iomap, unit;
 	uint16_t		rl_did = 0;
 	char			tn[32];
 
@@ -828,10 +810,31 @@ rl_attach(device_t dev)
 
 	pci_enable_busmaster(dev);
 
-	/* Map control/status registers. */
-	rid = RL_RID;
-	sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid, RF_ACTIVE);
 
+	/*
+	 * Map control/status registers.
+	 * Default to using PIO access for this driver. On SMP systems,
+	 * there appear to be problems with memory mapped mode: it looks
+	 * like doing too many memory mapped access back to back in rapid
+	 * succession can hang the bus. I'm inclined to blame this on
+	 * crummy design/construction on the part of RealTek. Memory
+	 * mapped mode does appear to work on uniprocessor systems though.
+	 */
+	prefer_iomap = 1;
+	snprintf(tn, sizeof(tn), "dev.rl.%d.prefer_iomap", unit);
+	TUNABLE_INT_FETCH(tn, &prefer_iomap);
+	if (prefer_iomap) {
+		sc->rl_res_id = PCIR_BAR(0);
+		sc->rl_res_type = SYS_RES_IOPORT;
+		sc->rl_res = bus_alloc_resource_any(dev, sc->rl_res_type,
+		    &sc->rl_res_id, RF_ACTIVE);
+	}
+	if (prefer_iomap == 0 || sc->rl_res == NULL) {
+		sc->rl_res_id = PCIR_BAR(1);
+		sc->rl_res_type = SYS_RES_MEMORY;
+		sc->rl_res = bus_alloc_resource_any(dev, sc->rl_res_type,
+		    &sc->rl_res_id, RF_ACTIVE);
+	}
 	if (sc->rl_res == NULL) {
 		device_printf(dev, "couldn't map ports/memory\n");
 		error = ENXIO;
@@ -1029,7 +1032,8 @@ rl_detach(device_t dev)
 	if (sc->rl_irq[0])
 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq[0]);
 	if (sc->rl_res)
-		bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
+		bus_release_resource(dev, sc->rl_res_type, sc->rl_res_id,
+		    sc->rl_res);
 
 	if (ifp)
 		if_free(ifp);



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