Package: grub
Version: 0.5.93.1

I have a buggy BIOS that supports the extended drive information call, but
not LBA read.  Grub can't read anything from the disk if NO_INT13_FALLBACK
is defined.  I see no reason not to enable the fallback all the time; the
appended patch for bios.c does that, and cleans up the logic a bit.

The motherboard is an Asus P3B-F; I am not sure of the precise BIOS
revision.

Incidentally, shouldn't grub use the cylinder/head/sector values from the
extended drive info call if available?

zw

--- grub-0.5.93.1/stage2/bios.c Thu Aug 12 02:38:44 1999
+++ grub-0.5.93.1z/stage2/bios.c        Sat Dec 25 08:55:26 1999
@@ -37,7 +37,14 @@
                                unsigned long *cylinders,
                                unsigned long *heads,
                                unsigned long *sectors);
-
+struct disk_address_packet
+{
+  unsigned char length;
+  unsigned char reserved;
+  unsigned short blocks;
+  unsigned long buffer;
+  unsigned long long block;
+};
 
 /* Read/write NSEC sectors starting from SECTOR in DRIVE disk with GEOMETRY
    from/into SEGMENT segment. If READ is BIOSDISK_READ, then read it,
@@ -48,19 +55,12 @@
 biosdisk (int read, int drive, struct geometry *geometry,
          int sector, int nsec, int segment)
 {
-  int err;
+  struct disk_address_packet dap;
+  int cylinder_offset, head_offset, sector_offset;
+  int head;
   
   if (geometry->flags & BIOSDISK_FLAG_LBA_EXTENSION)
     {
-      struct disk_address_packet
-      {
-       unsigned char length;
-       unsigned char reserved;
-       unsigned short blocks;
-       unsigned long buffer;
-       unsigned long long block;
-      } dap;
-      
       if (sector >= geometry->total_sectors)
        return BIOSDISK_ERROR_GEOMETRY;
 
@@ -70,46 +70,33 @@
       dap.block = sector;
       dap.blocks = nsec;
       dap.reserved = 0;
-      /* This is undocumented part. The address is formated in
-        SEGMENT:ADDRESS.  */
+      /* The buffer address is expected in SEGMENT:OFFSET notation.
+        We know the OFFSET is zero.  */
       dap.buffer = segment << 16;
       
-      err = biosdisk_int13_extensions (read + 0x42, drive, &dap);
+      if (biosdisk_int13_extensions (read + 0x42, drive, &dap) == 0)
+       return 0;
 
-#define NO_INT13_FALLBACK      1
-#ifndef NO_INT13_FALLBACK
-      if (err)
-       {
-         geometry->flags &= ~BIOSDISK_FLAG_LBA_EXTENSION;
-         geometry->total_sectors = (geometry->cylinders
-                                    * geometry->heads
-                                    * geometry->sectors);
-         return biosdisk (read, drive, geometry, sector, nsec, segment);
-       }
-#endif /* ! NO_INT13_FALLBACK */
-      
+      /* That didn't work.  Fall back to the old BIOS call.  */
+      geometry->flags &= ~BIOSDISK_FLAG_LBA_EXTENSION;
+      geometry->total_sectors = (geometry->cylinders
+                                * geometry->heads
+                                * geometry->sectors);
     }
-  else
-    {
-      int cylinder_offset, head_offset, sector_offset;
-      int head;
 
-      /* SECTOR_OFFSET is counted from one, while HEAD_OFFSET and
-        CYLINDER_OFFSET are counted from zero.  */
-      sector_offset = sector % geometry->sectors + 1;
-      head = sector / geometry->sectors;
-      head_offset = head % geometry->heads;
-      cylinder_offset = head / geometry->heads;
+  /* SECTOR_OFFSET is counted from one, while HEAD_OFFSET and
+     CYLINDER_OFFSET are counted from zero.  */
+  sector_offset = sector % geometry->sectors + 1;
+  head = sector / geometry->sectors;
+  head_offset = head % geometry->heads;
+  cylinder_offset = head / geometry->heads;
       
-      if (cylinder_offset >= geometry->cylinders)
-       return BIOSDISK_ERROR_GEOMETRY;
-
-      err = biosdisk_standard (read + 0x02, drive,
-                              cylinder_offset, head_offset, sector_offset,
-                              nsec, segment);
-    }
+  if (cylinder_offset >= geometry->cylinders)
+    return BIOSDISK_ERROR_GEOMETRY;
 
-  return err;
+  return biosdisk_standard (read + 0x02, drive,
+                           cylinder_offset, head_offset, sector_offset,
+                           nsec, segment);
 }
 
 /* Return the geometry of DRIVE in GEOMETRY. If an error occurs, return

Reply via email to