From a59f6b7a8cf6877ac1d79d0bd3381814f3061ce9 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Fri, 12 Mar 2021 14:31:32 +0100 Subject: [PATCH] mmc_bus: fix possible deadlock when initialization fails Should fix the remaining part of #16778 Change-Id: Ia148f4bde095d33752df788b8f7911ee9cf44c61 Reviewed-on: https://review.haiku-os.org/c/haiku/+/3773 Reviewed-by: Adrien Destugues --- .../kernel/bus_managers/mmc/mmc_bus.cpp | 19 +++++++++++++++---- src/add-ons/kernel/busses/mmc/sdhci_pci.cpp | 6 +++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/mmc/mmc_bus.cpp b/src/add-ons/kernel/bus_managers/mmc/mmc_bus.cpp index e8587eab00..c27999d9e5 100644 --- a/src/add-ons/kernel/bus_managers/mmc/mmc_bus.cpp +++ b/src/add-ons/kernel/bus_managers/mmc/mmc_bus.cpp @@ -49,16 +49,20 @@ MMCBus::~MMCBus() { CALLED(); - // stop worker thread + // Tell the worker thread we want to stop fStatus = B_SHUTTING_DOWN; + // Delete the semaphores (this will unlock the worker thread if it was + // waiting on them) + delete_sem(fScanSemaphore); + delete_sem(fLockSemaphore); + + // Wait for the worker thread to terminate status_t result; if (fWorkerThread != 0) wait_for_thread(fWorkerThread, &result); - // TODO power off cards, stop clock, etc if needed. - delete_sem(fLockSemaphore); - delete_sem(fScanSemaphore); + // TODO power off cards, stop clock, etc if needed. } @@ -159,6 +163,13 @@ MMCBus::_WorkerThread(void* cookie) do { bus->_AcquireScanSemaphore(); + // Check if we need to exit early (possible if the parent device did + // not manage initialize itself correctly) + if (bus->fStatus == B_SHUTTING_DOWN) { + release_sem(bus->fLockSemaphore); + return B_OK; + } + TRACE("Reset the bus...\n"); result = bus->ExecuteCommand(0, SD_GO_IDLE_STATE, 0, NULL); TRACE("CMD0 result: %s\n", strerror(result)); diff --git a/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp b/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp index 50b9e493c2..152956a978 100644 --- a/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp +++ b/src/add-ons/kernel/busses/mmc/sdhci_pci.cpp @@ -663,13 +663,13 @@ init_bus(device_node* node, void** bus_cookie) sPCIx86Module = NULL; ERROR("PCIx86Module not loaded\n"); // FIXME try probing FDT as well - return -1; + return B_NO_MEMORY; } uint8_t bar, slot; if (gDeviceManager->get_attr_uint8(node, SLOT_NUMBER, &slot, false) < B_OK || gDeviceManager->get_attr_uint8(node, BAR_INDEX, &bar, false) < B_OK) - return -1; + return B_BAD_TYPE; // Ignore invalid bars TRACE("Register SD bus at slot %d, using bar %d\n", slot + 1, bar); @@ -679,7 +679,7 @@ init_bus(device_node* node, void** bus_cookie) if (pciInfo.u.h0.base_register_sizes[bar] == 0) { ERROR("No registers to map\n"); - return -1; + return B_IO_ERROR; } int msiCount = sPCIx86Module->get_msi_count(pciInfo.bus,