Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 May 2017 21:01:02 +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-10@freebsd.org
Subject:   svn commit: r318198 - in stable/10: . etc/mtree include sys/arm/at91 sys/arm/broadcom/bcm2835 sys/arm/freescale/imx sys/arm/lpc sys/arm/ti sys/conf sys/dev/mmc sys/dev/sdhci sys/modules sys/modules...
Message-ID:  <201705112101.v4BL12n5033434@repo.freebsd.org>

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

Log:
  MFC: r292180 (partial), r297127 (partial), r311911, r311923, r312939,
       r313250, r313712, r314811 (partial), r314887 (partial), r315430,
       r317981, r315466
  
  o Move the DRIVER_MODULE() statements that declare mmc(4) to be a child
    of the various bridge drivers out of dev/mmc.c and into the bridge
    drivers.
  
  o Add ACPI platform support for SDHCI driver.
  
  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.

Added:
  stable/10/sys/dev/mmc/mmc_ioctl.h
     - copied unchanged from r315430, head/sys/dev/mmc/mmc_ioctl.h
  stable/10/sys/dev/mmc/mmc_private.h
     - copied unchanged from r315430, head/sys/dev/mmc/mmc_private.h
  stable/10/sys/dev/mmc/mmc_subr.c
     - copied unchanged from r315430, head/sys/dev/mmc/mmc_subr.c
  stable/10/sys/dev/mmc/mmc_subr.h
     - copied unchanged from r315430, head/sys/dev/mmc/mmc_subr.h
  stable/10/sys/dev/sdhci/sdhci_acpi.c
     - copied, changed from r311911, head/sys/dev/sdhci/sdhci_acpi.c
  stable/10/sys/modules/sdhci_acpi/
     - copied from r311911, head/sys/modules/sdhci_acpi/
Modified:
  stable/10/UPDATING
  stable/10/etc/mtree/BSD.include.dist
  stable/10/include/Makefile
  stable/10/sys/arm/at91/at91_mci.c
  stable/10/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
  stable/10/sys/arm/freescale/imx/imx_sdhci.c
  stable/10/sys/arm/lpc/lpc_mmc.c
  stable/10/sys/arm/ti/ti_sdhci.c
  stable/10/sys/conf/files
  stable/10/sys/dev/mmc/bridge.h
  stable/10/sys/dev/mmc/mmc.c
  stable/10/sys/dev/mmc/mmcbr_if.m
  stable/10/sys/dev/mmc/mmcbrvar.h
  stable/10/sys/dev/mmc/mmcreg.h
  stable/10/sys/dev/mmc/mmcsd.c
  stable/10/sys/dev/mmc/mmcvar.h
  stable/10/sys/dev/sdhci/sdhci.c
  stable/10/sys/dev/sdhci/sdhci.h
  stable/10/sys/dev/sdhci/sdhci_fdt.c
  stable/10/sys/dev/sdhci/sdhci_if.m
  stable/10/sys/dev/sdhci/sdhci_pci.c
  stable/10/sys/modules/Makefile
  stable/10/sys/modules/mmc/Makefile
  stable/10/sys/modules/sdhci_acpi/Makefile
  stable/10/sys/powerpc/mpc85xx/fsl_sdhc.c
  stable/10/sys/sys/param.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/UPDATING
==============================================================================
--- stable/10/UPDATING	Thu May 11 20:55:11 2017	(r318197)
+++ stable/10/UPDATING	Thu May 11 21:01:02 2017	(r318198)
@@ -16,6 +16,13 @@ from older versions of FreeBSD, try WITH
 stable/10, and then rebuild without this option. The bootstrap process from
 older version of current 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).
+
 20170413:
 	As of r316810 for ipfilter, keep frags is no longer assumed when
 	keep state is specified in a rule. r316810 aligns ipfilter with

Modified: stable/10/etc/mtree/BSD.include.dist
==============================================================================
--- stable/10/etc/mtree/BSD.include.dist	Thu May 11 20:55:11 2017	(r318197)
+++ stable/10/etc/mtree/BSD.include.dist	Thu May 11 21:01:02 2017	(r318198)
@@ -132,6 +132,8 @@
         ..
         mfi
         ..
+        mmc
+        ..
         mpt
             mpilib
             ..

Modified: stable/10/include/Makefile
==============================================================================
--- stable/10/include/Makefile	Thu May 11 20:55:11 2017	(r318197)
+++ stable/10/include/Makefile	Thu May 11 21:01:02 2017	(r318198)
@@ -45,7 +45,8 @@ LDIRS=	bsm cam geom net net80211 netatal
 LSUBDIRS=	cam/ata 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_ieee488} dev/io dev/lmc dev/mfi dev/nvme \
+	dev/ic dev/iicbus ${_dev_ieee488} 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/10/sys/arm/at91/at91_mci.c
==============================================================================
--- stable/10/sys/arm/at91/at91_mci.c	Thu May 11 20:55:11 2017	(r318197)
+++ stable/10/sys/arm/at91/at91_mci.c	Thu May 11 21:01:02 2017	(r318198)
@@ -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/cpu.h>
@@ -61,7 +54,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
@@ -1410,3 +1402,5 @@ DRIVER_MODULE(at91_mci, simplebus, at91_
 DRIVER_MODULE(at91_mci, atmelarm, at91_mci_driver, at91_mci_devclass, NULL,
     NULL);
 #endif
+
+MMC_DECLARE_BRIDGE(at91_mci);

Modified: stable/10/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
==============================================================================
--- stable/10/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c	Thu May 11 20:55:11 2017	(r318197)
+++ stable/10/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c	Thu May 11 21:01:02 2017	(r318198)
@@ -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"
@@ -637,7 +638,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),
@@ -660,7 +660,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;
@@ -671,5 +671,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);
+MMC_DECLARE_BRIDGE(sdhci_bcm);

Modified: stable/10/sys/arm/freescale/imx/imx_sdhci.c
==============================================================================
--- stable/10/sys/arm/freescale/imx/imx_sdhci.c	Thu May 11 20:55:11 2017	(r318197)
+++ stable/10/sys/arm/freescale/imx/imx_sdhci.c	Thu May 11 21:01:02 2017	(r318198)
@@ -835,4 +835,5 @@ static driver_t imx_sdhci_driver = {
 
 DRIVER_MODULE(sdhci_imx, simplebus, imx_sdhci_driver, imx_sdhci_devclass, 0, 0);
 MODULE_DEPEND(sdhci_imx, sdhci, 1, 1, 1);
-
+DRIVER_MODULE(mmc, sdhci_imx, mmc_driver, mmc_devclass, NULL, NULL);
+MODULE_DEPEND(sdhci_imx, mmc, 1, 1, 1);

Modified: stable/10/sys/arm/lpc/lpc_mmc.c
==============================================================================
--- stable/10/sys/arm/lpc/lpc_mmc.c	Thu May 11 20:55:11 2017	(r318197)
+++ stable/10/sys/arm/lpc/lpc_mmc.c	Thu May 11 21:01:02 2017	(r318198)
@@ -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/cpu.h>
@@ -58,7 +48,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>
@@ -754,7 +743,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),
@@ -763,7 +751,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;
@@ -774,4 +762,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(lpcmmc, simplebus, lpc_mmc_driver, lpc_mmc_devclass, NULL, NULL);
+MMC_DECLARE_BRIDGE(lpcmmc);

Modified: stable/10/sys/arm/ti/ti_sdhci.c
==============================================================================
--- stable/10/sys/arm/ti/ti_sdhci.c	Thu May 11 20:55:11 2017	(r318197)
+++ stable/10/sys/arm/ti/ti_sdhci.c	Thu May 11 21:01:02 2017	(r318198)
@@ -599,6 +599,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.
@@ -685,7 +690,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),
@@ -715,5 +719,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);
+MMC_DECLARE_BRIDGE(sdhci_ti);

