grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] ata.mod under qemu


From: Christian Franke
Subject: Re: [PATCH] ata.mod under qemu
Date: Wed, 20 May 2009 23:40:17 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.21) Gecko/20090403 SeaMonkey/1.1.16

The attached patch should fix this. It should also prevents misleading error messages if a device does not exist.

2009-05-20  Christian Franke  <address@hidden>

        * disk/ata.c: (grub_ata_wait_not_busy): Add debug output of status
        register.
        (grub_ata_identify): Suppress error message if status register
        is 0x00 after command failure.
        (grub_device_initialize): Remove unsafe status register check.
        Thanks to 'phcoder' for problem report and patch.
        Prevent sign extension in debug message.


--
Regards,
Christian Franke


diff --git a/disk/ata.c b/disk/ata.c
index ea42d59..651937d 100644
--- a/disk/ata.c
+++ b/disk/ata.c
@@ -41,11 +41,14 @@ grub_ata_wait_not_busy (struct grub_ata_device *dev, int 
milliseconds)
   grub_millisleep (1);
 
   int i = 1;
-  while (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY)
+  grub_uint8_t sts;
+  while ((sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS))
+        & GRUB_ATA_STATUS_BUSY)
     {
       if (i >= milliseconds)
         {
-         grub_dprintf ("ata", "timeout: %dms\n", milliseconds);
+         grub_dprintf ("ata", "timeout: %dms, status=0x%x\n",
+                       milliseconds, sts);
          return grub_error (GRUB_ERR_TIMEOUT, "ATA timeout");
        }
 
@@ -259,20 +262,21 @@ grub_ata_identify (struct grub_ata_device *dev)
 
   if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
     {
+      grub_free(info);
+      grub_errno = GRUB_ERR_NONE;
+
       if (grub_ata_regget (dev, GRUB_ATA_REG_ERROR) & 0x04) /* ABRT */
-       {
-         /* Device without ATA IDENTIFY, try ATAPI.  */
-         grub_free(info);
-         grub_errno = GRUB_ERR_NONE;
-         return grub_atapi_identify (dev);
-       }
+       /* Device without ATA IDENTIFY, try ATAPI.  */
+       return grub_atapi_identify (dev);
+
+      else if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) == 0x00)
+       /* No device, return error but don't print message.  */
+       return GRUB_ERR_UNKNOWN_DEVICE;
+
       else
-       {
-         /* Error.  */
-         grub_free(info);
-         return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                            "device can not be identified");
-       }
+       /* Other Error.  */
+       return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                          "device can not be identified");
     }
 
   grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
@@ -334,26 +338,12 @@ grub_ata_device_initialize (int port, int device, int 
addr, int addr2)
   grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
   grub_ata_wait ();
 
-  /* If status is 0x00, it is safe to assume that there
-     is no device (or only a !READY) device connected.  */
-  grub_int8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
-  grub_dprintf ("ata", "status=0x%x\n", sts);
-  if (sts == 0x00)
-    {
-      grub_free(dev);
-      return 0;
-    }
-
   /* Try to detect if the port is in use by writing to it,
      waiting for a while and reading it again.  If the value
-     was preserved, there is a device connected.
-     But this tests often detects a second (slave) device
-     connected to a SATA controller which supports only one
-     (master) device.  In this case, the status register
-     check above usually works.  */
+     was preserved, there is a device connected.  */
   grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);  
   grub_ata_wait ();
-  grub_int8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
+  grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
   grub_dprintf ("ata", "sectors=0x%x\n", sec);
   if (sec != 0x5A)
     {
@@ -361,6 +351,12 @@ grub_ata_device_initialize (int port, int device, int 
addr, int addr2)
       return 0;
     }
 
+  /* The above test may detect a second (slave) device
+     connected to a SATA controller which supports only one
+     (master) device.  It is not safe to use the status register
+     READY bit to check for controller channel existence.  Some
+     ATAPI commands (RESET, DIAGNOSTIC) may clear this bit.  */
+
   /* Use the IDENTIFY DEVICE command to query the device.  */
   if (grub_ata_identify (dev))
     {

reply via email to

[Prev in Thread] Current Thread [Next in Thread]