Implement time based checks even when looping on an ioport.
[seabios.git] / src / ata.c
index 2e7c4cc22260bcbb638b6e65b1408bf3c79f01a2..53f9196378756f94fdeac15fb25659081be6e084 100644 (file)
--- a/src/ata.c
+++ b/src/ata.c
 static int
 await_ide(u8 when_done, u16 base, u16 timeout)
 {
-    u32 time=0, last=0;
+    u64 end = calc_future_tsc(timeout);
     for (;;) {
         u8 status = inb(base+ATA_CB_STAT);
-        time++;
         u8 result = 0;
         if (when_done == BSY)
             result = status & ATA_CB_STAT_BSY;
@@ -55,20 +54,13 @@ await_ide(u8 when_done, u16 base, u16 timeout)
 
         if (result)
             return status;
-        // mod 2048 each 16 ms
-        if (time>>16 != last) {
-            last = time >>16;
-            dprintf(6, "await_ide: (TIMEOUT,BSY,!BSY,!BSY_DRQ"
-                    ",!BSY_!DRQ,!BSY_RDY) %d time= %d timeout= %d\n"
-                    , when_done, time>>11, timeout);
-        }
         if (status & ATA_CB_STAT_ERR) {
             dprintf(1, "await_ide: ERROR (TIMEOUT,BSY,!BSY,!BSY_DRQ"
-                    ",!BSY_!DRQ,!BSY_RDY) %d status=%x time= %d timeout= %d\n"
-                    , when_done, status, time>>11, timeout);
+                    ",!BSY_!DRQ,!BSY_RDY) %d status=%x timeout=%d\n"
+                    , when_done, status, timeout);
             return -1;
         }
-        if (timeout == 0 || (time>>11) > timeout)
+        if (rdtscll() >= end)
             break;
     }
     dprintf(1, "IDE time out\n");
@@ -893,18 +885,11 @@ ata_init()
     }
 
     // Scan PCI bus for ATA adapters
-    int count=0, bdf=-1;
-    u16 classid = PCI_CLASS_STORAGE_OTHER; // SATA first
-    while (count<CONFIG_MAX_ATA_INTERFACES-1) {
-        bdf = pci_find_class(classid, bdf+1);
-        if (bdf < 0) {
-            if (classid == PCI_CLASS_STORAGE_IDE)
-                // Done
-                break;
-            classid = PCI_CLASS_STORAGE_IDE; // PATA controllers
-            bdf = -1;
+    int count=0;
+    int bdf, max;
+    foreachpci(bdf, max) {
+        if (pci_config_readw(bdf, PCI_CLASS_DEVICE) != PCI_CLASS_STORAGE_IDE)
             continue;
-        }
 
         u8 irq = pci_config_readb(bdf, PCI_INTERRUPT_LINE);
         SET_EBDA(ata.channels[count].irq, irq);
@@ -913,7 +898,7 @@ ata_init()
         u8 prog_if = pci_config_readb(bdf, PCI_CLASS_PROG);
         u32 port1, port2;
 
-        if (classid != PCI_CLASS_STORAGE_IDE || prog_if & 1) {
+        if (prog_if & 1) {
             port1 = pci_config_readl(bdf, PCI_BASE_ADDRESS_0) & ~3;
             port2 = pci_config_readl(bdf, PCI_BASE_ADDRESS_1) & ~3;
         } else {
@@ -922,19 +907,19 @@ ata_init()
         }
         SET_EBDA(ata.channels[count].iobase1, port1);
         SET_EBDA(ata.channels[count].iobase2, port2);
-        dprintf(1, "ATA controller %d at %x/%x (dev %x class %x/%x)\n"
-                , count, port1, port2, bdf, classid, prog_if);
+        dprintf(1, "ATA controller %d at %x/%x (dev %x prog_if %x)\n"
+                , count, port1, port2, bdf, prog_if);
         count++;
 
-        if (classid != PCI_CLASS_STORAGE_IDE || prog_if & 4) {
+        if (prog_if & 4) {
             port1 = pci_config_readl(bdf, PCI_BASE_ADDRESS_2) & ~3;
             port2 = pci_config_readl(bdf, PCI_BASE_ADDRESS_3) & ~3;
         } else {
             port1 = 0x170;
             port2 = 0x370;
         }
-        dprintf(1, "ATA controller %d at %x/%x (dev %x class %x/%x)\n"
-                , count, port1, port2, bdf, classid, prog_if);
+        dprintf(1, "ATA controller %d at %x/%x (dev %x prog_if %x)\n"
+                , count, port1, port2, bdf, prog_if);
         SET_EBDA(ata.channels[count].iobase1, port1);
         SET_EBDA(ata.channels[count].iobase2, port2);
         count++;