aboutsummaryrefslogtreecommitdiff
path: root/sys/cam/mmc/mmc_xpt.c
diff options
context:
space:
mode:
authorIlya Bakulin <kibab@FreeBSD.org>2018-06-19 20:02:03 +0000
committerIlya Bakulin <kibab@FreeBSD.org>2018-06-19 20:02:03 +0000
commite8e5c7641943fb2f14d15dfc669316f75b470552 (patch)
tree9d6a83352168c1bfcc9cca2feaa48d7ab4d5f34b /sys/cam/mmc/mmc_xpt.c
parent6b82569f2d7e692b05771660d3ffd29bc9b38e53 (diff)
downloadsrc-e8e5c7641943fb2f14d15dfc669316f75b470552.tar.gz
src-e8e5c7641943fb2f14d15dfc669316f75b470552.zip
Fix setting RCA for MMC cards
Unlike SD cards, that publish RCA in response to CMD3, MMC cards expect the host to set RCA itself. Since we don't support multiple MMC cards on the bus, just assign a static RCA of 2 to the attached MMC card. Approved by: imp (mentor) Differential Revision: https://reviews.freebsd.org/D13063
Notes
Notes: svn path=/head/; revision=335384
Diffstat (limited to 'sys/cam/mmc/mmc_xpt.c')
-rw-r--r--sys/cam/mmc/mmc_xpt.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/sys/cam/mmc/mmc_xpt.c b/sys/cam/mmc/mmc_xpt.c
index 00fa9b85ff72..745ec5a22d3d 100644
--- a/sys/cam/mmc/mmc_xpt.c
+++ b/sys/cam/mmc/mmc_xpt.c
@@ -98,7 +98,8 @@ typedef enum {
PROBE_GET_CID,
PROBE_GET_CSD,
PROBE_SEND_RELATIVE_ADDR,
- PROBE_SELECT_CARD,
+ PROBE_MMC_SET_RELATIVE_ADDR,
+ PROBE_SELECT_CARD,
PROBE_DONE,
PROBE_INVALID
} probe_action;
@@ -114,6 +115,7 @@ static char *probe_action_text[] = {
"PROBE_GET_CID",
"PROBE_GET_CSD",
"PROBE_SEND_RELATIVE_ADDR",
+ "PROBE_MMC_SET_RELATIVE_ADDR",
"PROBE_SELECT_CARD",
"PROBE_DONE",
"PROBE_INVALID"
@@ -702,7 +704,6 @@ mmcprobe_start(struct cam_periph *periph, union ccb *start_ccb)
mmcio->cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
mmcio->stop.opcode = 0;
break;
-
case PROBE_SEND_RELATIVE_ADDR:
init_standard_ccb(start_ccb, XPT_MMC_IO);
mmcio->cmd.opcode = SD_SEND_RELATIVE_ADDR;
@@ -710,6 +711,13 @@ mmcprobe_start(struct cam_periph *periph, union ccb *start_ccb)
mmcio->cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
mmcio->stop.opcode = 0;
break;
+ case PROBE_MMC_SET_RELATIVE_ADDR:
+ init_standard_ccb(start_ccb, XPT_MMC_IO);
+ mmcio->cmd.opcode = MMC_SET_RELATIVE_ADDR;
+ mmcio->cmd.arg = MMC_PROPOSED_RCA << 16;
+ mmcio->cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+ mmcio->stop.opcode = 0;
+ break;
case PROBE_SELECT_CARD:
init_standard_ccb(start_ccb, XPT_MMC_IO);
mmcio->cmd.opcode = MMC_SELECT_CARD;
@@ -985,7 +993,10 @@ mmcprobe_done(struct cam_periph *periph, union ccb *done_ccb)
mmcp->card_cid[1],
mmcp->card_cid[2],
mmcp->card_cid[3]));
- PROBE_SET_ACTION(softc, PROBE_SEND_RELATIVE_ADDR);
+ if (mmcp->card_features & CARD_FEATURE_MMC)
+ PROBE_SET_ACTION(softc, PROBE_MMC_SET_RELATIVE_ADDR);
+ else
+ PROBE_SET_ACTION(softc, PROBE_SEND_RELATIVE_ADDR);
break;
}
case PROBE_SEND_RELATIVE_ADDR: {
@@ -1010,6 +1021,18 @@ mmcprobe_done(struct cam_periph *periph, union ccb *done_ccb)
PROBE_SET_ACTION(softc, PROBE_SELECT_CARD);
break;
}
+ case PROBE_MMC_SET_RELATIVE_ADDR:
+ mmcio = &done_ccb->mmcio;
+ err = mmcio->cmd.error;
+ if (err != MMC_ERR_NONE) {
+ CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_PROBE,
+ ("PROBE_MMC_SET_RELATIVE_ADDR: error %d\n", err));
+ PROBE_SET_ACTION(softc, PROBE_INVALID);
+ break;
+ }
+ path->device->mmc_ident_data.card_rca = MMC_PROPOSED_RCA;
+ PROBE_SET_ACTION(softc, PROBE_GET_CSD);
+ break;
case PROBE_GET_CSD: {
mmcio = &done_ccb->mmcio;
err = mmcio->cmd.error;