Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 May 2017 20:55:11 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r318197 - in stable/11: . etc/mtree include sys/arm/allwinner sys/arm/amlogic/aml8726 sys/arm/at91 sys/arm/broadcom/bcm2835 sys/arm/lpc sys/arm/nvidia sys/arm/ti sys/conf sys/dev/mmc sy...
Message-ID:  <201705112055.v4BKtBKp032320@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marius
Date: Thu May 11 20:55:11 2017
New Revision: 318197
URL: https://svnweb.freebsd.org/changeset/base/318197

Log:
  MFC: r312939, r313250, r314811 (partial), r314887 (partial), r315760,
       r315845, 315430, r317981, r315466
  
  o Fix some overly long lines, whitespace and other bugs according to
    style(9) as well as spelling etc. in mmc(4), mmcsd(4) and sdhci(4).
  
  o In the mmc(4) bridges and sdhci(4) (bus) front-ends:
    - Remove redundant assignments of the default bus_generic_print_child
      device method,
    - use DEVMETHOD_END,
    - use NULL instead of 0 for pointers.
  
  o Trim/adjust includes.
  
  o Add and use a MMC_DECLARE_BRIDGE macro for declaring mmc(4) bridges
    as kernel drivers and their dependency onto mmc(4).
  
  o Add support for eMMC "partitions". Besides the user data area, i. e.
    the default partition, eMMC v4.41 and later devices can additionally
    provide up to:
    1 enhanced user data area partition
    2 boot partitions
    1 RPMB (Replay Protected Memory Block) partition
    4 general purpose partitions (optionally with a enhanced or extended
      attribute)
  
    Besides simply subdividing eMMC devices, some Intel NUCs having UEFI
    code in the boot partitions etc., another use case for the partition
    support is the activation of pseudo-SLC mode, which manufacturers of
    eMMC chips typically associate with the enhanced user data area and/
    or the enhanced attribute of general purpose partitions.
  
    CAVEAT EMPTOR: Partitioning eMMC devices is a one-time operation.
  
  o Now that properly issuing CMD6 is crucial (so data isn't written to
    the wrong partition for example), make a step into the direction of
    correctly handling the timeout for these commands in the MMC layer.
    Also, do a SEND_STATUS when CMD6 is invoked with an R1B response as
    recommended by relevant specifications.
  
  o Add an IOCTL interface to mmcsd(4); this is sufficiently compatible
    with Linux so that the GNU mmc-utils can be ported to and used with
    FreeBSD (note that due to the remaining deficiencies outlined above
    SANITIZE operations issued by/with `mmc` currently most likely will
    fail). These latter have been added to ports as sysutils/mmc-utils.
    Among others, the `mmc` tool of mmc-utils allows for partitioning
    eMMC devices (tested working).
  
  o For devices following the eMMC specification v4.41 or later, year 0
    is 2013 rather than 1997; so correct this for assembling the device
    ID string properly.
  
  o Let mmcsd.ko depend on mmc.ko. Additionally, bump MMC_VERSION as at
    least for some of the above a matching pair is required.
  
  o In the ACPI front-end of sdhci(4) describe the Intel eMMC and SDXC
    controllers as such in order to match the PCI one.
    Additionally, in the entry for the 80860F14 SDXC controller remove
    the eMMC-only SDHCI_QUIRK_INTEL_POWER_UP_RESET.

Added:
  stable/11/sys/dev/mmc/mmc_ioctl.h
     - copied unchanged from r315430, head/sys/dev/mmc/mmc_ioctl.h
  stable/11/sys/dev/mmc/mmc_private.h
     - copied unchanged from r315430, head/sys/dev/mmc/mmc_private.h
  stable/11/sys/dev/mmc/mmc_subr.c
     - copied unchanged from r315430, head/sys/dev/mmc/mmc_subr.c
  stable/11/sys/dev/mmc/mmc_subr.h
     - copied unchanged from r315430, head/sys/dev/mmc/mmc_subr.h
Modified:
  stable/11/UPDATING
  stable/11/etc/mtree/BSD.include.dist
  stable/11/include/Makefile
  stable/11/sys/arm/allwinner/a10_mmc.c
  stable/11/sys/arm/amlogic/aml8726/aml8726_mmc.c
  stable/11/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c
  stable/11/sys/arm/at91/at91_mci.c
  stable/11/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
  stable/11/sys/arm/lpc/lpc_mmc.c
  stable/11/sys/arm/nvidia/tegra_sdhci.c
  stable/11/sys/arm/ti/ti_sdhci.c
  stable/11/sys/conf/files
  stable/11/sys/dev/mmc/bridge.h
  stable/11/sys/dev/mmc/host/dwmmc.c
  stable/11/sys/dev/mmc/mmc.c
  stable/11/sys/dev/mmc/mmcbr_if.m
  stable/11/sys/dev/mmc/mmcbrvar.h
  stable/11/sys/dev/mmc/mmcreg.h
  stable/11/sys/dev/mmc/mmcsd.c
  stable/11/sys/dev/mmc/mmcvar.h
  stable/11/sys/dev/sdhci/fsl_sdhci.c
  stable/11/sys/dev/sdhci/sdhci.c
  stable/11/sys/dev/sdhci/sdhci.h
  stable/11/sys/dev/sdhci/sdhci_acpi.c
  stable/11/sys/dev/sdhci/sdhci_fdt.c
  stable/11/sys/dev/sdhci/sdhci_if.m
  stable/11/sys/dev/sdhci/sdhci_pci.c
  stable/11/sys/modules/mmc/Makefile
  stable/11/sys/sys/param.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/UPDATING
==============================================================================
--- stable/11/UPDATING	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/UPDATING	Thu May 11 20:55:11 2017	(r318197)
@@ -16,6 +16,13 @@ from older versions of FreeBSD, try WITH
 the tip of head, and then rebuild without this option. The bootstrap process
 from older version of current across the gcc/clang cutover is a bit fragile.
 
+20170511:
+	The mmcsd.ko module now additionally depends on geom_flashmap.ko.
+	Also, mmc.ko and mmcsd.ko need to be a matching pair built from the
+	same source (previously, the dependency of mmcsd.ko on mmc.ko was
+	missing, but mmcsd.ko now will refuse to load if it is incompatible
+	with mmc.ko).
+
 20170414:
 	Binds and sends to the loopback addresses, IPv6 and IPv4, will now
 	use any explicitly assigned loopback address available in the jail

Modified: stable/11/etc/mtree/BSD.include.dist
==============================================================================
--- stable/11/etc/mtree/BSD.include.dist	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/etc/mtree/BSD.include.dist	Thu May 11 20:55:11 2017	(r318197)
@@ -130,6 +130,8 @@
         ..
         mfi
         ..
