Author: mav
Date: Mon Feb 23 19:52:47 2009
New Revision: 188952
URL: http://svn.freebsd.org/changeset/base/188952

Log:
  MFC rev. 187525 187543 187546 187551 187875 187877 188044 188725
  
  Sync MMC subsystem with HEAD.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/dev/mmc/mmc.c
  stable/7/sys/dev/mmc/mmcreg.h
  stable/7/sys/dev/mmc/mmcsd.c

Modified: stable/7/sys/dev/mmc/mmc.c
==============================================================================
--- stable/7/sys/dev/mmc/mmc.c  Mon Feb 23 19:31:48 2009        (r188951)
+++ stable/7/sys/dev/mmc/mmc.c  Mon Feb 23 19:52:47 2009        (r188952)
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mutex.h>
 #include <sys/bus.h>
 #include <sys/endian.h>
+#include <sys/sysctl.h>
 
 #include <dev/mmc/mmcreg.h>
 #include <dev/mmc/mmcbrvar.h>
@@ -104,6 +105,11 @@ struct mmc_ivars {
 
 #define CMD_RETRIES    3
 
+SYSCTL_NODE(_hw, OID_AUTO, mmc, CTLFLAG_RD, NULL, "mmc driver");
+
+static int mmc_debug;
+SYSCTL_INT(_hw_mmc, OID_AUTO, debug, CTLFLAG_RW, &mmc_debug, 0, "Debug level");
+
 /* bus entry points */
 static int mmc_probe(device_t dev);
 static int mmc_attach(device_t dev);
@@ -233,7 +239,7 @@ mmc_acquire_bus(device_t busdev, device_
                        sc->last_rca = rca;
                        /* Prepare bus width for the new card. */
                        ivar = device_get_ivars(dev);
-                       if (bootverbose) {
+                       if (bootverbose || mmc_debug) {
                                device_printf(busdev,
                                    "setting bus width to %d bits\n",
                                    (ivar->bus_width == bus_width_4) ? 4 :
@@ -315,11 +321,21 @@ mmc_wait_for_req(struct mmc_softc *sc, s
 
        req->done = mmc_wakeup;
        req->done_data = sc;
+       if (mmc_debug > 1) {
+               device_printf(sc->dev, "REQUEST: CMD%d arg %#x flags %#x",
+                   req->cmd->opcode, req->cmd->arg, req->cmd->flags);
+               if (req->cmd->data) {
+                       printf(" data %d\n", (int)req->cmd->data->len);
+               } else
+                       printf("\n");
+       }
        MMCBR_REQUEST(device_get_parent(sc->dev), sc->dev, req);
        MMC_LOCK(sc);
        while ((req->flags & MMC_REQ_DONE) == 0)
                msleep(req, &sc->sc_mtx, 0, "mmcreq", 0);
        MMC_UNLOCK(sc);
+       if (mmc_debug > 2 || (mmc_debug > 1 && req->cmd->error))
+               device_printf(sc->dev, "RESULT: %d\n", req->cmd->error);
        return (0);
 }
 
@@ -340,7 +356,6 @@ mmc_wait_for_cmd(struct mmc_softc *sc, s
        memset(cmd->resp, 0, sizeof(cmd->resp));
        cmd->retries = retries;
        mreq.cmd = cmd;
-/*     printf("CMD: %x ARG %x\n", cmd->opcode, cmd->arg); */
        mmc_wait_for_req(sc, &mreq);
        return (cmd->error);
 }
@@ -555,7 +570,8 @@ mmc_switch(struct mmc_softc *sc, uint8_t
 }
 
 static int
-mmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value, 
uint8_t *res)
+mmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value,
+    uint8_t *res)
 {
        int err;
        struct mmc_command cmd;
@@ -563,11 +579,11 @@ mmc_sd_switch(struct mmc_softc *sc, uint
 
        memset(&cmd, 0, sizeof(struct mmc_command));
        memset(&data, 0, sizeof(struct mmc_data));
-
        memset(res, 0, 64);
+
        cmd.opcode = SD_SWITCH_FUNC;
        cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
-       cmd.arg = mode << 31;
+       cmd.arg = mode << 31;                   /* 0 - check, 1 - set */
        cmd.arg |= 0x00FFFFFF;
        cmd.arg &= ~(0xF << (grp * 4));
        cmd.arg |= value << (grp * 4);
@@ -584,11 +600,11 @@ mmc_sd_switch(struct mmc_softc *sc, uint
 static int
 mmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width)
 {
+       struct mmc_command cmd;
        int err;
+       uint8_t value;
 
        if (mmcbr_get_mode(sc->dev) == mode_sd) {
-               struct mmc_command cmd;
-
                memset(&cmd, 0, sizeof(struct mmc_command));
                cmd.opcode = ACMD_SET_BUS_WIDTH;
                cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
@@ -604,8 +620,6 @@ mmc_set_card_bus_width(struct mmc_softc 
                }
                err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES);
        } else {
-               uint8_t value;
-
                switch (width) {
                case bus_width_1:
                        value = EXT_CSD_BUS_WIDTH_1;
@@ -619,7 +633,8 @@ 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, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
+                   value);
        }
        return (err);
 }
@@ -629,6 +644,7 @@ mmc_set_timing(struct mmc_softc *sc, int
 {
        int err;
        uint8_t value;
+       u_char switch_res[64];
 
        switch (timing) {
        case bus_timing_normal:
@@ -640,14 +656,12 @@ mmc_set_timing(struct mmc_softc *sc, int
        default:
                return (MMC_ERR_INVALID);
        }
-       if (mmcbr_get_mode(sc->dev) == mode_sd) {
-               u_char switch_res[64];
-
-               err = mmc_sd_switch(sc, 1, 0, value, switch_res);
-       } else {
+       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);
-       }
        return (err);
 }
 
@@ -749,9 +763,10 @@ mmc_decode_cid_sd(uint32_t *raw_cid, str
        cid->oid = mmc_get_bits(raw_cid, 128, 104, 16);
        for (i = 0; i < 5; i++)
                cid->pnm[i] = mmc_get_bits(raw_cid, 128, 96 - i * 8, 8);
+       cid->pnm[5] = 0;
        cid->prv = mmc_get_bits(raw_cid, 128, 56, 8);
        cid->psn = mmc_get_bits(raw_cid, 128, 24, 32);
-       cid->mdt_year = mmc_get_bits(raw_cid, 128, 12, 8) + 2001;
+       cid->mdt_year = mmc_get_bits(raw_cid, 128, 12, 8) + 2000;
        cid->mdt_month = mmc_get_bits(raw_cid, 128, 8, 4);
 }
 
@@ -766,6 +781,7 @@ mmc_decode_cid_mmc(uint32_t *raw_cid, st
        cid->oid = mmc_get_bits(raw_cid, 128, 104, 8);
        for (i = 0; i < 6; i++)
                cid->pnm[i] = mmc_get_bits(raw_cid, 128, 96 - i * 8, 8);
+       cid->pnm[6] = 0;
        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);
@@ -1060,6 +1076,29 @@ mmc_send_relative_addr(struct mmc_softc 
 }
 
 static void
+mmc_log_card(device_t dev, struct mmc_ivars *ivar, int newcard)
+{
+       device_printf(dev, "Card at relative address %d%s:\n",
+           ivar->rca, newcard ? " added" : "");
+       device_printf(dev, " card: %s%s (0x%x/0x%x/\"%s\" rev %d.%d "
+           "m/d %02d.%04d s/n %08x)\n",
+           ivar->mode == mode_sd ? "SD" : "MMC",
+           ivar->high_cap ? " High Capacity" : "", 
+           ivar->cid.mid, ivar->cid.oid,
+           ivar->cid.pnm, ivar->cid.prv >> 4, ivar->cid.prv & 0x0f,
+           ivar->cid.mdt_month, ivar->cid.mdt_year, ivar->cid.psn);
+       device_printf(dev, " bus: %ubit, %uMHz%s\n",
+           (ivar->bus_width == bus_width_1 ? 1 :
+           (ivar->bus_width == bus_width_4 ? 4 : 8)),
+           (ivar->timing == bus_timing_hs ?
+               ivar->hs_tran_speed : ivar->tran_speed) / 1000000,
+           ivar->timing == bus_timing_hs ? ", high speed timing" : "");
+       device_printf(dev, " memory: %u blocks, erase sector %u blocks%s\n",
+           ivar->sec_count, ivar->erase_sector,
+           ivar->read_only ? ", read-only" : "");
+}
+
+static void
 mmc_discover_cards(struct mmc_softc *sc)
 {
        struct mmc_ivars *ivar = NULL;
@@ -1071,6 +1110,8 @@ mmc_discover_cards(struct mmc_softc *sc)
        uint16_t rca = 2;
        u_char switch_res[64];
 
+       if (bootverbose || mmc_debug)
+               device_printf(sc->dev, "Probing cards\n");
        while (1) {
                err = mmc_all_send_cid(sc, raw_cid);
                if (err == MMC_ERR_TIMEOUT)
@@ -1090,6 +1131,11 @@ mmc_discover_cards(struct mmc_softc *sc)
                        }
                }
                free(devlist, M_TEMP);
+               if (bootverbose || mmc_debug) {
+                       device_printf(sc->dev, "%sard detected (CID 
%08x%08x%08x%08x)\n",
+                           newcard ? "New c" : "C",
+                           raw_cid[0], raw_cid[1], raw_cid[2], raw_cid[3]);
+               }
                if (newcard) {
                        ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF,
                            M_WAITOK | M_ZERO);
@@ -1100,6 +1146,7 @@ mmc_discover_cards(struct mmc_softc *sc)
                if (mmcbr_get_ro(sc->dev))
                        ivar->read_only = 1;
                ivar->bus_width = bus_width_1;
+               ivar->timing = bus_timing_normal;
                ivar->mode = mmcbr_get_mode(sc->dev);
                if (ivar->mode == mode_sd) {
                        mmc_decode_cid_sd(ivar->raw_cid, &ivar->cid);
@@ -1118,13 +1165,15 @@ mmc_discover_cards(struct mmc_softc *sc)
                        mmc_select_card(sc, ivar->rca);
                        mmc_app_send_scr(sc, ivar->rca, ivar->raw_scr);
                        mmc_app_decode_scr(ivar->raw_scr, &ivar->scr);
-                       /* Get card switch capabilities. */
+                       /* Get card switch capabilities (command class 10). */
                        if ((ivar->scr.sda_vsn >= 1) &&
                            (ivar->csd.ccc & (1<<10))) {
-                               mmc_sd_switch(sc, 0, 0, 0xF, switch_res);
+                               mmc_sd_switch(sc, SD_SWITCH_MODE_CHECK,
+                                   SD_SWITCH_GROUP1, SD_SWITCH_NOCHANGE,
+                                   switch_res);
                                if (switch_res[13] & 2) {
                                        ivar->timing = bus_timing_hs;
-                                       ivar->hs_tran_speed = 50000000;
+                                       ivar->hs_tran_speed = SD_MAX_HS;
                                }
                        }
                        mmc_app_sd_status(sc, ivar->rca, ivar->raw_sd_status);
@@ -1139,6 +1188,8 @@ mmc_discover_cards(struct mmc_softc *sc)
                        if ((mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) &&
                            (ivar->scr.bus_widths & SD_SCR_BUS_WIDTH_4))
                                ivar->bus_width = bus_width_4;
+                       if (bootverbose || mmc_debug)
+                               mmc_log_card(sc->dev, ivar, newcard);
                        if (newcard) {
                                /* Add device. */
                                child = device_add_child(sc->dev, NULL, -1);
@@ -1174,10 +1225,10 @@ mmc_discover_cards(struct mmc_softc *sc)
                        ivar->timing = bus_timing_hs;
                        if (ivar->raw_ext_csd[EXT_CSD_CARD_TYPE]
                            & EXT_CSD_CARD_TYPE_52)
-                               ivar->hs_tran_speed = 52000000;
+                               ivar->hs_tran_speed = MMC_TYPE_52_MAX_HS;
                        else if (ivar->raw_ext_csd[EXT_CSD_CARD_TYPE]
                            & EXT_CSD_CARD_TYPE_26)
-                               ivar->hs_tran_speed = 26000000;
+                               ivar->hs_tran_speed = MMC_TYPE_26_MAX_HS;
                        else
                                ivar->hs_tran_speed = ivar->tran_speed;
                        /* Find max supported bus width. */
@@ -1194,6 +1245,8 @@ mmc_discover_cards(struct mmc_softc *sc)
                        ivar->bus_width = bus_width_1;
                        ivar->timing = bus_timing_normal;
                }
+               if (bootverbose || mmc_debug)
+                       mmc_log_card(sc->dev, ivar, newcard);
                if (newcard) {
                        /* Add device. */
                        child = device_add_child(sc->dev, NULL, -1);
@@ -1214,6 +1267,9 @@ mmc_rescan_cards(struct mmc_softc *sc)
        for (i = 0; i < devcount; i++) {
                ivar = device_get_ivars(devlist[i]);
                if (mmc_select_card(sc, ivar->rca)) {
+                       if (bootverbose || mmc_debug)
+                               device_printf(sc->dev, "Card at relative 
address %d lost.\n",
+                                   ivar->rca);
                        device_delete_child(sc->dev, devlist[i]);
                        free(ivar, M_DEVBUF);
                }
@@ -1233,6 +1289,9 @@ mmc_delete_cards(struct mmc_softc *sc)
                return (err);
        for (i = 0; i < devcount; i++) {
                ivar = device_get_ivars(devlist[i]);
+               if (bootverbose || mmc_debug)
+                       device_printf(sc->dev, "Card at relative address %d 
deleted.\n",
+                           ivar->rca);
                device_delete_child(sc->dev, devlist[i]);
                free(ivar, M_DEVBUF);
        }
@@ -1255,17 +1314,30 @@ mmc_go_discovery(struct mmc_softc *sc)
                mmcbr_set_mode(dev, mode_sd);
                mmc_power_up(sc);
                mmcbr_set_bus_mode(dev, pushpull);
+               if (bootverbose || mmc_debug)
+                       device_printf(sc->dev, "Probing bus\n");
                mmc_idle_cards(sc);
                err = mmc_send_if_cond(sc, 1);
+               if ((bootverbose || mmc_debug) && err == 0)
+                       device_printf(sc->dev, "SD 2.0 interface conditions: 
OK\n");
                if (mmc_send_app_op_cond(sc, err ? 0 : MMC_OCR_CCS, &ocr) !=
                    MMC_ERR_NONE) {
+                       if (bootverbose || mmc_debug)
+                               device_printf(sc->dev, "SD probe: failed\n");
                        /*
                         * Failed, try MMC
                         */
                        mmcbr_set_mode(dev, mode_mmc);
-                       if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE)
+                       if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE) {
+                               if (bootverbose || mmc_debug)
+                                       device_printf(sc->dev, "MMC probe: 
failed\n");
                                ocr = 0; /* Failed both, powerdown. */
-               }
+                       } else if (bootverbose || mmc_debug)
+                               device_printf(sc->dev,
+                                   "MMC probe: OK (OCR: 0x%08x)\n", ocr);
+               } else if (bootverbose || mmc_debug)
+                       device_printf(sc->dev, "SD probe: OK (OCR: 0x%08x)\n", 
ocr);
+
                mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr));
                if (mmcbr_get_ocr(dev) != 0)
                        mmc_idle_cards(sc);
@@ -1279,6 +1351,8 @@ mmc_go_discovery(struct mmc_softc *sc)
         * Make sure that we have a mutually agreeable voltage to at least
         * one card on the bus.
         */
+       if (bootverbose || mmc_debug)
+               device_printf(sc->dev, "Current OCR: 0x%08x\n", 
mmcbr_get_ocr(dev));
        if (mmcbr_get_ocr(dev) == 0) {
                mmc_delete_cards(sc);
                mmc_power_down(sc);
@@ -1326,7 +1400,7 @@ mmc_calculate_clock(struct mmc_softc *sc
                        max_timing = ivar->timing;
                if (ivar->tran_speed < max_dtr)
                        max_dtr = ivar->tran_speed;
-               if (ivar->hs_tran_speed < max_dtr)
+               if (ivar->hs_tran_speed < max_hs_dtr)
                        max_hs_dtr = ivar->hs_tran_speed;
        }
        for (i = 0; i < nkid; i++) {
@@ -1340,7 +1414,7 @@ mmc_calculate_clock(struct mmc_softc *sc
        free(kids, M_TEMP);
        if (max_timing == bus_timing_hs)
                max_dtr = max_hs_dtr;
-       if (bootverbose) {
+       if (bootverbose || mmc_debug) {
                device_printf(sc->dev,
                    "setting transfer rate to %d.%03dMHz%s\n",
                    max_dtr / 1000000, (max_dtr / 1000) % 1000,
@@ -1454,5 +1528,5 @@ static driver_t mmc_driver = {
 static devclass_t mmc_devclass;
 
 
-DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, 0, 0);
-DRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, 0, 0);
+DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, NULL, NULL);
+DRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, NULL, NULL);

Modified: stable/7/sys/dev/mmc/mmcreg.h
==============================================================================
--- stable/7/sys/dev/mmc/mmcreg.h       Mon Feb 23 19:31:48 2009        
(r188951)
+++ stable/7/sys/dev/mmc/mmcreg.h       Mon Feb 23 19:52:47 2009        
(r188952)
@@ -97,6 +97,7 @@ struct mmc_command {
 #define        MMC_ERR_FAILED  4
 #define        MMC_ERR_INVALID 5
 #define        MMC_ERR_NO_MEMORY 6
+#define MMC_ERR_MAX    6
        struct mmc_data *data;          /* Data segment with cmd */
        struct mmc_request *mrq;        /* backpointer to request */
 };
@@ -287,7 +288,6 @@ struct mmc_request {
 /*
  * EXT_CSD fields
  */
-
 #define EXT_CSD_ERASE_GRP_DEF  175     /* R/W */
 #define EXT_CSD_BUS_WIDTH      183     /* R/W */
 #define EXT_CSD_HS_TIMING      185     /* R/W */
@@ -300,7 +300,6 @@ struct mmc_request {
 /*
  * EXT_CSD field definitions
  */
-
 #define EXT_CSD_CMD_SET_NORMAL         1
 #define EXT_CSD_CMD_SET_SECURE         2
 #define EXT_CSD_CMD_SET_CPSECURE       4
@@ -312,12 +311,27 @@ struct mmc_request {
 #define EXT_CSD_BUS_WIDTH_4    1
 #define EXT_CSD_BUS_WIDTH_8    2
 
+#define MMC_TYPE_26_MAX_HS     26000000
+#define MMC_TYPE_52_MAX_HS     52000000
+
 /*
  * SD bus widths
  */
 #define SD_BUS_WIDTH_1         0
 #define SD_BUS_WIDTH_4         2
 
+/*
+ * SD Switch
+ */
+#define SD_SWITCH_MODE_CHECK   0
+#define SD_SWITCH_MODE_SET     1
+#define SD_SWITCH_GROUP1       0
+#define SD_SWITCH_NORMAL_MODE  0
+#define SD_SWITCH_HS_MODE      1
+#define SD_SWITCH_NOCHANGE     0xF
+
+#define        SD_MAX_HS               50000000
+
 /* OCR bits */
 
 /*

Modified: stable/7/sys/dev/mmc/mmcsd.c
==============================================================================
--- stable/7/sys/dev/mmc/mmcsd.c        Mon Feb 23 19:31:48 2009        
(r188951)
+++ stable/7/sys/dev/mmc/mmcsd.c        Mon Feb 23 19:52:47 2009        
(r188952)
@@ -91,6 +91,8 @@ static int mmcsd_detach(device_t dev);
 static int mmcsd_open(struct disk *dp);
 static int mmcsd_close(struct disk *dp);
 static void mmcsd_strategy(struct bio *bp);
+static int mmcsd_dump(void *arg, void *virtual, vm_offset_t physical,
+       off_t offset, size_t length);
 static void mmcsd_task(void *arg);
 
 static const char *mmcsd_card_name(device_t dev);
@@ -130,7 +132,7 @@ mmcsd_attach(device_t dev)
        d->d_open = mmcsd_open;
        d->d_close = mmcsd_close;
        d->d_strategy = mmcsd_strategy;
-       // d->d_dump = mmcsd_dump;      Need polling mmc layer
+       d->d_dump = mmcsd_dump;
        d->d_name = "mmcsd";
        d->d_drv1 = sc;
        d->d_maxsize = 4*1024*1024;     /* Maximum defined SD card AU size. */
@@ -415,6 +417,33 @@ mmcsd_delete(struct mmcsd_softc *sc, str
        return (end);
 }
 
+static int
+mmcsd_dump(void *arg, void *virtual, vm_offset_t physical,
+       off_t offset, size_t length)
+{
+       struct disk *disk = arg;
+       struct mmcsd_softc *sc = (struct mmcsd_softc *)disk->d_drv1;
+       device_t dev = sc->dev;
+       struct bio bp;
+       daddr_t block, end;
+
+       /* length zero is special and really means flush buffers to media */
+       if (!length)
+               return (0);
+
+       bzero(&bp, sizeof(struct bio));
+       bp.bio_disk = disk;
+       bp.bio_pblkno = offset / disk->d_sectorsize;
+       bp.bio_bcount = length;
+       bp.bio_data = virtual;
+       bp.bio_cmd = BIO_WRITE;
+       end = bp.bio_pblkno + bp.bio_bcount / sc->disk->d_sectorsize;
+       MMCBUS_ACQUIRE_BUS(device_get_parent(dev), dev);
+       block = mmcsd_rw(sc, &bp);
+       MMCBUS_RELEASE_BUS(device_get_parent(dev), dev);
+       return ((end < block) ? EIO : 0);
+}
+
 static void
 mmcsd_task(void *arg)
 {
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to