|
@@ -172,7 +172,79 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries
|
|
|
|
|
|
EXPORT_SYMBOL(mmc_wait_for_cmd);
|
|
EXPORT_SYMBOL(mmc_wait_for_cmd);
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * mmc_wait_for_app_cmd - start an application command and wait for
|
|
|
|
+ completion
|
|
|
|
+ * @host: MMC host to start command
|
|
|
|
+ * @rca: RCA to send MMC_APP_CMD to
|
|
|
|
+ * @cmd: MMC command to start
|
|
|
|
+ * @retries: maximum number of retries
|
|
|
|
+ *
|
|
|
|
+ * Sends a MMC_APP_CMD, checks the card response, sends the command
|
|
|
|
+ * in the parameter and waits for it to complete. Return any error
|
|
|
|
+ * that occurred while the command was executing. Do not attempt to
|
|
|
|
+ * parse the response.
|
|
|
|
+ */
|
|
|
|
+int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca,
|
|
|
|
+ struct mmc_command *cmd, int retries)
|
|
|
|
+{
|
|
|
|
+ struct mmc_request mrq;
|
|
|
|
+ struct mmc_command appcmd;
|
|
|
|
+
|
|
|
|
+ int i, err;
|
|
|
|
+
|
|
|
|
+ BUG_ON(host->card_busy == NULL);
|
|
|
|
+ BUG_ON(retries < 0);
|
|
|
|
+
|
|
|
|
+ err = MMC_ERR_INVALID;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * We have to resend MMC_APP_CMD for each attempt so
|
|
|
|
+ * we cannot use the retries field in mmc_command.
|
|
|
|
+ */
|
|
|
|
+ for (i = 0;i <= retries;i++) {
|
|
|
|
+ memset(&mrq, 0, sizeof(struct mmc_request));
|
|
|
|
+
|
|
|
|
+ appcmd.opcode = MMC_APP_CMD;
|
|
|
|
+ appcmd.arg = rca << 16;
|
|
|
|
+ appcmd.flags = MMC_RSP_R1;
|
|
|
|
+ appcmd.retries = 0;
|
|
|
|
+ memset(appcmd.resp, 0, sizeof(appcmd.resp));
|
|
|
|
+ appcmd.data = NULL;
|
|
|
|
+
|
|
|
|
+ mrq.cmd = &appcmd;
|
|
|
|
+ appcmd.data = NULL;
|
|
|
|
+
|
|
|
|
+ mmc_wait_for_req(host, &mrq);
|
|
|
|
+
|
|
|
|
+ if (appcmd.error) {
|
|
|
|
+ err = appcmd.error;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Check that card supported application commands */
|
|
|
|
+ if (!(appcmd.resp[0] & R1_APP_CMD))
|
|
|
|
+ return MMC_ERR_FAILED;
|
|
|
|
+
|
|
|
|
+ memset(&mrq, 0, sizeof(struct mmc_request));
|
|
|
|
+
|
|
|
|
+ memset(cmd->resp, 0, sizeof(cmd->resp));
|
|
|
|
+ cmd->retries = 0;
|
|
|
|
+
|
|
|
|
+ mrq.cmd = cmd;
|
|
|
|
+ cmd->data = NULL;
|
|
|
|
+
|
|
|
|
+ mmc_wait_for_req(host, &mrq);
|
|
|
|
|
|
|
|
+ err = cmd->error;
|
|
|
|
+ if (cmd->error == MMC_ERR_NONE)
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return err;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+EXPORT_SYMBOL(mmc_wait_for_app_cmd);
|
|
|
|
|
|
/**
|
|
/**
|
|
* __mmc_claim_host - exclusively claim a host
|
|
* __mmc_claim_host - exclusively claim a host
|
|
@@ -322,48 +394,70 @@ static void mmc_decode_cid(struct mmc_card *card)
|
|
|
|
|
|
memset(&card->cid, 0, sizeof(struct mmc_cid));
|
|
memset(&card->cid, 0, sizeof(struct mmc_cid));
|
|
|
|
|
|
- /*
|
|
|
|
- * The selection of the format here is guesswork based upon
|
|
|
|
- * information people have sent to date.
|
|
|
|
- */
|
|
|
|
- switch (card->csd.mmca_vsn) {
|
|
|
|
- case 0: /* MMC v1.? */
|
|
|
|
- case 1: /* MMC v1.4 */
|
|
|
|
- card->cid.manfid = UNSTUFF_BITS(resp, 104, 24);
|
|
|
|
- card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
|
|
|
|
- card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
|
|
|
|
- card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
|
|
|
|
- card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
|
|
|
|
- card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
|
|
|
|
- card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
|
|
|
|
- card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8);
|
|
|
|
- card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4);
|
|
|
|
- card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4);
|
|
|
|
- card->cid.serial = UNSTUFF_BITS(resp, 16, 24);
|
|
|
|
- card->cid.month = UNSTUFF_BITS(resp, 12, 4);
|
|
|
|
- card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997;
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 2: /* MMC v2.x ? */
|
|
|
|
- case 3: /* MMC v3.x ? */
|
|
|
|
- card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
|
|
|
|
- card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
|
|
|
|
- card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
|
|
|
|
- card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
|
|
|
|
- card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
|
|
|
|
- card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
|
|
|
|
- card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
|
|
|
|
- card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
|
|
|
|
- card->cid.serial = UNSTUFF_BITS(resp, 16, 32);
|
|
|
|
- card->cid.month = UNSTUFF_BITS(resp, 12, 4);
|
|
|
|
- card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997;
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- default:
|
|
|
|
- printk("%s: card has unknown MMCA version %d\n",
|
|
|
|
- mmc_hostname(card->host), card->csd.mmca_vsn);
|
|
|
|
- mmc_card_set_bad(card);
|
|
|
|
- break;
|
|
|
|
|
|
+ if (mmc_card_sd(card)) {
|
|
|
|
+ /*
|
|
|
|
+ * SD doesn't currently have a version field so we will
|
|
|
|
+ * have to assume we can parse this.
|
|
|
|
+ */
|
|
|
|
+ card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
|
|
|
|
+ card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
|
|
|
|
+ card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
|
|
|
|
+ card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
|
|
|
|
+ card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
|
|
|
|
+ card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
|
|
|
|
+ card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
|
|
|
|
+ card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4);
|
|
|
|
+ card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4);
|
|
|
|
+ card->cid.serial = UNSTUFF_BITS(resp, 24, 32);
|
|
|
|
+ card->cid.year = UNSTUFF_BITS(resp, 12, 8);
|
|
|
|
+ card->cid.month = UNSTUFF_BITS(resp, 8, 4);
|
|
|
|
+
|
|
|
|
+ card->cid.year += 2000; /* SD cards year offset */
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ /*
|
|
|
|
+ * The selection of the format here is based upon published
|
|
|
|
+ * specs from sandisk and from what people have reported.
|
|
|
|
+ */
|
|
|
|
+ switch (card->csd.mmca_vsn) {
|
|
|
|
+ case 0: /* MMC v1.0 - v1.2 */
|
|
|
|
+ case 1: /* MMC v1.4 */
|
|
|
|
+ card->cid.manfid = UNSTUFF_BITS(resp, 104, 24);
|
|
|
|
+ card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
|
|
|
|
+ card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
|
|
|
|
+ card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
|
|
|
|
+ card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
|
|
|
|
+ card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
|
|
|
|
+ card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
|
|
|
|
+ card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8);
|
|
|
|
+ card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4);
|
|
|
|
+ card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4);
|
|
|
|
+ card->cid.serial = UNSTUFF_BITS(resp, 16, 24);
|
|
|
|
+ card->cid.month = UNSTUFF_BITS(resp, 12, 4);
|
|
|
|
+ card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 2: /* MMC v2.0 - v2.2 */
|
|
|
|
+ case 3: /* MMC v3.1 - v3.3 */
|
|
|
|
+ card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
|
|
|
|
+ card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
|
|
|
|
+ card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
|
|
|
|
+ card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
|
|
|
|
+ card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
|
|
|
|
+ card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
|
|
|
|
+ card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
|
|
|
|
+ card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
|
|
|
|
+ card->cid.serial = UNSTUFF_BITS(resp, 16, 32);
|
|
|
|
+ card->cid.month = UNSTUFF_BITS(resp, 12, 4);
|
|
|
|
+ card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ printk("%s: card has unknown MMCA version %d\n",
|
|
|
|
+ mmc_hostname(card->host), card->csd.mmca_vsn);
|
|
|
|
+ mmc_card_set_bad(card);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -376,34 +470,61 @@ static void mmc_decode_csd(struct mmc_card *card)
|
|
unsigned int e, m, csd_struct;
|
|
unsigned int e, m, csd_struct;
|
|
u32 *resp = card->raw_csd;
|
|
u32 *resp = card->raw_csd;
|
|
|
|
|
|
- /*
|
|
|
|
- * We only understand CSD structure v1.1 and v2.
|
|
|
|
- * v2 has extra information in bits 15, 11 and 10.
|
|
|
|
- */
|
|
|
|
- csd_struct = UNSTUFF_BITS(resp, 126, 2);
|
|
|
|
- if (csd_struct != 1 && csd_struct != 2) {
|
|
|
|
- printk("%s: unrecognised CSD structure version %d\n",
|
|
|
|
- mmc_hostname(card->host), csd_struct);
|
|
|
|
- mmc_card_set_bad(card);
|
|
|
|
- return;
|
|
|
|
|
|
+ if (mmc_card_sd(card)) {
|
|
|
|
+ csd_struct = UNSTUFF_BITS(resp, 126, 2);
|
|
|
|
+ if (csd_struct != 0) {
|
|
|
|
+ printk("%s: unrecognised CSD structure version %d\n",
|
|
|
|
+ mmc_hostname(card->host), csd_struct);
|
|
|
|
+ mmc_card_set_bad(card);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ m = UNSTUFF_BITS(resp, 115, 4);
|
|
|
|
+ e = UNSTUFF_BITS(resp, 112, 3);
|
|
|
|
+ csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
|
|
|
|
+ csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100;
|
|
|
|
+
|
|
|
|
+ m = UNSTUFF_BITS(resp, 99, 4);
|
|
|
|
+ e = UNSTUFF_BITS(resp, 96, 3);
|
|
|
|
+ csd->max_dtr = tran_exp[e] * tran_mant[m];
|
|
|
|
+ csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
|
|
|
|
+
|
|
|
|
+ e = UNSTUFF_BITS(resp, 47, 3);
|
|
|
|
+ m = UNSTUFF_BITS(resp, 62, 12);
|
|
|
|
+ csd->capacity = (1 + m) << (e + 2);
|
|
|
|
+
|
|
|
|
+ csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
|
|
}
|
|
}
|
|
|
|
+ else {
|
|
|
|
+ /*
|
|
|
|
+ * We only understand CSD structure v1.1 and v1.2.
|
|
|
|
+ * v1.2 has extra information in bits 15, 11 and 10.
|
|
|
|
+ */
|
|
|
|
+ csd_struct = UNSTUFF_BITS(resp, 126, 2);
|
|
|
|
+ if (csd_struct != 1 && csd_struct != 2) {
|
|
|
|
+ printk("%s: unrecognised CSD structure version %d\n",
|
|
|
|
+ mmc_hostname(card->host), csd_struct);
|
|
|
|
+ mmc_card_set_bad(card);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
|
|
- csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4);
|
|
|
|
- m = UNSTUFF_BITS(resp, 115, 4);
|
|
|
|
- e = UNSTUFF_BITS(resp, 112, 3);
|
|
|
|
- csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
|
|
|
|
- csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100;
|
|
|
|
|
|
+ csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4);
|
|
|
|
+ m = UNSTUFF_BITS(resp, 115, 4);
|
|
|
|
+ e = UNSTUFF_BITS(resp, 112, 3);
|
|
|
|
+ csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
|
|
|
|
+ csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100;
|
|
|
|
|
|
- m = UNSTUFF_BITS(resp, 99, 4);
|
|
|
|
- e = UNSTUFF_BITS(resp, 96, 3);
|
|
|
|
- csd->max_dtr = tran_exp[e] * tran_mant[m];
|
|
|
|
- csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
|
|
|
|
|
|
+ m = UNSTUFF_BITS(resp, 99, 4);
|
|
|
|
+ e = UNSTUFF_BITS(resp, 96, 3);
|
|
|
|
+ csd->max_dtr = tran_exp[e] * tran_mant[m];
|
|
|
|
+ csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
|
|
|
|
|
|
- e = UNSTUFF_BITS(resp, 47, 3);
|
|
|
|
- m = UNSTUFF_BITS(resp, 62, 12);
|
|
|
|
- csd->capacity = (1 + m) << (e + 2);
|
|
|
|
|
|
+ e = UNSTUFF_BITS(resp, 47, 3);
|
|
|
|
+ m = UNSTUFF_BITS(resp, 62, 12);
|
|
|
|
+ csd->capacity = (1 + m) << (e + 2);
|
|
|
|
|
|
- csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
|
|
|
|
|
|
+ csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -536,6 +657,34 @@ static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
|
|
|
|
+{
|
|
|
|
+ struct mmc_command cmd;
|
|
|
|
+ int i, err = 0;
|
|
|
|
+
|
|
|
|
+ cmd.opcode = SD_APP_OP_COND;
|
|
|
|
+ cmd.arg = ocr;
|
|
|
|
+ cmd.flags = MMC_RSP_R3;
|
|
|
|
+
|
|
|
|
+ for (i = 100; i; i--) {
|
|
|
|
+ err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES);
|
|
|
|
+ if (err != MMC_ERR_NONE)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ err = MMC_ERR_TIMEOUT;
|
|
|
|
+
|
|
|
|
+ mmc_delay(10);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (rocr)
|
|
|
|
+ *rocr = cmd.resp[0];
|
|
|
|
+
|
|
|
|
+ return err;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Discover cards by requesting their CID. If this command
|
|
* Discover cards by requesting their CID. If this command
|
|
* times out, it is not an error; there are no further cards
|
|
* times out, it is not an error; there are no further cards
|
|
@@ -579,13 +728,28 @@ static void mmc_discover_cards(struct mmc_host *host)
|
|
|
|
|
|
card->state &= ~MMC_STATE_DEAD;
|
|
card->state &= ~MMC_STATE_DEAD;
|
|
|
|
|
|
- cmd.opcode = MMC_SET_RELATIVE_ADDR;
|
|
|
|
- cmd.arg = card->rca << 16;
|
|
|
|
- cmd.flags = MMC_RSP_R1;
|
|
|
|
|
|
+ if (host->mode == MMC_MODE_SD) {
|
|
|
|
+ mmc_card_set_sd(card);
|
|
|
|
|
|
- err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
|
|
|
|
- if (err != MMC_ERR_NONE)
|
|
|
|
- mmc_card_set_dead(card);
|
|
|
|
|
|
+ cmd.opcode = SD_SEND_RELATIVE_ADDR;
|
|
|
|
+ cmd.arg = 0;
|
|
|
|
+ cmd.flags = MMC_RSP_R1;
|
|
|
|
+
|
|
|
|
+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
|
|
|
|
+ if (err != MMC_ERR_NONE)
|
|
|
|
+ mmc_card_set_dead(card);
|
|
|
|
+ else
|
|
|
|
+ card->rca = cmd.resp[0] >> 16;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ cmd.opcode = MMC_SET_RELATIVE_ADDR;
|
|
|
|
+ cmd.arg = card->rca << 16;
|
|
|
|
+ cmd.flags = MMC_RSP_R1;
|
|
|
|
+
|
|
|
|
+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
|
|
|
|
+ if (err != MMC_ERR_NONE)
|
|
|
|
+ mmc_card_set_dead(card);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -669,12 +833,25 @@ static void mmc_setup(struct mmc_host *host)
|
|
int err;
|
|
int err;
|
|
u32 ocr;
|
|
u32 ocr;
|
|
|
|
|
|
|
|
+ host->mode = MMC_MODE_MMC;
|
|
|
|
+
|
|
mmc_power_up(host);
|
|
mmc_power_up(host);
|
|
mmc_idle_cards(host);
|
|
mmc_idle_cards(host);
|
|
|
|
|
|
err = mmc_send_op_cond(host, 0, &ocr);
|
|
err = mmc_send_op_cond(host, 0, &ocr);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * If we fail to detect any cards then try
|
|
|
|
+ * searching for SD cards.
|
|
|
|
+ */
|
|
if (err != MMC_ERR_NONE)
|
|
if (err != MMC_ERR_NONE)
|
|
- return;
|
|
|
|
|
|
+ {
|
|
|
|
+ err = mmc_send_app_op_cond(host, 0, &ocr);
|
|
|
|
+ if (err != MMC_ERR_NONE)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ host->mode = MMC_MODE_SD;
|
|
|
|
+ }
|
|
|
|
|
|
host->ocr = mmc_select_voltage(host, ocr);
|
|
host->ocr = mmc_select_voltage(host, ocr);
|
|
|
|
|
|
@@ -714,7 +891,10 @@ static void mmc_setup(struct mmc_host *host)
|
|
* all get the idea that they should be ready for CMD2.
|
|
* all get the idea that they should be ready for CMD2.
|
|
* (My SanDisk card seems to need this.)
|
|
* (My SanDisk card seems to need this.)
|
|
*/
|
|
*/
|
|
- mmc_send_op_cond(host, host->ocr, NULL);
|
|
|
|
|
|
+ if (host->mode == MMC_MODE_SD)
|
|
|
|
+ mmc_send_app_op_cond(host, host->ocr, NULL);
|
|
|
|
+ else
|
|
|
|
+ mmc_send_op_cond(host, host->ocr, NULL);
|
|
|
|
|
|
mmc_discover_cards(host);
|
|
mmc_discover_cards(host);
|
|
|
|
|