From ff800af820e9ff5d1cd6cc148dda98e8947dc348 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Sun, 17 Sep 2017 11:15:26 +0200 Subject: [PATCH] ahci: make port enumeration independent from port count fixes #2522 --- repos/os/src/drivers/ahci/ahci.cc | 34 ++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/repos/os/src/drivers/ahci/ahci.cc b/repos/os/src/drivers/ahci/ahci.cc index 598c978a2..467f6fd3d 100644 --- a/repos/os/src/drivers/ahci/ahci.cc +++ b/repos/os/src/drivers/ahci/ahci.cc @@ -95,6 +95,19 @@ struct Ahci platform_hba.ack_irq(); } + /* + * Least significant bit + */ + unsigned lsb(unsigned bits) const + { + for (unsigned i = 0; i < 32; i++) + if (bits & (1u << i)) { + return i; + } + + return 0; + } + void info() { using Genode::log; @@ -116,38 +129,39 @@ struct Ahci for (unsigned i = 0; i < hba.port_count(); i++) { /* check if port is implemented */ - if (!(available & (1U << i))) - continue; + if (!available) break; + unsigned index = lsb(available); + available ^= (1u << index); bool enabled = false; - switch (Port_base(i, hba).read()) { + switch (Port_base(index, hba).read()) { case ATA_SIG: try { - ports[i] = new (&alloc) + ports[index] = new (&alloc) Ata_driver(alloc, ram, root, ready_count, rm, hba, - platform_hba, i, device_identified); + platform_hba, index, device_identified); enabled = true; } catch (...) { } - log("\t\t#", i, ":", enabled ? " ATA" : " off (ATA)"); + log("\t\t#", index, ":", enabled ? " ATA" : " off (ATA)"); break; case ATAPI_SIG: case ATAPI_SIG_QEMU: if (enable_atapi) try { - ports[i] = new (&alloc) + ports[index] = new (&alloc) Atapi_driver(ram, root, ready_count, rm, hba, - platform_hba, i); + platform_hba, index); enabled = true; } catch (...) { } - log("\t\t#", i, ":", enabled ? " ATAPI" : " off (ATAPI)"); + log("\t\t#", index, ":", enabled ? " ATAPI" : " off (ATAPI)"); break; default: - log("\t\t#", i, ": off (unknown device signature)"); + log("\t\t#", index, ": off (unknown device signature)"); } } };