Forum | Documentation | Website | Blog

Skip to content
Snippets Groups Projects
Commit c9b74c5b authored by Pierre Ossman's avatar Pierre Ossman
Browse files

sdhci: don't check block count for progress


The specification is insufficiently strict when it comes to how the
hardware should update the block count register, making it useless
for checking transfer progress.

Signed-off-by: default avatarPierre Ossman <drzeus@drzeus.cx>
parent 50515af2
No related merge requests found
...@@ -567,7 +567,6 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, ...@@ -567,7 +567,6 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
static void sdhci_finish_data(struct sdhci_host *host) static void sdhci_finish_data(struct sdhci_host *host)
{ {
struct mmc_data *data; struct mmc_data *data;
u16 blocks;
BUG_ON(!host->data); BUG_ON(!host->data);
...@@ -580,20 +579,16 @@ static void sdhci_finish_data(struct sdhci_host *host) ...@@ -580,20 +579,16 @@ static void sdhci_finish_data(struct sdhci_host *host)
} }
/* /*
* Controller doesn't count down when in single block mode. * The specification states that the block count register must
* be updated, but it does not specify at what point in the
* data flow. That makes the register entirely useless to read
* back so we have to assume that nothing made it to the card
* in the event of an error.
*/ */
if (data->blocks == 1) if (data->error)
blocks = (data->error == 0) ? 0 : 1; data->bytes_xfered = 0;
else else
blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); data->bytes_xfered = data->blksz * data->blocks;
data->bytes_xfered = data->blksz * (data->blocks - 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 = -EIO;
}
if (data->stop) { if (data->stop) {
/* /*
...@@ -1466,7 +1461,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) ...@@ -1466,7 +1461,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
mmc->ops = &sdhci_ops; mmc->ops = &sdhci_ops;
mmc->f_min = host->max_clk / 256; mmc->f_min = host->max_clk / 256;
mmc->f_max = host->max_clk; mmc->f_max = host->max_clk;
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_SDIO_IRQ; mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
if (caps & SDHCI_CAN_DO_HISPD) if (caps & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED; mmc->caps |= MMC_CAP_SD_HIGHSPEED;
......
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