commit-grub
[Top][All Lists]
Advanced

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

[1796] 2008-08-08 Marco Gerards <address@hidden>


From: Marco Gerards
Subject: [1796] 2008-08-08 Marco Gerards <address@hidden>
Date: Thu, 07 Aug 2008 23:37:33 +0000

Revision: 1796
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=1796
Author:   marco_g
Date:     2008-08-07 23:37:33 +0000 (Thu, 07 Aug 2008)

Log Message:
-----------
2008-08-08  Marco Gerards  <address@hidden>

        * disk/ata.c (grub_ata_regget): Change return type to
        `grub_uint8_t'.
        (grub_ata_regget2): Likewise.
        (grub_ata_wait_status): New function.
        (grub_ata_wait_busy): Removed function, updated all users to use
        `grub_ata_wait_status'.
        (grub_ata_wait_drq): Likewise.
        (grub_ata_cmd): New function.
        (grub_ata_pio_read): Change return type to `grub_uint8_t'.  Add
        error handling.
        (grub_ata_pio_write): Add error handling.
        (grub_atapi_identify): Likewise.
        (grub_atapi_packet): Use `grub_ata_cmd' and improve error
        handling.
        (grub_ata_identify): Use `grub_ata_cmd' and improve error
        handling.  Actually use the detected registers.  Reorder the
        detection logic such that it is easier to read.
        (grub_ata_pciinit): Do not assign the same ID to each controller.
        (grub_ata_setaddress): Use `grub_ata_cmd' and improve error
        handling.
        (grub_atapi_readsector): Check the result of `grub_ata_pio_read'.

        * include/grub/err.h (grub_err_t): Add `GRUB_ERR_TIMEOUT'.

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/disk/ata.c
    trunk/grub2/include/grub/err.h

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog       2008-08-07 22:55:50 UTC (rev 1795)
+++ trunk/grub2/ChangeLog       2008-08-07 23:37:33 UTC (rev 1796)
@@ -1,5 +1,31 @@
 2008-08-08  Marco Gerards  <address@hidden>
 
+       * disk/ata.c (grub_ata_regget): Change return type to
+       `grub_uint8_t'.
+       (grub_ata_regget2): Likewise.
+       (grub_ata_wait_status): New function.
+       (grub_ata_wait_busy): Removed function, updated all users to use
+       `grub_ata_wait_status'.
+       (grub_ata_wait_drq): Likewise.
+       (grub_ata_cmd): New function.
+       (grub_ata_pio_read): Change return type to `grub_uint8_t'.  Add
+       error handling.
+       (grub_ata_pio_write): Add error handling.
+       (grub_atapi_identify): Likewise.
+       (grub_atapi_packet): Use `grub_ata_cmd' and improve error
+       handling.
+       (grub_ata_identify): Use `grub_ata_cmd' and improve error
+       handling.  Actually use the detected registers.  Reorder the
+       detection logic such that it is easier to read.
+       (grub_ata_pciinit): Do not assign the same ID to each controller.
+       (grub_ata_setaddress): Use `grub_ata_cmd' and improve error
+       handling.
+       (grub_atapi_readsector): Check the result of `grub_ata_pio_read'.
+
+       * include/grub/err.h (grub_err_t): Add `GRUB_ERR_TIMEOUT'.
+
+2008-08-08  Marco Gerards  <address@hidden>
+
        * NEWS: Update.
 
 2008-08-07  Bean  <address@hidden>

Modified: trunk/grub2/disk/ata.c
===================================================================
--- trunk/grub2/disk/ata.c      2008-08-07 22:55:50 UTC (rev 1795)
+++ trunk/grub2/disk/ata.c      2008-08-07 23:37:33 UTC (rev 1796)
@@ -118,7 +118,7 @@
   grub_outb (val, dev->ioaddress + reg);
 }
 
-static inline int
+static inline grub_uint8_t
 grub_ata_regget (struct grub_ata_device *dev, int reg)
 {
   return grub_inb (dev->ioaddress + reg);
@@ -130,23 +130,30 @@
   grub_outb (val, dev->ioaddress2 + reg);
 }
 
-static inline int
+static inline grub_uint8_t
 grub_ata_regget2 (struct grub_ata_device *dev, int reg)
 {
   return grub_inb (dev->ioaddress2 + reg);
 }
 
