mirror of https://gitee.com/openkylin/linux.git
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-mmc
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-mmc: [MMC] Don't check READY_FOR_DATA when reading [MMC] MMC_CAP_BYTEBLOCK flag for non-log2 block sizes capable hosts [MMC] Add multi block-write capability [MMC] Remove data->blksz_bits member [MMC] Convert mmci to use data->blksz rather than data->blksz_bits
This commit is contained in:
commit
fecf3404f4
|
@ -822,6 +822,7 @@ static int at91_mci_probe(struct platform_device *pdev)
|
|||
mmc->f_min = 375000;
|
||||
mmc->f_max = 25000000;
|
||||
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||
mmc->caps = MMC_CAP_BYTEBLOCK;
|
||||
|
||||
host = mmc_priv(mmc);
|
||||
host->mmc = mmc;
|
||||
|
|
|
@ -956,7 +956,7 @@ static int imxmci_probe(struct platform_device *pdev)
|
|||
mmc->f_min = 150000;
|
||||
mmc->f_max = CLK_RATE/2;
|
||||
mmc->ocr_avail = MMC_VDD_32_33;
|
||||
mmc->caps |= MMC_CAP_4_BIT_DATA;
|
||||
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_BYTEBLOCK;
|
||||
|
||||
/* MMC core transfer sizes tunable parameters */
|
||||
mmc->max_hw_segs = 64;
|
||||
|
|
|
@ -996,7 +996,6 @@ static void mmc_read_scrs(struct mmc_host *host)
|
|||
|
||||
mmc_set_data_timeout(&data, card, 0);
|
||||
|
||||
data.blksz_bits = 3;
|
||||
data.blksz = 1 << 3;
|
||||
data.blocks = 1;
|
||||
data.flags = MMC_DATA_READ;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/protocol.h>
|
||||
#include <linux/mmc/host.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
@ -165,6 +166,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
|||
do {
|
||||
struct mmc_blk_request brq;
|
||||
struct mmc_command cmd;
|
||||
u32 readcmd, writecmd;
|
||||
|
||||
memset(&brq, 0, sizeof(struct mmc_blk_request));
|
||||
brq.mrq.cmd = &brq.cmd;
|
||||
|
@ -172,7 +174,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
|||
|
||||
brq.cmd.arg = req->sector << 9;
|
||||
brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
|
||||
brq.data.blksz_bits = md->block_bits;
|
||||
brq.data.blksz = 1 << md->block_bits;
|
||||
brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
|
||||
brq.stop.opcode = MMC_STOP_TRANSMISSION;
|
||||
|
@ -181,20 +182,31 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
|||
|
||||
mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ);
|
||||
|
||||
if (rq_data_dir(req) == READ) {
|
||||
brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK;
|
||||
brq.data.flags |= MMC_DATA_READ;
|
||||
} else {
|
||||
brq.cmd.opcode = MMC_WRITE_BLOCK;
|
||||
brq.data.flags |= MMC_DATA_WRITE;
|
||||
/*
|
||||
* If the host doesn't support multiple block writes, force
|
||||
* block writes to single block.
|
||||
*/
|
||||
if (rq_data_dir(req) != READ &&
|
||||
!(card->host->caps & MMC_CAP_MULTIWRITE))
|
||||
brq.data.blocks = 1;
|
||||
}
|
||||
|
||||
if (brq.data.blocks > 1) {
|
||||
brq.data.flags |= MMC_DATA_MULTI;
|
||||
brq.mrq.stop = &brq.stop;
|
||||
readcmd = MMC_READ_MULTIPLE_BLOCK;
|
||||
writecmd = MMC_WRITE_MULTIPLE_BLOCK;
|
||||
} else {
|
||||
brq.mrq.stop = NULL;
|
||||
readcmd = MMC_READ_SINGLE_BLOCK;
|
||||
writecmd = MMC_WRITE_BLOCK;
|
||||
}
|
||||
|
||||
if (rq_data_dir(req) == READ) {
|
||||
brq.cmd.opcode = readcmd;
|
||||
brq.data.flags |= MMC_DATA_READ;
|
||||
} else {
|
||||
brq.cmd.opcode = writecmd;
|
||||
brq.data.flags |= MMC_DATA_WRITE;
|
||||
}
|
||||
|
||||
brq.data.sg = mq->sg;
|
||||
|
@ -219,27 +231,29 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
|||
goto cmd_err;
|
||||
}
|
||||
|
||||
do {
|
||||
int err;
|
||||
if (rq_data_dir(req) != READ) {
|
||||
do {
|
||||
int err;
|
||||
|
||||
cmd.opcode = MMC_SEND_STATUS;
|
||||
cmd.arg = card->rca << 16;
|
||||
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
|
||||
err = mmc_wait_for_cmd(card->host, &cmd, 5);
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: error %d requesting status\n",
|
||||
req->rq_disk->disk_name, err);
|
||||
goto cmd_err;
|
||||
}
|
||||
} while (!(cmd.resp[0] & R1_READY_FOR_DATA));
|
||||
cmd.opcode = MMC_SEND_STATUS;
|
||||
cmd.arg = card->rca << 16;
|
||||
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
|
||||
err = mmc_wait_for_cmd(card->host, &cmd, 5);
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: error %d requesting status\n",
|
||||
req->rq_disk->disk_name, err);
|
||||
goto cmd_err;
|
||||
}
|
||||
} while (!(cmd.resp[0] & R1_READY_FOR_DATA));
|
||||
|
||||
#if 0
|
||||
if (cmd.resp[0] & ~0x00000900)
|
||||
printk(KERN_ERR "%s: status = %08x\n",
|
||||
req->rq_disk->disk_name, cmd.resp[0]);
|
||||
if (mmc_decode_status(cmd.resp))
|
||||
goto cmd_err;
|
||||
if (cmd.resp[0] & ~0x00000900)
|
||||
printk(KERN_ERR "%s: status = %08x\n",
|
||||
req->rq_disk->disk_name, cmd.resp[0]);
|
||||
if (mmc_decode_status(cmd.resp))
|
||||
goto cmd_err;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* A block was successfully transferred.
|
||||
|
|
|
@ -69,12 +69,13 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
|
|||
unsigned int datactrl, timeout, irqmask;
|
||||
unsigned long long clks;
|
||||
void __iomem *base;
|
||||
int blksz_bits;
|
||||
|
||||
DBG(host, "blksz %04x blks %04x flags %08x\n",
|
||||
1 << data->blksz_bits, data->blocks, data->flags);
|
||||
data->blksz, data->blocks, data->flags);
|
||||
|
||||
host->data = data;
|
||||
host->size = data->blocks << data->blksz_bits;
|
||||
host->size = data->blksz;
|
||||
host->data_xfered = 0;
|
||||
|
||||
mmci_init_sg(host, data);
|
||||
|
@ -88,7 +89,10 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
|
|||
writel(timeout, base + MMCIDATATIMER);
|
||||
writel(host->size, base + MMCIDATALENGTH);
|
||||
|
||||
datactrl = MCI_DPSM_ENABLE | data->blksz_bits << 4;
|
||||
blksz_bits = ffs(data->blksz) - 1;
|
||||
BUG_ON(1 << blksz_bits != data->blksz);
|
||||
|
||||
datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;
|
||||
if (data->flags & MMC_DATA_READ) {
|
||||
datactrl |= MCI_DPSM_DIRECTION;
|
||||
irqmask = MCI_RXFIFOHALFFULLMASK;
|
||||
|
@ -145,7 +149,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
|
|||
unsigned int status)
|
||||
{
|
||||
if (status & MCI_DATABLOCKEND) {
|
||||
host->data_xfered += 1 << data->blksz_bits;
|
||||
host->data_xfered += data->blksz;
|
||||
}
|
||||
if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
|
||||
if (status & MCI_DATACRCFAIL)
|
||||
|
@ -505,6 +509,7 @@ static int mmci_probe(struct amba_device *dev, void *id)
|
|||
mmc->f_min = (host->mclk + 511) / 512;
|
||||
mmc->f_max = min(host->mclk, fmax);
|
||||
mmc->ocr_avail = plat->ocr_mask;
|
||||
mmc->caps = MMC_CAP_MULTIWRITE;
|
||||
|
||||
/*
|
||||
* We can do SGIO
|
||||
|
|
|
@ -1034,13 +1034,14 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
|
|||
host->irq = pdev->resource[1].start;
|
||||
host->base = (void __iomem*)IO_ADDRESS(r->start);
|
||||
|
||||
if (minfo->wire4)
|
||||
mmc->caps |= MMC_CAP_4_BIT_DATA;
|
||||
|
||||
mmc->ops = &mmc_omap_ops;
|
||||
mmc->f_min = 400000;
|
||||
mmc->f_max = 24000000;
|
||||
mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
|
||||
mmc->caps = MMC_CAP_BYTEBLOCK;
|
||||
|
||||
if (minfo->wire4)
|
||||
mmc->caps |= MMC_CAP_4_BIT_DATA;
|
||||
|
||||
/* Use scatterlist DMA to reduce per-transfer costs.
|
||||
* NOTE max_seg_size assumption that small blocks aren't
|
||||
|
|
|
@ -1262,7 +1262,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
|
|||
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->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
|
||||
|
||||
mmc->ocr_avail = 0;
|
||||
if (caps & SDHCI_CAN_VDD_330)
|
||||
|
|
|
@ -1323,7 +1323,7 @@ static int __devinit wbsd_alloc_mmc(struct device *dev)
|
|||
mmc->f_min = 375000;
|
||||
mmc->f_max = 24000000;
|
||||
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||
mmc->caps = MMC_CAP_4_BIT_DATA;
|
||||
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
|
||||
|
||||
spin_lock_init(&host->lock);
|
||||
|
||||
|
|
|
@ -85,6 +85,8 @@ struct mmc_host {
|
|||
unsigned long caps; /* Host capabilities */
|
||||
|
||||
#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */
|
||||
#define MMC_CAP_MULTIWRITE (1 << 1) /* Can accurately report bytes sent to card on error */
|
||||
#define MMC_CAP_BYTEBLOCK (1 << 2) /* Can do non-log2 block sizes */
|
||||
|
||||
/* host specific block data */
|
||||
unsigned int max_seg_size; /* see blk_queue_max_segment_size */
|
||||
|
|
|
@ -68,7 +68,6 @@ struct mmc_command {
|
|||
struct mmc_data {
|
||||
unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */
|
||||
unsigned int timeout_clks; /* data timeout (in clocks) */
|
||||
unsigned int blksz_bits; /* data block size */
|
||||
unsigned int blksz; /* data block size */
|
||||
unsigned int blocks; /* number of blocks */
|
||||
unsigned int error; /* data error */
|
||||
|
|
Loading…
Reference in New Issue