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

Sean Anderson
2021-02-01T16:47:09Z

On 2/1/21 2:59 AM, Lukasz Majewski wrote:
> 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.

Ok, I've resent after rebasing. However, I would appreciate if you could
hold off on merging Patrick's first two patches. I think this series
better solves his problem.

--Sean

>
>>
>> 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
>