Re: IDE disk geometry + patch

Andre M. Hedrick (
Sat, 5 Dec 1998 13:18:02 -0600 (CST)

On Fri, 4 Dec 1998 wrote:

> From Fri Dec 4 21:09:04 1998
> Please be careful, last time changes like that were made
> it killed my setup:
> Heads: 16 Sectors per Track: 63 Cylinders: 2100
> Yes, let us be careful - that is also what mlord said,
> and I reacted a bit irritated because he knows these things
> and would have understood that the change was good, even necessary,
> had he thought about it.

You don't get it Mark Lord has stopped doing the Maintaining.
I have slowly began to replace him after 6 Years of busting his
fanny. I have agreed to address the issue and have been working on it
long before you brought it to the mainstream.

Now, please on the side, give me the exact details of what you are
proposing for a solution. But in the meantime::

A snip from ide.c

case 3: /* cyl,head,sect */
drive->media = ide_disk;
drive->cyl = drive->bios_cyl = vals[0];
drive->head = drive->bios_head = vals[1];
drive->sect = drive->bios_sect = vals[2];
drive->present = 1;
drive->forced_geom = 1;
hwif->noprobe = 0;
goto done;

As you can see, if you force pass the CHS regardless of the BIOS,
Linux will overide the BIOS and force report the parameters to both

I need from you............

Documentation/ description
drivers/block/ patch

if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
if [ "$CONFIG_BLK_DEV_IDEDISK" != "n" ]; then


place original kernek code bracket here........
place your proposed changes here...........

repeat in all locations that you declare as important.

This is the only solution/compromise you will get from me,
since this is the on acceptable solution with 2.2.0 around the corner.
I promise you that this will be hard enough to get Linus to accept.

I am sitting on 250K of IDE code that maybe half will make it in by 2.2.0.
The other half is Geert's and Russell's multi-platform/chipset additions.

If I can test it and it is stable, I will carry the patch until it gets

> Now that you do not seem to know this stuff, and you are not alone,
> let me try to explain a bit more.

Sorry, but I beat you to the problem a long time ago.......
I have been discussing this with Mark for several months now.

> There are 1-dimensional disk addresses: just give a sector number n.
> And there are 3-dimensional disk addresses: give cylinder c, head h,
> sector s. If the disk has in total C cylinders, H heads, S sectors/track,
> then the conversion is n = c*H*S + h*S + s.
> (Yes, I know, some misguided people prefer to start counting sectors
> at 1 instead of 0 - they may have to subtract 1 if they count n
> from 0 but s from 1.)
> Converting back goes like c = n/(H*S), r = n%(H*S), h = r/S, s = r%S.
> Under some circumstances the 3D address is used, under some
> the 1D. For example, LILO uses the 3D address, but uses the 1D
> address if you give the keyword "linear". And fdisk describes
> a partition both in 3D and in 1D addresses.
> Now look at the conversion between the two.
> This conversion uses H and S. So, if someone comes along
> and changes the system's idea about H and S, then Bad Things
> may happen - the correspondence between 3D and 1D addresses
> has changed. Maybe DOS and Linux now disagree about where
> the partitions are and your filesystems are corrupted.
> So: Never change H and S if you can avoid it.
> On the other hand, C does not occur in these equations.
> The only place C is used is for the computation of the
> total capacity of the disk C*H*S. So, if you know the
> total capacity T, and you are careful not to change H and S,
> then you have to compute C = T/(H*S).
> OK - that is the general theory. See the Large Disk Howto
> for more details. Now what is the current point of discussion?
> If you ask a current 8+ GB disk about its geometry using the
> IDENTIFY command, it will return C/H/S=16383/16/63. These
> values are a convention, and just as you recognize 1 Jan 1970
> as "no date", so does "16383/16/63" mean "big disk, look at
> LBA capacity to see how big". Such large IDE disks did not
> exist until recently, since it was unclear how DOS could
> use them, but these days 12 GB and 16 GB IDE disks are cheap.
> Old kernels did not know about this convention, and didnt believe
> the LBA capacity if it differed more than 10% from C*H*S.
> Since 2.1.90 and 2.0.35 the Linux kernel knows about this,
> and people who do not use translation have no problems with
> these big disks.
> But most BIOSes allow you to complicate matters by choosing
> "LBA" or "Large" or "Extended" or "Translation", in which case
> C,H,S will be replaced by the BIOS by C',H',S' such that
> C*H*S = C'*H'*S'. If the BIOS does not know about the
> abovementioned convention, then it will replace 16383/16/63
> by 1023/255/63 (or 1024/255/63 or so).
> At present Linux recognizes 16383/16/63 and knows that it is
> not for real, and looks at LBA capacity to see how large the
> disk is in reality, but the kernel does not recognize such
> translated geometries like 1023/255/63.
> This leads to the situation where fdisk can only describe
> 8 GB of a much larger disk in case the BIOS uses some translation.
> The solution is very simple. When the kernel has decided on
> what the total capacity T of the disk is, and the BIOS has
> mentioned its favourite H and S, the kernel must compute
> C = T/(H*S).

In reality, if it was that simple, don't you think that it would have been
done a long time ago? Your intentions are helpful, but potentially short
sighted in backwards compatibilty.

You forgot to address the other following issues in your rush to protest
the slow grinding pace the kernel development takes.

static int lba_capacity_is_ok (struct hd_driveid *id) {

if ((id->lba_capacity >= 16514064) &&
(id->heads == 16 || id->heads == 15) &&
(id->sectors == 63)) {
id->cyls = (int)(id->lba_capacity/(id->heads * id->sectors));
drive->bios_cyl = id->cyls;
drive->bios_head = id->heads;
drive->bios_sect = id->sectors;
drive->forced_geom = 1;
return 0; /* lba_capacity value is not wanted */

static void idedisk_add_settings(ide_drive_t *drive) {

ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_SHORT, 0,
1023, 1, 1, &drive->bios_cyl, NULL);

This allow other parts of the driver to see the rest
of the sectors correctly.

ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_SHORT, 0,
32768, 1, 1, &drive->bios_cyl, NULL);


> Andries

Andre Hedrick
The IDE-FNG for Linux
The APC UPS Specialist for Linux

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
Please read the FAQ at