ahci: Reset port before access

Also throw error if wakup from power safe mode failes.

Fix #1776
This commit is contained in:
Sebastian Sumpf 2015-11-12 15:00:39 +01:00 committed by Christian Helmuth
parent 5f2d92f916
commit ab79b0d5e0
2 changed files with 33 additions and 8 deletions

View File

@ -71,6 +71,11 @@ struct Ahci
return sig == ATAPI_SIG_QEMU || sig == ATAPI_SIG;
}
bool is_ata(unsigned sig)
{
return sig == ATA_SIG;
}
/**
* Forward IRQs to ports
*/
@ -121,12 +126,21 @@ struct Ahci
continue;
Port port(hba, platform_hba, i);
bool enabled = port.enable();
unsigned sig = port.read<Port::Sig>();
PINF("\t\t#%u: %s", i, enabled ?
(is_atapi(sig) ? "ATAPI" : "ATA") :
"off");
/* check for ATA/ATAPI devices */
unsigned sig = port.read<Port::Sig>();
if (!is_atapi(sig) && !is_ata(sig)) {
PINF("\t\t#%u: off", i);
continue;
}
port.reset();
bool enabled = false;
try { enabled = port.enable(); }
catch (Port::Not_ready) { PERR("Could not enable port %u", i); }
PINF("\t\t#%u: %s", i, is_atapi(sig) ? "ATAPI" : "ATA");
if (!enabled)
continue;

View File

@ -16,6 +16,7 @@
#include <block/component.h>
#include <os/attached_mmio.h>
#include <util/retry.h>
#include <util/volatile_object.h>
static bool constexpr verbose = false;
@ -389,6 +390,9 @@ struct Command_table
*/
struct Port : Genode::Mmio
{
struct Not_ready : Genode::Exception { };
Hba &hba;
Platform::Hba &platform_hba;
unsigned cmd_slots = hba.command_slots();
@ -639,9 +643,16 @@ struct Port : Genode::Mmio
/* try to wake up device */
write<Cmd::Icc>(Ssts::Ipm::ACTIVE);
while ((Ssts::Dec::get(status) != Ssts::Dec::ESTABLISHED) ||
!(Ssts::Ipm::get(status) & Ssts::Ipm::ACTIVE))
status = read<Ssts>();
Genode::retry<Not_ready>(
[&] {
if ((Ssts::Dec::get(status) != Ssts::Dec::ESTABLISHED) ||
!(Ssts::Ipm::get(status) & Ssts::Ipm::ACTIVE))
throw Not_ready();
},
[&] {
hba.delayer().usleep(1000);
status = read<Ssts>();
}, 10);
}
return ((Ssts::Dec::get(status) == Ssts::Dec::ESTABLISHED) &&