sdhci: prepare for MMC EXT_SEND_CSD command

This is needed to handle MMC devices larger than 2GB. The protocol used
is different from how it's done in SDHC/SDXC.

Change-Id: I12edb1a4196c1e8f375886e9e5a5c1cef111e33c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/10929
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
PulkoMandy
2026-05-07 07:22:21 +00:00
committed by Adrien Destugues
parent 9e21efa6d8
commit 05b7380f79
2 changed files with 71 additions and 66 deletions
+9 -2
View File
@@ -31,9 +31,16 @@ typedef enum card_type {
// Commands for SD/eMMC cards defined in: // Commands for SD/eMMC cards defined in:
// SD: Physical Layer Simplified Specification Version 8.00 // SD: Physical Layer Simplified Specification Version 8.00
// eMMC: JEDEC Standard No. 84-B51. Sec 6.10.4 // eMMC: JEDEC Standard No. 84-B51. Sec 6.10.4
//
// They are in the common .h file for the mmc stack because the SDHCI driver // They are in the common .h file for the mmc stack because the SDHCI driver
// currently needs to map them to the corresponding expected response types. // currently needs to map them to the corresponding expected response types.
// card type prefix to distinguish non common commands. //
// TODO maybe it would be simpler to have the upper layers (the bus manager and mmc_disk) specify
// the expected response type when sending a command. This would avoid hardcoding command types
// and the corresponding response types in the command sending code.
//
// When the commands are specific to SD or MMC types, the constant is named with the corresponding
// prefix.
enum SD_COMMANDS { enum SD_COMMANDS {
// Basic commands, class 0 // Basic commands, class 0
GO_IDLE_STATE = 0, GO_IDLE_STATE = 0,
@@ -43,8 +50,8 @@ enum SD_COMMANDS {
SD_SEND_RELATIVE_ADDR = 3, SD_SEND_RELATIVE_ADDR = 3,
MMC_SET_RELATIVE_ADDR = 3, MMC_SET_RELATIVE_ADDR = 3,
SELECT_DESELECT_CARD = 7, SELECT_DESELECT_CARD = 7,
// resp can be R1 per mmc spec,keep R1b for now.
SD_SEND_IF_COND = 8, SD_SEND_IF_COND = 8,
MMC_SEND_EXT_CSD = 8,
SEND_CSD = 9, SEND_CSD = 9,
SD_STOP_TRANSMISSION = 12, SD_STOP_TRANSMISSION = 12,
+29 -31
View File
@@ -220,34 +220,46 @@ SdhciBus::ExecuteCommand(uint8_t command, uint32_t argument, uint32_t* response)
uint32_t replyType; uint32_t replyType;
uint16 transferMode = 0; uint16 transferMode = 0;
bool cmdResolved = false;
// Resolve replyType for card type specific commands.
if (fCardType == CARD_TYPE_MMC) {
if (command == MMC_SET_RELATIVE_ADDR) {
replyType = Command::kR1Type;
cmdResolved = true;
}
} else if (command == SD_SEND_RELATIVE_ADDR) {
replyType = Command::kR6Type;
cmdResolved = true;
}
if (cmdResolved == false) {
switch (command) { switch (command) {
// Basic reply types
case GO_IDLE_STATE: case GO_IDLE_STATE:
replyType = Command::kNoReplyType; replyType = Command::kNoReplyType;
break; break;
case ALL_SEND_CID: case SD_APP_CMD:
case SEND_CSD: case SD_ERASE_WR_BLK_START:
replyType = Command::kR2Type; case SD_ERASE_WR_BLK_END:
case SD_SET_BUS_WIDTH: // SD Application command
replyType = Command::kR1Type;
break; break;
case SELECT_DESELECT_CARD: case SELECT_DESELECT_CARD:
case SD_ERASE: case SD_ERASE:
replyType = Command::kR1bType; replyType = Command::kR1bType;
break; break;
case SD_SEND_IF_COND: case ALL_SEND_CID:
case SEND_CSD:
replyType = Command::kR2Type;
break;
case MMC_SEND_OP_COND:
case SD_SEND_OP_COND: // SD Application command
replyType = Command::kR3Type;
break;
// Commands defined with different reply types in SD and MMC specifications
case SD_SEND_RELATIVE_ADDR: // also MMC_SET_RELATIVE_ADDR
if (fCardType == CARD_TYPE_MMC)
replyType = Command::kR1Type;
else
replyType = Command::kR6Type;
break;
case SD_SEND_IF_COND: // also MMC_SEND_EXT_CSD
if (fCardType == CARD_TYPE_MMC)
replyType = Command::kR1Type;
else
replyType = Command::kR7Type; replyType = Command::kR7Type;
break; break;
// Commands with data transfer replies, also set transferMode
case SD_READ_SINGLE_BLOCK: case SD_READ_SINGLE_BLOCK:
transferMode = TransferMode::kRead | TransferMode::kDmaEnable; transferMode = TransferMode::kRead | TransferMode::kDmaEnable;
replyType = Command::kR1Type | Command::kDataPresent; replyType = Command::kR1Type | Command::kDataPresent;
@@ -268,25 +280,11 @@ SdhciBus::ExecuteCommand(uint8_t command, uint32_t argument, uint32_t* response)
| TransferMode::kDmaEnable; | TransferMode::kDmaEnable;
replyType = Command::kR1Type | Command::kDataPresent; replyType = Command::kR1Type | Command::kDataPresent;
break; break;
case SD_APP_CMD:
case SD_ERASE_WR_BLK_START:
case SD_ERASE_WR_BLK_END:
case SD_SET_BUS_WIDTH: // SD Application command
replyType = Command::kR1Type;
break;
case SD_SEND_OP_COND: // SD Application command
replyType = Command::kR3Type;
break;
// MMC / eMMC commands
case MMC_SEND_OP_COND:
// MMC/eMMC SEND_OP_COND command, CMD1.
replyType = Command::kR3Type;
break;
default: default:
ERROR("Unknown command %x\n", command); ERROR("Unknown command %x\n", command);
return B_BAD_DATA; return B_BAD_DATA;
} }
}
// Check if DATA line is available (if needed) // Check if DATA line is available (if needed)
if ((replyType & Command::k32BitResponseCheckBusy) != 0 if ((replyType & Command::k32BitResponseCheckBusy) != 0
&& command != SD_STOP_TRANSMISSION && command != SD_IO_ABORT) { && command != SD_STOP_TRANSMISSION && command != SD_IO_ABORT) {