+        mmc
+        ..
         mpt
             mpilib
             ..

Modified: stable/11/include/Makefile
==============================================================================
--- stable/11/include/Makefile	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/include/Makefile	Thu May 11 20:55:11 2017	(r318197)
@@ -45,7 +45,7 @@ LDIRS=	bsm cam geom net net80211 netgrap
 LSUBDIRS=	cam/ata cam/nvme cam/scsi \
 	dev/acpica dev/agp dev/an dev/bktr dev/ciss dev/filemon dev/firewire \
 	dev/hwpmc dev/hyperv \
-	dev/ic dev/iicbus dev/io dev/lmc dev/mfi dev/nvme \
+	dev/ic dev/iicbus dev/io dev/lmc dev/mfi dev/mmc dev/nvme \
 	dev/ofw dev/pbio dev/pci ${_dev_powermac_nvram} dev/ppbus dev/smbus \
 	dev/speaker dev/utopia dev/vkbd dev/wi \
 	fs/devfs fs/fdescfs fs/msdosfs fs/nandfs fs/nfs fs/nullfs \

Modified: stable/11/sys/arm/allwinner/a10_mmc.c
==============================================================================
--- stable/11/sys/arm/allwinner/a10_mmc.c	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/sys/arm/allwinner/a10_mmc.c	Thu May 11 20:55:11 2017	(r318197)
@@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$");
 #include <dev/ofw/ofw_bus_subr.h>
 
 #include <dev/mmc/bridge.h>
-#include <dev/mmc/mmcreg.h>
 #include <dev/mmc/mmcbrvar.h>
 
 #include <arm/allwinner/a10_mmc.h>
@@ -897,7 +896,6 @@ static device_method_t a10_mmc_methods[]
 	/* Bus interface */
 	DEVMETHOD(bus_read_ivar,	a10_mmc_read_ivar),
 	DEVMETHOD(bus_write_ivar,	a10_mmc_write_ivar),
-	DEVMETHOD(bus_print_child,	bus_generic_print_child),
 
 	/* MMC bridge interface */
 	DEVMETHOD(mmcbr_update_ios,	a10_mmc_update_ios),
@@ -917,6 +915,6 @@ static driver_t a10_mmc_driver = {
 	sizeof(struct a10_mmc_softc),
 };
 
-DRIVER_MODULE(a10_mmc, simplebus, a10_mmc_driver, a10_mmc_devclass, 0, 0);
-DRIVER_MODULE(mmc, a10_mmc, mmc_driver, mmc_devclass, NULL, NULL);
-MODULE_DEPEND(a10_mmc, mmc, 1, 1, 1);
+DRIVER_MODULE(a10_mmc, simplebus, a10_mmc_driver, a10_mmc_devclass, NULL,
+    NULL);
+MMC_DECLARE_BRIDGE(a10_mmc);

Modified: stable/11/sys/arm/amlogic/aml8726/aml8726_mmc.c
==============================================================================
--- stable/11/sys/arm/amlogic/aml8726/aml8726_mmc.c	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/sys/arm/amlogic/aml8726/aml8726_mmc.c	Thu May 11 20:55:11 2017	(r318197)
@@ -33,7 +33,6 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/conf.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
@@ -52,7 +51,6 @@ __FBSDID("$FreeBSD$");
 #include <dev/ofw/ofw_bus_subr.h>
 
 #include <dev/mmc/bridge.h>
-#include <dev/mmc/mmcreg.h>
 #include <dev/mmc/mmcbrvar.h>
 
 #include <arm/amlogic/aml8726/aml8726_mmc.h>
@@ -1096,7 +1094,6 @@ static driver_t aml8726_mmc_driver = {
 static devclass_t aml8726_mmc_devclass;
 
 DRIVER_MODULE(aml8726_mmc, simplebus, aml8726_mmc_driver,
-    aml8726_mmc_devclass, 0, 0);
+    aml8726_mmc_devclass, NULL, NULL);
 MODULE_DEPEND(aml8726_mmc, aml8726_gpio, 1, 1, 1);
-DRIVER_MODULE(mmc, aml8726_mmc, mmc_driver, mmc_devclass, NULL, NULL);
-MODULE_DEPEND(aml8726_mmc, mmc, 1, 1, 1);
+MMC_DECLARE_BRIDGE(aml8726_mmc);

Modified: stable/11/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c
==============================================================================
--- stable/11/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c	Thu May 11 20:55:11 2017	(r318197)
@@ -33,7 +33,6 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/conf.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
@@ -1375,7 +1374,6 @@ static driver_t aml8726_sdxc_driver = {
 static devclass_t aml8726_sdxc_devclass;
 
 DRIVER_MODULE(aml8726_sdxc, simplebus, aml8726_sdxc_driver,
-    aml8726_sdxc_devclass, 0, 0);
+    aml8726_sdxc_devclass, NULL, NULL);
 MODULE_DEPEND(aml8726_sdxc, aml8726_gpio, 1, 1, 1);
-DRIVER_MODULE(mmc, aml8726_sdxc, mmc_driver, mmc_devclass, NULL, NULL);
-MODULE_DEPEND(aml8726_sdxc, mmc, 1, 1, 1);
+MMC_DECLARE_BRIDGE(aml8726_sdxc);

Modified: stable/11/sys/arm/at91/at91_mci.c
==============================================================================
--- stable/11/sys/arm/at91/at91_mci.c	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/sys/arm/at91/at91_mci.c	Thu May 11 20:55:11 2017	(r318197)
@@ -32,23 +32,16 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/bio.h>
 #include <sys/bus.h>
-#include <sys/conf.h>
 #include <sys/endian.h>
 #include <sys/kernel.h>
-#include <sys/kthread.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/mutex.h>
-#include <sys/queue.h>
 #include <sys/resource.h>
 #include <sys/rman.h>
 #include <sys/sysctl.h>
-#include <sys/time.h>
-#include <sys/timetc.h>
-#include <sys/watchdog.h>
 
 #include <machine/bus.h>
 #include <machine/resource.h>
@@ -59,7 +52,6 @@ __FBSDID("$FreeBSD$");
 #include <arm/at91/at91_pdcreg.h>
 
 #include <dev/mmc/bridge.h>
-#include <dev/mmc/mmcreg.h>
 #include <dev/mmc/mmcbrvar.h>
 
 #ifdef FDT
@@ -1409,5 +1401,5 @@ DRIVER_MODULE(at91_mci, simplebus, at91_
 DRIVER_MODULE(at91_mci, atmelarm, at91_mci_driver, at91_mci_devclass, NULL,
     NULL);
 #endif
-DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, NULL, NULL);
-MODULE_DEPEND(at91_mci, mmc, 1, 1, 1);
+
+MMC_DECLARE_BRIDGE(at91_mci);

Modified: stable/11/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
==============================================================================
--- stable/11/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c	Thu May 11 20:55:11 2017	(r318197)
@@ -47,9 +47,10 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/mmc/bridge.h>
 #include <dev/mmc/mmcreg.h>
-#include <dev/mmc/mmcbrvar.h>
 
 #include <dev/sdhci/sdhci.h>
+
+#include "mmcbr_if.h"
 #include "sdhci_if.h"
 
 #include "bcm2835_dma.h"
@@ -643,7 +644,6 @@ static device_method_t bcm_sdhci_methods
 	/* Bus interface */
 	DEVMETHOD(bus_read_ivar,	sdhci_generic_read_ivar),
 	DEVMETHOD(bus_write_ivar,	sdhci_generic_write_ivar),
-	DEVMETHOD(bus_print_child,	bus_generic_print_child),
 
 	/* MMC bridge interface */
 	DEVMETHOD(mmcbr_update_ios,	sdhci_generic_update_ios),
@@ -666,7 +666,7 @@ static device_method_t bcm_sdhci_methods
 	DEVMETHOD(sdhci_write_4,	bcm_sdhci_write_4),
 	DEVMETHOD(sdhci_write_multi_4,	bcm_sdhci_write_multi_4),
 
-	{ 0, 0 }
+	DEVMETHOD_END
 };
 
 static devclass_t bcm_sdhci_devclass;
@@ -677,7 +677,7 @@ static driver_t bcm_sdhci_driver = {
 	sizeof(struct bcm_sdhci_softc),
 };
 
-DRIVER_MODULE(sdhci_bcm, simplebus, bcm_sdhci_driver, bcm_sdhci_devclass, 0, 0);
+DRIVER_MODULE(sdhci_bcm, simplebus, bcm_sdhci_driver, bcm_sdhci_devclass,
+    NULL, NULL);
 MODULE_DEPEND(sdhci_bcm, sdhci, 1, 1, 1);
-DRIVER_MODULE(mmc, sdhci_bcm, mmc_driver, mmc_devclass, NULL, NULL);
-MODULE_DEPEND(sdhci_bcm, mmc, 1, 1, 1);
+MMC_DECLARE_BRIDGE(sdhci_bcm);

Modified: stable/11/sys/arm/lpc/lpc_mmc.c
==============================================================================
--- stable/11/sys/arm/lpc/lpc_mmc.c	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/sys/arm/lpc/lpc_mmc.c	Thu May 11 20:55:11 2017	(r318197)
@@ -29,24 +29,14 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/bio.h>
 #include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/endian.h>
 #include <sys/kernel.h>
-#include <sys/kthread.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/mutex.h>
-#include <sys/queue.h>
 #include <sys/resource.h>
 #include <sys/rman.h>
-#include <sys/time.h>
-#include <sys/timetc.h>
-#include <sys/watchdog.h>
-
-#include <sys/kdb.h>
 
 #include <machine/bus.h>
 #include <machine/resource.h>
@@ -56,7 +46,6 @@ __FBSDID("$FreeBSD$");
 #include <dev/ofw/ofw_bus_subr.h>
 
 #include <dev/mmc/bridge.h>
-#include <dev/mmc/mmcreg.h>
 #include <dev/mmc/mmcbrvar.h>
 
 #include <arm/lpc/lpcreg.h>
@@ -752,7 +741,6 @@ static device_method_t lpc_mmc_methods[]
 	/* Bus interface */
 	DEVMETHOD(bus_read_ivar,	lpc_mmc_read_ivar),
 	DEVMETHOD(bus_write_ivar,	lpc_mmc_write_ivar),
-	DEVMETHOD(bus_print_child,	bus_generic_print_child),
 
 	/* MMC bridge interface */
 	DEVMETHOD(mmcbr_update_ios,	lpc_mmc_update_ios),
@@ -761,7 +749,7 @@ static device_method_t lpc_mmc_methods[]
 	DEVMETHOD(mmcbr_acquire_host,	lpc_mmc_acquire_host),
 	DEVMETHOD(mmcbr_release_host,	lpc_mmc_release_host),
 
-	{ 0, 0 }
+	DEVMETHOD_END
 };
 
 static devclass_t lpc_mmc_devclass;
@@ -772,6 +760,5 @@ static driver_t lpc_mmc_driver = {
 	sizeof(struct lpc_mmc_softc),
 };
 
-DRIVER_MODULE(lpcmmc, simplebus, lpc_mmc_driver, lpc_mmc_devclass, 0, 0);
-DRIVER_MODULE(mmc, lpcmmc, mmc_driver, mmc_devclass, NULL, NULL);
-MODULE_DEPEND(lpcmmc, mmc, 1, 1, 1);
+DRIVER_MODULE(lpcmmc, simplebus, lpc_mmc_driver, lpc_mmc_devclass, NULL, NULL);
+MMC_DECLARE_BRIDGE(lpcmmc);

Modified: stable/11/sys/arm/nvidia/tegra_sdhci.c
==============================================================================
--- stable/11/sys/arm/nvidia/tegra_sdhci.c	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/sys/arm/nvidia/tegra_sdhci.c	Thu May 11 20:55:11 2017	(r318197)
@@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/types.h>
 #include <sys/bus.h>
-#include <sys/callout.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
@@ -45,7 +44,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/rman.h>
 #include <sys/sysctl.h>
 #include <sys/taskqueue.h>
-#include <sys/time.h>
 
 #include <machine/bus.h>
 #include <machine/resource.h>
@@ -55,7 +53,6 @@ __FBSDID("$FreeBSD$");
 #include <dev/extres/hwreset/hwreset.h>
 #include <dev/gpio/gpiobusvar.h>
 #include <dev/mmc/bridge.h>
-#include <dev/mmc/mmcreg.h>
 #include <dev/mmc/mmcbrvar.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
@@ -457,5 +454,4 @@ static DEFINE_CLASS_0(sdhci, tegra_sdhci
 DRIVER_MODULE(sdhci_tegra, simplebus, tegra_sdhci_driver, tegra_sdhci_devclass,
     NULL, NULL);
 MODULE_DEPEND(sdhci_tegra, sdhci, 1, 1, 1);
-DRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, NULL, NULL);
-MODULE_DEPEND(sdhci_tegra, mmc, 1, 1, 1);
+MMC_DECLARE_BRIDGE(sdhci);

