Messages in this thread Patch in this message | | | Date | Sat, 23 Jan 1999 02:11:52 +0100 | From | Roger Espel Llima <> | Subject | Re: 10.2 Gig HDD : 2.0.36 patch for better C/H/S translation |
| |
> Basically there are *no* problems with large disks.
Well, I just helped someone get Linux to use the last 4G of his 12G disk, and fdisk wouldn't recognize them automatically (I had to tell it the number of "bios" cylinders), so there *is* a problem.
The kernel is 2.0.36, unpatched.
His bios does LBA, so the Linux kernel has no problem accessing sectors above 8G. However, the C/H/S reported by the bios is 1024/255/63, while C/H/S reported by the IDE probe is 25113/16/63. The former is saved for fdisk's benefit, but should be corrected to 1575/255/63.
I've tried with 2.2.0-pre9, and it gets this right.
With 2.0.36, the kernel does notice that 1024/255/63 is smaller than the reported size, but it also notices that 255 (bios heads) != 16 (ATA probe heads), so it (rightly) won't set it to 25133/255/63.
However, at this point it should realize that, 1024/255/63 being the bios's maximum, it makes sense to just calculate a new cylinder number based on the total size.
Here's a patch for 2.0.36 that makes it work in this special case.
Disclaimer: This patch works for me and should be safe, at least for "normal" situations (I don't know about disk managers). Messing with fdisk and its parameters is inherently dangerous, so be careful, and use at your own risk.
Roger -- Roger Espel Llima, espel@llaic.u-clermont1.fr http://www.eleves.ens.fr:8080/home/espel/index.html --- ide.c.org Sat Jan 23 01:42:35 1999 +++ ide.c Sat Jan 23 01:55:04 1999 @@ -2585,6 +2585,19 @@ if (drive->sect == drive->bios_sect && drive->head == drive->bios_head) { if (drive->cyl > drive->bios_cyl) drive->bios_cyl = drive->cyl; + + /* same, when the bios value is as big as it can be, but the ide + * probe didn't return the same number of heads -orabidoo + */ + } else if (drive->sect == 63 && drive->head == 16 && + drive->bios_sect == 63 && drive->bios_head == 255 && + drive->bios_cyl == 1024) { + + unsigned long my_cyl = drive->cyl * 16 / 255; + + /* more than 128G (ide limit) => probably bogus */ + if (my_cyl > 1024 && my_cyl < 16384) + drive->bios_cyl = my_cyl; } if (!strncmp(id->model, "BMI ", 4) && | |