[PATCH v2 1/9] mmc: sandbox: Add support for writing

Lukasz Majewski
2021-02-01T07:59:08Z

Hi Sean,

> This adds support writing to the sandbox mmc backed by an in-memory
> buffer. The unit test has been updated to test reading, writing, and
> erasing. I'm not sure what MMCs erase to; I picked 0, but if it's 0xFF
> then that can be easily changed.

Could you rebase this patch series on top of:
https://gitlab.denx.de/u-boot/custodians/u-boot-dfu/-/commits/master

I've encountered some conflicts with previous patches.

(And of course sorry for trouble - this patch series is the last one
with the pile I've got for USB/DFU).

Thanks in advance.

>
> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> ---
>
> (no changes since v1)
>
> drivers/mmc/sandbox_mmc.c | 41
> ++++++++++++++++++++++++++++++++++----- test/dm/mmc.c |
> 19 +++++++++++++----- 2 files changed, 50 insertions(+), 10
> deletions(-)
>
> diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c
> index e86ea8fe09..3daf708451 100644
> --- a/drivers/mmc/sandbox_mmc.c
> +++ b/drivers/mmc/sandbox_mmc.c
> @@ -17,6 +17,17 @@ struct sandbox_mmc_plat {
> struct mmc mmc;
> };
>
> +#define MMC_CSIZE 0
> +#define MMC_CMULT 8 /* 8 because the card is high-capacity */
> +#define MMC_BL_LEN_SHIFT 10
> +#define MMC_BL_LEN BIT(MMC_BL_LEN_SHIFT)
> +#define MMC_CAPACITY (((MMC_CSIZE + 1) << (MMC_CMULT + 2)) \
> + * MMC_BL_LEN) /* 1 MiB */
> +
> +struct sandbox_mmc_priv {
> + u8 buf[MMC_CAPACITY];
> +};
> +
> /**
> * sandbox_mmc_send_cmd() - Emulate SD commands
> *
> @@ -26,6 +37,10 @@ struct sandbox_mmc_plat {
> static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd
> *cmd, struct mmc_data *data)
> {
> + struct sandbox_mmc_priv *priv = dev_get_priv(dev);
> + struct mmc *mmc = mmc_get_mmc_dev(dev);
> + static ulong erase_start, erase_end;
> +
> switch (cmd->cmdidx) {
> case MMC_CMD_ALL_SEND_CID:
> memset(cmd->response, '\0', sizeof(cmd->response));
> @@ -44,8 +59,9 @@ static int sandbox_mmc_send_cmd(struct udevice
> *dev, struct mmc_cmd *cmd, break;
> case MMC_CMD_SEND_CSD:
> cmd->response[0] = 0;
> - cmd->response[1] = 10 << 16; /* 1 <<
> block_len */
> - cmd->response[2] = 0;
> + cmd->response[1] = (MMC_BL_LEN_SHIFT << 16) |
> + ((MMC_CSIZE >> 16) & 0x3f);
> + cmd->response[2] = (MMC_CSIZE & 0xffff) << 16;
> cmd->response[3] = 0;
> break;
> case SD_CMD_SWITCH_FUNC: {
> @@ -59,13 +75,27 @@ static int sandbox_mmc_send_cmd(struct udevice
> *dev, struct mmc_cmd *cmd, break;
> }
> case MMC_CMD_READ_SINGLE_BLOCK:
> - memset(data->dest, '\0', data->blocksize);
> - break;
> case MMC_CMD_READ_MULTIPLE_BLOCK:
> - strcpy(data->dest, "this is a test");
> + memcpy(data->dest, &priv->buf[cmd->cmdarg *
> data->blocksize],
> + data->blocks * data->blocksize);
> + break;
> + case MMC_CMD_WRITE_SINGLE_BLOCK:
> + case MMC_CMD_WRITE_MULTIPLE_BLOCK:
> + memcpy(&priv->buf[cmd->cmdarg * data->blocksize],
> data->src,
> + data->blocks * data->blocksize);
> break;
> case MMC_CMD_STOP_TRANSMISSION:
> break;
> + case SD_CMD_ERASE_WR_BLK_START:
> + erase_start = cmd->cmdarg;
> + break;
> + case SD_CMD_ERASE_WR_BLK_END:
> + erase_end = cmd->cmdarg;
> + break;
> + case MMC_CMD_ERASE:
> + memset(&priv->buf[erase_start * mmc->write_bl_len],
> '\0',
> + (erase_end - erase_start + 1) *
> mmc->write_bl_len);
> + break;
> case SD_CMD_APP_SEND_OP_COND:
> cmd->response[0] = OCR_BUSY | OCR_HCS;
> cmd->response[1] = 0;
> @@ -148,5 +178,6 @@ U_BOOT_DRIVER(mmc_sandbox) = {
> .bind = sandbox_mmc_bind,
> .unbind = sandbox_mmc_unbind,
> .probe = sandbox_mmc_probe,
> + .priv_auto_alloc_size = sizeof(struct sandbox_mmc_priv),
> .platdata_auto_alloc_size = sizeof(struct sandbox_mmc_plat),
> };
> diff --git a/test/dm/mmc.c b/test/dm/mmc.c
> index 4e5136c850..f744452ff2 100644
> --- a/test/dm/mmc.c
> +++ b/test/dm/mmc.c
> @@ -29,16 +29,25 @@ static int dm_test_mmc_blk(struct unit_test_state
> *uts) {
> struct udevice *dev;
> struct blk_desc *dev_desc;
> - char cmp[1024];
> + int i;
> + char write[1024], read[1024];
>
> ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
> ut_assertok(blk_get_device_by_str("mmc", "0", &dev_desc));
>
> - /* Read a few blocks and look for the string we expect */
> + /* Write a few blocks and verify that we get the same data
> back */ ut_asserteq(512, dev_desc->blksz);
> - memset(cmp, '\0', sizeof(cmp));
> - ut_asserteq(2, blk_dread(dev_desc, 0, 2, cmp));
> - ut_assertok(strcmp(cmp, "this is a test"));
> + for (i = 0; i < sizeof(write); i++)
> + write[i] = i;
> + ut_asserteq(2, blk_dwrite(dev_desc, 0, 2, write));
> + ut_asserteq(2, blk_dread(dev_desc, 0, 2, read));
> + ut_asserteq_mem(write, read, sizeof(write));
> +
> + /* Now erase them */
> + memset(write, '\0', sizeof(write));
> + ut_asserteq(2, blk_derase(dev_desc, 0, 2));
> + ut_asserteq(2, blk_dread(dev_desc, 0, 2, read));
> + ut_asserteq_mem(write, read, sizeof(write));
>
> return 0;
> }

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma at denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210201/1da8b461/attachment.sig>