Modified: stable/11/sys/arm/ti/ti_sdhci.c
==============================================================================
--- stable/11/sys/arm/ti/ti_sdhci.c	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/sys/arm/ti/ti_sdhci.c	Thu May 11 20:55:11 2017	(r318197)
@@ -606,6 +606,11 @@ ti_sdhci_attach(device_t dev)
 	 * before waiting to see them de-asserted.
 	 */
 	sc->slot.quirks |= SDHCI_QUIRK_WAITFOR_RESET_ASSERTED;
+	
+	/*
+	 * The controller waits for busy responses.
+	 */
+	sc->slot.quirks |= SDHCI_QUIRK_WAIT_WHILE_BUSY;
 
 	/*
 	 * DMA is not really broken, I just haven't implemented it yet.
@@ -692,7 +697,6 @@ static device_method_t ti_sdhci_methods[
 	/* Bus interface */
 	DEVMETHOD(bus_read_ivar,	sdhci_generic_read_ivar),
 	DEVMETHOD(bus_write_ivar,	sdhci_generic_write_ivar),
-	DEVMETHOD(bus_print_child,	bus_generic_print_child),
 
 	/* MMC bridge interface */
 	DEVMETHOD(mmcbr_update_ios,	ti_sdhci_update_ios),
@@ -723,7 +727,7 @@ static driver_t ti_sdhci_driver = {
 	sizeof(struct ti_sdhci_softc),
 };
 
-DRIVER_MODULE(sdhci_ti, simplebus, ti_sdhci_driver, ti_sdhci_devclass, 0, 0);
+DRIVER_MODULE(sdhci_ti, simplebus, ti_sdhci_driver, ti_sdhci_devclass, NULL,
+    NULL);
 MODULE_DEPEND(sdhci_ti, sdhci, 1, 1, 1);
-DRIVER_MODULE(mmc, sdhci_ti, mmc_driver, mmc_devclass, NULL, NULL);
-MODULE_DEPEND(sdhci_ti, mmc, 1, 1, 1);
+MMC_DECLARE_BRIDGE(sdhci_ti);

Modified: stable/11/sys/conf/files
==============================================================================
--- stable/11/sys/conf/files	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/sys/conf/files	Thu May 11 20:55:11 2017	(r318197)
@@ -2169,6 +2169,7 @@ dev/mlx/mlx.c			optional mlx
 dev/mlx/mlx_disk.c		optional mlx
 dev/mlx/mlx_pci.c		optional mlx pci
 dev/mly/mly.c			optional mly
+dev/mmc/mmc_subr.c		optional mmc | mmcsd
 dev/mmc/mmc.c			optional mmc
 dev/mmc/mmcbr_if.m		standard
 dev/mmc/mmcbus_if.m		standard
@@ -3209,7 +3210,7 @@ geom/geom_disk.c		standard
 geom/geom_dump.c		standard
 geom/geom_event.c		standard
 geom/geom_fox.c			optional geom_fox
-geom/geom_flashmap.c		optional fdt cfi | fdt nand | fdt mx25l
+geom/geom_flashmap.c		optional fdt cfi | fdt nand | fdt mx25l | mmcsd
 geom/geom_io.c			standard
 geom/geom_kern.c		standard
 geom/geom_map.c			optional geom_map

Modified: stable/11/sys/dev/mmc/bridge.h
==============================================================================
--- stable/11/sys/dev/mmc/bridge.h	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/sys/dev/mmc/bridge.h	Thu May 11 20:55:11 2017	(r318197)
@@ -52,7 +52,7 @@
  */
 
 #ifndef DEV_MMC_BRIDGE_H
-#define DEV_MMC_BRIDGE_H
+#define	DEV_MMC_BRIDGE_H
 
 #include <sys/bus.h>
 
@@ -60,7 +60,7 @@
  * This file defines interfaces for the mmc bridge.  The names chosen
  * are similar to or the same as the names used in Linux to allow for
  * easy porting of what Linux calls mmc host drivers.  I use the
- * FreeBSD terminology of bridge and bus for consistancy with other
+ * FreeBSD terminology of bridge and bus for consistency with other
  * drivers in the system.  This file corresponds roughly to the Linux
  * linux/mmc/host.h file.
  *
@@ -73,10 +73,9 @@
  * to be added to the mmcbus file).
  *
  * Attached to the mmc bridge is an mmcbus.  The mmcbus is described
- * in dev/mmc/bus.h.
+ * in dev/mmc/mmcbus_if.m.
  */
 
-
 /*
  * mmc_ios is a structure that is used to store the state of the mmc/sd
  * bus configuration.  This include the bus' clock speed, its voltage,
@@ -112,7 +111,7 @@ enum mmc_bus_timing {
 
 struct mmc_ios {
 	uint32_t	clock;	/* Speed of the clock in Hz to move data */
-	enum mmc_vdd	vdd;	/* Voltage to apply to the power pins/ */
+	enum mmc_vdd	vdd;	/* Voltage to apply to the power pins */
 	enum mmc_bus_mode bus_mode;
 	enum mmc_chip_select chip_select;
 	enum mmc_bus_width bus_width;
@@ -130,9 +129,11 @@ struct mmc_host {
 	uint32_t host_ocr;
 	uint32_t ocr;
 	uint32_t caps;
-#define MMC_CAP_4_BIT_DATA	(1 << 0) /* Can do 4-bit data transfers */
-#define MMC_CAP_8_BIT_DATA	(1 << 1) /* Can do 8-bit data transfers */
-#define MMC_CAP_HSPEED		(1 << 2) /* Can do High Speed transfers */
+#define	MMC_CAP_4_BIT_DATA	(1 <<  0) /* Can do 4-bit data transfers */
+#define	MMC_CAP_8_BIT_DATA	(1 <<  1) /* Can do 8-bit data transfers */
+#define	MMC_CAP_HSPEED		(1 <<  2) /* Can do High Speed transfers */
+#define	MMC_CAP_BOOT_NOACC	(1 <<  4) /* Cannot access boot partitions */
+#define	MMC_CAP_WAIT_WHILE_BUSY	(1 <<  5) /* Host waits for busy responses */
 	enum mmc_card_mode mode;
 	struct mmc_ios ios;	/* Current state of the host */
 };
@@ -140,4 +141,12 @@ struct mmc_host {
 extern driver_t   mmc_driver;
 extern devclass_t mmc_devclass;
 
+#define	MMC_VERSION	2
+
+#define	MMC_DECLARE_BRIDGE(name)					\
+    DRIVER_MODULE(mmc, name, mmc_driver, mmc_devclass, NULL, NULL);	\
+    MODULE_DEPEND(name, mmc, MMC_VERSION, MMC_VERSION, MMC_VERSION);
+#define	MMC_DEPEND(name)						\
+    MODULE_DEPEND(name, mmc, MMC_VERSION, MMC_VERSION, MMC_VERSION);
+
 #endif /* DEV_MMC_BRIDGE_H */

Modified: stable/11/sys/dev/mmc/host/dwmmc.c
==============================================================================
--- stable/11/sys/dev/mmc/host/dwmmc.c	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/sys/dev/mmc/host/dwmmc.c	Thu May 11 20:55:11 2017	(r318197)
@@ -43,11 +43,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/module.h>
 #include <sys/malloc.h>
 #include <sys/rman.h>
-#include <sys/timeet.h>
-#include <sys/timetc.h>
 
 #include <dev/mmc/bridge.h>
-#include <dev/mmc/mmcreg.h>
 #include <dev/mmc/mmcbrvar.h>
 
 #include <dev/fdt/fdt_common.h>
@@ -1182,7 +1179,6 @@ driver_t dwmmc_driver = {
 
 static devclass_t dwmmc_devclass;
 
-DRIVER_MODULE(dwmmc, simplebus, dwmmc_driver, dwmmc_devclass, 0, 0);
-DRIVER_MODULE(dwmmc, ofwbus, dwmmc_driver, dwmmc_devclass, 0, 0);
-DRIVER_MODULE(mmc, dwmmc, mmc_driver, mmc_devclass, NULL, NULL);
-MODULE_DEPEND(dwmmc, mmc, 1, 1, 1);
+DRIVER_MODULE(dwmmc, simplebus, dwmmc_driver, dwmmc_devclass, NULL, NULL);
+DRIVER_MODULE(dwmmc, ofwbus, dwmmc_driver, dwmmc_devclass, NULL, NULL);
+MMC_DECLARE_BRIDGE(dwmmc);

Modified: stable/11/sys/dev/mmc/mmc.c
==============================================================================
--- stable/11/sys/dev/mmc/mmc.c	Thu May 11 20:30:44 2017	(r318196)
+++ stable/11/sys/dev/mmc/mmc.c	Thu May 11 20:55:11 2017	(r318197)
@@ -65,25 +65,16 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysctl.h>
 #include <sys/time.h>
 
+#include <dev/mmc/bridge.h>
+#include <dev/mmc/mmc_private.h>
+#include <dev/mmc/mmc_subr.h>
 #include <dev/mmc/mmcreg.h>
 #include <dev/mmc/mmcbrvar.h>
 #include <dev/mmc/mmcvar.h>
+
 #include "mmcbr_if.h"
 #include "mmcbus_if.h"
 
-struct mmc_softc {
-	device_t dev;
-	struct mtx sc_mtx;
-	struct intr_config_hook config_intrhook;
-	device_t owner;
-	uint32_t last_rca;
-	int	 squelched; /* suppress reporting of (expected) errors */
-	int	 log_count;
-	struct timeval log_time;
-};
-
-#define	LOG_PPS		5 /* Log no more than 5 errors per second. */
-
 /*
  * Per-card data
  */
@@ -91,7 +82,7 @@ struct mmc_ivars {
 	uint32_t raw_cid[4];	/* Raw bits of the CID */
 	uint32_t raw_csd[4];	/* Raw bits of the CSD */
 	uint32_t raw_scr[2];	/* Raw bits of the SCR */
-	uint8_t raw_ext_csd[512];	/* Raw bits of the EXT_CSD */
+	uint8_t raw_ext_csd[MMC_EXTCSD_SIZE]; /* Raw bits of the EXT_CSD */
 	uint32_t raw_sd_status[16];	/* Raw bits of the SD_STATUS */
 	uint16_t rca;
 	enum mmc_card_mode mode;
@@ -107,18 +98,20 @@ struct mmc_ivars {
 	uint32_t tran_speed;	/* Max speed in normal mode */
 	uint32_t hs_tran_speed;	/* Max speed in high speed mode */
 	uint32_t erase_sector;	/* Card native erase sector size */
+	uint32_t cmd6_time;	/* Generic switch timeout [us] */
 	char card_id_string[64];/* Formatted CID info (serial, MFG, etc) */
 	char card_sn_string[16];/* Formatted serial # for disk->d_ident */
 };
 
-#define CMD_RETRIES	3
+#define	CMD_RETRIES	3
 
 #define	CARD_ID_FREQUENCY 400000 /* Spec requires 400kHz max during ID phase. */
 
 static SYSCTL_NODE(_hw, OID_AUTO, mmc, CTLFLAG_RD, NULL, "mmc driver");
 
 static int mmc_debug;
-SYSCTL_INT(_hw_mmc, OID_AUTO, debug, CTLFLAG_RWTUN, &mmc_debug, 0, "Debug level");
+SYSCTL_INT(_hw_mmc, OID_AUTO, debug, CTLFLAG_RWTUN, &mmc_debug, 0,
+    "Debug level");
 
 /* bus entry points */
 static int mmc_acquire_bus(device_t busdev, device_t dev);
@@ -137,14 +130,14 @@ static int mmc_wait_for_request(device_t
 static int mmc_write_ivar(device_t bus, device_t child, int which,
     uintptr_t value);
 
-#define MMC_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	MMC_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
 #define	MMC_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
-#define MMC_LOCK_INIT(_sc)					\
-	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev),	\
+#define	MMC_LOCK_INIT(_sc)						\
+	mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->dev),	\
 	    "mmc", MTX_DEF)
-#define MMC_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
-#define MMC_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
-#define MMC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+#define	MMC_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_mtx);
+#define	MMC_ASSERT_LOCKED(_sc)	mtx_assert(&(_sc)->sc_mtx, MA_OWNED);
+#define	MMC_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED);
 
 static int mmc_all_send_cid(struct mmc_softc *sc, uint32_t *rawcid);
 static void mmc_app_decode_scr(uint32_t *raw_scr, struct mmc_scr *scr);
@@ -155,7 +148,8 @@ static int mmc_app_sd_status(struct mmc_
 static int mmc_app_send_scr(struct mmc_softc *sc, uint16_t rca,
     uint32_t *rawscr);
 static int mmc_calculate_clock(struct mmc_softc *sc);
-static void mmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid);
+static void mmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid,
+    bool is_4_41p);
 static void mmc_decode_cid_sd(uint32_t *raw_cid, struct mmc_cid *cid);
 static void mmc_decode_csd_mmc(uint32_t *raw_csd, struct mmc_csd *csd);
 static void mmc_decode_csd_sd(uint32_t *raw_csd, struct mmc_csd *csd);
