Re: [PATCH 2/2] mmc: esdhc: add quirk to support 3.3v for T4240
[...] But the operation will make host-ocr_mask to have no use for other voltage supporting. I think using | instead or just assigning host-ocr_mask to ocr_avail should be ok. If so, there is no need to add this quirk. This is kind of a policy change for how to treat the configuration from DT. I have cc:ed Haijun Zhang, which invented the binding to see if we can get some feeback from him. The commit is: 6e9e318b304fd7373a0754805a76a02ddbc69a41 (mmc: core: parse voltage from device-tree) The email of Haijun Zhang, bounced so I guess we shouldn't expect any response from him. Kind regards Uffe -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/2] mmc: sdhci-bcm2835: Actually enable the clock
On 5 June 2015 at 04:59, Stephen Warren swar...@wwwdotorg.org wrote: On 05/29/2015 03:06 PM, Eric Anholt wrote: We're currently using a fixed frequency clock specified in the DT, so enabling is a no-op. However, the RPi firmware-based clocks driver can actually disable unused clocks, so when switching to use it we ended up losing our MMC clock once all devices were probed. diff --git a/drivers/mmc/host/sdhci-bcm2835.c b/drivers/mmc/host/sdhci-bcm2835.c + ret = clk_prepare_enable(pltfm_host-clk); + if (ret) { + dev_err(pdev-dev, failed to enable host clk\n); + goto err; + } Given that pltfm_host is a struct sdhci_pltfm_host i.e. a type defined/handled by sdhci-pltfm.c , I'm rather surprised that sdhci-pltfm.c doesn't do this itself. Wouldn't it make sense for it to do so? We could likely move additional clock management into the sdhci-pltfm. So we would then remove some duplicated code, but we would potentially also loose some in flexibility. It's worth an effort to look into. Please go ahead and have a try. :-) Kind regards Uffe -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] mmc: esdhc: add quirk to support 3.3v for T4240
[...] Actually the sdhci-of-esdhc driver would set host-ocr_mask when it probes. mmc_of_parse_voltage(np, host-ocr_mask); Okay, got it - thanks! So I tried to understand when the voltage-range binding should be used, but the DT documentation is quite poor for it. Anyway, I assumes the binding is there to describe internal HW characteristics of the what regulator levels the mmc controller can support. And the regulator levels are for the power to the card, *not* for the IO voltage. So, is this according to what you expects as well, especially since you were aiming to fix something for the IO voltage in patch1? But the operation will make host-ocr_mask to have no use for other voltage supporting. I think using | instead or just assigning host-ocr_mask to ocr_avail should be ok. If so, there is no need to add this quirk. This is kind of a policy change for how to treat the configuration from DT. I have cc:ed Haijun Zhang, which invented the binding to see if we can get some feeback from him. The commit is: 6e9e318b304fd7373a0754805a76a02ddbc69a41 (mmc: core: parse voltage from device-tree) Haijun Zhang had left his job. And I have worked instead of him recently. I have new find about this. commit c0b887b66c95fe5abaac071b8332b8c21113d84b Author: Haijun Zhang haijun.zh...@freescale.com Date: Mon Aug 26 09:19:23 2013 +0800 mmc: sdhci: get voltage from sdhc host We use host-ocr_mask to hold the voltage get from device-tree node, In case host-ocr_mask was available, we use host-ocr_mask as the final available voltage can be used by MMC/SD/SDIO card. Signed-off-by: Haijun Zhang haijun.zh...@freescale.com Reviewed-by: Anton Vorontsov an...@enomsg.org Signed-off-by: Chris Ball c...@laptop.org This was change by commit 3a48edc4bd68f841c07c7bc86358d2f02133f247. But I didn’t see the reason. Oh, that's unfortunate. I think it shouldn't have done that. Looking a bit further up in the code in sdhci_add_host(), you will find that the ocr_avail mask is created by calling mmc_regulator_get_supply() (and not mmc_of_parse() as told you before). If there are external regulators, the ocr_avail mask will then override the values from SDHCI's caps register. But there is no external regulator on boards that using eSDHC... Quoted from your response in patch1: Although the controller only supports 1.8v, the hardware circuit has a level translator for supporting 3.3v. Again, that seems to concern the IO voltage, but if not - could it be modelled as regulator and thus used to fetch the ocr mask from? It's quite common that we use GPIO regulators in the mmc subsystem for this matter. I am afraid not. Such as, some boards only support 1.8v, but we used adapter card that makes sd work on 3.3v power voltage and 3.3v IO voltage. And some boards may be integrated the level translator on the board to make sd card work on 3.3v power and 3.3v IO voltage. I believe am starting to understand the problem now. You are likely suffering from the change in 3a48edc4bd68f841c07c7bc86358d2f02133f247. I will cook a patch for you that you can test. Kind regards Uffe -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] mmc: esdhc: add quirk to support 3.3v for T4240
On 5 June 2015 at 09:10, Lu Y.B. yangbo...@freescale.com wrote: Thanks a lot, see my comments. -Original Message- From: Ulf Hansson [mailto:ulf.hans...@linaro.org] Sent: Thursday, June 04, 2015 7:36 PM To: Lu Yangbo-B47093 Cc: linux-mmc; Chris Ball Subject: Re: [PATCH 2/2] mmc: esdhc: add quirk to support 3.3v for T4240 On 4 June 2015 at 11:56, Lu Y.B. yangbo...@freescale.com wrote: Pls see my comments below. -Original Message- From: Ulf Hansson [mailto:ulf.hans...@linaro.org] Sent: Thursday, June 04, 2015 3:51 PM To: Lu Yangbo-B47093 Cc: linux-mmc; Chris Ball Subject: Re: [PATCH 2/2] mmc: esdhc: add quirk to support 3.3v for T4240 On 2 June 2015 at 09:09, Yangbo Lu yangbo...@freescale.com wrote: Add SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS33 for T4240 Signed-off-by: Yangbo Lu yangbo...@freescale.com --- drivers/mmc/host/sdhci-of-esdhc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 22e9111..4f5fe42 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -369,6 +369,9 @@ static int sdhci_esdhc_probe(struct platform_device *pdev) host-quirks2 |= SDHCI_QUIRK2_BROKEN_HOST_CONTROL; } + if (of_device_is_compatible(np, fsl,t4240-esdhc)) + host-quirks2 |= SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS33; + Instead of checking the compatible, could you check the ocr_avail mask which mmc_of_parse() create from the vmmc regulator? It could get ocr_mask value supporting 3.3v from dts, and get ocr_avail not supporting 3.3v from capability register. But in sdhci.c, the ocr_avail will the ocr_mask value, this makes 3.3v supporting bit cleaned. if (host-ocr_mask) ocr_avail = host-ocr_mask; I have to admit that this looks a bit odd... Anyway, as long as you don't specify the host-ocr_mask the above if will not change the ocr_avail mask. Actually the sdhci-of-esdhc driver would set host-ocr_mask when it probes. mmc_of_parse_voltage(np, host-ocr_mask); Okay, got it - thanks! So I tried to understand when the voltage-range binding should be used, but the DT documentation is quite poor for it. Anyway, I assumes the binding is there to describe internal HW characteristics of the what regulator levels the mmc controller can support. And the regulator levels are for the power to the card, *not* for the IO voltage. So, is this according to what you expects as well, especially since you were aiming to fix something for the IO voltage in patch1? But the operation will make host-ocr_mask to have no use for other voltage supporting. I think using | instead or just assigning host-ocr_mask to ocr_avail should be ok. If so, there is no need to add this quirk. This is kind of a policy change for how to treat the configuration from DT. I have cc:ed Haijun Zhang, which invented the binding to see if we can get some feeback from him. The commit is: 6e9e318b304fd7373a0754805a76a02ddbc69a41 (mmc: core: parse voltage from device-tree) Looking a bit further up in the code in sdhci_add_host(), you will find that the ocr_avail mask is created by calling mmc_regulator_get_supply() (and not mmc_of_parse() as told you before). If there are external regulators, the ocr_avail mask will then override the values from SDHCI's caps register. But there is no external regulator on boards that using eSDHC... Quoted from your response in patch1: Although the controller only supports 1.8v, the hardware circuit has a level translator for supporting 3.3v. Again, that seems to concern the IO voltage, but if not - could it be modelled as regulator and thus used to fetch the ocr mask from? It's quite common that we use GPIO regulators in the mmc subsystem for this matter. Kind regards Uffe -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] mmc: sdhci: add SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS33 quirk support
On 5 June 2015 at 10:10, Lu Y.B. yangbo...@freescale.com wrote: On 2 June 2015 at 09:09, Yangbo Lu yangbo...@freescale.com wrote: This quirk is used for controllers that can only support 1.8V voltage but the peripheral hardware circuit has capability to support 3.3V voltage. Which voltage are you referring to? The I/O voltage or the power to the card? VCC or VCCQ? Kind regards Uffe The voltage here means I/O voltage. Although the controller only supports 1.8v, the hardware circuit has a level translator for supporting 3.3v. Thanks for clarifying. Sorry, it should be power voltage... This quirk is used to set capability register Voltage Support 3.3V bit since the controller self doesn’t support but circuit supports. Okay. So then please tell me, exactly, how is the power being controlled when using this hardware circuit? This patchset only tries to change the content of the ocr_mask, but there is no logic added to support changing voltage levels by using the external circuit. At least to my understanding. Kind regards Uffe -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] mmc: sdhci: add SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS33 quirk support
On 5 June 2015 at 10:49, Lu Y.B. yangbo...@freescale.com wrote: On 5 June 2015 at 10:10, Lu Y.B. yangbo...@freescale.com wrote: On 2 June 2015 at 09:09, Yangbo Lu yangbo...@freescale.com wrote: This quirk is used for controllers that can only support 1.8V voltage but the peripheral hardware circuit has capability to support 3.3V voltage. Which voltage are you referring to? The I/O voltage or the power to the card? VCC or VCCQ? Kind regards Uffe The voltage here means I/O voltage. Although the controller only supports 1.8v, the hardware circuit has a level translator for supporting 3.3v. Thanks for clarifying. Sorry, it should be power voltage... This quirk is used to set capability register Voltage Support 3.3V bit since the controller self doesn’t support but circuit supports. Okay. So then please tell me, exactly, how is the power being controlled when using this hardware circuit? This patchset only tries to change the content of the ocr_mask, but there is no logic added to support changing voltage levels by using the external circuit. At least to my understanding. As I said, the controller only support 1.8v but we could use adapter card or add level translator on board directly to make sd *only* work on 3.3v power and 3.3v IO voltage. Thanks. How does this level translator work? Doesn't it need to be controlled somehow? Do you have a datasheet you can share for it? Kind regards Uffe -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] SDHCI: Change AMD SDHCI quirk application scope
On Fri, Jun 05, 2015 at 09:37:09AM +0800, Wan ZongShun wrote: Boris, I means I put this KERCZ Mircro in pci_ids.h, and I also will send the other patch to instead the following '0x790b' of codes. I think it is reasonable, right? No, it means two things: * why does it contain KERNCZ? What does that mean? * #define PCI_DEVICE_ID_AMD_better_name_SMBUS 0x790b should be in drivers/mmc/host/sdhci-pci.c as it is used only there. Thanks. -- Regards/Gruss, Boris. ECO tip #101: Trim your mails when you reply. -- -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] mmc: sdhci: add SDHCI_QUIRK2_CIRCUIT_SUPPORT_VS33 quirk support
On 5 June 2015 at 11:09, Lu Y.B. yangbo...@freescale.com wrote: On 5 June 2015 at 10:49, Lu Y.B. yangbo...@freescale.com wrote: On 5 June 2015 at 10:10, Lu Y.B. yangbo...@freescale.com wrote: On 2 June 2015 at 09:09, Yangbo Lu yangbo...@freescale.com wrote: This quirk is used for controllers that can only support 1.8V voltage but the peripheral hardware circuit has capability to support 3.3V voltage. Which voltage are you referring to? The I/O voltage or the power to the card? VCC or VCCQ? Kind regards Uffe The voltage here means I/O voltage. Although the controller only supports 1.8v, the hardware circuit has a level translator for supporting 3.3v. Thanks for clarifying. Sorry, it should be power voltage... This quirk is used to set capability register Voltage Support 3.3V bit since the controller self doesn’t support but circuit supports. Okay. So then please tell me, exactly, how is the power being controlled when using this hardware circuit? This patchset only tries to change the content of the ocr_mask, but there is no logic added to support changing voltage levels by using the external circuit. At least to my understanding. As I said, the controller only support 1.8v but we could use adapter card or add level translator on board directly to make sd *only* work on 3.3v power and 3.3v IO voltage. Thanks. How does this level translator work? Doesn't it need to be controlled somehow? Do you have a datasheet you can share for it? I attached a adapter picture for you. we would never control the power to change. Although the io voltage could be control in design, we would never control it either. Always connect Vccb_SEL to GND. Thanks. This make it crystal clear to me, but I think you have some more homework to do. :-) This is a commonly used circuit to be able to boost the IO voltage levels from the SoC, towards the card. According to the SD spec, all cards needs to support the IO legacy voltage levels (2.7-3.6V). UHS-I SD cards, are also operate using 1.8V IO voltage, but the early initialization must be done using the legacy IO voltage level domain. So, I assume that when grounding Vccb_SEL, the IO voltage will be 2.9 V, which means you will always remain in legacy IO voltage level domain. That's fine, as long as you don't care about UHS cards. So, again this patchset really doesn't make sense. Kind regards Uffe -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] SDHCI: Change AMD SDHCI quirk application scope
2015-06-05 17:20 GMT+08:00 Borislav Petkov b...@alien8.de: On Fri, Jun 05, 2015 at 09:37:09AM +0800, Wan ZongShun wrote: Boris, I means I put this KERCZ Mircro in pci_ids.h, and I also will send the other patch to instead the following '0x790b' of codes. I think it is reasonable, right? No, it means two things: * why does it contain KERNCZ? What does that mean? The KERNCZ is new AMD SB/FCH generation name, like HUDSON2 is old FCH generation. We will adopt 0x790b as device ID since from this KERNCZ gereration. * #define PCI_DEVICE_ID_AMD_better_name_SMBUS 0x790b should be in drivers/mmc/host/sdhci-pci.c as it is used only there. The i2cpiix4.c driver and eMMC driver both will use this device ID macro, Do you think I should submit two patches synchronously? like patch1: change i2cpiix4 driver to use PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, patch2: for eMMC quirk in sdhci-pci.c? And then the PCI_DEVICE_ID_AMD_KERNCZ_SMBUS can be go into pci ids.h? Thanks. -- Regards/Gruss, Boris. ECO tip #101: Trim your mails when you reply. -- -- Wan ZongShun. www.mcuos.com -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: sdhci: Restore behavior while creating OCR mask
Commit 3a48edc4bd68 (mmc: sdhci: Use mmc core regulator infrastucture) changed the behavior for how to assign the ocr_avail mask for the mmc host. More precisely it started to mask the bits instead of assigning them. Restore the behavior, but also make it clear that an OCR mask created from an external regulator overrides the other ones. Fixes: 3a48edc4bd68 (mmc: sdhci: Use mmc core regulator infrastucture) Cc: Tim Kryger tim.kry...@gmail.com Reported-by: Yangbo Lu yangbo...@freescale.com Signed-off-by: Ulf Hansson ulf.hans...@linaro.org --- drivers/mmc/host/sdhci.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 1b4861d..706bb60 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -3256,13 +3256,14 @@ int sdhci_add_host(struct sdhci_host *host) SDHCI_MAX_CURRENT_MULTIPLIER; } - /* If OCR set by external regulators, use it instead */ + /* If OCR set by host, use it instead. */ + if (host-ocr_mask) + ocr_avail = host-ocr_mask; + + /* If OCR set by external regulators, give it highest prio. */ if (mmc-ocr_avail) ocr_avail = mmc-ocr_avail; - if (host-ocr_mask) - ocr_avail = host-ocr_mask; - mmc-ocr_avail = ocr_avail; mmc-ocr_avail_sdio = ocr_avail; if (host-ocr_avail_sdio) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] SDHCI: Change AMD SDHCI quirk application scope
On Fri, Jun 05, 2015 at 06:01:56PM +0800, Wan ZongShun wrote: The KERNCZ is new AMD SB/FCH generation name, like HUDSON2 is old FCH generation. We will adopt 0x790b as device ID since from this KERNCZ gereration. True story. Strange name that. The i2cpiix4.c driver and eMMC driver both will use this device ID macro, Do you think I should submit two patches synchronously? like patch1: change i2cpiix4 driver to use PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, patch2: for eMMC quirk in sdhci-pci.c? And then the PCI_DEVICE_ID_AMD_KERNCZ_SMBUS can be go into pci ids.h? If you have all those patches ready, you could do a first patch adding the PCI ID to pci_ids.h only. Then follow with the different driver changes, i.e. sdhci-pci.c, i2cpiix4, and so on and make it clear in the 0/n message that they all depend on the first one. Or something along those lines. Thanks. -- Regards/Gruss, Boris. ECO tip #101: Trim your mails when you reply. -- -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3 4/8] mmc: lock: Add card lock/unlock maintenance commands
Create a sysfs interface that allows a user to manage an inserted cards lock state. The sysfs attribute lock will be added to the device's sysfs directory. The following commands are supported: setpw - Set the cards password clearpw - Clear the cards password lock- Lock the card unlock - Unlock the card erase - Force erase the card, clear the password and unlock it Commands that require a password will request the password through the kernels KEYS subsystem. Signed-off-by: Al Cooper alcoop...@gmail.com --- drivers/mmc/core/mmc.c | 81 ++ 1 file changed, 81 insertions(+) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index f36c76f..8e94eb8 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -697,6 +697,84 @@ static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) return err; } +#ifdef CONFIG_MMC_LOCK + +ssize_t mmc_lock_show(struct device *dev, struct device_attribute *att, + char *buf) +{ + struct mmc_card *card = mmc_dev_to_card(dev); + + if (!mmc_card_lockable(card)) + return sprintf(buf, unsupported\n); + else + return sprintf(buf, %slocked\n, mmc_card_locked(card) ? + : un); +} + + +static struct lock_cmd { + const char *name; + int io_cmd; + int locked_required; + int need_pw; +} lock_cmds[] = { + { erase, MMC_LOCK_MODE_ERASE, true, false }, + { clrpw, MMC_LOCK_MODE_CLR_PWD, false, true }, + { setpw, MMC_LOCK_MODE_SET_PWD, false, true }, + { lock, MMC_LOCK_MODE_LOCK, false, true }, + { unlock, MMC_LOCK_MODE_UNLOCK, true, true }, +}; + +/* + * implement MMC password functions: force erase, set password, + * clear password, lock and unlock. + */ +ssize_t mmc_lock_store(struct device *dev, struct device_attribute *att, + const char *data, size_t len) +{ + struct mmc_card *card = mmc_dev_to_card(dev); + int res = -EINVAL; + int x; + struct mmc_password password; + + mmc_claim_host(card-host); + if (!mmc_card_lockable(card)) + goto out; + for (x = 0; x ARRAY_SIZE(lock_cmds); x++) { + if (sysfs_streq(data, lock_cmds[x].name)) + break; + } + if (x = ARRAY_SIZE(lock_cmds)) + goto out; + + if ((lock_cmds[x].locked_required !mmc_card_locked(card)) || + (!lock_cmds[x].locked_required mmc_card_locked(card))) { + dev_warn(dev, %s requires %slocked card\n, +lock_cmds[x].name, +lock_cmds[x].locked_required ? : un); + goto out; + } + if (lock_cmds[x].need_pw) { + res = mmc_get_password(card, password); + if (res) + goto out; + } + res = mmc_lock_unlock(card, password, lock_cmds[x].io_cmd); +out: + mmc_release_host(card-host); + if (res == 0) + return len; + else + return res; +} + +static DEVICE_ATTR(lock, S_IWUSR | S_IRUGO, + mmc_lock_show, mmc_lock_store); + + +#endif /* CONFIG_MMC_LOCK */ + + MMC_DEV_ATTR(cid, %08x%08x%08x%08x\n, card-raw_cid[0], card-raw_cid[1], card-raw_cid[2], card-raw_cid[3]); MMC_DEV_ATTR(csd, %08x%08x%08x%08x\n, card-raw_csd[0], card-raw_csd[1], @@ -751,6 +829,9 @@ static struct attribute *mmc_std_attrs[] = { dev_attr_enhanced_area_size.attr, dev_attr_raw_rpmb_size_mult.attr, dev_attr_rel_sectors.attr, +#ifdef CONFIG_MMC_LOCK + dev_attr_lock.attr, +#endif /* CONFIG_MMC_LOCK */ NULL, }; ATTRIBUTE_GROUPS(mmc_std); -- 1.9.0.138.g2de3478 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3 5/8] mmc: lock: Change SD init functionality to handle locked SD cards
- Change mmc_sd_init_card() to check for a locked card and, if found, try to get a password using the kernel KEYS subsystem, unlock the card and continue. The unlock can fail due to a bad password, no password or during boot when the rootfs that holds the password is not yet available. To handle this, mmc_sd_init_card() will send just the early init commands before trying to unlock and, on unlock failure, skip the later init commands (which would fail on a locked card). mmc_sd_init_card() will also handle the retry case, trigger via sysfs, where it will skip the already issued early init commands, try again to unlock the card and if successful issue the previously skipped later init commands. These changes allow a card that failed unlock to still come up to the point that the block device and sysfs for the device is created. This allows the sysfs to be used to issue LOCK maintenance commands or to trigger a retry, presumably after the password has be made available by user space. - Add sysfs attribute unlock_retry that will try again to unlock and fully init the card. - Add sysfs attribute lock to enable sysfs LOCK maintenance commands Signed-off-by: Al Cooper alcoop...@gmail.com --- drivers/mmc/core/core.h | 4 ++ drivers/mmc/core/sd.c| 161 +-- include/linux/mmc/card.h | 1 + 3 files changed, 118 insertions(+), 48 deletions(-) diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index b91bc3e..6b9c972 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -97,5 +97,9 @@ struct mmc_password { }; int mmc_unlock_card(struct mmc_card *card); int mmc_get_password(struct mmc_card *card, struct mmc_password *password); +ssize_t mmc_lock_show(struct device *dev, struct device_attribute *att, + char *buf); +ssize_t mmc_lock_store(struct device *dev, struct device_attribute *att, + const char *data, size_t len); #endif diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 31a9ef2..fd40946 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -27,6 +27,9 @@ #include sd.h #include sd_ops.h +static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, + struct mmc_card *oldcard); + static const unsigned int tran_exp[] = { 1, 10, 100,1000, 0, 0, 0, 0 @@ -670,6 +673,40 @@ out: return err; } +#ifdef CONFIG_MMC_LOCK +static ssize_t mmc_sd_unlock_retry_store(struct device *dev, +struct device_attribute *att, +const char *data, size_t len) +{ + int err; + struct mmc_card *card = mmc_dev_to_card(dev); + struct mmc_host *host = card-host; + + BUG_ON(!card); + BUG_ON(!host); + + mmc_claim_host(host); + if (!mmc_card_locked(card)) { + mmc_release_host(host); + return len; + } + err = mmc_sd_init_card(host, card-ocr, card); + mmc_release_host(host); + if (err) + return len; + device_release_driver(dev); + err = device_attach(dev); + if (err 0) + dev_warn(dev, device_attach() failed, error: %d\n, err); + return len; +} + +static DEVICE_ATTR(lock, S_IWUSR | S_IRUGO, + mmc_lock_show, mmc_lock_store); +static DEVICE_ATTR(unlock_retry, S_IWUSR, + NULL, mmc_sd_unlock_retry_store); +#endif /* CONFIG_MMC_LOCK */ + MMC_DEV_ATTR(cid, %08x%08x%08x%08x\n, card-raw_cid[0], card-raw_cid[1], card-raw_cid[2], card-raw_cid[3]); MMC_DEV_ATTR(csd, %08x%08x%08x%08x\n, card-raw_csd[0], card-raw_csd[1], @@ -699,6 +736,10 @@ static struct attribute *sd_std_attrs[] = { dev_attr_name.attr, dev_attr_oemid.attr, dev_attr_serial.attr, +#ifdef CONFIG_MMC_LOCK + dev_attr_lock.attr, + dev_attr_unlock_retry.attr, +#endif /* CONFIG_MMC_LOCK */ NULL, }; ATTRIBUTE_GROUPS(sd_std); @@ -901,69 +942,92 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, int err; u32 cid[4]; u32 rocr = 0; + u32 status; BUG_ON(!host); WARN_ON(!host-claimed); - err = mmc_sd_get_cid(host, ocr, cid, rocr); - if (err) - return err; - - if (oldcard) { - if (memcmp(cid, oldcard-raw_cid, sizeof(cid)) != 0) - return -ENOENT; - + /* Retry init of locked card */ + if (oldcard mmc_card_locked(oldcard)) { card = oldcard; + oldcard = NULL; + rocr = card-raw_ocr; } else { + err = mmc_sd_get_cid(host, ocr, cid, rocr); + if (err) + return err; + + if (oldcard) { + if (memcmp(cid, oldcard-raw_cid, sizeof(cid)) != 0) +
[PATCH V3 0/8 RESEND] Add password protected lock/unlock support for SD/MMC
This set of patches adds support for password protected locking and unlocking of MMC and SD devices. It uses the LOCK/UNLOCK command (CMD42) available in both the MMC and SD command sets. Some of this code was based on a patch set submitted in 2006 by Anderson Briglia Add MMC Password Protection (lock/unlock). This patch set never made it into mainline. By default, a card with no password assigned is always in unlocked state. After password assignment, in the next power cycle the card switches to a locked state where only the basic and lock card command classes are accepted by the card. Only after unlocking it with the correct password can the card be used for normal operations like block I/O. Password management and caching is done through the Kernel Key Retention Service mechanism and the sysfs filesystem. Two new sysfs attributes were added. The lock attribute is used to lock, unlock, assign a password, clear a password and force erase a card. The unlock_retry attribute is used to retry an unlock that failed during boot because the rootfs was not yet available with the password. The user space software needed to test this new feature is available on GitHub at: https://github.com/alcooper/mmc-password-utils See the README for a detailed description of the user space layer and how to use this feature. Changed for V3: - Ported the V2 patch set submitted Aug. 2013 to the latest mainline (v4.1-rc4). - Created a GitHub project for the user space layer. - Change the lock command (CMD42) to round up the data buffer size to 512 for SD but leave exact size for eMMC based on the SD and eMMC specs. Changed for V2: The V2 changes were not functional and were just general cleanup. - Use stub functions to reduce the number of CONFIG ifdefs. - Add static to a few functions that were local. - Use pr_warn instead of pr_warning. - Improve a few variable names and messages. Abbas Raza (1): According to SD Physical Layer Specifications: Locked cards respond to (and execute) all commands in the basic command class (class 0), ACMD41, CMD16 and lock card command class. Thus, the host is allowed to reset, initialize, select, query for status, etc., but not to access data on the card. Al Cooper (7): mmc: lock: Use the kernel KEYS subsystem to get a card's password mmc: lock: Add low level LOCK_UNLOCK command mmc: lock: Add function to unlock a password locked card mmc: lock: Add card lock/unlock maintenance commands mmc: lock: Change SD init functionality to handle locked SD cards mmc: lock: Prevent partition table read for locked cards. mmc: lock: Change MMC init to handle locked cards. drivers/mmc/card/block.c | 14 drivers/mmc/core/Kconfig | 8 +++ drivers/mmc/core/core.c| 120 + drivers/mmc/core/core.h| 14 +++- drivers/mmc/core/mmc.c | 123 ++ drivers/mmc/core/mmc_ops.c | 150 + drivers/mmc/core/mmc_ops.h | 13 drivers/mmc/core/sd.c | 161 +++-- include/linux/mmc/card.h | 6 ++ 9 files changed, 560 insertions(+), 49 deletions(-) -- 1.9.0.138.g2de3478 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3 6/8] mmc: lock: Prevent partition table read for locked cards.
Change the MMC block layer to avoid reading the partition table when the card is locked because read commands will fail. Signed-off-by: Al Cooper alcoop...@gmail.com --- drivers/mmc/card/block.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 60f7141..5650748 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -2147,6 +2147,13 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, md-disk-flags |= GENHD_FL_NO_PART_SCAN; /* +* If the card is locked, reads will fail so prevent partition +* table scan +*/ + if (mmc_card_locked(card)) + md-disk-flags |= GENHD_FL_NO_PART_SCAN; + + /* * As discussed on lkml, GENHD_FL_REMOVABLE should: * * - be set for removable media with permanent block devices -- 1.9.0.138.g2de3478 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3 2/8] mmc: lock: Add low level LOCK_UNLOCK command
Add support for the LOCK_UNLOCK command. This command can lock, unlock, set password, clear password and force erase SD and MMC cards. Signed-off-by: Al Cooper alcoop...@gmail.com --- drivers/mmc/core/core.c| 5 +- drivers/mmc/core/mmc_ops.c | 150 + drivers/mmc/core/mmc_ops.h | 13 include/linux/mmc/card.h | 5 ++ 4 files changed, 169 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f7d7ad9..4b0d26e 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2716,11 +2716,8 @@ static int mmc_key_instantiate(struct key *key, char *payload; if (prep-datalen = 0 || prep-datalen MMC_PASSWORD_MAX || - !prep-data) { - pr_warn(Invalid data\n); + !prep-data) return -EINVAL; - } - payload = kmalloc(prep-datalen, GFP_KERNEL); if (!payload) return -ENOMEM; diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 0ea042d..c15c285 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -13,6 +13,8 @@ #include linux/export.h #include linux/types.h #include linux/scatterlist.h +#include linux/key.h +#include linux/err.h #include linux/mmc/host.h #include linux/mmc/card.h @@ -783,3 +785,151 @@ int mmc_can_ext_csd(struct mmc_card *card) { return (card card-csd.mmca_vsn CSD_SPEC_VER_3); } + +#ifdef CONFIG_MMC_LOCK +/** + * mmc_lock_unlock - send LOCK_UNLOCK command to a specific card. + * @card: card to which the LOCK_UNLOCK command should be sent + * @key: key containing the MMC password + * @mode: LOCK_UNLOCK mode + * + */ +int mmc_lock_unlock(struct mmc_card *card, struct mmc_password *password, + int mode) +{ + struct mmc_request mrq; + struct mmc_command cmd_sbl; + struct mmc_command cmd; + struct mmc_data data; + struct scatterlist sg; + unsigned long erase_timeout; + int err, data_size; + u8 *data_buf = NULL; + + if (mmc_card_mmc(card)) { + /* Lock commands only work on the data partition, select it */ + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_PART_CONFIG, + card-ext_csd.part_config + ~EXT_CSD_PART_CONFIG_ACC_MASK, + card-ext_csd.part_time); + + if (err != 0) + pr_warn(%s: Data partition select failed.\n, + mmc_hostname(card-host)); + + /* +* The MMC spec does not allow rounding up the data to 512 +* bytes like SD spec +*/ + if (mode MMC_LOCK_MODE_ERASE) + data_size = 4; + else + data_size = 2 + password-length; + } else { + /* Round up the size of the data block to 512 bytes for SD */ + data_size = 512; + } + data_buf = kzalloc(data_size, GFP_KERNEL); + if (!data_buf) + return -ENOMEM; + data_buf[0] |= mode; + if (!(mode MMC_LOCK_MODE_ERASE)) { + data_buf[1] = password-length; + memcpy(data_buf + 2, password-password, password-length); + } + + memset(cmd_sbl, 0, sizeof(struct mmc_command)); + cmd_sbl.opcode = MMC_SET_BLOCKLEN; + cmd_sbl.arg = data_size; + cmd_sbl.flags = MMC_RSP_R1 | MMC_CMD_AC; + err = mmc_wait_for_cmd(card-host, cmd_sbl, MMC_CMD_RETRIES); + if (err) + goto out; + + memset(cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = MMC_LOCK_UNLOCK; + cmd.arg = 0; + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + + memset(data, 0, sizeof(struct mmc_data)); + mmc_set_data_timeout(data, card); + data.blksz = data_size; + data.blocks = 1; + data.flags = MMC_DATA_WRITE; + data.sg = sg; + data.sg_len = 1; + + memset(mrq, 0, sizeof(struct mmc_request)); + mrq.cmd = cmd; + mrq.data = data; + + sg_init_one(sg, data_buf, data_size); + mmc_wait_for_req(card-host, mrq); + if (cmd.error) { + err = cmd.error; + goto out; + } + if (data.error) { + err = data.error; + goto out; + } + + memset(cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = MMC_SEND_STATUS; + cmd.arg = card-rca 16; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + + /* set timeout for forced erase operation to 3 min. (see MMC spec) */ + erase_timeout = jiffies + 180 * HZ; + do { + /* +* we cannot use retries here because the +* R1_LOCK_UNLOCK_FAILED bit is cleared by subsequent reads to +* the status
[PATCH V3 7/8] mmc: lock: Change MMC init to handle locked cards.
- Change mmc_init_card() to check for a locked card and, if found, try to get a password using the kernel KEYS subsystem, unlock the card and continue. Unlike SD cards, MMC cards support all initialization commands when locked so the init sequence can be completed on a locked card and the card can be used without further init after being unlocked. If the unlock fails, the card state will be marked as locked which will prevent the block layer from reading the partition table. - Add sysfs attribute unlock_retry that will try again to unlock the card. If the unlock succeeds, the cards locked state will be cleared and the block layer restarted which will now read the partition table. Signed-off-by: Al Cooper alcoop...@gmail.com --- drivers/mmc/core/mmc.c | 46 -- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 8e94eb8..2c953c5 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -768,10 +768,37 @@ out: return res; } -static DEVICE_ATTR(lock, S_IWUSR | S_IRUGO, - mmc_lock_show, mmc_lock_store); +static ssize_t mmc_unlock_retry_store(struct device *dev, + struct device_attribute *att, + const char *data, size_t len) +{ + struct mmc_card *card = mmc_dev_to_card(dev); + struct mmc_host *host = card-host; + int err; + BUG_ON(!card); + BUG_ON(!host); + mmc_claim_host(host); + if (!mmc_card_locked(card)) { + mmc_release_host(host); + return len; + } + err = mmc_unlock_card(card); + mmc_release_host(host); + if (err 0) + return err; + device_release_driver(dev); + err = device_attach(dev); + if (err 0) + return err; + return len; +} + +static DEVICE_ATTR(lock, S_IWUSR | S_IRUGO, + mmc_lock_show, mmc_lock_store); +static DEVICE_ATTR(unlock_retry, S_IWUSR, + NULL, mmc_unlock_retry_store); #endif /* CONFIG_MMC_LOCK */ @@ -831,6 +858,7 @@ static struct attribute *mmc_std_attrs[] = { dev_attr_rel_sectors.attr, #ifdef CONFIG_MMC_LOCK dev_attr_lock.attr, + dev_attr_unlock_retry.attr, #endif /* CONFIG_MMC_LOCK */ NULL, }; @@ -1279,6 +1307,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, int err; u32 cid[4]; u32 rocr; + u32 status; BUG_ON(!host); WARN_ON(!host-claimed); @@ -1568,6 +1597,19 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, } } + /* If card is locked, try to unlock it */ + err = mmc_send_status(card, status); + if (err) + goto free_card; + if (status R1_CARD_IS_LOCKED) { + pr_info(%s: card is locked.\n, mmc_hostname(card-host)); + err = mmc_unlock_card(card); + if (err != 0) { + pr_warn(%s: Card unlock failed.\n, + mmc_hostname(card-host)); + } + } + if (!oldcard) host-card = card; -- 1.9.0.138.g2de3478 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3 3/8] mmc: lock: Add function to unlock a password locked card
This function will try to get a password for the card and use the password to unlock it. It will leave the card state flag set appropriately. Signed-off-by: Al Cooper alcoop...@gmail.com --- drivers/mmc/core/core.c | 26 ++ 1 file changed, 26 insertions(+) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 4b0d26e..61f1f78 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2777,6 +2777,27 @@ static inline void mmc_unregister_key_type(void) unregister_key_type(key_type_mmc); } +int mmc_unlock_card(struct mmc_card *card) +{ + int stat; + struct mmc_password password; + + mmc_card_set_locked(card); + stat = mmc_get_password(card, password); + if (stat) { + pr_warn(%s: Cannot find matching key\n, + mmc_hostname(card-host)); + return stat; + } + stat = mmc_lock_unlock(card, password, MMC_LOCK_MODE_UNLOCK); + if (stat) + pr_warn(%s: Password failed to unlock card\n, + mmc_hostname(card-host)); + else + mmc_card_clear_locked(card); + return stat; +} + #else /* CONFIG_MMC_LOCK */ int mmc_get_password(struct mmc_card *card, struct mmc_password *password) @@ -2793,6 +2814,11 @@ static inline void mmc_unregister_key_type(void) { } +int mmc_unlock_card(struct mmc_card *card) +{ + return -ENOKEY; +} + #endif /* CONFIG_MMC_LOCK */ static int __init mmc_init(void) -- 1.9.0.138.g2de3478 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3 1/8] mmc: lock: Use the kernel KEYS subsystem to get a card's password
Use the kernel KEYS subsystem to get a password for a card based on the card's CID. This code was based on a patch set submitted by Anderson Briglia in 2006. Signed-off-by: Al Cooper alcoop...@gmail.com --- drivers/mmc/core/Kconfig | 8 drivers/mmc/core/core.c | 97 drivers/mmc/core/core.h | 10 - 3 files changed, 114 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig index 9ebee72..1d073cd 100644 --- a/drivers/mmc/core/Kconfig +++ b/drivers/mmc/core/Kconfig @@ -11,3 +11,11 @@ config MMC_CLKGATE support handling this in order for it to be of any use. If unsure, say N. + +config MMC_LOCK + bool MMC/SD password based card lock/unlock + select KEYS + help + This will add the ability to lock/unlock SD and MMC cards. + + If unsure, say N. diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 92e7671..f7d7ad9 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -29,6 +29,7 @@ #include linux/random.h #include linux/slab.h #include linux/of.h +#include linux/key-type.h #include linux/mmc/card.h #include linux/mmc/host.h @@ -2707,6 +2708,96 @@ void mmc_init_context_info(struct mmc_host *host) init_waitqueue_head(host-context_info.wait); } +#ifdef CONFIG_MMC_LOCK + +static int mmc_key_instantiate(struct key *key, + struct key_preparsed_payload *prep) +{ + char *payload; + + if (prep-datalen = 0 || prep-datalen MMC_PASSWORD_MAX || + !prep-data) { + pr_warn(Invalid data\n); + return -EINVAL; + } + + payload = kmalloc(prep-datalen, GFP_KERNEL); + if (!payload) + return -ENOMEM; + memcpy(payload, prep-data, prep-datalen); + key-payload.data = payload; + key-datalen = prep-datalen; + return 0; +} + +/* + * dispose of the data dangling from the corpse of a mmc key + */ +static void mmc_key_destroy(struct key *key) +{ + kfree(key-payload.data); +} + +struct key_type key_type_mmc = { + .name = mmc, + .instantiate= mmc_key_instantiate, + .destroy= mmc_key_destroy, +}; + +int mmc_get_password(struct mmc_card *card, struct mmc_password *password) +{ + struct key *mmc_key; + char key_desc[(sizeof(card-raw_cid) * 2) + 1]; + + /* Use the CID to uniquely identify the card */ + snprintf(key_desc, sizeof(key_desc), %08x%08x%08x%08x, +card-raw_cid[0], card-raw_cid[1], +card-raw_cid[2], card-raw_cid[3]); + + mmc_key = request_key(key_type_mmc, key_desc, + password); + if (IS_ERR(mmc_key)) { + dev_warn(card-dev, Error, request_key %ld\n, +PTR_ERR(mmc_key)); + return PTR_ERR(mmc_key); + } + dev_dbg(card-dev, Found matching key\n); + memcpy(password-password, mmc_key-payload.data, + mmc_key-datalen); + password-length = mmc_key-datalen; + key_put(mmc_key); + + return 0; +} + +static inline int mmc_register_key_type(void) +{ + return register_key_type(key_type_mmc); +} + +static inline void mmc_unregister_key_type(void) +{ + unregister_key_type(key_type_mmc); +} + +#else /* CONFIG_MMC_LOCK */ + +int mmc_get_password(struct mmc_card *card, struct mmc_password *password) +{ + return -ENOKEY; +} + +static inline int mmc_register_key_type(void) +{ + return 0; +} + +static inline void mmc_unregister_key_type(void) +{ +} + +#endif /* CONFIG_MMC_LOCK */ + static int __init mmc_init(void) { int ret; @@ -2727,8 +2818,13 @@ static int __init mmc_init(void) if (ret) goto unregister_host_class; + ret = mmc_register_key_type(); + if (ret) + goto unregister_sdio_bus; return 0; +unregister_sdio_bus: + sdio_unregister_bus(); unregister_host_class: mmc_unregister_host_class(); unregister_bus: @@ -2741,6 +2837,7 @@ destroy_workqueue: static void __exit mmc_exit(void) { + mmc_unregister_key_type(); sdio_unregister_bus(); mmc_unregister_host_class(); mmc_unregister_bus(); diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index cfba3c0..b91bc3e 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -89,5 +89,13 @@ void mmc_init_context_info(struct mmc_host *host); int mmc_execute_tuning(struct mmc_card *card); -#endif +/* Lock/Unlock functionality */ +#define MMC_PASSWORD_MAX 16 +struct mmc_password { + char password[MMC_PASSWORD_MAX]; + int length; +}; +int mmc_unlock_card(struct mmc_card *card); +int mmc_get_password(struct mmc_card *card, struct mmc_password *password); +#endif -- 1.9.0.138.g2de3478 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of
[PATCH V3 8/8] According to SD Physical Layer Specifications: Locked cards respond to (and execute) all commands in the basic command class (class 0), ACMD41, CMD16 and lock card command class. Th
From: Abbas Raza abbas_r...@mentor.com But when a locked card is inserted into system having no key added for this card, following errors are observed until the card is removed [ 36.955193] mmc0: card is locked. [ 36.959746] mmc (null): Error, request_key -2 [ 36.964622] mmc0: Cannot find matching key [ 36.968765] mmc0: Card unlock failed. [ 36.972717] mmc0: new SDHC card at address 0002 [ 36.977747] mmcblk0: mmc0:0002 0 7.41 GiB [ 36.989596] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 36.999630] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.009604] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.019574] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.029548] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.039514] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.046729] end_request: I/O error, dev mmcblk0, sector 15556480 [ 37.052813] Buffer I/O error on device mmcblk0, logical block 1944560 [ 37.062139] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.072106] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.082072] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 . [ 46.249273] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 46.259247] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 46.269215] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 46.279183] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 46.289151] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 As a workaround, skip all the regular block io operations if the card is locked. One can unlock the card after system boot by following below steps 1) Add key for this card. 2) Unlock the card using sysfs attribute 'unlock_retry' for this card. Cc: Al Cooper alcoop...@gmail.com Cc: Chris Ball c...@laptop.org Signed-off-by: Abbas Raza abbas_r...@mentor.com --- drivers/mmc/card/block.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 5650748..79c8861 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -2026,6 +2026,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) /* claim host only for the first request */ mmc_get_card(card); + if (mmc_card_locked(card)) { + if (req) + blk_end_request_all(req, 0); + ret = 0; + goto out; + } + ret = mmc_blk_part_switch(card, md); if (ret) { if (req) { -- 1.9.0.138.g2de3478 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH RESEND v7 2/2] mmc: host: sdhci: Add support to disable SDR104/SDR50/DDR50 based on capability register 0.
On Mon, Jun 01, 2015 at 01:38:47PM +0530, Suman Tripathi wrote: Hi Aisheng, On Wed, May 27, 2015 at 7:46 PM, Suman Tripathi [1]stripa...@apm.com wrote: On Tue, May 26, 2015 at 6:06 PM, Ulf Hansson [2]ulf.hans...@linaro.org wrote: On 21 May 2015 at 10:43, Suman Tripathi [3]stripa...@apm.com wrote: The sdhci framework disables SDR104/SDR50/DDR50 based on only quirk. This patch adds the support to disable SDR104/SDR50/DDR50 based on reading the capability register 0. Signed-off-by: Suman Tripathi [4]stripa...@apm.com --- --- drivers/mmc/host/sdhci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 58c1770..a3d9b8a 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -3118,7 +3118,8 @@ int sdhci_add_host(struct sdhci_host *host) } } - if (host-quirks2 SDHCI_QUIRK2_NO_1_8_V) + if (host-quirks2 SDHCI_QUIRK2_NO_1_8_V || + !(caps[0] SDHCI_CAN_VDD_180)) caps[1] = ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50); -- 1.8.2.1 I have no problem with this patch, except that it would be nice to get a few tested by to make sure it doesn't break UHS support for some SoCs. Kind regards Uffe Can anyone test this in some other SoC ? Appreciate your help .. Can you test this patch on imx SoC ? (Your email have some format issue.) I have tested this patch and it does not break imx SoC. You can add my tag. Tested-by: Dong Aisheng aisheng.d...@freescale.com However, it looks to me SDHCI_CAN_VDD_180 is only indicating the host VDD capabiliies, not IO voltage capability. SD3.0 cards require 1.8v IO voltage support. So should this bit affect SD3.0 support? e.g. some hosts can only work at VDD_330 (most VDD of SD slot on IMX boards is using external regulator and is fixed to 3.3v), but it can support 1.8v IO voltage, so it can support SD3.0 cards as well. Ulf, Can you help confirm it? Regards Dong Aisheng -- Thanks, with regards, Suman Tripathi -- Thanks, with regards, Suman Tripathi References Visible links 1. mailto:stripa...@apm.com 2. mailto:ulf.hans...@linaro.org 3. mailto:stripa...@apm.com 4. mailto:stripa...@apm.com perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = (unset), LC_ALL = (unset), LC_TIME = zh_CN.UTF-8, LC_MONETARY = zh_CN.UTF-8, LC_ADDRESS = zh_CN.UTF-8, LC_TELEPHONE = zh_CN.UTF-8, LC_NAME = zh_CN.UTF-8, LC_MEASUREMENT = zh_CN.UTF-8, LC_IDENTIFICATION = zh_CN.UTF-8, LC_NUMERIC = zh_CN.UTF-8, LC_PAPER = zh_CN.UTF-8, LANG = en_US.UTF-8 are supported and installed on your system. perl: warning: Falling back to the standard locale (C). -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] mmc: enable Enhance Strobe for HS400.
Hi Sun, Did you get to test this feature on any of the target? On Fri, Jun 5, 2015 at 8:20 AM, Yi Sun yi.y@intel.com wrote: Enhance Strobe is defined in v5.1 eMMC spec. This commit is to implement it. Normal Strobe signal for HS400 is only provided during Data Out and CRC Response. While Enhance Strobe is enabled, Strobe signal is provided during Data Out, CRC Response and CMD Response. While enabling Enhance Strobe, the initialization of HS400 does not need enabling HS200 and executing tuning anymore. If enhanced strobe is enabled, what about SDHCI_NEEDS_RETUNING flag ? In case of CRC error, we do execute tuning, but now after support of enhanced strobe, how will that be taken care of? This simplifies the HS400 initialization process much. Per spec, there is a STROBE_SUPPORT added in EXT_CSD register to indicate that card supports Enhance Strobe or not. If it is supported, host can enable this feature by enabling the most significant bit of BUS_WIDTH before set HS_TIMING to HS400. enhanced strobe feature also requires support from host controller side as well. Dont you think we should provide some ops here for that? Signed-off-by: Yi Sun yi.y@intel.com --- drivers/mmc/core/mmc.c | 61 ++ include/linux/mmc/card.h |1 + include/linux/mmc/mmc.h |2 ++ 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index e519e31..c9ef2de 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -585,6 +585,12 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) card-ext_csd.ffu_capable = (ext_csd[EXT_CSD_SUPPORTED_MODE] 0x1) !(ext_csd[EXT_CSD_FW_CONFIG] 0x1); + + /* Enhance Strobe is supported since v5.1 which rev should be +* 8 but some eMMC devices can support it with rev 7. So handle +* Enhance Strobe here. +*/ + card-ext_csd.strobe_support = ext_csd[EXT_CSD_STROBE_SUPPORT]; } out: return err; @@ -1049,9 +1055,28 @@ static int mmc_select_hs400(struct mmc_card *card) /* * HS400 mode requires 8-bit bus width */ comment not valid? - if (!(card-mmc_avail_type EXT_CSD_CARD_TYPE_HS400 - host-ios.bus_width == MMC_BUS_WIDTH_8)) - return 0; + if (card-ext_csd.strobe_support) { + if (!(card-mmc_avail_type EXT_CSD_CARD_TYPE_HS400 + host-caps MMC_CAP_8_BIT_DATA)) + return 0; + + /* For Enhance Strobe flow. For non Enhance Strobe, signal +* voltage will not be set. +*/ + if (card-mmc_avail_type EXT_CSD_CARD_TYPE_HS200_1_2V) + err = __mmc_set_signal_voltage(host, + MMC_SIGNAL_VOLTAGE_120); + + if (err card-mmc_avail_type EXT_CSD_CARD_TYPE_HS200_1_8V) + err = __mmc_set_signal_voltage(host, + MMC_SIGNAL_VOLTAGE_180); + if (err) + return err; + } else { + if (!(card-mmc_avail_type EXT_CSD_CARD_TYPE_HS400 + host-ios.bus_width == MMC_BUS_WIDTH_8)) + return 0; + } /* * Before switching to dual data rate operation for HS400, @@ -1072,15 +1097,36 @@ static int mmc_select_hs400(struct mmc_card *card) return err; } + val = EXT_CSD_DDR_BUS_WIDTH_8; + if (card-ext_csd.strobe_support) + val |= EXT_CSD_BUS_WIDTH_STROBE; err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, -EXT_CSD_DDR_BUS_WIDTH_8, +val, card-ext_csd.generic_cmd6_time); if (err) { pr_err(%s: switch to bus width for hs400 failed, err:%d\n, mmc_hostname(host), err); return err; } + if (card-ext_csd.strobe_support) { + mmc_set_bus_width(host, MMC_BUS_WIDTH_8); + /* +* If controller can't handle bus width test, +* compare ext_csd previously read in 1 bit mode +* against ext_csd at new bus width +*/ + if (!(host-caps MMC_CAP_BUS_WIDTH_TEST)) + err = mmc_compare_ext_csds(card, MMC_BUS_WIDTH_8); + else + err = mmc_bus_test(card, MMC_BUS_WIDTH_8); + + if (err) { + pr_warn(%s: switch to bus width %d failed\n, + mmc_hostname(host), MMC_BUS_WIDTH_8); +