Commit b41465f9 authored by Russell King's avatar Russell King

[MMC] Clean up MMC card CID/CSD decoding, stage 1.

Now that the raw CSD and CID information are available in mmc_card,
there's little point not passing the mmc_card structure into the
decode functions themselves.

This will be necessary, since there's several different formats of
CID decode, and the format appears to depend on data in the CSD.

If we are unable to decode the CID or CSD, we can mark the card bad
and refuse to bind it to any drivers.  Users can then retrieve the
raw undecoded CID and CSD from sysfs for debugging purposes.
parent 6284454c
...@@ -300,8 +300,11 @@ static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) ...@@ -300,8 +300,11 @@ static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
return ocr; return ocr;
} }
static void mmc_decode_cid(struct mmc_cid *cid, u32 *resp) static void mmc_decode_cid(struct mmc_card *card)
{ {
struct mmc_cid *cid = &card->cid;
u32 *resp = card->raw_cid;
memset(cid, 0, sizeof(struct mmc_cid)); memset(cid, 0, sizeof(struct mmc_cid));
cid->manfid = resp[0] >> 8; cid->manfid = resp[0] >> 8;
...@@ -320,9 +323,11 @@ static void mmc_decode_cid(struct mmc_cid *cid, u32 *resp) ...@@ -320,9 +323,11 @@ static void mmc_decode_cid(struct mmc_cid *cid, u32 *resp)
cid->year = (resp[3] >> 8) & 15; cid->year = (resp[3] >> 8) & 15;
} }
static void mmc_decode_csd(struct mmc_csd *csd, u32 *resp) static void mmc_decode_csd(struct mmc_card *card)
{ {
struct mmc_csd *csd = &card->csd;
unsigned int e, m; unsigned int e, m;
u32 *resp = card->raw_csd;
csd->mmc_prot = (resp[0] >> 26) & 15; csd->mmc_prot = (resp[0] >> 26) & 15;
m = (resp[0] >> 19) & 15; m = (resp[0] >> 19) & 15;
...@@ -498,7 +503,7 @@ static void mmc_discover_cards(struct mmc_host *host) ...@@ -498,7 +503,7 @@ static void mmc_discover_cards(struct mmc_host *host)
err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
if (err != MMC_ERR_NONE) if (err != MMC_ERR_NONE)
card->state |= MMC_STATE_DEAD; mmc_card_set_dead(card);
} }
} }
...@@ -519,14 +524,14 @@ static void mmc_read_csds(struct mmc_host *host) ...@@ -519,14 +524,14 @@ static void mmc_read_csds(struct mmc_host *host)
err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
if (err != MMC_ERR_NONE) { if (err != MMC_ERR_NONE) {
card->state |= MMC_STATE_DEAD; mmc_card_set_dead(card);
continue; continue;
} }
memcpy(card->raw_csd, cmd.resp, sizeof(card->raw_csd)); memcpy(card->raw_csd, cmd.resp, sizeof(card->raw_csd));
mmc_decode_csd(&card->csd, cmd.resp); mmc_decode_csd(card);
mmc_decode_cid(&card->cid, card->raw_cid); mmc_decode_cid(card);
} }
} }
...@@ -572,7 +577,7 @@ static void mmc_check_cards(struct mmc_host *host) ...@@ -572,7 +577,7 @@ static void mmc_check_cards(struct mmc_host *host)
if (err == MMC_ERR_NONE) if (err == MMC_ERR_NONE)
continue; continue;
card->state |= MMC_STATE_DEAD; mmc_card_set_dead(card);
} }
} }
...@@ -677,9 +682,9 @@ static void mmc_rescan(void *data) ...@@ -677,9 +682,9 @@ static void mmc_rescan(void *data)
*/ */
if (!mmc_card_present(card) && !mmc_card_dead(card)) { if (!mmc_card_present(card) && !mmc_card_dead(card)) {
if (mmc_register_card(card)) if (mmc_register_card(card))
card->state |= MMC_STATE_DEAD; mmc_card_set_dead(card);
else else
card->state |= MMC_STATE_PRESENT; mmc_card_set_present(card);
} }
/* /*
......
...@@ -31,11 +31,12 @@ static void mmc_release_card(struct device *dev) ...@@ -31,11 +31,12 @@ static void mmc_release_card(struct device *dev)
/* /*
* This currently matches any MMC driver to any MMC card - drivers * This currently matches any MMC driver to any MMC card - drivers
* themselves make the decision whether to drive this card in their * themselves make the decision whether to drive this card in their
* probe method. * probe method. However, we force "bad" cards to fail.
*/ */
static int mmc_bus_match(struct device *dev, struct device_driver *drv) static int mmc_bus_match(struct device *dev, struct device_driver *drv)
{ {
return 1; struct mmc_card *card = dev_to_mmc_card(dev);
return !mmc_card_bad(card);
} }
static int static int
......
...@@ -43,16 +43,22 @@ struct mmc_card { ...@@ -43,16 +43,22 @@ struct mmc_card {
struct device dev; /* the device */ struct device dev; /* the device */
unsigned int rca; /* relative card address of device */ unsigned int rca; /* relative card address of device */
unsigned int state; /* (our) card state */ unsigned int state; /* (our) card state */
#define MMC_STATE_PRESENT (1<<0) #define MMC_STATE_PRESENT (1<<0) /* present in sysfs */
#define MMC_STATE_DEAD (1<<1) #define MMC_STATE_DEAD (1<<1) /* device no longer in stack */
#define MMC_STATE_BAD (1<<2) /* unrecognised device */
u32 raw_cid[4]; /* raw card CID */ u32 raw_cid[4]; /* raw card CID */
u32 raw_csd[4]; /* raw card CSD */ u32 raw_csd[4]; /* raw card CSD */
struct mmc_cid cid; /* card identification */ struct mmc_cid cid; /* card identification */
struct mmc_csd csd; /* card specific */ struct mmc_csd csd; /* card specific */
}; };
#define mmc_card_dead(c) ((c)->state & MMC_STATE_DEAD)
#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
#define mmc_card_dead(c) ((c)->state & MMC_STATE_DEAD)
#define mmc_card_bad(c) ((c)->state & MMC_STATE_BAD)
#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
#define mmc_card_set_dead(c) ((c)->state |= MMC_STATE_DEAD)
#define mmc_card_set_bad(c) ((c)->state |= MMC_STATE_BAD)
#define mmc_card_name(c) ((c)->cid.prod_name) #define mmc_card_name(c) ((c)->cid.prod_name)
#define mmc_card_id(c) ((c)->dev.bus_id) #define mmc_card_id(c) ((c)->dev.bus_id)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment