commit-grub
[Top][All Lists]
Advanced

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

[1953] 2009-01-22 Christian Franke <address@hidden>


From: Christian Franke
Subject: [1953] 2009-01-22 Christian Franke <address@hidden>
Date: Thu, 22 Jan 2009 20:15:05 +0000

Revision: 1953
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=1953
Author:   chrfranke
Date:     2009-01-22 20:15:05 +0000 (Thu, 22 Jan 2009)

Log Message:
-----------
2009-01-22  Christian Franke  <address@hidden>

        * disk/ata.c (grub_ata_wait_status): Replace by ...
        (grub_ata_wait_not_busy): ... this function.  Checks only BSY bit,
        other status bits may be invalid while BSY is asserted.
        (grub_ata_check_ready): New function.
        (grub_ata_cmd): Removed.
        (grub_ata_wait_drq): New function.
        (grub_ata_strncpy): Remove inline.
        (grub_ata_pio_read): Reduce to actual block transfer.  BSY wait
        and error check now done by grub_ata_wait_drq ().
        (grub_ata_pio_write): Likewise.
        (grub_atapi_identify): Set DEV before check for !BSY.  Use
        grub_ata_wait_drq () to wait for data.
        (grub_ata_device_initialize): Add status register check to
        detect missing SATA slave devices.  Add debug messages.
        (grub_atapi_wait_drq): Use grub_ata_wait_not_busy ().
        (grub_atapi_packet): Set DEV before check for !BSY.  Replace
        transfer loop by grub_ata_pio_write ().
        (grub_ata_identify): Set DEV before check for !BSY. Use
        grub_ata_wait_drq () to wait for data.
        (grub_ata_setaddress): Set DEV before check for !BSY. 
        (grub_ata_readwrite): Remove duplicate code, handle batch/rest and
        read/write in one loop.  Fix invalid command on write.  Fix incomplete
        command on (size % batch) == 0.  Add missing error check after write of
        last block.  Add debug messages.
        (grub_atapi_read):  Replace transfer loop by grub_ata_pio_read ().

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/disk/ata.c

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog       2009-01-19 20:39:57 UTC (rev 1952)
+++ trunk/grub2/ChangeLog       2009-01-22 20:15:05 UTC (rev 1953)
@@ -1,3 +1,31 @@
+2009-01-22  Christian Franke  <address@hidden>
+
+       * disk/ata.c (grub_ata_wait_status): Replace by ...
+       (grub_ata_wait_not_busy): ... this function.  Checks only BSY bit,
+       other status bits may be invalid while BSY is asserted.
+       (grub_ata_check_ready): New function.
+       (grub_ata_cmd): Removed.
+       (grub_ata_wait_drq): New function.
+       (grub_ata_strncpy): Remove inline.
+       (grub_ata_pio_read): Reduce to actual block transfer.  BSY wait
+       and error check now done by grub_ata_wait_drq ().
+       (grub_ata_pio_write): Likewise.
+       (grub_atapi_identify): Set DEV before check for !BSY.  Use
+       grub_ata_wait_drq () to wait for data.
+       (grub_ata_device_initialize): Add status register check to
+       detect missing SATA slave devices.  Add debug messages.
+       (grub_atapi_wait_drq): Use grub_ata_wait_not_busy ().
+       (grub_atapi_packet): Set DEV before check for !BSY.  Replace
+       transfer loop by grub_ata_pio_write ().
+       (grub_ata_identify): Set DEV before check for !BSY. Use
+       grub_ata_wait_drq () to wait for data.
+       (grub_ata_setaddress): Set DEV before check for !BSY. 
+       (grub_ata_readwrite): Remove duplicate code, handle batch/rest and
+       read/write in one loop.  Fix invalid command on write.  Fix incomplete
+       command on (size % batch) == 0.  Add missing error check after write of
+       last block.  Add debug messages.
+       (grub_atapi_read):  Replace transfer loop by grub_ata_pio_read ().
+
 2009-01-19  Christian Franke  <address@hidden>
 
        * disk/ata.c (GRUB_ATAPI_REG_*): New defines.

