[Midnightbsd-cvs] src [10093] trunk/sys/dev: sync with freebsd

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun May 27 19:34:04 EDT 2018


Revision: 10093
          http://svnweb.midnightbsd.org/src/?rev=10093
Author:   laffer1
Date:     2018-05-27 19:34:03 -0400 (Sun, 27 May 2018)
Log Message:
-----------
sync with freebsd

Modified Paths:
--------------
    trunk/sys/dev/mii/acphy.c
    trunk/sys/dev/mii/acphyreg.h
    trunk/sys/dev/mii/amphy.c
    trunk/sys/dev/mii/amphyreg.h
    trunk/sys/dev/mii/atphy.c
    trunk/sys/dev/mii/atphyreg.h
    trunk/sys/dev/mii/axphy.c
    trunk/sys/dev/mii/bmtphy.c
    trunk/sys/dev/mii/bmtphyreg.h
    trunk/sys/dev/mii/brgphy.c
    trunk/sys/dev/mii/brgphyreg.h
    trunk/sys/dev/mii/ciphy.c
    trunk/sys/dev/mii/ciphyreg.h
    trunk/sys/dev/mii/e1000phy.c
    trunk/sys/dev/mii/e1000phyreg.h
    trunk/sys/dev/mii/gentbi.c
    trunk/sys/dev/mii/icsphy.c
    trunk/sys/dev/mii/icsphyreg.h
    trunk/sys/dev/mii/ip1000phy.c
    trunk/sys/dev/mii/ip1000phyreg.h
    trunk/sys/dev/mii/jmphy.c
    trunk/sys/dev/mii/jmphyreg.h
    trunk/sys/dev/mii/lxtphy.c
    trunk/sys/dev/mii/lxtphyreg.h
    trunk/sys/dev/mii/mii.c
    trunk/sys/dev/mii/mii.h
    trunk/sys/dev/mii/mii_bitbang.c
    trunk/sys/dev/mii/mii_bitbang.h
    trunk/sys/dev/mii/mii_physubr.c
    trunk/sys/dev/mii/miibus_if.m
    trunk/sys/dev/mii/miidevs
    trunk/sys/dev/mii/miivar.h
    trunk/sys/dev/mii/mlphy.c
    trunk/sys/dev/mii/nsgphy.c
    trunk/sys/dev/mii/nsgphyreg.h
    trunk/sys/dev/mii/nsphy.c
    trunk/sys/dev/mii/nsphyreg.h
    trunk/sys/dev/mii/nsphyter.c
    trunk/sys/dev/mii/nsphyterreg.h
    trunk/sys/dev/mii/pnaphy.c
    trunk/sys/dev/mii/qsphy.c
    trunk/sys/dev/mii/qsphyreg.h
    trunk/sys/dev/mii/rdcphy.c
    trunk/sys/dev/mii/rdcphyreg.h
    trunk/sys/dev/mii/rgephy.c
    trunk/sys/dev/mii/rgephyreg.h
    trunk/sys/dev/mii/rlphy.c
    trunk/sys/dev/mii/rlswitch.c
    trunk/sys/dev/mii/smcphy.c
    trunk/sys/dev/mii/tdkphy.c
    trunk/sys/dev/mii/tdkphyreg.h
    trunk/sys/dev/mii/tlphy.c
    trunk/sys/dev/mii/tlphyreg.h
    trunk/sys/dev/mii/truephy.c
    trunk/sys/dev/mii/truephyreg.h
    trunk/sys/dev/mii/ukphy.c
    trunk/sys/dev/mii/ukphy_subr.c
    trunk/sys/dev/mii/xmphy.c
    trunk/sys/dev/mii/xmphyreg.h
    trunk/sys/dev/mk48txx/mk48txx.c
    trunk/sys/dev/mk48txx/mk48txxreg.h
    trunk/sys/dev/mk48txx/mk48txxvar.h
    trunk/sys/dev/mlx/mlx.c
    trunk/sys/dev/mlx/mlx_disk.c
    trunk/sys/dev/mlx/mlx_pci.c
    trunk/sys/dev/mlx/mlxio.h
    trunk/sys/dev/mlx/mlxreg.h
    trunk/sys/dev/mlx/mlxvar.h
    trunk/sys/dev/mly/mly.c
    trunk/sys/dev/mly/mly_tables.h
    trunk/sys/dev/mly/mlyio.h
    trunk/sys/dev/mly/mlyreg.h
    trunk/sys/dev/mly/mlyvar.h
    trunk/sys/dev/nvd/nvd.c

Added Paths:
-----------
    trunk/sys/dev/netfpga10g/
    trunk/sys/dev/netfpga10g/nf10bmac/
    trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c
    trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c
    trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h

Property Changed:
----------------
    trunk/sys/dev/mii/miibus_if.m
    trunk/sys/dev/mii/miidevs

Modified: trunk/sys/dev/mii/acphy.c
===================================================================
--- trunk/sys/dev/mii/acphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/acphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -53,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/acphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * Driver for Altima AC101 10/100 PHY

Modified: trunk/sys/dev/mii/acphyreg.h
===================================================================
--- trunk/sys/dev/mii/acphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/acphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2001 Semen Ustimenko (semenu at FreeBSD.org)
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/acphyreg.h 165986 2007-01-12 22:58:04Z marius $
  */
 
 #ifndef _DEV_MII_ACPHYREG_H_

Modified: trunk/sys/dev/mii/amphy.c
===================================================================
--- trunk/sys/dev/mii/amphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/amphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1997, 1998, 1999
  *	Bill Paul <wpaul at ee.columbia.edu>.  All rights reserved.
@@ -31,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/amphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * driver for AMD AM79c873 PHYs

Modified: trunk/sys/dev/mii/amphyreg.h
===================================================================
--- trunk/sys/dev/mii/amphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/amphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1997, 1998, 1999
  *	Bill Paul <wpaul at ee.columbia.edu>.  All rights reserved.
@@ -29,7 +30,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/amphyreg.h 139749 2005-01-06 01:43:34Z imp $
  */
 
 #ifndef _DEV_MII_AMTPHYREG_H_

Modified: trunk/sys/dev/mii/atphy.c
===================================================================
--- trunk/sys/dev/mii/atphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/atphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008, Pyun YongHyeon <yongari at FreeBSD.org>
  * All rights reserved.
@@ -26,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/atphy.c 266000 2014-05-14 01:53:20Z ian $");
 
 /*
  * Driver for the Attansic/Atheros F1 10/100/1000 PHY.
@@ -80,6 +81,7 @@
 static const struct mii_phydesc atphys[] = {
 	MII_PHY_DESC(xxATHEROS, F1),
 	MII_PHY_DESC(xxATHEROS, F1_7),
+	MII_PHY_DESC(xxATHEROS, AR8021),
 	MII_PHY_DESC(xxATHEROS, F2),
 	MII_PHY_END
 };

Modified: trunk/sys/dev/mii/atphyreg.h
===================================================================
--- trunk/sys/dev/mii/atphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/atphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008, Pyun YongHyeon
  * All rights reserved.
@@ -24,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/atphyreg.h 179098 2008-05-19 01:12:10Z yongari $
  */
 
 #ifndef	_DEV_MII_ATPHYREG_H_

Modified: trunk/sys/dev/mii/axphy.c
===================================================================
--- trunk/sys/dev/mii/axphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/axphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2009, M. Warner Losh
  * All rights reserved.
@@ -25,7 +26,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/axphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * driver for internal phy in the AX88x9x chips.

Modified: trunk/sys/dev/mii/bmtphy.c
===================================================================
--- trunk/sys/dev/mii/bmtphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/bmtphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -56,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/bmtphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * Driver for the Broadcom BCM5201/BCM5202 "Mini-Theta" PHYs.  This also

Modified: trunk/sys/dev/mii/bmtphyreg.h
===================================================================
--- trunk/sys/dev/mii/bmtphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/bmtphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -28,7 +29,7 @@
  *
  *	from NetBSD: bmtphyreg.h,v 1.1 2001/06/02 21:42:10 thorpej Exp
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/bmtphyreg.h 204646 2010-03-03 17:55:51Z joel $
  */
 
 #ifndef _DEV_MII_BMTPHYREG_H_

Modified: trunk/sys/dev/mii/brgphy.c
===================================================================
--- trunk/sys/dev/mii/brgphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/brgphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000
  *	Bill Paul <wpaul at ee.columbia.edu>.  All rights reserved.
@@ -31,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/brgphy.c 282878 2015-05-14 05:10:42Z yongari $");
 
 /*
  * Driver for the Broadcom BCM54xx/57xx 1000baseTX PHY.
@@ -147,6 +148,7 @@
 	MII_PHY_DESC(BROADCOM3, BCM5720C),
 	MII_PHY_DESC(BROADCOM3, BCM57765),
 	MII_PHY_DESC(BROADCOM3, BCM57780),
+	MII_PHY_DESC(BROADCOM4, BCM5725C),
 	MII_PHY_DESC(xxBROADCOM_ALT1, BCM5906),
 	MII_PHY_END
 };
@@ -157,25 +159,33 @@
 	brgphy_reset
 };
 
-#define HS21_PRODUCT_ID	"IBM eServer BladeCenter HS21"
-#define HS21_BCM_CHIPID	0x57081021
+static const struct hs21_type {
+	const uint32_t id;
+	const char *prod;
+} hs21_type_lists[] = {
+	{ 0x57081021, "IBM eServer BladeCenter HS21" },
+	{ 0x57081011, "IBM eServer BladeCenter HS21 -[8853PAU]-" },
+};
 
 static int
 detect_hs21(struct bce_softc *bce_sc)
 {
 	char *sysenv;
-	int found;
+	int found, i;
 
 	found = 0;
-	if (bce_sc->bce_chipid == HS21_BCM_CHIPID) {
-		sysenv = getenv("smbios.system.product");
-		if (sysenv != NULL) {
-			if (strncmp(sysenv, HS21_PRODUCT_ID,
-			    strlen(HS21_PRODUCT_ID)) == 0)
-				found = 1;
-			freeenv(sysenv);
+	sysenv = getenv("smbios.system.product");
+	if (sysenv == NULL)
+		return (found);
+	for (i = 0; i < nitems(hs21_type_lists); i++) {
+		if (bce_sc->bce_chipid == hs21_type_lists[i].id &&
+		    strncmp(sysenv, hs21_type_lists[i].prod,
+		    strlen(hs21_type_lists[i].prod)) == 0) {
+			found++;
+			break;
 		}
 	}
+	freeenv(sysenv);
 	return (found);
 }
 
@@ -932,6 +942,8 @@
 			return;
 		}
 		break;
+	case MII_OUI_BROADCOM4:
+		return;
 	}
 
 	ifp = sc->mii_pdata->mii_ifp;

Modified: trunk/sys/dev/mii/brgphyreg.h
===================================================================
--- trunk/sys/dev/mii/brgphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/brgphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000
  *	Bill Paul <wpaul at ee.columbia.edu>.  All rights reserved.
@@ -29,7 +30,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/brgphyreg.h 220938 2011-04-22 09:22:27Z marius $
  */
 
 #ifndef _DEV_MII_BRGPHYREG_H_

Modified: trunk/sys/dev/mii/ciphy.c
===================================================================
--- trunk/sys/dev/mii/ciphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/ciphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2004
  *	Bill Paul <wpaul at windriver.com>.  All rights reserved.
@@ -31,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/ciphy.c 235999 2012-05-25 15:05:17Z raj $");
 
 /*
  * Driver for the Cicada/Vitesse CS/VSC8xxx 10/100/1000 copper PHY.
@@ -91,8 +92,10 @@
 	MII_PHY_DESC(xxCICADA, CS8201B),
 	MII_PHY_DESC(xxCICADA, CS8204),
 	MII_PHY_DESC(xxCICADA, VSC8211),
+	MII_PHY_DESC(xxCICADA, VSC8221),
 	MII_PHY_DESC(xxCICADA, CS8244),
 	MII_PHY_DESC(xxVITESSE, VSC8601),
+	MII_PHY_DESC(xxVITESSE, VSC8641),
 	MII_PHY_END
 };
 
@@ -368,8 +371,10 @@
 
 		break;
 	case MII_MODEL_xxCICADA_VSC8211:
+	case MII_MODEL_xxCICADA_VSC8221:
 	case MII_MODEL_xxCICADA_CS8244:
 	case MII_MODEL_xxVITESSE_VSC8601:
+	case MII_MODEL_xxVITESSE_VSC8641:
 		break;
 	default:
 		device_printf(sc->mii_dev, "unknown CICADA PHY model %x\n",

Modified: trunk/sys/dev/mii/ciphyreg.h
===================================================================
--- trunk/sys/dev/mii/ciphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/ciphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2004
  *	Bill Paul <wpaul at windriver.com>.  All rights reserved.
@@ -29,7 +30,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/ciphyreg.h 220938 2011-04-22 09:22:27Z marius $
  */
 
 #ifndef _DEV_MII_CIPHYREG_H_

Modified: trunk/sys/dev/mii/e1000phy.c
===================================================================
--- trunk/sys/dev/mii/e1000phy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/e1000phy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Principal Author: Parag Patel
  * Copyright (c) 2001
@@ -30,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/e1000phy.c 273305 2014-10-20 07:25:57Z yongari $");
 
 /*
  * driver for the Marvell 88E1000 series external 1000/100/10-BT PHY.
@@ -106,7 +107,9 @@
 	MII_PHY_DESC(xxMARVELL, E1111),
 	MII_PHY_DESC(xxMARVELL, E1116),
 	MII_PHY_DESC(xxMARVELL, E1116R),
+	MII_PHY_DESC(xxMARVELL, E1116R_29),
 	MII_PHY_DESC(xxMARVELL, E1118),
+	MII_PHY_DESC(xxMARVELL, E1145),
 	MII_PHY_DESC(xxMARVELL, E1149R),
 	MII_PHY_DESC(xxMARVELL, E3016),
 	MII_PHY_DESC(xxMARVELL, PHYG65G),
@@ -167,8 +170,12 @@
 	PHY_RESET(sc);
 
 	sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & sc->mii_capmask;
-	if (sc->mii_capabilities & BMSR_EXTSTAT)
+	if (sc->mii_capabilities & BMSR_EXTSTAT) {
 		sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
+		if ((sc->mii_extcapabilities &
+		    (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0)
+			sc->mii_flags |= MIIF_HAVE_GTCR;
+	}
 	device_printf(dev, " ");
 	mii_phy_add_media(sc);
 	printf("\n");
@@ -208,6 +215,7 @@
 		case MII_MODEL_xxMARVELL_E1111:
 		case MII_MODEL_xxMARVELL_E1112:
 		case MII_MODEL_xxMARVELL_E1116:
+		case MII_MODEL_xxMARVELL_E1116R_29:
 		case MII_MODEL_xxMARVELL_E1118:
 		case MII_MODEL_xxMARVELL_E1149:
 		case MII_MODEL_xxMARVELL_E1149R:
@@ -215,7 +223,8 @@
 			/* Disable energy detect mode. */
 			reg &= ~E1000_SCR_EN_DETECT_MASK;
 			reg |= E1000_SCR_AUTO_X_MODE;
-			if (sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1116)
+			if (sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1116 ||
+			    sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1116R_29)
 				reg &= ~E1000_SCR_POWER_DOWN;
 			reg |= E1000_SCR_ASSERT_CRS_ON_TX;
 			break;
@@ -243,6 +252,7 @@
 		PHY_WRITE(sc, E1000_SCR, reg);
 
 		if (sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1116 ||
+		    sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1116R_29 ||
 		    sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1149 ||
 		    sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1149R) {
 			PHY_WRITE(sc, E1000_EADR, 2);
@@ -259,6 +269,7 @@
 	case MII_MODEL_xxMARVELL_E1118:
 		break;
 	case MII_MODEL_xxMARVELL_E1116:
+	case MII_MODEL_xxMARVELL_E1116R_29:
 		page = PHY_READ(sc, E1000_EADR);
 		/* Select page 3, LED control register. */
 		PHY_WRITE(sc, E1000_EADR, 3);
@@ -319,8 +330,7 @@
 		speed = 0;
 		switch (IFM_SUBTYPE(ife->ifm_media)) {
 		case IFM_1000_T:
-			if ((sc->mii_extcapabilities &
-			    (EXTSR_1000TFDX | EXTSR_1000THDX)) == 0)
+			if ((sc->mii_flags & MIIF_HAVE_GTCR) == 0)
 				return (EINVAL);
 			speed = E1000_CR_SPEED_1000;
 			break;
@@ -357,10 +367,9 @@
 
 		if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
 			gig |= E1000_1GCR_MS_ENABLE;
-			if ((ife->ifm_media & IFM_ETH_MASTER) != 0)	
+			if ((ife->ifm_media & IFM_ETH_MASTER) != 0)
 				gig |= E1000_1GCR_MS_VALUE;
-		} else if ((sc->mii_extcapabilities &
-		    (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0)
+		} else if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0)
 			gig = 0;
 		PHY_WRITE(sc, E1000_1GCR, gig);
 		PHY_WRITE(sc, E1000_AR, E1000_AR_SELECTOR_FIELD);
@@ -491,9 +500,14 @@
 		PHY_WRITE(sc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD);
 	} else
 		PHY_WRITE(sc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X);
-	if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0)
-		PHY_WRITE(sc, E1000_1GCR,
-		    E1000_1GCR_1000T_FD | E1000_1GCR_1000T);
+	if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) {
+		reg = 0;
+		if ((sc->mii_extcapabilities & EXTSR_1000TFDX) != 0)
+			reg |= E1000_1GCR_1000T_FD;
+		if ((sc->mii_extcapabilities & EXTSR_1000THDX) != 0)
+			reg |= E1000_1GCR_1000T;
+		PHY_WRITE(sc, E1000_1GCR, reg);
+	}
 	PHY_WRITE(sc, E1000_CR,
 	    E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG);
 

Modified: trunk/sys/dev/mii/e1000phyreg.h
===================================================================
--- trunk/sys/dev/mii/e1000phyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/e1000phyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,4 +1,5 @@
 /* $MidnightBSD$ */
+/* $FreeBSD: stable/10/sys/dev/mii/e1000phyreg.h 220938 2011-04-22 09:22:27Z marius $ */
 /*-
  * Principal Author: Parag Patel
  * Copyright (c) 2001

Modified: trunk/sys/dev/mii/gentbi.c
===================================================================
--- trunk/sys/dev/mii/gentbi.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/gentbi.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: gentbi.c,v 1.15 2006/03/29 07:05:24 thorpej Exp $	*/
 
 /*-
@@ -62,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/gentbi.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * Driver for generic unknown ten-bit interfaces(1000BASE-{LX,SX}

Modified: trunk/sys/dev/mii/icsphy.c
===================================================================
--- trunk/sys/dev/mii/icsphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/icsphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: icsphy.c,v 1.41 2006/11/16 21:24:07 christos Exp $	*/
 
 /*-
@@ -55,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/icsphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * driver for Integrated Circuit Systems' ICS1889-1893 ethernet 10/100 PHY

Modified: trunk/sys/dev/mii/icsphyreg.h
===================================================================
--- trunk/sys/dev/mii/icsphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/icsphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: icsphyreg.h,v 1.2 2003/07/01 22:46:08 msaitoh Exp $	*/
 
 /*-
@@ -29,7 +30,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/icsphyreg.h 204646 2010-03-03 17:55:51Z joel $
  */
 
 #ifndef _DEV_MII_ICSPHYREG_H_

Modified: trunk/sys/dev/mii/ip1000phy.c
===================================================================
--- trunk/sys/dev/mii/ip1000phy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/ip1000phy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2006, Pyun YongHyeon <yongari at FreeBSD.org>
  * All rights reserved.
@@ -27,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/ip1000phy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * Driver for the IC Plus IP1000A/IP1001 10/100/1000 PHY.

Modified: trunk/sys/dev/mii/ip1000phyreg.h
===================================================================
--- trunk/sys/dev/mii/ip1000phyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/ip1000phyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2006, Pyun YongHyeon
  * All rights reserved.
@@ -24,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/ip1000phyreg.h 189567 2009-03-09 08:17:46Z yongari $
  */
 
 #ifndef	_DEV_MII_IP1000PHYREG_H_

Modified: trunk/sys/dev/mii/jmphy.c
===================================================================
--- trunk/sys/dev/mii/jmphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/jmphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008, Pyun YongHyeon <yongari at FreeBSD.org>
  * All rights reserved.
@@ -26,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/jmphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * Driver for the JMicron JMP211 10/100/1000, JMP202 10/100 PHY.

Modified: trunk/sys/dev/mii/jmphyreg.h
===================================================================
--- trunk/sys/dev/mii/jmphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/jmphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008, Pyun YongHyeon
  * All rights reserved.
@@ -24,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/jmphyreg.h 216551 2010-12-18 23:52:50Z yongari $
  */
 
 #ifndef	_DEV_MII_JMPHYREG_H_

Modified: trunk/sys/dev/mii/lxtphy.c
===================================================================
--- trunk/sys/dev/mii/lxtphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/lxtphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	OpenBSD: lxtphy.c,v 1.5 2000/08/26 20:04:17 nate Exp 	*/
 /*	NetBSD: lxtphy.c,v 1.19 2000/02/02 23:34:57 thorpej Exp 	*/
 
@@ -56,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/lxtphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * driver for Level One's LXT-970 ethernet 10/100 PHY

Modified: trunk/sys/dev/mii/lxtphyreg.h
===================================================================
--- trunk/sys/dev/mii/lxtphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/lxtphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,6 +1,7 @@
+/* $MidnightBSD$ */
 /*	OpenBSD: lxtphyreg.h,v 1.1 1998/11/11 19:34:47 jason Exp 	*/
 /*	NetBSD: lxtphyreg.h,v 1.1 1998/10/24 00:33:17 thorpej Exp 	*/
-/*	$MidnightBSD$	*/
+/*	$FreeBSD: stable/10/sys/dev/mii/lxtphyreg.h 204646 2010-03-03 17:55:51Z joel $	*/
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.

Modified: trunk/sys/dev/mii/mii.c
===================================================================
--- trunk/sys/dev/mii/mii.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/mii.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: mii.c,v 1.12 1999/08/03 19:41:49 drochner Exp $	*/
 
 /*-
@@ -31,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/mii.c 279158 2015-02-22 15:28:49Z kevlo $");
 
 /*
  * MII bus layer, glues MII-capable network interface drivers to sharable
@@ -373,7 +374,7 @@
 	}
 
 	if (offloc != MII_OFFSET_ANY && (offloc < 0 || offloc >= MII_NPHY)) {
-		printf("%s: ivalid offloc %d\n", __func__, offloc);
+		printf("%s: invalid offloc %d\n", __func__, offloc);
 		return (EINVAL);
 	}
 
@@ -382,7 +383,7 @@
 		phymax = MII_NPHY - 1;
 	} else {
 		if (phyloc < 0 || phyloc >= MII_NPHY) {
-			printf("%s: ivalid phyloc %d\n", __func__, phyloc);
+			printf("%s: invalid phyloc %d\n", __func__, phyloc);
 			return (EINVAL);
 		}
 		phymin = phymax = phyloc;

Modified: trunk/sys/dev/mii/mii.h
===================================================================
--- trunk/sys/dev/mii/mii.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/mii.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,4 +1,5 @@
-/*	$NetBSD: mii.h,v 1.9 2001/05/31 03:07:14 thorpej Exp $	*/
+/* $MidnightBSD$ */
+/*	$NetBSD: mii.h,v 1.18 2014/06/16 14:43:22 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 1997 Manuel Bouyer.  All rights reserved.
@@ -26,7 +27,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/mii.h 286053 2015-07-30 00:28:27Z marius $
  */
 
 #ifndef _DEV_MII_MII_H_
@@ -87,7 +88,7 @@
 /*
  * Note that the EXTSTAT bit indicates that there is extended status
  * info available in register 15, but 802.3 section 22.2.4.3 also
- * states that that all 1000 Mb/s capable PHYs will set this bit to 1.
+ * states that all 1000 Mb/s capable PHYs will set this bit to 1.
  */
 
 #define	BMSR_MEDIAMASK	(BMSR_100T4|BMSR_100TXFDX|BMSR_100TXHDX| \
