From 0c24e06130bd034474a33a191c6da095f4f59a5e Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 23 Aug 2016 14:22:26 +0200 Subject: mmc: Update to FreeBSD trunk 2016-08-23 --- freebsd/sys/dev/mmc/bridge.h | 5 ++ freebsd/sys/dev/mmc/mmc.c | 200 ++++++++++++++++++++++++++++++------------- freebsd/sys/dev/mmc/mmcreg.h | 11 ++- freebsd/sys/dev/mmc/mmcsd.c | 120 ++++++++++++++++++-------- freebsd/sys/dev/mmc/mmcvar.h | 16 ++-- libbsd.txt | 1 + rtemsbsd/include/geom/geom.h | 0 7 files changed, 241 insertions(+), 112 deletions(-) create mode 100644 rtemsbsd/include/geom/geom.h diff --git a/freebsd/sys/dev/mmc/bridge.h b/freebsd/sys/dev/mmc/bridge.h index bd61c15a..a26c31ec 100644 --- a/freebsd/sys/dev/mmc/bridge.h +++ b/freebsd/sys/dev/mmc/bridge.h @@ -54,6 +54,8 @@ #ifndef DEV_MMC_BRIDGE_H #define DEV_MMC_BRIDGE_H +#include + /* * 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 @@ -135,4 +137,7 @@ struct mmc_host { struct mmc_ios ios; /* Current state of the host */ }; +extern driver_t mmc_driver; +extern devclass_t mmc_devclass; + #endif /* DEV_MMC_BRIDGE_H */ diff --git a/freebsd/sys/dev/mmc/mmc.c b/freebsd/sys/dev/mmc/mmc.c index 7a94dc48..d3c9fcb2 100644 --- a/freebsd/sys/dev/mmc/mmc.c +++ b/freebsd/sys/dev/mmc/mmc.c @@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -78,8 +79,13 @@ struct mmc_softc { 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 */ @@ -104,14 +110,17 @@ struct mmc_ivars { uint32_t hs_tran_speed; /* Max speed in high speed mode */ uint32_t erase_sector; /* Card native erase sector size */ 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 CARD_ID_FREQUENCY 400000 /* Spec requires 400kHz max during ID phase. */ + static SYSCTL_NODE(_hw, OID_AUTO, mmc, CTLFLAG_RD, NULL, "mmc driver"); static int mmc_debug; -SYSCTL_INT(_hw_mmc, OID_AUTO, debug, CTLFLAG_RW, &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); @@ -355,7 +364,8 @@ mmc_highest_voltage(uint32_t ocr) { int i; - for (i = 30; i >= 0; i--) + for (i = MMC_OCR_MAX_VOLTAGE_SHIFT; + i >= MMC_OCR_MIN_VOLTAGE_SHIFT; i--) if (ocr & (1 << i)) return (i); return (-1); @@ -392,8 +402,9 @@ mmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req) 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); + if (mmc_debug > 2 || (mmc_debug > 0 && req->cmd->error != MMC_ERR_NONE)) + device_printf(sc->dev, "CMD%d RESULT: %d\n", + req->cmd->opcode, req->cmd->error); return (0); } @@ -409,13 +420,28 @@ static int mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries) { struct mmc_request mreq; + int err; - memset(&mreq, 0, sizeof(mreq)); - memset(cmd->resp, 0, sizeof(cmd->resp)); - cmd->retries = retries; - mreq.cmd = cmd; - mmc_wait_for_req(sc, &mreq); - return (cmd->error); + 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 @@ -423,24 +449,38 @@ mmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca, struct mmc_command *cmd, int retries) { struct mmc_command appcmd; - int err = MMC_ERR_NONE, i; + int err; - for (i = 0; i <= retries; i++) { + /* 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; - mmc_wait_for_cmd(sc, &appcmd, 0); - err = appcmd.error; - if (err != MMC_ERR_NONE) - continue; - if (!(appcmd.resp[0] & R1_APP_CMD)) - return MMC_ERR_FAILED; - mmc_wait_for_cmd(sc, cmd, 0); - err = cmd->error; - if (err == MMC_ERR_NONE) - break; + 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); } @@ -459,8 +499,6 @@ mmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode, err = mmc_wait_for_cmd(sc, &cmd, retries); if (err) return (err); - if (cmd.error) - return (cmd.error); if (resp) { if (flags & MMC_RSP_136) memcpy(resp, cmd.resp, 4 * sizeof(uint32_t)); @@ -486,7 +524,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, 0); + mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); mmc_ms_delay(1); mmcbr_set_chip_select(dev, cs_dontcare); @@ -579,7 +617,7 @@ mmc_power_up(struct mmc_softc *sc) mmcbr_update_ios(dev); mmc_ms_delay(1); - mmcbr_set_clock(dev, mmcbr_get_f_min(sc->dev)); + mmcbr_set_clock(dev, CARD_ID_FREQUENCY); mmcbr_set_timing(dev, bus_timing_normal); mmcbr_set_power_mode(dev, power_on); mmcbr_update_ios(dev); @@ -616,6 +654,7 @@ 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) | @@ -623,7 +662,7 @@ mmc_switch(struct mmc_softc *sc, uint8_t set, uint8_t index, uint8_t value) set; cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; cmd.data = NULL; - err = mmc_wait_for_cmd(sc, &cmd, 0); + err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); return (err); } @@ -635,8 +674,8 @@ mmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value, struct mmc_command cmd; struct mmc_data data; - memset(&cmd, 0, sizeof(struct mmc_command)); - memset(&data, 0, sizeof(struct mmc_data)); + memset(&cmd, 0, sizeof(cmd)); + memset(&data, 0, sizeof(data)); memset(res, 0, 64); cmd.opcode = SD_SWITCH_FUNC; @@ -663,14 +702,14 @@ mmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width) uint8_t value; if (mmcbr_get_mode(sc->dev) == mode_sd) { - memset(&cmd, 0, sizeof(struct mmc_command)); + memset(&cmd, 0, sizeof(cmd)); 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); if (err != 0) return (err); - memset(&cmd, 0, sizeof(struct mmc_command)); + memset(&cmd, 0, sizeof(cmd)); cmd.opcode = ACMD_SET_BUS_WIDTH; cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; switch (width) { @@ -746,6 +785,9 @@ mmc_test_bus_width(struct mmc_softc *sc) mmcbr_set_bus_width(sc->dev, bus_width_8); mmcbr_update_ios(sc->dev); + sc->squelched++; /* Errors are expected, squelch reporting. */ + memset(&cmd, 0, sizeof(cmd)); + memset(&data, 0, sizeof(data)); cmd.opcode = MMC_BUSTEST_W; cmd.arg = 0; cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; @@ -756,6 +798,8 @@ mmc_test_bus_width(struct mmc_softc *sc) data.flags = MMC_DATA_WRITE; mmc_wait_for_cmd(sc, &cmd, 0); + memset(&cmd, 0, sizeof(cmd)); + memset(&data, 0, sizeof(data)); cmd.opcode = MMC_BUSTEST_R; cmd.arg = 0; cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; @@ -765,6 +809,7 @@ mmc_test_bus_width(struct mmc_softc *sc) data.len = 8; data.flags = MMC_DATA_READ; err = mmc_wait_for_cmd(sc, &cmd, 0); + sc->squelched--; mmcbr_set_bus_width(sc->dev, bus_width_1); mmcbr_update_ios(sc->dev); @@ -777,6 +822,9 @@ mmc_test_bus_width(struct mmc_softc *sc) mmcbr_set_bus_width(sc->dev, bus_width_4); mmcbr_update_ios(sc->dev); + sc->squelched++; /* Errors are expected, squelch reporting. */ + memset(&cmd, 0, sizeof(cmd)); + memset(&data, 0, sizeof(data)); cmd.opcode = MMC_BUSTEST_W; cmd.arg = 0; cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; @@ -787,6 +835,8 @@ mmc_test_bus_width(struct mmc_softc *sc) data.flags = MMC_DATA_WRITE; mmc_wait_for_cmd(sc, &cmd, 0); + memset(&cmd, 0, sizeof(cmd)); + memset(&data, 0, sizeof(data)); cmd.opcode = MMC_BUSTEST_R; cmd.arg = 0; cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; @@ -796,6 +846,7 @@ mmc_test_bus_width(struct mmc_softc *sc) data.len = 4; data.flags = MMC_DATA_READ; err = mmc_wait_for_cmd(sc, &cmd, 0); + sc->squelched--; mmcbr_set_bus_width(sc->dev, bus_width_1); mmcbr_update_ios(sc->dev); @@ -866,6 +917,9 @@ mmc_format_card_id_string(struct mmc_ivars *ivar) * mmcsd0: 968MB at mmc0 * 22.5MHz/4bit/128-block * + * Also format just the card serial number, which the mmcsd driver will + * use as the disk->d_ident string. + * * The card_id_string in mmc_ivars is currently allocated as 64 bytes, * and our max formatted length is currently 55 bytes if every field * contains the largest value. @@ -879,8 +933,10 @@ mmc_format_card_id_string(struct mmc_ivars *ivar) snprintf(oidstr, sizeof(oidstr), "%c%c", c1, c2); else snprintf(oidstr, sizeof(oidstr), "0x%04x", ivar->cid.oid); + snprintf(ivar->card_sn_string, sizeof(ivar->card_sn_string), + "%08X", ivar->cid.psn); snprintf(ivar->card_id_string, sizeof(ivar->card_id_string), - "%s%s %s %d.%d SN %u MFG %02d/%04d by %d %s", + "%s%s %s %d.%d SN %08X MFG %02d/%04d by %d %s", ivar->mode == mode_sd ? "SD" : "MMC", ivar->high_cap ? "HC" : "", ivar->cid.pnm, ivar->cid.prv >> 4, ivar->cid.prv & 0x0f, ivar->cid.psn, ivar->cid.mdt_month, ivar->cid.mdt_year, @@ -1048,11 +1104,12 @@ mmc_all_send_cid(struct mmc_softc *sc, uint32_t *rawcid) struct mmc_command cmd; int err; + memset(&cmd, 0, sizeof(cmd)); cmd.opcode = MMC_ALL_SEND_CID; cmd.arg = 0; cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; cmd.data = NULL; - err = mmc_wait_for_cmd(sc, &cmd, 0); + err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t)); return (err); } @@ -1063,11 +1120,12 @@ mmc_send_csd(struct mmc_softc *sc, uint16_t rca, uint32_t *rawcsd) struct mmc_command cmd; int err; + memset(&cmd, 0, sizeof(cmd)); cmd.opcode = MMC_SEND_CSD; cmd.arg = rca << 16; cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; cmd.data = NULL; - err = mmc_wait_for_cmd(sc, &cmd, 0); + err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); memcpy(rawcsd, cmd.resp, 4 * sizeof(uint32_t)); return (err); } @@ -1079,8 +1137,8 @@ mmc_app_send_scr(struct mmc_softc *sc, uint16_t rca, uint32_t *rawscr) struct mmc_command cmd; struct mmc_data data; - memset(&cmd, 0, sizeof(struct mmc_command)); - memset(&data, 0, sizeof(struct mmc_data)); + memset(&cmd, 0, sizeof(cmd)); + memset(&data, 0, sizeof(data)); memset(rawscr, 0, 8); cmd.opcode = ACMD_SEND_SCR; @@ -1105,8 +1163,8 @@ mmc_send_ext_csd(struct mmc_softc *sc, uint8_t *rawextcsd) struct mmc_command cmd; struct mmc_data data; - memset(&cmd, 0, sizeof(struct mmc_command)); - memset(&data, 0, sizeof(struct mmc_data)); + memset(&cmd, 0, sizeof(cmd)); + memset(&data, 0, sizeof(data)); memset(rawextcsd, 0, 512); cmd.opcode = MMC_SEND_EXT_CSD; @@ -1129,8 +1187,8 @@ mmc_app_sd_status(struct mmc_softc *sc, uint16_t rca, uint32_t *rawsdstatus) struct mmc_command cmd; struct mmc_data data; - memset(&cmd, 0, sizeof(struct mmc_command)); - memset(&data, 0, sizeof(struct mmc_data)); + memset(&cmd, 0, sizeof(cmd)); + memset(&data, 0, sizeof(data)); memset(rawsdstatus, 0, 64); cmd.opcode = ACMD_SD_STATUS; @@ -1154,11 +1212,12 @@ mmc_set_relative_addr(struct mmc_softc *sc, uint16_t resp) struct mmc_command cmd; int err; + memset(&cmd, 0, sizeof(cmd)); cmd.opcode = MMC_SET_RELATIVE_ADDR; cmd.arg = resp << 16; cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; cmd.data = NULL; - err = mmc_wait_for_cmd(sc, &cmd, 0); + err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); return (err); } @@ -1168,11 +1227,12 @@ mmc_send_relative_addr(struct mmc_softc *sc, uint32_t *resp) struct mmc_command cmd; int err; + memset(&cmd, 0, sizeof(cmd)); cmd.opcode = SD_SEND_RELATIVE_ADDR; cmd.arg = 0; cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; cmd.data = NULL; - err = mmc_wait_for_cmd(sc, &cmd, 0); + err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); *resp = cmd.resp[0]; return (err); } @@ -1183,11 +1243,12 @@ 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, 0); + err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES); *status = cmd.resp[0]; return (err); } @@ -1198,18 +1259,19 @@ mmc_set_blocklen(struct mmc_softc *sc, uint32_t len) struct mmc_command cmd; int err; + memset(&cmd, 0, sizeof(cmd)); cmd.opcode = MMC_SET_BLOCKLEN; cmd.arg = len; cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; cmd.data = NULL; - err = mmc_wait_for_cmd(sc, &cmd, 0); + err = mmc_wait_for_cmd(sc, &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 %d%s:\n", + 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); device_printf(dev, " bus: %ubit, %uMHz%s\n", @@ -1237,7 +1299,9 @@ mmc_discover_cards(struct mmc_softc *sc) if (bootverbose || mmc_debug) device_printf(sc->dev, "Probing cards\n"); while (1) { + sc->squelched++; /* Errors are expected, squelch reporting. */ err = mmc_all_send_cid(sc, raw_cid); + sc->squelched--; if (err == MMC_ERR_TIMEOUT) break; if (err != MMC_ERR_NONE) { @@ -1263,8 +1327,6 @@ mmc_discover_cards(struct mmc_softc *sc) if (newcard) { ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF, M_WAITOK | M_ZERO); - if (!ivar) - return; memcpy(ivar->raw_cid, raw_cid, sizeof(raw_cid)); } if (mmcbr_get_ro(sc->dev)) @@ -1319,6 +1381,21 @@ mmc_discover_cards(struct mmc_softc *sc) ivar->hs_tran_speed = SD_MAX_HS; } } + + /* + * We deselect then reselect the card here. Some cards + * become unselected and timeout with the above two + * commands, although the state tables / diagrams in the + * standard suggest they go back to the transfer state. + * Other cards don't become deselected, and if we + * atttempt to blindly re-select them, we get timeout + * errors from some controllers. So we deselect then + * reselect to handle all situations. The only thing we + * use from the sd_status is the erase sector size, but + * it is still nice to get that right. + */ + mmc_select_card(sc, 0); + mmc_select_card(sc, ivar->rca); mmc_app_sd_status(sc, ivar->rca, ivar->raw_sd_status); mmc_app_decode_sd_status(ivar->raw_sd_status, &ivar->sd_status); @@ -1326,7 +1403,6 @@ mmc_discover_cards(struct mmc_softc *sc) ivar->erase_sector = 16 << ivar->sd_status.au_size; } - mmc_select_card(sc, 0); /* Find max supported bus width. */ if ((mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) && (ivar->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) @@ -1354,6 +1430,7 @@ mmc_discover_cards(struct mmc_softc *sc) child = device_add_child(sc->dev, NULL, -1); device_set_ivars(child, ivar); } + mmc_select_card(sc, 0); return; } mmc_decode_cid_mmc(ivar->raw_cid, &ivar->cid); @@ -1386,10 +1463,10 @@ mmc_discover_cards(struct mmc_softc *sc) break; } + mmc_select_card(sc, ivar->rca); + /* Only MMC >= 4.x cards support EXT_CSD. */ if (ivar->csd.spec_vers >= 4) { - /* Card must be selected to fetch EXT_CSD. */ - mmc_select_card(sc, ivar->rca); mmc_send_ext_csd(sc, ivar->raw_ext_csd); /* Handle extended capacity from EXT_CSD */ sec_count = ivar->raw_ext_csd[EXT_CSD_SEC_CNT] + @@ -1412,7 +1489,6 @@ mmc_discover_cards(struct mmc_softc *sc) ivar->hs_tran_speed = ivar->tran_speed; /* Find max supported bus width. */ ivar->bus_width = mmc_test_bus_width(sc); - mmc_select_card(sc, 0); /* Handle HC erase sector size. */ if (ivar->raw_ext_csd[EXT_CSD_ERASE_GRP_SIZE] != 0) { ivar->erase_sector = 1024 * @@ -1446,6 +1522,7 @@ mmc_discover_cards(struct mmc_softc *sc) child = device_add_child(sc->dev, NULL, -1); device_set_ivars(child, ivar); } + mmc_select_card(sc, 0); } } @@ -1505,6 +1582,7 @@ mmc_go_discovery(struct mmc_softc *sc) /* * First, try SD modes */ + sc->squelched++; /* Errors are expected, squelch reporting. */ mmcbr_set_mode(dev, mode_sd); mmc_power_up(sc); mmcbr_set_bus_mode(dev, pushpull); @@ -1530,13 +1608,14 @@ mmc_go_discovery(struct mmc_softc *sc) "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); + sc->squelched--; mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr)); if (mmcbr_get_ocr(dev) != 0) mmc_idle_cards(sc); } else { mmcbr_set_bus_mode(dev, opendrain); - mmcbr_set_clock(dev, mmcbr_get_f_min(dev)); + mmcbr_set_clock(dev, CARD_ID_FREQUENCY); mmcbr_update_ios(dev); /* XXX recompute vdd based on new cards? */ } @@ -1547,6 +1626,7 @@ mmc_go_discovery(struct mmc_softc *sc) if (bootverbose || mmc_debug) device_printf(sc->dev, "Current OCR: 0x%08x\n", mmcbr_get_ocr(dev)); if (mmcbr_get_ocr(dev) == 0) { + device_printf(sc->dev, "No compatible cards found on bus\n"); mmc_delete_cards(sc); mmc_power_down(sc); return; @@ -1559,7 +1639,7 @@ mmc_go_discovery(struct mmc_softc *sc) mmc_send_app_op_cond(sc, (err ? 0 : MMC_OCR_CCS) | mmcbr_get_ocr(dev), NULL); } else - mmc_send_op_cond(sc, mmcbr_get_ocr(dev), NULL); + mmc_send_op_cond(sc, MMC_OCR_CCS | mmcbr_get_ocr(dev), NULL); mmc_discover_cards(sc); mmc_rescan_cards(sc); @@ -1574,11 +1654,10 @@ static int mmc_calculate_clock(struct mmc_softc *sc) { int max_dtr, max_hs_dtr, max_timing; - int nkid, i, f_min, f_max; + int nkid, i, f_max; device_t *kids; struct mmc_ivars *ivar; - f_min = mmcbr_get_f_min(sc->dev); f_max = mmcbr_get_f_max(sc->dev); max_dtr = max_hs_dtr = f_max; if ((mmcbr_get_caps(sc->dev) & MMC_CAP_HSPEED)) @@ -1673,6 +1752,9 @@ mmc_read_ivar(device_t bus, device_t child, int which, uintptr_t *result) case MMC_IVAR_CARD_ID_STRING: *(char **)result = ivar->card_id_string; break; + case MMC_IVAR_CARD_SN_STRING: + *(char **)result = ivar->card_sn_string; + break; } return (0); } @@ -1725,13 +1807,11 @@ static device_method_t mmc_methods[] = { DEVMETHOD_END }; -static driver_t mmc_driver = { +driver_t mmc_driver = { "mmc", mmc_methods, sizeof(struct mmc_softc), }; -static devclass_t mmc_devclass; +devclass_t mmc_devclass; -DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, NULL, NULL); -DRIVER_MODULE(mmc, dw_mmc, mmc_driver, mmc_devclass, NULL, NULL); -DRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, NULL, NULL); +MODULE_VERSION(mmc, 1); diff --git a/freebsd/sys/dev/mmc/mmcreg.h b/freebsd/sys/dev/mmc/mmcreg.h index 3d2b5691..f25c0f63 100644 --- a/freebsd/sys/dev/mmc/mmcreg.h +++ b/freebsd/sys/dev/mmc/mmcreg.h @@ -85,8 +85,11 @@ struct mmc_command { #define MMC_RSP_R1B (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY) #define MMC_RSP_R2 (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC) #define MMC_RSP_R3 (MMC_RSP_PRESENT) -#define MMC_RSP_R6 (MMC_RSP_PRESENT | MMC_RSP_CRC) -#define MMC_RSP_R7 (MMC_RSP_PRESENT | MMC_RSP_CRC) +#define MMC_RSP_R4 (MMC_RSP_PRESENT) +#define MMC_RSP_R5 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) +#define MMC_RSP_R5B (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY) +#define MMC_RSP_R6 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) +#define MMC_RSP_R7 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) #define MMC_RSP(x) ((x) & MMC_RSP_MASK) uint32_t retries; uint32_t error; @@ -353,6 +356,7 @@ struct mmc_request { #define MMC_OCR_VOLTAGE 0x3fffffffU /* Vdd Voltage mask */ #define MMC_OCR_LOW_VOLTAGE (1u << 7) /* Low Voltage Range -- tbd */ #define MMC_OCR_200_210 (1U << 8) /* Vdd voltage 2.00 ~ 2.10 */ +#define MMC_OCR_MIN_VOLTAGE_SHIFT 8 #define MMC_OCR_210_220 (1U << 9) /* Vdd voltage 2.10 ~ 2.20 */ #define MMC_OCR_220_230 (1U << 10) /* Vdd voltage 2.20 ~ 2.30 */ #define MMC_OCR_230_240 (1U << 11) /* Vdd voltage 2.30 ~ 2.40 */ @@ -368,6 +372,7 @@ struct mmc_request { #define MMC_OCR_330_340 (1U << 21) /* Vdd voltage 3.30 ~ 3.40 */ #define MMC_OCR_340_350 (1U << 22) /* Vdd voltage 3.40 ~ 3.50 */ #define MMC_OCR_350_360 (1U << 23) /* Vdd voltage 3.50 ~ 3.60 */ +#define MMC_OCR_MAX_VOLTAGE_SHIFT 23 #define MMC_OCR_CCS (1u << 30) /* Card Capacity status (SD vs SDHC) */ #define MMC_OCR_CARD_BUSY (1U << 31) /* Card Power up status */ @@ -436,7 +441,7 @@ struct mmc_sd_status * Older versions of the MMC standard had a variable sector size. However, * I've been able to find no old MMC or SD cards that have a non 512 * byte sector size anywhere, so we assume that such cards are very rare - * and only note their existance in passing here... + * and only note their existence in passing here... */ #define MMC_SECTOR_SIZE 512 diff --git a/freebsd/sys/dev/mmc/mmcsd.c b/freebsd/sys/dev/mmc/mmcsd.c index 42c45cf7..d02abf1c 100644 --- a/freebsd/sys/dev/mmc/mmcsd.c +++ b/freebsd/sys/dev/mmc/mmcsd.c @@ -66,6 +66,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -96,9 +98,26 @@ struct mmcsd_softc { daddr_t eblock, eend; /* Range remaining after the last erase. */ int running; int suspend; + int log_count; + struct timeval log_time; #endif /* __rtems__ */ }; +#ifndef __rtems__ +static const char *errmsg[] = +{ + "None", + "Timeout", + "Bad CRC", + "Fifo", + "Failed", + "Invalid", + "NO MEMORY" +}; +#endif /* __rtems__ */ + +#define LOG_PPS 5 /* Log no more than 5 errors per second. */ + /* bus entry points */ static int mmcsd_attach(device_t dev); static int mmcsd_detach(device_t dev); @@ -347,6 +366,11 @@ mmcsd_attach(device_t dev) struct mmcsd_softc *sc; #ifndef __rtems__ struct disk *d; +#else /* __rtems__ */ + struct { + char d_ident[16]; + char d_descr[64]; + } x, *d = &x; #endif /* __rtems__ */ intmax_t mb; uint32_t speed; @@ -365,45 +389,49 @@ mmcsd_attach(device_t dev) 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. */ d->d_sectorsize = mmc_get_sector_size(dev); + d->d_maxsize = mmc_get_max_data(dev) * d->d_sectorsize; d->d_mediasize = (off_t)mmc_get_media_size(dev) * d->d_sectorsize; - d->d_stripeoffset = 0; d->d_stripesize = mmc_get_erase_sector(dev) * d->d_sectorsize; d->d_unit = device_get_unit(dev); d->d_flags = DISKFLAG_CANDELETE; + d->d_delmaxsize = mmc_get_erase_sector(dev) * d->d_sectorsize; +#endif /* __rtems__ */ + strlcpy(d->d_ident, mmc_get_card_sn_string(dev), sizeof(d->d_ident)); + strlcpy(d->d_descr, mmc_get_card_id_string(dev), sizeof(d->d_descr)); + +#ifndef __rtems__ /* - * Display in most natural units. There's no cards < 1MB. - * The SD standard goes to 2GiB, but the data format supports - * up to 4GiB and some card makers push it up to this limit. - * The SDHC standard only goes to 32GiB (the data format in - * SDHC is good to 2TiB however, which isn't too ugly at - * 2048GiBm, so we note it in passing here and don't add the - * code to print TiB). + * Display in most natural units. There's no cards < 1MB. The SD + * standard goes to 2GiB due to its reliance on FAT, but the data + * format supports up to 4GiB and some card makers push it up to this + * limit. The SDHC standard only goes to 32GiB due to FAT32, but the + * data format supports up to 2TiB however. 2048GB isn't too ugly, so + * we note it in passing here and don't add the code to print + * TB). Since these cards are sold in terms of MB and GB not MiB and + * GiB, report them like that. We also round to the nearest unit, since + * many cards are a few percent short, even of the power of 10 size. */ - mb = d->d_mediasize >> 20; /* 1MiB == 1 << 20 */ + mb = (d->d_mediasize + 1000000 / 2 - 1) / 1000000; #else /* __rtems__ */ mb = mmc_get_media_size(dev); mb *= mmc_get_sector_size(dev); - mb >>= 20; + mb = (mb + 1000000 / 2 - 1) / 1000000; #endif /* __rtems__ */ unit = 'M'; - if (mb >= 10240) { /* 1GiB = 1024 MiB */ + if (mb >= 1000) { unit = 'G'; - mb /= 1024; + mb = (mb + 1000 / 2 - 1) / 1000; } /* * Report the clock speed of the underlying hardware, which might be * different than what the card reports due to hardware limitations. - * Report how many blocks the hardware transfers at once, but clip the - * number to MAXPHYS since the system won't initiate larger transfers. + * Report how many blocks the hardware transfers at once. */ speed = mmcbr_get_clock(device_get_parent(dev)); maxblocks = mmc_get_max_data(dev); - if (maxblocks > MAXPHYS) - maxblocks = MAXPHYS; device_printf(dev, "%ju%cB <%s>%s at %s %d.%01dMHz/%dbit/%d-block\n", - mb, unit, mmc_get_card_id_string(dev), + mb, unit, d->d_descr, mmc_get_read_only(dev) ? " (read-only)" : "", device_get_nameunit(device_get_parent(dev)), speed / 1000000, (speed / 100000) % 10, @@ -415,7 +443,8 @@ mmcsd_attach(device_t dev) sc->running = 1; sc->suspend = 0; sc->eblock = sc->eend = 0; - kproc_create(&mmcsd_task, sc, &sc->p, 0, 0, "task: mmc/sd card"); + kproc_create(&mmcsd_task, sc, &sc->p, 0, 0, "%s: mmc/sd card", + device_get_nameunit(dev)); #else /* __rtems__ */ rtems_status_code status_code = rtems_media_server_disk_attach( device_get_name(dev), @@ -493,7 +522,8 @@ mmcsd_resume(device_t dev) if (sc->running <= 0) { sc->running = 1; MMCSD_UNLOCK(sc); - kproc_create(&mmcsd_task, sc, &sc->p, 0, 0, "task: mmc/sd card"); + kproc_create(&mmcsd_task, sc, &sc->p, 0, 0, "%s: mmc/sd card", + device_get_nameunit(dev)); } else MMCSD_UNLOCK(sc); #else /* __rtems__ */ @@ -534,6 +564,14 @@ mmcsd_strategy(struct bio *bp) } } +static const char * +mmcsd_errmsg(int e) +{ + if (e < 0 || e > MMC_ERR_MAX) + return "Bad error code"; + return errmsg[e]; +} + static daddr_t mmcsd_rw(struct mmcsd_softc *sc, struct bio *bp) { @@ -544,6 +582,7 @@ mmcsd_rw(struct mmcsd_softc *sc, struct bio *bp) struct mmc_data data; device_t dev = sc->dev; int sz = sc->disk->d_sectorsize; + device_t mmcbr = device_get_parent(dev); block = bp->bio_pblkno; end = bp->bio_pblkno + (bp->bio_bcount / sz); @@ -554,6 +593,8 @@ mmcsd_rw(struct mmcsd_softc *sc, struct bio *bp) memset(&req, 0, sizeof(req)); memset(&cmd, 0, sizeof(cmd)); memset(&stop, 0, sizeof(stop)); + memset(&data, 0, sizeof(data)); + cmd.mrq = &req; req.cmd = &cmd; cmd.data = &data; if (bp->bio_cmd == BIO_READ) { @@ -583,14 +624,17 @@ mmcsd_rw(struct mmcsd_softc *sc, struct bio *bp) stop.opcode = MMC_STOP_TRANSMISSION; stop.arg = 0; stop.flags = MMC_RSP_R1B | MMC_CMD_AC; + stop.mrq = &req; req.stop = &stop; } -// printf("Len %d %lld-%lld flags %#x sz %d\n", -// (int)data.len, (long long)block, (long long)end, data.flags, sz); - MMCBUS_WAIT_FOR_REQUEST(device_get_parent(dev), dev, - &req); - if (req.cmd->error != MMC_ERR_NONE) + MMCBUS_WAIT_FOR_REQUEST(mmcbr, dev, &req); + if (req.cmd->error != MMC_ERR_NONE) { + if (ppsratecheck(&sc->log_time, &sc->log_count, LOG_PPS)) { + device_printf(dev, "Error indicated: %d %s\n", + req.cmd->error, mmcsd_errmsg(req.cmd->error)); + } break; + } block += numblocks; } return (block); @@ -605,6 +649,7 @@ mmcsd_delete(struct mmcsd_softc *sc, struct bio *bp) device_t dev = sc->dev; int sz = sc->disk->d_sectorsize; int erase_sector; + device_t mmcbr = device_get_parent(dev); block = bp->bio_pblkno; end = bp->bio_pblkno + (bp->bio_bcount / sz); @@ -629,6 +674,7 @@ mmcsd_delete(struct mmcsd_softc *sc, struct bio *bp) /* Set erase start position. */ memset(&req, 0, sizeof(req)); memset(&cmd, 0, sizeof(cmd)); + cmd.mrq = &req; req.cmd = &cmd; if (mmc_get_card_type(dev) == mode_sd) cmd.opcode = SD_ERASE_WR_BLK_START; @@ -638,8 +684,7 @@ mmcsd_delete(struct mmcsd_softc *sc, struct bio *bp) if (!mmc_get_high_cap(dev)) cmd.arg <<= 9; cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; - MMCBUS_WAIT_FOR_REQUEST(device_get_parent(dev), dev, - &req); + MMCBUS_WAIT_FOR_REQUEST(mmcbr, dev, &req); if (req.cmd->error != MMC_ERR_NONE) { printf("erase err1: %d\n", req.cmd->error); return (block); @@ -657,8 +702,7 @@ mmcsd_delete(struct mmcsd_softc *sc, struct bio *bp) cmd.arg <<= 9; cmd.arg--; cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; - MMCBUS_WAIT_FOR_REQUEST(device_get_parent(dev), dev, - &req); + MMCBUS_WAIT_FOR_REQUEST(mmcbr, dev, &req); if (req.cmd->error != MMC_ERR_NONE) { printf("erase err2: %d\n", req.cmd->error); return (block); @@ -670,8 +714,7 @@ mmcsd_delete(struct mmcsd_softc *sc, struct bio *bp) cmd.opcode = MMC_ERASE; cmd.arg = 0; cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; - MMCBUS_WAIT_FOR_REQUEST(device_get_parent(dev), dev, - &req); + MMCBUS_WAIT_FOR_REQUEST(mmcbr, dev, &req); if (req.cmd->error != MMC_ERR_NONE) { printf("erase err3 %d\n", req.cmd->error); return (block); @@ -696,21 +739,22 @@ mmcsd_dump(void *arg, void *virtual, vm_offset_t physical, device_t dev = sc->dev; struct bio bp; daddr_t block, end; + device_t mmcbr = device_get_parent(dev); /* length zero is special and really means flush buffers to media */ if (!length) return (0); - bzero(&bp, sizeof(struct bio)); + g_reset_bio(&bp); 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); + MMCBUS_ACQUIRE_BUS(mmcbr, dev); block = mmcsd_rw(sc, &bp); - MMCBUS_RELEASE_BUS(device_get_parent(dev), dev); + MMCBUS_RELEASE_BUS(mmcbr, dev); return ((end < block) ? EIO : 0); } @@ -721,9 +765,9 @@ mmcsd_task(void *arg) struct bio *bp; int sz; daddr_t block, end; - device_t dev; + device_t dev = sc->dev; + device_t mmcbr = device_get_parent(sc->dev); - dev = sc->dev; while (1) { MMCSD_LOCK(sc); do { @@ -741,7 +785,7 @@ mmcsd_task(void *arg) biodone(bp); continue; } - MMCBUS_ACQUIRE_BUS(device_get_parent(dev), dev); + MMCBUS_ACQUIRE_BUS(mmcbr, dev); sz = sc->disk->d_sectorsize; block = bp->bio_pblkno; end = bp->bio_pblkno + (bp->bio_bcount / sz); @@ -753,7 +797,7 @@ mmcsd_task(void *arg) } else if (bp->bio_cmd == BIO_DELETE) { block = mmcsd_delete(sc, bp); } - MMCBUS_RELEASE_BUS(device_get_parent(dev), dev); + MMCBUS_RELEASE_BUS(mmcbr, dev); if (block < end) { bp->bio_error = EIO; bp->bio_resid = (end - block) * sz; diff --git a/freebsd/sys/dev/mmc/mmcvar.h b/freebsd/sys/dev/mmc/mmcvar.h index 99b8a6a5..c7a4af99 100644 --- a/freebsd/sys/dev/mmc/mmcvar.h +++ b/freebsd/sys/dev/mmc/mmcvar.h @@ -69,25 +69,18 @@ enum mmc_device_ivars { MMC_IVAR_BUS_WIDTH, MMC_IVAR_ERASE_SECTOR, MMC_IVAR_MAX_DATA, - MMC_IVAR_CARD_ID_STRING + MMC_IVAR_CARD_ID_STRING, + MMC_IVAR_CARD_SN_STRING, }; /* - * Simplified accessors for pci devices + * Simplified accessors for mmc devices */ #define MMC_ACCESSOR(var, ivar, type) \ __BUS_ACCESSOR(mmc, var, MMC, ivar, type) MMC_ACCESSOR(dsr_imp, DSR_IMP, int) -#ifndef __rtems__ -MMC_ACCESSOR(media_size, MEDIA_SIZE, off_t) -#else /* __rtems__ */ -/* - * The instance variable value storage is limited by the uintptr_t type. Since - * off_t has more bits than uintptr_t on most RTEMS targets, we need this hack. - */ -MMC_ACCESSOR(media_size, MEDIA_SIZE, uintptr_t) -#endif /* __rtems__ */ +MMC_ACCESSOR(media_size, MEDIA_SIZE, long) MMC_ACCESSOR(rca, RCA, int) MMC_ACCESSOR(sector_size, SECTOR_SIZE, int) MMC_ACCESSOR(tran_speed, TRAN_SPEED, int) @@ -98,5 +91,6 @@ MMC_ACCESSOR(bus_width, BUS_WIDTH, int) MMC_ACCESSOR(erase_sector, ERASE_SECTOR, int) MMC_ACCESSOR(max_data, MAX_DATA, int) MMC_ACCESSOR(card_id_string, CARD_ID_STRING, const char *) +MMC_ACCESSOR(card_sn_string, CARD_SN_STRING, const char *) #endif /* DEV_MMC_MMCVAR_H */ diff --git a/libbsd.txt b/libbsd.txt index 6b9e2a91..8af302fe 100644 --- a/libbsd.txt +++ b/libbsd.txt @@ -766,6 +766,7 @@ detail and debug level information from the command. == FreeBSD version of imported files and directories . sys/dev/dwc/*, trunk, 2015-03-26, cfc3df2b8f708ce8494d9d556e3472a5c8c21b8a +. sys/dev/mmc/*, trunk, 2016-08-23, 9fe7c416e6abb28b1398fd3e5687099846800cfd . sys/dev/usb/*, trunk, 2015-10-30, 968dafb4fcf133cb8beb6fa3c558fecd7dc00ef0 . *, stable/9, 2015-04-08, 99a648a912e81e29d9c4c159cbbe263462f2d719 diff --git a/rtemsbsd/include/geom/geom.h b/rtemsbsd/include/geom/geom.h new file mode 100644 index 00000000..e69de29b -- cgit v1.2.3