[coreboot] seabios - long delays detecting disks

Kevin O'Connor kevin at koconnor.net
Sun May 24 20:04:09 CEST 2009


On Thu, May 21, 2009 at 12:19:20PM -0400, Ward Vandewege wrote:
> This board (m57sli) has only one ide connector.

That's odd - what is:

ata2-0: PCHS=16383/16/63 translation=lba LCHS=1024/255/63
ata2-0: WDC WD2500SD-01KCB0 ATA-6 Hard-Disk (232 GiBytes)

from?

>The CDROM drive is the only
> thing connected to it via an 80 pin ide cable with two connectors. It's
> connected to the connector at the end of the cable. The drive is set to
> master with a jumper. It's a Pioneer DVR-111D. It appears to work normally
> (at least for reading data CDs from gnu/linux).
> 
> > Because seabios thinks something is present on the second drive, it
> > tries to identify it.  The packet identify command fails ("send_cmd :
> > read error"), and then seabios waits for the RDY signal so that it can
> > send a normal identify command.  However, RDY never becomes available
> > and SeaBIOS times out 30 seconds later.
> 
> Hmm. So, cdrom firmware bug?

It looks that way to me.

Filo has a specific test to see if a "slave" drive exists.  Can you
try the patch attached and see if it improves things?

-Kevin
-------------- next part --------------
diff --git a/src/ata.c b/src/ata.c
index db0996a..e05ac22 100644
--- a/src/ata.c
+++ b/src/ata.c
@@ -647,11 +647,10 @@ extract_identify(int driveid, u16 *buffer)
 }
 
 static int
-init_drive_atapi(int driveid)
+init_drive_atapi(int driveid, u16 *buffer)
 {
     // Send an IDENTIFY_DEVICE_PACKET command to device
-    u16 buffer[256];
-    memset(buffer, 0, sizeof(buffer));
+    memset(buffer, 0, IDE_SECTOR_SIZE);
     struct disk_op_s dop;
     dop.driveid = driveid;
     dop.command = ATA_CMD_IDENTIFY_DEVICE_PACKET;
@@ -685,11 +684,10 @@ init_drive_atapi(int driveid)
 }
 
 static int
-init_drive_ata(int driveid)
+init_drive_ata(int driveid, u16 *buffer)
 {
     // Send an IDENTIFY_DEVICE command to device
-    u16 buffer[256];
-    memset(buffer, 0, sizeof(buffer));
+    memset(buffer, 0, IDE_SECTOR_SIZE);
     struct disk_op_s dop;
     dop.driveid = driveid;
     dop.command = ATA_CMD_IDENTIFY_DEVICE;
@@ -807,23 +805,34 @@ ata_detect()
         }
 
         // check for ATAPI
-        int ret = init_drive_atapi(driveid);
-        if (!ret)
+        u16 buffer[256];
+        int ret = init_drive_atapi(driveid, buffer);
+        if (!ret) {
             // Found an ATAPI drive.
-            continue;
-
-        u8 st = inb(iobase1+ATA_CB_STAT);
-        if (!st)
-            // Status not set - can't be a valid drive.
-            continue;
-
-        // Wait for RDY.
-        ret = await_rdy(iobase1);
-        if (ret < 0)
-            continue;
+        } else {
+            u8 st = inb(iobase1+ATA_CB_STAT);
+            if (!st)
+                // Status not set - can't be a valid drive.
+                continue;
+
+            // Wait for RDY.
+            ret = await_rdy(iobase1);
+            if (ret < 0)
+                continue;
+
+            // check for ATA.
+            ret = init_drive_ata(driveid, buffer);
+            if (ret)
+                // No ATA drive found
+                continue;
+        }
 
-        // check for ATA.
-        init_drive_ata(driveid);
+        u16 resetresult = buffer[93];
+        dprintf(6, "ata_detect resetresult=%04x\n", resetresult);
+        if (CONFIG_COREBOOT && !slave && ((resetresult >> 14) & 3) == 1
+            && ((resetresult >> 5) & 1) == 0)
+            // No slave present - skip detection.
+            driveid++;
     }
 
     printf("\n");


More information about the coreboot mailing list