@@ -111,6 +112,7 @@
 #define ANAR_NP		0x8000	/* Next page (ro) */
 #define	ANAR_ACK	0x4000	/* link partner abilities acknowledged (ro) */
 #define ANAR_RF		0x2000	/* remote fault (ro) */
+		/* Annex 28B.2 */
 #define	ANAR_FC		0x0400	/* local device supports PAUSE */
 #define ANAR_T4		0x0200	/* local device supports 100bT4 */
 #define ANAR_TX_FD	0x0100	/* local device supports 100bTx FD */
@@ -123,6 +125,7 @@
 #define	ANAR_PAUSE_ASYM		(2 << 10)
 #define	ANAR_PAUSE_TOWARDS	(3 << 10)
 
+		/* Annex 28D */
 #define	ANAR_X_FD	0x0020	/* local device supports 1000BASE-X FD */
 #define	ANAR_X_HD	0x0040	/* local device supports 1000BASE-X HD */
 #define	ANAR_X_PAUSE_NONE	(0 << 7)
@@ -184,12 +187,47 @@
 #define	GTSR_MAN_MS_FLT	0x8000	/* master/slave config fault */
 #define	GTSR_MS_RES	0x4000	/* result: 1 = master, 0 = slave */
 #define	GTSR_LRS	0x2000	/* local rx status, 1 = ok */
-#define	GTSR_RRS	0x1000	/* remove rx status, 1 = ok */
+#define	GTSR_RRS	0x1000	/* remote rx status, 1 = ok */
 #define	GTSR_LP_1000TFDX 0x0800	/* link partner 1000baseT FDX capable */
 #define	GTSR_LP_1000THDX 0x0400	/* link partner 1000baseT HDX capable */
 #define	GTSR_LP_ASM_DIR	0x0200	/* link partner asym. pause dir. capable */
 #define	GTSR_IDLE_ERR	0x00ff	/* IDLE error count */
 
+#define	MII_PSECR	0x0b	/* PSE control register */
+#define	PSECR_PACTLMASK	0x000c	/* pair control mask */
+#define	PSECR_PSEENMASK	0x0003	/* PSE enable mask */
+#define	PSECR_PINOUTB	0x0008	/* PSE pinout Alternative B */
+#define	PSECR_PINOUTA	0x0004	/* PSE pinout Alternative A */
+#define	PSECR_FOPOWTST	0x0002	/* Force Power Test Mode */
+#define	PSECR_PSEEN	0x0001	/* PSE Enabled */
+#define	PSECR_PSEDIS	0x0000	/* PSE Disabled */
+
+#define	MII_PSESR	0x0c	/* PSE status register */
+#define	PSESR_PWRDENIED	0x1000	/* Power Denied */
+#define	PSESR_VALSIG	0x0800	/* Valid PD signature detected */
+#define	PSESR_INVALSIG	0x0400	/* Invalid PD signature detected */
+#define	PSESR_SHORTCIRC	0x0200	/* Short circuit condition detected */
+#define	PSESR_OVERLOAD	0x0100	/* Overload condition detected */
+#define	PSESR_MPSABSENT	0x0080	/* MPS absent condition detected */
+#define	PSESR_PDCLMASK	0x0070	/* PD Class mask */
+#define	PSESR_STATMASK	0x000e	/* PSE Status mask */
+#define	PSESR_PAIRCTABL	0x0001	/* PAIR Control Ability */
+#define	PSESR_PDCL_4		(4 << 4)	/* Class 4 */
+#define	PSESR_PDCL_3		(3 << 4)	/* Class 3 */
+#define	PSESR_PDCL_2		(2 << 4)	/* Class 2 */
+#define	PSESR_PDCL_1		(1 << 4)	/* Class 1 */
+#define	PSESR_PDCL_0		(0 << 4)	/* Class 0 */
+
+#define	MII_MMDACR	0x0d	/* MMD access control register */
+#define	MMDACR_FUNCMASK	0xc000	/* function */
+#define	MMDACR_DADDRMASK 0x001f	/* device address */
+#define	MMDACR_FN_ADDRESS	(0 << 14) /* address */
+#define	MMDACR_FN_DATANPI	(1 << 14) /* data, no post increment */
+#define	MMDACR_FN_DATAPIRW	(2 << 14) /* data, post increment on r/w */
+#define	MMDACR_FN_DATAPIW	(3 << 14) /* data, post increment on wr only */
+
+#define	MII_MMDAADR	0x0e	/* MMD access address data register */
+
 #define	MII_EXTSR	0x0f	/* Extended status register */
 #define	EXTSR_1000XFDX	0x8000	/* 1000X full-duplex capable */
 #define	EXTSR_1000XHDX	0x4000	/* 1000X half-duplex capable */

Modified: trunk/sys/dev/mii/mii_bitbang.c
===================================================================
--- trunk/sys/dev/mii/mii_bitbang.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/mii_bitbang.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: mii_bitbang.c,v 1.12 2008/05/04 17:06:09 xtraeme Exp $	*/
 
 /*-
@@ -35,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/mii_bitbang.c 226995 2011-11-01 16:13:59Z marius $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/dev/mii/mii_bitbang.h
===================================================================
--- trunk/sys/dev/mii/mii_bitbang.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/mii_bitbang.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: mii_bitbang.h,v 1.6 2009/05/12 14:31:27 cegger Exp $	*/
 
 /*-
@@ -29,7 +30,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/mii_bitbang.h 226995 2011-11-01 16:13:59Z marius $
  */
 
 #define	MII_BIT_MDO		0	/* data out (host->PHY) */

Modified: trunk/sys/dev/mii/mii_physubr.c
===================================================================
--- trunk/sys/dev/mii/mii_physubr.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/mii_physubr.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: mii_physubr.c,v 1.5 1999/08/03 19:41:49 drochner Exp $	*/
 
 /*-
@@ -31,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/mii_physubr.c 225014 2011-08-19 19:12:58Z marius $");
 
 /*
  * Subroutines common to all PHYs.

Modified: trunk/sys/dev/mii/miibus_if.m
===================================================================
--- trunk/sys/dev/mii/miibus_if.m	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/miibus_if.m	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,4 +1,5 @@
-# $MidnightBSD$
+/* $MidnightBSD$ */
+# $FreeBSD: stable/10/sys/dev/mii/miibus_if.m 84140 2001-09-29 18:40:06Z jlemon $
 
 #include <sys/bus.h>
 


Property changes on: trunk/sys/dev/mii/miibus_if.m
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/sys/dev/mii/miidevs
===================================================================
--- trunk/sys/dev/mii/miidevs	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/miidevs	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,4 +1,5 @@
-$MidnightBSD$
+/* $MidnightBSD$ */
+$FreeBSD: stable/10/sys/dev/mii/miidevs 266000 2014-05-14 01:53:20Z ian $
 /*$NetBSD: miidevs,v 1.105 2011/11/25 23:28:14 jakllsch Exp $*/
 
 /*-
@@ -52,7 +53,8 @@
 oui BROADCOM			0x001018	Broadcom Corporation
 oui BROADCOM2			0x000af7	Broadcom Corporation
 oui BROADCOM3			0x001be9	Broadcom Corporation
-oui CICADA			0x0003F1	Cicada Semiconductor
+oui BROADCOM4			0x18c086	Broadcom Corporation
+oui CICADA			0x0003f1	Cicada Semiconductor
 oui DAVICOM			0x00606e	Davicom Semiconductor
 oui ENABLESEMI			0x0010dd	Enable Semiconductor
 oui ICPLUS			0x0090c3	IC Plus Corp.
@@ -69,8 +71,10 @@
 oui REALTEK			0x00e04c	RealTek Semicondctor
 oui SEEQ			0x00a07d	Seeq Technology
 oui SIS				0x00e006	Silicon Integrated Systems
+oui SMC				0x00800f	SMC
 oui TI				0x080028	Texas Instruments
 oui TSC				0x00c039	TDK Semiconductor
+oui VITESSE			0x0001c1	Vitesse Semiconductor
 oui XAQTI			0x00e0ae	XaQti Corp.
 
 /* Some Intel 82553's use an alternative OUI. */
@@ -133,6 +137,7 @@
 /* Atheros Communications/Attansic PHYs */
 model xxATHEROS F1		0x0001 Atheros F1 10/100/1000 PHY
 model xxATHEROS F2		0x0002 Atheros F2 10/100 PHY
+model xxATHEROS AR8021		0x0004 Atheros AR8021 10/100/1000 PHY
 model xxATHEROS F1_7		0x0007 Atheros F1 10/100/1000 PHY
 
 /* Asix semiconductor PHYs */
@@ -184,6 +189,7 @@
 model BROADCOM3 BCM5719C	0x0022 BCM5719C 1000BASE-T media interface
 model BROADCOM3 BCM57765	0x0024 BCM57765 1000BASE-T media interface
 model BROADCOM3 BCM5720C	0x0036 BCM5720C 1000BASE-T media interface
+model BROADCOM4 BCM5725C	0x0038 BCM5725C 1000BASE-T media interface
 model xxBROADCOM_ALT1 BCM5906	0x0004 BCM5906 10/100baseTX media interface
 
 /* Cicada Semiconductor PHYs (now owned by Vitesse?) */
@@ -190,6 +196,7 @@
 model xxCICADA CS8201		0x0001 Cicada CS8201 10/100/1000TX PHY
 model xxCICADA CS8204		0x0004 Cicada CS8204 10/100/1000TX PHY
 model xxCICADA VSC8211		0x000b Cicada VSC8211 10/100/1000TX PHY
+model xxCICADA VSC8221		0x0015 Cicada CS8201 10/100/1000TX PHY
 model xxCICADA CS8201A		0x0020 Cicada CS8201 10/100/1000TX PHY
 model xxCICADA CS8201B		0x0021 Cicada CS8201 10/100/1000TX PHY
 model xxCICADA CS8244		0x002c Cicada CS8244 10/100/1000TX PHY
@@ -299,6 +306,7 @@
 model xxREALTEK RTL8169S	0x0011 RTL8169S/8110S/8211 1000BASE-T media interface
 model REALTEK RTL8305SC		0x0005 RTL8305SC 10/100 802.1q switch
 model REALTEK RTL8201E		0x0008 RTL8201E 10/100 media interface
+model REALTEK RTL8251		0x0000 RTL8251 1000BASE-T media interface
 model REALTEK RTL8169S		0x0011 RTL8169S/8110S/8211 1000BASE-T media interface
 
 /* Seeq Seeq PHYs */
@@ -318,5 +326,11 @@
 model xxTSC 78Q2120		0x0014 78Q2120 10/100 media interface
 model xxTSC 78Q2121		0x0015 78Q2121 100BASE-TX media interface
 
+/* Vitesse Semiconductor */
+model xxVITESSE VSC8641		0x0003 Vitesse VSC8641 10/100/1000TX PHY
+
 /* XaQti Corp. PHYs */
 model xxXAQTI XMACII		0x0000 XaQti Corp. XMAC II gigabit interface
+
+/* SMC */
+model SMC LAN8710A		0x000F SMC LAN8710A 10/100 interface


Property changes on: trunk/sys/dev/mii/miidevs
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/sys/dev/mii/miivar.h
===================================================================
--- trunk/sys/dev/mii/miivar.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/miivar.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: miivar.h,v 1.8 1999/04/23 04:24:32 thorpej Exp $	*/
 
 /*-
@@ -29,7 +30,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/miivar.h 227688 2011-11-18 22:58:13Z marius $
  */
 
 #ifndef _DEV_MII_MIIVAR_H_

Modified: trunk/sys/dev/mii/mlphy.c
===================================================================
--- trunk/sys/dev/mii/mlphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/mlphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1997, 1998, 1999
  *	Bill Paul <wpaul at ctr.columbia.edu>.  All rights reserved.
@@ -32,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/mlphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * driver for Micro Linear 6692 PHYs

Modified: trunk/sys/dev/mii/nsgphy.c
===================================================================
--- trunk/sys/dev/mii/nsgphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/nsgphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2001 Wind River Systems
  * Copyright (c) 2001
@@ -38,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/nsgphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * Driver for the National Semiconductor DP83861, DP83865 and DP83891

Modified: trunk/sys/dev/mii/nsgphyreg.h
===================================================================
--- trunk/sys/dev/mii/nsgphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/nsgphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2001 Wind River Systems
  * Copyright (c) 2001
@@ -30,7 +31,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/nsgphyreg.h 139749 2005-01-06 01:43:34Z imp $
  */
 
 #ifndef _DEV_MII_NSGPHYREG_H_

Modified: trunk/sys/dev/mii/nsphy.c
===================================================================
--- trunk/sys/dev/mii/nsphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/nsphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: nsphy.c,v 1.18 1999/07/14 23:57:36 thorpej Exp $	*/
 
 /*-
@@ -55,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/nsphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * driver for National Semiconductor's DP83840A ethernet 10/100 PHY

Modified: trunk/sys/dev/mii/nsphyreg.h
===================================================================
--- trunk/sys/dev/mii/nsphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/nsphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: nsphyreg.h,v 1.1 1998/08/10 23:58:39 thorpej Exp $	*/
 
 /*-
@@ -29,7 +30,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/nsphyreg.h 204646 2010-03-03 17:55:51Z joel $
  */
 
 #ifndef _DEV_MII_NSPHYREG_H_

Modified: trunk/sys/dev/mii/nsphyter.c
===================================================================
--- trunk/sys/dev/mii/nsphyter.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/nsphyter.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: nsphyter.c,v 1.28 2008/01/20 07:58:19 msaitoh Exp $	*/
 
 /*-
@@ -55,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/nsphyter.c 231914 2012-02-19 12:25:58Z marius $");
 
 /*
  * Driver for the National Semiconductor's DP83843, DP83847 and DP83849

Modified: trunk/sys/dev/mii/nsphyterreg.h
===================================================================
--- trunk/sys/dev/mii/nsphyterreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/nsphyterreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: nsphyterreg.h,v 1.4 2005/12/11 12:22:42 christos Exp $	*/
 
 /*-
@@ -29,7 +30,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/nsphyterreg.h 204646 2010-03-03 17:55:51Z joel $
  */
 
 #ifndef _DEV_MII_NSPHYTERREG_H_

Modified: trunk/sys/dev/mii/pnaphy.c
===================================================================
--- trunk/sys/dev/mii/pnaphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/pnaphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000 Berkeley Software Design, Inc.
  * Copyright (c) 1997, 1998, 1999, 2000
@@ -32,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/pnaphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * driver for homePNA PHYs

Modified: trunk/sys/dev/mii/qsphy.c
===================================================================
--- trunk/sys/dev/mii/qsphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/qsphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	OpenBSD: qsphy.c,v 1.6 2000/08/26 20:04:18 nate Exp */
 /*	NetBSD: qsphy.c,v 1.19 2000/02/02 23:34:57 thorpej Exp 	*/
 
@@ -56,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/qsphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * driver for Quality Semiconductor's QS6612 ethernet 10/100 PHY

Modified: trunk/sys/dev/mii/qsphyreg.h
===================================================================
--- trunk/sys/dev/mii/qsphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/qsphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,6 +1,7 @@
+/* $MidnightBSD$ */
 /*	OpenBSD: qsphyreg.h,v 1.2 1999/03/09 00:02:45 jason Exp 	*/
 /*	NetBSD: qsphyreg.h,v 1.1 1998/08/11 00:01:03 thorpej Exp 	*/
-/*	$MidnightBSD$	*/
+/*	$FreeBSD: stable/10/sys/dev/mii/qsphyreg.h 204646 2010-03-03 17:55:51Z joel $	*/
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.

Modified: trunk/sys/dev/mii/rdcphy.c
===================================================================
--- trunk/sys/dev/mii/rdcphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/rdcphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2010, Pyun YongHyeon <yongari at FreeBSD.org>
  * All rights reserved.
@@ -26,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/rdcphy.c 227848 2011-11-22 21:55:40Z marius $");
 
 /*
  * Driver for the RDC Semiconductor R6040 10/100 PHY.

Modified: trunk/sys/dev/mii/rdcphyreg.h
===================================================================
--- trunk/sys/dev/mii/rdcphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/rdcphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2010, Pyun YongHyeon <yongari at FreeBSD.org>
  * All rights reserved.
@@ -24,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/rdcphyreg.h 216828 2010-12-30 23:50:25Z yongari $
  */
 
 #ifndef _DEV_MII_RDCPHYREG_H_

Modified: trunk/sys/dev/mii/rgephy.c
===================================================================
--- trunk/sys/dev/mii/rgephy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/rgephy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003
  *	Bill Paul <wpaul at windriver.com>.  All rights reserved.
@@ -31,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/rgephy.c 292780 2015-12-27 17:12:54Z marius $");
 
 /*
  * Driver for the RealTek 8169S/8110S/8211B/8211C internal 10/100/1000 PHY.
@@ -57,7 +58,7 @@
 #include "miibus_if.h"
 
 #include <machine/bus.h>
-#include <pci/if_rlreg.h>
+#include <dev/rl/if_rlreg.h>
 
 static int rgephy_probe(device_t);
 static int rgephy_attach(device_t);
@@ -85,11 +86,13 @@
 static void	rgephy_status(struct mii_softc *);
 static int	rgephy_mii_phy_auto(struct mii_softc *, int);
 static void	rgephy_reset(struct mii_softc *);
+static int	rgephy_linkup(struct mii_softc *);
 static void	rgephy_loop(struct mii_softc *);
 static void	rgephy_load_dspcode(struct mii_softc *);
 
 static const struct mii_phydesc rgephys[] = {
 	MII_PHY_DESC(REALTEK, RTL8169S),
+	MII_PHY_DESC(REALTEK, RTL8251),
 	MII_PHY_END
 };
 
@@ -146,7 +149,7 @@
 rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
 {
 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
-	int reg, speed, gig, anar;
+	int speed, gig, anar;
 
 	switch (cmd) {
 	case MII_POLLSTAT:
@@ -248,20 +251,9 @@
 		 * Check to see if we have link.  If we do, we don't
 		 * need to restart the autonegotiation process.
 		 */
-		if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 &&
-		    sc->mii_mpd_rev >= 2) {
-			/* RTL8211B(L) */
-			reg = PHY_READ(sc, RGEPHY_MII_SSR);
-			if (reg & RGEPHY_SSR_LINK) {
-				sc->mii_ticks = 0;
-				break;
-			}
-		} else {
-			reg = PHY_READ(sc, RL_GMEDIASTAT);
-			if (reg & RL_GMEDIASTAT_LINK) {
-				sc->mii_ticks = 0;
-				break;
-			}
+		if (rgephy_linkup(sc) != 0) {
+			sc->mii_ticks = 0;
+			break;
 		}
 
 		/* Announce link loss right after it happens. */
@@ -294,6 +286,33 @@
 	return (0);
 }
 
+static int
+rgephy_linkup(struct mii_softc *sc)
+{
+	int linkup;
+	uint16_t reg;
+
+	linkup = 0;
+	if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 &&
+	    sc->mii_mpd_rev >= RGEPHY_8211B) {
+		if (sc->mii_mpd_rev == RGEPHY_8211F) {
+			reg = PHY_READ(sc, RGEPHY_F_MII_SSR);
+			if (reg & RGEPHY_F_SSR_LINK)
+				linkup++;
+		} else {
+			reg = PHY_READ(sc, RGEPHY_MII_SSR);
+			if (reg & RGEPHY_SSR_LINK)
+				linkup++;
+		}
+	} else {
+		reg = PHY_READ(sc, RL_GMEDIASTAT);
+		if (reg & RL_GMEDIASTAT_LINK)
+			linkup++;
+	}
+
+	return (linkup);
+}
+
 static void
 rgephy_status(struct mii_softc *sc)
 {
@@ -304,18 +323,10 @@
 	mii->mii_media_status = IFM_AVALID;
 	mii->mii_media_active = IFM_ETHER;
 
-	if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) {
-		ssr = PHY_READ(sc, RGEPHY_MII_SSR);
-		if (ssr & RGEPHY_SSR_LINK)
-			mii->mii_media_status |= IFM_ACTIVE;
-	} else {
-		bmsr = PHY_READ(sc, RL_GMEDIASTAT);
-		if (bmsr & RL_GMEDIASTAT_LINK)
-			mii->mii_media_status |= IFM_ACTIVE;
-	}
+	if (rgephy_linkup(sc) != 0)
+		mii->mii_media_status |= IFM_ACTIVE;
 
 	bmsr = PHY_READ(sc, RGEPHY_MII_BMSR);
-
 	bmcr = PHY_READ(sc, RGEPHY_MII_BMCR);
 	if (bmcr & RGEPHY_BMCR_ISO) {
 		mii->mii_media_active |= IFM_NONE;
@@ -334,26 +345,50 @@
 		}
 	}
 
-	if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) {
-		ssr = PHY_READ(sc, RGEPHY_MII_SSR);
-		switch (ssr & RGEPHY_SSR_SPD_MASK) {
-		case RGEPHY_SSR_S1000:
-			mii->mii_media_active |= IFM_1000_T;
-			break;
-		case RGEPHY_SSR_S100:
-			mii->mii_media_active |= IFM_100_TX;
-			break;
-		case RGEPHY_SSR_S10:
-			mii->mii_media_active |= IFM_10_T;
-			break;
-		default:
-			mii->mii_media_active |= IFM_NONE;
-			break;
+	if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 &&
+	    sc->mii_mpd_rev >= RGEPHY_8211B) {
+		if (sc->mii_mpd_rev == RGEPHY_8211F) {
+			ssr = PHY_READ(sc, RGEPHY_F_MII_SSR);
+			switch (ssr & RGEPHY_F_SSR_SPD_MASK) {
+			case RGEPHY_F_SSR_S1000:
+				mii->mii_media_active |= IFM_1000_T;
+				break;
+			case RGEPHY_F_SSR_S100:
+				mii->mii_media_active |= IFM_100_TX;
+				break;
+			case RGEPHY_F_SSR_S10:
+				mii->mii_media_active |= IFM_10_T;
+				break;
+			default:
+				mii->mii_media_active |= IFM_NONE;
+				break;
+			}
+			if (ssr & RGEPHY_F_SSR_FDX)
+				mii->mii_media_active |= IFM_FDX;
+			else
+				mii->mii_media_active |= IFM_HDX;
+
+		} else {
+			ssr = PHY_READ(sc, RGEPHY_MII_SSR);
+			switch (ssr & RGEPHY_SSR_SPD_MASK) {
+			case RGEPHY_SSR_S1000:
+				mii->mii_media_active |= IFM_1000_T;
+				break;
+			case RGEPHY_SSR_S100:
+				mii->mii_media_active |= IFM_100_TX;
+				break;
+			case RGEPHY_SSR_S10:
+				mii->mii_media_active |= IFM_10_T;
+				break;
+			default:
+				mii->mii_media_active |= IFM_NONE;
+				break;
+			}
+			if (ssr & RGEPHY_SSR_FDX)
+				mii->mii_media_active |= IFM_FDX;
+			else
+				mii->mii_media_active |= IFM_HDX;
 		}
-		if (ssr & RGEPHY_SSR_FDX)
-			mii->mii_media_active |= IFM_FDX;
-		else
-			mii->mii_media_active |= IFM_HDX;
 	} else {
 		bmsr = PHY_READ(sc, RL_GMEDIASTAT);
 		if (bmsr & RL_GMEDIASTAT_1000MBPS)
@@ -406,7 +441,8 @@
 {
 	int i;
 
-	if (sc->mii_mpd_rev < 2) {
+	if (sc->mii_mpd_model != MII_MODEL_REALTEK_RTL8251 &&
+	    sc->mii_mpd_rev < RGEPHY_8211B) {
 		PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN);
 		DELAY(1000);
 	}
@@ -439,7 +475,8 @@
 {
 	int val;
 
-	if (sc->mii_mpd_rev >= 2)
+	if (sc->mii_mpd_model == MII_MODEL_REALTEK_RTL8251 ||
+	    sc->mii_mpd_rev >= RGEPHY_8211B)
 		return;
 
 	PHY_WRITE(sc, 31, 0x0001);
@@ -490,22 +527,34 @@
 {
 	uint16_t pcr, ssr;
 
-	if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev == 3) {
-		/* RTL8211C(L) */
-		ssr = PHY_READ(sc, RGEPHY_MII_SSR);
-		if ((ssr & RGEPHY_SSR_ALDPS) != 0) {
-			ssr &= ~RGEPHY_SSR_ALDPS;
-			PHY_WRITE(sc, RGEPHY_MII_SSR, ssr);
+	switch (sc->mii_mpd_rev) {
+	case RGEPHY_8211F:
+		pcr = PHY_READ(sc, RGEPHY_F_MII_PCR1);
+		if ((pcr & RGEPHY_F_PCR1_MDI_MM) != 0) {
+			pcr &= ~RGEPHY_F_PCR1_MDI_MM;
+			PHY_WRITE(sc, RGEPHY_F_MII_PCR1, pcr);
 		}
-	}
-
-	if (sc->mii_mpd_rev >= 2) {
-		pcr = PHY_READ(sc, RGEPHY_MII_PCR);
-		if ((pcr & RGEPHY_PCR_MDIX_AUTO) == 0) {
-			pcr &= ~RGEPHY_PCR_MDI_MASK;
-			pcr |= RGEPHY_PCR_MDIX_AUTO;
-			PHY_WRITE(sc, RGEPHY_MII_PCR, pcr);
+		break;
+	case RGEPHY_8211C:
+		if ((sc->mii_flags & MIIF_PHYPRIV0) == 0) {
+			/* RTL8211C(L) */
+			ssr = PHY_READ(sc, RGEPHY_MII_SSR);
+			if ((ssr & RGEPHY_SSR_ALDPS) != 0) {
+				ssr &= ~RGEPHY_SSR_ALDPS;
+				PHY_WRITE(sc, RGEPHY_MII_SSR, ssr);
+			}
 		}
+		/* FALLTHROUGH */
+	default:
+		if (sc->mii_mpd_rev >= RGEPHY_8211B) {
+			pcr = PHY_READ(sc, RGEPHY_MII_PCR);
+			if ((pcr & RGEPHY_PCR_MDIX_AUTO) == 0) {
+				pcr &= ~RGEPHY_PCR_MDI_MASK;
+				pcr |= RGEPHY_PCR_MDIX_AUTO;
+				PHY_WRITE(sc, RGEPHY_MII_PCR, pcr);
+			}
+		}
+		break;
 	}
 
 	mii_phy_reset(sc);

Modified: trunk/sys/dev/mii/rgephyreg.h
===================================================================
--- trunk/sys/dev/mii/rgephyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/rgephyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003
  *	Bill Paul <wpaul at windriver.com>.  All rights reserved.
@@ -29,12 +30,16 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/rgephyreg.h 280667 2015-03-26 05:44:21Z yongari $
  */
 
 #ifndef _DEV_MII_RGEPHYREG_H_
 #define	_DEV_MII_RGEPHYREG_H_
 
+#define	RGEPHY_8211B		2
+#define	RGEPHY_8211C		3
+#define	RGEPHY_8211F		6
+
 /*
  * RealTek 8169S/8110S gigE PHY registers
  */
@@ -162,4 +167,21 @@
 #define	RGEPHY_SSR_ALDPS	0x0008	/* RTL8211C(L) only */
 #define	RGEPHY_SSR_JABBER	0x0001	/* Jabber */
 
+/* RTL8211F */
+#define	RGEPHY_F_MII_PCR1	0x18	/* PHY Specific control register 1 */
+#define	RGEPHY_F_PCR1_MDI_MM	0x0200	/* MDI / MDIX Manual Mode */
+#define	RGEPHY_F_PCR1_MDI_MODE	0x0100	/* MDI Mode (0=MDIX,1=MDI) */
+#define	RGEPHY_F_PCR1_ALDPS_EN	0x0004	/* Link Down Power Saving Enable */
+
+/* RTL8211F */
+#define	RGEPHY_F_MII_SSR	0x1A	/* PHY Specific status register */
+#define	RGEPHY_F_SSR_S1000	0x0020	/* 1000Mbps */
+#define	RGEPHY_F_SSR_S100	0x0010	/* 100Mbps */
+#define	RGEPHY_F_SSR_S10	0x0000	/* 10Mbps */
+#define	RGEPHY_F_SSR_SPD_MASK	0x0030
+#define	RGEPHY_F_SSR_FDX	0x0008	/* full duplex */
+#define	RGEPHY_F_SSR_LINK	0x0004	/* link up */
+#define	RGEPHY_F_SSR_MDI	0x0002	/* MDI/MDIX */
+#define	RGEPHY_F_SSR_JABBER	0x0001	/* Jabber */
+
 #endif /* _DEV_RGEPHY_MIIREG_H_ */

Modified: trunk/sys/dev/mii/rlphy.c
===================================================================
--- trunk/sys/dev/mii/rlphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/rlphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1997, 1998, 1999
  *	Bill Paul <wpaul at ctr.columbia.edu>.  All rights reserved.
@@ -31,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/rlphy.c 292780 2015-12-27 17:12:54Z marius $");
 
 /*
  * driver for RealTek 8139 internal PHYs
@@ -53,7 +54,7 @@
 #include "miidevs.h"
 
 #include <machine/bus.h>
-#include <pci/if_rlreg.h>
+#include <dev/rl/if_rlreg.h>
 
 #include "miibus_if.h"
 

Modified: trunk/sys/dev/mii/rlswitch.c
===================================================================
--- trunk/sys/dev/mii/rlswitch.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/rlswitch.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1997, 1998, 1999
  *	Bill Paul <wpaul at ctr.columbia.edu>.  All rights reserved.
@@ -32,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/rlswitch.c 292780 2015-12-27 17:12:54Z marius $");
 
 /*
  * driver for RealTek 8305 pseudo PHYs
@@ -54,7 +55,7 @@
 #include "miidevs.h"
 
 #include <machine/bus.h>
-#include <pci/if_rlreg.h>
+#include <dev/rl/if_rlreg.h>
 
 #include "miibus_if.h"
 

Modified: trunk/sys/dev/mii/smcphy.c
===================================================================
--- trunk/sys/dev/mii/smcphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/smcphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2006 Benno Rice.  All rights reserved.
  *
@@ -23,10 +24,11 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/smcphy.c 239275 2012-08-15 04:03:55Z gonzo $");
 
 /*
- * Driver for the internal PHY on the SMSC LAN91C111.
+ * Driver for the SEEQ 80220 and 84220.
+ * (Originally developed for the internal PHY on the SMSC LAN91C111.)
  */
 
 #include <sys/param.h>

Modified: trunk/sys/dev/mii/tdkphy.c
===================================================================
--- trunk/sys/dev/mii/tdkphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/tdkphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000,2001 Jonathan Chen.
  * All rights reserved.
@@ -27,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/tdkphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * Driver for the TDK 78Q2120 MII

Modified: trunk/sys/dev/mii/tdkphyreg.h
===================================================================
--- trunk/sys/dev/mii/tdkphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/tdkphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000,2001 Jonathan Chen.
  * All rights reserved.
@@ -25,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/tdkphyreg.h 139749 2005-01-06 01:43:34Z imp $
  */
 
 /*

Modified: trunk/sys/dev/mii/tlphy.c
===================================================================
--- trunk/sys/dev/mii/tlphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/tlphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: tlphy.c,v 1.18 1999/05/14 11:40:28 drochner Exp $	*/
 
 /*-
@@ -55,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/tlphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * Driver for Texas Instruments's ThunderLAN PHYs

Modified: trunk/sys/dev/mii/tlphyreg.h
===================================================================
--- trunk/sys/dev/mii/tlphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/tlphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: tlphyreg.h,v 1.1 1998/08/10 23:59:58 thorpej Exp $	*/
  
 /*-
@@ -23,7 +24,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/tlphyreg.h 213188 2010-09-26 22:11:41Z marius $
  */
 
 #ifndef _DEV_MII_TLPHYREG_H_

Modified: trunk/sys/dev/mii/truephy.c
===================================================================
--- trunk/sys/dev/mii/truephy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/truephy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
  * 
@@ -32,7 +33,7 @@
  * SUCH DAMAGE.
  * 
  * $DragonFly: src/sys/dev/netif/mii_layer/truephy.c,v 1.3 2008/02/10 07:29:27 sephe Exp $
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/truephy.c 227908 2011-11-23 20:27:26Z marius $
  */
 
 #include <sys/param.h>

Modified: trunk/sys/dev/mii/truephyreg.h
===================================================================
--- trunk/sys/dev/mii/truephyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/truephyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
  * 
@@ -32,7 +33,7 @@
  * SUCH DAMAGE.
  * 
  * $DragonFly: src/sys/dev/netif/mii_layer/truephyreg.h,v 1.2 2007/10/23 14:28:42 sephe Exp $
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/truephyreg.h 179896 2008-06-20 19:30:44Z delphij $
  */
 
 #ifndef _MII_TRUEPHYREG_H

Modified: trunk/sys/dev/mii/ukphy.c
===================================================================
--- trunk/sys/dev/mii/ukphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/ukphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: ukphy.c,v 1.2 1999/04/23 04:24:32 thorpej Exp $	*/
 
 /*-
@@ -55,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/ukphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * driver for generic unknown PHYs

Modified: trunk/sys/dev/mii/ukphy_subr.c
===================================================================
--- trunk/sys/dev/mii/ukphy_subr.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/ukphy_subr.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: ukphy_subr.c,v 1.2 1998/11/05 04:08:02 thorpej Exp $	*/
 
 /*-
@@ -31,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/ukphy_subr.c 215297 2010-11-14 13:26:10Z marius $");
 
 /*
  * Subroutines shared by the ukphy driver and other PHY drivers.

Modified: trunk/sys/dev/mii/xmphy.c
===================================================================
--- trunk/sys/dev/mii/xmphy.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/xmphy.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000
  *	Bill Paul <wpaul at ee.columbia.edu>.  All rights reserved.
@@ -31,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mii/xmphy.c 227908 2011-11-23 20:27:26Z marius $");
 
 /*
  * driver for the XaQti XMAC II's internal PHY. This is sort of

Modified: trunk/sys/dev/mii/xmphyreg.h
===================================================================
--- trunk/sys/dev/mii/xmphyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mii/xmphyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000
  *	Bill Paul <wpaul at ee.columbia.edu>.  All rights reserved.
@@ -29,7 +30,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mii/xmphyreg.h 220938 2011-04-22 09:22:27Z marius $
  */
 
 #ifndef _DEV_MII_XMPHYREG_H_

Modified: trunk/sys/dev/mk48txx/mk48txx.c
===================================================================
--- trunk/sys/dev/mk48txx/mk48txx.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mk48txx/mk48txx.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -30,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mk48txx/mk48txx.c 263763 2014-03-26 07:31:57Z dim $");
 
 /*
  * Mostek MK48T02, MK48T08, MK48T18, MK48T37 and MK48T59 time-of-day chip
@@ -64,7 +65,7 @@
 	bus_size_t clkoff;
 	u_int flags;
 #define	MK48TXX_EXT_REGISTERS	1	/* Has extended register set. */
-} const mk48txx_models[] = {
+} mk48txx_models[] = {
 	{ "mk48t02", MK48T02_CLKSZ, MK48T02_CLKOFF, 0 },
 	{ "mk48t08", MK48T08_CLKSZ, MK48T08_CLKOFF, 0 },
 	{ "mk48t18", MK48T18_CLKSZ, MK48T18_CLKOFF, 0 },

Modified: trunk/sys/dev/mk48txx/mk48txxreg.h
===================================================================
--- trunk/sys/dev/mk48txx/mk48txxreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mk48txx/mk48txxreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -28,7 +29,7 @@
  *
  *	$NetBSD: mk48txxreg.h,v 1.10 2008/04/28 20:23:50 martin Exp $
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mk48txx/mk48txxreg.h 221957 2011-05-15 13:17:08Z marius $
  */
 
 /*

Modified: trunk/sys/dev/mk48txx/mk48txxvar.h
===================================================================
--- trunk/sys/dev/mk48txx/mk48txxvar.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mk48txx/mk48txxvar.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -28,7 +29,7 @@
  *
  *	$NetBSD: mk48txxvar.h,v 1.6 2008/04/28 20:23:50 martin Exp $
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/mk48txx/mk48txxvar.h 201005 2009-12-25 21:53:20Z marius $
  */
 
 typedef uint8_t (*mk48txx_nvrd_t)(device_t dev, int off);

Modified: trunk/sys/dev/mlx/mlx.c
===================================================================
--- trunk/sys/dev/mlx/mlx.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mlx/mlx.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1999 Michael Smith
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$MidnightBSD$
+ *	$FreeBSD: stable/10/sys/dev/mlx/mlx.c 281826 2015-04-21 11:27:50Z mav $
  */
 
 /*
@@ -32,8 +33,12 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/lock.h>
 #include <sys/malloc.h>
+#include <sys/mutex.h>
 #include <sys/kernel.h>
+#include <sys/sx.h>
 
 #include <sys/bus.h>
 #include <sys/conf.h>
@@ -46,7 +51,6 @@
 
 #include <geom/geom_disk.h>
 
-#include <dev/mlx/mlx_compat.h>
 #include <dev/mlx/mlxio.h>
 #include <dev/mlx/mlxvar.h>
 #include <dev/mlx/mlxreg.h>
@@ -53,7 +57,6 @@
 
 static struct cdevsw mlx_cdevsw = {
 	.d_version =	D_VERSION,
-	.d_flags =	D_NEEDGIANT,
 	.d_open =	mlx_open,
 	.d_close =	mlx_close,
 	.d_ioctl =	mlx_ioctl,
@@ -68,17 +71,17 @@
 static int			mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc);
 static int			mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
 static void			mlx_v3_intaction(struct mlx_softc *sc, int action);
-static int			mlx_v3_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2);
+static int			mlx_v3_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2, int first);
 
 static int			mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc);
 static int			mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
 static void			mlx_v4_intaction(struct mlx_softc *sc, int action);
-static int			mlx_v4_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2);
+static int			mlx_v4_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2, int first);
 
 static int			mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc);
 static int			mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
 static void			mlx_v5_intaction(struct mlx_softc *sc, int action);
-static int			mlx_v5_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2);
+static int			mlx_v5_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2, int first);
 
 /*
  * Status monitoring
@@ -130,8 +133,9 @@
 						 bus_dma_segment_t *segs,
 						 int nsegments, int error);
 static void			mlx_unmapcmd(struct mlx_command *mc);
+static int			mlx_shutdown_locked(struct mlx_softc *sc);
 static int			mlx_start(struct mlx_command *mc);
-static int			mlx_done(struct mlx_softc *sc);
+static int			mlx_done(struct mlx_softc *sc, int startio);
 static void			mlx_complete(struct mlx_softc *sc);
 
 /*
@@ -164,8 +168,16 @@
 
     debug_called(1);
 
+    /* destroy control device */
+    if (sc->mlx_dev_t != NULL)
+	destroy_dev(sc->mlx_dev_t);
+
+    if (sc->mlx_intr)
+	bus_teardown_intr(sc->mlx_dev, sc->mlx_irq, sc->mlx_intr);
+
     /* cancel status timeout */
-    untimeout(mlx_periodic, sc, sc->mlx_timeout);
+    MLX_IO_LOCK(sc);
+    callout_stop(&sc->mlx_timeout);
 
     /* throw away any command buffers */
     while ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL) {
@@ -172,6 +184,8 @@
 	TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link);
 	mlx_freecmd(mc);
     }
+    MLX_IO_UNLOCK(sc);
+    callout_drain(&sc->mlx_timeout);
 
     /* destroy data-transfer DMA tag */
     if (sc->mlx_buffer_dmat)
@@ -184,8 +198,6 @@
 	bus_dma_tag_destroy(sc->mlx_sg_dmat);
 
     /* disconnect the interrupt handler */
-    if (sc->mlx_intr)
-	bus_teardown_intr(sc->mlx_dev, sc->mlx_irq, sc->mlx_intr);
     if (sc->mlx_irq != NULL)
 	bus_release_resource(sc->mlx_dev, SYS_RES_IRQ, 0, sc->mlx_irq);
 
@@ -201,9 +213,8 @@
     if (sc->mlx_enq2 != NULL)
 	free(sc->mlx_enq2, M_DEVBUF);
 
-    /* destroy control device */
-    if (sc->mlx_dev_t != (struct cdev *)NULL)
-	destroy_dev(sc->mlx_dev_t);
+    sx_destroy(&sc->mlx_config_lock);
+    mtx_destroy(&sc->mlx_io_lock);
 }
 
 /********************************************************************************
@@ -297,7 +308,7 @@
      */
     TAILQ_INIT(&sc->mlx_work);
     TAILQ_INIT(&sc->mlx_freecmds);
-    MLX_BIO_QINIT(sc->mlx_bioq);
+    bioq_init(&sc->mlx_bioq);
 
     /* 
      * Select accessor methods based on controller interface type.
@@ -327,7 +338,9 @@
     }
 
     /* disable interrupts before we start talking to the controller */
+    MLX_IO_LOCK(sc);
     sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
+    MLX_IO_UNLOCK(sc);
 
     /* 
      * Wait for the controller to come ready, handshake with the firmware if required.
@@ -336,7 +349,8 @@
      */
     hsmsg = 0;
     DELAY(1000);
-    while ((hscode = sc->mlx_fw_handshake(sc, &hserror, &hsparam1, &hsparam2)) != 0) {
+    while ((hscode = sc->mlx_fw_handshake(sc, &hserror, &hsparam1, &hsparam2,
+	hsmsg == 0)) != 0) {
 	/* report first time around... */
 	if (hsmsg == 0) {
 	    device_printf(sc->mlx_dev, "controller initialisation in progress...\n");
@@ -364,7 +378,8 @@
 	device_printf(sc->mlx_dev, "can't allocate interrupt\n");
 	return(ENXIO);
     }
-    error = bus_setup_intr(sc->mlx_dev, sc->mlx_irq, INTR_TYPE_BIO | INTR_ENTROPY, NULL, mlx_intr, sc, &sc->mlx_intr);
+    error = bus_setup_intr(sc->mlx_dev, sc->mlx_irq, INTR_TYPE_BIO |
+	INTR_ENTROPY | INTR_MPSAFE, NULL, mlx_intr, sc, &sc->mlx_intr);
     if (error) {
 	device_printf(sc->mlx_dev, "can't set up interrupt\n");
 	return(ENXIO);
@@ -378,11 +393,12 @@
 			       BUS_SPACE_MAXADDR,	/* lowaddr */
 			       BUS_SPACE_MAXADDR, 	/* highaddr */
 			       NULL, NULL, 		/* filter, filterarg */
-			       MAXBSIZE, MLX_NSEG,	/* maxsize, nsegments */
+			       MLX_MAXPHYS,		/* maxsize */
+			       MLX_NSEG,		/* nsegments */
 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
 			       0,			/* flags */
 			       busdma_lock_mutex,	/* lockfunc */
-			       &Giant,			/* lockarg */
+			       &sc->mlx_io_lock,	/* lockarg */
 			       &sc->mlx_buffer_dmat);
     if (error != 0) {
 	device_printf(sc->mlx_dev, "can't allocate buffer DMA tag\n");
@@ -407,7 +423,9 @@
     /* 
      * Obtain controller feature information
      */
+    MLX_IO_LOCK(sc);
     if ((sc->mlx_enq2 = mlx_enquire(sc, MLX_CMD_ENQUIRY2, sizeof(struct mlx_enquiry2), NULL)) == NULL) {
+	MLX_IO_UNLOCK(sc);
 	device_printf(sc->mlx_dev, "ENQUIRY2 failed\n");
 	return(ENXIO);
     }
@@ -420,6 +438,7 @@
     case MLX_IFTYPE_2:
 	/* These controllers don't report the firmware version in the ENQUIRY2 response */
 	if ((meo = mlx_enquire(sc, MLX_CMD_ENQUIRY_OLD, sizeof(struct mlx_enquiry_old), NULL)) == NULL) {
+	    MLX_IO_UNLOCK(sc);
 	    device_printf(sc->mlx_dev, "ENQUIRY_OLD failed\n");
 	    return(ENXIO);
 	}
@@ -453,8 +472,10 @@
 	}
 	break;
     default:
+	MLX_IO_UNLOCK(sc);
 	return(ENXIO);		/* should never happen */
     }
+    MLX_IO_UNLOCK(sc);
 
     /*
      * Create the final scatter/gather mappings now that we have characterised the controller.
@@ -481,7 +502,7 @@
     /*
      * Start the timeout routine.
      */
-    sc->mlx_timeout = timeout(mlx_periodic, sc, hz);
+    callout_reset(&sc->mlx_timeout, hz, mlx_periodic, sc);
 
     /* print a little information about the controller */
     mlx_describe_controller(sc);
@@ -505,7 +526,9 @@
      * Scan all the system drives and attach children for those that
      * don't currently have them.
      */
+    MLX_IO_LOCK(sc);
     mes = mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(*mes) * MLX_MAXDRIVES, NULL);
+    MLX_IO_UNLOCK(sc);
     if (mes == NULL) {
 	device_printf(sc->mlx_dev, "error fetching drive status\n");
 	return;
@@ -512,6 +535,7 @@
     }
     
     /* iterate over drives returned */
+    MLX_CONFIG_LOCK(sc);
     for (i = 0, dr = &sc->mlx_sysdrive[0];
 	 (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff);
 	 i++, dr++) {
@@ -543,10 +567,13 @@
 	device_printf(sc->mlx_dev, "bus_generic_attach returned %d", error);
 
     /* mark controller back up */
+    MLX_IO_LOCK(sc);
     sc->mlx_state &= ~MLX_STATE_SHUTDOWN;
 
     /* enable interrupts */
     sc->mlx_intaction(sc, MLX_INTACTION_ENABLE);
+    MLX_IO_UNLOCK(sc);
+    MLX_CONFIG_UNLOCK(sc);
 }
 
 /********************************************************************************
@@ -557,12 +584,12 @@
 {
     struct mlx_softc	*sc = device_get_softc(dev);
     struct mlxd_softc	*mlxd;
-    int			i, s, error;
+    int			i, error;
 
     debug_called(1);
 
     error = EBUSY;
-    s = splbio();
+    MLX_CONFIG_LOCK(sc);
     if (sc->mlx_state & MLX_STATE_OPEN)
 	goto out;
 
@@ -577,12 +604,13 @@
     }
     if ((error = mlx_shutdown(dev)))
 	goto out;
+    MLX_CONFIG_UNLOCK(sc);
 
     mlx_free(sc);
 
-    error = 0;
+    return (0);
  out:
-    splx(s);
+    MLX_CONFIG_UNLOCK(sc);
     return(error);
 }
 
@@ -600,13 +628,24 @@
 mlx_shutdown(device_t dev)
 {
     struct mlx_softc	*sc = device_get_softc(dev);
-    int			i, s, error;
+    int			error;
 
+    MLX_CONFIG_LOCK(sc);
+    error = mlx_shutdown_locked(sc);
+    MLX_CONFIG_UNLOCK(sc);
+    return (error);
+}
+
+static int
+mlx_shutdown_locked(struct mlx_softc *sc)
+{
+    int			i, error;
+
     debug_called(1);
 
-    s = splbio();
-    error = 0;
+    MLX_CONFIG_ASSERT_LOCKED(sc);
 
+    MLX_IO_LOCK(sc);
     sc->mlx_state |= MLX_STATE_SHUTDOWN;
     sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
 
@@ -617,19 +656,18 @@
     } else {
 	printf("done\n");
     }
+    MLX_IO_UNLOCK(sc);
     
     /* delete all our child devices */
     for (i = 0; i < MLX_MAXDRIVES; i++) {
 	if (sc->mlx_sysdrive[i].ms_disk != 0) {
 	    if ((error = device_delete_child(sc->mlx_dev, sc->mlx_sysdrive[i].ms_disk)) != 0)
-		goto out;
+		return (error);
 	    sc->mlx_sysdrive[i].ms_disk = 0;
 	}
     }
 
- out:
-    splx(s);
-    return(error);
+    return (0);
 }
 
 /********************************************************************************
@@ -639,11 +677,10 @@
 mlx_suspend(device_t dev)
 {
     struct mlx_softc	*sc = device_get_softc(dev);
-    int			s;
 
     debug_called(1);
 
-    s = splbio();
+    MLX_IO_LOCK(sc);
     sc->mlx_state |= MLX_STATE_SUSPEND;
     
     /* flush controller */
@@ -651,7 +688,7 @@
     printf("%s\n", mlx_flush(sc) ? "failed" : "done");
 
     sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
-    splx(s);
+    MLX_IO_UNLOCK(sc);
 
     return(0);
 }
@@ -666,8 +703,10 @@
 
     debug_called(1);
 
+    MLX_IO_LOCK(sc);
     sc->mlx_state &= ~MLX_STATE_SUSPEND;
     sc->mlx_intaction(sc, MLX_INTACTION_ENABLE);
+    MLX_IO_UNLOCK(sc);
 
     return(0);
 }
@@ -684,7 +723,9 @@
     debug_called(1);
 
     /* collect finished commands, queue anything waiting */
-    mlx_done(sc);
+    MLX_IO_LOCK(sc);
+    mlx_done(sc, 1);
+    MLX_IO_UNLOCK(sc);
 };
 
 /*******************************************************************************
@@ -692,16 +733,14 @@
  * disk resource, then poke the disk resource to start as much work as it can.
  */
 int
-mlx_submit_buf(struct mlx_softc *sc, mlx_bio *bp)
+mlx_submit_buf(struct mlx_softc *sc, struct bio *bp)
 {
-    int		s;
     
     debug_called(1);
 
-    s = splbio();
-    MLX_BIO_QINSERT(sc->mlx_bioq, bp);
+    MLX_IO_ASSERT_LOCKED(sc);
+    bioq_insert_tail(&sc->mlx_bioq, bp);
     sc->mlx_waitbufs++;
-    splx(s);
     mlx_startio(sc);
     return(0);
 }
@@ -714,7 +753,11 @@
 {
     struct mlx_softc	*sc = dev->si_drv1;
 
+    MLX_CONFIG_LOCK(sc);
+    MLX_IO_LOCK(sc);
     sc->mlx_state |= MLX_STATE_OPEN;
+    MLX_IO_UNLOCK(sc);
+    MLX_CONFIG_UNLOCK(sc);
     return(0);
 }
 
@@ -726,7 +769,11 @@
 {
     struct mlx_softc	*sc = dev->si_drv1;
 
+    MLX_CONFIG_LOCK(sc);
+    MLX_IO_LOCK(sc);
     sc->mlx_state &= ~MLX_STATE_OPEN;
+    MLX_IO_UNLOCK(sc);
+    MLX_CONFIG_UNLOCK(sc);
     return (0);
 }
 
@@ -753,6 +800,7 @@
 	 */
     case MLX_NEXT_CHILD:
 	/* search system drives */
+	MLX_CONFIG_LOCK(sc);
 	for (i = 0; i < MLX_MAXDRIVES; i++) {
 	    /* is this one attached? */
 	    if (sc->mlx_sysdrive[i].ms_disk != 0) {
@@ -759,6 +807,7 @@
 		/* looking for the next one we come across? */
 		if (*arg == -1) {
 		    *arg = device_get_unit(sc->mlx_sysdrive[i].ms_disk);
+		    MLX_CONFIG_UNLOCK(sc);
 		    return(0);
 		}
 		/* we want the one after this one */
@@ -766,6 +815,7 @@
 		    *arg = -1;
 	    }
 	}
+	MLX_CONFIG_UNLOCK(sc);
 	return(ENOENT);
 
 	/*
@@ -772,7 +822,9 @@
 	 * Scan the controller to see whether new drives have appeared.
 	 */
     case MLX_RESCAN_DRIVES:
+	mtx_lock(&Giant);
 	mlx_startup(sc);
+	mtx_unlock(&Giant);	
 	return(0);
 
 	/*
@@ -780,10 +832,12 @@
 	 * away.
 	 */
     case MLX_DETACH_DRIVE:			/* detach one drive */
-	
+	MLX_CONFIG_LOCK(sc);
 	if (((dr = mlx_findunit(sc, *arg)) == NULL) || 
-	    ((mlxd = device_get_softc(dr->ms_disk)) == NULL))
+	    ((mlxd = device_get_softc(dr->ms_disk)) == NULL)) {
+	    MLX_CONFIG_UNLOCK(sc);
 	    return(ENOENT);
+	}
 
 	device_printf(dr->ms_disk, "detaching...");
 	error = 0;
@@ -793,10 +847,13 @@
 	}
 	
 	/* flush controller */
+	MLX_IO_LOCK(sc);
 	if (mlx_flush(sc)) {
+	    MLX_IO_UNLOCK(sc);
 	    error = EBUSY;
 	    goto detach_out;
 	}
+	MLX_IO_UNLOCK(sc);
 
 	/* nuke drive */
 	if ((error = device_delete_child(sc->mlx_dev, dr->ms_disk)) != 0)
@@ -804,6 +861,7 @@
 	dr->ms_disk = 0;
 
     detach_out:
+	MLX_CONFIG_UNLOCK(sc);
 	if (error) {
 	    printf("failed\n");
 	} else {
@@ -823,7 +881,14 @@
 	if (!(sc->mlx_feature & MLX_FEAT_PAUSEWORKS))
 	    return(EOPNOTSUPP);
 
+	/* check time values */
 	mp = (struct mlx_pause *)addr;
+	if ((mp->mp_when < 0) || (mp->mp_when > 3600))
+	    return(EINVAL);
+	if ((mp->mp_howlong < 1) || (mp->mp_howlong > (0xf * 30)))
+	    return(EINVAL);
+
+	MLX_IO_LOCK(sc);
 	if ((mp->mp_which == MLX_PAUSE_CANCEL) && (sc->mlx_pause.mp_when != 0)) {
 	    /* cancel a pending pause operation */
 	    sc->mlx_pause.mp_which = 0;
@@ -830,15 +895,12 @@
 	} else {
 	    /* fix for legal channels */
 	    mp->mp_which &= ((1 << sc->mlx_enq2->me_actual_channels) -1);
-	    /* check time values */
-	    if ((mp->mp_when < 0) || (mp->mp_when > 3600))
-		return(EINVAL);
-	    if ((mp->mp_howlong < 1) || (mp->mp_howlong > (0xf * 30)))
-		return(EINVAL);
 	    
 	    /* check for a pause currently running */
-	    if ((sc->mlx_pause.mp_which != 0) && (sc->mlx_pause.mp_when == 0))
+	    if ((sc->mlx_pause.mp_which != 0) && (sc->mlx_pause.mp_when == 0)) {
+		MLX_IO_UNLOCK(sc);
 		return(EBUSY);
+	    }
 
 	    /* looks ok, go with it */
 	    sc->mlx_pause.mp_which = mp->mp_which;
@@ -845,6 +907,7 @@
 	    sc->mlx_pause.mp_when = time_second + mp->mp_when;
 	    sc->mlx_pause.mp_howlong = sc->mlx_pause.mp_when + mp->mp_howlong;
 	}
+	MLX_IO_UNLOCK(sc);
 	return(0);
 
 	/*
@@ -857,7 +920,9 @@
 	 * Start a rebuild on a given SCSI disk
 	 */
     case MLX_REBUILDASYNC:
+	MLX_IO_LOCK(sc);
 	if (sc->mlx_background != 0) {
+	    MLX_IO_UNLOCK(sc);
 	    rb->rr_status = 0x0106;
 	    return(EBUSY);
 	}
@@ -887,6 +952,7 @@
 	}
 	if (error == 0)
 	    sc->mlx_background = MLX_BACKGROUND_REBUILD;
+	MLX_IO_UNLOCK(sc);
 	return(error);
 	
 	/*
@@ -893,7 +959,9 @@
 	 * Get the status of the current rebuild or consistency check.
 	 */
     case MLX_REBUILDSTAT:
+	MLX_IO_LOCK(sc);
 	*rs = sc->mlx_rebuildstat;
+	MLX_IO_UNLOCK(sc);
 	return(0);
 
 	/*
@@ -902,12 +970,16 @@
 	 */
     case MLX_GET_SYSDRIVE:
 	error = ENOENT;
+	MLX_CONFIG_LOCK(sc);
+	mtx_lock(&Giant);
 	mlxd = (struct mlxd_softc *)devclass_get_softc(mlxd_devclass, *arg);
+	mtx_unlock(&Giant);
 	if ((mlxd != NULL) && (mlxd->mlxd_drive >= sc->mlx_sysdrive) && 
 	    (mlxd->mlxd_drive < (sc->mlx_sysdrive + MLX_MAXDRIVES))) {
 	    error = 0;
 	    *arg = mlxd->mlxd_drive - sc->mlx_sysdrive;
 	}
+	MLX_CONFIG_UNLOCK(sc);
 	return(error);
 	
     default:	
@@ -930,7 +1002,9 @@
 	 * Return the current status of this drive.
 	 */
     case MLXD_STATUS:
+	MLX_IO_LOCK(sc);
 	*arg = drive->ms_state;
+	MLX_IO_UNLOCK(sc);
 	return(0);
 	
 	/*
@@ -937,7 +1011,9 @@
 	 * Start a background consistency check on this drive.
 	 */
     case MLXD_CHECKASYNC:		/* start a background consistency check */
+	MLX_IO_LOCK(sc);
 	if (sc->mlx_background != 0) {
+	    MLX_IO_UNLOCK(sc);
 	    *arg = 0x0106;
 	    return(EBUSY);
 	}
@@ -964,6 +1040,7 @@
 	}
 	if (error == 0)
 	    sc->mlx_background = MLX_BACKGROUND_CHECK;
+	MLX_IO_UNLOCK(sc);
 	*arg = result;
 	return(error);
 
@@ -987,6 +1064,7 @@
     struct mlx_softc *sc = (struct mlx_softc *)data;
 
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /*
      * Run a bus pause? 
@@ -1045,10 +1123,10 @@
     mlx_enquire(sc, MLX_CMD_REBUILDSTAT, sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild);
 
     /* deal with possibly-missed interrupts and timed-out commands */
-    mlx_done(sc);
+    mlx_done(sc, 1);
 
     /* reschedule another poll next second or so */
-    sc->mlx_timeout = timeout(mlx_periodic, sc, hz);
+    callout_reset(&sc->mlx_timeout, hz, mlx_periodic, sc);
 }
 
 /********************************************************************************
@@ -1060,6 +1138,7 @@
     struct mlx_softc		*sc = mc->mc_sc;
 
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* Command completed OK? */
     if (mc->mc_status != 0) {
@@ -1124,7 +1203,7 @@
 	    debug(1, "event log pointer was %d, now %d\n", sc->mlx_lastevent, sc->mlx_currevent);
 
 	    /* mark the event log as busy */
-	    atomic_set_int(&sc->mlx_flags, MLX_EVENTLOG_BUSY);
+	    sc->mlx_flags |= MLX_EVENTLOG_BUSY;
 	    
 	    /* drain new eventlog entries */
 	    mlx_periodic_eventlog_poll(sc);
@@ -1205,6 +1284,7 @@
     int			error = 0;
 
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* get ourselves a command buffer */
     error = 1;
@@ -1263,6 +1343,7 @@
     char			*reason;
 
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     sc->mlx_lastevent++;		/* next message... */
     if (mc->mc_status == 0) {
@@ -1321,7 +1402,7 @@
 	mlx_periodic_eventlog_poll(sc);
     } else {
 	/* clear log-busy status */
-	atomic_clear_int(&sc->mlx_flags, MLX_EVENTLOG_BUSY);
+	sc->mlx_flags &= ~MLX_EVENTLOG_BUSY;
     }
 }
 
@@ -1334,6 +1415,7 @@
     struct mlx_softc		*sc = mc->mc_sc;
     struct mlx_rebuild_status	*mr = (struct mlx_rebuild_status *)mc->mc_data;
 
+    MLX_IO_ASSERT_LOCKED(sc);
     switch(mc->mc_status) {
     case 0:				/* operation running, update stats */
 	sc->mlx_rebuildstat = *mr;
@@ -1384,6 +1466,8 @@
     struct mlx_command	*mc;
     int			failsafe, i, command;
 
+    MLX_IO_ASSERT_LOCKED(sc);
+
     /* What are we doing here? */
     if (sc->mlx_pause.mp_when == 0) {
 	command = MLX_CMD_STARTCHANNEL;
@@ -1440,7 +1524,8 @@
     struct mlx_softc	*sc = mc->mc_sc;
     int			command = mc->mc_mailbox[0];
     int			channel = mc->mc_mailbox[2] & 0xf;
-    
+
+    MLX_IO_ASSERT_LOCKED(sc);
     if (mc->mc_status != 0) {
 	device_printf(sc->mlx_dev, "%s command failed - %s\n", 
 		      command == MLX_CMD_STOPCHANNEL ? "pause" : "resume", mlx_diagnose_command(mc));
@@ -1509,6 +1594,7 @@
     int			error;
 
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* get ourselves a command buffer */
     error = 1;
@@ -1562,6 +1648,7 @@
     int			error;
 
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* get ourselves a command buffer */
     error = 1;
@@ -1604,6 +1691,7 @@
     int			error;
 
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* get ourselves a command buffer */
     error = 0x10000;
@@ -1647,6 +1735,7 @@
     int			error;
 
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* get ourselves a command buffer */
     error = 0x10000;
@@ -1689,6 +1778,7 @@
     int			error, count;
 
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     mc->mc_complete = NULL;
     mc->mc_private = mc;		/* wake us when you're done */
@@ -1698,7 +1788,7 @@
     count = 0;
     /* XXX better timeout? */
     while ((mc->mc_status == MLX_STATUS_BUSY) && (count < 30)) {
-	tsleep(mc->mc_private, PRIBIO | PCATCH, "mlxwcmd", hz);
+	mtx_sleep(mc->mc_private, &sc->mlx_io_lock, PRIBIO | PCATCH, "mlxwcmd", hz);
     }
 
     if (mc->mc_status != 0) {
@@ -1720,9 +1810,10 @@
 mlx_poll_command(struct mlx_command *mc)
 {
     struct mlx_softc	*sc = mc->mc_sc;
-    int			error, count, s;
+    int			error, count;
 
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     mc->mc_complete = NULL;
     mc->mc_private = NULL;	/* we will poll for it */
@@ -1732,13 +1823,11 @@
     count = 0;
     do {
 	/* poll for completion */
-	mlx_done(mc->mc_sc);
+	mlx_done(mc->mc_sc, 1);
 	
     } while ((mc->mc_status == MLX_STATUS_BUSY) && (count++ < 15000000));
     if (mc->mc_status != MLX_STATUS_BUSY) {
-	s = splbio();
 	TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
-	splx(s);
 	return(0);
     }
     device_printf(sc->mlx_dev, "command failed - %s\n", mlx_diagnose_command(mc));
@@ -1751,7 +1840,7 @@
     struct mlx_command	*mc;
     struct mlxd_softc	*mlxd;
     struct mlx_softc	*sc;
-    mlx_bio		*bp;
+    struct bio		*bp;
     int			blkcount;
     int			driveno;
     int			cmd;
@@ -1762,7 +1851,7 @@
     sc = mc->mc_sc;
     bp = mc->mc_private;
 
-    if (MLX_BIO_IS_READ(bp)) {
+    if (bp->bio_cmd == BIO_READ) {
 	mc->mc_flags |= MLX_CMD_DATAIN;
 	cmd = MLX_CMD_READSG;
     } else {
@@ -1771,14 +1860,14 @@
     }
 
     /* build a suitable I/O command (assumes 512-byte rounded transfers) */
-    mlxd = (struct mlxd_softc *)MLX_BIO_SOFTC(bp);
+    mlxd = bp->bio_disk->d_drv1;
     driveno = mlxd->mlxd_drive - sc->mlx_sysdrive;
-    blkcount = (MLX_BIO_LENGTH(bp) + MLX_BLKSIZE - 1) / MLX_BLKSIZE;
+    blkcount = (bp->bio_bcount + MLX_BLKSIZE - 1) / MLX_BLKSIZE;
 
-    if ((MLX_BIO_LBA(bp) + blkcount) > sc->mlx_sysdrive[driveno].ms_size)
+    if ((bp->bio_pblkno + blkcount) > sc->mlx_sysdrive[driveno].ms_size)
 	device_printf(sc->mlx_dev,
 		      "I/O beyond end of unit (%lld,%d > %lu)\n", 
-		      (long long)MLX_BIO_LBA(bp), blkcount,
+		      (long long)bp->bio_pblkno, blkcount,
 		      (u_long)sc->mlx_sysdrive[driveno].ms_size);
 
     /*
@@ -1789,7 +1878,7 @@
 	mlx_make_type1(mc, (cmd == MLX_CMD_WRITESG) ? MLX_CMD_WRITESG_OLD :
 						      MLX_CMD_READSG_OLD,
 		       blkcount & 0xff, 	/* xfer length low byte */
-		       MLX_BIO_LBA(bp),		/* physical block number */
+		       bp->bio_pblkno,		/* physical block number */
 		       driveno,			/* target drive number */
 		       mc->mc_sgphys,		/* location of SG list */
 		       mc->mc_nsgent & 0x3f);	/* size of SG list */
@@ -1798,7 +1887,7 @@
 		       blkcount & 0xff, 	/* xfer length low byte */
 		       (driveno << 3) | ((blkcount >> 8) & 0x07),
 						/* target+length high 3 bits */
-		       MLX_BIO_LBA(bp),		/* physical block number */
+		       bp->bio_pblkno,		/* physical block number */
 		       mc->mc_sgphys,		/* location of SG list */
 		       mc->mc_nsgent & 0x3f);	/* size of SG list */
     }
@@ -1809,33 +1898,30 @@
 	mc->mc_status = MLX_STATUS_WEDGED;
 	mlx_completeio(mc);
     }
+
+    sc->mlx_state &= ~MLX_STATE_QFROZEN;
 }
 
 /********************************************************************************
  * Pull as much work off the softc's work queue as possible and give it to the
  * controller.  Leave a couple of slots free for emergencies.
- *
- * Must be called at splbio or in an equivalent fashion that prevents 
- * reentry or activity on the bioq.
  */
 static void
 mlx_startio(struct mlx_softc *sc)
 {
     struct mlx_command	*mc;
-    mlx_bio		*bp;
-    int			s;
+    struct bio		*bp;
     int			error;
 
-    /* avoid reentrancy */
-    if (mlx_lock_tas(sc, MLX_LOCK_STARTING))
-	return;
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* spin until something prevents us from doing any work */
-    s = splbio();
     for (;;) {
+	if (sc->mlx_state & MLX_STATE_QFROZEN)
+	    break;
 
 	/* see if there's work to be done */
-	if ((bp = MLX_BIO_QFIRST(sc->mlx_bioq)) == NULL)
+	if ((bp = bioq_first(&sc->mlx_bioq)) == NULL)
 	    break;
 	/* get a command */
 	if ((mc = mlx_alloccmd(sc)) == NULL)
@@ -1846,27 +1932,23 @@
 	    break;
 	}
 	/* get the buf containing our work */
-	MLX_BIO_QREMOVE(sc->mlx_bioq, bp);
+	bioq_remove(&sc->mlx_bioq, bp);
 	sc->mlx_waitbufs--;
-	splx(s);
 	
 	/* connect the buf to the command */
 	mc->mc_complete = mlx_completeio;
 	mc->mc_private = bp;
-	mc->mc_data = MLX_BIO_DATA(bp);
-	mc->mc_length = MLX_BIO_LENGTH(bp);
+	mc->mc_data = bp->bio_data;
+	mc->mc_length = bp->bio_bcount;
 	
 	/* map the command so the controller can work with it */
 	error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
 				mc->mc_length, mlx_startio_cb, mc, 0);
-	if (error == EINPROGRESS) { 
-		break;
+	if (error == EINPROGRESS) {
+	    sc->mlx_state |= MLX_STATE_QFROZEN;
+	    break;
 	}
-	
-	s = splbio();
     }
-    splx(s);
-    mlx_lock_clr(sc, MLX_LOCK_STARTING);
 }
 
 /********************************************************************************
@@ -1876,11 +1958,13 @@
 mlx_completeio(struct mlx_command *mc)
 {
     struct mlx_softc	*sc = mc->mc_sc;
-    mlx_bio		*bp = (mlx_bio *)mc->mc_private;
-    struct mlxd_softc	*mlxd = (struct mlxd_softc *)MLX_BIO_SOFTC(bp);
-    
+    struct bio		*bp = mc->mc_private;
+    struct mlxd_softc	*mlxd = bp->bio_disk->d_drv1;
+
+    MLX_IO_ASSERT_LOCKED(sc);
     if (mc->mc_status != MLX_STATUS_OK) {	/* could be more verbose here? */
-	MLX_BIO_SET_ERROR(bp, EIO);
+	bp->bio_error = EIO;
+	bp->bio_flags |= BIO_ERROR;
 
 	switch(mc->mc_status) {
 	case MLX_STATUS_RDWROFFLINE:		/* system drive has gone offline */
@@ -1893,7 +1977,7 @@
 	    device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc));
 #if 0
 	    device_printf(sc->mlx_dev, "  b_bcount %ld  blkcount %ld  b_pblkno %d\n", 
-			  MLX_BIO_LENGTH(bp), MLX_BIO_LENGTH(bp) / MLX_BLKSIZE, MLX_BIO_LBA(bp));
+			  bp->bio_bcount, bp->bio_bcount / MLX_BLKSIZE, bp->bio_pblkno);
 	    device_printf(sc->mlx_dev, "  %13D\n", mc->mc_mailbox, " ");
 #endif
 	    break;
@@ -1969,8 +2053,11 @@
     error = ENOMEM;
 
     /* get ourselves a command and copy in from user space */
-    if ((mc = mlx_alloccmd(sc)) == NULL)
+    MLX_IO_LOCK(sc);
+    if ((mc = mlx_alloccmd(sc)) == NULL) {
+	MLX_IO_UNLOCK(sc);
 	return(error);
+    }
     bcopy(mu->mu_command, mc->mc_mailbox, sizeof(mc->mc_mailbox));
     debug(0, "got command buffer");
 
@@ -1983,9 +2070,13 @@
 	    error = EINVAL;
 	    goto out;
 	}
+	MLX_IO_UNLOCK(sc);
 	if (((kbuf = malloc(mu->mu_datasize, M_DEVBUF, M_WAITOK)) == NULL) ||
-	    (error = copyin(mu->mu_buf, kbuf, mu->mu_datasize)))
+	    (error = copyin(mu->mu_buf, kbuf, mu->mu_datasize))) {
+	    MLX_IO_LOCK(sc);
 	    goto out;
+	}
+	MLX_IO_LOCK(sc);
 	debug(0, "got kernel buffer");
     }
 
@@ -2010,17 +2101,20 @@
     mc->mc_private = mu;
     error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
 			    mc->mc_length, mlx_user_cb, mc, BUS_DMA_NOWAIT);
+    if (error)
+	goto out;
 
     /* copy out status and data */
     mu->mu_status = mc->mc_status;
-    if ((mu->mu_datasize > 0) &&
-	((error = copyout(kbuf, mu->mu_buf, mu->mu_datasize))))
-	goto out;
+    if (mu->mu_datasize > 0) {
+	MLX_IO_UNLOCK(sc);
+	error = copyout(kbuf, mu->mu_buf, mu->mu_datasize);
+	MLX_IO_LOCK(sc);
+    }
 