Modified: trunk/grub2/disk/ata.c
===================================================================
--- trunk/grub2/disk/ata.c      2009-01-19 20:39:57 UTC (rev 1952)
+++ trunk/grub2/disk/ata.c      2009-01-22 20:15:05 UTC (rev 1953)
@@ -152,25 +152,29 @@
   return grub_inb (dev->ioaddress2 + reg);
 }
 
-static inline grub_err_t
-grub_ata_wait_status (struct grub_ata_device *dev,
-                     grub_uint8_t maskset, grub_uint8_t maskclear,
-                     int milliseconds)
+/* Wait for !BSY.  */
+static grub_err_t
+grub_ata_wait_not_busy (struct grub_ata_device *dev, int milliseconds)
 {
-  int i;
+  /* ATA requires 400ns (after a write to CMD register) or
+     1 PIO cycle (after a DRQ block transfer) before
+     first check of BSY.  */
+  grub_millisleep (1);
 
-  for (i = 0; i < milliseconds; i++)
+  int i = 1;
+  while (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY)
     {
-      grub_uint8_t reg;
+      if (i >= milliseconds)
+        {
+         grub_dprintf ("ata", "timeout: %dms\n", milliseconds);
+         return grub_error (GRUB_ERR_TIMEOUT, "ATA timeout");
+       }
 
-      reg = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
-      if ((reg & maskset) == maskset && (reg & maskclear) == 0)
-       return GRUB_ERR_NONE;
-
       grub_millisleep (1);
+      i++;
     }
 
-  return grub_error (GRUB_ERR_TIMEOUT, "ata timeout");
+  return GRUB_ERR_NONE;
 }
 
 static inline void
@@ -179,19 +183,42 @@
   grub_millisleep (50);
 }
 
+/* Check for !BSY before issuing a new command.  */
+static inline grub_err_t
+grub_ata_check_ready (struct grub_ata_device *dev)
+{
+  if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY)
+    return grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_STD);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Wait for !BSY, DRQ.  */
 static grub_err_t
-grub_ata_cmd (struct grub_ata_device *dev, int cmd)
+grub_ata_wait_drq (struct grub_ata_device *dev, int rw,
+                  int milliseconds)
 {
-  if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY, GRUB_ATA_TOUT_STD))
+  if (grub_ata_wait_not_busy (dev, milliseconds))
     return grub_errno;
 
-  grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd);
+  /* !DRQ implies error condition.  */
+  grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
+  if ((sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
+      != GRUB_ATA_STATUS_DRQ)
+    {
+      grub_dprintf ("ata", "ata error: status=0x%x, error=0x%x\n",
+                   sts, grub_ata_regget (dev, GRUB_ATA_REG_ERROR));
+      if (! rw)
+        return grub_error (GRUB_ERR_READ_ERROR, "ATA read error");
+      else
+        return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
+    }
 
   return GRUB_ERR_NONE;
 }
 
 /* Byteorder has to be changed before strings can be read.  */
-static inline void
+static void
 grub_ata_strncpy (char *dst, char *src, grub_size_t len)
 {
   grub_uint16_t *src16 = (grub_uint16_t *) src;
@@ -203,52 +230,26 @@
   dst[len] = '\0';
 }
 
-static grub_err_t
-grub_ata_pio_read (struct grub_ata_device *dev, char *buf,
-                  grub_size_t size, int milliseconds)
+static void
+grub_ata_pio_read (struct grub_ata_device *dev, char *buf, grub_size_t size)
 {
   grub_uint16_t *buf16 = (grub_uint16_t *) buf;
   unsigned int i;
 
-  if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_ERR)
-    return grub_error (GRUB_ERR_READ_ERROR, "ATA read error");
-
-  /* Wait until the data is available.  */
-  if (grub_ata_wait_status (dev, GRUB_ATA_STATUS_DRQ, 0, milliseconds))
-    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_error (GRUB_ERR_READ_ERROR, "ATA read error");
-
-  return GRUB_ERR_NONE;
 }
 
-static grub_err_t
-grub_ata_pio_write (struct grub_ata_device *dev, char *buf,
-                   grub_size_t size, int milliseconds)
+static void
+grub_ata_pio_write (struct grub_ata_device *dev, char *buf, grub_size_t size)
 {
   grub_uint16_t *buf16 = (grub_uint16_t *) buf;
   unsigned int i;
 
-  if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_ERR)
-    return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
-
-  /* Wait until drive is ready to read data.  */
-  if (grub_ata_wait_status (dev, GRUB_ATA_STATUS_DRQ, 0, milliseconds))
-    return grub_errno;
-
   /* 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_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
-
-  return GRUB_ERR_NONE;
 }
 
 static void
@@ -280,26 +281,22 @@
   if (! info)
     return grub_errno;
 
-  if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY, GRUB_ATA_TOUT_STD))
-    {
-      grub_free (info);
-      return grub_errno;
-    }
-
   grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
-
-  if (grub_ata_cmd (dev, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE))
+  if (grub_ata_check_ready (dev))
     {
       grub_free (info);
       return grub_errno;
     }
+
+  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE);
   grub_ata_wait ();
 
-  if (grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE, GRUB_ATA_TOUT_STD))
+  if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
     {
       grub_free (info);
       return grub_errno;
     }
+  grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
 
   dev->atapi = 1;
 
@@ -315,9 +312,8 @@
                     grub_uint8_t ireason,
                     int milliseconds)
 {
-  grub_millisleep (1); /* ATA allows 400ns to assert BSY.  */
-
-  if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY, milliseconds))
+  /* Wait for !BSY, DRQ, ireason */
+  if (grub_ata_wait_not_busy (dev, milliseconds))
     return grub_errno;
 
   grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
@@ -328,9 +324,9 @@
       && (irs & GRUB_ATAPI_IREASON_MASK) == ireason)
     return GRUB_ERR_NONE;
 
-  /* No DRQ implies error condition.  */
-  grub_dprintf("ata", "atapi error: status=0x%x, ireason=0x%x, error=0x%x\n",
-              sts, irs, grub_ata_regget (dev, GRUB_ATA_REG_ERROR));
+  /* !DRQ implies error condition.  */
+  grub_dprintf ("ata", "atapi error: status=0x%x, ireason=0x%x, error=0x%x\n",
+               sts, irs, grub_ata_regget (dev, GRUB_ATA_REG_ERROR));
 
   if (! (sts & GRUB_ATA_STATUS_DRQ)
       && (irs & GRUB_ATAPI_IREASON_MASK) == GRUB_ATAPI_IREASON_ERROR)
@@ -348,11 +344,11 @@
 grub_atapi_packet (struct grub_ata_device *dev, char *packet,
                   grub_size_t size)
 {
-  if (grub_ata_wait_status(dev, 0, GRUB_ATA_STATUS_BUSY, GRUB_ATA_TOUT_STD))
+  grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
+  if (grub_ata_check_ready (dev))
     return grub_errno;
 
   /* Send ATA PACKET command.  */
-  grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
   grub_ata_regset (dev, GRUB_ATA_REG_FEATURES, 0);
   grub_ata_regset (dev, GRUB_ATAPI_REG_IREASON, 0);
   grub_ata_regset (dev, GRUB_ATAPI_REG_CNTHIGH, size >> 8);
@@ -365,10 +361,7 @@
     return grub_errno;
 
   /* Write the packet.  */
-  grub_uint16_t *buf16 = (grub_uint16_t *) packet;
-  unsigned i;
-  for (i = 0; i < 12 / 2; i++)
-    grub_outw (grub_cpu_to_le16 (buf16[i]), dev->ioaddress + 
GRUB_ATA_REG_DATA);
+  grub_ata_pio_write (dev, packet, 12);
 
   return GRUB_ERR_NONE;
 }
@@ -385,21 +378,17 @@
 
   info16 = (grub_uint16_t *) info;
 
-  if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY, GRUB_ATA_TOUT_STD))
-    {
-      grub_free (info);
-      return grub_errno;
-    }
-
   grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