Modified: stable/10/sys/conf/files
==============================================================================
--- stable/10/sys/conf/files	Thu May 11 20:55:11 2017	(r318197)
+++ stable/10/sys/conf/files	Thu May 11 21:01:02 2017	(r318198)
@@ -1899,6 +1899,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
@@ -2288,6 +2289,7 @@ dev/scd/scd.c			optional scd isa
 dev/scd/scd_isa.c		optional scd isa
 dev/sdhci/sdhci.c		optional sdhci
 dev/sdhci/sdhci_if.m		optional sdhci
+dev/sdhci/sdhci_acpi.c		optional sdhci acpi
 dev/sdhci/sdhci_pci.c		optional sdhci pci
 dev/sf/if_sf.c			optional sf pci
 dev/sge/if_sge.c		optional sge pci
@@ -2898,7 +2900,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
+geom/geom_flashmap.c		optional fdt cfi | fdt nand | mmcsd
 geom/geom_io.c			standard
 geom/geom_kern.c		standard
 geom/geom_map.c			optional geom_map

Modified: stable/10/sys/dev/mmc/bridge.h
==============================================================================
--- stable/10/sys/dev/mmc/bridge.h	Thu May 11 20:55:11 2017	(r318197)
+++ stable/10/sys/dev/mmc/bridge.h	Thu May 11 21:01:02 2017	(r318198)
@@ -52,13 +52,15 @@
  */
 
 #ifndef DEV_MMC_BRIDGE_H
-#define DEV_MMC_BRIDGE_H
+#define	DEV_MMC_BRIDGE_H
+
+#include <sys/bus.h>
 
 /*
  * 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.
  *
@@ -71,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,
@@ -110,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;
@@ -128,11 +129,24 @@ 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 */
 };
 
+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/10/sys/dev/mmc/mmc.c
==============================================================================
--- stable/10/sys/dev/mmc/mmc.c	Thu May 11 20:55:11 2017	(r318197)
+++ stable/10/sys/dev/mmc/mmc.c	Thu May 11 21:01:02 2017	(r318198)
@@ -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,11 +98,12 @@ 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. */
 
@@ -119,7 +111,8 @@ static SYSCTL_NODE(_hw, OID_AUTO, mmc, C
 
 static int mmc_debug;
 TUNABLE_INT("hw.mmc.debug", &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);
@@ -138,14 +131,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);
@@ -156,7 +149,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);
@@ -182,25 +176,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);
@@ -260,7 +246,7 @@ mmc_suspend(device_t dev)
 
 	err = bus_generic_suspend(dev);
 	if (err)
-	        return (err);
+		return (err);
 	mmc_power_down(sc);
 	return (0);
 }
@@ -299,19 +285,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);
 		}
@@ -408,7 +394,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);
 
@@ -416,74 +403,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)
 {
@@ -495,7 +414,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) {
@@ -523,7 +442,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);
@@ -544,7 +463,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) ||
@@ -571,7 +491,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) ||
@@ -597,7 +517,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);
 }
 
@@ -648,24 +568,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)
 {
@@ -689,12 +591,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;
@@ -705,13 +607,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;
@@ -721,9 +624,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;
@@ -736,18 +640,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:
@@ -759,26 +664,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);
@@ -792,10 +723,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));
@@ -807,7 +738,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);
@@ -829,10 +760,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));
@@ -844,7 +775,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);
@@ -862,6 +793,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));
@@ -886,7 +818,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;
 
@@ -900,7 +832,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
@@ -981,10 +917,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;
@@ -1009,8 +949,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);
@@ -1108,7 +1048,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);
 }
@@ -1124,7 +1064,7 @@ mmc_send_csd(struct mmc_softc *sc, uint1
 	cmd.arg = rca << 16;
 	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(rawcsd, cmd.resp, 4 * sizeof(uint32_t));
 	return (err);
 }