-/* Wait until the device DEV has the status set to ready.  */
-static inline void
-grub_ata_wait_busy (struct grub_ata_device *dev)
+static inline grub_err_t
+grub_ata_wait_status (struct grub_ata_device *dev,
+                     grub_uint8_t maskset, grub_uint8_t maskclear)
 {
-  while ((grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY));
-}
+  int i;
 
-static inline void
-grub_ata_wait_drq (struct grub_ata_device *dev)
-{
-  while (! (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_DRQ));
+  for (i = 0; i < 1000; i++)
+    {
+      grub_uint8_t reg;
+
+      reg = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
+      if ((reg & maskset) == maskset && (reg & maskclear) == 0)
+       return GRUB_ERR_NONE;
+
+      grub_millisleep (1);
+    }
+
+  return grub_error (GRUB_ERR_TIMEOUT, "ata timeout");
 }
 
 static inline void
@@ -155,6 +162,21 @@
   grub_millisleep (50);
 }
 
+static grub_err_t
+grub_ata_cmd (struct grub_ata_device *dev, int cmd)
+{
+  grub_err_t err;
+
+  err = grub_ata_wait_status (dev, 0, 
+                             GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_BUSY);
+  if (err)
+    return err;
+
+  grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd);
+
+  return GRUB_ERR_NONE;
+}
+
 /* Byteorder has to be changed before strings can be read.  */
 static inline void
 grub_ata_strncpy (char *dst, char *src, grub_size_t len)
@@ -164,11 +186,11 @@
   unsigned int i;
 
   for (i = 0; i < len / 2; i++)
-    *(dst16++) = grub_be_to_cpu16(*(src16++));
+    *(dst16++) = grub_be_to_cpu16 (*(src16++));
   dst[len] = '\0';
 }
 
-static int
+static grub_err_t
 grub_ata_pio_read (struct grub_ata_device *dev, char *buf,
                   grub_size_t size)
 {
@@ -179,16 +201,17 @@
     return grub_ata_regget (dev, GRUB_ATA_REG_ERROR);
 
   /* Wait until the data is available.  */
-  grub_ata_wait_drq (dev);
+  if (grub_ata_wait_status (dev, GRUB_ATA_STATUS_DRQ, 0))
+    return grub_errno;;
 
   /* Read in the data, word by word.  */
   for (i = 0; i < size / 2; i++)
     buf16[i] = grub_le_to_cpu16 (grub_inw(dev->ioaddress + GRUB_ATA_REG_DATA));
 
   if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_ERR)
-    return grub_ata_regget (dev, GRUB_ATA_REG_ERROR);
+    return grub_error (GRUB_ERR_READ_ERROR, "ATA read error");
 
-  return 0;
+  return GRUB_ERR_NONE;
 }
 
 static grub_err_t
@@ -201,17 +224,18 @@
   if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_ERR)
     return grub_ata_regget (dev, GRUB_ATA_REG_ERROR);
 
-  /* Wait until the device is ready to write.  */
-  grub_ata_wait_drq (dev);
+  /* Wait until the data is available.  */
+  if (grub_ata_wait_status (dev, GRUB_ATA_STATUS_DRQ, 0))
+    return 0;
 
   /* Write the data, word by word.  */
   for (i = 0; i < size / 2; i++)
     grub_outw(grub_cpu_to_le16 (buf16[i]), dev->ioaddress + GRUB_ATA_REG_DATA);
 
   if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_ERR)
-    return grub_ata_regget (dev, GRUB_ATA_REG_ERROR);
+    return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
 
-  return 0;
+  return GRUB_ERR_NONE;
 }
 
 static void
@@ -243,22 +267,33 @@
   if (! info)
     return grub_errno;
 
-  grub_ata_wait_busy (dev);
+  if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
+    {
+      grub_free (info);
+      return grub_errno;
+    }
 
   grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
-  grub_ata_regset (dev, GRUB_ATA_REG_CMD,
-                  GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE);
-  grub_ata_wait ();
 
-  grub_ata_pio_read (dev, info, 256);
+  if (grub_ata_cmd (dev, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE))
+    {
+      grub_free (info);
+      return grub_errno;
+    }
 
+  if (grub_ata_pio_read (dev, info, 256))
+    {
+      grub_free (info);
+      return grub_errno;
+    }
+
   dev->atapi = 1;
 
   grub_ata_dumpinfo (dev, info);
 
   grub_free (info);
 
