On Tue, Jul 31, 2012 at 7:30 AM, Kyungsik Lee <kyungsik....@lge.com> wrote: > It is expected that Extended CSD register(the size of this register > is larger than CID/CSD) will be referenced more frequently as more > fields have been added to Extended CSD and it seems that it is not > a good option to double the memory used. > > This patch is intended to avoid the use of bounce buffer for reading > Extended CSD register in mmc_send_cxd_data(). > > Signed-off-by: Kyungsik Lee <kyungsik....@lge.com> > --- > Changes in v2: > - Handling on-stack buffer if it's used in caller. > > Changes in v3: > - Remove unnecesary code. > --- > drivers/mmc/core/mmc_ops.c | 54 ++++++++++++++++++++++++++++++++----------- > 1 files changed, 40 insertions(+), 14 deletions(-) > > diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c > index 0ed2cc5..036e6d5 100644 > --- a/drivers/mmc/core/mmc_ops.c > +++ b/drivers/mmc/core/mmc_ops.c > @@ -239,13 +239,19 @@ mmc_send_cxd_data(struct mmc_card *card, struct > mmc_host *host, > struct mmc_data data = {0}; > struct scatterlist sg; > void *data_buf; > + int is_on_stack; > > - /* dma onto stack is unsafe/nonportable, but callers to this > - * routine normally provide temporary on-stack buffers ... > - */ > - data_buf = kmalloc(len, GFP_KERNEL); > - if (data_buf == NULL) > - return -ENOMEM; > + is_on_stack = object_is_on_stack(buf); > + if (is_on_stack) { > + > + /* dma onto stack is unsafe/nonportable, but callers to this > + * routine normally provide temporary on-stack buffers ... > + */ > + data_buf = kmalloc(len, GFP_KERNEL); > + if (data_buf == NULL) > + return -ENOMEM; > + } else > + data_buf = buf; > > mrq.cmd = &cmd; > mrq.data = &data; > @@ -280,8 +286,10 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host > *host, > > mmc_wait_for_req(host, &mrq); > > - memcpy(buf, data_buf, len); > - kfree(data_buf); > + if (is_on_stack) { > + memcpy(buf, data_buf, len); > + kfree(data_buf); > + } > > if (cmd.error) > return cmd.error; > @@ -294,24 +302,34 @@ mmc_send_cxd_data(struct mmc_card *card, struct > mmc_host *host, > int mmc_send_csd(struct mmc_card *card, u32 *csd) > { > int ret, i; > + u32 *csd_tmp; > > if (!mmc_host_is_spi(card->host)) > return mmc_send_cxd_native(card->host, card->rca << 16, > csd, MMC_SEND_CSD); > > - ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16); > + csd_tmp = kmalloc(16, GFP_KERNEL); > + if (!csd_tmp) > + return -ENOMEM; > + > + ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd_tmp, 16); > if (ret) > - return ret; > + goto err; > + > + memcpy(csd, csd_tmp, 16); Can this memcpy be folded into the for loop below as for (....) { csd[i] = be32_to_cpu(csd_tmp[i]); ?
> > for (i = 0;i < 4;i++) > csd[i] = be32_to_cpu(csd[i]); > > - return 0; > +err: > + kfree(csd_tmp); > + return ret; > } > > int mmc_send_cid(struct mmc_host *host, u32 *cid) > { > int ret, i; > + u32 *cid_tmp; > > if (!mmc_host_is_spi(host)) { > if (!host->card) > @@ -320,14 +338,22 @@ int mmc_send_cid(struct mmc_host *host, u32 *cid) > cid, MMC_SEND_CID); > } > > - ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16); > + cid_tmp = kmalloc(16, GFP_KERNEL); > + if (!cid_tmp) > + return -ENOMEM; > + > + ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid_tmp, 16); > if (ret) > - return ret; > + goto err; > + > + memcpy(cid, cid_tmp, 16); > <Same comment as above> > for (i = 0;i < 4;i++) > cid[i] = be32_to_cpu(cid[i]); > > - return 0; > +err: > + kfree(cid_tmp); > + return ret; > } > > int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) > -- > 1.7.0.4 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/