tifm_sd: merge dma and pio request processing paths
To allow for switching of trasfer mode (dma/pio) on a per-request basis, pio and dma request issue and completion function are now merged. Signed-off-by: Alex Dubov <oakad@yahoo.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
This commit is contained in:
committed by
Pierre Ossman
parent
0007d4837a
commit
dfef26d9aa
@@ -484,19 +484,40 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|||||||
if (r_data) {
|
if (r_data) {
|
||||||
tifm_sd_set_data_timeout(host, r_data);
|
tifm_sd_set_data_timeout(host, r_data);
|
||||||
|
|
||||||
sg_count = tifm_map_sg(sock, r_data->sg, r_data->sg_len,
|
if (host->no_dma) {
|
||||||
mrq->cmd->flags & MMC_DATA_WRITE
|
host->buffer_size = mrq->cmd->data->blocks
|
||||||
? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
|
* mrq->cmd->data->blksz;
|
||||||
if (sg_count != 1) {
|
|
||||||
printk(KERN_ERR DRIVER_NAME
|
|
||||||
": scatterlist map failed\n");
|
|
||||||
spin_unlock_irqrestore(&sock->lock, flags);
|
|
||||||
goto err_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
host->written_blocks = 0;
|
writel(TIFM_MMCSD_BUFINT
|
||||||
host->cmd_flags &= ~CARD_BUSY;
|
| readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
|
||||||
tifm_sd_prepare_data(host, mrq->cmd);
|
sock->addr + SOCK_MMCSD_INT_ENABLE);
|
||||||
|
writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8)
|
||||||
|
| (TIFM_MMCSD_FIFO_SIZE - 1),
|
||||||
|
sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
|
||||||
|
|
||||||
|
host->written_blocks = 0;
|
||||||
|
host->cmd_flags &= ~CARD_BUSY;
|
||||||
|
host->buffer_pos = 0;
|
||||||
|
writel(r_data->blocks - 1,
|
||||||
|
sock->addr + SOCK_MMCSD_NUM_BLOCKS);
|
||||||
|
writel(r_data->blksz - 1,
|
||||||
|
sock->addr + SOCK_MMCSD_BLOCK_LEN);
|
||||||
|
} else {
|
||||||
|
sg_count = tifm_map_sg(sock, r_data->sg, r_data->sg_len,
|
||||||
|
mrq->cmd->flags & MMC_DATA_WRITE
|
||||||
|
? PCI_DMA_TODEVICE
|
||||||
|
: PCI_DMA_FROMDEVICE);
|
||||||
|
if (sg_count != 1) {
|
||||||
|
printk(KERN_ERR DRIVER_NAME
|
||||||
|
": scatterlist map failed\n");
|
||||||
|
spin_unlock_irqrestore(&sock->lock, flags);
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
host->written_blocks = 0;
|
||||||
|
host->cmd_flags &= ~CARD_BUSY;
|
||||||
|
tifm_sd_prepare_data(host, mrq->cmd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
host->req = mrq;
|
host->req = mrq;
|
||||||
@@ -542,19 +563,41 @@ static void tifm_sd_end_cmd(unsigned long data)
|
|||||||
|
|
||||||
r_data = mrq->cmd->data;
|
r_data = mrq->cmd->data;
|
||||||
if (r_data) {
|
if (r_data) {
|
||||||
if (r_data->flags & MMC_DATA_WRITE) {
|
if (host->no_dma) {
|
||||||
r_data->bytes_xfered = host->written_blocks
|
writel((~TIFM_MMCSD_BUFINT) &
|
||||||
* r_data->blksz;
|
readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
|
||||||
|
sock->addr + SOCK_MMCSD_INT_ENABLE);
|
||||||
|
|
||||||
|
if (r_data->flags & MMC_DATA_WRITE) {
|
||||||
|
r_data->bytes_xfered = host->written_blocks
|
||||||
|
* r_data->blksz;
|
||||||
|
} else {
|
||||||
|
r_data->bytes_xfered = r_data->blocks -
|
||||||
|
readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS)
|
||||||
|
- 1;
|
||||||
|
r_data->bytes_xfered *= r_data->blksz;
|
||||||
|
r_data->bytes_xfered += r_data->blksz
|
||||||
|
- readl(sock->addr + SOCK_MMCSD_BLOCK_LEN)
|
||||||
|
+ 1;
|
||||||
|
}
|
||||||
|
host->buffer_pos = 0;
|
||||||
|
host->buffer_size = 0;
|
||||||
} else {
|
} else {
|
||||||
r_data->bytes_xfered = r_data->blocks -
|
if (r_data->flags & MMC_DATA_WRITE) {
|
||||||
readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
|
r_data->bytes_xfered = host->written_blocks
|
||||||
r_data->bytes_xfered *= r_data->blksz;
|
* r_data->blksz;
|
||||||
r_data->bytes_xfered += r_data->blksz -
|
} else {
|
||||||
readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1;
|
r_data->bytes_xfered = r_data->blocks -
|
||||||
|
readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
|
||||||
|
r_data->bytes_xfered *= r_data->blksz;
|
||||||
|
r_data->bytes_xfered += r_data->blksz -
|
||||||
|
readl(sock->addr + SOCK_MMCSD_BLOCK_LEN)
|
||||||
|
+ 1;
|
||||||
|
}
|
||||||
|
tifm_unmap_sg(sock, r_data->sg, r_data->sg_len,
|
||||||
|
(r_data->flags & MMC_DATA_WRITE)
|
||||||
|
? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
|
||||||
}
|
}
|
||||||
tifm_unmap_sg(sock, r_data->sg, r_data->sg_len,
|
|
||||||
(r_data->flags & MMC_DATA_WRITE)
|
|
||||||
? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
|
writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
|
||||||
@@ -564,109 +607,6 @@ static void tifm_sd_end_cmd(unsigned long data)
|
|||||||
mmc_request_done(mmc, mrq);
|
mmc_request_done(mmc, mrq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq)
|
|
||||||
{
|
|
||||||
struct tifm_sd *host = mmc_priv(mmc);
|
|
||||||
struct tifm_dev *sock = host->dev;
|
|
||||||
unsigned long flags;
|
|
||||||
struct mmc_data *r_data = mrq->cmd->data;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&sock->lock, flags);
|
|
||||||
if (host->eject) {
|
|
||||||
spin_unlock_irqrestore(&sock->lock, flags);
|
|
||||||
goto err_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (host->req) {
|
|
||||||
printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n");
|
|
||||||
spin_unlock_irqrestore(&sock->lock, flags);
|
|
||||||
goto err_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r_data) {
|
|
||||||
tifm_sd_set_data_timeout(host, r_data);
|
|
||||||
|
|
||||||
host->buffer_size = mrq->cmd->data->blocks
|
|
||||||
* mrq->cmd->data->blksz;
|
|
||||||
|
|
||||||
writel(TIFM_MMCSD_BUFINT
|
|
||||||
| readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
|
|
||||||
sock->addr + SOCK_MMCSD_INT_ENABLE);
|
|
||||||
writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8)
|
|
||||||
| (TIFM_MMCSD_FIFO_SIZE - 1),
|
|
||||||
sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
|
|
||||||
|
|
||||||
host->written_blocks = 0;
|
|
||||||
host->cmd_flags &= ~CARD_BUSY;
|
|
||||||
host->buffer_pos = 0;
|
|
||||||
writel(r_data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
|
|
||||||
writel(r_data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
host->req = mrq;
|
|
||||||
mod_timer(&host->timer, jiffies + host->timeout_jiffies);
|
|
||||||
host->state = CMD;
|
|
||||||
writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
|
|
||||||
sock->addr + SOCK_CONTROL);
|
|
||||||
tifm_sd_exec(host, mrq->cmd);
|
|
||||||
spin_unlock_irqrestore(&sock->lock, flags);
|
|
||||||
return;
|
|
||||||
|
|
||||||
err_out:
|
|
||||||
mrq->cmd->error = MMC_ERR_TIMEOUT;
|
|
||||||
mmc_request_done(mmc, mrq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tifm_sd_end_cmd_nodma(unsigned long data)
|
|
||||||
{
|
|
||||||
struct tifm_sd *host = (struct tifm_sd*)data;
|
|
||||||
struct tifm_dev *sock = host->dev;
|
|
||||||
struct mmc_host *mmc = tifm_get_drvdata(sock);
|
|
||||||
struct mmc_request *mrq;
|
|
||||||
struct mmc_data *r_data = NULL;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&sock->lock, flags);
|
|
||||||
|
|
||||||
del_timer(&host->timer);
|
|
||||||
mrq = host->req;
|
|
||||||
host->req = NULL;
|
|
||||||
host->state = IDLE;
|
|
||||||
|
|
||||||
if (!mrq) {
|
|
||||||
printk(KERN_ERR DRIVER_NAME ": no request to complete?\n");
|
|
||||||
spin_unlock_irqrestore(&sock->lock, flags);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
r_data = mrq->cmd->data;
|
|
||||||
if (r_data) {
|
|
||||||
writel((~TIFM_MMCSD_BUFINT) &
|
|
||||||
readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
|
|
||||||
sock->addr + SOCK_MMCSD_INT_ENABLE);
|
|
||||||
|
|
||||||
if (r_data->flags & MMC_DATA_WRITE) {
|
|
||||||
r_data->bytes_xfered = host->written_blocks
|
|
||||||
* r_data->blksz;
|
|
||||||
} else {
|
|
||||||
r_data->bytes_xfered = r_data->blocks -
|
|
||||||
readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
|
|
||||||
r_data->bytes_xfered *= r_data->blksz;
|
|
||||||
r_data->bytes_xfered += r_data->blksz -
|
|
||||||
readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1;
|
|
||||||
}
|
|
||||||
host->buffer_pos = 0;
|
|
||||||
host->buffer_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
|
|
||||||
sock->addr + SOCK_CONTROL);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&sock->lock, flags);
|
|
||||||
|
|
||||||
mmc_request_done(mmc, mrq);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tifm_sd_abort(unsigned long data)
|
static void tifm_sd_abort(unsigned long data)
|
||||||
{
|
{
|
||||||
struct tifm_sd *host = (struct tifm_sd*)data;
|
struct tifm_sd *host = (struct tifm_sd*)data;
|
||||||
@@ -755,7 +695,7 @@ static int tifm_sd_ro(struct mmc_host *mmc)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mmc_host_ops tifm_sd_ops = {
|
static const struct mmc_host_ops tifm_sd_ops = {
|
||||||
.request = tifm_sd_request,
|
.request = tifm_sd_request,
|
||||||
.set_ios = tifm_sd_ios,
|
.set_ios = tifm_sd_ios,
|
||||||
.get_ro = tifm_sd_ro
|
.get_ro = tifm_sd_ro
|
||||||
@@ -846,12 +786,10 @@ static int tifm_sd_probe(struct tifm_dev *sock)
|
|||||||
host->dev = sock;
|
host->dev = sock;
|
||||||
host->timeout_jiffies = msecs_to_jiffies(1000);
|
host->timeout_jiffies = msecs_to_jiffies(1000);
|
||||||
|
|
||||||
tasklet_init(&host->finish_tasklet,
|
tasklet_init(&host->finish_tasklet, tifm_sd_end_cmd,
|
||||||
host->no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd,
|
|
||||||
(unsigned long)host);
|
(unsigned long)host);
|
||||||
setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host);
|
setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host);
|
||||||
|
|
||||||
tifm_sd_ops.request = host->no_dma ? tifm_sd_request_nodma : tifm_sd_request;
|
|
||||||
mmc->ops = &tifm_sd_ops;
|
mmc->ops = &tifm_sd_ops;
|
||||||
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
|
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||||
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE;
|
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE;
|
||||||
|
Reference in New Issue
Block a user