RE: [PATCH] mmc-utils: correct and clean up the file handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi everyone,

Comments are in-line bellow.

>Bruni hi,
>Thank you for your patch.
>
>> Hi everyone,
>> 
>> Here is the rebased patch.
>> 
>> Add the check if the whole firmware was loaded.
>> Cleaned up the leftovers of handling the file in chunks.
>> 
>> Signed-off-by: Bruno Matic <bruno.matic@xxxxxxxxx>
>> 
>> ---
>>  mmc_cmds.c | 67 
>> +++++++++++++++++++++++++++---------------------------
>>  1 file changed, 33 insertions(+), 34 deletions(-)
>> 
>> diff --git a/mmc_cmds.c b/mmc_cmds.c
>> index 8d7910e..d017b64 100644
>> --- a/mmc_cmds.c
>> +++ b/mmc_cmds.c
>> @@ -2812,7 +2812,6 @@ int do_ffu(int nargs, char **argv)
>>         __u8 *buf = NULL;
>>         __u32 arg;
>>         off_t fw_size;
>> -       ssize_t chunk_size;
>>         char *device;
>>         struct mmc_ioc_multi_cmd *multi_cmd = NULL;
>> 
>> @@ -2926,45 +2925,45 @@ int do_ffu(int nargs, char **argv)
>>         multi_cmd->cmds[3].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | 
>> MMC_CMD_AC;
>>         multi_cmd->cmds[3].write_flag = 1;
>> 
>> -do_retry:
>> -       /* read firmware chunk */
>> +       /* read firmware */
>>         lseek(img_fd, 0, SEEK_SET);
>> -       chunk_size = read(img_fd, buf, fw_size);
>> +       if (read(img_fd, buf, fw_size) != fw_size) {
>> +               fprintf(stderr, "Could not read the whole firmware file\n");
>> +               ret = -ENOSPC;
>No space left?
>
Here I would propose to use perror instead of fprintf - something like:
	perror("Could not read the firmware file: ");
This will also propagate the errno from read.

>> +               goto out;
>> +       }
>> 
>> -       if (chunk_size > 0) {
>> -               /* send ioctl with multi-cmd */
>> -               ret = ioctl(dev_fd, MMC_IOC_MULTI_CMD, multi_cmd);
>> +do_retry:
>> +       /* send ioctl with multi-cmd */
>> +       ret = ioctl(dev_fd, MMC_IOC_MULTI_CMD, multi_cmd);
>> 
>> -               if (ret) {
>> -                       perror("Multi-cmd ioctl");
>> -                       /* In case multi-cmd ioctl failed before exiting from ffu mode */
>> -                       ioctl(dev_fd, MMC_IOC_CMD, &multi_cmd->cmds[3]);
>> -                       goto out;
>> -               }
>> +       if (ret) {
>> +               perror("Multi-cmd ioctl");
>> +               /* In case multi-cmd ioctl failed before exiting from ffu mode */
>> +               ioctl(dev_fd, MMC_IOC_CMD, &multi_cmd->cmds[3]);
>> +               goto out;
>> +       }
>Why do we need this hack?
>Why would the last command is prone to fail?
>If there is no good reason - Lets remove this hack - as a 2nd patch in this series.
If I assume correctly you refer to repetition of third command after a failure.
This was left as-is since I understood that first and second command can fail, but the device
should not remain in upgrade mode in case of failure.

>
>> 
>> -               ret = read_extcsd(dev_fd, ext_csd);
>> -               if (ret) {
>> -                       fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
>> -                       goto out;
>> -               }
>> +       ret = read_extcsd(dev_fd, ext_csd);
>> +       if (ret) {
>> +               fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
>> +               goto out;
>> +       }
>> 
>> -               /* Test if we need to restart the download */
>> -               sect_done = ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_0] |
>> -                               ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_1] << 8 |
>> -                               ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_2] << 16 |
>> -                               ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_3] << 24;
>> -               /* By spec, host should re-start download from the first sector if
>> sect_done is 0 */
>> -               if (sect_done == 0) {
>> -                       if (retry > 0) {
>> -                               retry--;
>> -                               fprintf(stderr, "Programming failed. Retrying... (%d)\n",
>> retry);
>> -                               goto do_retry;
>> -                       }
>> -                       fprintf(stderr, "Programming failed! Aborting...\n");
>> -                       goto out;
>> -               } else {
>> -                       fprintf(stderr, "Programmed %d/%jd bytes\r", sect_done *
>> sect_size, (intmax_t)fw_size);
>> +       /* Test if we need to restart the download */
>> +       sect_done = ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_0] |
>> +                       ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_1] << 8 |
>> +                       ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_2] << 16 |
>> +                       ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_3] << 24;
>> +       /* By spec, host should re-start download from the first 
>> + sector if
>> sect_done is 0 */
>Can we use here be32toh or get_unaligned_be32 or something instead?
Tried to look into it - none of the functions fit the need, input must be an int.
Best I can offer is to write a macro - something along the lines:
	#define le32toh_array(p) (p | *(&p+1) << 8 | *(&p+2) << 16 | *(&p+3) << 24 )
	sect_done = le32toh_array(ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_0]);

>
>> +       if (sect_done == 0) {
>> +               if (retry > 0) {
>If (retry--)
Agreed - will be done in v2.

>
>> +                       retry--;
>> +                       fprintf(stderr, "Programming failed. Retrying... (%d)\n", retry);
>> +                       goto do_retry;
>>                 }
>> +               fprintf(stderr, "Programming failed! Aborting...\n");
>> +               goto out;
>>         }
>> 
>>         if ((sect_done * sect_size) == fw_size) {
>> 
>> Best regards,
>> Bruno Matić
>
>Thanks,
>Avri
>




[Index of Archives]     [Linux Memonry Technology]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux