--- linux-3.8.7.orig/drivers/mmc/card/block.c	2013-04-12 18:52:28.000000000 +0200
+++ linux-3.8.7/drivers/mmc/card/block.c	2013-05-27 10:05:58.000630168 +0200
@@ -761,7 +761,7 @@
 	u32 status, stop_status = 0;
 	int err, retry;
 
-	if (mmc_card_removed(card))
+	if (mmc_card_removed(card) || mmc_card_locked(card))
 		return ERR_NOMEDIUM;
 
 	/*
@@ -1363,6 +1363,7 @@
 			areq = &mq->mqrq_cur->mmc_active;
 		} else
 			areq = NULL;
+
 		areq = mmc_start_req(card->host, areq, (int *) &status);
 		if (!areq)
 			return 0;
@@ -1453,7 +1454,7 @@
 	return 1;
 
  cmd_abort:
-	if (mmc_card_removed(card))
+	if (mmc_card_removed(card) || mmc_card_locked(card))
 		req->cmd_flags |= REQ_QUIET;
 	while (ret)
 		ret = blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
@@ -1586,6 +1587,13 @@
 	if (area_type & MMC_BLK_DATA_AREA_RPMB)
 		md->disk->flags |= GENHD_FL_NO_PART_SCAN;
 
+	/* If SD/MMC is locked, any read operation will fail
+	 * so there is no point in doing a partition scan
+	 * until the device is unlocked.
+	 */
+	if (mmc_card_locked(card))
+		md->disk->flags |= GENHD_FL_NO_PART_SCAN;
+
 	/*
 	 * As discussed on lkml, GENHD_FL_REMOVABLE should:
 	 *
@@ -1652,6 +1660,7 @@
 		 */
 		size = card->csd.capacity << (card->csd.read_blkbits - 9);
 	}
+
 
 	md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL,
 					MMC_BLK_DATA_AREA_MAIN);
@@ -1877,9 +1886,10 @@
 
 	string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2,
 			cap_str, sizeof(cap_str));
-	pr_info("%s: %s %s %s %s\n",
+	pr_info("%s: %s %s %s %s %s\n",
 		md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
-		cap_str, md->read_only ? "(ro)" : "");
+		cap_str, md->read_only ? "(ro)" : "",
+		mmc_card_locked(card) ? "(locked)" : "");
 
 	if (mmc_blk_alloc_parts(card, md))
 		goto out;
--- linux-3.8.7.orig/drivers/mmc/core/sd.c	2013-04-12 18:52:28.000000000 +0200
+++ linux-3.8.7/drivers/mmc/core/sd.c	2013-05-27 10:04:56.568770589 +0200
@@ -796,8 +796,30 @@
 	bool reinit)
 {
 	int err;
+	int status;
 
-	if (!reinit) {
+	/*
+	 * Test if card is locked
+	 */
+	err = mmc_send_status(card, &status);
+	if (err)
+		return err;
+
+	if (status & R1_CARD_IS_LOCKED)
+		mmc_card_set_locked(card);
+	else {
+		/* If card used to be locked, this is _not_ an reinit! */
+		if (mmc_card_locked(card))
+			reinit = false;
+
+		mmc_card_clr_locked(card);
+	}
+
+	/*
+	 * If card is locked or already initialized, do not try to
+	 * set it up further .
+	 */
+	if (!reinit && !mmc_card_locked(card)) {
 		/*
 		 * Fetch SCR from card.
 		 */
--- linux-3.8.7.orig/include/linux/mmc/card.h	2013-04-12 18:52:28.000000000 +0200
+++ linux-3.8.7/include/linux/mmc/card.h	2013-05-27 10:03:39.828834488 +0200
@@ -233,6 +233,7 @@
 #define MMC_CARD_REMOVED	(1<<7)		/* card has been removed */
 #define MMC_STATE_HIGHSPEED_200	(1<<8)		/* card is in HS200 mode */
 #define MMC_STATE_DOING_BKOPS	(1<<10)		/* card is doing BKOPS */
+#define MMC_STATE_LOCKED	(1<<11)		/* card is password protected */
 	unsigned int		quirks; 	/* card quirks */
 #define MMC_QUIRK_LENIENT_FN0	(1<<0)		/* allow SDIO FN0 writes outside of the VS CCCR range */
 #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)	/* use func->cur_blksize */
@@ -395,6 +396,7 @@
 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
 #define mmc_card_removed(c)	((c) && ((c)->state & MMC_CARD_REMOVED))
 #define mmc_card_doing_bkops(c)	((c)->state & MMC_STATE_DOING_BKOPS)
+#define mmc_card_locked(c)	((c)->state & MMC_STATE_LOCKED)
 
 #define mmc_card_set_present(c)	((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
@@ -408,6 +410,8 @@
 #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
 #define mmc_card_set_doing_bkops(c)	((c)->state |= MMC_STATE_DOING_BKOPS)
 #define mmc_card_clr_doing_bkops(c)	((c)->state &= ~MMC_STATE_DOING_BKOPS)
+#define mmc_card_set_locked(c)	((c)->state |= MMC_STATE_LOCKED)
+#define mmc_card_clr_locked(c)	((c)->state &= ~MMC_STATE_LOCKED)
 
 /*
  * Quirk add/remove for MMC products.
