diff --git a/target/linux/generic-2.6/patches-2.6.23/301-mmc_sdhci_fixes.patch b/target/linux/generic-2.6/patches-2.6.23/301-mmc_sdhci_fixes.patch new file mode 100644 index 0000000000..6694f58959 --- /dev/null +++ b/target/linux/generic-2.6/patches-2.6.23/301-mmc_sdhci_fixes.patch @@ -0,0 +1,154 @@ +Index: linux-2.6.23.16/drivers/mmc/host/sdhci.c +=================================================================== +--- linux-2.6.23.16.orig/drivers/mmc/host/sdhci.c 2008-04-28 08:33:14.000000000 +0200 ++++ linux-2.6.23.16/drivers/mmc/host/sdhci.c 2008-04-28 08:36:40.000000000 +0200 +@@ -487,16 +487,16 @@ + * Controller doesn't count down when in single block mode. + */ + if (data->blocks == 1) +- blocks = (data->error == MMC_ERR_NONE) ? 0 : 1; ++ blocks = (data->error == 0) ? 0 : 1; + else + blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); + data->bytes_xfered = data->blksz * (data->blocks - blocks); + +- if ((data->error == MMC_ERR_NONE) && blocks) { ++ if (!data->error && blocks) { + printk(KERN_ERR "%s: Controller signalled completion even " + "though there were blocks left.\n", + mmc_hostname(host->mmc)); +- data->error = MMC_ERR_FAILED; ++ data->error = -EIO; + } + + if (data->stop) { +@@ -504,7 +504,7 @@ + * The controller needs a reset of internal state machines + * upon error conditions. + */ +- if (data->error != MMC_ERR_NONE) { ++ if (data->error) { + sdhci_reset(host, SDHCI_RESET_CMD); + sdhci_reset(host, SDHCI_RESET_DATA); + } +@@ -539,7 +539,7 @@ + printk(KERN_ERR "%s: Controller never released " + "inhibit bit(s).\n", mmc_hostname(host->mmc)); + sdhci_dumpregs(host); +- cmd->error = MMC_ERR_FAILED; ++ cmd->error = -EIO; + tasklet_schedule(&host->finish_tasklet); + return; + } +@@ -560,7 +560,7 @@ + if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { + printk(KERN_ERR "%s: Unsupported response type!\n", + mmc_hostname(host->mmc)); +- cmd->error = MMC_ERR_INVALID; ++ cmd->error = -EINVAL; + tasklet_schedule(&host->finish_tasklet); + return; + } +@@ -607,7 +607,7 @@ + } + } + +- host->cmd->error = MMC_ERR_NONE; ++ host->cmd->error = 0; + + if (host->data && host->data_early) + sdhci_finish_data(host); +@@ -730,7 +730,7 @@ + host->mrq = mrq; + + if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { +- host->mrq->cmd->error = MMC_ERR_TIMEOUT; ++ host->mrq->cmd->error = -ENOMEDIUM; + tasklet_schedule(&host->finish_tasklet); + } else + sdhci_send_command(host, mrq->cmd); +@@ -839,7 +839,7 @@ + sdhci_reset(host, SDHCI_RESET_CMD); + sdhci_reset(host, SDHCI_RESET_DATA); + +- host->mrq->cmd->error = MMC_ERR_FAILED; ++ host->mrq->cmd->error = -ENOMEDIUM; + tasklet_schedule(&host->finish_tasklet); + } + } +@@ -867,9 +867,9 @@ + * The controller needs a reset of internal state machines + * upon error conditions. + */ +- if ((mrq->cmd->error != MMC_ERR_NONE) || +- (mrq->data && ((mrq->data->error != MMC_ERR_NONE) || +- (mrq->data->stop && (mrq->data->stop->error != MMC_ERR_NONE))))) { ++ if (mrq->cmd->error || ++ (mrq->data && (mrq->data->error || ++ (mrq->data->stop && mrq->data->stop->error)))) { + + /* Some controllers need this kick or reset won't work here */ + if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { +@@ -914,13 +914,13 @@ + sdhci_dumpregs(host); + + if (host->data) { +- host->data->error = MMC_ERR_TIMEOUT; ++ host->data->error = -ETIMEDOUT; + sdhci_finish_data(host); + } else { + if (host->cmd) +- host->cmd->error = MMC_ERR_TIMEOUT; ++ host->cmd->error = -ETIMEDOUT; + else +- host->mrq->cmd->error = MMC_ERR_TIMEOUT; ++ host->mrq->cmd->error = -ETIMEDOUT; + + tasklet_schedule(&host->finish_tasklet); + } +@@ -949,13 +949,12 @@ + } + + if (intmask & SDHCI_INT_TIMEOUT) +- host->cmd->error = MMC_ERR_TIMEOUT; +- else if (intmask & SDHCI_INT_CRC) +- host->cmd->error = MMC_ERR_BADCRC; +- else if (intmask & (SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) +- host->cmd->error = MMC_ERR_FAILED; ++ host->cmd->error = -ETIMEDOUT; ++ else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT | ++ SDHCI_INT_INDEX)) ++ host->cmd->error = -EILSEQ; + +- if (host->cmd->error != MMC_ERR_NONE) ++ if (host->cmd->error) + tasklet_schedule(&host->finish_tasklet); + else if (intmask & SDHCI_INT_RESPONSE) + sdhci_finish_command(host); +@@ -982,13 +981,11 @@ + } + + if (intmask & SDHCI_INT_DATA_TIMEOUT) +- host->data->error = MMC_ERR_TIMEOUT; +- else if (intmask & SDHCI_INT_DATA_CRC) +- host->data->error = MMC_ERR_BADCRC; +- else if (intmask & SDHCI_INT_DATA_END_BIT) +- host->data->error = MMC_ERR_FAILED; ++ host->data->error = -ETIMEDOUT; ++ else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT)) ++ host->data->error = -EILSEQ; + +- if (host->data->error != MMC_ERR_NONE) ++ if (host->data->error) + sdhci_finish_data(host); + else { + if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) +@@ -1320,7 +1317,7 @@ + mmc->ops = &sdhci_ops; + mmc->f_min = host->max_clk / 256; + mmc->f_max = host->max_clk; +- mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK; ++ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; + + if (caps & SDHCI_CAN_DO_HISPD) + mmc->caps |= MMC_CAP_SD_HIGHSPEED;