aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2006-11-21 17:54:23 +0100
committerPierre Ossman <drzeus@drzeus.cx>2007-02-04 20:54:10 +0100
commitfe4a3c7a20f14d86022a8132adbf6ddb98e7197c (patch)
tree0719b8eb2d8c04c286095365ebff3d29285a5796
parenttifm_sd: add suspend and resume functionality (diff)
downloadlinux-dev-fe4a3c7a20f14d86022a8132adbf6ddb98e7197c.tar.xz
linux-dev-fe4a3c7a20f14d86022a8132adbf6ddb98e7197c.zip
mmc: Allow host drivers to specify a max block size
Most controllers have an upper limit on the block size. Allow the host drivers to specify this and make sure we avoid hitting this limit. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
-rw-r--r--drivers/mmc/at91_mci.c2
-rw-r--r--drivers/mmc/au1xmmc.c2
-rw-r--r--drivers/mmc/imxmmc.c1
-rw-r--r--drivers/mmc/mmc.c4
-rw-r--r--drivers/mmc/mmci.c5
-rw-r--r--drivers/mmc/omap.c1
-rw-r--r--drivers/mmc/pxamci.c5
-rw-r--r--drivers/mmc/sdhci.c24
-rw-r--r--drivers/mmc/sdhci.h1
-rw-r--r--drivers/mmc/tifm_sd.c4
-rw-r--r--drivers/mmc/wbsd.c6
-rw-r--r--include/linux/mmc/host.h1
12 files changed, 44 insertions, 12 deletions
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c
index aa152f31851e..e28850dec9ed 100644
--- a/drivers/mmc/at91_mci.c
+++ b/drivers/mmc/at91_mci.c
@@ -823,6 +823,8 @@ static int __init at91_mci_probe(struct platform_device *pdev)
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
mmc->caps = MMC_CAP_BYTEBLOCK;
+ mmc->max_blk_size = 4095;
+
host = mmc_priv(mmc);
host->mmc = mmc;
host->buffer = NULL;
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c
index 6d6fe6e6d415..74e6ac0c7f71 100644
--- a/drivers/mmc/au1xmmc.c
+++ b/drivers/mmc/au1xmmc.c
@@ -922,6 +922,8 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE;
mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT;
+ mmc->max_blk_size = 2048;
+
mmc->ocr_avail = AU1XMMC_OCR;
host = mmc_priv(mmc);
diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c
index bfb9ff693208..2107f8a8605e 100644
--- a/drivers/mmc/imxmmc.c
+++ b/drivers/mmc/imxmmc.c
@@ -960,6 +960,7 @@ static int imxmci_probe(struct platform_device *pdev)
mmc->max_phys_segs = 64;
mmc->max_sectors = 64; /* default 1 << (PAGE_CACHE_SHIFT - 9) */
mmc->max_seg_size = 64*512; /* default PAGE_CACHE_SIZE */
+ mmc->max_blk_size = 2048;
host = mmc_priv(mmc);
host->mmc = mmc;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index b48c277312de..9bda3fddad17 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -108,6 +108,8 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
mrq->cmd->error = 0;
mrq->cmd->mrq = mrq;
if (mrq->data) {
+ BUG_ON(mrq->data->blksz > host->max_blk_size);
+
mrq->cmd->data = mrq->data;
mrq->data->error = 0;
mrq->data->mrq = mrq;
@@ -1605,6 +1607,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
host->max_phys_segs = 1;
host->max_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
host->max_seg_size = PAGE_CACHE_SIZE;
+
+ host->max_blk_size = 512;
}
return host;
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index ccfe6561be24..5d48e0081894 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -534,6 +534,11 @@ static int mmci_probe(struct amba_device *dev, void *id)
*/
mmc->max_seg_size = mmc->max_sectors << 9;
+ /*
+ * Block size can be up to 2048 bytes, but must be a power of two.
+ */
+ mmc->max_blk_size = 2048;
+
spin_lock_init(&host->lock);
writel(0, host->base + MMCIMASK0);
diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c
index d30540b27614..fa69a0dc5969 100644
--- a/drivers/mmc/omap.c
+++ b/drivers/mmc/omap.c
@@ -1099,6 +1099,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
*/
mmc->max_phys_segs = 32;
mmc->max_hw_segs = 32;
+ mmc->max_blk_size = 2048; /* BLEN is 11 bits (+1) */
mmc->max_sectors = 256; /* NBLK max 11-bits, OMAP also limited by DMA */
mmc->max_seg_size = mmc->max_sectors * 512;
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index 6073d998b11f..9fc9aed1a5ef 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -450,6 +450,11 @@ static int pxamci_probe(struct platform_device *pdev)
*/
mmc->max_seg_size = PAGE_SIZE;
+ /*
+ * Block length register is 10 bits.
+ */
+ mmc->max_blk_size = 1023;
+
host = mmc_priv(mmc);
host->mmc = mmc;
host->dma = -1;
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 175a9427b9ba..155aafe69bf4 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -381,7 +381,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
/* Sanity checks */
BUG_ON(data->blksz * data->blocks > 524288);
- BUG_ON(data->blksz > host->max_block);
+ BUG_ON(data->blksz > host->mmc->max_blk_size);
BUG_ON(data->blocks > 65535);
/* timeout in us */
@@ -1290,15 +1290,6 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
if (caps & SDHCI_TIMEOUT_CLK_UNIT)
host->timeout_clk *= 1000;
- host->max_block = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
- if (host->max_block >= 3) {
- printk(KERN_ERR "%s: Invalid maximum block size.\n",
- host->slot_descr);
- ret = -ENODEV;
- goto unmap;
- }
- host->max_block = 512 << host->max_block;
-
/*
* Set host parameters.
*/
@@ -1353,6 +1344,19 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
mmc->max_seg_size = mmc->max_sectors * 512;
/*
+ * Maximum block size. This varies from controller to controller and
+ * is specified in the capabilities register.
+ */
+ mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
+ if (mmc->max_blk_size >= 3) {
+ printk(KERN_ERR "%s: Invalid maximum block size.\n",
+ host->slot_descr);
+ ret = -ENODEV;
+ goto unmap;
+ }
+ mmc->max_blk_size = 512 << mmc->max_blk_size;
+
+ /*
* Init tasklets.
*/
tasklet_init(&host->card_tasklet,
diff --git a/drivers/mmc/sdhci.h b/drivers/mmc/sdhci.h
index f9d1a0a6f03a..bc6bf7e7757d 100644
--- a/drivers/mmc/sdhci.h
+++ b/drivers/mmc/sdhci.h
@@ -174,7 +174,6 @@ struct sdhci_host {
unsigned int max_clk; /* Max possible freq (MHz) */
unsigned int timeout_clk; /* Timeout freq (KHz) */
- unsigned int max_block; /* Max block size (bytes) */
unsigned int clock; /* Current clock (MHz) */
unsigned short power; /* Current voltage */
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index ce19b045ca6a..bdfad15371b8 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -886,7 +886,9 @@ static int tifm_sd_probe(struct tifm_dev *sock)
mmc->max_hw_segs = 1;
mmc->max_phys_segs = 1;
mmc->max_sectors = 127;
- mmc->max_seg_size = mmc->max_sectors << 11; //2k maximum hw block length
+ //2k maximum hw block length
+ mmc->max_seg_size = mmc->max_sectors << 11;
+ mmc->max_blk_size = 2048;
sock->signal_irq = tifm_sd_signal_irq;
rc = tifm_sd_initialize_host(host);
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 7a282672f8e9..5711beecb4e8 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1354,6 +1354,12 @@ static int __devinit wbsd_alloc_mmc(struct device *dev)
*/
mmc->max_seg_size = mmc->max_sectors * 512;
+ /*
+ * Maximum block size. We have 12 bits (= 4095) but have to subtract
+ * space for CRC. So the maximum is 4095 - 4*2 = 4087.
+ */
+ mmc->max_blk_size = 4087;
+
dev_set_drvdata(dev, mmc);
return 0;
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index ae98d6766bdd..2da0c918a8cc 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -94,6 +94,7 @@ struct mmc_host {
unsigned short max_phys_segs; /* see blk_queue_max_phys_segments */
unsigned short max_sectors; /* see blk_queue_max_sectors */
unsigned short unused;
+ unsigned int max_blk_size; /* maximum size of one mmc block */
/* private data */
struct mmc_ios ios; /* current io bus settings */