summaryrefslogtreecommitdiff
path: root/sys/dev/sdmmc
diff options
context:
space:
mode:
authorRaphael Graf <rapha@cvs.openbsd.org>2014-09-23 12:08:14 +0000
committerRaphael Graf <rapha@cvs.openbsd.org>2014-09-23 12:08:14 +0000
commitf2bb874073ea96763592128e60c52f29680d663b (patch)
tree87d31297eee5261e380f4d5b58019266dfae5f66 /sys/dev/sdmmc
parentf1c9e193f5e4245788a169307c088d1963b38258 (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.c27
-rw-r--r--sys/dev/sdmmc/sdmmcreg.h3
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)