diff options
author | Raphael Graf <rapha@cvs.openbsd.org> | 2014-09-23 12:08:14 +0000 |
---|---|---|
committer | Raphael Graf <rapha@cvs.openbsd.org> | 2014-09-23 12:08:14 +0000 |
commit | f2bb874073ea96763592128e60c52f29680d663b (patch) | |
tree | 87d31297eee5261e380f4d5b58019266dfae5f66 /sys/dev/sdmmc | |
parent | f1c9e193f5e4245788a169307c088d1963b38258 (diff) |
Fix high capacity (> 2GB) eMMC support.
Based on a diff by Cedric Tessier, nezetic at gmail dot com, thanks!
Discussed with and ok jsg@
Diffstat (limited to 'sys/dev/sdmmc')
-rw-r--r-- | sys/dev/sdmmc/sdmmc_mem.c | 27 | ||||
-rw-r--r-- | sys/dev/sdmmc/sdmmcreg.h | 3 |
2 files changed, 18 insertions, 12 deletions
diff --git a/sys/dev/sdmmc/sdmmc_mem.c b/sys/dev/sdmmc/sdmmc_mem.c index 3d4d9d25c6a..35002091ca7 100644 --- a/sys/dev/sdmmc/sdmmc_mem.c +++ b/sys/dev/sdmmc/sdmmc_mem.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sdmmc_mem.c,v 1.19 2014/07/12 18:48:52 tedu Exp $ */ +/* $OpenBSD: sdmmc_mem.c,v 1.20 2014/09/23 12:08:13 rapha Exp $ */ /* * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> @@ -428,6 +428,7 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) u_int8_t ext_csd[512]; int speed = 0; int hs_timing = 0; + u_int32_t sectors = 0; if (sf->csd.mmcver >= MMC_CSD_MMCVER_4_0) { /* read EXT_CSD */ @@ -439,18 +440,12 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) return error; } - switch (ext_csd[EXT_CSD_CARD_TYPE]) { - case EXT_CSD_CARD_TYPE_26M: - speed = 26000; - break; - case EXT_CSD_CARD_TYPE_52M: - case EXT_CSD_CARD_TYPE_52M_V18: - case EXT_CSD_CARD_TYPE_52M_V12: - case EXT_CSD_CARD_TYPE_52M_V12_18: + if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_52M) { speed = 52000; hs_timing = 1; - break; - default: + } else if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_26M) { + speed = 26000; + } else { printf("%s: unknown CARD_TYPE 0x%x\n", DEVNAME(sc), ext_csd[EXT_CSD_CARD_TYPE]); } @@ -488,6 +483,16 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) return EINVAL; } } + + sectors = ext_csd[EXT_CSD_SEC_COUNT + 0] << 0 | + ext_csd[EXT_CSD_SEC_COUNT + 1] << 8 | + ext_csd[EXT_CSD_SEC_COUNT + 2] << 16 | + ext_csd[EXT_CSD_SEC_COUNT + 3] << 24; + + if (sectors > (2u * 1024 * 1024 * 1024) / 512) { + sf->flags |= SFF_SDHC; + sf->csd.capacity = sectors; + } } return error; diff --git a/sys/dev/sdmmc/sdmmcreg.h b/sys/dev/sdmmc/sdmmcreg.h index 99660761c7f..7807f3b76ea 100644 --- a/sys/dev/sdmmc/sdmmcreg.h +++ b/sys/dev/sdmmc/sdmmcreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sdmmcreg.h,v 1.5 2013/09/12 11:54:04 rapha Exp $ */ +/* $OpenBSD: sdmmcreg.h,v 1.6 2014/09/23 12:08:13 rapha Exp $ */ /* * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> @@ -95,6 +95,7 @@ #define EXT_CSD_REV 192 /* RO */ #define EXT_CSD_STRUCTURE 194 /* RO */ #define EXT_CSD_CARD_TYPE 196 /* RO */ +#define EXT_CSD_SEC_COUNT 212 /* RO */ /* EXT_CSD field definitions */ #define EXT_CSD_CMD_SET_NORMAL (1U << 0) |