From: Maxim Levitsky <maximlevitsky@gmail.com>
To: Alex Dubov <oakad@yahoo.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
LKML <linux-kernel@vger.kernel.org>,
Maxim Levitsky <maximlevitsky@gmail.com>
Subject: [PATCH 23/29] memstick: jmb38x_ms: use DMA for all TPCs with len greater that 8 by default
Date: Sat, 23 Oct 2010 01:53:51 +0200 [thread overview]
Message-ID: <1287791637-10329-24-git-send-email-maximlevitsky@gmail.com> (raw)
In-Reply-To: <1287791637-10329-1-git-send-email-maximlevitsky@gmail.com>
This is to workaround a wierd hardware bug:
If PIO write is used, and then after it DMA write is used, DMA
engine stops doing writes.
That condition even persists after device reset.
To be maxumum safe, we do dma to a scratch page
and memcpy from/to it.
Besides this change should just improve performance.
Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
---
drivers/memstick/host/jmb38x_ms.c | 65 ++++++++++++++++++++++++++----------
drivers/memstick/host/jmb38x_ms.h | 5 +++
2 files changed, 52 insertions(+), 18 deletions(-)
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 6b87e23..77e4971 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -261,6 +261,7 @@ static int j38ms_execute_tpc(struct j38ms_host *host)
unsigned int data_len = host->req->long_data ?
host->req->sg.length : host->req->data_len;
bool is_read = host->req->data_dir == READ;
+ dma_addr_t dma_address;
if (!(j38ms_read_reg(host, STATUS) & STATUS_HAS_MEDIA)) {
dbg(host, "IO: card removed, refusing to send TPC");
@@ -316,30 +317,40 @@ static int j38ms_execute_tpc(struct j38ms_host *host)
}
/* DMA */
- if (!no_dma && host->req->long_data) {
+ if (!no_dma) {
dbg(host, "IO: Using DMA");
host->cmd_flags |= DMA_DATA;
- if (pci_map_sg(host->chip->pdev,
- &host->req->sg, 1, is_read
- ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE) != 1) {
+ if (host->req->long_data) {
- dbg(host, "IO: DMA map failed");
- host->req->error = -ENOMEM;
- return host->req->error;
- }
+ if (pci_map_sg(host->chip->pdev,
+ &host->req->sg, 1, is_read
+ ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE) != 1) {
+
+ dbg(host, "IO: DMA map failed");
+ host->req->error = -ENOMEM;
+ return host->req->error;
+ }
+
+ /* We really shouldn't pretend we support that case */
+ if (sg_dma_len(&host->req->sg) != data_len) {
+ dbg(host, "IO: DMA len mismatch");
+ host->req->error = -EFAULT;
+ return host->req->error;
+ }
- /* We really shouldn't pretend we support that case */
- if (sg_dma_len(&host->req->sg) != data_len) {
- dbg(host, "IO: DMA len mismatch");
- host->req->error = -EFAULT;
- return host->req->error;
+ dma_address = sg_dma_address(&host->req->sg);
+
+ } else {
+ if (!is_read)
+ memcpy(host->dma_bounce_page,
+ host->req->data, data_len);
+ dma_address = host->dma_bus_address;
}
j38ms_write_reg(host, BLOCK, data_len | BLOCK_COUNT_1BLOCK);
- j38ms_write_reg(host, DMA_ADDRESS,
- sg_dma_address(&host->req->sg));
+ j38ms_write_reg(host, DMA_ADDRESS, dma_address);
j38ms_write_reg(host, DMA_CONTROL, DMA_CONTROL_ENABLE);
/* PIO */
} else {
@@ -392,9 +403,13 @@ static void j38ms_complete_tpc(struct memstick_host *msh, int last)
host->req->int_reg = j38ms_read_reg(host, STATUS) & 0xFF;
if (host->cmd_flags & DMA_DATA) {
- pci_unmap_sg(host->chip->pdev, &host->req->sg, 1,
- host->req->data_dir == READ
- ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+ if (host->req->long_data)
+ pci_unmap_sg(host->chip->pdev, &host->req->sg, 1,
+ host->req->data_dir == READ
+ ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+ else if (host->req->data_dir == READ)
+ memcpy(host->req->data,
+ host->dma_bounce_page, host->req->data_len);
} else if (host->cmd_flags & PIO_DATA) {
u32 t_val = INT_STATUS_FIFO_RRDY | INT_STATUS_FIFO_WRDY;
@@ -771,12 +786,23 @@ static struct memstick_host *j38ms_alloc_host(struct j38ms *jm, int cnt)
setup_timer(&host->timer, j38ms_irq_timeout, (unsigned long)msh);
+ host->dma_bounce_page = pci_alloc_consistent(
+ jm->pdev, PAGE_SIZE, &host->dma_bus_address);
+
+ if (!host->dma_bounce_page)
+ goto err_out_free;
+
if (!request_irq(host->irq, j38ms_isr, IRQF_SHARED, host->host_id,
msh))
return msh;
iounmap(host->addr);
err_out_free:
+
+ if (host->dma_bounce_page)
+ pci_free_consistent(jm->pdev, PAGE_SIZE,
+ host->dma_bounce_page, host->dma_bus_address);
+
kfree(msh);
return NULL;
}
@@ -787,6 +813,9 @@ static void j38ms_free_host(struct memstick_host *msh)
free_irq(host->irq, msh);
iounmap(host->addr);
+
+ pci_free_consistent(host->chip->pdev, PAGE_SIZE,
+ host->dma_bounce_page, host->dma_bus_address);
memstick_free_host(msh);
}
diff --git a/drivers/memstick/host/jmb38x_ms.h b/drivers/memstick/host/jmb38x_ms.h
index 429ed49..5599803 100644
--- a/drivers/memstick/host/jmb38x_ms.h
+++ b/drivers/memstick/host/jmb38x_ms.h
@@ -161,6 +161,11 @@ struct j38ms_host {
unsigned char pio_offset;
unsigned char pio_tmp_buf[4];
unsigned int pio_tmp_buf_len;
+
+ /* DMA bounce buffer */
+ void *dma_bounce_page;
+ dma_addr_t dma_bus_address;
+
};
struct j38ms {
--
1.7.1
next prev parent reply other threads:[~2010-10-22 23:54 UTC|newest]
Thread overview: 84+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-22 23:53 [PATCH 0/29] My patch queue for memorystick subsystem Maxim Levitsky
2010-10-22 23:53 ` [PATCH 01/29] memstick: core: header cleanups Maxim Levitsky
2010-10-25 14:44 ` Alex Dubov
2010-10-26 1:10 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 02/29] memstick: core: reorder functions This patch just reorders functions in memstick.c So that host specific and card driver specific functions are now grouped together. This makes it easier to understand the code Maxim Levitsky
2010-10-25 14:50 ` Alex Dubov
2010-10-26 1:14 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 03/29] memstick: core: add new functions Maxim Levitsky
2010-10-25 14:56 ` Alex Dubov
2010-10-26 1:20 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 04/29] memstick: core: rework state machines Maxim Levitsky
2010-10-25 15:01 ` Alex Dubov
2010-10-26 1:34 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 05/29] memstick: mspro_block: move declarations to header and refactor things a bit Maxim Levitsky
2010-10-25 15:07 ` Alex Dubov
2010-10-26 1:46 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 06/29] memstick: mspro: kill the BKL Maxim Levitsky
2010-10-25 15:12 ` Alex Dubov
2010-10-26 1:50 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 07/29] memstick: mspro: two fixes Maxim Levitsky
2010-10-25 15:13 ` Alex Dubov
2010-10-26 1:51 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 08/29] memstick: mspro: add comments to few functions Maxim Levitsky
2010-10-25 15:18 ` Alex Dubov
2010-10-26 1:54 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 09/29] memstick: rework state machines + attribute read function Maxim Levitsky
2010-10-25 15:23 ` Alex Dubov
2010-10-26 1:57 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 10/29] memstick: mspro: create _setup_io helper Maxim Levitsky
2010-10-25 15:25 ` Alex Dubov
2010-10-26 1:58 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 11/29] memstick: mspro: use MS_TPC_EX_SET_CMD Maxim Levitsky
2010-10-25 15:27 ` Alex Dubov
2010-10-26 2:00 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 12/29] memstick: mspro: rework interface switch Maxim Levitsky
2010-10-25 15:28 ` Alex Dubov
2010-10-26 2:01 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 13/29] memstick: core: stop passing pointer to card->current_mrq Maxim Levitsky
2010-10-25 15:41 ` Alex Dubov
2010-10-26 2:04 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 14/29] memstick: remove the memstick_set_rw_addr Maxim Levitsky
2010-10-25 15:55 ` Alex Dubov
2010-10-26 2:08 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 15/29] memstick: jmb38x_ms: Create header Maxim Levitsky
2010-10-25 15:56 ` Alex Dubov
2010-10-26 2:10 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 16/29] memstick: jmb38x_ms: s/jmb38x_ms/j38ms/g Maxim Levitsky
2010-10-25 15:58 ` Alex Dubov
2010-10-26 2:13 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 17/29] memstick: jmb38x_ms: move "reg_data" functions together Maxim Levitsky
2010-10-25 16:00 ` Alex Dubov
2010-10-26 2:14 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 18/29] memstick: jmb38x_ms: rename functions Maxim Levitsky
2010-10-25 16:00 ` Alex Dubov
2010-10-26 2:17 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 19/29] memstick: jmb38x_ms: add register read/write functions Maxim Levitsky
2010-10-25 16:03 ` Alex Dubov
2010-10-26 2:19 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 20/29] memstick: jmb38x_ms: rework PIO Maxim Levitsky
2010-10-25 16:05 ` Alex Dubov
2010-10-26 2:21 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 21/29] memstick: jmb38x_ms: rework TPC execution Maxim Levitsky
2010-10-25 16:08 ` Alex Dubov
2010-10-26 2:22 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 22/29] memstick: jmb38x_ms: rework ISR Maxim Levitsky
2010-10-25 16:11 ` Alex Dubov
2010-10-26 2:23 ` Maxim Levitsky
2010-10-22 23:53 ` Maxim Levitsky [this message]
2010-10-25 16:12 ` [PATCH 23/29] memstick: jmb38x_ms: use DMA for all TPCs with len greater that 8 by default Alex Dubov
2010-10-26 2:29 ` Maxim Levitsky
2010-10-22 23:53 ` [PATCH 24/29] memstick: jmb38x_ms: rework processing of the TPC one after another Maxim Levitsky
2010-10-25 16:14 ` Alex Dubov
2010-10-22 23:53 ` [PATCH 25/29] memstick: jmb38x_ms: pass j38ms_host to few functions instead of memstick_host Maxim Levitsky
2010-10-22 23:53 ` [PATCH 26/29] memstick: jmb38x_ms: rework hardware setup/reset Maxim Levitsky
2010-10-25 16:17 ` Alex Dubov
2010-10-22 23:53 ` [PATCH 27/29] memstick: jmb38x_ms: minor additions Maxim Levitsky
2010-10-22 23:53 ` [PATCH 28/29] memstick: add support for legacy memorysticks Maxim Levitsky
2010-10-22 23:53 ` [PATCH 29/29] memstick: Add driver for Ricoh R5C592 Card reader Maxim Levitsky
2010-10-25 2:01 ` [PATCH 0/29] My patch queue for memorystick subsystem Maxim Levitsky
2010-10-25 14:39 ` Alex Dubov
2010-10-25 16:07 ` Andrew Morton
2010-10-25 16:10 ` Alex Dubov
2010-10-26 2:32 ` Maxim Levitsky
2010-10-25 16:25 ` Alex Dubov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1287791637-10329-24-git-send-email-maximlevitsky@gmail.com \
--to=maximlevitsky@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=oakad@yahoo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome