Am Sun, 9 Jul 2017 16:57:24 +0000 (UTC)
Warner Losh <i...@freebsd.org> schrieb:

> Author: imp
> Date: Sun Jul  9 16:57:24 2017
> New Revision: 320844
> URL: https://svnweb.freebsd.org/changeset/base/320844
> 
> Log:
>   An MMC/SD/SDIO stack using CAM
>   
>   Implement the MMC/SD/SDIO protocol within a CAM framework. CAM's
>   flexible queueing will make it easier to write non-storage drivers
>   than the legacy stack. SDIO drivers from both the kernel and as
>   userland daemons are possible, though much of that functionality will
>   come later.
>   
>   Some of the CAM integration isn't complete (there are sleeps in the
>   device probe state machine, for example), but those minor issues can
>   be improved in-tree more easily than out of tree and shouldn't gate
>   progress on other fronts. Appologies to reviews if specific items
>   have been overlooked.
>   
>   Submitted by: Ilya Bakulin
>   Reviewed by: emaste, imp, mav, adrian, ian
>   Differential Review: https://reviews.freebsd.org/D4761
>   
>   merge with first commit, various compile hacks.
> 
> Added:
>   head/sys/amd64/conf/MMCCAM   (contents, props changed)
>   head/sys/arm/conf/BEAGLEBONE-MMCCAM   (contents, props changed)
>   head/sys/cam/mmc/
>   head/sys/cam/mmc/mmc.h
>      - copied, changed from r320843, head/sys/dev/mmc/mmcbrvar.h
>   head/sys/cam/mmc/mmc_all.h
>      - copied, changed from r320843, head/sys/dev/mmc/mmcbrvar.h
>   head/sys/cam/mmc/mmc_bus.h   (contents, props changed)
>   head/sys/cam/mmc/mmc_da.c   (contents, props changed)
>   head/sys/cam/mmc/mmc_sdio.c   (contents, props changed)
>   head/sys/cam/mmc/mmc_sdio.h
>      - copied, changed from r320843, head/sys/dev/mmc/mmcbrvar.h
>   head/sys/cam/mmc/mmc_xpt.c   (contents, props changed)
> Modified:
>   head/etc/mtree/BSD.include.dist
>   head/include/Makefile
>   head/lib/libcam/Makefile
>   head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
>   head/sys/arm/ti/ti_sdhci.c
>   head/sys/cam/cam_ccb.h
>   head/sys/cam/cam_periph.c
>   head/sys/cam/cam_xpt.c
>   head/sys/cam/cam_xpt.h
>   head/sys/cam/cam_xpt_internal.h
>   head/sys/cam/scsi/scsi_pass.c
>   head/sys/conf/files
>   head/sys/conf/options
>   head/sys/dev/mmc/bridge.h
>   head/sys/dev/mmc/mmcbrvar.h
>   head/sys/dev/mmc/mmcreg.h
>   head/sys/dev/sdhci/fsl_sdhci.c
>   head/sys/dev/sdhci/sdhci.c
>   head/sys/dev/sdhci/sdhci.h
>   head/sys/dev/sdhci/sdhci_acpi.c
>   head/sys/dev/sdhci/sdhci_pci.c
>   head/sys/modules/Makefile
> 
> Modified: head/etc/mtree/BSD.include.dist
> ==============================================================================
> --- head/etc/mtree/BSD.include.dist   Sun Jul  9 15:41:49 2017        
> (r320843)
> +++ head/etc/mtree/BSD.include.dist   Sun Jul  9 16:57:24 2017        
> (r320844)
> @@ -90,6 +90,8 @@
>      cam
>          ata
>          ..
> +        mmc
> +        ..
>          nvme
>          ..
>          scsi
> 
> Modified: head/include/Makefile
> ==============================================================================
> --- head/include/Makefile     Sun Jul  9 15:41:49 2017        (r320843)
> +++ head/include/Makefile     Sun Jul  9 16:57:24 2017        (r320844)
> @@ -42,7 +42,7 @@ LHDRS=      aio.h errno.h fcntl.h linker_set.h poll.h stdat
>  LDIRS=       bsm cam geom net net80211 netgraph netinet netinet6 \
>       netipsec netsmb nfs nfsclient nfsserver sys vm
>  
> -LSUBDIRS=    cam/ata cam/nvme cam/scsi \
> +LSUBDIRS=    cam/ata cam/mmc 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/mmc dev/nvme \
> 
> Modified: head/lib/libcam/Makefile
> ==============================================================================
> --- head/lib/libcam/Makefile  Sun Jul  9 15:41:49 2017        (r320843)
> +++ head/lib/libcam/Makefile  Sun Jul  9 16:57:24 2017        (r320844)
> @@ -38,6 +38,7 @@ MLINKS+=    cam.3 cam_open_device.3 \
>  
>  .PATH:               ${SRCTOP}/sys/cam \
>               ${SRCTOP}/sys/cam/ata \
> +             ${SRCTOP}/sys/cam/mmc \
>               ${SRCTOP}/sys/cam/scsi
>  
>  CFLAGS+=     -I${.CURDIR} -I${SRCTOP}/sys
> 
> Added: head/sys/amd64/conf/MMCCAM
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/sys/amd64/conf/MMCCAM        Sun Jul  9 16:57:24 2017        
> (r320844)
> @@ -0,0 +1,36 @@
> +# MMCCAM is the kernel config for doing MMC on CAM development
> +# and testing on bhyve
> +# $FreeBSD$
> +
> +include         MINIMAL
> +
> +ident                MMCCAM
> +
> +# Access GPT-formatted and labeled root volume
> +options         GEOM_PART_GPT
> +options         GEOM_LABEL
> +
> +# UART -- for bhyve console
> +device          uart
> +
> +# kgdb stub
> +device          bvmdebug
> +
> +# VirtIO support, needed for bhyve
> +device               virtio                  # Generic VirtIO bus (required)
> +device               virtio_pci              # VirtIO PCI device
> +device               vtnet                   # VirtIO Ethernet device
> +device               virtio_blk              # VirtIO Block device
> +device               virtio_scsi             # VirtIO SCSI device
> +device               virtio_balloon          # VirtIO Memory Balloon device
> +
> +# CAM-specific stuff
> +device               pass
> +device               scbus
> +device               da
> +device               mmccam
> +
> +options      MMCCAM
> +# Add CAMDEBUG stuff
> +options CAMDEBUG
> +options
> CAM_DEBUG_FLAGS=(CAM_DEBUG_INFO|CAM_DEBUG_PROBE|CAM_DEBUG_PERIPH|CAM_DEBUG_TRACE)
> 
> Modified: head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
> ==============================================================================
> --- head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c     Sun Jul  9 15:41:49
> 2017  (r320843) +++ head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c     Sun Jul
> 9 16:57:24 2017       (r320844) @@ -52,6 +52,8 @@ __FBSDID("$FreeBSD$");
>  #include "mmcbr_if.h"
>  #include "sdhci_if.h"
>  
> +#include "opt_mmccam.h"
> +
>  #include "bcm2835_dma.h"
>  #include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h>
>  #include "bcm2835_vcbus.h"
> @@ -253,7 +255,11 @@ bcm_sdhci_attach(device_t dev)
>       bus_generic_probe(dev);
>       bus_generic_attach(dev);
>  
> +#ifdef MMCCAM
> +     sdhci_cam_start_slot(&sc->sc_slot);
> +#else
>       sdhci_start_slot(&sc->sc_slot);
> +#endif
>  
>       return (0);
>  
> 
> Added: head/sys/arm/conf/BEAGLEBONE-MMCCAM
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/sys/arm/conf/BEAGLEBONE-MMCCAM       Sun Jul  9 16:57:24 2017        
> (r320844)
> @@ -0,0 +1,21 @@
> +#
> +# BEAGLEBONE-MMCCAM
> +#
> +# Custom kernel for Beaglebone plus MMCCAM as opposed to the prior MMC 
> stack. It is
> +# present to keep it building in tree since it wouldn't work in LINT.
> +#
> +# $FreeBSD$
> +
> +include              BEAGLEBONE
> +
> +# Add CAMDEBUG stuff
> +options      CAMDEBUG
> +options
> CAM_DEBUG_FLAGS=(CAM_DEBUG_INFO|CAM_DEBUG_PROBE|CAM_DEBUG_PERIPH|CAM_DEBUG_TRACE)
>  +
> +# pass(4) device
> +device               pass
> +device               mmccam
> +options              MMCCAM
> +
> +nodevice     mmc
> +nodevice     mmcsd
> 
> Modified: head/sys/arm/ti/ti_sdhci.c
> ==============================================================================
> --- head/sys/arm/ti/ti_sdhci.c        Sun Jul  9 15:41:49 2017        
> (r320843)
> +++ head/sys/arm/ti/ti_sdhci.c        Sun Jul  9 16:57:24 2017        
> (r320844)
> @@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$");
>  #include <sys/rman.h>
>  #include <sys/sysctl.h>
>  #include <sys/taskqueue.h>
> +#include <sys/lock.h>
> +#include <sys/mutex.h>
>  
>  #include <machine/bus.h>
>  #include <machine/resource.h>
> @@ -60,6 +62,8 @@ __FBSDID("$FreeBSD$");
>  #include <arm/ti/ti_hwmods.h>
>  #include "gpio_if.h"
>  
> +#include "opt_mmccam.h"
> +
>  struct ti_sdhci_softc {
>       device_t                dev;
>       struct sdhci_fdt_gpio * gpio;
> @@ -122,6 +126,11 @@ static struct ofw_compat_data compat_data[] = {
>  #define        MMCHS_SD_CAPA_VS30              (1 << 25)
>  #define        MMCHS_SD_CAPA_VS33              (1 << 24)
>  
> +/* Forward declarations, CAM-relataed */
> +// static void ti_sdhci_cam_poll(struct cam_sim *);
> +// static void ti_sdhci_cam_action(struct cam_sim *, union ccb *);
> +// static int ti_sdhci_cam_settran_settings(struct ti_sdhci_softc *sc, union 
> ccb *);
> +
>  static inline uint32_t
>  ti_mmchs_read_4(struct ti_sdhci_softc *sc, bus_size_t off)
>  {
> @@ -241,6 +250,22 @@ ti_sdhci_write_1(device_t dev, struct sdhci_slot *slot
>       struct ti_sdhci_softc *sc = device_get_softc(dev);
>       uint32_t val32;
>  
> +#ifdef MMCCAM
> +     uint32_t newval32;
> +     if (off == SDHCI_HOST_CONTROL) {
> +             val32 = ti_mmchs_read_4(sc, MMCHS_CON);
> +             newval32  = val32;
> +             if (val & SDHCI_CTRL_8BITBUS) {
> +                     device_printf(dev, "Custom-enabling 8-bit bus\n");
> +                     newval32 |= MMCHS_CON_DW8;
> +             } else {
> +                     device_printf(dev, "Custom-disabling 8-bit bus\n");
> +                     newval32 &= ~MMCHS_CON_DW8;
> +             }
> +             if (newval32 != val32)
> +                     ti_mmchs_write_4(sc, MMCHS_CON, newval32);
> +     }
> +#endif
>       val32 = RD4(sc, off & ~3);
>       val32 &= ~(0xff << (off & 3) * 8);
>       val32 |= (val << (off & 3) * 8);
> @@ -658,8 +683,11 @@ ti_sdhci_attach(device_t dev)
>       bus_generic_probe(dev);
>       bus_generic_attach(dev);
>  
> +#ifdef MMCCAM
> +     sdhci_cam_start_slot(&sc->slot);
> +#else
>       sdhci_start_slot(&sc->slot);
> -
> +#endif
>       return (0);
>  
>  fail:
> @@ -730,4 +758,7 @@ static driver_t ti_sdhci_driver = {
>  DRIVER_MODULE(sdhci_ti, simplebus, ti_sdhci_driver, ti_sdhci_devclass, NULL,
>      NULL);
>  MODULE_DEPEND(sdhci_ti, sdhci, 1, 1, 1);
> +
> +#ifndef MMCCAM
>  MMC_DECLARE_BRIDGE(sdhci_ti);
> +#endif
> 
> Modified: head/sys/cam/cam_ccb.h
> ==============================================================================
> --- head/sys/cam/cam_ccb.h    Sun Jul  9 15:41:49 2017        (r320843)
> +++ head/sys/cam/cam_ccb.h    Sun Jul  9 16:57:24 2017        (r320844)
> @@ -42,6 +42,7 @@
>  #include <cam/scsi/scsi_all.h>
>  #include <cam/ata/ata_all.h>
>  #include <cam/nvme/nvme_all.h>
> +#include <cam/mmc/mmc_all.h>
>  
>  /* General allocation length definitions for CCB structures */
>  #define      IOCDBLEN        CAM_MAX_CDBLEN  /* Space for CDB bytes/pointer 
> */
> @@ -208,10 +209,10 @@ typedef enum {
>       XPT_NVME_IO             = 0x1c | XPT_FC_DEV_QUEUED,
>                               /* Execiute the requestred NVMe I/O operation */
>  
> -     XPT_MMCSD_IO            = 0x1d | XPT_FC_DEV_QUEUED,
> +     XPT_MMC_IO              = 0x1d | XPT_FC_DEV_QUEUED,
>                               /* Placeholder for MMC / SD / SDIO I/O stuff */
>  
> -     XPT_SCAN_TGT            = 0x1E | XPT_FC_QUEUED | XPT_FC_USER_CCB
> +     XPT_SCAN_TGT            = 0x1e | XPT_FC_QUEUED | XPT_FC_USER_CCB
>                                      | XPT_FC_XPT_ONLY,
>                               /* Scan Target */
>  
> @@ -267,6 +268,7 @@ typedef enum {
>       PROTO_SATAPM,   /* SATA Port Multiplier */
>       PROTO_SEMB,     /* SATA Enclosure Management Bridge */
>       PROTO_NVME,     /* NVME */
> +     PROTO_MMCSD,    /* MMC, SD, SDIO */
>  } cam_proto;
>  
>  typedef enum {
> @@ -283,6 +285,7 @@ typedef enum {
>       XPORT_ISCSI,    /* iSCSI */
>       XPORT_SRP,      /* SCSI RDMA Protocol */
>       XPORT_NVME,     /* NVMe over PCIe */
> +     XPORT_MMCSD,    /* MMC, SD, SDIO card */
>  } cam_xport;
>  
>  #define XPORT_IS_NVME(t)     ((t) == XPORT_NVME)
> @@ -498,6 +501,7 @@ struct device_match_result {
>       cam_proto                       protocol;
>       struct scsi_inquiry_data        inq_data;
>       struct ata_params               ident_data;
> +        struct mmc_params               mmc_ident_data;
>       dev_result_flags                flags;
>  };
>  
> @@ -773,6 +777,16 @@ struct ccb_ataio {
>       uint32_t   unused;
>  };
>  
> +/*
> + * MMC I/O Request CCB used for the XPT_MMC_IO function code.
> + */
> +struct ccb_mmcio {
> +     struct     ccb_hdr ccb_h;
> +     union      ccb *next_ccb;       /* Ptr for next CCB for action */
> +     struct mmc_command cmd;
> +        struct mmc_command stop;
> +};
> +
>  struct ccb_accept_tio {
>       struct     ccb_hdr ccb_h;
>       cdb_t      cdb_io;              /* Union for CDB bytes/pointer */
> @@ -1005,7 +1019,28 @@ struct ccb_trans_settings_nvme 
>       u_int           max_xfer;       /* Max transfer size (0 -> unlimited */
>       u_int           caps;
>  };
> -     
> +
> +#include <cam/mmc/mmc_bus.h>
> +struct ccb_trans_settings_mmc {
> +     struct mmc_ios ios;
> +#define MMC_CLK              (1 << 1)
> +#define MMC_VDD              (1 << 2)
> +#define MMC_CS               (1 << 3)
> +#define MMC_BW               (1 << 4)
> +#define MMC_PM               (1 << 5)
> +#define MMC_BT               (1 << 6)
> +#define MMC_BM               (1 << 7)
> +     uint32_t ios_valid;
> +/* The folowing is used only for GET_TRAN_SETTINGS */
> +     uint32_t        host_ocr;
> +     int host_f_min;
> +     int host_f_max;
> +#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 
> */
> +     uint32_t host_caps;
> +};
> +
>  /* Get/Set transfer rate/width/disconnection/tag queueing settings */
>  struct ccb_trans_settings {
>       struct    ccb_hdr ccb_h;
> @@ -1019,6 +1054,7 @@ struct ccb_trans_settings {
>               struct ccb_trans_settings_ata ata;
>               struct ccb_trans_settings_scsi scsi;
>               struct ccb_trans_settings_nvme nvme;
> +             struct ccb_trans_settings_mmc mmc;
>       } proto_specific;
>       union {
>               u_int  valid;   /* Which fields to honor */
> @@ -1284,6 +1320,7 @@ union ccb {
>       struct  ccb_dev_advinfo         cdai;
>       struct  ccb_async               casync;
>       struct  ccb_nvmeio              nvmeio;
> +     struct  ccb_mmcio               mmcio;
>  };
>  
>  #define CCB_CLEAR_ALL_EXCEPT_HDR(ccbp)                       \
> @@ -1327,6 +1364,13 @@ cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retri
>              uint32_t timeout);
>  
>  static __inline void
> +cam_fill_mmcio(struct ccb_mmcio *mmcio, uint32_t retries,
> +            void (*cbfcnp)(struct cam_periph *, union ccb *), uint32_t flags,
> +               uint32_t mmc_opcode, uint32_t mmc_arg, uint32_t mmc_flags,
> +            struct mmc_data *mmc_d,
> +            uint32_t timeout);
> +
> +static __inline void
>  cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries,
>             void (*cbfcnp)(struct cam_periph *, union ccb *),
>             u_int32_t flags, u_int8_t tag_action,
> @@ -1412,6 +1456,34 @@ cam_fill_smpio(struct ccb_smpio *smpio, uint32_t retri
>       smpio->smp_request_len = smp_request_len;
>       smpio->smp_response = smp_response;
>       smpio->smp_response_len = smp_response_len;
> +}
> +
> +static __inline void
> +cam_fill_mmcio(struct ccb_mmcio *mmcio, uint32_t retries,
> +            void (*cbfcnp)(struct cam_periph *, union ccb *), uint32_t flags,
> +            uint32_t mmc_opcode, uint32_t mmc_arg, uint32_t mmc_flags,
> +            struct mmc_data *mmc_d,
> +            uint32_t timeout)
> +{
> +     mmcio->ccb_h.func_code = XPT_MMC_IO;
> +     mmcio->ccb_h.flags = flags;
> +     mmcio->ccb_h.retry_count = retries;
> +     mmcio->ccb_h.cbfcnp = cbfcnp;
> +     mmcio->ccb_h.timeout = timeout;
> +     mmcio->cmd.opcode = mmc_opcode;
> +     mmcio->cmd.arg = mmc_arg;
> +     mmcio->cmd.flags = mmc_flags;
> +     mmcio->stop.opcode = 0;
> +     mmcio->stop.arg = 0;
> +     mmcio->stop.flags = 0;
> +     if (mmc_d != NULL) {
> +             mmcio->cmd.data = mmc_d;
> +     } else
> +             mmcio->cmd.data = NULL;
> +     mmcio->cmd.resp[0] = 0;
> +     mmcio->cmd.resp[1] = 0;
> +     mmcio->cmd.resp[2] = 0;
> +     mmcio->cmd.resp[3] = 0;
>  }
>  
>  static __inline void
> 
> Modified: head/sys/cam/cam_periph.c
> ==============================================================================
> --- head/sys/cam/cam_periph.c Sun Jul  9 15:41:49 2017        (r320843)
> +++ head/sys/cam/cam_periph.c Sun Jul  9 16:57:24 2017        (r320844)
> @@ -827,6 +827,18 @@ cam_periph_mapmem(union ccb *ccb, struct cam_periph_ma
>               dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK;
>               numbufs = 1;
>               break;
> +     case XPT_MMC_IO:
> +             if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE)
> +                     return(0);
> +             /* Two mappings: one for cmd->data and one for cmd->data->data 
> */
> +             data_ptrs[0] = (unsigned char **)&ccb->mmcio.cmd.data;
> +             lengths[0] = sizeof(struct mmc_data *);
> +             dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK;
> +             data_ptrs[1] = (unsigned char **)&ccb->mmcio.cmd.data->data;
> +             lengths[1] = ccb->mmcio.cmd.data->len;
> +             dirs[1] = ccb->ccb_h.flags & CAM_DIR_MASK;
> +             numbufs = 2;
> +             break;
>       case XPT_SMP_IO:
>               data_ptrs[0] = &ccb->smpio.smp_request;
>               lengths[0] = ccb->smpio.smp_request_len;
> 
> Modified: head/sys/cam/cam_xpt.c
> ==============================================================================
> --- head/sys/cam/cam_xpt.c    Sun Jul  9 15:41:49 2017        (r320843)
> +++ head/sys/cam/cam_xpt.c    Sun Jul  9 16:57:24 2017        (r320844)
> @@ -329,7 +329,6 @@ static xpt_devicefunc_t   xptsetasyncfunc;
>  static xpt_busfunc_t xptsetasyncbusfunc;
>  static cam_status    xptregister(struct cam_periph *periph,
>                                   void *arg);
> -static const char *  xpt_action_name(uint32_t action);
>  static __inline int device_is_queued(struct cam_ed *device);
>  
>  static __inline int
> @@ -412,7 +411,7 @@ xptioctl(struct cdev *dev, u_long cmd, caddr_t addr, i
>       }
>       return (error);
>  }
> -     
> +
>  static int
>  xptdoioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct 
> thread *td)
>  {
> @@ -820,6 +819,8 @@ xpt_scanner_thread(void *dummy)
>                       TAILQ_REMOVE(&xsoftc.ccb_scanq, &ccb->ccb_h, 
> sim_links.tqe);
>                       xpt_unlock_buses();
>  
> +                        printf("xpt_scanner_thread is firing on path ");
> +                        xpt_print_path(ccb->ccb_h.path);printf("\n");
>                       /*
>                        * Since lock can be dropped inside and path freed
>                        * by completion callback even before return here,
> @@ -1503,7 +1504,7 @@ xptdevicematch(struct dev_match_pattern *patterns, u_i
>  
>               cur_pattern = &patterns[i].pattern.device_pattern;
>  
> -             /* Error out if mutually exclusive options are specified. */ 
> +             /* Error out if mutually exclusive options are specified. */
>               if ((cur_pattern->flags & (DEV_MATCH_INQUIRY|DEV_MATCH_DEVID))
>                == (DEV_MATCH_INQUIRY|DEV_MATCH_DEVID))
>                       return(DM_RET_ERROR);
> @@ -1905,6 +1906,9 @@ xptedtdevicefunc(struct cam_ed *device, void *arg)
>               bcopy(&device->ident_data,
>                     &cdm->matches[j].result.device_result.ident_data,
>                     sizeof(struct ata_params));
> +             bcopy(&device->mmc_ident_data,
> +                   &cdm->matches[j].result.device_result.mmc_ident_data,
> +                   sizeof(struct mmc_params));
>  
>               /* Let the user know whether this device is unconfigured */
>               if (device->flags & CAM_DEV_UNCONFIGURED)
> @@ -2690,6 +2694,8 @@ xpt_action_default(union ccb *start_ccb)
>               if (start_ccb->ccb_h.func_code == XPT_NVME_IO)
>                       start_ccb->nvmeio.resid = 0;
>               /* FALLTHROUGH */
> +     case XPT_MMC_IO:
> +             /* XXX just like nmve_io? */
>       case XPT_RESET_DEV:
>       case XPT_ENG_EXEC:
>       case XPT_SMP_IO:
> @@ -2801,11 +2807,12 @@ call_sim:
>                       mtx_lock(mtx);
>               else
>                       mtx = NULL;
> +
>               CAM_DEBUG(path, CAM_DEBUG_TRACE,
> -                 ("sim->sim_action: func=%#x\n", 
> start_ccb->ccb_h.func_code));
> +                 ("Calling sim->sim_action(): func=%#x\n",
> start_ccb->ccb_h.func_code)); (*(sim->sim_action))(sim, start_ccb);
>               CAM_DEBUG(path, CAM_DEBUG_TRACE,
> -                 ("sim->sim_action: status=%#x\n", start_ccb->ccb_h.status));
> +                 ("sim->sim_action returned: status=%#x\n",
> start_ccb->ccb_h.status)); if (mtx)
>                       mtx_unlock(mtx);
>               break;
> @@ -5540,7 +5547,7 @@ static struct kv map[] = {
>       { XPT_GET_SIM_KNOB, "XPT_GET_SIM_KNOB" },
>       { XPT_SET_SIM_KNOB, "XPT_SET_SIM_KNOB" },
>       { XPT_NVME_IO, "XPT_NVME_IO" },
> -     { XPT_MMCSD_IO, "XPT_MMCSD_IO" },
> +     { XPT_MMC_IO, "XPT_MMC_IO" },
>       { XPT_SMP_IO, "XPT_SMP_IO" },
>       { XPT_SCAN_TGT, "XPT_SCAN_TGT" },
>       { XPT_ENG_INQ, "XPT_ENG_INQ" },
> @@ -5556,7 +5563,7 @@ static struct kv map[] = {
>       { 0, 0 }
>  };
>  
> -static const char *
> +const char *
>  xpt_action_name(uint32_t action) 
>  {
>       static char buffer[32]; /* Only for unknown messages -- racy */
> 
> Modified: head/sys/cam/cam_xpt.h
> ==============================================================================
> --- head/sys/cam/cam_xpt.h    Sun Jul  9 15:41:49 2017        (r320843)
> +++ head/sys/cam/cam_xpt.h    Sun Jul  9 16:57:24 2017        (r320844)
> @@ -141,6 +141,8 @@ void                      xpt_copy_path(struct cam_path 
> *new_path,
>  
>  void                 xpt_release_path(struct cam_path *path);
>  
> +const char *         xpt_action_name(uint32_t action);
> +
>  #endif /* _KERNEL */
>  
>  #endif /* _CAM_CAM_XPT_H */
> 
> Modified: head/sys/cam/cam_xpt_internal.h
> ==============================================================================
> --- head/sys/cam/cam_xpt_internal.h   Sun Jul  9 15:41:49 2017        
> (r320843)
> +++ head/sys/cam/cam_xpt_internal.h   Sun Jul  9 16:57:24 2017        
> (r320844)
> @@ -125,6 +125,7 @@ struct cam_ed {
>       uint32_t         rcap_len;
>       uint8_t          *rcap_buf;
>       struct           ata_params ident_data;
> +        struct                mmc_params mmc_ident_data;
>       u_int8_t         inq_flags;     /*
>                                        * Current settings for inquiry flags.
>                                        * This allows us to override settings
> 
> Copied and modified: head/sys/cam/mmc/mmc.h (from r320843, 
> head/sys/dev/mmc/mmcbrvar.h)
> ==============================================================================
> --- head/sys/dev/mmc/mmcbrvar.h       Sun Jul  9 15:41:49 2017        
> (r320843, copy
> source) +++ head/sys/cam/mmc/mmc.h    Sun Jul  9 16:57:24 2017        
> (r320844)
> @@ -1,6 +1,5 @@
>  /*-
> - * Copyright (c) 2006 Bernd Walter.  All rights reserved.
> - * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
> + * Copyright (c) 2014-2016 Ilya Bakulin.  All rights reserved.
>   *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
> @@ -49,77 +48,47 @@
>   * or the SD Card Association to disclose or distribute any technical
>   * information, know-how or other confidential information to any third 
> party.
>   *
> + * Inspired coded in sys/dev/mmc. Thanks to Warner Losh <i...@freebsd.org>,
> + * Bernd Walter <ti...@freebsd.org>, and other authors.
> + *
>   * $FreeBSD$
>   */
>  
> -#ifndef DEV_MMC_MMCBRVAR_H
> -#define      DEV_MMC_MMCBRVAR_H
> +#ifndef CAM_MMC_H
> +#define CAM_MMC_H
>  
>  #include <dev/mmc/mmcreg.h>
> -
> -#include "mmcbr_if.h"
> -
> -enum mmcbr_device_ivars {
> -    MMCBR_IVAR_BUS_MODE,
> -    MMCBR_IVAR_BUS_WIDTH,
> -    MMCBR_IVAR_CHIP_SELECT,
> -    MMCBR_IVAR_CLOCK,
> -    MMCBR_IVAR_F_MIN,
> -    MMCBR_IVAR_F_MAX,
> -    MMCBR_IVAR_HOST_OCR,
> -    MMCBR_IVAR_MODE,
> -    MMCBR_IVAR_OCR,
> -    MMCBR_IVAR_POWER_MODE,
> -    MMCBR_IVAR_VDD,
> -    MMCBR_IVAR_VCCQ,
> -    MMCBR_IVAR_CAPS,
> -    MMCBR_IVAR_TIMING,
> -    MMCBR_IVAR_MAX_DATA,
> -    MMCBR_IVAR_MAX_BUSY_TIMEOUT
> -};
> -
>  /*
> - * Simplified accessors for bridge devices
> + * This structure describes an MMC/SD card
>   */
> -#define      MMCBR_ACCESSOR(var, ivar, type)                                 
> \
> -     __BUS_ACCESSOR(mmcbr, var, MMCBR, ivar, type)
> +struct mmc_params {
> +        u_int8_t     model[40]; /* Card model */
>  
> -MMCBR_ACCESSOR(bus_mode, BUS_MODE, int)
> -MMCBR_ACCESSOR(bus_width, BUS_WIDTH, int)
> -MMCBR_ACCESSOR(chip_select, CHIP_SELECT, int)
> -MMCBR_ACCESSOR(clock, CLOCK, int)
> -MMCBR_ACCESSOR(f_max, F_MAX, int)
> -MMCBR_ACCESSOR(f_min, F_MIN, int)
> -MMCBR_ACCESSOR(host_ocr, HOST_OCR, int)
> -MMCBR_ACCESSOR(mode, MODE, int)
> -MMCBR_ACCESSOR(ocr, OCR, int)
> -MMCBR_ACCESSOR(power_mode, POWER_MODE, int)
> -MMCBR_ACCESSOR(vdd, VDD, int)
> -MMCBR_ACCESSOR(vccq, VCCQ, int)
> -MMCBR_ACCESSOR(caps, CAPS, int)
> -MMCBR_ACCESSOR(timing, TIMING, int)
> -MMCBR_ACCESSOR(max_data, MAX_DATA, int)
> -MMCBR_ACCESSOR(max_busy_timeout, MAX_BUSY_TIMEOUT, u_int)
> +        /* Card OCR */
> +        uint32_t card_ocr;
>  
> -static int __inline
> -mmcbr_update_ios(device_t dev)
> -{
> +        /* OCR of the IO portion of the card */
> +        uint32_t io_ocr;
>  
> -     return (MMCBR_UPDATE_IOS(device_get_parent(dev), dev));
> -}
> +        /* Card CID -- raw and parsed */
> +        uint32_t card_cid[4];
> +        struct mmc_cid  cid;
>  
> -static int __inline
> -mmcbr_switch_vccq(device_t dev)
> -{
> +        /* Card CSD -- raw */
> +        uint32_t card_csd[4];
>  
> -     return (MMCBR_SWITCH_VCCQ(device_get_parent(dev), dev));
> -}
> +        /* Card RCA */
> +        uint16_t card_rca;
>  
> -static int __inline
> -mmcbr_get_ro(device_t dev)
> -{
> +        /* What kind of card is it */
> +        uint32_t card_features;
> +#define CARD_FEATURE_MEMORY 0x1
> +#define CARD_FEATURE_SDHC   0x1 << 1
> +#define CARD_FEATURE_SDIO   0x1 << 2
> +#define CARD_FEATURE_SD20   0x1 << 3
> +#define CARD_FEATURE_MMC    0x1 << 4
>  
> -     return (MMCBR_GET_RO(device_get_parent(dev), dev));
> -}
> +        uint8_t sdio_func_count;
> +} __packed;
>  
> -#endif /* DEV_MMC_MMCBRVAR_H */
> +#endif
> 
> Copied and modified: head/sys/cam/mmc/mmc_all.h (from r320843,
> head/sys/dev/mmc/mmcbrvar.h)
> ==============================================================================
>  ---
> head/sys/dev/mmc/mmcbrvar.h   Sun Jul  9 15:41:49 2017        (r320843, copy
> source) +++ head/sys/cam/mmc/mmc_all.h        Sun Jul  9 16:57:24 2017        
> (r320844)
> @@ -1,6 +1,5 @@ /*-
> - * Copyright (c) 2006 Bernd Walter.  All rights reserved.
> - * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
> + * Copyright (c) 2014-2016 Ilya Bakulin.  All rights reserved.
>   *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
> @@ -52,74 +51,20 @@
>   * $FreeBSD$
>   */
>  
> -#ifndef DEV_MMC_MMCBRVAR_H
> -#define      DEV_MMC_MMCBRVAR_H
> -
> -#include <dev/mmc/mmcreg.h>
> -
> -#include "mmcbr_if.h"
> -
> -enum mmcbr_device_ivars {
> -    MMCBR_IVAR_BUS_MODE,
> -    MMCBR_IVAR_BUS_WIDTH,
> -    MMCBR_IVAR_CHIP_SELECT,
> -    MMCBR_IVAR_CLOCK,
> -    MMCBR_IVAR_F_MIN,
> -    MMCBR_IVAR_F_MAX,
> -    MMCBR_IVAR_HOST_OCR,
> -    MMCBR_IVAR_MODE,
> -    MMCBR_IVAR_OCR,
> -    MMCBR_IVAR_POWER_MODE,
> -    MMCBR_IVAR_VDD,
> -    MMCBR_IVAR_VCCQ,
> -    MMCBR_IVAR_CAPS,
> -    MMCBR_IVAR_TIMING,
> -    MMCBR_IVAR_MAX_DATA,
> -    MMCBR_IVAR_MAX_BUSY_TIMEOUT
> -};
> -
>  /*
> - * Simplified accessors for bridge devices
> + * MMC function that should be visible to the CAM subsystem
> + * and are somehow useful should be declared here
> + *
> + * Like in other *_all.h, it's also a nice place to include
> + * some other transport-specific headers.
>   */
> -#define      MMCBR_ACCESSOR(var, ivar, type)                                 
> \
> -     __BUS_ACCESSOR(mmcbr, var, MMCBR, ivar, type)
>  
> -MMCBR_ACCESSOR(bus_mode, BUS_MODE, int)
> -MMCBR_ACCESSOR(bus_width, BUS_WIDTH, int)
> -MMCBR_ACCESSOR(chip_select, CHIP_SELECT, int)
> -MMCBR_ACCESSOR(clock, CLOCK, int)
> -MMCBR_ACCESSOR(f_max, F_MAX, int)
> -MMCBR_ACCESSOR(f_min, F_MIN, int)
> -MMCBR_ACCESSOR(host_ocr, HOST_OCR, int)
> -MMCBR_ACCESSOR(mode, MODE, int)
> -MMCBR_ACCESSOR(ocr, OCR, int)
> -MMCBR_ACCESSOR(power_mode, POWER_MODE, int)
> -MMCBR_ACCESSOR(vdd, VDD, int)
> -MMCBR_ACCESSOR(vccq, VCCQ, int)
> -MMCBR_ACCESSOR(caps, CAPS, int)
> -MMCBR_ACCESSOR(timing, TIMING, int)
> -MMCBR_ACCESSOR(max_data, MAX_DATA, int)
> -MMCBR_ACCESSOR(max_busy_timeout, MAX_BUSY_TIMEOUT, u_int)
> +#ifndef CAM_MMC_ALL_H
> +#define CAM_MMC_ALL_H
>  
> -static int __inline
> -mmcbr_update_ios(device_t dev)
> -{
> +#include <cam/mmc/mmc.h>
> +#include <dev/mmc/mmcreg.h>
>  
> -     return (MMCBR_UPDATE_IOS(device_get_parent(dev), dev));
> -}
> +void mmc_print_ident(struct mmc_params *ident_data);
>  
> -static int __inline
> -mmcbr_switch_vccq(device_t dev)
> -{
> -
> -     return (MMCBR_SWITCH_VCCQ(device_get_parent(dev), dev));
> -}
> -
> -static int __inline
> -mmcbr_get_ro(device_t dev)
> -{
> -
> -     return (MMCBR_GET_RO(device_get_parent(dev), dev));
> -}
> -
> -#endif /* DEV_MMC_MMCBRVAR_H */
> +#endif
> 
> Added: head/sys/cam/mmc/mmc_bus.h
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/sys/cam/mmc/mmc_bus.h        Sun Jul  9 16:57:24 2017        
> (r320844)
> @@ -0,0 +1,5 @@
> +/*
> + * This file is in the public domain.
> + * $FreeBSD$
> + */
> +#include <dev/mmc/bridge.h>
> 
> Added: head/sys/cam/mmc/mmc_da.c
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/sys/cam/mmc/mmc_da.c Sun Jul  9 16:57:24 2017        (r320844)
> @@ -0,0 +1,1432 @@
> +/*-
> + * Copyright (c) 2006 Bernd Walter <ti...@freebsd.org>
> + * Copyright (c) 2006 M. Warner Losh <i...@freebsd.org>
> + * Copyright (c) 2009 Alexander Motin <m...@freebsd.org>
> + * Copyright (c) 2015-2017 Ilya Bakulin <ki...@freebsd.org>
> + * All rights reserved.
> + *
> + * 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,
> + *    without modification, immediately at the beginning of the file.
> + * 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 ``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 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.
> + *
> + * Some code derived from the sys/dev/mmc and sys/cam/ata
> + * Thanks to Warner Losh <i...@freebsd.org>, Alexander Motin 
> <m...@freebsd.org>
> + * Bernd Walter <ti...@freebsd.org>, and other authors.
> + */
> +
> +#include <sys/cdefs.h>
> +__FBSDID("$FreeBSD$");
> +
> +//#include "opt_sdda.h"
> +
> +#include <sys/param.h>
> +
> +#ifdef _KERNEL
> +#include <sys/systm.h>
> +#include <sys/kernel.h>
> +#include <sys/bio.h>
> +#include <sys/endian.h>
> +#include <sys/taskqueue.h>
> +#include <sys/lock.h>
> +#include <sys/mutex.h>
> +#include <sys/conf.h>
> +#include <sys/devicestat.h>
> +#include <sys/eventhandler.h>
> +#include <sys/malloc.h>
> +#include <sys/cons.h>
> +#include <sys/proc.h>
> +#include <sys/reboot.h>
> +#include <geom/geom_disk.h>
> +#include <machine/_inttypes.h>  /* for PRIu64 */
> +#endif /* _KERNEL */
> +
> +#ifndef _KERNEL
> +#include <stdio.h>
> +#include <string.h>
> +#endif /* _KERNEL */
> +
> +#include <cam/cam.h>
> +#include <cam/cam_ccb.h>
> +#include <cam/cam_queue.h>
> +#include <cam/cam_periph.h>
> +#include <cam/cam_sim.h>
> +#include <cam/cam_xpt.h>
> +#include <cam/cam_xpt_sim.h>
> +#include <cam/cam_xpt_periph.h>
> +#include <cam/cam_xpt_internal.h>
> +#include <cam/cam_debug.h>
> +
> +
> +#include <cam/mmc/mmc_all.h>
> +
> +#include <machine/md_var.h>  /* geometry translation */
> +
> +#ifdef _KERNEL
> +
> +typedef enum {
> +     SDDA_FLAG_OPEN          = 0x0002,
> +     SDDA_FLAG_DIRTY         = 0x0004
> +} sdda_flags;
> +
> +typedef enum {
> +        SDDA_STATE_INIT,
> +        SDDA_STATE_INVALID,
> +        SDDA_STATE_NORMAL
> +} sdda_state;
> +
> +struct sdda_softc {
> +     struct   bio_queue_head bio_queue;
> +     int      outstanding_cmds;      /* Number of active commands */
> +     int      refcount;              /* Active xpt_action() calls */
> +     sdda_state state;
> +     sdda_flags flags;
> +     struct mmc_data *mmcdata;
> +//   sdda_quirks quirks;
> +     struct task start_init_task;
> +     struct   disk *disk;
> +        uint32_t raw_csd[4];
> +     uint8_t raw_ext_csd[512]; /* MMC only? */
> +        struct mmc_csd csd;
> +        struct mmc_cid cid;
> +     struct mmc_scr scr;
> +        /* Calculated from CSD */
> +        uint64_t sector_count;
> +        uint64_t mediasize;
> +
> +        /* Calculated from CID */
> +     char card_id_string[64];/* Formatted CID info (serial, MFG, etc) */
> +     char card_sn_string[16];/* Formatted serial # for disk->d_ident */
> +     /* Determined from CSD + is highspeed card*/
> +     uint32_t card_f_max;
> +};
> +
> +#define ccb_bp               ppriv_ptr1
> +
> +static       disk_strategy_t sddastrategy;
> +static       periph_init_t   sddainit;
> +static       void            sddaasync(void *callback_arg, u_int32_t code,
> +                             struct cam_path *path, void *arg);
> +static       periph_ctor_t   sddaregister;
> +static       periph_dtor_t   sddacleanup;
> +static       periph_start_t  sddastart;
> +static       periph_oninv_t  sddaoninvalidate;
> +static       void            sddadone(struct cam_periph *periph,
> +                            union ccb *done_ccb);
> +static  int          sddaerror(union ccb *ccb, u_int32_t cam_flags,
> +                             u_int32_t sense_flags);
> +
> +static uint16_t get_rca(struct cam_periph *periph);
> +static cam_status sdda_hook_into_geom(struct cam_periph *periph);
> +static void sdda_start_init(void *context, union ccb *start_ccb);
> +static void sdda_start_init_task(void *context, int pending);
> +
> +static struct periph_driver sddadriver =
> +{
> +     sddainit, "sdda",
> +     TAILQ_HEAD_INITIALIZER(sddadriver.units), /* generation */ 0
> +};
> +
> +PERIPHDRIVER_DECLARE(sdda, sddadriver);
> +
> +static MALLOC_DEFINE(M_SDDA, "sd_da", "sd_da buffers");
> +
> +static const int exp[8] = {
> +     1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
> +};
> +
> +static const int mant[16] = {
> +     0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
> +};
> +
> +static const int cur_min[8] = {
> +     500, 1000, 5000, 10000, 25000, 35000, 60000, 100000
> +};
> +
> +static const int cur_max[8] = {
> +     1000, 5000, 10000, 25000, 35000, 45000, 800000, 200000
> +};
> +
> +static uint16_t
> +get_rca(struct cam_periph *periph) {
> +     return periph->path->device->mmc_ident_data.card_rca;
> +}
> +
> +static uint32_t
> +mmc_get_bits(uint32_t *bits, int bit_len, int start, int size)
> +{
> +     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));
> +}
> +
> +
> +static void
> +mmc_decode_csd_sd(uint32_t *raw_csd, struct mmc_csd *csd)
> +{
> +     int v;
> +     int m;
> +     int e;
> +
> +     memset(csd, 0, sizeof(*csd));
> +     csd->csd_structure = v = mmc_get_bits(raw_csd, 128, 126, 2);
> +     if (v == 0) {
> +             m = mmc_get_bits(raw_csd, 128, 115, 4);
> +             e = mmc_get_bits(raw_csd, 128, 112, 3);
> +             csd->tacc = (exp[e] * mant[m] + 9) / 10;
> +             csd->nsac = mmc_get_bits(raw_csd, 128, 104, 8) * 100;
> +             m = mmc_get_bits(raw_csd, 128, 99, 4);
> +             e = mmc_get_bits(raw_csd, 128, 96, 3);
> +             csd->tran_speed = exp[e] * 10000 * mant[m];
> +             csd->ccc = mmc_get_bits(raw_csd, 128, 84, 12);
> +             csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 128, 80, 4);
> +             csd->read_bl_partial = mmc_get_bits(raw_csd, 128, 79, 1);
> +             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)];
> +             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;
> +             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);
> +             csd->wp_grp_enable = mmc_get_bits(raw_csd, 128, 31, 1);
> +             csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3);
> +             csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4);
> +             csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1);
> +     } else if (v == 1) {
> +             m = mmc_get_bits(raw_csd, 128, 115, 4);
> +             e = mmc_get_bits(raw_csd, 128, 112, 3);
> +             csd->tacc = (exp[e] * mant[m] + 9) / 10;
> +             csd->nsac = mmc_get_bits(raw_csd, 128, 104, 8) * 100;
> +             m = mmc_get_bits(raw_csd, 128, 99, 4);
> +             e = mmc_get_bits(raw_csd, 128, 96, 3);
> +             csd->tran_speed = exp[e] * 10000 * mant[m];
> +             csd->ccc = mmc_get_bits(raw_csd, 128, 84, 12);
> +             csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 128, 80, 4);
> +             csd->read_bl_partial = mmc_get_bits(raw_csd, 128, 79, 1);
> +             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->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);
> +             csd->wp_grp_enable = mmc_get_bits(raw_csd, 128, 31, 1);
> +             csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3);
> +             csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4);
> +             csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1);
> +     } else
> +             panic("unknown SD CSD version");
> +}
> +
> +static void
> +mmc_decode_csd_mmc(uint32_t *raw_csd, struct mmc_csd *csd)
> +{
> +     int m;
> +     int e;
> +
> +     memset(csd, 0, sizeof(*csd));
> +     csd->csd_structure = mmc_get_bits(raw_csd, 128, 126, 2);
> +     csd->spec_vers = mmc_get_bits(raw_csd, 128, 122, 4);
> +     m = mmc_get_bits(raw_csd, 128, 115, 4);
> +     e = mmc_get_bits(raw_csd, 128, 112, 3);
> +     csd->tacc = exp[e] * mant[m] + 9 / 10;
> +     csd->nsac = mmc_get_bits(raw_csd, 128, 104, 8) * 100;
> +     m = mmc_get_bits(raw_csd, 128, 99, 4);
> +     e = mmc_get_bits(raw_csd, 128, 96, 3);
> +     csd->tran_speed = exp[e] * 10000 * mant[m];
> +     csd->ccc = mmc_get_bits(raw_csd, 128, 84, 12);
> +     csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 128, 80, 4);
> +     csd->read_bl_partial = mmc_get_bits(raw_csd, 128, 79, 1);
> +     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)];
> +     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;
> +     csd->erase_blk_en = 0;
> +     csd->erase_sector = (mmc_get_bits(raw_csd, 128, 42, 5) + 1) *
> +         (mmc_get_bits(raw_csd, 128, 37, 5) + 1);
> +     csd->wp_grp_size = mmc_get_bits(raw_csd, 128, 32, 5);
> +     csd->wp_grp_enable = mmc_get_bits(raw_csd, 128, 31, 1);
> +     csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3);
> +     csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4);
> +     csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1);
> +}
> +
> +static void
> +mmc_decode_cid_sd(uint32_t *raw_cid, struct mmc_cid *cid)
> +{
> +     int i;
> +
> +     /* There's no version info, so we take it on faith */
> +     memset(cid, 0, sizeof(*cid));
> 
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
> _______________________________________________
> svn-src-h...@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-head
> To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

r320847 doesn't boot. It cycles all over a kernel panic (looks like a trap12), 
reboots.
Then, sometimes if the boot process can proceed after an erratic number of 
attempts, it
gets stuck in the loader's mountroot, bad device 16 error.

I can not say whether this is due to this commit (On the crashing box, I have no
debugging enabled an I'm back with r320829 which seems to work).

-- 
O. Hartmann

Ich widerspreche der Nutzung oder Übermittlung meiner Daten für
Werbezwecke oder für die Markt- oder Meinungsforschung (§ 28 Abs. 4 BDSG).

Attachment: pgpNqDz6ebSXh.pgp
Description: OpenPGP digital signature

Reply via email to