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

Sean Anderson sean.anderson at seco.com
Mon Feb 1 17:47:09 CET 2021


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 at seco.com>
>> Reviewed-by: Simon Glass <sjg at 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
> 



More information about the U-Boot mailing list