@@ -1149,42 +1089,18 @@ mmc_app_send_scr(struct mmc_softc *sc, u
 	data.len = 8;
 	data.flags = MMC_DATA_READ;
 
-	err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES);
+	err = mmc_wait_for_app_cmd(sc->dev, sc->dev, rca, &cmd, CMD_RETRIES);
 	rawscr[0] = be32toh(rawscr[0]);
 	rawscr[1] = be32toh(rawscr[1]);
 	return (err);
 }
 
 static int
-mmc_send_ext_csd(struct mmc_softc *sc, uint8_t *rawextcsd)
-{
-	int err;
-	struct mmc_command cmd;
-	struct mmc_data data;
-
-	memset(&cmd, 0, sizeof(cmd));
-	memset(&data, 0, sizeof(data));
-
-	memset(rawextcsd, 0, 512);
-	cmd.opcode = MMC_SEND_EXT_CSD;
-	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
-	cmd.arg = 0;
-	cmd.data = &data;
-
-	data.data = rawextcsd;
-	data.len = 512;
-	data.flags = MMC_DATA_READ;
-
-	err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
-	return (err);
-}
-
-static int
 mmc_app_sd_status(struct mmc_softc *sc, uint16_t rca, uint32_t *rawsdstatus)
 {
-	int err, i;
 	struct mmc_command cmd;
 	struct mmc_data data;
+	int err, i;
 
 	memset(&cmd, 0, sizeof(cmd));
 	memset(&data, 0, sizeof(data));
@@ -1199,7 +1115,7 @@ mmc_app_sd_status(struct mmc_softc *sc, 
 	data.len = 64;
 	data.flags = MMC_DATA_READ;
 
-	err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES);
+	err = mmc_wait_for_app_cmd(sc->dev, sc->dev, rca, &cmd, CMD_RETRIES);
 	for (i = 0; i < 16; i++)
 	    rawsdstatus[i] = be32toh(rawsdstatus[i]);
 	return (err);
@@ -1216,7 +1132,7 @@ mmc_set_relative_addr(struct mmc_softc *
 	cmd.arg = resp << 16;
 	cmd.flags = MMC_RSP_R6 | 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);
 }
 
@@ -1231,28 +1147,12 @@ mmc_send_relative_addr(struct mmc_softc 
 	cmd.arg = 0;
 	cmd.flags = MMC_RSP_R6 | 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);
 	*resp = cmd.resp[0];
 	return (err);
 }
 
 static int
-mmc_send_status(struct mmc_softc *sc, uint16_t rca, uint32_t *status)
-{
-	struct mmc_command cmd;
-	int err;
-
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.opcode = MMC_SEND_STATUS;
-	cmd.arg = rca << 16;
-	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
-	cmd.data = NULL;
-	err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
-	*status = cmd.resp[0];
-	return (err);
-}
-
-static int
 mmc_set_blocklen(struct mmc_softc *sc, uint32_t len)
 {
 	struct mmc_command cmd;
@@ -1263,13 +1163,14 @@ mmc_set_blocklen(struct mmc_softc *sc, u
 	cmd.arg = len;
 	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 	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);
 }
 
 static void
 mmc_log_card(device_t dev, struct mmc_ivars *ivar, int newcard)
 {
+
 	device_printf(dev, "Card at relative address 0x%04x%s:\n",
 	    ivar->rca, newcard ? " added" : "");
 	device_printf(dev, " card: %s\n", ivar->card_id_string);
@@ -1287,13 +1188,14 @@ mmc_log_card(device_t dev, struct mmc_iv
 static void
 mmc_discover_cards(struct mmc_softc *sc)
 {
+	u_char switch_res[64];
+	uint32_t raw_cid[4];
 	struct mmc_ivars *ivar = NULL;
 	device_t *devlist;
-	int err, i, devcount, newcard;

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



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