Skip to contentSkip to conversation

Add MMC password protection (lock/unlock) support V3

PATCH In review Anderson Briglia 3 participants 7 messages Jan 9, 2006 – Jan 11, 2006 MMC, SD and SDIO

lore
Share & tools
lore
#0 lore raw

PATCH 1/5 Add MMC password protection (lock/unlock) support V3

When a card is locked, only commands from the "basic" and "lock card" classes are accepted. To be able to use the other commands, the card must be unlocked first.

This patch prevents the block driver from trying to run privileged class commands on locked MMC cards, which will fail anyway.

drivers/mmc/mmc.c +7 -2
Index: linux-2.6.15-rc4/drivers/mmc/mmc.c
===================================================================
@@ -986,10 +986,15 @@ static void mmc_check_cards(struct mmc_h
 		cmd.flags = MMC_RSP_R1;
 
 		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-		if (err == MMC_ERR_NONE)
+		if (err != MMC_ERR_NONE) {
+			mmc_card_set_dead(card);
 			continue;
+		}
 
-		mmc_card_set_dead(card);
+		if (cmd.resp[0] & R1_CARD_IS_LOCKED)
+			mmc_card_set_locked(card);
+		else
+			card->state &= ~MMC_STATE_LOCKED;
 	}
 }
 
drivers/mmc/mmc_sysfs.c +13 -3
Index: linux-2.6.15-rc4/drivers/mmc/mmc_sysfs.c
===================================================================
@@ -16,6 +16,7 @@
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/protocol.h>
 
 #include "mmc.h"
 
@@ -69,13 +70,22 @@ static void mmc_release_card(struct devi
 }
 
 /*
- * This currently matches any MMC driver to any MMC card - drivers
- * themselves make the decision whether to drive this card in their
- * probe method.  However, we force "bad" cards to fail.
+ * This currently matches any MMC driver to any MMC card - drivers themselves
+ * make the decision whether to drive this card in their probe method.
+ * However, we force "bad" cards to fail.
+ *
+ * We also fail for all locked cards; drivers expect to be able to do block
+ * I/O still on probe(), which is not possible while the card is locked.
+ * Device probing must be triggered sometime later to make the card available
+ * to the block driver.
  */
 static int mmc_bus_match(struct device *dev, struct device_driver *drv)
 {
 	struct mmc_card *card = dev_to_mmc_card(dev);
+	if (mmc_card_lockable(card) && mmc_card_locked(card)) {
+		dev_dbg(&card->dev, "card is locked; binding is deferred\n");
+		return 0;
+	}
 	return !mmc_card_bad(card);
 }
 
