diff options
author | Eric Nelson <eric.nelson@boundarydevices.com> | 2012-06-25 16:26:23 -0700 |
---|---|---|
committer | Eric Nelson <eric.nelson@boundarydevices.com> | 2012-06-25 16:26:23 -0700 |
commit | 576b8cf2a1711ea1bb638b484c092c8c10029925 (patch) | |
tree | 6891126b1523aea3c0efcf4ff9fa7ee4be56d988 /drivers | |
parent | a2c3ad945df6fc746cb5bcc70c89cc454780c065 (diff) |
sdio_cis: hack for broken wl127x CIS
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/core/sdio_cis.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index 541bdb89e0c5..3b0ca8379897 100644 --- a/drivers/mmc/core/sdio_cis.c +++ b/drivers/mmc/core/sdio_cis.c @@ -230,6 +230,7 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) int ret; struct sdio_func_tuple *this, **prev; unsigned i, ptr = 0; + unsigned ptr_null_end; /* * Note that this works for the common CIS (function number 0) as @@ -258,6 +259,7 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) BUG_ON(*prev); + ptr_null_end = (ptr | 0xff) + 1; do { unsigned char tpl_code, tpl_link; @@ -269,6 +271,9 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) if (tpl_code == 0xff) break; + if ((tpl_code == 0x00) && (ptr == ptr_null_end)) + break; /* patch for misbehaving rtl8712 card */ + /* null entries have no link field or data */ if (tpl_code == 0x00) continue; @@ -282,9 +287,10 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) break; this = kmalloc(sizeof(*this) + tpl_link, GFP_KERNEL); - if (!this) - return -ENOMEM; - + if (!this) { + ret = -ENOMEM; + break; + } for (i = 0; i < tpl_link; i++) { ret = mmc_io_rw_direct(card, 0, 0, ptr + i, 0, &this->data[i]); @@ -328,6 +334,12 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) * not going to be queued for a driver. */ kfree(this); + if (ret) { + printk(KERN_WARNING "%s: dropping invalid" + " CIS tuple 0x%02x (%u bytes)\n", + mmc_hostname(card->host), + tpl_code, tpl_link); + } } ptr += tpl_link; |