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

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

 



Dear, Grant.

On 04/02/2014 05:30 AM, Grant Grundler wrote:
> argh...reposting my response as text only since linux-mmc doesn't like
> html mail. :(
> 
> On Tue, Apr 1, 2014 at 1:26 PM, Grant Grundler <grundler@xxxxxxxxxxxx> wrote:
>>
>>
>>
>> On Mon, Mar 31, 2014 at 9:17 PM, Jaehoon Chung <jh80.chung@xxxxxxxxxxx>
>> wrote:
>>>
>>> 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.)
>>
>>
>> I believe Seunguk Shin provided the information so someone else could add
>> this code. I could be that person if no one from Samsung has have time for
>> this.  I'm very grateful to Seungguk for posting these details.

Right. his comment is helpful, when samsung eMMC is used.
But I think it should be separated with this patch. :)
>>
>> I hope we can see the same details for Samsung eMMC 4.5 also (but please use
>> a different email Subject line so we aren't confused.)
>>
>>> This patch isn't patch for samsung eMMC.
>>> I didn't see this patch fully, but i think this patch is general code.
>>
>>
>> AFAICT, the MANFID_SAMSUNG is only a "quirk" for Samsung devices which
>> specify the EXT_CSD_FFU_ARG as 0.
>>
>> The original patch from SanDisk is general code and most of Seunguk's
>> comments are general too. SanDisk (ie Avi) should please ACK they've seen
>> those comments since I believe Seunguk is correct.
Other comment is general, but I think he have also mentioned the samsung specific part.

Best Regards,
Jaehoon Chung
>>
>> And Avi, please let us know if/when you plan on posting a V2. Or at least
>> not be offended if I get impatient and hijack this patch series. :)
>>
>> cheers,
>> grant
>>
>>> 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
>>
>>
> --
> 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