-    error = 0;
-
  out:
     mlx_releasecmd(mc);
+    MLX_IO_UNLOCK(sc);
     if (kbuf != NULL)
 	free(kbuf, M_DEVBUF);
     return(error);
@@ -2042,10 +2136,12 @@
 mlx_getslot(struct mlx_command *mc)
 {
     struct mlx_softc	*sc = mc->mc_sc;
-    int			s, slot, limit;
+    int			slot, limit;
 
     debug_called(1);
 
+    MLX_IO_ASSERT_LOCKED(sc);
+
     /* 
      * Enforce slot-usage limit, if we have the required information.
      */
@@ -2062,7 +2158,6 @@
      *
      * XXX linear search is slow
      */
-    s = splbio();
     for (slot = 0; slot < limit; slot++) {
 	debug(2, "try slot %d", slot);
 	if (sc->mlx_busycmd[slot] == NULL)
@@ -2072,7 +2167,6 @@
 	sc->mlx_busycmd[slot] = mc;
 	sc->mlx_busycmds++;
     }
-    splx(s);
 
     /* out of slots? */
     if (slot >= limit)
@@ -2153,7 +2247,7 @@
 mlx_start(struct mlx_command *mc)
 {
     struct mlx_softc	*sc = mc->mc_sc;
-    int			i, s, done;
+    int			i;
 
     debug_called(1);
 
@@ -2165,22 +2259,17 @@
 
     /* set a default 60-second timeout  XXX tunable?  XXX not currently used */
     mc->mc_timeout = time_second + 60;
-    
+
     /* spin waiting for the mailbox */
-    for (i = 100000, done = 0; (i > 0) && !done; i--) {
-	s = splbio();
+    for (i = 100000; i > 0; i--) {
 	if (sc->mlx_tryqueue(sc, mc)) {
-	    done = 1;
 	    /* move command to work queue */
 	    TAILQ_INSERT_TAIL(&sc->mlx_work, mc, mc_link);
-	}
-	splx(s);	/* drop spl to allow completion interrupts */
+	    return (0);
+	} else if (i > 1)
+	    mlx_done(sc, 0);
     }
 
-    /* command is enqueued */
-    if (done)
-	return(0);
-
     /* 
      * We couldn't get the controller to take the command.  Revoke the slot
      * that the command was given and return it with a bad status.
@@ -2200,19 +2289,19 @@
  * Returns nonzero if one or more commands were completed.
  */
 static int
-mlx_done(struct mlx_softc *sc)
+mlx_done(struct mlx_softc *sc, int startio)
 {
     struct mlx_command	*mc;
-    int			s, result;
+    int			result;
     u_int8_t		slot;
     u_int16_t		status;
     
     debug_called(2);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     result = 0;
 
     /* loop collecting completed commands */
-    s = splbio();
     for (;;) {
 	/* poll for a completed command's identifier and status */
 	if (sc->mlx_findcomplete(sc, &slot, &status)) {
@@ -2235,10 +2324,9 @@
 	    break;
 	}
     }
-    splx(s);
 
     /* if we've completed any commands, try posting some more */
-    if (result)
+    if (result && startio)
 	mlx_startio(sc);
 
     /* handle completion and timeouts */
@@ -2254,17 +2342,10 @@
 mlx_complete(struct mlx_softc *sc) 
 {
     struct mlx_command	*mc, *nc;
-    int			s, count;
     
     debug_called(2);
+    MLX_IO_ASSERT_LOCKED(sc);
 
-    /* avoid reentrancy  XXX might want to signal and request a restart */
-    if (mlx_lock_tas(sc, MLX_LOCK_COMPLETING))
-	return;
-
-    s = splbio();
-    count = 0;
-
     /* scan the list of busy/done commands */
     mc = TAILQ_FIRST(&sc->mlx_work);
     while (mc != NULL) {
@@ -2300,9 +2381,6 @@
 	}
 	mc = nc;
     }
-    splx(s);
-
-    mlx_lock_clr(sc, MLX_LOCK_COMPLETING);
 }
 
 /********************************************************************************
@@ -2330,14 +2408,12 @@
 {
     struct mlx_command	*mc;
     int			error;
-    int			s;
 
     debug_called(1);
 
-    s = splbio();
+    MLX_IO_ASSERT_LOCKED(sc);
     if ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL)
 	TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link);
-    splx(s);
 
     /* allocate a new command buffer? */
     if (mc == NULL) {
@@ -2363,13 +2439,11 @@
 static void
 mlx_releasecmd(struct mlx_command *mc)
 {
-    int		s;
     
     debug_called(1);
 
-    s = splbio();
+    MLX_IO_ASSERT_LOCKED(mc->mc_sc);
     TAILQ_INSERT_HEAD(&mc->mc_sc->mlx_freecmds, mc, mc_link);
-    splx(s);
 }
 
 /********************************************************************************
@@ -2395,8 +2469,6 @@
 /********************************************************************************
  * Try to give (mc) to the controller.  Returns 1 if successful, 0 on failure
  * (the controller is not ready to take a command).
- *
- * Must be called at splbio or in a fashion that prevents reentry.
  */
 static int
 mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
@@ -2404,6 +2476,7 @@
     int		i;
     
     debug_called(2);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* ready for our command? */
     if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_FULL)) {
@@ -2421,8 +2494,6 @@
 /********************************************************************************
  * See if a command has been completed, if so acknowledge its completion
  * and recover the slot number and status code.
- *
- * Must be called at splbio or in a fashion that prevents reentry.
  */
 static int
 mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
@@ -2429,6 +2500,7 @@
 {
 
     debug_called(2);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* status available? */
     if (MLX_V3_GET_ODBR(sc) & MLX_V3_ODB_SAVAIL) {
@@ -2445,13 +2517,12 @@
 
 /********************************************************************************
  * Enable/disable interrupts as requested. (No acknowledge required)
- *
- * Must be called at splbio or in a fashion that prevents reentry.
  */
 static void
 mlx_v3_intaction(struct mlx_softc *sc, int action)
 {
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     switch(action) {
     case MLX_INTACTION_DISABLE:
@@ -2471,18 +2542,17 @@
  * error has been fetched, 2 if an error has been retrieved.
  */
 static int 
-mlx_v3_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2)
+mlx_v3_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2,
+    int first)
 {
     u_int8_t	fwerror;
-    static int	initted = 0;
 
     debug_called(2);
 
     /* first time around, clear any hardware completion status */
-    if (!initted) {
+    if (first) {
 	MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK);
 	DELAY(1000);
-	initted = 1;
     }
 
     /* init in progress? */
@@ -2514,8 +2584,6 @@
 /********************************************************************************
  * Try to give (mc) to the controller.  Returns 1 if successful, 0 on failure
  * (the controller is not ready to take a command).
- *
- * Must be called at splbio or in a fashion that prevents reentry.
  */
 static int
 mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
@@ -2523,6 +2591,7 @@
     int		i;
     
     debug_called(2);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* ready for our command? */
     if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_FULL)) {
@@ -2531,7 +2600,7 @@
 	    MLX_V4_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
 	
 	/* memory-mapped controller, so issue a write barrier to ensure the mailbox is filled */
-	bus_space_barrier(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_MAILBOX, MLX_V4_MAILBOX_LENGTH,
+	bus_barrier(sc->mlx_mem, MLX_V4_MAILBOX, MLX_V4_MAILBOX_LENGTH,
 			  BUS_SPACE_BARRIER_WRITE);
 
 	/* post command */
@@ -2544,8 +2613,6 @@
 /********************************************************************************
  * See if a command has been completed, if so acknowledge its completion
  * and recover the slot number and status code.
- *
- * Must be called at splbio or in a fashion that prevents reentry.
  */
 static int
 mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
@@ -2552,6 +2619,7 @@
 {
 
     debug_called(2);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* status available? */
     if (MLX_V4_GET_ODBR(sc) & MLX_V4_ODB_HWSAVAIL) {
@@ -2568,13 +2636,12 @@
 
 /********************************************************************************
  * Enable/disable interrupts as requested.
- *
- * Must be called at splbio or in a fashion that prevents reentry.
  */
 static void
 mlx_v4_intaction(struct mlx_softc *sc, int action)
 {
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     switch(action) {
     case MLX_INTACTION_DISABLE:
@@ -2594,18 +2661,17 @@
  * error has been fetched, 2 if an error has been retrieved.
  */
 static int 
-mlx_v4_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2)
+mlx_v4_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2,
+    int first)
 {
     u_int8_t	fwerror;
-    static int	initted = 0;
 
     debug_called(2);
 
     /* first time around, clear any hardware completion status */
-    if (!initted) {
+    if (first) {
 	MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK);
 	DELAY(1000);
-	initted = 1;
     }
 
     /* init in progress? */
@@ -2637,8 +2703,6 @@
 /********************************************************************************
  * Try to give (mc) to the controller.  Returns 1 if successful, 0 on failure
  * (the controller is not ready to take a command).
- *
- * Must be called at splbio or in a fashion that prevents reentry.
  */
 static int
 mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
@@ -2646,6 +2710,7 @@
     int		i;
 
     debug_called(2);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* ready for our command? */
     if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_EMPTY) {
@@ -2663,8 +2728,6 @@
 /********************************************************************************
  * See if a command has been completed, if so acknowledge its completion
  * and recover the slot number and status code.
- *
- * Must be called at splbio or in a fashion that prevents reentry.
  */
 static int
 mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
@@ -2671,6 +2734,7 @@
 {
 
     debug_called(2);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     /* status available? */
     if (MLX_V5_GET_ODBR(sc) & MLX_V5_ODB_HWSAVAIL) {
@@ -2687,13 +2751,12 @@
 
 /********************************************************************************
  * Enable/disable interrupts as requested.
- *
- * Must be called at splbio or in a fashion that prevents reentry.
  */
 static void
 mlx_v5_intaction(struct mlx_softc *sc, int action)
 {
     debug_called(1);
+    MLX_IO_ASSERT_LOCKED(sc);
 
     switch(action) {
     case MLX_INTACTION_DISABLE:
@@ -2713,18 +2776,17 @@
  * error has been fetched, 2 if an error has been retrieved.
  */
 static int 
-mlx_v5_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2)
+mlx_v5_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2,
+    int first)
 {
     u_int8_t	fwerror;
-    static int	initted = 0;
 
     debug_called(2);
 
     /* first time around, clear any hardware completion status */
-    if (!initted) {
+    if (first) {
 	MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK);
 	DELAY(1000);
-	initted = 1;
     }
 
     /* init in progress? */
@@ -2993,6 +3055,7 @@
     int		i;
     
     /* search system drives */
+    MLX_CONFIG_ASSERT_LOCKED(sc);
     for (i = 0; i < MLX_MAXDRIVES; i++) {
 	/* is this one attached? */
 	if (sc->mlx_sysdrive[i].ms_disk != 0) {

Modified: trunk/sys/dev/mlx/mlx_disk.c
===================================================================
--- trunk/sys/dev/mlx/mlx_disk.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mlx/mlx_disk.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1999 Jonathan Lemon
  * Copyright (c) 1999 Michael Smith
@@ -27,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mlx/mlx_disk.c 240963 2012-09-26 14:17:14Z jhb $");
 
 /*
  * Disk driver for Mylex DAC960 RAID adapters.
@@ -35,8 +36,11 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/bio.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/module.h>
+#include <sys/sx.h>
 
 #include <sys/bus.h>
 #include <sys/conf.h>
@@ -46,7 +50,6 @@
 
 #include <geom/geom_disk.h>
 
-#include <dev/mlx/mlx_compat.h>
 #include <dev/mlx/mlxio.h>
 #include <dev/mlx/mlxvar.h>
 #include <dev/mlx/mlxreg.h>
@@ -84,10 +87,17 @@
 	return (ENXIO);
 
     /* controller not active? */
-    if (sc->mlxd_controller->mlx_state & MLX_STATE_SHUTDOWN)
+    MLX_CONFIG_LOCK(sc->mlxd_controller);
+    MLX_IO_LOCK(sc->mlxd_controller);
+    if (sc->mlxd_controller->mlx_state & MLX_STATE_SHUTDOWN) {
+	MLX_IO_UNLOCK(sc->mlxd_controller);
+	MLX_CONFIG_UNLOCK(sc->mlxd_controller);
 	return(ENXIO);
+    }
 
     sc->mlxd_flags |= MLXD_OPEN;
+    MLX_IO_UNLOCK(sc->mlxd_controller);
+    MLX_CONFIG_UNLOCK(sc->mlxd_controller);
     return (0);
 }
 
@@ -97,10 +107,14 @@
     struct mlxd_softc	*sc = (struct mlxd_softc *)dp->d_drv1;
 
     debug_called(1);
-	
+
     if (sc == NULL)
 	return (ENXIO);
+    MLX_CONFIG_LOCK(sc->mlxd_controller);
+    MLX_IO_LOCK(sc->mlxd_controller);
     sc->mlxd_flags &= ~MLXD_OPEN;
+    MLX_IO_UNLOCK(sc->mlxd_controller);
+    MLX_CONFIG_UNLOCK(sc->mlxd_controller);
     return (0);
 }
 
@@ -129,26 +143,30 @@
  * be a multiple of a sector in length.
  */
 static void
-mlxd_strategy(mlx_bio *bp)
+mlxd_strategy(struct bio *bp)
 {
-    struct mlxd_softc	*sc = (struct mlxd_softc *)MLX_BIO_SOFTC(bp);
+    struct mlxd_softc	*sc = bp->bio_disk->d_drv1;
 
     debug_called(1);
 
     /* bogus disk? */
     if (sc == NULL) {
-	MLX_BIO_SET_ERROR(bp, EINVAL);
+	bp->bio_error = EINVAL;
+	bp->bio_flags |= BIO_ERROR;
 	goto bad;
     }
 
     /* XXX may only be temporarily offline - sleep? */
+    MLX_IO_LOCK(sc->mlxd_controller);
     if (sc->mlxd_drive->ms_state == MLX_SYSD_OFFLINE) {
-	MLX_BIO_SET_ERROR(bp, ENXIO);
+	MLX_IO_UNLOCK(sc->mlxd_controller);
+	bp->bio_error = ENXIO;
+	bp->bio_flags |= BIO_ERROR;
 	goto bad;
     }
 
-    MLX_BIO_STATS_START(bp);
     mlx_submit_buf(sc->mlxd_controller, bp);
+    MLX_IO_UNLOCK(sc->mlxd_controller);
     return;
 
  bad:
@@ -155,25 +173,23 @@
     /*
      * Correctly set the bio to indicate a failed tranfer.
      */
-    MLX_BIO_RESID(bp) = MLX_BIO_LENGTH(bp);
-    MLX_BIO_DONE(bp);
+    bp->bio_resid = bp->bio_bcount;
+    biodone(bp);
     return;
 }
 
 void
-mlxd_intr(void *data)
+mlxd_intr(struct bio *bp)
 {
-    mlx_bio 		*bp = (mlx_bio *)data;
 
     debug_called(1);
 	
-    if (MLX_BIO_HAS_ERROR(bp))
-	MLX_BIO_SET_ERROR(bp, EIO);
+    if (bp->bio_flags & BIO_ERROR)
+	bp->bio_error = EIO;
     else
-	MLX_BIO_RESID(bp) = 0;
+	bp->bio_resid = 0;
 
-    MLX_BIO_STATS_END(bp);
-    MLX_BIO_DONE(bp);
+    biodone(bp);
 }
 
 static int
@@ -232,7 +248,6 @@
     sc->mlxd_disk->d_mediasize = MLX_BLKSIZE * (off_t)sc->mlxd_drive->ms_size;
     sc->mlxd_disk->d_fwsectors = sc->mlxd_drive->ms_sectors;
     sc->mlxd_disk->d_fwheads = sc->mlxd_drive->ms_heads;
-    sc->mlxd_disk->d_flags = DISKFLAG_NEEDSGIANT;
 
     /* 
      * Set maximum I/O size to the lesser of the recommended maximum and the practical

Modified: trunk/sys/dev/mlx/mlx_pci.c
===================================================================
--- trunk/sys/dev/mlx/mlx_pci.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mlx/mlx_pci.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1999 Michael Smith
  * All rights reserved.
@@ -25,12 +26,16 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/mlx/mlx_pci.c 281826 2015-04-21 11:27:50Z mav $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/bio.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/sx.h>
 
 #include <sys/bus.h>
 #include <sys/conf.h>
@@ -44,7 +49,6 @@
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 
-#include <dev/mlx/mlx_compat.h>
 #include <dev/mlx/mlxio.h>
 #include <dev/mlx/mlxvar.h>
 #include <dev/mlx/mlxreg.h>
@@ -88,6 +92,21 @@
     {0, 0, 0, 0, 0, 0}
 };
 
+static struct mlx_ident *
+mlx_pci_match(device_t dev)
+{
+    struct mlx_ident *m;
+
+    for (m = mlx_identifiers; m->vendor != 0; m++) {
+	if ((m->vendor == pci_get_vendor(dev)) &&
+	    (m->device == pci_get_device(dev)) &&
+	    ((m->subvendor == 0) || ((m->subvendor == pci_get_subvendor(dev)) &&
+				     (m->subdevice == pci_get_subdevice(dev)))))
+	    return (m);
+    }
+    return (NULL);
+}
+
 static int
 mlx_pci_probe(device_t dev)
 {
@@ -95,15 +114,10 @@
 
     debug_called(1);
 
-    for (m = mlx_identifiers; m->vendor != 0; m++) {
-	if ((m->vendor == pci_get_vendor(dev)) &&
-	    (m->device == pci_get_device(dev)) &&
-	    ((m->subvendor == 0) || ((m->subvendor == pci_get_subvendor(dev)) &&
-				     (m->subdevice == pci_get_subdevice(dev))))) {
-	    
-	    device_set_desc(dev, m->desc);
-	    return(BUS_PROBE_DEFAULT);
-	}
+    m = mlx_pci_match(dev);
+    if (m != NULL) {
+	device_set_desc(dev, m->desc);
+	return(BUS_PROBE_DEFAULT);
     }
     return(ENXIO);
 }
@@ -112,28 +126,14 @@
 mlx_pci_attach(device_t dev)
 {
     struct mlx_softc	*sc;
-    int			i, error;
-    u_int32_t		command;
+    struct mlx_ident	*m;
+    int			error;
 
     debug_called(1);
 
-    /*
-     * Make sure we are going to be able to talk to this board.
-     */
-    command = pci_read_config(dev, PCIR_COMMAND, 2);
-    if ((command & PCIM_CMD_MEMEN) == 0) {
-	device_printf(dev, "memory window not available\n");
-	return(ENXIO);
-    }
-    /* force the busmaster enable bit on */
-    command |= PCIM_CMD_BUSMASTEREN;
-    pci_write_config(dev, PCIR_COMMAND, command, 2);
+    pci_enable_busmaster(dev);
 
-    /*
-     * Initialise softc.
-     */
     sc = device_get_softc(dev);
-    bzero(sc, sizeof(*sc));
     sc->mlx_dev = dev;
 
     /*
@@ -140,17 +140,15 @@
      * Work out what sort of adapter this is (we need to know this in order
      * to map the appropriate interface resources).
      */
-    sc->mlx_iftype = 0;
-    for (i = 0; mlx_identifiers[i].vendor != 0; i++) {
-	if ((mlx_identifiers[i].vendor == pci_get_vendor(dev)) &&
-	    (mlx_identifiers[i].device == pci_get_device(dev))) {
-	    sc->mlx_iftype = mlx_identifiers[i].iftype;
-	    break;
-	}
-    }
-    if (sc->mlx_iftype == 0)		/* shouldn't happen */
+    m = mlx_pci_match(dev);
+    if (m == NULL)		/* shouldn't happen */
 	return(ENXIO);
-    
+    sc->mlx_iftype = m->iftype;
+
+    mtx_init(&sc->mlx_io_lock, "mlx I/O", NULL, MTX_DEF);
+    sx_init(&sc->mlx_config_lock, "mlx config");
+    callout_init_mtx(&sc->mlx_timeout, &sc->mlx_io_lock, 0);
+
     /*
      * Allocate the PCI register window.
      */
@@ -183,8 +181,6 @@
 	mlx_free(sc);
 	return(ENXIO);
     }
-    sc->mlx_btag = rman_get_bustag(sc->mlx_mem);
-    sc->mlx_bhandle = rman_get_bushandle(sc->mlx_mem);
 
     /*
      * Allocate the parent bus DMA tag appropriate for PCI.
@@ -194,7 +190,8 @@
 			       BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
 			       BUS_SPACE_MAXADDR, 	/* highaddr */
 			       NULL, NULL, 		/* filter, filterarg */
-			       MAXBSIZE, MLX_NSEG,	/* maxsize, nsegments */
+			       BUS_SPACE_MAXSIZE_32BIT, /* maxsize */
+			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
 			       BUS_DMA_ALLOCNOW,	/* flags */
 			       NULL,			/* lockfunc */

Modified: trunk/sys/dev/mlx/mlxio.h
===================================================================
--- trunk/sys/dev/mlx/mlxio.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mlx/mlxio.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1999 Michael Smith
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$MidnightBSD$
+ *	$FreeBSD: stable/10/sys/dev/mlx/mlxio.h 59136 2000-04-11 02:52:46Z msmith $
  */
 
 #include <sys/ioccom.h>

Modified: trunk/sys/dev/mlx/mlxreg.h
===================================================================
--- trunk/sys/dev/mlx/mlxreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mlx/mlxreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1999 Michael Smith
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$MidnightBSD$
+ *	$FreeBSD: stable/10/sys/dev/mlx/mlxreg.h 240608 2012-09-17 15:27:30Z jhb $
  */
 
 #define MLX_BLKSIZE	512		/* fixed feature */
@@ -78,18 +79,18 @@
 #define MLX_V3_FWERROR_PARAM1	0x00
 #define MLX_V3_FWERROR_PARAM2	0x01
 
-#define MLX_V3_PUT_MAILBOX(sc, idx, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_MAILBOX + idx, val)
-#define MLX_V3_GET_STATUS_IDENT(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_STATUS_IDENT)
-#define MLX_V3_GET_STATUS(sc)		 bus_space_read_2 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_STATUS)
-#define MLX_V3_GET_IDBR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_IDBR)
-#define MLX_V3_PUT_IDBR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_IDBR, val)
-#define MLX_V3_GET_ODBR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_ODBR)
-#define MLX_V3_PUT_ODBR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_ODBR, val)
-#define MLX_V3_PUT_IER(sc, val)		 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_IER, val)
-#define MLX_V3_GET_FWERROR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_FWERROR)
-#define MLX_V3_PUT_FWERROR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V3_FWERROR, val)
-#define MLX_V3_GET_FWERROR_PARAM1(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_FWERROR_PARAM1)
-#define MLX_V3_GET_FWERROR_PARAM2(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V3_FWERROR_PARAM2)
+#define MLX_V3_PUT_MAILBOX(sc, idx, val) bus_write_1(sc->mlx_mem, MLX_V3_MAILBOX + idx, val)
+#define MLX_V3_GET_STATUS_IDENT(sc)	 bus_read_1 (sc->mlx_mem, MLX_V3_STATUS_IDENT)
+#define MLX_V3_GET_STATUS(sc)		 bus_read_2 (sc->mlx_mem, MLX_V3_STATUS)
+#define MLX_V3_GET_IDBR(sc)		 bus_read_1 (sc->mlx_mem, MLX_V3_IDBR)
+#define MLX_V3_PUT_IDBR(sc, val)	 bus_write_1(sc->mlx_mem, MLX_V3_IDBR, val)
+#define MLX_V3_GET_ODBR(sc)		 bus_read_1 (sc->mlx_mem, MLX_V3_ODBR)
+#define MLX_V3_PUT_ODBR(sc, val)	 bus_write_1(sc->mlx_mem, MLX_V3_ODBR, val)
+#define MLX_V3_PUT_IER(sc, val)		 bus_write_1(sc->mlx_mem, MLX_V3_IER, val)
+#define MLX_V3_GET_FWERROR(sc)		 bus_read_1 (sc->mlx_mem, MLX_V3_FWERROR)
+#define MLX_V3_PUT_FWERROR(sc, val)	 bus_write_1(sc->mlx_mem, MLX_V3_FWERROR, val)
+#define MLX_V3_GET_FWERROR_PARAM1(sc)	 bus_read_1 (sc->mlx_mem, MLX_V3_FWERROR_PARAM1)
+#define MLX_V3_GET_FWERROR_PARAM2(sc)	 bus_read_1 (sc->mlx_mem, MLX_V3_FWERROR_PARAM2)
 
 #define MLX_V3_IDB_FULL		(1<<0)		/* mailbox is full */
 #define MLX_V3_IDB_INIT_BUSY	(1<<1)		/* initialisation in progress */
@@ -115,18 +116,18 @@
 #define MLX_V4_FWERROR_PARAM2	0x1001
 
 /* use longword access? */
-#define MLX_V4_PUT_MAILBOX(sc, idx, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_MAILBOX + idx, val)
-#define MLX_V4_GET_STATUS_IDENT(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_STATUS_IDENT)
-#define MLX_V4_GET_STATUS(sc)		 bus_space_read_2 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_STATUS)
-#define MLX_V4_GET_IDBR(sc)		 bus_space_read_4 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_IDBR)
-#define MLX_V4_PUT_IDBR(sc, val)	 bus_space_write_4(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_IDBR, val)
-#define MLX_V4_GET_ODBR(sc)		 bus_space_read_4 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_ODBR)
-#define MLX_V4_PUT_ODBR(sc, val)	 bus_space_write_4(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_ODBR, val)
-#define MLX_V4_PUT_IER(sc, val)		 bus_space_write_4(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_IER, val)
-#define MLX_V4_GET_FWERROR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_FWERROR)
-#define MLX_V4_PUT_FWERROR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_FWERROR, val)
-#define MLX_V4_GET_FWERROR_PARAM1(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_FWERROR_PARAM1)
-#define MLX_V4_GET_FWERROR_PARAM2(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V4_FWERROR_PARAM2)
+#define MLX_V4_PUT_MAILBOX(sc, idx, val) bus_write_1(sc->mlx_mem, MLX_V4_MAILBOX + idx, val)
+#define MLX_V4_GET_STATUS_IDENT(sc)	 bus_read_1 (sc->mlx_mem, MLX_V4_STATUS_IDENT)
+#define MLX_V4_GET_STATUS(sc)		 bus_read_2 (sc->mlx_mem, MLX_V4_STATUS)
+#define MLX_V4_GET_IDBR(sc)		 bus_read_4 (sc->mlx_mem, MLX_V4_IDBR)
+#define MLX_V4_PUT_IDBR(sc, val)	 bus_write_4(sc->mlx_mem, MLX_V4_IDBR, val)
+#define MLX_V4_GET_ODBR(sc)		 bus_read_4 (sc->mlx_mem, MLX_V4_ODBR)
+#define MLX_V4_PUT_ODBR(sc, val)	 bus_write_4(sc->mlx_mem, MLX_V4_ODBR, val)
+#define MLX_V4_PUT_IER(sc, val)		 bus_write_4(sc->mlx_mem, MLX_V4_IER, val)
+#define MLX_V4_GET_FWERROR(sc)		 bus_read_1 (sc->mlx_mem, MLX_V4_FWERROR)
+#define MLX_V4_PUT_FWERROR(sc, val)	 bus_write_1(sc->mlx_mem, MLX_V4_FWERROR, val)
+#define MLX_V4_GET_FWERROR_PARAM1(sc)	 bus_read_1 (sc->mlx_mem, MLX_V4_FWERROR_PARAM1)
+#define MLX_V4_GET_FWERROR_PARAM2(sc)	 bus_read_1 (sc->mlx_mem, MLX_V4_FWERROR_PARAM2)
 
 #define MLX_V4_IDB_FULL		(1<<0)		/* mailbox is full */
 #define MLX_V4_IDB_INIT_BUSY	(1<<1)		/* initialisation in progress */
@@ -160,18 +161,18 @@
 #define MLX_V5_FWERROR_PARAM1	0x50
 #define MLX_V5_FWERROR_PARAM2	0x51
 
-#define MLX_V5_PUT_MAILBOX(sc, idx, val) bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_MAILBOX + idx, val)
-#define MLX_V5_GET_STATUS_IDENT(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_STATUS_IDENT)
-#define MLX_V5_GET_STATUS(sc)		 bus_space_read_2 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_STATUS)
-#define MLX_V5_GET_IDBR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_IDBR)
-#define MLX_V5_PUT_IDBR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_IDBR, val)
-#define MLX_V5_GET_ODBR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_ODBR)
-#define MLX_V5_PUT_ODBR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_ODBR, val)
-#define MLX_V5_PUT_IER(sc, val)		 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_IER, val)
-#define MLX_V5_GET_FWERROR(sc)		 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_FWERROR)
-#define MLX_V5_PUT_FWERROR(sc, val)	 bus_space_write_1(sc->mlx_btag, sc->mlx_bhandle, MLX_V5_FWERROR, val)
-#define MLX_V5_GET_FWERROR_PARAM1(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_FWERROR_PARAM1)
-#define MLX_V5_GET_FWERROR_PARAM2(sc)	 bus_space_read_1 (sc->mlx_btag, sc->mlx_bhandle, MLX_V5_FWERROR_PARAM2)
+#define MLX_V5_PUT_MAILBOX(sc, idx, val) bus_write_1(sc->mlx_mem, MLX_V5_MAILBOX + idx, val)
+#define MLX_V5_GET_STATUS_IDENT(sc)	 bus_read_1 (sc->mlx_mem, MLX_V5_STATUS_IDENT)
+#define MLX_V5_GET_STATUS(sc)		 bus_read_2 (sc->mlx_mem, MLX_V5_STATUS)
+#define MLX_V5_GET_IDBR(sc)		 bus_read_1 (sc->mlx_mem, MLX_V5_IDBR)
+#define MLX_V5_PUT_IDBR(sc, val)	 bus_write_1(sc->mlx_mem, MLX_V5_IDBR, val)
+#define MLX_V5_GET_ODBR(sc)		 bus_read_1 (sc->mlx_mem, MLX_V5_ODBR)
+#define MLX_V5_PUT_ODBR(sc, val)	 bus_write_1(sc->mlx_mem, MLX_V5_ODBR, val)
+#define MLX_V5_PUT_IER(sc, val)		 bus_write_1(sc->mlx_mem, MLX_V5_IER, val)
+#define MLX_V5_GET_FWERROR(sc)		 bus_read_1 (sc->mlx_mem, MLX_V5_FWERROR)
+#define MLX_V5_PUT_FWERROR(sc, val)	 bus_write_1(sc->mlx_mem, MLX_V5_FWERROR, val)
+#define MLX_V5_GET_FWERROR_PARAM1(sc)	 bus_read_1 (sc->mlx_mem, MLX_V5_FWERROR_PARAM1)
+#define MLX_V5_GET_FWERROR_PARAM2(sc)	 bus_read_1 (sc->mlx_mem, MLX_V5_FWERROR_PARAM2)
 
 #define MLX_V5_IDB_EMPTY	(1<<0)		/* mailbox is empty */
 #define MLX_V5_IDB_INIT_DONE	(1<<1)		/* initialisation has completed */

Modified: trunk/sys/dev/mlx/mlxvar.h
===================================================================
--- trunk/sys/dev/mlx/mlxvar.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mlx/mlxvar.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1999 Michael Smith
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$MidnightBSD$
+ *	$FreeBSD: stable/10/sys/dev/mlx/mlxvar.h 240963 2012-09-26 14:17:14Z jhb $
  */
 
 /*
@@ -47,7 +48,7 @@
  * making that fit cleanly without crossing page boundaries requires rounding up
  * to the next power of two.
  */
-#define MLX_MAXPHYS	(128 * 124)
+#define MLX_MAXPHYS	(128 * 1024)
 #define MLX_NSEG	64
 
 #define MLX_NSLOTS	256		/* max number of command slots */
@@ -113,8 +114,6 @@
     struct resource	*mlx_mem;	/* mailbox interface window */
     int			mlx_mem_rid;
     int			mlx_mem_type;
-    bus_space_handle_t	mlx_bhandle;	/* bus space handle */
-    bus_space_tag_t	mlx_btag;	/* bus space tag */
     bus_dma_tag_t	mlx_parent_dmat;/* parent DMA tag */
     bus_dma_tag_t	mlx_buffer_dmat;/* data buffer DMA tag */
     struct resource	*mlx_irq;	/* interrupt */
@@ -137,7 +136,7 @@
     struct mlx_command	*mlx_busycmd[MLX_NSLOTS];	/* busy commands */
     int			mlx_busycmds;			/* count of busy commands */
     struct mlx_sysdrive	mlx_sysdrive[MLX_MAXDRIVES];	/* system drives */
-    mlx_bioq		mlx_bioq;			/* outstanding I/O operations */
+    struct bio_queue_head mlx_bioq;			/* outstanding I/O operations */
     int			mlx_waitbufs;			/* number of bufs awaiting commands */
 
     /* controller status */
@@ -149,7 +148,10 @@
 #define MLX_STATE_SHUTDOWN	(1<<1)	/* controller is shut down */
 #define MLX_STATE_OPEN		(1<<2)	/* control device is open */
 #define MLX_STATE_SUSPEND	(1<<3)	/* controller is suspended */
-    struct callout_handle mlx_timeout;	/* periodic status monitor */
+#define	MLX_STATE_QFROZEN	(1<<4)  /* bio queue frozen */
+    struct mtx		mlx_io_lock;
+    struct sx		mlx_config_lock;
+    struct callout	mlx_timeout;	/* periodic status monitor */
     time_t		mlx_lastpoll;	/* last time_second we polled for status */
     u_int16_t		mlx_lastevent;	/* sequence number of the last event we recorded */
     int			mlx_currevent;	/* sequence number last time we looked */
@@ -160,7 +162,6 @@
     struct mlx_rebuild_status mlx_rebuildstat;	/* last rebuild status */
     struct mlx_pause	mlx_pause;	/* pending pause operation details */
 
-    int			mlx_locks;	/* reentrancy avoidance */
     int			mlx_flags;
 #define MLX_SPINUP_REPORTED	(1<<0)	/* "spinning up drives" message displayed */
 #define MLX_EVENTLOG_BUSY	(1<<1)	/* currently reading event log */
@@ -174,35 +175,18 @@
     int			(* mlx_tryqueue)(struct mlx_softc *sc, struct mlx_command *mc);
     int			(* mlx_findcomplete)(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
     void		(* mlx_intaction)(struct mlx_softc *sc, int action);
-    int			(* mlx_fw_handshake)(struct mlx_softc *sc, int *error, int *param1, int *param2);
+    int			(* mlx_fw_handshake)(struct mlx_softc *sc, int *error, int *param1, int *param2, int first);
 #define MLX_INTACTION_DISABLE		0
 #define MLX_INTACTION_ENABLE		1
 };
 
-/*
- * Simple (stupid) locks.
- *
- * Note that these are designed to avoid reentrancy, not concurrency, and will
- * need to be replaced with something better.
- */
-#define MLX_LOCK_COMPLETING	(1<<0)
-#define MLX_LOCK_STARTING	(1<<1)
+#define	MLX_IO_LOCK(sc)			mtx_lock(&(sc)->mlx_io_lock)
+#define	MLX_IO_UNLOCK(sc)		mtx_unlock(&(sc)->mlx_io_lock)
+#define	MLX_IO_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->mlx_io_lock, MA_OWNED)
+#define	MLX_CONFIG_LOCK(sc)		sx_xlock(&(sc)->mlx_config_lock)
+#define	MLX_CONFIG_UNLOCK(sc)		sx_xunlock(&(sc)->mlx_config_lock)
+#define	MLX_CONFIG_ASSERT_LOCKED(sc)	sx_assert(&(sc)->mlx_config_lock, SA_XLOCKED)
 
-static __inline int
-mlx_lock_tas(struct mlx_softc *sc, int lock)
-{
-    if ((sc)->mlx_locks & (lock))
-	return(1);
-    atomic_set_int(&sc->mlx_locks, lock);
-    return(0);
-}
-
-static __inline void
-mlx_lock_clr(struct mlx_softc *sc, int lock)
-{
-    atomic_clear_int(&sc->mlx_locks, lock);
-}
-
 /*
  * Interface between bus connections and driver core.
  */
@@ -238,10 +222,10 @@
 /*
  * Interface between driver core and disk driver (should be using a bus?)
  */
-extern int	mlx_submit_buf(struct mlx_softc *sc, mlx_bio *bp);
+extern int	mlx_submit_buf(struct mlx_softc *sc, struct bio *bp);
 extern int	mlx_submit_ioctl(struct mlx_softc *sc,
 			struct mlx_sysdrive *drive, u_long cmd, 
 			caddr_t addr, int32_t flag, struct thread *td);
-extern void	mlxd_intr(void *data);
+extern void	mlxd_intr(struct bio *bp);
 
 

Modified: trunk/sys/dev/mly/mly.c
===================================================================
--- trunk/sys/dev/mly/mly.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mly/mly.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000, 2001 Michael Smith
  * Copyright (c) 2000 BSDi
@@ -24,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$MidnightBSD$
+ *	$FreeBSD: stable/10/sys/dev/mly/mly.c 323826 2017-09-20 20:48:21Z jhb $
  */
 
 #include <sys/param.h>
@@ -333,7 +334,6 @@
 mly_pci_attach(struct mly_softc *sc)
 {
     int			i, error;
-    u_int32_t		command;
 
     debug_called(1);
 
@@ -342,21 +342,8 @@
 
     /* 
      * Verify that the adapter is correctly set up in PCI space.
-     * 
-     * XXX we shouldn't do this; the PCI code should.
      */
-    command = pci_read_config(sc->mly_dev, PCIR_COMMAND, 2);
-    command |= PCIM_CMD_BUSMASTEREN;
-    pci_write_config(sc->mly_dev, PCIR_COMMAND, command, 2);
-    command = pci_read_config(sc->mly_dev, PCIR_COMMAND, 2);
-    if (!(command & PCIM_CMD_BUSMASTEREN)) {
-	mly_printf(sc, "can't enable busmaster feature\n");
-	goto fail;
-    }
-    if ((command & PCIM_CMD_MEMEN) == 0) {
-	mly_printf(sc, "memory window not available\n");
-	goto fail;
-    }
+    pci_enable_busmaster(sc->mly_dev);
 
     /*
      * Allocate the PCI register window.
@@ -397,7 +384,8 @@
 			   BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
 			   BUS_SPACE_MAXADDR, 		/* highaddr */
 			   NULL, NULL, 			/* filter, filterarg */
-			   MAXBSIZE, MLY_MAX_SGENTRIES,	/* maxsize, nsegments */
+			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
+			   BUS_SPACE_UNRESTRICTED,	/* nsegments */
 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
 			   BUS_DMA_ALLOCNOW,		/* flags */
 			   NULL,			/* lockfunc */
@@ -415,7 +403,8 @@
 			   BUS_SPACE_MAXADDR,		/* lowaddr */
 			   BUS_SPACE_MAXADDR, 		/* highaddr */
 			   NULL, NULL, 			/* filter, filterarg */
-			   MAXBSIZE, MLY_MAX_SGENTRIES,	/* maxsize, nsegments */
+			   DFLTPHYS,			/* maxsize */
+			   MLY_MAX_SGENTRIES,		/* nsegments */
 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
 			   0,				/* flags */
 			   busdma_lock_mutex,		/* lockfunc */
@@ -1350,7 +1339,6 @@
 	if (action == 'r')
 	    sc->mly_btl[bus][target].mb_flags |= MLY_BTL_RESCAN;
 	break;
-      break;
     case 's':		/* report of sense data */
 	if (((ssd->flags & SSD_KEY) == SSD_KEY_NO_SENSE) ||
 	    (((ssd->flags & SSD_KEY) == SSD_KEY_NOT_READY) && 
@@ -1865,9 +1853,13 @@
 
     /* does the command have a data buffer? */
     if (mc->mc_data != NULL) {
-	bus_dmamap_load(sc->mly_buffer_dmat, mc->mc_datamap, mc->mc_data, mc->mc_length, 
-			mly_map_command_sg, mc, 0);
-	
+	if (mc->mc_flags & MLY_CMD_CCB)
+		bus_dmamap_load_ccb(sc->mly_buffer_dmat, mc->mc_datamap,
+				mc->mc_data, mly_map_command_sg, mc, 0);
+	else 
+		bus_dmamap_load(sc->mly_buffer_dmat, mc->mc_datamap,
+				mc->mc_data, mc->mc_length, 
+				mly_map_command_sg, mc, 0);
 	if (mc->mc_flags & MLY_CMD_DATAIN)
 	    bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_PREREAD);
 	if (mc->mc_flags & MLY_CMD_DATAOUT)
@@ -2022,7 +2014,7 @@
 	mly_printf(sc, "rescan failed (can't allocate CCB)\n");
 	return;
     }
-    if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, 
+    if (xpt_create_path(&ccb->ccb_h.path, NULL,
 	    cam_sim_path(sc->mly_cam_sim[bus]), target, 0) != CAM_REQ_CMP) {
 	mly_printf(sc, "rescan failed (can't create path)\n");
 	xpt_free_ccb(ccb);
@@ -2085,9 +2077,9 @@
 	cpi->max_target = MLY_MAX_TARGETS - 1;
 	cpi->max_lun = MLY_MAX_LUNS - 1;
 	cpi->initiator_id = sc->mly_controllerparam->initiator_id;
-	strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
-        strncpy(cpi->hba_vid, "FreeBSD", HBA_IDLEN);
-        strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
+	strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
+        strlcpy(cpi->hba_vid, "Mylex", HBA_IDLEN);
+        strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
         cpi->unit_number = cam_sim_unit(sim);
         cpi->bus_id = cam_sim_bus(sim);
 	cpi->base_transfer_speed = 132 * 1024;	/* XXX what to set this to? */
@@ -2221,18 +2213,6 @@
 	csio->ccb_h.status = CAM_REQ_CMP_ERR;
     }
 
-    /* if there is data transfer, it must be to/from a virtual address */
-    if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
-	if (csio->ccb_h.flags & CAM_DATA_PHYS) {		/* we can't map it */
-	    debug(0, "  data pointer is to physical address");
-	    csio->ccb_h.status = CAM_REQ_CMP_ERR;
-	}
-	if (csio->ccb_h.flags & CAM_SCATTER_VALID) {	/* we want to do the s/g setup */
-	    debug(0, "  data has premature s/g setup");
-	    csio->ccb_h.status = CAM_REQ_CMP_ERR;
-	}
-    }
-
     /* abandon aborted ccbs or those that have failed validation */
     if ((csio->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
 	debug(2, "abandoning CCB due to abort/validation failure");
@@ -2252,10 +2232,12 @@
     }
     
     /* build the command */
-    mc->mc_data = csio->data_ptr;
+    mc->mc_data = csio;
     mc->mc_length = csio->dxfer_len;
     mc->mc_complete = mly_cam_complete;
     mc->mc_private = csio;
+    mc->mc_flags |= MLY_CMD_CCB;
+    /* XXX This code doesn't set the data direction in mc_flags. */
 
     /* save the bus number in the ccb for later recovery XXX should be a better way */
      csio->ccb_h.sim_priv.entries[0].field = bus;
@@ -2880,8 +2862,7 @@
 
     /* allocate a command */
     if (mly_alloc_command(sc, &mc)) {
-	error = ENOMEM;
-	goto out;		/* XXX Linux version will wait for a command */
+	return (ENOMEM);	/* XXX Linux version will wait for a command */
     }
 
     /* handle data size/direction */
@@ -2937,8 +2918,7 @@
  out:
     if (mc->mc_data != NULL)
 	free(mc->mc_data, M_DEVBUF);
-    if (mc != NULL)
-	mly_release_command(mc);
+    mly_release_command(mc);
     return(error);
 }
 

Modified: trunk/sys/dev/mly/mly_tables.h
===================================================================
--- trunk/sys/dev/mly/mly_tables.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mly/mly_tables.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000 Michael Smith
  * Copyright (c) 2000 BSDi
@@ -24,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$MidnightBSD$
+ *	$FreeBSD: stable/10/sys/dev/mly/mly_tables.h 91448 2002-02-27 23:57:18Z peter $
  */
 
 /*

Modified: trunk/sys/dev/mly/mlyio.h
===================================================================
--- trunk/sys/dev/mly/mlyio.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mly/mlyio.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2001 Michael Smith
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$MidnightBSD$
+ *	$FreeBSD: stable/10/sys/dev/mly/mlyio.h 79695 2001-07-14 00:12:23Z msmith $
  */
 
 /********************************************************************************

Modified: trunk/sys/dev/mly/mlyreg.h
===================================================================
--- trunk/sys/dev/mly/mlyreg.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mly/mlyreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000 Michael Smith
  * Copyright (c) 2000 BSDi
@@ -24,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$MidnightBSD$
+ *	$FreeBSD: stable/10/sys/dev/mly/mlyreg.h 103870 2002-09-23 18:54:32Z alfred $
  */
 
 /*

Modified: trunk/sys/dev/mly/mlyvar.h
===================================================================
--- trunk/sys/dev/mly/mlyvar.h	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/mly/mlyvar.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2000, 2001 Michael Smith
  * Copyright (c) 2000 BSDi
@@ -24,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$MidnightBSD$
+ *	$FreeBSD: stable/10/sys/dev/mly/mlyvar.h 246713 2013-02-12 16:57:20Z kib $
  */
 
 /********************************************************************************
@@ -126,6 +127,7 @@
 #define MLY_CMD_MAPPED		(1<<3)		/* command has had its data mapped */
 #define MLY_CMD_DATAIN		(1<<4)		/* data moves controller->system */
 #define MLY_CMD_DATAOUT		(1<<5)		/* data moves system->controller */
+#define MLY_CMD_CCB		(1<<6)		/* data is ccb. */
     u_int16_t			mc_status;	/* command completion status */
     u_int8_t			mc_sense;	/* sense data length */
     int32_t			mc_resid;	/* I/O residual count */

Added: trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c
===================================================================
--- trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c	                        (rev 0)
+++ trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -0,0 +1,970 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012-2014 Bjoern A. Zeeb
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
+ * ("MRC2"), as part of the DARPA MRC research programme.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This driver is modelled after atse(4).  We need to seriously reduce the
+ * per-driver code we have to write^wcopy & paste.
+ *
+ * TODO:
+ * - figure out on the HW side why some data is LE and some is BE.
+ * - general set of improvements possible (e.g., reduce times of copying,
+ *   do on-the-copy checksum calculations)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c 270061 2014-08-16 14:30:46Z bz $");
+
+#include "opt_device_polling.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/types.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_vlan_var.h>
+
+#include <net/bpf.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include "if_nf10bmacreg.h"
+
+#ifndef	NF10BMAC_MAX_PKTS
+/*
+ * We have a 4k buffer in HW, so do not try to send more than 3 packets.
+ * At the time of writing HW is orders of magnitude faster than we can
+ * enqueue so it would not matter but need an escape.
+ */
+#define	NF10BMAC_MAX_PKTS		3
+#endif
+
+#ifndef NF10BMAC_WATCHDOG_TIME
+#define	NF10BMAC_WATCHDOG_TIME		5	/* seconds */
+#endif
+
+#ifdef DEVICE_POLLING
+static poll_handler_t nf10bmac_poll;
+#endif
+
+#define	NF10BMAC_LOCK(_sc)		mtx_lock(&(_sc)->nf10bmac_mtx)
+#define	NF10BMAC_UNLOCK(_sc)		mtx_unlock(&(_sc)->nf10bmac_mtx)
+#define	NF10BMAC_LOCK_ASSERT(_sc)	\
+	mtx_assert(&(_sc)->nf10bmac_mtx, MA_OWNED)
+
+#define	NF10BMAC_CTRL0			0x00
+#define	NF10BMAC_TX_DATA		0x00
+#define	NF10BMAC_TX_META		0x08
+#define	NF10BMAC_TX_LEN			0x10
+#define	NF10BMAC_RX_DATA		0x00
+#define	NF10BMAC_RX_META		0x08
+#define	NF10BMAC_RX_LEN			0x10
+#define	NF10BMAC_INTR_CLEAR_DIS		0x00
+#define	NF10BMAC_INTR_CTRL		0x08
+
+#define NF10BMAC_TUSER_MAC0		(1 << 0)
+#define NF10BMAC_TUSER_CPU0		(1 << 1)
+#define NF10BMAC_TUSER_MAC1		(1 << 2)
+#define NF10BMAC_TUSER_CPU1		(1 << 3)
+#define NF10BMAC_TUSER_MAC2		(1 << 4)
+#define NF10BMAC_TUSER_CPU2		(1 << 5)
+#define NF10BMAC_TUSER_MAC3		(1 << 6)
+#define NF10BMAC_TUSER_CPU3		(1 << 7)
+
+#define	NF10BMAC_DATA_LEN_MASK		0x0000ffff
+#define	NF10BMAC_DATA_DPORT_MASK	0xff000000
+#define	NF10BMAC_DATA_DPORT_SHIFT	24
+#define	NF10BMAC_DATA_SPORT_MASK	0x00ff0000
+#define	NF10BMAC_DATA_SPORT_SHIFT	16
+#define	NF10BMAC_DATA_LAST		0x00008000
+#ifdef NF10BMAC_64BIT
+#define	NF10BMAC_DATA_STRB		0x000000ff
+#define	REGWTYPE			uint64_t
+#else
+#define	NF10BMAC_DATA_STRB		0x0000000f
+#define	REGWTYPE			uint32_t
+#endif
+
+
+static inline void
+nf10bmac_write(struct resource *res, REGWTYPE reg, REGWTYPE val,
+    const char *f __unused, const int l __unused)
+{
+
+#ifdef NF10BMAC_64BIT
+	bus_write_8(res, reg, htole64(val));
+#else
+	bus_write_4(res, reg, htole32(val));
+#endif
+}
+
+static inline REGWTYPE
+nf10bmac_read(struct resource *res, REGWTYPE reg,
+    const char *f __unused, const int l __unused)
+{
+
+#ifdef NF10BMAC_64BIT
+	return (le64toh(bus_read_8(res, reg)));
+#else
+	return (le32toh(bus_read_4(res, reg)));
+#endif
+}
+
+static inline void
+nf10bmac_write_be(struct resource *res, REGWTYPE reg, REGWTYPE val,
+    const char *f __unused, const int l __unused)
+{
+
+#ifdef NF10BMAC_64BIT
+	bus_write_8(res, reg, htobe64(val));
+#else
+	bus_write_4(res, reg, htobe32(val));
+#endif
+}
+
+
+static inline REGWTYPE
+nf10bmac_read_be(struct resource *res, REGWTYPE reg,
+    const char *f __unused, const int l __unused)
+{
+
+#ifdef NF10BMAC_64BIT
+	return (be64toh(bus_read_8(res, reg)));
+#else
+	return (be32toh(bus_read_4(res, reg)));
+#endif
+}
+
+#define	NF10BMAC_WRITE_CTRL(sc, reg, val)				\
+	nf10bmac_write((sc)->nf10bmac_ctrl_res, (reg), (val),		\
+	    __func__, __LINE__)
+#define	NF10BMAC_WRITE(sc, reg, val)					\
+	nf10bmac_write((sc)->nf10bmac_tx_mem_res, (reg), (val),		\
+	    __func__, __LINE__)
+#define	NF10BMAC_READ(sc, reg)						\
+	nf10bmac_read((sc)->nf10bmac_rx_mem_res, (reg),			\
+	    __func__, __LINE__)
+#define	NF10BMAC_WRITE_BE(sc, reg, val)					\
+	nf10bmac_write_be((sc)->nf10bmac_tx_mem_res, (reg), (val),	\
+	    __func__, __LINE__)
+#define	NF10BMAC_READ_BE(sc, reg)					\
+	nf10bmac_read_be((sc)->nf10bmac_rx_mem_res, (reg),		\
+	    __func__, __LINE__)
+
+#define	NF10BMAC_WRITE_INTR(sc, reg, val, _f, _l)			\
+	nf10bmac_write((sc)->nf10bmac_intr_res, (reg), (val),		\
+	    (_f), (_l))
+
+#define	NF10BMAC_RX_INTR_CLEAR_DIS(sc)					\
+	NF10BMAC_WRITE_INTR((sc), NF10BMAC_INTR_CLEAR_DIS, 1,		\
+	__func__, __LINE__)
+#define	NF10BMAC_RX_INTR_ENABLE(sc)					\
+	NF10BMAC_WRITE_INTR((sc), NF10BMAC_INTR_CTRL, 1,		\
+	__func__, __LINE__)
+#define	NF10BMAC_RX_INTR_DISABLE(sc)					\
+	NF10BMAC_WRITE_INTR((sc), NF10BMAC_INTR_CTRL, 0,		\
+	__func__, __LINE__)
+
+
+#ifdef ENABLE_WATCHDOG
+static void nf10bmac_tick(void *);
+#endif
+static int nf10bmac_detach(device_t);
+
+devclass_t nf10bmac_devclass;
+
+
+static int
+nf10bmac_tx_locked(struct nf10bmac_softc *sc, struct mbuf *m)
+{
+	int32_t len, l, ml;
+	REGWTYPE md, val;
+
+	NF10BMAC_LOCK_ASSERT(sc);
+
+	KASSERT(m != NULL, ("%s: m is null: sc=%p", __func__, sc));
+	KASSERT(m->m_flags & M_PKTHDR, ("%s: not a pkthdr: m=%p", __func__, m));
+	/*
+	 * Copy to buffer to minimize our pain as we can only store
+	 * double words which, after the first mbuf gets out of alignment
+	 * quite quickly.
+	 */
+	m_copydata(m, 0, m->m_pkthdr.len, sc->nf10bmac_tx_buf);
+	len = m->m_pkthdr.len;
+
+	/* Write the length at start of packet. */
+	NF10BMAC_WRITE(sc, NF10BMAC_TX_LEN, len);
+
+	/* Write the meta data and data. */
+	ml = len / sizeof(val);
+	len -= (ml * sizeof(val));
+	for (l = 0; l <= ml; l++) {
+		int32_t cl;
+
+		cl = sizeof(val);
+		md = (NF10BMAC_TUSER_CPU0 << NF10BMAC_DATA_SPORT_SHIFT);
+		if (l == ml || (len == 0 && l == (ml - 1))) {
+			if (l == ml && len == 0) {
+				break;
+			} else {
+				uint8_t s;
+				int sl;
+
+				if (l == (ml - 1))
+					len = sizeof(val);
+				cl = len;
+
+				for (s = 0, sl = len; sl > 0; sl--)
+					s |= (1 << (sl - 1));
+				md |= (s & NF10BMAC_DATA_STRB);
+				md |= NF10BMAC_DATA_LAST;
+			}
+		} else {
+			md |= NF10BMAC_DATA_STRB;
+		}
+		NF10BMAC_WRITE(sc, NF10BMAC_TX_META, md);
+		bcopy(&sc->nf10bmac_tx_buf[l*sizeof(val)], &val, cl);
+		NF10BMAC_WRITE_BE(sc, NF10BMAC_TX_DATA, val);	
+	}
+
+	/* If anyone is interested give them a copy. */
+	BPF_MTAP(sc->nf10bmac_ifp, m);
+
+	m_freem(m);
+
+	return (0);
+}
+
+static void
+nf10bmac_start_locked(struct ifnet *ifp)
+{
+	struct nf10bmac_softc *sc;
+	int count, error;
+
+	sc = ifp->if_softc;
+	NF10BMAC_LOCK_ASSERT(sc);
+
+	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+	    IFF_DRV_RUNNING || (sc->nf10bmac_flags & NF10BMAC_FLAGS_LINK) == 0)
+		return;
+
+#ifdef ENABLE_WATCHDOG
+	/*
+	 * Disable the watchdog while sending, we are batching packets.
+	 * Though we should never reach 5 seconds, and are holding the lock,
+	 * but who knows.
+	 */
+	sc->nf10bmac_watchdog_timer = 0;
+#endif
+
+	/* Send up to MAX_PKTS_PER_TX_LOOP packets. */
+	for (count = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
+	    count < NF10BMAC_MAX_PKTS; count++) {
+		struct mbuf *m;
+
+		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+		if (m == NULL)
+			break;
+		error = nf10bmac_tx_locked(sc, m);
+		if (error != 0)
+			break;
+	}
+
+#ifdef ENABLE_WATCHDOG
+done:
+	/* If the IP core walks into Nekromanteion try to bail out. */
+	/* XXX-BZ useless until we have direct FIFO fill status feedback. */
+	if (count > 0)
+		sc->nf10bmac_watchdog_timer = NF10BMAC_WATCHDOG_TIME;
+#endif
+}
+
+static void
+nf10bmac_start(struct ifnet *ifp)
+{
+	struct nf10bmac_softc *sc;
+
+	sc = ifp->if_softc;
+	NF10BMAC_LOCK(sc);
+	nf10bmac_start_locked(ifp);
+	NF10BMAC_UNLOCK(sc);
+}
+
+static void
+nf10bmac_eat_packet_munch_munch(struct nf10bmac_softc *sc)
+{
+	REGWTYPE md, val;
+
+	do {
+		md = NF10BMAC_READ_BE(sc, NF10BMAC_RX_META);
+		if ((md & NF10BMAC_DATA_STRB) != 0)
+			val = NF10BMAC_READ_BE(sc, NF10BMAC_RX_DATA);
+	} while ((md & NF10BMAC_DATA_STRB) != 0 &&
+	    (md & NF10BMAC_DATA_LAST) == 0);
+}
+
+static int
+nf10bmac_rx_locked(struct nf10bmac_softc *sc)
+{
+	struct ifnet *ifp;
+	struct mbuf *m;
+	REGWTYPE md, val;
+	int32_t len, l;
+
+	/*
+	 * General problem here in case we need to sync ourselves to the
+	 * beginning of a packet.  Length will only be set for the first
+	 * read, and together with strb we can detect the begining (or
+	 * skip to tlast).
+	 */
+
+	len = NF10BMAC_READ(sc, NF10BMAC_RX_LEN) & NF10BMAC_DATA_LEN_MASK;
+	if (len > (MCLBYTES - ETHER_ALIGN)) {
+		nf10bmac_eat_packet_munch_munch(sc);
+		return (0);
+	}
+
+	md = NF10BMAC_READ(sc, NF10BMAC_RX_META);
+	if (len == 0 && (md & NF10BMAC_DATA_STRB) == 0) {
+		/* No packet data available. */
+		return (0);
+	} else if (len == 0 && (md & NF10BMAC_DATA_STRB) != 0) {
+		/* We are in the middle of a packet. */
+		nf10bmac_eat_packet_munch_munch(sc);
+		return (0);
+	} else if ((md & NF10BMAC_DATA_STRB) == 0) {
+		/* Invalid length "hint". */
+		device_printf(sc->nf10bmac_dev,
+		    "Unexpected length %d on zero strb\n", len);
+		return (0);
+	}
+
+	/* Assume at this point that we have data and a full packet. */
+	if ((len + ETHER_ALIGN) >= MINCLSIZE) {
+		/* Get a cluster. */
+		m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+		if (m == NULL)
+			return (0);
+		m->m_len = m->m_pkthdr.len = MCLBYTES;
+	} else {
+		/* Hey this still fits into the mbuf+pkthdr. */
+		m = m_gethdr(M_NOWAIT, MT_DATA);
+		if (m == NULL)
+			return (0);
+		m->m_len = m->m_pkthdr.len = MHLEN;
+	}
+	/* Make sure upper layers will be aligned. */
+	m_adj(m, ETHER_ALIGN);
+
+	ifp = sc->nf10bmac_ifp;
+	l = 0;
+/*
+	while ((md & NF10BMAC_DATA_STRB) != 0 && l < len) {
+*/
+	while (l < len) {
+		size_t cl;
+
+		if ((md & NF10BMAC_DATA_LAST) == 0 &&
+		    (len - l) < sizeof(val)) {
+			/*
+			 * Our length and LAST disagree. We have a valid STRB.
+			 * We could continue until we fill the mbuf and just
+			 * log the invlid length "hint".  For now drop the
+			 * packet on the floor and count the error.
+			 */
+			nf10bmac_eat_packet_munch_munch(sc);		
+			ifp->if_ierrors++;
+			m_freem(m);
+			return (0);
+		} else if ((len - l) <= sizeof(val)) {
+			cl = len - l;
+		} else {
+			cl = sizeof(val);
+		}
+
+		/* Read the first bytes of data as well. */
+		val = NF10BMAC_READ_BE(sc, NF10BMAC_RX_DATA);
+		bcopy(&val, (uint8_t *)(m->m_data + l), cl);
+		l += cl;
+
+		if ((md & NF10BMAC_DATA_LAST) != 0 || l >= len)
+			break;
+		else {
+			DELAY(50);
+			md = NF10BMAC_READ(sc, NF10BMAC_RX_META);
+		}
+
+		cl = 10;
+		while ((md & NF10BMAC_DATA_STRB) == 0 && cl-- > 0) {
+			DELAY(10);
+			md = NF10BMAC_READ(sc, NF10BMAC_RX_META);
+		}
+	}
+	/* We should get out of this loop with tlast and tsrb. */
+	if ((md & NF10BMAC_DATA_LAST) == 0 || (md & NF10BMAC_DATA_STRB) == 0) {
+		device_printf(sc->nf10bmac_dev, "Unexpected rx loop end state: "
+		    "md=0x%08jx len=%d l=%d\n", (uintmax_t)md, len, l);
+		ifp->if_ierrors++;
+		m_freem(m);
+		return (0);
+	}
+
+	m->m_pkthdr.len = m->m_len = len;
+	m->m_pkthdr.rcvif = ifp;
+	ifp->if_ipackets++;
+
+	NF10BMAC_UNLOCK(sc);
+	(*ifp->if_input)(ifp, m);
+	NF10BMAC_LOCK(sc);
+
+	return (1);
+}
+
+
+static int
+nf10bmac_stop_locked(struct nf10bmac_softc *sc)
+{
+	struct ifnet *ifp;
+
+	NF10BMAC_LOCK_ASSERT(sc);
+
+#ifdef ENABLE_WATCHDOG
+	sc->nf10bmac_watchdog_timer = 0;
+	callout_stop(&sc->nf10bmac_tick);
+#endif
+
+	ifp = sc->nf10bmac_ifp;
+	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+	NF10BMAC_RX_INTR_CLEAR_DIS(sc);
+
+	sc->nf10bmac_flags &= ~NF10BMAC_FLAGS_LINK;
+	if_link_state_change(ifp, LINK_STATE_DOWN);
+
+	return (0);
+}
+
+static int
+nf10bmac_reset(struct nf10bmac_softc *sc)
+{
+
+	/*
+	 * If we do not have an ether address set, initialize to the same
+	 * OUI as NetFPGA-10G Linux driver does (which luckily seems
+	 * unallocated).  We just change the NIC specific part from
+	 * the slightly long "\0NF10C0" to "\0NFBSD".
+	 * Oh and we keep the way of setting it from a string as they do.
+	 * It's an amazing way to hide it.
+	 * XXX-BZ If NetFPGA gets their own OUI we should fix this.
+	 */
+	if (sc->nf10bmac_eth_addr[0] == 0x00 &&
+	    sc->nf10bmac_eth_addr[1] == 0x00 &&
+	    sc->nf10bmac_eth_addr[2] == 0x00 &&
+	    sc->nf10bmac_eth_addr[3] == 0x00 &&
+	    sc->nf10bmac_eth_addr[4] == 0x00 &&
+	    sc->nf10bmac_eth_addr[5] == 0x00) {
+		memcpy(&sc->nf10bmac_eth_addr, "\0NFBSD", ETHER_ADDR_LEN);
+		sc->nf10bmac_eth_addr[5] += sc->nf10bmac_unit;
+	}
+
+	return (0);
+}
+
+static void
+nf10bmac_init_locked(struct nf10bmac_softc *sc)
+{
+	struct ifnet *ifp;
+	uint8_t *eaddr;
+
+	NF10BMAC_LOCK_ASSERT(sc);
+	ifp = sc->nf10bmac_ifp;
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+		return;
+
+	/*
+	 * Must update the ether address if changed.  Given we do not handle
+	 * in nf10bmac_ioctl() but it's in the general framework, just always
+	 * do it here before nf10bmac_reset().
+	 */
+	eaddr = IF_LLADDR(sc->nf10bmac_ifp);
+	bcopy(eaddr, &sc->nf10bmac_eth_addr, ETHER_ADDR_LEN);
+	/* XXX-BZ we do not have any way to tell the NIC our ether address. */
+
+	/* Make things frind to halt, cleanup, ... */
+	nf10bmac_stop_locked(sc);
+	/* ... reset, ... */
+	nf10bmac_reset(sc);
+
+	/* Memory rings?  DMA engine? MC filter?  MII? */
+	/* Instead drain the FIFO; or at least a possible first packet.. */
+	nf10bmac_eat_packet_munch_munch(sc);
+
+#ifdef DEVICE_POLLING
+	/* Only enable interrupts if we are not polling. */
+	if (ifp->if_capenable & IFCAP_POLLING) {
+		NF10BMAC_RX_INTR_CLEAR_DIS(sc);
+	} else
+#endif
+	{
+		NF10BMAC_RX_INTR_ENABLE(sc);
+	}
+
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+	/* We have no underlying media, fake link state. */
+	sc->nf10bmac_flags = NF10BMAC_FLAGS_LINK;	/* Always up. */
+	if_link_state_change(sc->nf10bmac_ifp, LINK_STATE_UP);
+
+#ifdef ENABLE_WATCHDOG
+	callout_reset(&sc->nf10bmac_tick, hz, nf10bmac_tick, sc);
+#endif
+}
+
+static void
+nf10bmac_init(void *xsc)
+{
+	struct nf10bmac_softc *sc;
+
+	sc = (struct nf10bmac_softc *)xsc;
+	NF10BMAC_LOCK(sc);
+	nf10bmac_init_locked(sc);
+	NF10BMAC_UNLOCK(sc);
+}
+
+#ifdef ENABLE_WATCHDOG
+static void
+nf10bmac_watchdog(struct nf10bmac_softc *sc)
+{
+
+	NF10BMAC_LOCK_ASSERT(sc);
+
+	if (sc->nf10bmac_watchdog_timer == 0 || --sc->nf10bmac_watchdog_timer > 0)
+		return;
+
+	device_printf(sc->nf10bmac_dev, "watchdog timeout\n");
+	sc->nf10bmac_ifp->if_oerrors++;
+
+	sc->nf10bmac_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+	nf10bmac_init_locked(sc);
+
+	if (!IFQ_DRV_IS_EMPTY(&sc->nf10bmac_ifp->if_snd))
+		nf10bmac_start_locked(sc->nf10bmac_ifp);
+}
+
+static void
+nf10bmac_tick(void *xsc)
+{
+	struct nf10bmac_softc *sc;
+	struct ifnet *ifp;
+
+	sc = (struct nf10bmac_softc *)xsc;
+	NF10BMAC_LOCK_ASSERT(sc);
+	ifp = sc->nf10bmac_ifp;
+
+	nf10bmac_watchdog(sc);
+	callout_reset(&sc->nf10bmac_tick, hz, nf10bmac_tick, sc);
+}
+#endif
+
+static void
+nf10bmac_intr(void *arg)
+{
+	struct nf10bmac_softc *sc;
+	struct ifnet *ifp;
+	int rx_npkts;
+
+	sc = (struct nf10bmac_softc *)arg;
+	ifp = sc->nf10bmac_ifp;
+
+	NF10BMAC_LOCK(sc);
+#ifdef DEVICE_POLLING
+	if (ifp->if_capenable & IFCAP_POLLING) {
+		NF10BMAC_UNLOCK(sc);
+		return;
+	} 
+#endif
+
+	/* NF10BMAC_RX_INTR_DISABLE(sc); */
+	NF10BMAC_RX_INTR_CLEAR_DIS(sc);
+
+	/* We only have an RX interrupt and no status information. */
+	rx_npkts = 0;
+	while (rx_npkts < NF10BMAC_MAX_PKTS) {
+		int c;
+
+		c = nf10bmac_rx_locked(sc);
+		rx_npkts += c;
+		if (c == 0)
+			break;
+	}
+
+	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+		/* Re-enable interrupts. */
+		NF10BMAC_RX_INTR_ENABLE(sc);
+
+		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+			nf10bmac_start_locked(ifp);
+	}
+	NF10BMAC_UNLOCK(sc);
+}
+
+
+#ifdef DEVICE_POLLING
+static int
+nf10bmac_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+{
+	struct nf10bmac_softc *sc;
+	int rx_npkts = 0;
+
+	sc = ifp->if_softc;
+	NF10BMAC_LOCK(sc);
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+		NF10BMAC_UNLOCK(sc);
+		return (rx_npkts);
+	}
+
+	while (rx_npkts < count) {
+		int c;
+
+		c = nf10bmac_rx_locked(sc);
+		rx_npkts += c;
+		if (c == 0)
+			break;
+	}
+	nf10bmac_start_locked(ifp);
+
+	if (rx_npkts > 0 || cmd == POLL_AND_CHECK_STATUS) {
+		/* We currently cannot do much. */
+		;
+	}
+
+        NF10BMAC_UNLOCK(sc);
+        return (rx_npkts);
+}
+#else
+#error We only support polling mode
+#endif /* DEVICE_POLLING */
+
+static int
+nf10bmac_media_change(struct ifnet *ifp __unused)
+{
+
+	/* Do nothing. */
+	return (0);
+}
+
+static void
+nf10bmac_media_status(struct ifnet *ifp __unused, struct ifmediareq *imr)
+{ 
+
+	imr->ifm_status = IFM_AVALID | IFM_ACTIVE;
+	imr->ifm_active = IFM_ETHER | IFM_10G_T | IFM_FDX;
+}
+
+static int
+nf10bmac_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
+{
+	struct nf10bmac_softc *sc;
+	struct ifreq *ifr;
+	int error, mask;
+
+	error = 0;
+	sc = ifp->if_softc;
+	ifr = (struct ifreq *)data;
+
+	switch (command) {
+	case SIOCSIFFLAGS:
+		NF10BMAC_LOCK(sc);
+		if (ifp->if_flags & IFF_UP) {
+			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
+			    ((ifp->if_flags ^ sc->nf10bmac_if_flags) &
+			    (IFF_PROMISC | IFF_ALLMULTI)) != 0)
+				/* Nothing we can do. */ ;
+			else
+				nf10bmac_init_locked(sc);
+		} else if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+			nf10bmac_stop_locked(sc);  
+		sc->nf10bmac_if_flags = ifp->if_flags;
+		NF10BMAC_UNLOCK(sc);
+		break;
+	case SIOCSIFCAP:
+		NF10BMAC_LOCK(sc);
+		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
+#ifdef DEVICE_POLLING
+		if ((mask & IFCAP_POLLING) != 0 &&
+		    (IFCAP_POLLING & ifp->if_capabilities) != 0) {
+			ifp->if_capenable ^= IFCAP_POLLING;
+			if ((IFCAP_POLLING & ifp->if_capenable) != 0) {
+
+				error = ether_poll_register(nf10bmac_poll, ifp);
+				if (error != 0) {
+					NF10BMAC_UNLOCK(sc);
+					break;
+				}
+
+				NF10BMAC_RX_INTR_CLEAR_DIS(sc);
+
+			/*
+			 * Do not allow disabling of polling if we do
+			 * not have interrupts.
+			 */
+			} else if (sc->nf10bmac_rx_irq_res != NULL) {
+				error = ether_poll_deregister(ifp);
+				/* Enable interrupts. */
+				NF10BMAC_RX_INTR_ENABLE(sc);
+			} else {
+				ifp->if_capenable ^= IFCAP_POLLING;
+				error = EINVAL;
+			}
+		}
+#endif /* DEVICE_POLLING */
+                NF10BMAC_UNLOCK(sc);
+                break;
+	case SIOCGIFMEDIA:
+	case SIOCSIFMEDIA:
+                error = ifmedia_ioctl(ifp, ifr, &sc->nf10bmac_media, command);
+		break;
+	default:
+		error = ether_ioctl(ifp, command, data);
+		break;
+	}
+
+	return (error);
+}
+
+/*
+ * Generic device handling routines.
+ */
+int
+nf10bmac_attach(device_t dev)
+{
+	struct nf10bmac_softc *sc;
+	struct ifnet *ifp;
+	int error;
+
+	sc = device_get_softc(dev);
+
+	mtx_init(&sc->nf10bmac_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
+	    MTX_DEF);
+
+#ifdef	ENABLE_WATCHDOG
+	callout_init_mtx(&sc->nf10bmac_tick, &sc->nf10bmac_mtx, 0);
+#endif
+
+	sc->nf10bmac_tx_buf = malloc(ETHER_MAX_LEN_JUMBO, M_DEVBUF, M_WAITOK);
+
+	/* Reset the adapter. */
+	nf10bmac_reset(sc);
+
+	/* Setup interface. */
+	ifp = sc->nf10bmac_ifp = if_alloc(IFT_ETHER);
+	if (ifp == NULL) {   
+		device_printf(dev, "if_alloc() failed\n");
+		error = ENOSPC;
+		goto err;
+	}
+	ifp->if_softc = sc;
+	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; /* | IFF_MULTICAST; */
+	ifp->if_ioctl = nf10bmac_ioctl;
+	ifp->if_start = nf10bmac_start;
+	ifp->if_init = nf10bmac_init;
+	IFQ_SET_MAXLEN(&ifp->if_snd, NF10BMAC_MAX_PKTS - 1);
+	ifp->if_snd.ifq_drv_maxlen = NF10BMAC_MAX_PKTS - 1;
+	IFQ_SET_READY(&ifp->if_snd);
+
+	/* Call media-indepedent attach routine. */
+	ether_ifattach(ifp, sc->nf10bmac_eth_addr);
+
+	/* Tell the upper layer(s) about vlan mtu support. */
+	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
+	ifp->if_capabilities |= IFCAP_VLAN_MTU;
+	ifp->if_capenable = ifp->if_capabilities;
+#ifdef DEVICE_POLLING
+	/* We will enable polling by default if no irqs available. See below. */
+	ifp->if_capabilities |= IFCAP_POLLING;
+#endif
+
+	/* We need more media attention.  Fake it! */
+        ifmedia_init(&sc->nf10bmac_media, 0, nf10bmac_media_change,
+	    nf10bmac_media_status);
+        ifmedia_add(&sc->nf10bmac_media, IFM_ETHER | IFM_10G_T, 0, NULL);
+        ifmedia_set(&sc->nf10bmac_media, IFM_ETHER | IFM_10G_T);
+
+	/* Initialise. */
+	error = 0;
+
+	/* Hook up interrupts. Well the one. */
+	if (sc->nf10bmac_rx_irq_res != NULL) {
+		error = bus_setup_intr(dev, sc->nf10bmac_rx_irq_res,
+		    INTR_TYPE_NET | INTR_MPSAFE, NULL, nf10bmac_intr,
+		    sc, &sc->nf10bmac_rx_intrhand);
+		if (error != 0) {
+			device_printf(dev, "enabling RX IRQ failed\n");
+			ether_ifdetach(ifp);
+			goto err;
+		}
+	}
+
+	if ((ifp->if_capenable & IFCAP_POLLING) != 0 ||
+	    sc->nf10bmac_rx_irq_res == NULL) {
+#ifdef DEVICE_POLLING
+		/* If not on and no IRQs force it on. */
+		if (sc->nf10bmac_rx_irq_res == NULL) {
+			ifp->if_capenable |= IFCAP_POLLING;
+			device_printf(dev,
+			    "forcing to polling due to no interrupts\n");
+		}
+		error = ether_poll_register(nf10bmac_poll, ifp);
+		if (error != 0)
+			goto err;
+#else
+		device_printf(dev, "no DEVICE_POLLING in kernel and no IRQs\n");
+		error = ENXIO;
+#endif
+	} else {
+		NF10BMAC_RX_INTR_ENABLE(sc);
+	}
+
+err:
+	if (error != 0)
+		nf10bmac_detach(dev);
+
+	return (error);                                                                                                                                                                      
+}
+
+static int
+nf10bmac_detach(device_t dev)
+{
+	struct nf10bmac_softc *sc;
+	struct ifnet *ifp;
+
+	sc = device_get_softc(dev);
+	KASSERT(mtx_initialized(&sc->nf10bmac_mtx),
+	    ("%s: mutex not initialized", device_get_nameunit(dev)));
+	ifp = sc->nf10bmac_ifp;
+
+#ifdef DEVICE_POLLING
+	if (ifp->if_capenable & IFCAP_POLLING)
+		ether_poll_deregister(ifp);
+#endif
+
+	/* Only cleanup if attach succeeded. */
+	if (device_is_attached(dev)) {
+		NF10BMAC_LOCK(sc);
+		nf10bmac_stop_locked(sc);
+		NF10BMAC_UNLOCK(sc);
+#ifdef ENABLE_WATCHDOG
+		callout_drain(&sc->nf10bmac_tick);
+#endif
+		ether_ifdetach(ifp);
+	}
+
+	if (sc->nf10bmac_rx_intrhand)
+		bus_teardown_intr(dev, sc->nf10bmac_rx_irq_res,
+		    sc->nf10bmac_rx_intrhand);
+
+	if (ifp != NULL)
+		if_free(ifp);
+	ifmedia_removeall(&sc->nf10bmac_media);
+
+	mtx_destroy(&sc->nf10bmac_mtx);
+
+	return (0);
+}
+
+/* Shared with the attachment specific (e.g., fdt) implementation. */
+void
+nf10bmac_detach_resources(device_t dev)
+{
+	struct nf10bmac_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (sc->nf10bmac_rx_irq_res != NULL) {
+		bus_release_resource(dev, SYS_RES_IRQ, sc->nf10bmac_rx_irq_rid,
+		    sc->nf10bmac_rx_irq_res);
+		sc->nf10bmac_rx_irq_res = NULL;
+	}
+	if (sc->nf10bmac_intr_res != NULL) {
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    sc->nf10bmac_intr_rid, sc->nf10bmac_intr_res);
+		sc->nf10bmac_intr_res = NULL;
+	}
+	if (sc->nf10bmac_rx_mem_res != NULL) {
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    sc->nf10bmac_rx_mem_rid, sc->nf10bmac_rx_mem_res);
+		sc->nf10bmac_rx_mem_res = NULL;
+	}
+	if (sc->nf10bmac_tx_mem_res != NULL) {
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    sc->nf10bmac_tx_mem_rid, sc->nf10bmac_tx_mem_res);
+		sc->nf10bmac_tx_mem_res = NULL;
+	}
+	if (sc->nf10bmac_ctrl_res != NULL) {
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    sc->nf10bmac_ctrl_rid, sc->nf10bmac_ctrl_res);
+		sc->nf10bmac_ctrl_res = NULL;
+	}
+}
+
+int
+nf10bmac_detach_dev(device_t dev)
+{
+	int error;
+
+	error = nf10bmac_detach(dev);
+	if (error) {
+		/* We are basically in undefined state now. */
+		device_printf(dev, "nf10bmac_detach() failed: %d\n", error);
+		return (error);
+	}
+
+	nf10bmac_detach_resources(dev);
+
+	return (0);
+}
+
+/* end */


Property changes on: trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c
===================================================================
--- trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c	                        (rev 0)
+++ trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -0,0 +1,204 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013-2014 Bjoern A. Zeeb
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
+ * ("MRC2"), as part of the DARPA MRC research programme.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This driver is modelled after atse(4).  We need to seriously reduce the
+ * per-driver code we have to write^wcopy & paste.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c 270061 2014-08-16 14:30:46Z bz $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_var.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "if_nf10bmacreg.h"
+
+static int
+nf10bmac_probe_fdt(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "netfpag10g,nf10bmac")) {
+		device_set_desc(dev, "NetFPGA-10G Embedded CPU Ethernet Core"); 
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+nf10bmac_attach_fdt(device_t dev)
+{
+	struct nf10bmac_softc *sc;
+	int error;
+
+	sc = device_get_softc(dev);
+	sc->nf10bmac_dev = dev;
+	sc->nf10bmac_unit = device_get_unit(dev);
+
+	/*
+	 * FDT lists our resources.  For convenience we use three different
+	 * mappings.  We need to attach them in the oder specified in .dts:
+	 * LOOP (size 0x1f), TX (0x2f), RX (0x2f), INTR (0xf).
+	 */
+
+	/*
+	 * LOOP memory region (this could be a general control region).
+	 * 0x00: 32/64bit register to enable a Y-"lopback".
+	 */
+        sc->nf10bmac_ctrl_rid = 0;
+        sc->nf10bmac_ctrl_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+            &sc->nf10bmac_ctrl_rid, RF_ACTIVE);
+        if (sc->nf10bmac_ctrl_res == NULL) {
+                device_printf(dev, "failed to map memory for CTRL region\n");
+                error = ENXIO;
+                goto err;
+        } 
+        if (bootverbose)
+                device_printf(sc->nf10bmac_dev, "CTRL region at mem %p-%p\n",
+                    (void *)rman_get_start(sc->nf10bmac_ctrl_res),
+                    (void *)(rman_get_start(sc->nf10bmac_ctrl_res) + 
+                    rman_get_size(sc->nf10bmac_ctrl_res)));
+
+        /*
+         * TX and TX metadata FIFO memory region.
+         * 0x00: 32/64bit FIFO data,
+	 * 0x08: 32/64bit FIFO metadata,
+         * 0x10: 32/64bit packet length.
+         */
+        sc->nf10bmac_tx_mem_rid = 1;
+        sc->nf10bmac_tx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+            &sc->nf10bmac_tx_mem_rid, RF_ACTIVE);
+        if (sc->nf10bmac_tx_mem_res == NULL) {
+                device_printf(dev, "failed to map memory for TX FIFO\n");
+                error = ENXIO;
+                goto err;
+        }
+        if (bootverbose)
+                device_printf(sc->nf10bmac_dev, "TX FIFO at mem %p-%p\n",
+                    (void *)rman_get_start(sc->nf10bmac_tx_mem_res),
+                    (void *)(rman_get_start(sc->nf10bmac_tx_mem_res) +
+                    rman_get_size(sc->nf10bmac_tx_mem_res)));
+
+        /*
+         * RX and RXC metadata FIFO memory region.
+         * 0x00: 32/64bit FIFO data,
+	 * 0x08: 32/64bit FIFO metadata,
+         * 0x10: 32/64bit packet length.
+         */
+        sc->nf10bmac_rx_mem_rid = 2;
+        sc->nf10bmac_rx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+            &sc->nf10bmac_rx_mem_rid, RF_ACTIVE);
+        if (sc->nf10bmac_rx_mem_res == NULL) {
+                device_printf(dev, "failed to map memory for RX FIFO\n");
+                error = ENXIO;
+                goto err;
+        } 
+        if (bootverbose)
+                device_printf(sc->nf10bmac_dev, "RX FIFO at mem %p-%p\n",
+                    (void *)rman_get_start(sc->nf10bmac_rx_mem_res),
+                    (void *)(rman_get_start(sc->nf10bmac_rx_mem_res) + 
+                    rman_get_size(sc->nf10bmac_rx_mem_res)));
+
+	/*
+	 * Interrupt handling registers.
+	 * 0x00: 32/64bit register to clear (and disable) the RX interrupt.
+	 * 0x08: 32/64bit register to enable or disable the RX interrupt.
+	 */
+        sc->nf10bmac_intr_rid = 3;
+        sc->nf10bmac_intr_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+            &sc->nf10bmac_intr_rid, RF_ACTIVE);
+        if (sc->nf10bmac_intr_res == NULL) {
+                device_printf(dev, "failed to map memory for INTR region\n");
+                error = ENXIO;
+                goto err;
+        } 
+        if (bootverbose)
+                device_printf(sc->nf10bmac_dev, "INTR region at mem %p-%p\n",
+                    (void *)rman_get_start(sc->nf10bmac_intr_res),
+                    (void *)(rman_get_start(sc->nf10bmac_intr_res) + 
+                    rman_get_size(sc->nf10bmac_intr_res)));
+
+	/* (Optional) RX and TX IRQ. */
+	sc->nf10bmac_rx_irq_rid = 0;
+	sc->nf10bmac_rx_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+	    &sc->nf10bmac_rx_irq_rid, RF_ACTIVE | RF_SHAREABLE);
+
+	error = nf10bmac_attach(dev);
+	if (error)
+		goto err;
+
+	return (0);
+
+err:
+	/* Cleanup. */
+	nf10bmac_detach_resources(dev);
+
+	return (error);
+}
+
+static device_method_t nf10bmac_methods_fdt[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		nf10bmac_probe_fdt),
+	DEVMETHOD(device_attach,	nf10bmac_attach_fdt),
+	DEVMETHOD(device_detach,	nf10bmac_detach_dev),
+
+	DEVMETHOD_END   
+};
+
+static driver_t nf10bmac_driver_fdt = {
+	"nf10bmac",
+	nf10bmac_methods_fdt,
+	sizeof(struct nf10bmac_softc)
+};
+
+DRIVER_MODULE(nf10bmac, simplebus, nf10bmac_driver_fdt, nf10bmac_devclass, 0,0);
+
+/* end */