-  return 0;
+  return GRUB_ERR_NONE;
 }
 
 static grub_err_t
@@ -269,12 +304,14 @@
   grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0);
   grub_ata_regset (dev, GRUB_ATA_REG_LBAHIGH, 0xFF);
   grub_ata_regset (dev, GRUB_ATA_REG_LBAMID, 0xFF);
-  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_PACKET);
-  grub_ata_wait ();
 
-  grub_ata_pio_write (dev, packet, 12);
+  if (grub_ata_cmd (dev, GRUB_ATA_CMD_PACKET))
+    return grub_errno;
 
-  return 0;
+  if (grub_ata_pio_write (dev, packet, 12))
+    return grub_errno;
+
+  return GRUB_ERR_NONE;
 }
 
 static grub_err_t
@@ -282,7 +319,7 @@
 {
   char *info;
   grub_uint16_t *info16;
-  int ataerr;
+  int ataerr = 0;
 
   info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
   if (! info)
@@ -290,13 +327,22 @@
 
   info16 = (grub_uint16_t *) info;
 
-  grub_ata_wait_busy (dev);
+  if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
+    {
+      grub_free (info);
+      return grub_errno;
+    }
 
   grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
-  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_DEVICE);
+  if (grub_ata_cmd (dev, GRUB_ATA_CMD_IDENTIFY_DEVICE))
+    {
+      grub_free (info);
+      return grub_errno;
+    }
   grub_ata_wait ();
 
-  ataerr = grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
+  if (grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE))
+    ataerr = grub_ata_regget (dev, GRUB_ATA_REG_ERROR);
   if (ataerr & 4)
     {
       /* ATAPI device detected.  */
@@ -361,8 +407,8 @@
   /* Setup the device information.  */
   dev->port = port;
   dev->device = device;
-  dev->ioaddress = grub_ata_ioaddress[dev->port];
-  dev->ioaddress2 = grub_ata_ioaddress2[dev->port];
+  dev->ioaddress = addr;
+  dev->ioaddress2 = addr2;
   dev->next = NULL;
 
   /* Try to detect if the port is in use by writing to it,
@@ -381,8 +427,11 @@
   /* Detect if the device is present by issuing a EXECUTE
      DEVICE DIAGNOSTICS command.  */
   grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
-  grub_ata_regset (dev, GRUB_ATA_REG_CMD,
-                  GRUB_ATA_CMD_EXEC_DEV_DIAGNOSTICS);
+  if (grub_ata_cmd (dev, GRUB_ATA_CMD_EXEC_DEV_DIAGNOSTICS))
+    {
+      grub_free (dev);
+      return grub_errno;
+    }
   grub_ata_wait ();
 
   grub_dprintf ("ata", "Registers: %x %x %x %x\n",
@@ -399,19 +448,19 @@
     {
       grub_dprintf ("ata", "ATAPI signature detected\n");
     }
-  else if (! (grub_ata_regget (dev, GRUB_ATA_REG_SECTORS) == 0x01
-             && grub_ata_regget (dev, GRUB_ATA_REG_LBALOW) == 0x01
-             && grub_ata_regget (dev, GRUB_ATA_REG_LBAMID) == 0x00
-             && grub_ata_regget (dev, GRUB_ATA_REG_LBAHIGH) == 0x00))
+  else if (grub_ata_regget (dev, GRUB_ATA_REG_SECTORS) == 0x01
+          && grub_ata_regget (dev, GRUB_ATA_REG_LBALOW) == 0x01
+          && grub_ata_regget (dev, GRUB_ATA_REG_LBAMID) == 0x00
+          && grub_ata_regget (dev, GRUB_ATA_REG_LBAHIGH) == 0x00)
     {
+      grub_dprintf ("ata", "ATA detected\n");
+    }
+  else
+    {
       grub_dprintf ("ata", "incorrect signature\n");
       grub_free (dev);
       return 0;
     }
-  else
-    {
-      grub_dprintf ("ata", "ATA detected\n");
-    }
 
 
   /* Use the IDENTIFY DEVICE command to query the device.  */
@@ -429,7 +478,8 @@
 }
 
 static int
-grub_ata_pciinit (int bus, int device, int func, grub_pci_id_t pciid)
+grub_ata_pciinit (int bus, int device, int func,
+                 grub_pci_id_t pciid __attribute__((unused)))
 {
   static int compat_use[2] = { 0 };
   grub_pci_address_t addr;
@@ -439,6 +489,7 @@
   int rega;
   int regb;
   int i;
+  static int controller = 0;
 
   /* Read class.  */
   addr = grub_pci_make_address (bus, device, func, 2);
@@ -487,11 +538,13 @@
 
       if (rega && regb)
        {
-         grub_ata_device_initialize (i, 0, rega, regb);
-         grub_ata_device_initialize (i, 1, rega, regb);
+         grub_ata_device_initialize (controller * 2 + i, 0, rega, regb);
+         grub_ata_device_initialize (controller * 2 + i, 1, rega, regb);
        }
     }
 
+  controller++;
+
   return 0;
 }
 
