From 72dd8bc4d05f41b3bc93515657c9835b4c305367 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Tue, 13 Jan 2026 16:06:34 +0000 Subject: [PATCH] sdmmc_host: implement sd_enable() This is mainly useful for bootloaders that want to safely disable the SD/MMC controller before booting. Disabling a controller will reset and power down the bus; all attempts to read or write to a disabled controller will fail. Change-Id: I4a7ec4287f2b8510a35d964cc806c74be8c86406 --- firmware/drivers/sdmmc_host.c | 34 ++++++++++++++++++++++++++++++++++ firmware/export/sdmmc_host.h | 1 + 2 files changed, 35 insertions(+) diff --git a/firmware/drivers/sdmmc_host.c b/firmware/drivers/sdmmc_host.c index e7110c64d1..c012731a7e 100644 --- a/firmware/drivers/sdmmc_host.c +++ b/firmware/drivers/sdmmc_host.c @@ -114,6 +114,7 @@ void sdmmc_host_init(struct sdmmc_host *host, host->ops = ops; host->controller = controller; host->present = !config->is_removable; + host->enabled = true; mutex_init(&host->lock); array[i] = host; @@ -188,6 +189,26 @@ static void sdmmc_host_bus_reset(struct sdmmc_host *host) memset(&host->cardinfo, 0, sizeof(host->cardinfo)); } +/* + * Call to enable/disable the host controller. If disabled then the + * controller and device are powered off and no access to the storage + * device is allowed. + */ +static void sdmmc_host_set_enabled(struct sdmmc_host *host, bool enabled) +{ + mutex_lock(&host->lock); + + if (enabled != host->enabled) + { + if (host->enabled) + sdmmc_host_bus_reset(host); + + host->enabled = enabled; + } + + mutex_unlock(&host->lock); +} + #ifdef HAVE_HOTSWAP static void sdmmc_host_hotswap_event(struct sdmmc_host *host, bool is_present) { @@ -629,6 +650,9 @@ static int sdmmc_host_transfer(struct sdmmc_host *host, mutex_lock(&host->lock); + if (!host->enabled) + goto out; + if (!sdmmc_host_medium_present(host)) goto out; @@ -721,6 +745,16 @@ tCardInfo *card_get_info_target(int drive) return &sdmmc_sd_hosts[drive]->cardinfo; } +void sd_enable(bool enabled) +{ + for (size_t i = 0; i < ARRAYLEN(sdmmc_sd_hosts); ++i) + { + struct sdmmc_host *host = sdmmc_sd_hosts[i]; + + sdmmc_host_set_enabled(host, enabled); + } +} + long sd_last_disk_activity(void) { return sdmmc_sd_last_activity; diff --git a/firmware/export/sdmmc_host.h b/firmware/export/sdmmc_host.h index 7aa48e5f9e..1d00c94a27 100644 --- a/firmware/export/sdmmc_host.h +++ b/firmware/export/sdmmc_host.h @@ -231,6 +231,7 @@ struct sdmmc_host struct mutex lock; /* Bus & device state flags; must only be accessed with lock held */ + bool enabled : 1; bool need_reset : 1; bool powered : 1; bool initialized : 1;