]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Give ATA device a bit more time on first try in order to allow disks
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 13 May 2011 19:41:18 +0000 (21:41 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 13 May 2011 19:41:18 +0000 (21:41 +0200)
to spin up.

* grub-core/disk/ata.c (grub_atapi_identify): Use GRUB_ATA_TOUT_DEV_INIT
if dev->present is 1. Reset dev->present on failure.
(grub_ata_device_initialize): Set dev->present to 1.
* include/grub/ata.h (GRUB_ATA_TOUT_DEV_INIT): New value.
(grub_ata_device): New member 'present'.

ChangeLog
grub-core/disk/ata.c
include/grub/ata.h

index 905b0e919489e6324c18d1665d3d0e02a20a365d..e20f2d3cfe7eeb52b4e87208405cc828fd6bb4b8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2011-05-13  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Give ATA device a bit more time on first try in order to allow disks
+       to spin up.
+
+       * grub-core/disk/ata.c (grub_atapi_identify): Use GRUB_ATA_TOUT_DEV_INIT
+       if dev->present is 1. Reset dev->present on failure.
+       (grub_ata_device_initialize): Set dev->present to 1.
+       * include/grub/ata.h (GRUB_ATA_TOUT_DEV_INIT): New value.
+       (grub_ata_device): New member 'present'.
+
 2011-05-13  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * util/grub-mkimage.c (generate_image): Update hash.
index 7f261560d579fd106c482287a05d8c03c5992854..391ccb9a2ee2ad35e6d8ceaa9cd7938164418051 100644 (file)
@@ -160,18 +160,23 @@ grub_atapi_identify (struct grub_ata_device *dev)
 
   grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
   grub_ata_wait ();
-  if (grub_ata_check_ready (dev))
+  if ((grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY)
+      && grub_ata_wait_not_busy (dev, dev->present ? GRUB_ATA_TOUT_DEV_INIT 
+                                : GRUB_ATA_TOUT_STD))
     {
       grub_free (info);
+      dev->present = 0;
       return grub_errno;
     }
 
   grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE);
   grub_ata_wait ();
 
-  if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
+  if (grub_ata_wait_drq (dev, 0, dev->present ? GRUB_ATA_TOUT_DEV_INIT 
+                        : GRUB_ATA_TOUT_STD))
     {
       grub_free (info);
+      dev->present = 0;
       return grub_errno;
     }
   grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
@@ -258,8 +263,11 @@ grub_ata_identify (struct grub_ata_device *dev)
 
   grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
   grub_ata_wait ();
-  if (grub_ata_check_ready (dev))
+  if ((grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY)
+      && grub_ata_wait_not_busy (dev, dev->present ? GRUB_ATA_TOUT_DEV_INIT 
+                                : GRUB_ATA_TOUT_STD))
     {
+      dev->present = 0;
       grub_free (info);
       return grub_errno;
     }
@@ -267,7 +275,8 @@ grub_ata_identify (struct grub_ata_device *dev)
   grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_DEVICE);
   grub_ata_wait ();
 
-  if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
+  if (grub_ata_wait_drq (dev, 0, dev->present ? GRUB_ATA_TOUT_DEV_INIT 
+                        : GRUB_ATA_TOUT_STD))
     {
       grub_free (info);
       grub_errno = GRUB_ERR_NONE;
@@ -280,13 +289,18 @@ grub_ata_identify (struct grub_ata_device *dev)
        return grub_atapi_identify (dev);
 
       else if (sts == 0x00)
-       /* No device, return error but don't print message.  */
-       return GRUB_ERR_UNKNOWN_DEVICE;
-
+       {
+         dev->present = 0;
+         /* No device, return error but don't print message.  */
+         return GRUB_ERR_UNKNOWN_DEVICE;
+       }
       else
-       /* Other Error.  */
-       return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                          "device cannot be identified");
+       {
+         dev->present = 0;
+         /* Other Error.  */
+         return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                            "device cannot be identified");
+       }
     }
 
   grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
@@ -381,6 +395,7 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2)
   dev->device = device;
   dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE;
   dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE;
+  dev->present = 1;
   dev->next = NULL;
 
   /* Register the device.  */
index 9e3aaf0e69407eec652328ec1d781c69fbad0088..c8f4e5e1b9bb285532744446e71c80d90a2ec2b1 100644 (file)
@@ -94,7 +94,8 @@ enum grub_ata_commands
 enum grub_ata_timeout_milliseconds
   {
     GRUB_ATA_TOUT_STD  =  1000,  /* 1s standard timeout.  */
-    GRUB_ATA_TOUT_DATA = 10000   /* 10s DATA I/O timeout.  */
+    GRUB_ATA_TOUT_DATA = 10000,   /* 10s DATA I/O timeout.  */
+    GRUB_ATA_TOUT_DEV_INIT  =  10000,  /* Give the device 10s on first try to spinon.  */
   };
 
 struct grub_ata_device
@@ -128,6 +129,8 @@ struct grub_ata_device
   /* Set to 0 for ATA, set to 1 for ATAPI.  */
   int atapi;
 
+  int present;
+
   struct grub_ata_device *next;
 };