@@ -519,7 +572,8 @@
                     grub_disk_addr_t sector,
                     grub_size_t size)
 {
-  grub_ata_wait_busy (dev);
+  if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
+    return grub_errno;
 
   switch (addressing)
     {
@@ -615,21 +669,31 @@
       if (rw == 0)
        {
          /* Read 256/65536 sectors.  */
-         grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd);
-         grub_ata_wait ();
+         if (grub_ata_cmd (dev, cmd))
+           return grub_errno;
+
+         /* Wait for the command to complete.  */
+         if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
+           return grub_errno;
+
          for (sect = 0; sect < batch; sect++)
            {
              if (grub_ata_pio_read (dev, buf,
                                     GRUB_DISK_SECTOR_SIZE))
-               return grub_error (GRUB_ERR_READ_ERROR, "ATA read error");
+               return grub_errno;
              buf += GRUB_DISK_SECTOR_SIZE;
            }
        }
       else
        {
          /* Write 256/65536 sectors.  */
-         grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd_write);
-         grub_ata_wait ();
+         if (grub_ata_cmd (dev, cmd))
+           return grub_errno;
+
+         /* Wait for the command to complete.  */
+         if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
+           return grub_errno;
+
          for (sect = 0; sect < batch; sect++)
            {
              if (grub_ata_pio_write (dev, buf,
@@ -648,18 +712,28 @@
   if (rw == 0)
     {
       /* Read sectors.  */
-      grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd);
-      grub_ata_wait ();
+      if (grub_ata_cmd (dev, cmd))
+       return grub_errno;
+
+      /* Wait for the command to complete.  */
+      if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
+       return grub_errno;
+
       for (sect = 0; sect < (size % batch); sect++)
        {
          if (grub_ata_pio_read (dev, buf, GRUB_DISK_SECTOR_SIZE))
-           return grub_error (GRUB_ERR_READ_ERROR, "ATA read error");
+           return grub_errno;
          buf += GRUB_DISK_SECTOR_SIZE;
        }
     } else {
       /* Write sectors.  */
-      grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd_write);
-      grub_ata_wait ();
+      if (grub_ata_cmd (dev, cmd))
+       return grub_errno;
+
+      /* Wait for the command to complete.  */
+      if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY))
+       return grub_errno;
+
       for (sect = 0; sect < (size % batch); sect++)
        {
          if (grub_ata_pio_write (dev, buf, GRUB_DISK_SECTOR_SIZE))
@@ -746,7 +820,8 @@
 
   grub_atapi_packet (dev, (char *) &readcmd);
   grub_ata_wait ();
-  grub_ata_pio_read (dev, buf, GRUB_CDROM_SECTOR_SIZE);
+  if (grub_ata_pio_read (dev, buf, GRUB_CDROM_SECTOR_SIZE))
+    return grub_errno;
 
   return 0;
 }

Modified: trunk/grub2/include/grub/err.h
===================================================================
--- trunk/grub2/include/grub/err.h      2008-08-07 22:55:50 UTC (rev 1795)
+++ trunk/grub2/include/grub/err.h      2008-08-07 23:37:33 UTC (rev 1796)
@@ -51,7 +51,8 @@
     GRUB_ERR_NOT_IMPLEMENTED_YET,
     GRUB_ERR_SYMLINK_LOOP,
     GRUB_ERR_BAD_GZIP_DATA,
-    GRUB_ERR_MENU
+    GRUB_ERR_MENU,
+    GRUB_ERR_TIMEOUT
   }
 grub_err_t;
 






reply via email to

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