Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 166645
b: refs/heads/master
c: ed9935f
h: refs/heads/master
i:
  166643: c0df183
v: v3
  • Loading branch information
Albert Herranz authored and Linus Torvalds committed Oct 1, 2009
1 parent 7cfc5aa commit 5639a38
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bf89c8c867322338f3f2b1255f280a3236b61a69
refs/heads/master: ed9935f4f9165fb306e59aa41a08be3eafe1486e
65 changes: 49 additions & 16 deletions trunk/drivers/mmc/core/sdio_cis.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,22 @@ static const unsigned char speed_val[16] =
static const unsigned int speed_unit[8] =
{ 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };

/* FUNCE tuples with these types get passed to SDIO drivers */
static const unsigned char funce_type_whitelist[] = {
4 /* CISTPL_FUNCE_LAN_NODE_ID used in Broadcom cards */
};

static int cistpl_funce_whitelisted(unsigned char type)
{
int i;

for (i = 0; i < ARRAY_SIZE(funce_type_whitelist); i++) {
if (funce_type_whitelist[i] == type)
return 1;
}
return 0;
}

static int cistpl_funce_common(struct mmc_card *card,
const unsigned char *buf, unsigned size)
{
Expand All @@ -120,6 +136,10 @@ static int cistpl_funce_func(struct sdio_func *func,
unsigned vsn;
unsigned min_size;

/* let SDIO drivers take care of whitelisted FUNCE tuples */
if (cistpl_funce_whitelisted(buf[0]))
return -EILSEQ;

vsn = func->card->cccr.sdio_vsn;
min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42;

Expand Down Expand Up @@ -154,13 +174,12 @@ static int cistpl_funce(struct mmc_card *card, struct sdio_func *func,
else
ret = cistpl_funce_common(card, buf, size);

if (ret) {
if (ret && ret != -EILSEQ) {
printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u "
"type %u\n", mmc_hostname(card->host), size, buf[0]);
return ret;
}

return 0;
return ret;
}

typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *,
Expand Down Expand Up @@ -253,29 +272,43 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++)
if (cis_tpl_list[i].code == tpl_code)
break;
if (i >= ARRAY_SIZE(cis_tpl_list)) {
/* this tuple is unknown to the core */
this->next = NULL;
this->code = tpl_code;
this->size = tpl_link;
*prev = this;
prev = &this->next;
printk(KERN_DEBUG
"%s: queuing CIS tuple 0x%02x length %u\n",
mmc_hostname(card->host), tpl_code, tpl_link);
} else {
if (i < ARRAY_SIZE(cis_tpl_list)) {
const struct cis_tpl *tpl = cis_tpl_list + i;
if (tpl_link < tpl->min_size) {
printk(KERN_ERR
"%s: bad CIS tuple 0x%02x (length = %u, expected >= %u)\n",
"%s: bad CIS tuple 0x%02x"
" (length = %u, expected >= %u)\n",
mmc_hostname(card->host),
tpl_code, tpl_link, tpl->min_size);
ret = -EINVAL;
} else if (tpl->parse) {
ret = tpl->parse(card, func,
this->data, tpl_link);
}
kfree(this);
/*
* We don't need the tuple anymore if it was
* successfully parsed by the SDIO core or if it is
* not going to be parsed by SDIO drivers.
*/
if (!ret || ret != -EILSEQ)
kfree(this);
} else {
/* unknown tuple */
ret = -EILSEQ;
}

if (ret == -EILSEQ) {
/* this tuple is unknown to the core or whitelisted */
this->next = NULL;
this->code = tpl_code;
this->size = tpl_link;
*prev = this;
prev = &this->next;
printk(KERN_DEBUG
"%s: queuing CIS tuple 0x%02x length %u\n",
mmc_hostname(card->host), tpl_code, tpl_link);
/* keep on analyzing tuples */
ret = 0;
}

ptr += tpl_link;
Expand Down

0 comments on commit 5639a38

Please sign in to comment.