diff -aur grub-0.96-orig/lib/device.c grub-0.96/lib/device.c --- grub-0.96-orig/lib/device.c 2005-03-21 15:07:17.394333000 +0100 +++ grub-0.96/lib/device.c 2005-03-21 15:47:56.695502856 +0100 @@ -147,6 +147,8 @@ /* XXX This is the default size. */ geom->sector_size = SECTOR_SIZE; + /* Use 0 to test later on if sector value has already been correctly retrieved. */ + geom->total_sectors = 0; #if defined(__linux__) /* Linux */ @@ -154,17 +156,16 @@ struct hd_geometry hdg; unsigned long nr; + if (! ioctl (fd, BLKGETSIZE, &nr)) + geom->total_sectors = nr; + if (ioctl (fd, HDIO_GETGEO, &hdg)) goto fail; - if (ioctl (fd, BLKGETSIZE, &nr)) - goto fail; - /* Got the geometry, so save it. */ geom->cylinders = hdg.cylinders; geom->heads = hdg.heads; geom->sectors = hdg.sectors; - geom->total_sectors = nr; goto success; } @@ -236,9 +237,17 @@ given a proper st_blocks size. */ if (drive & 0x80) { + /* If a total sector count has been found and it exceeds CHS capacities, + * use large drive placeholder values. */ + if (geom->total_sectors && (geom->total_sectors >= 255*63*1024)) { + geom->cylinders = 1024; + geom->heads = 255; + geom->sectors = 63; + } else { geom->cylinders = DEFAULT_HD_CYLINDERS; geom->heads = DEFAULT_HD_HEADS; geom->sectors = DEFAULT_HD_SECTORS; + } } else { @@ -247,11 +256,13 @@ geom->sectors = DEFAULT_FD_SECTORS; } - /* Set the total sectors properly, if we can. */ + /* If total sectors hasn't been set yet, try and get a proper value. */ + if (! geom->total_sectors) { if (! fstat (fd, &st) && st.st_blocks) geom->total_sectors = st.st_blocks; else geom->total_sectors = geom->cylinders * geom->heads * geom->sectors; + } } success: