Power off SD card if no voltage range support.
The goal is to handle `FIXME` within WorkerThread that of MMCBus. [+] Extended SDHCIBus to have: > private PowerOff() to clear corresponding VDD1 power bit. > Public TerminateBus() to terminate the bus powering off,disabling clock and interrupts. Also called within the destructor. [+] Extend `mmc_bus_interface` to encapsulate terminate_bus coping the same style of other interface utilities. [+] MMCBus can its newly added private _TerminateBus() for handling sd cards not supporting proposed voltage range. Testing: - used false invokation on qemu emulated sd card to test the termination branch. - Successfully built and run,SD card doesn't show up in DriveSetup - debug Log show correct power and clock bit setting(power=0xe, clock=0x800b). Please Guide me further on more effective test method. Change-Id: Icc8eeac97b9c96dfbf0106871d26a41d7faea5dc Reviewed-on: https://review.haiku-os.org/c/haiku/+/10622 Haiku-Format: Haiku-format Bot <[email protected]> Tested-by: Commit checker robot <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
ef2e71c652
commit
aaed8a220f
@@ -88,6 +88,8 @@ typedef struct mmc_bus_interface {
|
||||
// Pass the semaphore used for device rescan to the bus controller
|
||||
void (*set_bus_width)(void* controller, int width);
|
||||
// Set the data bus width to 1, 4 or 8 bit mode.
|
||||
void (*terminate_bus)(void* controller);
|
||||
// Terminate use of the underlying sdhci bus.
|
||||
} mmc_bus_interface;
|
||||
|
||||
|
||||
|
||||
@@ -61,8 +61,6 @@ MMCBus::~MMCBus()
|
||||
status_t result;
|
||||
if (fWorkerThread != 0)
|
||||
wait_for_thread(fWorkerThread, &result);
|
||||
|
||||
// TODO power off cards, stop clock, etc if needed.
|
||||
}
|
||||
|
||||
|
||||
@@ -144,6 +142,13 @@ void MMCBus::_AcquireScanSemaphore()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MMCBus::_TerminateBus()
|
||||
{
|
||||
fController->terminate_bus(fCookie);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MMCBus::_WorkerThread(void* cookie)
|
||||
{
|
||||
@@ -211,7 +216,9 @@ MMCBus::_WorkerThread(void* cookie)
|
||||
} else if (response != probe) {
|
||||
ERROR("Card does not support voltage range (expected %x, "
|
||||
"reply %x)\n", probe, response);
|
||||
// TODO we should power off the bus in this case.
|
||||
bus->_TerminateBus();
|
||||
release_sem(bus->fLockSemaphore);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// Probe OCR, waiting for card to become ready
|
||||
|
||||
@@ -55,6 +55,7 @@ public:
|
||||
private:
|
||||
status_t _ActivateDevice(uint16_t rca);
|
||||
void _AcquireScanSemaphore();
|
||||
void _TerminateBus();
|
||||
static status_t _WorkerThread(void*);
|
||||
|
||||
private:
|
||||
|
||||
@@ -149,7 +149,7 @@ SdhciBus::SdhciBus(struct registers* registers, uint8_t irq, bool poll)
|
||||
|
||||
SdhciBus::~SdhciBus()
|
||||
{
|
||||
DisableInterrupts();
|
||||
TerminateBus();
|
||||
|
||||
if (fIrq != 0)
|
||||
remove_io_interrupt_handler(fIrq, sdhci_generic_interrupt, this);
|
||||
@@ -605,6 +605,36 @@ SdhciBus::PowerOn()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SdhciBus::PowerOff()
|
||||
{
|
||||
fRegisters->power_control.PowerOff();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SdhciBus::TerminateBus()
|
||||
{
|
||||
CALLED();
|
||||
|
||||
DisableInterrupts();
|
||||
fRegisters->clock_control.DisableSD();
|
||||
PowerOff();
|
||||
/*
|
||||
// Debugging.
|
||||
uint8_t powerBits = fRegisters->power_control.Bits();
|
||||
uint16_t clockBits = fRegisters->clock_control.Bits();
|
||||
if ((powerBits & 0x1) != 0 || (clockBits & (1 << 2)) != 0) {
|
||||
ERROR("TerminateBus: Not killed. "
|
||||
"(power=%#x, clock=%#x)\n", powerBits, clockBits);
|
||||
} else {
|
||||
TRACE("TerminateBus: killed. (power=%#x, "
|
||||
"clock=%#x)\n", powerBits, clockBits);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SdhciBus::RecoverError()
|
||||
{
|
||||
@@ -904,6 +934,14 @@ set_bus_width(void* controller, int width)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
terminate_bus(void* controller)
|
||||
{
|
||||
SdhciBus* bus = (SdhciBus*)controller;
|
||||
bus->TerminateBus();
|
||||
}
|
||||
|
||||
|
||||
// Root device that binds to the ACPI or PCI bus. It will register an mmc_bus_interface
|
||||
// node for each SD slot in the device.
|
||||
static driver_module_info sSDHCIDevice = {
|
||||
|
||||
@@ -34,9 +34,11 @@ class SdhciBus {
|
||||
bool offsetAsSectors);
|
||||
void SetScanSemaphore(sem_id sem);
|
||||
void SetBusWidth(int width);
|
||||
void TerminateBus();
|
||||
|
||||
private:
|
||||
bool PowerOn();
|
||||
void PowerOff();
|
||||
void RecoverError();
|
||||
static status_t _WorkerThread(void*);
|
||||
|
||||
@@ -516,6 +518,7 @@ status_t do_io(void* controller, uint8_t command,
|
||||
IOOperation* operation, bool offsetAsSectors);
|
||||
void set_scan_semaphore(void* controller, sem_id sem);
|
||||
void set_bus_width(void* controller, int width);
|
||||
void terminate_bus(void* controller);
|
||||
|
||||
extern mmc_bus_interface gSDHCIACPIDeviceModule;
|
||||
extern mmc_bus_interface gSDHCIPCIDeviceModule;
|
||||
|
||||
@@ -239,4 +239,5 @@ mmc_bus_interface gSDHCIACPIDeviceModule = {
|
||||
.do_io = do_io,
|
||||
.set_scan_semaphore = set_scan_semaphore,
|
||||
.set_bus_width = set_bus_width,
|
||||
.terminate_bus = terminate_bus,
|
||||
};
|
||||
|
||||
@@ -331,4 +331,5 @@ mmc_bus_interface gSDHCIPCIDeviceModule = {
|
||||
.do_io = do_io,
|
||||
.set_scan_semaphore = set_scan_semaphore,
|
||||
.set_bus_width = set_bus_width,
|
||||
.terminate_bus = terminate_bus,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user