@@ -181,25 +175,17 @@ static uint32_t mmc_select_vdd(struct mm
 static int mmc_send_app_op_cond(struct mmc_softc *sc, uint32_t ocr,
     uint32_t *rocr);
 static int mmc_send_csd(struct mmc_softc *sc, uint16_t rca, uint32_t *rawcsd);
-static int mmc_send_ext_csd(struct mmc_softc *sc, uint8_t *rawextcsd);
 static int mmc_send_if_cond(struct mmc_softc *sc, uint8_t vhs);
 static int mmc_send_op_cond(struct mmc_softc *sc, uint32_t ocr,
     uint32_t *rocr);
 static int mmc_send_relative_addr(struct mmc_softc *sc, uint32_t *resp);
-static int mmc_send_status(struct mmc_softc *sc, uint16_t rca,
-    uint32_t *status);
 static int mmc_set_blocklen(struct mmc_softc *sc, uint32_t len);
-static int mmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca,
-    int width);
+static int mmc_set_card_bus_width(struct mmc_softc *sc,
+    struct mmc_ivars *ivar);
 static int mmc_set_relative_addr(struct mmc_softc *sc, uint16_t resp);
-static int mmc_set_timing(struct mmc_softc *sc, int timing);
-static int mmc_switch(struct mmc_softc *sc, uint8_t set, uint8_t index,
-    uint8_t value);
+static int mmc_set_timing(struct mmc_softc *sc, struct mmc_ivars *ivar,
+    int timing);
 static int mmc_test_bus_width(struct mmc_softc *sc);
-static int mmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca,
-    struct mmc_command *cmd, int retries);
-static int mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd,
-    int retries);
 static int mmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode,
     uint32_t arg, uint32_t flags, uint32_t *resp, int retries);
 static int mmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req);
@@ -259,7 +245,7 @@ mmc_suspend(device_t dev)
 
 	err = bus_generic_suspend(dev);
 	if (err)
-	        return (err);
+		return (err);
 	mmc_power_down(sc);
 	return (0);
 }
@@ -298,19 +284,19 @@ mmc_acquire_bus(device_t busdev, device_
 		 * unselect unless the bus code itself wants the mmc
 		 * bus, and constantly reselecting causes problems.
 		 */
-		rca = mmc_get_rca(dev);
+		ivar = device_get_ivars(dev);
+		rca = ivar->rca;
 		if (sc->last_rca != rca) {
 			mmc_select_card(sc, rca);
 			sc->last_rca = rca;
 			/* Prepare bus width for the new card. */
-			ivar = device_get_ivars(dev);
 			if (bootverbose || mmc_debug) {
 				device_printf(busdev,
 				    "setting bus width to %d bits\n",
 				    (ivar->bus_width == bus_width_4) ? 4 :
 				    (ivar->bus_width == bus_width_8) ? 8 : 1);
 			}
-			mmc_set_card_bus_width(sc, rca, ivar->bus_width);
+			mmc_set_card_bus_width(sc, ivar);
 			mmcbr_set_bus_width(busdev, ivar->bus_width);
 			mmcbr_update_ios(busdev);
 		}
@@ -407,7 +393,8 @@ mmc_wait_for_req(struct mmc_softc *sc, s
 }
 
 static int
-mmc_wait_for_request(device_t brdev, device_t reqdev, struct mmc_request *req)
+mmc_wait_for_request(device_t brdev, device_t reqdev __unused,
+    struct mmc_request *req)
 {
 	struct mmc_softc *sc = device_get_softc(brdev);
 
@@ -415,74 +402,6 @@ mmc_wait_for_request(device_t brdev, dev
 }
 
 static int
-mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries)
-{
-	struct mmc_request mreq;
-	int err;
-
-	do {
-		memset(&mreq, 0, sizeof(mreq));
-		memset(cmd->resp, 0, sizeof(cmd->resp));
-		cmd->retries = 0; /* Retries done here, not in hardware. */
-		cmd->mrq = &mreq;
-		mreq.cmd = cmd;
-		if (mmc_wait_for_req(sc, &mreq) != 0)
-			err = MMC_ERR_FAILED;
-		else
-			err = cmd->error;
-	} while (err != MMC_ERR_NONE && retries-- > 0);
-
-	if (err != MMC_ERR_NONE && sc->squelched == 0) {
-		if (ppsratecheck(&sc->log_time, &sc->log_count, LOG_PPS)) {
-			device_printf(sc->dev, "CMD%d failed, RESULT: %d\n",
-			    cmd->opcode, err);
-		}
-	}
-
-	return (err);
-}
-
-static int
-mmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca,
-    struct mmc_command *cmd, int retries)
-{
-	struct mmc_command appcmd;
-	int err;
-
-	/* Squelch error reporting at lower levels, we report below. */
-	sc->squelched++;
-	do {
-		memset(&appcmd, 0, sizeof(appcmd));
-		appcmd.opcode = MMC_APP_CMD;
-		appcmd.arg = rca << 16;
-		appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
-		appcmd.data = NULL;
-		if (mmc_wait_for_cmd(sc, &appcmd, 0) != 0)
-			err = MMC_ERR_FAILED;
-		else
-			err = appcmd.error;
-		if (err == MMC_ERR_NONE) {
-			if (!(appcmd.resp[0] & R1_APP_CMD))
-				err = MMC_ERR_FAILED;
-			else if (mmc_wait_for_cmd(sc, cmd, 0) != 0)
-				err = MMC_ERR_FAILED;
-			else
-				err = cmd->error;
-		}
-	} while (err != MMC_ERR_NONE && retries-- > 0);
-	sc->squelched--;
-
-	if (err != MMC_ERR_NONE && sc->squelched == 0) {
-		if (ppsratecheck(&sc->log_time, &sc->log_count, LOG_PPS)) {
-			device_printf(sc->dev, "ACMD%d failed, RESULT: %d\n",
-			    cmd->opcode, err);
-		}
-	}
-
-	return (err);
-}
-
-static int
 mmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode,
     uint32_t arg, uint32_t flags, uint32_t *resp, int retries)
 {
@@ -494,7 +413,7 @@ mmc_wait_for_command(struct mmc_softc *s
 	cmd.arg = arg;
 	cmd.flags = flags;
 	cmd.data = NULL;
-	err = mmc_wait_for_cmd(sc, &cmd, retries);
+	err = mmc_wait_for_cmd(sc->dev, sc->dev, &cmd, retries);
 	if (err)
 		return (err);
 	if (resp) {
@@ -522,7 +441,7 @@ mmc_idle_cards(struct mmc_softc *sc)
 	cmd.arg = 0;
 	cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
 	cmd.data = NULL;
-	mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
+	mmc_wait_for_cmd(sc->dev, sc->dev, &cmd, CMD_RETRIES);
 	mmc_ms_delay(1);
 
 	mmcbr_set_chip_select(dev, cs_dontcare);
@@ -543,7 +462,8 @@ mmc_send_app_op_cond(struct mmc_softc *s
 	cmd.data = NULL;
 
 	for (i = 0; i < 1000; i++) {
-		err = mmc_wait_for_app_cmd(sc, 0, &cmd, CMD_RETRIES);
+		err = mmc_wait_for_app_cmd(sc->dev, sc->dev, 0, &cmd,
+		    CMD_RETRIES);
 		if (err != MMC_ERR_NONE)
 			break;
 		if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) ||
@@ -570,7 +490,7 @@ mmc_send_op_cond(struct mmc_softc *sc, u
 	cmd.data = NULL;
 
 	for (i = 0; i < 1000; i++) {
-		err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
+		err = mmc_wait_for_cmd(sc->dev, sc->dev, &cmd, CMD_RETRIES);
 		if (err != MMC_ERR_NONE)
 			break;
 		if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) ||
@@ -596,7 +516,7 @@ mmc_send_if_cond(struct mmc_softc *sc, u
 	cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR;
 	cmd.data = NULL;
 
-	err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
+	err = mmc_wait_for_cmd(sc->dev, sc->dev, &cmd, CMD_RETRIES);
 	return (err);
 }
 
@@ -647,24 +567,6 @@ mmc_select_card(struct mmc_softc *sc, ui
 }
 
 static int
-mmc_switch(struct mmc_softc *sc, uint8_t set, uint8_t index, uint8_t value)
-{
-	struct mmc_command cmd;
-	int err;
-
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.opcode = MMC_SWITCH_FUNC;
-	cmd.arg = (MMC_SWITCH_FUNC_WR << 24) |
-	    (index << 16) |
-	    (value << 8) |
-	    set;
-	cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
-	cmd.data = NULL;
-	err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
-	return (err);
-}
-
-static int
 mmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value,
     uint8_t *res)
 {
@@ -688,12 +590,12 @@ mmc_sd_switch(struct mmc_softc *sc, uint
 	data.len = 64;
 	data.flags = MMC_DATA_READ;
 
-	err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
+	err = mmc_wait_for_cmd(sc->dev, sc->dev, &cmd, CMD_RETRIES);
 	return (err);
 }
 
 static int
-mmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width)
+mmc_set_card_bus_width(struct mmc_softc *sc, struct mmc_ivars *ivar)
 {
 	struct mmc_command cmd;
 	int err;
@@ -704,13 +606,14 @@ mmc_set_card_bus_width(struct mmc_softc 
 		cmd.opcode = ACMD_SET_CLR_CARD_DETECT;
 		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 		cmd.arg = SD_CLR_CARD_DETECT;
-		err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES);
+		err = mmc_wait_for_app_cmd(sc->dev, sc->dev, ivar->rca, &cmd,
+		    CMD_RETRIES);
 		if (err != 0)
 			return (err);
 		memset(&cmd, 0, sizeof(cmd));
 		cmd.opcode = ACMD_SET_BUS_WIDTH;
 		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
-		switch (width) {
+		switch (ivar->bus_width) {
 		case bus_width_1:
 			cmd.arg = SD_BUS_WIDTH_1;
 			break;
@@ -720,9 +623,10 @@ mmc_set_card_bus_width(struct mmc_softc 
 		default:
 			return (MMC_ERR_INVALID);
 		}
-		err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES);
+		err = mmc_wait_for_app_cmd(sc->dev, sc->dev, ivar->rca, &cmd,
+		    CMD_RETRIES);
 	} else {
-		switch (width) {
+		switch (ivar->bus_width) {
 		case bus_width_1:
 			value = EXT_CSD_BUS_WIDTH_1;
 			break;
@@ -735,18 +639,19 @@ mmc_set_card_bus_width(struct mmc_softc 
 		default:
 			return (MMC_ERR_INVALID);
 		}
-		err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
-		    value);
+		err = mmc_switch(sc->dev, sc->dev, ivar->rca,
+		    EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, value,
+		    ivar->cmd6_time, true);
 	}
 	return (err);
 }
 
 static int
-mmc_set_timing(struct mmc_softc *sc, int timing)
+mmc_set_timing(struct mmc_softc *sc, struct mmc_ivars *ivar, int timing)
 {
-	int err;
-	uint8_t	value;
 	u_char switch_res[64];
+	uint8_t	value;
+	int err;
 
 	switch (timing) {
 	case bus_timing_normal:
@@ -758,26 +663,52 @@ mmc_set_timing(struct mmc_softc *sc, int
 	default:
 		return (MMC_ERR_INVALID);
 	}
-	if (mmcbr_get_mode(sc->dev) == mode_sd)
+	if (mmcbr_get_mode(sc->dev) == mode_sd) {
 		err = mmc_sd_switch(sc, SD_SWITCH_MODE_SET, SD_SWITCH_GROUP1,
 		    value, switch_res);
-	else
-		err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL,
-		    EXT_CSD_HS_TIMING, value);
+		if (err != MMC_ERR_NONE)
+			return (err);
+		if ((switch_res[16] & 0xf) != value)
+			return (MMC_ERR_FAILED);
+		mmcbr_set_timing(sc->dev, timing);
+		mmcbr_update_ios(sc->dev);
+	} else {
+		err = mmc_switch(sc->dev, sc->dev, ivar->rca,
+		    EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, value,
+		    ivar->cmd6_time, false);
+		if (err != MMC_ERR_NONE)
+			return (err);
+		mmcbr_set_timing(sc->dev, timing);
+		mmcbr_update_ios(sc->dev);
+		err = mmc_switch_status(sc->dev, sc->dev, ivar->rca,
+		    ivar->cmd6_time);
+	}
 	return (err);
 }
 
+static const uint8_t p8[8] = {
+	0x55, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint8_t p8ok[8] = {
+	0xAA, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint8_t p4[4] = {
+	0x5A, 0x00, 0x00, 0x00
+};
+
+static const uint8_t p4ok[4] = {
+	0xA5, 0x00, 0x00, 0x00
+};
+
 static int
 mmc_test_bus_width(struct mmc_softc *sc)
 {
 	struct mmc_command cmd;
 	struct mmc_data data;
-	int err;
 	uint8_t buf[8];
-	uint8_t	p8[8] =   { 0x55, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-	uint8_t	p8ok[8] = { 0xAA, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-	uint8_t	p4[4] =   { 0x5A, 0x00, 0x00, 0x00, };
-	uint8_t	p4ok[4] = { 0xA5, 0x00, 0x00, 0x00, };
+	int err;
 
 	if (mmcbr_get_caps(sc->dev) & MMC_CAP_8_BIT_DATA) {
 		mmcbr_set_bus_width(sc->dev, bus_width_8);
@@ -791,10 +722,10 @@ mmc_test_bus_width(struct mmc_softc *sc)
 		cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
 		cmd.data = &data;
 
-		data.data = p8;
+		data.data = __DECONST(void *, p8);
 		data.len = 8;
 		data.flags = MMC_DATA_WRITE;
-		mmc_wait_for_cmd(sc, &cmd, 0);
+		mmc_wait_for_cmd(sc->dev, sc->dev, &cmd, 0);
 
 		memset(&cmd, 0, sizeof(cmd));
 		memset(&data, 0, sizeof(data));
@@ -806,7 +737,7 @@ mmc_test_bus_width(struct mmc_softc *sc)
 		data.data = buf;
 		data.len = 8;
 		data.flags = MMC_DATA_READ;
-		err = mmc_wait_for_cmd(sc, &cmd, 0);
+		err = mmc_wait_for_cmd(sc->dev, sc->dev, &cmd, 0);
 		sc->squelched--;
 
 		mmcbr_set_bus_width(sc->dev, bus_width_1);
@@ -828,10 +759,10 @@ mmc_test_bus_width(struct mmc_softc *sc)
 		cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
 		cmd.data = &data;
 
-		data.data = p4;
+		data.data = __DECONST(void *, p4);
 		data.len = 4;
 		data.flags = MMC_DATA_WRITE;
-		mmc_wait_for_cmd(sc, &cmd, 0);
+		mmc_wait_for_cmd(sc->dev, sc->dev, &cmd, 0);
 
 		memset(&cmd, 0, sizeof(cmd));
 		memset(&data, 0, sizeof(data));
@@ -843,7 +774,7 @@ mmc_test_bus_width(struct mmc_softc *sc)
 		data.data = buf;
 		data.len = 4;
 		data.flags = MMC_DATA_READ;
-		err = mmc_wait_for_cmd(sc, &cmd, 0);
+		err = mmc_wait_for_cmd(sc->dev, sc->dev, &cmd, 0);
 		sc->squelched--;
 
 		mmcbr_set_bus_width(sc->dev, bus_width_1);
@@ -861,6 +792,7 @@ mmc_get_bits(uint32_t *bits, int bit_len
 	const int i = (bit_len / 32) - (start / 32) - 1;
 	const int shift = start & 31;
 	uint32_t retval = bits[i] >> shift;
+
 	if (size + shift > 32)
 		retval |= bits[i - 1] << (32 - shift);
 	return (retval & ((1llu << size) - 1));
@@ -885,7 +817,7 @@ mmc_decode_cid_sd(uint32_t *raw_cid, str
 }
 
 static void
-mmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid)
+mmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid, bool is_4_41p)
 {
 	int i;
 
@@ -899,7 +831,11 @@ mmc_decode_cid_mmc(uint32_t *raw_cid, st
 	cid->prv = mmc_get_bits(raw_cid, 128, 48, 8);
 	cid->psn = mmc_get_bits(raw_cid, 128, 16, 32);
 	cid->mdt_month = mmc_get_bits(raw_cid, 128, 12, 4);
-	cid->mdt_year = mmc_get_bits(raw_cid, 128, 8, 4) + 1997;
+	cid->mdt_year = mmc_get_bits(raw_cid, 128, 8, 4);
+	if (is_4_41p)
+		cid->mdt_year += 2013;
+	else
+		cid->mdt_year += 1997;
 }
 
 static void
@@ -980,10 +916,14 @@ mmc_decode_csd_sd(uint32_t *raw_csd, str
 		csd->write_blk_misalign = mmc_get_bits(raw_csd, 128, 78, 1);
 		csd->read_blk_misalign = mmc_get_bits(raw_csd, 128, 77, 1);
 		csd->dsr_imp = mmc_get_bits(raw_csd, 128, 76, 1);
-		csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 59, 3)];
-		csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 56, 3)];
-		csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 128, 53, 3)];
-		csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 128, 50, 3)];
+		csd->vdd_r_curr_min =
+		    cur_min[mmc_get_bits(raw_csd, 128, 59, 3)];
+		csd->vdd_r_curr_max =
+		    cur_max[mmc_get_bits(raw_csd, 128, 56, 3)];
+		csd->vdd_w_curr_min =
+		    cur_min[mmc_get_bits(raw_csd, 128, 53, 3)];
+		csd->vdd_w_curr_max =
+		    cur_max[mmc_get_bits(raw_csd, 128, 50, 3)];
 		m = mmc_get_bits(raw_csd, 128, 62, 12);
 		e = mmc_get_bits(raw_csd, 128, 47, 3);
 		csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len;
@@ -1008,8 +948,8 @@ mmc_decode_csd_sd(uint32_t *raw_csd, str
 		csd->write_blk_misalign = mmc_get_bits(raw_csd, 128, 78, 1);
 		csd->read_blk_misalign = mmc_get_bits(raw_csd, 128, 77, 1);
 		csd->dsr_imp = mmc_get_bits(raw_csd, 128, 76, 1);
-		csd->capacity = ((uint64_t)mmc_get_bits(raw_csd, 128, 48, 22) + 1) *
-		    512 * 1024;
+		csd->capacity = ((uint64_t)mmc_get_bits(raw_csd, 128, 48, 22) +
+		    1) * 512 * 1024;
 		csd->erase_blk_en = mmc_get_bits(raw_csd, 128, 46, 1);
 		csd->erase_sector = mmc_get_bits(raw_csd, 128, 39, 7) + 1;
 		csd->wp_grp_size = mmc_get_bits(raw_csd, 128, 32, 7);
@@ -1107,7 +1047,7 @@ mmc_all_send_cid(struct mmc_softc *sc, u
 	cmd.arg = 0;
 	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
 	cmd.data = NULL;
-	err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
+	err = mmc_wait_for_cmd(sc->dev, sc->dev, &cmd, CMD_RETRIES);
 	memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t));
 	return (err);
 }
@@ -1123,7 +1063,7 @@ mmc_send_csd(struct mmc_softc *sc, uint1
 	cmd.arg = rca << 16;
 	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
 	cmd.data = NULL;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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