-  if (grub_ata_cmd (dev, GRUB_ATA_CMD_IDENTIFY_DEVICE))
+  if (grub_ata_check_ready (dev))
     {
       grub_free (info);
       return grub_errno;
     }
+
+  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_DEVICE);
   grub_ata_wait ();
 
-  if (grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE, GRUB_ATA_TOUT_STD))
+  if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
     {
       if (grub_ata_regget (dev, GRUB_ATA_REG_ERROR) & 0x04) /* ABRT */
        {
@@ -417,6 +406,8 @@
        }
     }
 
+  grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
+
   /* Now it is certain that this is not an ATAPI device.  */
   dev->atapi = 0;
 
@@ -471,14 +462,31 @@
   dev->ioaddress2 = addr2;
   dev->next = NULL;
 
-  /* 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.  */
   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.  */
   grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);  
   grub_ata_wait ();
-  if (grub_ata_regget (dev, GRUB_ATA_REG_SECTORS) != 0x5A)
+  grub_int8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
+  grub_dprintf ("ata", "sectors=0x%x\n", sec);
+  if (sec != 0x5A)
     {
       grub_free(dev);
       return 0;
@@ -612,9 +620,6 @@
                     grub_disk_addr_t sector,
                     grub_size_t size)
 {
-  if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY, GRUB_ATA_TOUT_STD))
-    return grub_errno;
-
   switch (addressing)
     {
     case GRUB_ATA_CHS:
@@ -637,6 +642,9 @@
                             "using CHS addressing", sector);
 
        grub_ata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4) | head);
+       if (grub_ata_check_ready (dev))
+         return grub_errno;
+
        grub_ata_regset (dev, GRUB_ATA_REG_SECTNUM, sect);
        grub_ata_regset (dev, GRUB_ATA_REG_CYLLSB, cylinder & 0xFF);
        grub_ata_regset (dev, GRUB_ATA_REG_CYLMSB, cylinder >> 8);
@@ -649,6 +657,9 @@
        size = 0;
       grub_ata_regset (dev, GRUB_ATA_REG_DISK,
                       0xE0 | (dev->device << 4) | ((sector >> 24) & 0x0F));
+      if (grub_ata_check_ready (dev))
+       return grub_errno;
+
       grub_ata_setlba (dev, sector, size);
       break;
 
@@ -657,6 +668,9 @@
        size = 0;
 
       grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | (dev->device << 4));
+      if (grub_ata_check_ready (dev))
+       return grub_errno;
+
       /* Set "Previous".  */
       grub_ata_setlba (dev, sector >> 24, size >> 8);
       /* Set "Current".  */
@@ -673,15 +687,13 @@
                    grub_size_t size, char *buf, int rw)
 {
   struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
-  grub_size_t cnt;
-  grub_size_t batch;
-  grub_ata_addressing_t addressing;
-  int cmd;
-  int cmd_write;
-  unsigned int sect;
 
-  addressing = dev->addr;
+  grub_dprintf("ata", "grub_ata_readwrite (size=%u, rw=%d)\n", size, rw);
 
+  grub_ata_addressing_t addressing = dev->addr;
+  grub_size_t batch;
+  int cmd, cmd_write;
+
   if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0)
     {
       batch = 65536;
@@ -697,89 +709,49 @@
       cmd_write = GRUB_ATA_CMD_WRITE_SECTORS;
     }
 
