Re: [RFC PATCH 1/1 ]mmc: Support-FFU-for-eMMC-v5.0

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

 



Hi, Seunguk.

On 03/31/2014 07:51 PM, Seunguk Shin wrote:
> Some of Samsung eMMC does not show the argument for ffu in ext_csd.
> In case of this, eMMC shows 0x0 from ext_csd, Host has to modify the
> argument.
> 
> Add "#define CID_MANFID_SAMSUNG		0x15"
If you need to add the Samsung eMMC specific code, 
it would be better you would send the Samsung eMMC specific patch. (based-on this patch.)
This patch isn't patch for samsung eMMC.
I didn't see this patch fully, but i think this patch is general code.

Best Regards,
Jaehoon Chung

> 
>> +int mmc_ffu_download(struct mmc_card *card, struct mmc_command *cmd,
>> +       u8 *data, int buf_bytes)
>> +{
>> +       u8 ext_csd[CARD_BLOCK_SIZE];
>> +       int err;
>> +       int ret;
>> +
>> +       /* Read the EXT_CSD */
>> +       err = mmc_send_ext_csd(card, ext_csd);
>> +       if (err) {
>> +               pr_err("FFU: %s: error %d sending ext_csd\n",
>> +                       mmc_hostname(card->host), err);
>> +               goto exit;
>> +       }
>> +
>> +       /* Check if FFU is supported by card */
>> +       if (!FFU_SUPPORTED_MODE(ext_csd[EXT_CSD_SUPPORTED_MODE])) {
>> +               err = -EINVAL;
>> +               pr_err("FFU: %s: error %d FFU is not supported\n",
>> +                       mmc_hostname(card->host), err);
>> +               goto exit;
>> +       }
>> +
>> +       err = mmc_host_set_ffu(card, ext_csd[EXT_CSD_FW_CONFIG]);
>> +       if (err) {
>> +               pr_err("FFU: %s: error %d FFU is not supported\n",
>> +                       mmc_hostname(card->host), err);
>> +               err = -EINVAL;
>> +               goto exit;
>> +       }
>> +
>> +       /* set device to FFU mode */
>> +       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> EXT_CSD_MODE_CONFIG,
>> +               MMC_FFU_MODE_SET, card->ext_csd.generic_cmd6_time);
>> +       if (err) {
>> +               pr_err("FFU: %s: error %d FFU is not supported\n",
>> +                       mmc_hostname(card->host), err);
>> +               goto exit_normal;
>> +       }
>> +
>> +       /* set CMD ARG */
>> +       cmd->arg = ext_csd[EXT_CSD_FFU_ARG] |
>> +               ext_csd[EXT_CSD_FFU_ARG + 1] << 8 |
>> +               ext_csd[EXT_CSD_FFU_ARG + 2] << 16 |
>> +               ext_csd[EXT_CSD_FFU_ARG + 3] << 24;
>> +
> 
> Add followings
> "
>        /* If arg is zero, should be set to a special value for samsung eMMC
> */
>        if ( card->cid.manfid == CID_MANFID_SAMSUNG && cmd->arg == 0x0 ) {
>                cmd->arg = 0xc7810000;
>        }
> "
> 
>> +       err = mmc_ffu_write(card, data, cmd->arg, buf_bytes);
>> +
>> +exit_normal:
>> +       /* host switch back to work in normal MMC Read/Write commands */
>> +       ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> +               EXT_CSD_MODE_CONFIG, MMC_FFU_MODE_NORMAL,
>> +               card->ext_csd.generic_cmd6_time);
>> +       if (ret)
>> +               err = ret;
>> +
>> +exit:
>> +       return err;
>> +}
>> +EXPORT_SYMBOL(mmc_ffu_download);
>> +
> 
> 
> 
> eMMC 5.0 Spec. says if device does not support MODE_OPERATION_CODES, device
> doesn't need to use NUMBER_OF_FW_SECTORS_CORRECTLY_PROGRAMMED.
> So, it's better to move the code for checking this value to
> FFU_FEATURES(ext_csd[EXT_CSD_FFU_FEATURES]
> 
>> +int mmc_ffu_install(struct mmc_card *card) {
>> +       u8 ext_csd[CARD_BLOCK_SIZE];
>> +       int err;
>> +       u32 ffu_data_len;
>> +       u32 timeout;
>> +
>> +       err = mmc_send_ext_csd(card, ext_csd);
>> +       if (err) {
>> +               pr_err("FFU: %s: error %d sending ext_csd\n",
>> +                       mmc_hostname(card->host), err);
>> +               goto exit;
>> +       }
>> +
>> +       /* Check if FFU is supported */
>> +       if (!FFU_SUPPORTED_MODE(ext_csd[EXT_CSD_SUPPORTED_MODE]) ||
>> +               FFU_CONFIG(ext_csd[EXT_CSD_FW_CONFIG])) {
>> +               err = -EINVAL;
>> +               pr_err("FFU: %s: error %d FFU is not supported\n",
>> +                       mmc_hostname(card->host), err);
>> +               goto exit;
>> +       }
> 
> Remove followings
> "
>        ffu_data_len = ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG]|
>                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;
> 
>        if (!ffu_data_len) {
>                err = -EPERM;
>                return err;
>        }
> "
> 
>> +
>> +       /* check mode operation */
>> +       if (!FFU_FEATURES(ext_csd[EXT_CSD_FFU_FEATURES])) {
>> +               /* restart the eMMC */
>> +               err = mmc_ffu_restart(card);
>> +               if (err) {
>> +                       pr_err("FFU: %s: error %d FFU install:\n",
>> +                               mmc_hostname(card->host), err);
>> +               }
>> +       } else {
> 
> Add followings
> "
>                         ffu_data_len = ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG]|
>                                 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;
> 
>                         if (!ffu_data_len) {
>                                 err = -EPERM;
>                                 return err;
>                         }
> "
> 
>> +                       /* set device to FFU mode */
>> +                       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> +                               EXT_CSD_MODE_CONFIG, 0x1,
>> +                               card->ext_csd.generic_cmd6_time);
>> +                       if (err) {
>> +                               pr_err("FFU: %s: error %d FFU is not
> supported\n",
>> +                                       mmc_hostname(card->host), err);
>> +                               goto exit;
>> +                       }
> 
> 
> 
> Checking ffu status in ext_csd should be done even if device does not
> support MODE_OPERATION_CODES So, it's better to move the code for checking
> this value to out of brace for FFU_FEATURES(ext_csd[EXT_CSD_FFU_FEATURES]
> 
>> +                       /* set ext_csd to install mode */
>> +                       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> +                               EXT_CSD_MODE_OPERATION_CODES,
>> +                               MMC_FFU_INSTALL_SET, timeout);
>> +
>> +                       if (err) {
>> +                               pr_err("FFU: %s: error %d setting install
> mode\n",
>> +                                       mmc_hostname(card->host), err);
>> +                               goto exit;
>> +                       }
>> +
> 
> Remove followings
> "
>                        /* read ext_csd */
>                        err = mmc_send_ext_csd(card, ext_csd);
>                        if (err) {
>                                pr_err("FFU: %s: error %d sending ext_csd\n",
>                                        mmc_hostname(card->host), err);
>                                goto exit;
>                        }
>                        /* return status */
>                        err = ext_csd[EXT_CSD_FFU_STATUS];
>                        if (err) {
>                                pr_err("FFU: %s: error %d FFU install:\n",
>                                        mmc_hostname(card->host), err);
>                                err = -EINVAL;
>                                goto exit;
>                        }
> "
> 
>> +               }
>> +
> 
> Add followings
> "
>            /* read ext_csd */
>            err = mmc_send_ext_csd(card, ext_csd);
>            if (err) {
>                    pr_err("FFU: %s: error %d sending ext_csd\n",
>                               mmc_hostname(card->host), err);
>                    goto exit;
>            }
>            /* return status */
>            err = ext_csd[EXT_CSD_FFU_STATUS];
>            if (err) {
>                    pr_err("FFU: %s: error %d FFU install:\n",
>                               mmc_hostname(card->host), err);
>                    err = -EINVAL;
>                    goto exit;
>            }
> "
> 
>> +exit:
>> +       return err;
>> +}
>> +EXPORT_SYMBOL(mmc_ffu_install);
>> +
> 
> 
> 
> And some device's fw should be transferred with one command.
> They does not support multiple commands for fw transfer.
> For these devices, MMC_IOC_MAX_BYTES should be greater.
> 
> diff --git a/include/uapi/linux/mmc/ioctl.h b/include/uapi/linux/mmc/ioctl.h
> index 1f5e689..af9ea62 100644
> --- a/include/uapi/linux/mmc/ioctl.h
> +++ b/include/uapi/linux/mmc/ioctl.h
> @@ -53,5 +53,5 @@ struct mmc_ioc_cmd {
>   * is enforced per ioctl call.  For larger data transfers, use the normal
>   * block device operations.
>   */
> -#define MMC_IOC_MAX_BYTES  (512L * 256)
> +#define MMC_IOC_MAX_BYTES  (512L * 1024)
>  #endif /* LINUX_MMC_IOCTL_H */
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




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

  Powered by Linux