aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/at91_mci.c1
-rw-r--r--drivers/mmc/imxmmc.c2
-rw-r--r--drivers/mmc/mmc.c1
-rw-r--r--drivers/mmc/mmc_block.c66
-rw-r--r--drivers/mmc/mmci.c13
-rw-r--r--drivers/mmc/omap.c7
-rw-r--r--drivers/mmc/sdhci.c2
-rw-r--r--drivers/mmc/wbsd.c2
-rw-r--r--include/linux/mmc/host.h2
-rw-r--r--include/linux/mmc/mmc.h1
10 files changed, 59 insertions, 38 deletions
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c
index 6b7638b84290..d34b7d9d92ed 100644
--- a/drivers/mmc/at91_mci.c
+++ b/drivers/mmc/at91_mci.c
@@ -822,6 +822,7 @@ static int at91_mci_probe(struct platform_device *pdev)
822 mmc->f_min = 375000; 822 mmc->f_min = 375000;
823 mmc->f_max = 25000000; 823 mmc->f_max = 25000000;
824 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 824 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
825 mmc->caps = MMC_CAP_BYTEBLOCK;
825 826
826 host = mmc_priv(mmc); 827 host = mmc_priv(mmc);
827 host->mmc = mmc; 828 host->mmc = mmc;
diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c
index fb6565b98f32..1b79dd271aae 100644
--- a/drivers/mmc/imxmmc.c
+++ b/drivers/mmc/imxmmc.c
@@ -956,7 +956,7 @@ static int imxmci_probe(struct platform_device *pdev)
956 mmc->f_min = 150000; 956 mmc->f_min = 150000;
957 mmc->f_max = CLK_RATE/2; 957 mmc->f_max = CLK_RATE/2;
958 mmc->ocr_avail = MMC_VDD_32_33; 958 mmc->ocr_avail = MMC_VDD_32_33;
959 mmc->caps |= MMC_CAP_4_BIT_DATA; 959 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_BYTEBLOCK;
960 960
961 /* MMC core transfer sizes tunable parameters */ 961 /* MMC core transfer sizes tunable parameters */
962 mmc->max_hw_segs = 64; 962 mmc->max_hw_segs = 64;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 74eaaee66de0..5b9caa7978d3 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -996,7 +996,6 @@ static void mmc_read_scrs(struct mmc_host *host)
996 996
997 mmc_set_data_timeout(&data, card, 0); 997 mmc_set_data_timeout(&data, card, 0);
998 998
999 data.blksz_bits = 3;
1000 data.blksz = 1 << 3; 999 data.blksz = 1 << 3;
1001 data.blocks = 1; 1000 data.blocks = 1;
1002 data.flags = MMC_DATA_READ; 1001 data.flags = MMC_DATA_READ;
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index a0e0dad1b419..db0e8ad439a5 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -32,6 +32,7 @@
32#include <linux/mmc/card.h> 32#include <linux/mmc/card.h>
33#include <linux/mmc/host.h> 33#include <linux/mmc/host.h>
34#include <linux/mmc/protocol.h> 34#include <linux/mmc/protocol.h>
35#include <linux/mmc/host.h>
35 36
36#include <asm/system.h> 37#include <asm/system.h>
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
@@ -165,6 +166,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
165 do { 166 do {
166 struct mmc_blk_request brq; 167 struct mmc_blk_request brq;
167 struct mmc_command cmd; 168 struct mmc_command cmd;
169 u32 readcmd, writecmd;
168 170
169 memset(&brq, 0, sizeof(struct mmc_blk_request)); 171 memset(&brq, 0, sizeof(struct mmc_blk_request));
170 brq.mrq.cmd = &brq.cmd; 172 brq.mrq.cmd = &brq.cmd;
@@ -172,7 +174,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
172 174
173 brq.cmd.arg = req->sector << 9; 175 brq.cmd.arg = req->sector << 9;
174 brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 176 brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
175 brq.data.blksz_bits = md->block_bits;
176 brq.data.blksz = 1 << md->block_bits; 177 brq.data.blksz = 1 << md->block_bits;
177 brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); 178 brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
178 brq.stop.opcode = MMC_STOP_TRANSMISSION; 179 brq.stop.opcode = MMC_STOP_TRANSMISSION;
@@ -181,20 +182,31 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
181 182
182 mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ); 183 mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ);
183 184
184 if (rq_data_dir(req) == READ) { 185 /*
185 brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; 186 * If the host doesn't support multiple block writes, force
186 brq.data.flags |= MMC_DATA_READ; 187 * block writes to single block.
187 } else { 188 */
188 brq.cmd.opcode = MMC_WRITE_BLOCK; 189 if (rq_data_dir(req) != READ &&
189 brq.data.flags |= MMC_DATA_WRITE; 190 !(card->host->caps & MMC_CAP_MULTIWRITE))
190 brq.data.blocks = 1; 191 brq.data.blocks = 1;
191 }
192 192
193 if (brq.data.blocks > 1) { 193 if (brq.data.blocks > 1) {
194 brq.data.flags |= MMC_DATA_MULTI; 194 brq.data.flags |= MMC_DATA_MULTI;
195 brq.mrq.stop = &brq.stop; 195 brq.mrq.stop = &brq.stop;
196 readcmd = MMC_READ_MULTIPLE_BLOCK;
197 writecmd = MMC_WRITE_MULTIPLE_BLOCK;
196 } else { 198 } else {
197 brq.mrq.stop = NULL; 199 brq.mrq.stop = NULL;
200 readcmd = MMC_READ_SINGLE_BLOCK;
201 writecmd = MMC_WRITE_BLOCK;
202 }
203
204 if (rq_data_dir(req) == READ) {
205 brq.cmd.opcode = readcmd;
206 brq.data.flags |= MMC_DATA_READ;
207 } else {
208 brq.cmd.opcode = writecmd;
209 brq.data.flags |= MMC_DATA_WRITE;
198 } 210 }
199 211
200 brq.data.sg = mq->sg; 212 brq.data.sg = mq->sg;
@@ -219,27 +231,29 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
219 goto cmd_err; 231 goto cmd_err;
220 } 232 }
221 233
222 do { 234 if (rq_data_dir(req) != READ) {
223 int err; 235 do {
224 236 int err;
225 cmd.opcode = MMC_SEND_STATUS; 237
226 cmd.arg = card->rca << 16; 238 cmd.opcode = MMC_SEND_STATUS;
227 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 239 cmd.arg = card->rca << 16;
228 err = mmc_wait_for_cmd(card->host, &cmd, 5); 240 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
229 if (err) { 241 err = mmc_wait_for_cmd(card->host, &cmd, 5);
230 printk(KERN_ERR "%s: error %d requesting status\n", 242 if (err) {
231 req->rq_disk->disk_name, err); 243 printk(KERN_ERR "%s: error %d requesting status\n",
232 goto cmd_err; 244 req->rq_disk->disk_name, err);
233 } 245 goto cmd_err;
234 } while (!(cmd.resp[0] & R1_READY_FOR_DATA)); 246 }
247 } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
235 248
236#if 0 249#if 0
237 if (cmd.resp[0] & ~0x00000900) 250 if (cmd.resp[0] & ~0x00000900)
238 printk(KERN_ERR "%s: status = %08x\n", 251 printk(KERN_ERR "%s: status = %08x\n",
239 req->rq_disk->disk_name, cmd.resp[0]); 252 req->rq_disk->disk_name, cmd.resp[0]);
240 if (mmc_decode_status(cmd.resp)) 253 if (mmc_decode_status(cmd.resp))
241 goto cmd_err; 254 goto cmd_err;
242#endif 255#endif
256 }
243 257
244 /* 258 /*
245 * A block was successfully transferred. 259 * A block was successfully transferred.
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 1886562abdd4..2b5a0cc9ea56 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -69,12 +69,13 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
69 unsigned int datactrl, timeout, irqmask; 69 unsigned int datactrl, timeout, irqmask;
70 unsigned long long clks; 70 unsigned long long clks;
71 void __iomem *base; 71 void __iomem *base;
72 int blksz_bits;
72 73
73 DBG(host, "blksz %04x blks %04x flags %08x\n", 74 DBG(host, "blksz %04x blks %04x flags %08x\n",
74 1 << data->blksz_bits, data->blocks, data->flags); 75 data->blksz, data->blocks, data->flags);
75 76
76 host->data = data; 77 host->data = data;
77 host->size = data->blocks << data->blksz_bits; 78 host->size = data->blksz;
78 host->data_xfered = 0; 79 host->data_xfered = 0;
79 80
80 mmci_init_sg(host, data); 81 mmci_init_sg(host, data);
@@ -88,7 +89,10 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
88 writel(timeout, base + MMCIDATATIMER); 89 writel(timeout, base + MMCIDATATIMER);
89 writel(host->size, base + MMCIDATALENGTH); 90 writel(host->size, base + MMCIDATALENGTH);
90 91
91 datactrl = MCI_DPSM_ENABLE | data->blksz_bits << 4; 92 blksz_bits = ffs(data->blksz) - 1;
93 BUG_ON(1 << blksz_bits != data->blksz);
94
95 datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;
92 if (data->flags & MMC_DATA_READ) { 96 if (data->flags & MMC_DATA_READ) {
93 datactrl |= MCI_DPSM_DIRECTION; 97 datactrl |= MCI_DPSM_DIRECTION;
94 irqmask = MCI_RXFIFOHALFFULLMASK; 98 irqmask = MCI_RXFIFOHALFFULLMASK;
@@ -145,7 +149,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
145 unsigned int status) 149 unsigned int status)
146{ 150{
147 if (status & MCI_DATABLOCKEND) { 151 if (status & MCI_DATABLOCKEND) {
148 host->data_xfered += 1 << data->blksz_bits; 152 host->data_xfered += data->blksz;
149 } 153 }
150 if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { 154 if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
151 if (status & MCI_DATACRCFAIL) 155 if (status & MCI_DATACRCFAIL)
@@ -505,6 +509,7 @@ static int mmci_probe(struct amba_device *dev, void *id)
505 mmc->f_min = (host->mclk + 511) / 512; 509 mmc->f_min = (host->mclk + 511) / 512;
506 mmc->f_max = min(host->mclk, fmax); 510 mmc->f_max = min(host->mclk, fmax);
507 mmc->ocr_avail = plat->ocr_mask; 511 mmc->ocr_avail = plat->ocr_mask;
512 mmc->caps = MMC_CAP_MULTIWRITE;
508 513
509 /* 514 /*
510 * We can do SGIO 515 * We can do SGIO
diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c
index ddf06b32c159..52c9e52e6b78 100644
--- a/drivers/mmc/omap.c
+++ b/drivers/mmc/omap.c
@@ -1034,13 +1034,14 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
1034 host->irq = pdev->resource[1].start; 1034 host->irq = pdev->resource[1].start;
1035 host->base = (void __iomem*)IO_ADDRESS(r->start); 1035 host->base = (void __iomem*)IO_ADDRESS(r->start);
1036 1036
1037 if (minfo->wire4)
1038 mmc->caps |= MMC_CAP_4_BIT_DATA;
1039
1040 mmc->ops = &mmc_omap_ops; 1037 mmc->ops = &mmc_omap_ops;
1041 mmc->f_min = 400000; 1038 mmc->f_min = 400000;
1042 mmc->f_max = 24000000; 1039 mmc->f_max = 24000000;
1043 mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; 1040 mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
1041 mmc->caps = MMC_CAP_BYTEBLOCK;
1042
1043 if (minfo->wire4)
1044 mmc->caps |= MMC_CAP_4_BIT_DATA;
1044 1045
1045 /* Use scatterlist DMA to reduce per-transfer costs. 1046 /* Use scatterlist DMA to reduce per-transfer costs.
1046 * NOTE max_seg_size assumption that small blocks aren't 1047 * NOTE max_seg_size assumption that small blocks aren't
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 4e21b3b9d330..fdfc3838dd79 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -1262,7 +1262,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1262 mmc->ops = &sdhci_ops; 1262 mmc->ops = &sdhci_ops;
1263 mmc->f_min = host->max_clk / 256; 1263 mmc->f_min = host->max_clk / 256;
1264 mmc->f_max = host->max_clk; 1264 mmc->f_max = host->max_clk;
1265 mmc->caps = MMC_CAP_4_BIT_DATA; 1265 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
1266 1266
1267 mmc->ocr_avail = 0; 1267 mmc->ocr_avail = 0;
1268 if (caps & SDHCI_CAN_VDD_330) 1268 if (caps & SDHCI_CAN_VDD_330)
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index c351c6d1a18a..6435a6822ad3 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1323,7 +1323,7 @@ static int __devinit wbsd_alloc_mmc(struct device *dev)
1323 mmc->f_min = 375000; 1323 mmc->f_min = 375000;
1324 mmc->f_max = 24000000; 1324 mmc->f_max = 24000000;
1325 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 1325 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
1326 mmc->caps = MMC_CAP_4_BIT_DATA; 1326 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
1327 1327
1328 spin_lock_init(&host->lock); 1328 spin_lock_init(&host->lock);
1329 1329
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index ba095aebedff..587264a58d56 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -85,6 +85,8 @@ struct mmc_host {
85 unsigned long caps; /* Host capabilities */ 85 unsigned long caps; /* Host capabilities */
86 86
87#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */ 87#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */
88#define MMC_CAP_MULTIWRITE (1 << 1) /* Can accurately report bytes sent to card on error */
89#define MMC_CAP_BYTEBLOCK (1 << 2) /* Can do non-log2 block sizes */
88 90
89 /* host specific block data */ 91 /* host specific block data */
90 unsigned int max_seg_size; /* see blk_queue_max_segment_size */ 92 unsigned int max_seg_size; /* see blk_queue_max_segment_size */
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 627e2c08ce41..a3594dfd6963 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -68,7 +68,6 @@ struct mmc_command {
68struct mmc_data { 68struct mmc_data {
69 unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */ 69 unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */
70 unsigned int timeout_clks; /* data timeout (in clocks) */ 70 unsigned int timeout_clks; /* data timeout (in clocks) */
71 unsigned int blksz_bits; /* data block size */
72 unsigned int blksz; /* data block size */ 71 unsigned int blksz; /* data block size */
73 unsigned int blocks; /* number of blocks */ 72 unsigned int blocks; /* number of blocks */
74 unsigned int error; /* data error */ 73 unsigned int error; /* data error */