summaryrefslogtreecommitdiffstats
path: root/sys/dev/mmc/mmc.c
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2008-10-09 19:47:28 +0000
committerimp <imp@FreeBSD.org>2008-10-09 19:47:28 +0000
commit2dffc5408e12482efac1e5f7c2035e9a5e7d45c9 (patch)
treec4b90d714746912f5b172c3dff55c3989f7f4b14 /sys/dev/mmc/mmc.c
parentb020102453778189fb638572efcf9bad3bf69b7a (diff)
downloadFreeBSD-src-2dffc5408e12482efac1e5f7c2035e9a5e7d45c9.zip
FreeBSD-src-2dffc5408e12482efac1e5f7c2035e9a5e7d45c9.tar.gz
o Use seprate routines to decode cid and csd for sd and mmc cards. All they
have in common right now is a memset. This saves a parameter to these routines, as well as a level of indentation. o Make mmc_get_bits a little clearer... It really only works on 128-bit registers right now.
Diffstat (limited to 'sys/dev/mmc/mmc.c')
-rw-r--r--sys/dev/mmc/mmc.c193
1 files changed, 103 insertions, 90 deletions
diff --git a/sys/dev/mmc/mmc.c b/sys/dev/mmc/mmc.c
index c99b366..172f5e4 100644
--- a/sys/dev/mmc/mmc.c
+++ b/sys/dev/mmc/mmc.c
@@ -718,7 +718,8 @@ mmc_test_bus_width(struct mmc_softc *sc)
static uint32_t
mmc_get_bits(uint32_t *bits, int start, int size)
{
- const int i = 3 - (start / 32);
+ const int bit_len = 128;
+ const int i = (bit_len / 32) - (start / 32) - 1;
const int shift = start & 31;
uint32_t retval = bits[i] >> shift;
if (size + shift > 32)
@@ -727,31 +728,37 @@ mmc_get_bits(uint32_t *bits, int start, int size)
}
static void
-mmc_decode_cid(int is_sd, uint32_t *raw_cid, struct mmc_cid *cid)
+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));
- if (is_sd) {
- /* There's no version info, so we take it on faith */
- cid->mid = mmc_get_bits(raw_cid, 120, 8);
- cid->oid = mmc_get_bits(raw_cid, 104, 16);
- for (i = 0; i < 5; i++)
- cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8);
- cid->prv = mmc_get_bits(raw_cid, 56, 8);
- cid->psn = mmc_get_bits(raw_cid, 24, 32);
- cid->mdt_year = mmc_get_bits(raw_cid, 12, 8) + 2001;
- cid->mdt_month = mmc_get_bits(raw_cid, 8, 4);
- } else {
- cid->mid = mmc_get_bits(raw_cid, 120, 8);
- cid->oid = mmc_get_bits(raw_cid, 104, 8);
- for (i = 0; i < 6; i++)
- cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8);
- cid->prv = mmc_get_bits(raw_cid, 48, 8);
- cid->psn = mmc_get_bits(raw_cid, 16, 32);
- cid->mdt_month = mmc_get_bits(raw_cid, 12, 4);
- cid->mdt_year = mmc_get_bits(raw_cid, 8, 4) + 1997;
- }
+ cid->mid = mmc_get_bits(raw_cid, 120, 8);
+ cid->oid = mmc_get_bits(raw_cid, 104, 16);
+ for (i = 0; i < 5; i++)
+ cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8);
+ cid->prv = mmc_get_bits(raw_cid, 56, 8);
+ cid->psn = mmc_get_bits(raw_cid, 24, 32);
+ cid->mdt_year = mmc_get_bits(raw_cid, 12, 8) + 2001;
+ cid->mdt_month = mmc_get_bits(raw_cid, 8, 4);
+}
+
+static void
+mmc_decode_cid_mmc(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));
+ cid->mid = mmc_get_bits(raw_cid, 120, 8);
+ cid->oid = mmc_get_bits(raw_cid, 104, 8);
+ for (i = 0; i < 6; i++)
+ cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8);
+ cid->prv = mmc_get_bits(raw_cid, 48, 8);
+ cid->psn = mmc_get_bits(raw_cid, 16, 32);
+ cid->mdt_month = mmc_get_bits(raw_cid, 12, 4);
+ cid->mdt_year = mmc_get_bits(raw_cid, 8, 4) + 1997;
}
static const int exp[8] = {
@@ -768,71 +775,15 @@ static const int cur_max[8] = {
};
static void
-mmc_decode_csd(int is_sd, uint32_t *raw_csd, struct mmc_csd *csd)
+mmc_decode_csd_sd(uint32_t *raw_csd, struct mmc_csd *csd)
{
int v;
int m;
int e;
memset(csd, 0, sizeof(*csd));
- if (is_sd) {
- csd->csd_structure = v = mmc_get_bits(raw_csd, 126, 2);
- if (v == 0) {
- m = mmc_get_bits(raw_csd, 115, 4);
- e = mmc_get_bits(raw_csd, 112, 3);
- csd->tacc = exp[e] * mant[m] + 9 / 10;
- csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100;
- m = mmc_get_bits(raw_csd, 99, 4);
- e = mmc_get_bits(raw_csd, 96, 3);
- csd->tran_speed = exp[e] * 10000 * mant[m];
- csd->ccc = mmc_get_bits(raw_csd, 84, 12);
- csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4);
- csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1);
- csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1);
- csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1);
- csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1);
- csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 59, 3)];
- csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 56, 3)];
- csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 53, 3)];
- csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 50, 3)];
- m = mmc_get_bits(raw_csd, 62, 12);
- e = mmc_get_bits(raw_csd, 47, 3);
- csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len;
- csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1);
- csd->sector_size = mmc_get_bits(raw_csd, 39, 7);
- csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7);
- csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1);
- csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3);
- csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4);
- csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1);
- } else if (v == 1) {
- m = mmc_get_bits(raw_csd, 115, 4);
- e = mmc_get_bits(raw_csd, 112, 3);
- csd->tacc = exp[e] * mant[m] + 9 / 10;
- csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100;
- m = mmc_get_bits(raw_csd, 99, 4);
- e = mmc_get_bits(raw_csd, 96, 3);
- csd->tran_speed = exp[e] * 10000 * mant[m];
- csd->ccc = mmc_get_bits(raw_csd, 84, 12);
- csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4);
- csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1);
- csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1);
- csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1);
- csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1);
- csd->capacity = ((uint64_t)mmc_get_bits(raw_csd, 48, 22) + 1) *
- 512 * 1024;
- csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1);
- csd->sector_size = mmc_get_bits(raw_csd, 39, 7);
- csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7);
- csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1);
- csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3);
- csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4);
- csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1);
- } else
- panic("unknown SD CSD version");
- } else {
- csd->csd_structure = mmc_get_bits(raw_csd, 126, 2);
- csd->spec_vers = mmc_get_bits(raw_csd, 122, 4);
+ csd->csd_structure = v = mmc_get_bits(raw_csd, 126, 2);
+ if (v == 0) {
m = mmc_get_bits(raw_csd, 115, 4);
e = mmc_get_bits(raw_csd, 112, 3);
csd->tacc = exp[e] * mant[m] + 9 / 10;
@@ -853,14 +804,76 @@ mmc_decode_csd(int is_sd, uint32_t *raw_csd, struct mmc_csd *csd)
m = mmc_get_bits(raw_csd, 62, 12);
e = mmc_get_bits(raw_csd, 47, 3);
csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len;
-// csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1);
-// csd->sector_size = mmc_get_bits(raw_csd, 39, 7);
- csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 5);
+ csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1);
+ csd->sector_size = mmc_get_bits(raw_csd, 39, 7);
+ csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7);
csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1);
csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3);
csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4);
csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1);
- }
+ } else if (v == 1) {
+ m = mmc_get_bits(raw_csd, 115, 4);
+ e = mmc_get_bits(raw_csd, 112, 3);
+ csd->tacc = exp[e] * mant[m] + 9 / 10;
+ csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100;
+ m = mmc_get_bits(raw_csd, 99, 4);
+ e = mmc_get_bits(raw_csd, 96, 3);
+ csd->tran_speed = exp[e] * 10000 * mant[m];
+ csd->ccc = mmc_get_bits(raw_csd, 84, 12);
+ csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4);
+ csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1);
+ csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1);
+ csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1);
+ csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1);
+ csd->capacity = ((uint64_t)mmc_get_bits(raw_csd, 48, 22) + 1) *
+ 512 * 1024;
+ csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1);
+ csd->sector_size = mmc_get_bits(raw_csd, 39, 7);
+ csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7);
+ csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1);
+ csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3);
+ csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4);
+ csd->write_bl_partial = mmc_get_bits(raw_csd, 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, 126, 2);
+ csd->spec_vers = mmc_get_bits(raw_csd, 122, 4);
+ m = mmc_get_bits(raw_csd, 115, 4);
+ e = mmc_get_bits(raw_csd, 112, 3);
+ csd->tacc = exp[e] * mant[m] + 9 / 10;
+ csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100;
+ m = mmc_get_bits(raw_csd, 99, 4);
+ e = mmc_get_bits(raw_csd, 96, 3);
+ csd->tran_speed = exp[e] * 10000 * mant[m];
+ csd->ccc = mmc_get_bits(raw_csd, 84, 12);
+ csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4);
+ csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1);
+ csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1);
+ csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1);
+ csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1);
+ csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 59, 3)];
+ csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 56, 3)];
+ csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 53, 3)];
+ csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 50, 3)];
+ m = mmc_get_bits(raw_csd, 62, 12);
+ e = mmc_get_bits(raw_csd, 47, 3);
+ csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len;
+// csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1);
+// csd->sector_size = mmc_get_bits(raw_csd, 39, 7);
+ csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 5);
+ csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1);
+ csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3);
+ csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4);
+ csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1);
}
static void
@@ -873,7 +886,7 @@ mmc_app_decode_scr(uint32_t *raw_scr, struct mmc_scr *scr)
tmp[2] = raw_scr[0];
memset(scr, 0, sizeof(*scr));
-
+
scr_struct = mmc_get_bits(tmp, 60, 4);
if (scr_struct != 0) {
printf("Unrecognised SCR structure version %d\n",
@@ -1020,12 +1033,12 @@ mmc_discover_cards(struct mmc_softc *sc)
ivar->bus_width = bus_width_1;
ivar->mode = mmcbr_get_mode(sc->dev);
if (ivar->mode == mode_sd) {
- mmc_decode_cid(1, ivar->raw_cid, &ivar->cid);
+ mmc_decode_cid_sd(ivar->raw_cid, &ivar->cid);
mmc_send_relative_addr(sc, &resp);
ivar->rca = resp >> 16;
/* Get card CSD. */
mmc_send_csd(sc, ivar->rca, ivar->raw_csd);
- mmc_decode_csd(1, ivar->raw_csd, &ivar->csd);
+ mmc_decode_csd_sd(ivar->raw_csd, &ivar->csd);
if (ivar->csd.csd_structure > 0)
ivar->high_cap = 1;
ivar->tran_speed = ivar->csd.tran_speed;
@@ -1052,12 +1065,12 @@ mmc_discover_cards(struct mmc_softc *sc)
device_set_ivars(child, ivar);
return;
}
- mmc_decode_cid(0, ivar->raw_cid, &ivar->cid);
+ mmc_decode_cid_mmc(ivar->raw_cid, &ivar->cid);
ivar->rca = rca++;
mmc_set_relative_addr(sc, ivar->rca);
/* Get card CSD. */
mmc_send_csd(sc, ivar->rca, ivar->raw_csd);
- mmc_decode_csd(0, ivar->raw_csd, &ivar->csd);
+ mmc_decode_csd_mmc(ivar->raw_csd, &ivar->csd);
ivar->tran_speed = ivar->csd.tran_speed;
/* Only MMC >= 4.x cards support EXT_CSD. */
if (ivar->csd.spec_vers >= 4) {
OpenPOWER on IntegriCloud