From: Linus Walleij <linus.walleij@linaro.org>
To: Christoph Hellwig <hch@lst.de>, Jens Axboe <axboe@kernel.dk>,
Ming Lei <ming.lei@redhat.com>, Arnd Bergmann <arnd@arndb.de>,
Ulf Hansson <ulf.hansson@linaro.org>,
Nicolas Pitre <nico@fluxnic.net>,
Aaro Koskinen <aaro.koskinen@iki.fi>,
Adrian Hunter <adrian.hunter@intel.com>,
Angelo Dureghello <angelo.dureghello@timesys.com>
Cc: linux-mmc@vger.kernel.org, linux-block@vger.kernel.org,
linux-omap@vger.kernel.org,
Linus Walleij <linus.walleij@linaro.org>
Subject: [PATCH v2 4/9] mmc: moxart-mmc: Use sg_miter for PIO
Date: Sat, 27 Jan 2024 01:19:51 +0100 [thread overview]
Message-ID: <20240127-mmc-proper-kmap-v2-4-d8e732aa97d1@linaro.org> (raw)
In-Reply-To: <20240127-mmc-proper-kmap-v2-0-d8e732aa97d1@linaro.org>
Use the scatterlist memory iterator instead of just
dereferencing virtual memory using sg_virt().
This make highmem references work properly.
Suggested-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/linux-mmc/20240122073423.GA25859@lst.de/
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/mmc/host/moxart-mmc.c | 77 +++++++++++++++++++------------------------
1 file changed, 34 insertions(+), 43 deletions(-)
diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c
index 8ede4ce93271..b88d6dec209f 100644
--- a/drivers/mmc/host/moxart-mmc.c
+++ b/drivers/mmc/host/moxart-mmc.c
@@ -131,12 +131,10 @@ struct moxart_host {
struct dma_async_tx_descriptor *tx_desc;
struct mmc_host *mmc;
struct mmc_request *mrq;
- struct scatterlist *cur_sg;
struct completion dma_complete;
struct completion pio_complete;
- u32 num_sg;
- u32 data_remain;
+ struct sg_mapping_iter sg_miter;
u32 data_len;
u32 fifo_width;
u32 timeout;
@@ -148,35 +146,6 @@ struct moxart_host {
bool is_removed;
};
-static inline void moxart_init_sg(struct moxart_host *host,
- struct mmc_data *data)
-{
- host->cur_sg = data->sg;
- host->num_sg = data->sg_len;
- host->data_remain = host->cur_sg->length;
-
- if (host->data_remain > host->data_len)
- host->data_remain = host->data_len;
-}
-
-static inline int moxart_next_sg(struct moxart_host *host)
-{
- int remain;
- struct mmc_data *data = host->mrq->cmd->data;
-
- host->cur_sg++;
- host->num_sg--;
-
- if (host->num_sg > 0) {
- host->data_remain = host->cur_sg->length;
- remain = host->data_len - data->bytes_xfered;
- if (remain > 0 && remain < host->data_remain)
- host->data_remain = remain;
- }
-
- return host->num_sg;
-}
-
static int moxart_wait_for_status(struct moxart_host *host,
u32 mask, u32 *status)
{
@@ -309,14 +278,28 @@ static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host)
static void moxart_transfer_pio(struct moxart_host *host)
{
+ struct sg_mapping_iter *sgm = &host->sg_miter;
struct mmc_data *data = host->mrq->cmd->data;
u32 *sgp, len = 0, remain, status;
if (host->data_len == data->bytes_xfered)
return;
- sgp = sg_virt(host->cur_sg);
- remain = host->data_remain;
+ /*
+ * By updating sgm->consumes this will get a proper pointer into the
+ * buffer at any time.
+ */
+ if (!sg_miter_next(sgm)) {
+ /* This shold not happen */
+ dev_err(mmc_dev(host->mmc), "ran out of scatterlist prematurely\n");
+ data->error = -EINVAL;
+ complete(&host->pio_complete);
+ return;
+ }
+ sgp = sgm->addr;
+ remain = sgm->length;
+ if (remain > host->data_len)
+ remain = host->data_len;
if (data->flags & MMC_DATA_WRITE) {
while (remain > 0) {
@@ -331,6 +314,7 @@ static void moxart_transfer_pio(struct moxart_host *host)
sgp++;
len += 4;
}
+ sgm->consumed += len;
remain -= len;
}
@@ -347,22 +331,22 @@ static void moxart_transfer_pio(struct moxart_host *host)
sgp++;
len += 4;
}
+ sgm->consumed += len;
remain -= len;
}
}
- data->bytes_xfered += host->data_remain - remain;
- host->data_remain = remain;
-
- if (host->data_len != data->bytes_xfered)
- moxart_next_sg(host);
- else
+ data->bytes_xfered += sgm->consumed;
+ if (host->data_len == data->bytes_xfered) {
complete(&host->pio_complete);
+ return;
+ }
}
static void moxart_prepare_data(struct moxart_host *host)
{
struct mmc_data *data = host->mrq->cmd->data;
+ unsigned int flags = SG_MITER_ATOMIC; /* Used from IRQ */
u32 datactrl;
int blksz_bits;
@@ -373,15 +357,19 @@ static void moxart_prepare_data(struct moxart_host *host)
blksz_bits = ffs(data->blksz) - 1;
BUG_ON(1 << blksz_bits != data->blksz);
- moxart_init_sg(host, data);
-
datactrl = DCR_DATA_EN | (blksz_bits & DCR_BLK_SIZE);
- if (data->flags & MMC_DATA_WRITE)
+ if (data->flags & MMC_DATA_WRITE) {
+ flags |= SG_MITER_FROM_SG;
datactrl |= DCR_DATA_WRITE;
+ } else {
+ flags |= SG_MITER_TO_SG;
+ }
if (moxart_use_dma(host))
datactrl |= DCR_DMA_EN;
+ else
+ sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
writel(DCR_DATA_FIFO_RESET, host->base + REG_DATA_CONTROL);
writel(MASK_DATA | FIFO_URUN | FIFO_ORUN, host->base + REG_CLEAR);
@@ -454,6 +442,9 @@ static void moxart_request(struct mmc_host *mmc, struct mmc_request *mrq)
}
request_done:
+ if (!moxart_use_dma(host))
+ sg_miter_stop(&host->sg_miter);
+
spin_unlock_irqrestore(&host->lock, flags);
mmc_request_done(host->mmc, mrq);
}
--
2.34.1
next prev parent reply other threads:[~2024-01-27 0:20 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-27 0:19 [PATCH v2 0/9] mmc: Use proper sg_miter for scatterlists Linus Walleij
2024-01-27 0:19 ` [PATCH v2 1/9] mmc: davinci_mmc: Use sg_miter for PIO Linus Walleij
2024-01-27 0:19 ` [PATCH v2 2/9] mmc: moxart-mmc: Factor out moxart_use_dma() helper Linus Walleij
2024-01-27 0:19 ` [PATCH v2 3/9] mmc: moxart-mmc: Fix accounting in DMA transfer Linus Walleij
2024-01-27 0:19 ` Linus Walleij [this message]
2024-01-27 0:19 ` [PATCH v2 5/9] mmc: mvsdio: Use sg_miter for PIO Linus Walleij
2024-01-27 3:51 ` Nicolas Pitre
2024-01-27 16:33 ` Linus Walleij
2024-01-27 22:23 ` Nicolas Pitre
2024-01-27 0:19 ` [PATCH v2 6/9] mmc: mxcmmc: " Linus Walleij
2024-01-27 0:19 ` [PATCH v2 7/9] mmc: omap: " Linus Walleij
2024-01-27 0:19 ` [PATCH v2 8/9] mmc: sdhci-esdhc-mcf: Use sg_miter for swapping Linus Walleij
2024-02-21 6:30 ` Adrian Hunter
2024-01-27 0:19 ` [PATCH v2 9/9] mmc: sh_mmcif: Use sg_miter for PIO Linus Walleij
2024-02-20 21:03 ` Geert Uytterhoeven
2024-02-20 23:00 ` Linus Walleij
2024-02-21 9:50 ` Geert Uytterhoeven
2024-02-21 21:25 ` Linus Walleij
2024-02-22 9:20 ` Geert Uytterhoeven
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=20240127-mmc-proper-kmap-v2-4-d8e732aa97d1@linaro.org \
--to=linus.walleij@linaro.org \
--cc=aaro.koskinen@iki.fi \
--cc=adrian.hunter@intel.com \
--cc=angelo.dureghello@timesys.com \
--cc=arnd@arndb.de \
--cc=axboe@kernel.dk \
--cc=hch@lst.de \
--cc=linux-block@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=linux-omap@vger.kernel.org \
--cc=ming.lei@redhat.com \
--cc=nico@fluxnic.net \
--cc=ulf.hansson@linaro.org \
/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;
as well as URLs for NNTP newsgroup(s).