Re: [PATCH 2/2] mmc: esdhc: add quirk to support 3.3v for T4240

2015-06-05 Thread Ulf Hansson
[...]

 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

2015-06-05 Thread Ulf Hansson
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

2015-06-05 Thread Ulf Hansson
[...]

  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

2015-06-05 Thread Ulf Hansson
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

2015-06-05 Thread Ulf Hansson
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

2015-06-05 Thread Ulf Hansson
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

2015-06-05 Thread Borislav Petkov
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

2015-06-05 Thread Ulf Hansson
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 Thread Wan ZongShun
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

2015-06-05 Thread Ulf Hansson
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

2015-06-05 Thread Borislav Petkov
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

2015-06-05 Thread Al Cooper
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

2015-06-05 Thread Al Cooper
- 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

2015-06-05 Thread Al Cooper
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.

2015-06-05 Thread Al Cooper
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

2015-06-05 Thread Al Cooper
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.

2015-06-05 Thread Al Cooper
- 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

2015-06-05 Thread Al Cooper
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

2015-06-05 Thread Al Cooper
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

2015-06-05 Thread Al Cooper
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.

2015-06-05 Thread Dong Aisheng
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.

2015-06-05 Thread Ritesh Harjani
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);
 +