Commit 6e58ddeb authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.6-mmc

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 6e544044 201ee40f
......@@ -300,58 +300,121 @@ static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
return ocr;
}
static void mmc_decode_cid(struct mmc_cid *cid, u32 *resp)
#define UNSTUFF_BITS(resp,start,size) \
({ \
const u32 __mask = (1 << (size)) - 1; \
const int __off = 3 - ((start) / 32); \
const int __shft = (start) & 31; \
u32 __res; \
\
__res = resp[__off] >> __shft; \
if ((size) + __shft >= 32) \
__res |= resp[__off-1] << (32 - __shft); \
__res & __mask; \
})
/*
* Given the decoded CSD structure, decode the raw CID to our CID structure.
*/
static void mmc_decode_cid(struct mmc_card *card)
{
memset(cid, 0, sizeof(struct mmc_cid));
cid->manfid = resp[0] >> 8;
cid->prod_name[0] = resp[0];
cid->prod_name[1] = resp[1] >> 24;
cid->prod_name[2] = resp[1] >> 16;
cid->prod_name[3] = resp[1] >> 8;
cid->prod_name[4] = resp[1];
cid->prod_name[5] = resp[2] >> 24;
cid->prod_name[6] = resp[2] >> 16;
cid->prod_name[7] = '\0';
cid->hwrev = (resp[2] >> 12) & 15;
cid->fwrev = (resp[2] >> 8) & 15;
cid->serial = (resp[2] & 255) << 16 | (resp[3] >> 16);
cid->month = (resp[3] >> 12) & 15;
cid->year = (resp[3] >> 8) & 15;
u32 *resp = card->raw_cid;
memset(&card->cid, 0, sizeof(struct mmc_cid));
/*
* The selection of the format here is guesswork based upon
* information people have sent to date.
*/
switch (card->csd.mmca_vsn) {
case 0: /* MMC v1.? */
case 1: /* MMC v1.4 */
card->cid.manfid = UNSTUFF_BITS(resp, 104, 24);
card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8);
card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4);
card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4);
card->cid.serial = UNSTUFF_BITS(resp, 16, 24);
card->cid.month = UNSTUFF_BITS(resp, 12, 4);
card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997;
break;
case 2: /* MMC v2.x ? */
case 3: /* MMC v3.x ? */
card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
card->cid.serial = UNSTUFF_BITS(resp, 16, 32);
card->cid.month = UNSTUFF_BITS(resp, 12, 4);
card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997;
break;
default:
printk("%s: card has unknown MMCA version %d\n",
card->host->host_name, card->csd.mmca_vsn);
mmc_card_set_bad(card);
break;
}
}
static void mmc_decode_csd(struct mmc_csd *csd, u32 *resp)
/*
* Given a 128-bit response, decode to our card CSD structure.
*/
static void mmc_decode_csd(struct mmc_card *card)
{
unsigned int e, m;
struct mmc_csd *csd = &card->csd;
unsigned int e, m, csd_struct;
u32 *resp = card->raw_csd;
csd->mmc_prot = (resp[0] >> 26) & 15;
m = (resp[0] >> 19) & 15;
e = (resp[0] >> 16) & 7;
/*
* We only understand CSD structure v1.1 and v2.
* v2 has extra information in bits 15, 11 and 10.
*/
csd_struct = UNSTUFF_BITS(resp, 126, 2);
if (csd_struct != 1 && csd_struct != 2) {
printk("%s: unrecognised CSD structure version %d\n",
card->host->host_name, csd_struct);
mmc_card_set_bad(card);
return;
}
csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4);
m = UNSTUFF_BITS(resp, 115, 4);
e = UNSTUFF_BITS(resp, 112, 3);
csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
csd->tacc_clks = ((resp[0] >> 8) & 255) * 100;
csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100;
m = (resp[0] >> 3) & 15;
e = resp[0] & 7;
m = UNSTUFF_BITS(resp, 99, 4);
e = UNSTUFF_BITS(resp, 96, 3);
csd->max_dtr = tran_exp[e] * tran_mant[m];
csd->cmdclass = (resp[1] >> 20) & 0xfff;
csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
e = (resp[2] >> 15) & 7;
m = (resp[1] << 2 | resp[2] >> 30) & 0x3fff;
e = UNSTUFF_BITS(resp, 47, 3);
m = UNSTUFF_BITS(resp, 62, 12);
csd->capacity = (1 + m) << (e + 2);
csd->read_blkbits = (resp[1] >> 16) & 15;
csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
}
/*
* Locate a MMC card on this MMC host given a CID.
* Locate a MMC card on this MMC host given a raw CID.
*/
static struct mmc_card *
mmc_find_card(struct mmc_host *host, struct mmc_cid *cid)
static struct mmc_card *mmc_find_card(struct mmc_host *host, u32 *raw_cid)
{
struct mmc_card *card;
list_for_each_entry(card, &host->cards, node) {
if (memcmp(&card->cid, cid, sizeof(struct mmc_cid)) == 0)
if (memcmp(card->raw_cid, raw_cid, sizeof(card->raw_cid)) == 0)
return card;
}
return NULL;
......@@ -361,7 +424,7 @@ mmc_find_card(struct mmc_host *host, struct mmc_cid *cid)
* Allocate a new MMC card, and assign a unique RCA.
*/
static struct mmc_card *
mmc_alloc_card(struct mmc_host *host, struct mmc_cid *cid, unsigned int *frca)
mmc_alloc_card(struct mmc_host *host, u32 *raw_cid, unsigned int *frca)
{
struct mmc_card *card, *c;
unsigned int rca = *frca;
......@@ -371,7 +434,7 @@ mmc_alloc_card(struct mmc_host *host, struct mmc_cid *cid, unsigned int *frca)
return ERR_PTR(-ENOMEM);
mmc_init_card(card, host);
memcpy(&card->cid, cid, sizeof(struct mmc_cid));
memcpy(card->raw_cid, raw_cid, sizeof(card->raw_cid));
again:
list_for_each_entry(c, &host->cards, node)
......@@ -456,7 +519,7 @@ static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
* to be discovered. Add new cards to the list.
*
* Create a mmc_card entry for each discovered card, assigning
* it an RCA, and save the CID.
* it an RCA, and save the raw CID for decoding later.
*/
static void mmc_discover_cards(struct mmc_host *host)
{
......@@ -465,7 +528,6 @@ static void mmc_discover_cards(struct mmc_host *host)
while (1) {
struct mmc_command cmd;
struct mmc_cid cid;
cmd.opcode = MMC_ALL_SEND_CID;
cmd.arg = 0;
......@@ -482,11 +544,9 @@ static void mmc_discover_cards(struct mmc_host *host)
break;
}
mmc_decode_cid(&cid, cmd.resp);
card = mmc_find_card(host, &cid);
card = mmc_find_card(host, cmd.resp);
if (!card) {
card = mmc_alloc_card(host, &cid, &first_rca);
card = mmc_alloc_card(host, cmd.resp, &first_rca);
if (IS_ERR(card)) {
err = PTR_ERR(card);
break;
......@@ -502,7 +562,7 @@ static void mmc_discover_cards(struct mmc_host *host)
err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
if (err != MMC_ERR_NONE)
card->state |= MMC_STATE_DEAD;
mmc_card_set_dead(card);
}
}
......@@ -523,11 +583,14 @@ static void mmc_read_csds(struct mmc_host *host)
err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
if (err != MMC_ERR_NONE) {
card->state |= MMC_STATE_DEAD;
mmc_card_set_dead(card);
continue;
}
mmc_decode_csd(&card->csd, cmd.resp);
memcpy(card->raw_csd, cmd.resp, sizeof(card->raw_csd));
mmc_decode_csd(card);
mmc_decode_cid(card);
}
}
......@@ -573,7 +636,7 @@ static void mmc_check_cards(struct mmc_host *host)
if (err == MMC_ERR_NONE)
continue;
card->state |= MMC_STATE_DEAD;
mmc_card_set_dead(card);
}
}
......@@ -678,9 +741,9 @@ static void mmc_rescan(void *data)
*/
if (!mmc_card_present(card) && !mmc_card_dead(card)) {
if (mmc_register_card(card))
card->state |= MMC_STATE_DEAD;
mmc_card_set_dead(card);
else
card->state |= MMC_STATE_PRESENT;
mmc_card_set_present(card);
}
/*
......
......@@ -31,11 +31,12 @@ static void mmc_release_card(struct device *dev)
/*
* This currently matches any MMC driver to any MMC card - drivers
* 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)
{
return 1;
struct mmc_card *card = dev_to_mmc_card(dev);
return !mmc_card_bad(card);
}
static int
......@@ -66,8 +67,9 @@ mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buf,
i = 0;
add_env("MMC_CCC=%s", ccc);
add_env("MMC_MANFID=%03x", card->cid.manfid);
add_env("MMC_SLOT_NAME=%s", card->dev.bus_id);
add_env("MMC_MANFID=%06x", card->cid.manfid);
add_env("MMC_NAME=%s", mmc_card_name(card));
add_env("MMC_OEMID=%04x", card->cid.oemid);
return 0;
}
......@@ -157,20 +159,28 @@ static ssize_t mmc_dev_show_##name (struct device *dev, char *buf) \
} \
static DEVICE_ATTR(name, S_IRUGO, mmc_dev_show_##name, NULL)
MMC_ATTR(date, "%02d/%04d\n", card->cid.month, 1997 + card->cid.year);
MMC_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
card->raw_cid[2], card->raw_cid[3]);
MMC_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
card->raw_csd[2], card->raw_csd[3]);
MMC_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year);
MMC_ATTR(fwrev, "0x%x\n", card->cid.fwrev);
MMC_ATTR(hwrev, "0x%x\n", card->cid.hwrev);
MMC_ATTR(manfid, "0x%03x\n", card->cid.manfid);
MMC_ATTR(serial, "0x%06x\n", card->cid.serial);
MMC_ATTR(manfid, "0x%06x\n", card->cid.manfid);
MMC_ATTR(name, "%s\n", card->cid.prod_name);
MMC_ATTR(oemid, "0x%04x\n", card->cid.oemid);
MMC_ATTR(serial, "0x%08x\n", card->cid.serial);
static struct device_attribute *mmc_dev_attributes[] = {
&dev_attr_cid,
&dev_attr_csd,
&dev_attr_date,
&dev_attr_fwrev,
&dev_attr_hwrev,
&dev_attr_manfid,
&dev_attr_serial,
&dev_attr_name,
&dev_attr_oemid,
&dev_attr_serial,
};
/*
......
......@@ -14,16 +14,17 @@
struct mmc_cid {
unsigned int manfid;
unsigned int serial;
char prod_name[8];
unsigned int serial;
unsigned short oemid;
unsigned short year;
unsigned char hwrev;
unsigned char fwrev;
unsigned char month;
unsigned char year;
};
struct mmc_csd {
unsigned char mmc_prot;
unsigned char mmca_vsn;
unsigned short cmdclass;
unsigned short tacc_clks;
unsigned int tacc_ns;
......@@ -43,14 +44,22 @@ struct mmc_card {
struct device dev; /* the device */
unsigned int rca; /* relative card address of device */
unsigned int state; /* (our) card state */
#define MMC_STATE_PRESENT (1<<0)
#define MMC_STATE_DEAD (1<<1)
#define MMC_STATE_PRESENT (1<<0) /* present in sysfs */
#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_csd[4]; /* raw card CSD */
struct mmc_cid cid; /* card identification */
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_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_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