Property changes on: trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h
===================================================================
--- trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h	                        (rev 0)
+++ trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h	2018-05-27 23:34:03 UTC (rev 10093)
@@ -0,0 +1,73 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Bjoern A. Zeeb
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
+ * ("MRC2"), as part of the DARPA MRC research programme.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h 270061 2014-08-16 14:30:46Z bz $
+ */
+
+#ifndef	_DEV_IF_NF10BMACREG_H
+#define	_DEV_IF_NF10BMACREG_H
+
+struct nf10bmac_softc {
+	struct ifnet		*nf10bmac_ifp;
+	struct resource		*nf10bmac_ctrl_res;
+	struct resource		*nf10bmac_tx_mem_res;
+	struct resource		*nf10bmac_rx_mem_res;
+	struct resource		*nf10bmac_intr_res;
+	struct resource		*nf10bmac_rx_irq_res;
+	void			*nf10bmac_rx_intrhand;
+	uint8_t			*nf10bmac_tx_buf;
+	device_t		nf10bmac_dev;
+	int			nf10bmac_unit;
+	int			nf10bmac_ctrl_rid;
+	int			nf10bmac_tx_mem_rid;
+	int			nf10bmac_rx_mem_rid;
+	int			nf10bmac_intr_rid;
+	int			nf10bmac_rx_irq_rid;
+	int			nf10bmac_if_flags;
+	uint32_t		nf10bmac_flags;
+#define	NF10BMAC_FLAGS_LINK		0x00000001
+	uint8_t			nf10bmac_eth_addr[ETHER_ADDR_LEN];
+#ifdef ENABLE_WATCHDOG
+	uint16_t		nf10bmac_watchdog_timer;
+	struct callout		nf10bmac_tick;
+#endif
+	struct ifmedia		nf10bmac_media; /* to fake it. */
+	struct mtx		nf10bmac_mtx;
+};
+
+int	nf10bmac_attach(device_t);
+int	nf10bmac_detach_dev(device_t);
+void	nf10bmac_detach_resources(device_t);
+
+extern devclass_t nf10bmac_devclass;
+
+#endif /* _DEV_IF_NF10BMACREG_H */
+
+/* end */


Property changes on: trunk/sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/dev/nvd/nvd.c
===================================================================
--- trunk/sys/dev/nvd/nvd.c	2018-05-27 23:32:51 UTC (rev 10092)
+++ trunk/sys/dev/nvd/nvd.c	2018-05-27 23:34:03 UTC (rev 10093)
@@ -1,5 +1,6 @@
+/* $MidnightBSD$ */
 /*-
- * Copyright (C) 2012-2013 Intel Corporation
+ * Copyright (C) 2012-2016 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/nvd/nvd.c 312406 2017-01-19 11:17:09Z mav $");
 
 #include <sys/param.h>
 #include <sys/bio.h>
@@ -32,6 +33,7 @@
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
+#include <sys/sysctl.h>
 #include <sys/systm.h>
 #include <sys/taskqueue.h>
 
@@ -47,6 +49,8 @@
 static disk_ioctl_t nvd_ioctl;
 static disk_strategy_t nvd_strategy;
 
+static void nvd_done(void *arg, const struct nvme_completion *cpl);
+
 static void *nvd_new_disk(struct nvme_namespace *ns, void *ctrlr);
 static void destroy_geom_disk(struct nvd_disk *ndisk);
 
@@ -71,6 +75,7 @@
 	struct nvme_namespace	*ns;
 
 	uint32_t		cur_depth;
+	uint32_t		ordered_in_flight;
 
 	TAILQ_ENTRY(nvd_disk)	global_tailq;
 	TAILQ_ENTRY(nvd_disk)	ctrlr_tailq;
@@ -85,6 +90,19 @@
 static TAILQ_HEAD(, nvd_controller)	ctrlr_head;
 static TAILQ_HEAD(disk_list, nvd_disk)	disk_head;
 
+static SYSCTL_NODE(_hw, OID_AUTO, nvd, CTLFLAG_RD, 0, "nvd driver parameters");
+/*
+ * The NVMe specification does not define a maximum or optimal delete size, so
+ *  technically max delete size is min(full size of the namespace, 2^32 - 1
+ *  LBAs).  A single delete for a multi-TB NVMe namespace though may take much
+ *  longer to complete than the nvme(4) I/O timeout period.  So choose a sensible
+ *  default here that is still suitably large to minimize the number of overall
+ *  delete operations.
+ */
+static uint64_t nvd_delete_max = (1024 * 1024 * 1024);  /* 1GB */
+SYSCTL_UQUAD(_hw_nvd, OID_AUTO, delete_max, CTLFLAG_RDTUN, &nvd_delete_max, 0,
+	     "nvd maximum BIO_DELETE size in bytes");
+
 static int nvd_modevent(module_t mod, int type, void *arg)
 {
 	int error = 0;
@@ -148,6 +166,28 @@
 	nvme_unregister_consumer(consumer_handle);
 }
 
+static int
+nvd_bio_submit(struct nvd_disk *ndisk, struct bio *bp)
+{
+	int err;
+
+	bp->bio_driver1 = NULL;
+	atomic_add_int(&ndisk->cur_depth, 1);
+	err = nvme_ns_bio_process(ndisk->ns, bp, nvd_done);
+	if (err) {
+		atomic_add_int(&ndisk->cur_depth, -1);
+		if (__predict_false(bp->bio_flags & BIO_ORDERED))
+			atomic_add_int(&ndisk->ordered_in_flight, -1);
+		bp->bio_error = err;
+		bp->bio_flags |= BIO_ERROR;
+		bp->bio_resid = bp->bio_bcount;
+		biodone(bp);
+		return (-1);
+	}
+
+	return (0);
+}
+
 static void
 nvd_strategy(struct bio *bp)
 {
@@ -155,6 +195,18 @@
 
 	ndisk = (struct nvd_disk *)bp->bio_disk->d_drv1;
 
+	if (__predict_false(bp->bio_flags & BIO_ORDERED))
+		atomic_add_int(&ndisk->ordered_in_flight, 1);
+
+	if (__predict_true(ndisk->ordered_in_flight == 0)) {
+		nvd_bio_submit(ndisk, bp);
+		return;
+	}
+
+	/*
+	 * There are ordered bios in flight, so we need to submit
+	 *  bios through the task queue to enforce ordering.
+	 */
 	mtx_lock(&ndisk->bioqlock);
 	bioq_insert_tail(&ndisk->bioq, bp);
 	mtx_unlock(&ndisk->bioqlock);
@@ -186,6 +238,8 @@
 	ndisk = bp->bio_disk->d_drv1;
 
 	atomic_add_int(&ndisk->cur_depth, -1);
+	if (__predict_false(bp->bio_flags & BIO_ORDERED))
+		atomic_add_int(&ndisk->ordered_in_flight, -1);
 
 	biodone(bp);
 }
@@ -195,7 +249,6 @@
 {
 	struct nvd_disk *ndisk = arg;
 	struct bio *bp;
-	int err;
 
 	for (;;) {
 		mtx_lock(&ndisk->bioqlock);
@@ -204,32 +257,10 @@
 		if (bp == NULL)
 			break;
 
-#ifdef BIO_ORDERED
-		/*
-		 * BIO_ORDERED flag dictates that all outstanding bios
-		 *  must be completed before processing the bio with
-		 *  BIO_ORDERED flag set.
-		 */
-		if (bp->bio_flags & BIO_ORDERED) {
-			while (ndisk->cur_depth > 0) {
-				pause("nvd flush", 1);
-			}
+		if (nvd_bio_submit(ndisk, bp) != 0) {
+			continue;
 		}
-#endif
 
-		bp->bio_driver1 = NULL;
-		atomic_add_int(&ndisk->cur_depth, 1);
-
-		err = nvme_ns_bio_process(ndisk->ns, bp, nvd_done);
-
-		if (err) {
-			atomic_add_int(&ndisk->cur_depth, -1);
-			bp->bio_error = err;
-			bp->bio_flags |= BIO_ERROR;
-			bp->bio_resid = bp->bio_bcount;
-			biodone(bp);
-		}
-
 #ifdef BIO_ORDERED
 		/*
 		 * BIO_ORDERED flag dictates that the bio with BIO_ORDERED
@@ -278,6 +309,10 @@
 	disk->d_maxsize = nvme_ns_get_max_io_xfer_size(ns);
 	disk->d_sectorsize = nvme_ns_get_sector_size(ns);
 	disk->d_mediasize = (off_t)nvme_ns_get_size(ns);
+	disk->d_delmaxsize = (off_t)nvme_ns_get_size(ns);
+	if (disk->d_delmaxsize > nvd_delete_max)
+		disk->d_delmaxsize = nvd_delete_max;
+	disk->d_stripesize = nvme_ns_get_stripesize(ns);
 
 	if (TAILQ_EMPTY(&disk_head))
 		disk->d_unit = 0;
@@ -285,7 +320,7 @@
 		disk->d_unit =
 		    TAILQ_LAST(&disk_head, disk_list)->disk->d_unit + 1;
 
-	disk->d_flags = 0;
+	disk->d_flags = DISKFLAG_DIRECT_COMPLETION;
 
 	if (nvme_ns_get_flags(ns) & NVME_NS_DEALLOCATE_SUPPORTED)
 		disk->d_flags |= DISKFLAG_CANDELETE;
@@ -304,17 +339,16 @@
 	 */
 	nvme_strvis(disk->d_ident, nvme_ns_get_serial_number(ns),
 	    sizeof(disk->d_ident), NVME_SERIAL_NUMBER_LENGTH);
-
 	nvme_strvis(descr, nvme_ns_get_model_number(ns), sizeof(descr),
 	    NVME_MODEL_NUMBER_LENGTH);
-
-#if __FreeBSD_version >= 900034
 	strlcpy(disk->d_descr, descr, sizeof(descr));
-#endif
 
+	disk->d_rotation_rate = DISK_RR_NON_ROTATING;
+
 	ndisk->ns = ns;
 	ndisk->disk = disk;
 	ndisk->cur_depth = 0;
+	ndisk->ordered_in_flight = 0;
 
 	mtx_init(&ndisk->bioqlock, "NVD bioq lock", NULL, MTX_DEF);
 	bioq_init(&ndisk->bioq);



More information about the Midnightbsd-cvs mailing list