* [PATCH] mmc: add API for data write using scatter gather DMA
@ 2016-03-29 12:57 Amitkumar Karwar
[not found] ` <1459256261-22492-1-git-send-email-akarwar-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
0 siblings, 1 reply; 3+ messages in thread
From: Amitkumar Karwar @ 2016-03-29 12:57 UTC (permalink / raw)
To: linux-wireless
Cc: Nishant Sarmukadam, linux-mmc, bin9zha0, Cathy Luo, Bing Zhao,
Xinming Hu, Amitkumar Karwar
From: Bing Zhao <bzhao@marvell.com>
This patch adds new API for SDIO scatter gather.
Existing mmc_io_rw_extended() API expects caller to pass single contiguous
buffer. It will be split if it exceeds segment size, SG table is prepared
and used it for reading/writing the data.
Our intention for defining new API here is to facilitate caller to provide
ready SG table(scattered buffer list). It will be useful for the drivers
which intend to handle SDIO SG internally.
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: Xinming Hu <huxm@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
drivers/mmc/core/sdio_ops.c | 64 +++++++++++++++++++++++++++++++++++++++++++
include/linux/mmc/sdio_func.h | 5 ++++
2 files changed, 69 insertions(+)
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
index 62508b4..6875980 100644
--- a/drivers/mmc/core/sdio_ops.c
+++ b/drivers/mmc/core/sdio_ops.c
@@ -204,6 +204,70 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
return 0;
}
+int mmc_io_rw_extended_sg(struct mmc_card *card, int write, unsigned fn,
+ unsigned addr, int incr_addr,
+ struct sg_table *sgt, unsigned blksz)
+{
+ struct mmc_request mrq = {NULL};
+ struct mmc_command cmd = {0};
+ struct mmc_data data = {0};
+ struct scatterlist *sg_ptr;
+ unsigned blocks = 0;
+ int i;
+
+ WARN_ON(!card || !card->host);
+ WARN_ON(fn > 7);
+ WARN_ON(blksz == 0);
+ for_each_sg(sgt->sgl, sg_ptr, sgt->nents, i) {
+ WARN_ON(sg_ptr->length > card->host->max_seg_size);
+ blocks += DIV_ROUND_UP(sg_ptr->length, blksz);
+ }
+
+ /* sanity check */
+ if (addr & ~0x1FFFF)
+ return -EINVAL;
+
+ mrq.cmd = &cmd;
+ mrq.data = &data;
+
+ cmd.opcode = SD_IO_RW_EXTENDED;
+ cmd.arg = write ? 0x80000000 : 0x00000000;
+ cmd.arg |= fn << 28;
+ cmd.arg |= incr_addr ? 0x04000000 : 0x00000000;
+ cmd.arg |= addr << 9;
+ cmd.arg |= 0x08000000 | blocks;
+ cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+
+ data.blksz = blksz;
+ data.blocks = blocks;
+ data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
+
+ data.sg = sgt->sgl;
+ data.sg_len = sgt->nents;
+
+ mmc_set_data_timeout(&data, card);
+ mmc_wait_for_req(card->host, &mrq);
+
+ if (cmd.error)
+ return cmd.error;
+ if (data.error)
+ return data.error;
+
+ if (mmc_host_is_spi(card->host)) {
+ /* host driver already reported errors */
+ } else {
+ if (cmd.resp[0] & R5_ERROR)
+ return -EIO;
+ if (cmd.resp[0] & R5_FUNCTION_NUMBER)
+ return -EINVAL;
+ if (cmd.resp[0] & R5_OUT_OF_RANGE)
+ return -ERANGE;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mmc_io_rw_extended_sg);
+
int sdio_reset(struct mmc_host *host)
{
int ret;
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
index aab032a..2107e91 100644
--- a/include/linux/mmc/sdio_func.h
+++ b/include/linux/mmc/sdio_func.h
@@ -14,6 +14,7 @@
#include <linux/device.h>
#include <linux/mod_devicetable.h>
+#include <linux/scatterlist.h>
#include <linux/mmc/pm.h>
@@ -151,6 +152,10 @@ extern int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr,
extern int sdio_writesb(struct sdio_func *func, unsigned int addr,
void *src, int count);
+int mmc_io_rw_extended_sg(struct mmc_card *card, int write, unsigned fn,
+ unsigned addr, int incr_addr,
+ struct sg_table *sgt, unsigned blksz);
+
extern unsigned char sdio_f0_readb(struct sdio_func *func,
unsigned int addr, int *err_ret);
extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b,
--
1.8.1.4
^ permalink raw reply related [flat|nested] 3+ messages in thread[parent not found: <1459256261-22492-1-git-send-email-akarwar-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>]
* Re: [PATCH] mmc: add API for data write using scatter gather DMA [not found] ` <1459256261-22492-1-git-send-email-akarwar-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org> @ 2016-04-22 14:17 ` Ulf Hansson 2016-05-05 10:59 ` Amitkumar Karwar 0 siblings, 1 reply; 3+ messages in thread From: Ulf Hansson @ 2016-04-22 14:17 UTC (permalink / raw) To: Amitkumar Karwar Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Nishant Sarmukadam, linux-mmc, Bing Zhao, Cathy Luo, Bing Zhao, Xinming Hu On 29 March 2016 at 14:57, Amitkumar Karwar <akarwar-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org> wrote: > From: Bing Zhao <bzhao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org> > > This patch adds new API for SDIO scatter gather. > > Existing mmc_io_rw_extended() API expects caller to pass single contiguous > buffer. It will be split if it exceeds segment size, SG table is prepared > and used it for reading/writing the data. > > Our intention for defining new API here is to facilitate caller to provide > ready SG table(scattered buffer list). It will be useful for the drivers > which intend to handle SDIO SG internally. > > Signed-off-by: Bing Zhao <bzhao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org> > Signed-off-by: Xinming Hu <huxm-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org> > Signed-off-by: Amitkumar Karwar <akarwar-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org> > --- So this has been posted and discussed earlier. In upcoming revisions, please attach that history so people know when reviewing. Moreover, if you have been using this API to improve throughput, perhaps you can provide us with some numbers as well!? > drivers/mmc/core/sdio_ops.c | 64 +++++++++++++++++++++++++++++++++++++++++++ > include/linux/mmc/sdio_func.h | 5 ++++ > 2 files changed, 69 insertions(+) > > diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c > index 62508b4..6875980 100644 > --- a/drivers/mmc/core/sdio_ops.c > +++ b/drivers/mmc/core/sdio_ops.c > @@ -204,6 +204,70 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, > return 0; > } > > +int mmc_io_rw_extended_sg(struct mmc_card *card, int write, unsigned fn, > + unsigned addr, int incr_addr, > + struct sg_table *sgt, unsigned blksz) > +{ > + struct mmc_request mrq = {NULL}; > + struct mmc_command cmd = {0}; > + struct mmc_data data = {0}; > + struct scatterlist *sg_ptr; > + unsigned blocks = 0; > + int i; > + > + WARN_ON(!card || !card->host); > + WARN_ON(fn > 7); > + WARN_ON(blksz == 0); WARN_ON is not correct here. You should return proper error codes instead. > + for_each_sg(sgt->sgl, sg_ptr, sgt->nents, i) { > + WARN_ON(sg_ptr->length > card->host->max_seg_size); This raises a concern. Somehow the callers of this new API needs to be able to fetch the max_seg_size, as otherwise how would they know what size to use when allocating the buffers. Of course they can just pick the value from card->host->max_seg_size, but that's not the correct way. Can we add a separate SDIO API for this!? Moreover, I think you should return a proper error code instead of WARN_ON. > + blocks += DIV_ROUND_UP(sg_ptr->length, blksz); > + } > + > + /* sanity check */ > + if (addr & ~0x1FFFF) > + return -EINVAL; > + > + mrq.cmd = &cmd; > + mrq.data = &data; > + > + cmd.opcode = SD_IO_RW_EXTENDED; > + cmd.arg = write ? 0x80000000 : 0x00000000; > + cmd.arg |= fn << 28; > + cmd.arg |= incr_addr ? 0x04000000 : 0x00000000; > + cmd.arg |= addr << 9; > + cmd.arg |= 0x08000000 | blocks; > + cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; > + > + data.blksz = blksz; > + data.blocks = blocks; > + data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; > + > + data.sg = sgt->sgl; > + data.sg_len = sgt->nents; > + > + mmc_set_data_timeout(&data, card); > + mmc_wait_for_req(card->host, &mrq); > + > + if (cmd.error) > + return cmd.error; > + if (data.error) > + return data.error; > + > + if (mmc_host_is_spi(card->host)) { > + /* host driver already reported errors */ > + } else { > + if (cmd.resp[0] & R5_ERROR) > + return -EIO; > + if (cmd.resp[0] & R5_FUNCTION_NUMBER) > + return -EINVAL; > + if (cmd.resp[0] & R5_OUT_OF_RANGE) > + return -ERANGE; > + } > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(mmc_io_rw_extended_sg); Besides these comment, clearly you have duplicated code from mmc_io_rw_extended() in the above function. Can you try to re-factor mmc_io_rw_extended(), so we can avoid too much code duplications. > + > int sdio_reset(struct mmc_host *host) > { > int ret; > diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h > index aab032a..2107e91 100644 > --- a/include/linux/mmc/sdio_func.h > +++ b/include/linux/mmc/sdio_func.h > @@ -14,6 +14,7 @@ > > #include <linux/device.h> > #include <linux/mod_devicetable.h> > +#include <linux/scatterlist.h> > > #include <linux/mmc/pm.h> > > @@ -151,6 +152,10 @@ extern int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr, > extern int sdio_writesb(struct sdio_func *func, unsigned int addr, > void *src, int count); > > +int mmc_io_rw_extended_sg(struct mmc_card *card, int write, unsigned fn, > + unsigned addr, int incr_addr, > + struct sg_table *sgt, unsigned blksz); > + > extern unsigned char sdio_f0_readb(struct sdio_func *func, > unsigned int addr, int *err_ret); > extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b, > -- > 1.8.1.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org > More majordomo info at http://vger.kernel.org/majordomo-info.html Kind regards Uffe -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 3+ messages in thread
* RE: [PATCH] mmc: add API for data write using scatter gather DMA 2016-04-22 14:17 ` Ulf Hansson @ 2016-05-05 10:59 ` Amitkumar Karwar 0 siblings, 0 replies; 3+ messages in thread From: Amitkumar Karwar @ 2016-05-05 10:59 UTC (permalink / raw) To: Ulf Hansson Cc: linux-wireless@vger.kernel.org, Nishant Sarmukadam, linux-mmc, Bing Zhao, Cathy Luo, Xinming Hu, Wei-Ning Huang Hi Ulf, > From: linux-wireless-owner@vger.kernel.org [mailto:linux-wireless- > owner@vger.kernel.org] On Behalf Of Ulf Hansson > Sent: Friday, April 22, 2016 7:48 PM > To: Amitkumar Karwar > Cc: linux-wireless@vger.kernel.org; Nishant Sarmukadam; linux-mmc; Bing > Zhao; Cathy Luo; Bing Zhao; Xinming Hu > Subject: Re: [PATCH] mmc: add API for data write using scatter gather > DMA > > On 29 March 2016 at 14:57, Amitkumar Karwar <akarwar@marvell.com> wrote: > > From: Bing Zhao <bzhao@marvell.com> > > > > This patch adds new API for SDIO scatter gather. > > > > Existing mmc_io_rw_extended() API expects caller to pass single > > contiguous buffer. It will be split if it exceeds segment size, SG > > table is prepared and used it for reading/writing the data. > > > > Our intention for defining new API here is to facilitate caller to > > provide ready SG table(scattered buffer list). It will be useful for > > the drivers which intend to handle SDIO SG internally. > > > > Signed-off-by: Bing Zhao <bzhao@marvell.com> > > Signed-off-by: Xinming Hu <huxm@marvell.com> > > Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> > > --- > > So this has been posted and discussed earlier. In upcoming revisions, > please attach that history so people know when reviewing. > > Moreover, if you have been using this API to improve throughput, perhaps > you can provide us with some numbers as well!? > Thanks for your comments. We are working on the updated version to resolve them. We will include the changelist history and share the throughput improvement numbers. Regards, Amitkumar ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-05-05 11:02 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-29 12:57 [PATCH] mmc: add API for data write using scatter gather DMA Amitkumar Karwar
[not found] ` <1459256261-22492-1-git-send-email-akarwar-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2016-04-22 14:17 ` Ulf Hansson
2016-05-05 10:59 ` Amitkumar Karwar
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).