include/linux/mmc/card.h +5 -0
Index: linux-2.6.15-rc4/include/linux/mmc/card.h
===================================================================
@@ -56,6 +56,7 @@ struct mmc_card {
 #define MMC_STATE_BAD		(1<<2)		/* unrecognised device */
 #define MMC_STATE_SDCARD	(1<<3)		/* is an SD card */
 #define MMC_STATE_READONLY	(1<<4)		/* card is read-only */
+#define MMC_STATE_LOCKED	(1<<5)		/* card is currently locked */
 	u32			raw_cid[4];	/* raw card CID */
 	u32			raw_csd[4];	/* raw card CSD */
 	u32			raw_scr[2];	/* raw card SCR */
@@ -69,12 +70,16 @@ struct mmc_card {
 #define mmc_card_bad(c)		((c)->state & MMC_STATE_BAD)
 #define mmc_card_sd(c)		((c)->state & MMC_STATE_SDCARD)
 #define mmc_card_readonly(c)	((c)->state & MMC_STATE_READONLY)
+#define mmc_card_locked(c)	((c)->state & MMC_STATE_LOCKED)
+
+#define mmc_card_lockable(c)	((c)->csd.cmdclass & CCC_LOCK_CARD)
 
 #define mmc_card_set_present(c)	((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_dead(c)	((c)->state |= MMC_STATE_DEAD)
 #define mmc_card_set_bad(c)	((c)->state |= MMC_STATE_BAD)
 #define mmc_card_set_sd(c)	((c)->state |= MMC_STATE_SDCARD)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
+#define mmc_card_set_locked(c)	((c)->state |= MMC_STATE_LOCKED)
 
 #define mmc_card_name(c)	((c)->cid.prod_name)
 #define mmc_card_id(c)		((c)->dev.bus_id)
#1 lore raw

Please send patches as text/plain - it makes it difficult to reply to them otherwise.

Quoted 3 lines · Anderson Briglia

When a card is locked, only commands from the "basic" and "lock card" classes are accepted. To be able to use the other commands, the card must be unlocked first.

I don't think this works as you intend.

When a card is initially inserted, we discover the cards via mmc_setup() and mmc_discover_cards(). This means that we'll never set the locked status for newly inserted cards.

Quoted 8 lines

===================================================================

drivers/mmc/mmc.c +0 -1
@@ -986,10 +986,15 @@ static void mmc_check_cards(struct mmc_h
 		cmd.flags = MMC_RSP_R1;
 
 		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-		if (err == MMC_ERR_NONE)

drivers/mmc/mmc.c static void mmc_check_cards(struct mmc_h · line 997

Quoted 10 lines
drivers/mmc/mmc.c +7 -1
+		if (err != MMC_ERR_NONE) {
+			mmc_card_set_dead(card);
 			continue;
+		}
 
-		mmc_card_set_dead(card);
+		if (cmd.resp[0] & R1_CARD_IS_LOCKED)
+			mmc_card_set_locked(card);
+		else
+			card->state &= ~MMC_STATE_LOCKED;

We need a mmc_card_clear_locked() here.

Signature · 3 lines
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 Serial core
#2 lore raw
Quoted 9 lines · Russell King
Quoted 5 lines · Anderson Briglia

When a card is locked, only commands from the "basic" and "lock card" classes are accepted. To be able to use the other commands, the card must be unlocked first.

Quoted 7 lines

I don't think this works as you intend.

When a card is initially inserted, we discover the cards via mmc_setup() and mmc_discover_cards(). This means that we'll never set the locked status for newly inserted cards.

mmc_setup() calls mmc_check_cards(). Our patch adds the necessary code to mmc_check_cards() to set the locked state when the card is locked.

Quoted 13 lines
Quoted 13 lines

===================================================================

drivers/mmc/mmc.c +3 -1
@@ -986,10 +986,15 @@ static void mmc_check_cards(struct mmc_h
 		cmd.flags = MMC_RSP_R1;
 
 		err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-		if (err == MMC_ERR_NONE)
+		if (err != MMC_ERR_NONE) {
+			mmc_card_set_dead(card);
 			continue;
+		}
 
Quoted 7 lines

drivers/mmc/mmc.c static void mmc_check_cards(struct mmc_h

Quoted 7 lines
drivers/mmc/mmc.c +4 -1
-		mmc_card_set_dead(card);
+		if (cmd.resp[0] & R1_CARD_IS_LOCKED)
+			mmc_card_set_locked(card);
+		else
+			card->state &= ~MMC_STATE_LOCKED;
 
 

Anderson Briglia
INdT - Manaus

#3 lore raw
Quoted 13 lines · Anderson Briglia
Quoted 11 lines · Russell King
Quoted 5 lines · Anderson Briglia

When a card is locked, only commands from the "basic" and "lock card" classes are accepted. To be able to use the other commands, the card must be unlocked first.

I don't think this works as you intend.

Quoted 7 lines
Quoted 5 lines

When a card is initially inserted, we discover the cards via mmc_setup() and mmc_discover_cards(). This means that we'll never set the locked status for newly inserted cards.

mmc_setup() calls mmc_check_cards(). Our patch adds the necessary code to mmc_check_cards() to set the locked state when the card is locked.

Not in Linus' kernel, it doesn't.

If you're working off the OMAP tree, bear in mind that I've found in the past that they have a large number of wrong or inappropriate changes to the MMC layer in there. They don't regularly merge either, and they certainly don't forward any bug fixes for review in a timely manner.

mmc_rescan() is the only caller of mmc_check_cards(), and this only happens if mmc_rescan() is called with the power already applied (iow, cards are already known to the MMC layer.)

This call is done _before_ we call mmc_setup() to discover new cards.

Calling mmc_check_cards() from mmc_rescan() is _wrong_, and from what I can ascertain, it's probably due to unforwarded broken changes in the OMAP tree.

Signature · 3 lines
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 Serial core
#4 lore raw
Quoted 22 lines · Russell King
Quoted 13 lines · Anderson Briglia
Quoted 11 lines · Russell King
Quoted 5 lines · Anderson Briglia

When a card is locked, only commands from the "basic" and "lock card" classes are accepted. To be able to use the other commands, the card must be unlocked first.

I don't think this works as you intend.

Quoted 7 lines
Quoted 5 lines

When a card is initially inserted, we discover the cards via mmc_setup() and mmc_discover_cards(). This means that we'll never set the locked status for newly inserted cards.

mmc_setup() calls mmc_check_cards(). Our patch adds the necessary code to mmc_check_cards() to set the locked state when the card is locked.

Quoted 7 lines

Not in Linus' kernel, it doesn't.

If you're working off the OMAP tree, bear in mind that I've found in the past that they have a large number of wrong or inappropriate changes to the MMC layer in there. They don't regularly merge either, and they certainly don't forward any bug fixes for review in a timely manner.

I agree the omap MMC driver should be cleaned-up and finally merged.

Anderson, since you are already patching it, do you want to take care of cleaning it up a bit and posting it here?

There are some mmc core hacks there for buggy cards that might worth testing on other platforms too. (It could also be that they are only needed on omap).

As far as I remember for omap we've had to do hacks for cards that claim to be ready before the data is transferred, and also hacks for cards that never set the ready bit...

Regards,

Tony

#5 lore raw
Quoted 37 lines · Tony Lindgren
Quoted 26 lines · Russell King
Quoted 15 lines · Anderson Briglia
Quoted 12 lines · Russell King
Quoted 5 lines · Anderson Briglia

When a card is locked, only commands from the "basic" and "lock card" classes are accepted. To be able to use the other commands, the card must be unlocked first.

I don't think this works as you intend.

Quoted 8 lines
Quoted 5 lines

When a card is initially inserted, we discover the cards via mmc_setup() and mmc_discover_cards(). This means that we'll never set the locked status for newly inserted cards.

mmc_setup() calls mmc_check_cards(). Our patch adds the necessary code to mmc_check_cards() to set the locked state when the card is locked.

Quoted 7 lines

Not in Linus' kernel, it doesn't.

If you're working off the OMAP tree, bear in mind that I've found in the past that they have a large number of wrong or inappropriate changes to the MMC layer in there. They don't regularly merge either, and they certainly don't forward any bug fixes for review in a timely manner.

Quoted 4 lines

I agree the omap MMC driver should be cleaned-up and finally merged.

Anderson, since you are already patching it, do you want to take care of cleaning it up a bit and posting it here?

OK Tony. I'll do it and post here asap.

Regards,

Anderson Briglia
INdT - Manaus

#6 lore raw
Quoted 38 lines · Anderson Briglia
Quoted 37 lines · Tony Lindgren
Quoted 33 lines · Russell King
Quoted 15 lines · Anderson Briglia
Quoted 12 lines · Russell King
Quoted 5 lines · Anderson Briglia

When a card is locked, only commands from the "basic" and "lock card" classes are accepted. To be able to use the other commands, the card must be unlocked first.

I don't think this works as you intend.

Quoted 8 lines
Quoted 5 lines

When a card is initially inserted, we discover the cards via mmc_setup() and mmc_discover_cards(). This means that we'll never set the locked status for newly inserted cards.

mmc_setup() calls mmc_check_cards(). Our patch adds the necessary code to mmc_check_cards() to set the locked state when the card is locked.

Not in Linus' kernel, it doesn't.

If you're working off the OMAP tree, bear in mind that I've found in the past that they have a large number of wrong or inappropriate changes to the MMC layer in there. They don't regularly merge either, and they certainly don't forward any bug fixes for review in a timely manner.

Quoted 6 lines
Quoted 4 lines

I agree the omap MMC driver should be cleaned-up and finally merged.

Anderson, since you are already patching it, do you want to take care of cleaning it up a bit and posting it here?

OK Tony. I'll do it and post here asap.

Cool, thanks!

Tony