-  cnt = size / batch;
-
-  /* Read/write batches of 256/65536 sectors, when more than 256/65536
-     sectors should be read/written.  */
-  for (; cnt; cnt--)
+  grub_size_t nsectors = 0;
+  while (nsectors < size)
     {
+      if (size - nsectors < batch)
+       batch = size - nsectors;
+
+      grub_dprintf("ata", "rw=%d, sector=%llu, batch=%u\n", rw, sector, batch);
+
+      /* Send read/write commmand.  */
       if (grub_ata_setaddress (dev, addressing, sector, batch))
        return grub_errno;
 
-      if (rw == 0)
-       {
-         /* Read 256/65536 sectors.  */
-         if (grub_ata_cmd (dev, cmd))
-           return grub_errno;
+      grub_ata_regset (dev, GRUB_ATA_REG_CMD, (! rw ? cmd : cmd_write));
 
-         /* Wait for the command to complete.  */
-         if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY, 
GRUB_ATA_TOUT_DATA))
-           return grub_errno;
-
-         for (sect = 0; sect < batch; sect++)
-           {
-             if (grub_ata_pio_read (dev, buf,
-                                    GRUB_DISK_SECTOR_SIZE, GRUB_ATA_TOUT_DATA))
-               return grub_errno;
-             buf += GRUB_DISK_SECTOR_SIZE;
-           }
-       }
-      else
+      unsigned sect;
+      for (sect = 0; sect < batch; sect++)
        {
-         /* Write 256/65536 sectors.  */
-         if (grub_ata_cmd (dev, cmd))
+         /* Wait for !BSY, DRQ.  */
+         if (grub_ata_wait_drq (dev, rw, GRUB_ATA_TOUT_DATA))
            return grub_errno;
 
-         /* Wait for the command to complete.  */
-         if (grub_ata_wait_status (dev, 0, GRUB_ATA_STATUS_BUSY, 
GRUB_ATA_TOUT_DATA))
-           return grub_errno;
+         /* Transfer data.  */
+         if (! rw)
+           grub_ata_pio_read (dev, buf, GRUB_DISK_SECTOR_SIZE);
+         else
+           grub_ata_pio_write (dev, buf, GRUB_DISK_SECTOR_SIZE);
 
-         for (sect = 0; sect < batch; sect++)
-           {
-             if (grub_ata_pio_write (dev, buf,
-                                     GRUB_DISK_SECTOR_SIZE, 
GRUB_ATA_TOUT_DATA))
-               return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
-             buf += GRUB_DISK_SECTOR_SIZE;
-           }
+         buf += GRUB_DISK_SECTOR_SIZE;
        }
-      sector += batch;
-    }
 
-  /* Read/write just a "few" sectors.  */
-  if (grub_ata_setaddress (dev, addressing, sector, size % batch))
-    return grub_errno;
-
-  if (rw == 0)
-    {
-      /* Read sectors.  */
-      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, 
GRUB_ATA_TOUT_DATA))
-       return grub_errno;
-
-      for (sect = 0; sect < (size % batch); sect++)
-       {
-         if (grub_ata_pio_read (dev, buf, GRUB_DISK_SECTOR_SIZE, 
GRUB_ATA_TOUT_DATA))
+      if (rw)
+        {
+         /* Check for write error.  */
+         if (grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA))
            return grub_errno;
-         buf += GRUB_DISK_SECTOR_SIZE;
-       }
-    } else {
-      /* Write sectors.  */
-      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, 
GRUB_ATA_TOUT_DATA))
-       return grub_errno;
-
-      for (sect = 0; sect < (size % batch); sect++)
-       {
-         if (grub_ata_pio_write (dev, buf, GRUB_DISK_SECTOR_SIZE, 
GRUB_ATA_TOUT_DATA))
+         if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS)
+             & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
            return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
-         buf += GRUB_DISK_SECTOR_SIZE;
        }
+
+      sector += batch;
+      nsectors += batch;
     }
 
   return GRUB_ERR_NONE;
@@ -924,10 +896,7 @@
        return grub_error (GRUB_ERR_READ_ERROR, "Invalid ATAPI transfer count");
 
       /* Read the data.  */
-      grub_uint16_t *buf16 = (grub_uint16_t *) (buf + nread);
-      unsigned i;
-      for (i = 0; i < cnt / 2; i++)
-       buf16[i] = grub_le_to_cpu16 (grub_inw (dev->ioaddress + 
GRUB_ATA_REG_DATA));
+      grub_ata_pio_read (dev, buf + nread, cnt);
 
       if (cnt & 1)
        buf[nread + cnt - 1] = (char) grub_le_to_cpu16 (grub_inw 
(dev->ioaddress + GRUB_ATA_REG_DATA));






reply via email to

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