ahci: make robuster during resume

During resume the waiting for Cmd::St takes ~2s on a T460p with Intel
AHCI SSD attached. According to the Serial ATA AHCI Spec. wakeup can take
seconds, e.g. chapter 8.2 Power State Mappings of the Serial ATA AHCI spec
(1.3.1).

Issue #5203
This commit is contained in:
Alexander Boettcher 2024-04-30 08:47:01 +02:00 committed by Christian Helmuth
parent dc4dad4608
commit bfddf08f75
2 changed files with 17 additions and 6 deletions

View File

@ -954,6 +954,9 @@ struct Ahci::Port : private Port_base
typedef Port_mmio::Ci Ci;
typedef Port_mmio::Register_set::Polling_timeout Polling_timeout;
typedef Port_mmio::Register_set::Attempts Attempts;
typedef Port_mmio::Register_set::Microseconds Microseconds;
void ack_irq(Port_mmio &mmio)
{
@ -992,7 +995,11 @@ struct Ahci::Port : private Port_base
return;
try {
mmio.wait_for(delayer, Tfd::Sts_bsy::Equal(0));
/* wait up to 5s */
mmio.wait_for(Port::Attempts(5000),
Port::Microseconds(1000),
delayer,
Tfd::Sts_bsy::Equal(0));
} catch (Polling_timeout) {
error("HBA busy unable to start command processing.");
return;

View File

@ -141,8 +141,6 @@ class Ahci::Driver : Noncopyable
device_release_if_stopped_and_idle();
log("driver halted");
return;
}
@ -153,9 +151,13 @@ class Ahci::Driver : Noncopyable
/* re-start request handling of client sessions */
for_each_port([&](auto &port, auto const index, auto) {
port.stop_processing = false;
port.reinit();
_dispatch.session(index);
try {
port.reinit();
port.stop_processing = false;
_dispatch.session(index);
} catch (...) {
error("port ", index, " failed to be resumed");
}
});
log("driver resumed");
@ -221,6 +223,8 @@ class Ahci::Driver : Noncopyable
if (pending)
return;
log("driver halted");
_resources.release_device();
}