[Kos-dev] Re: Few questions about CHS and LBA

Søren Schmidt kos-dev@enix.org
Tue, 5 Feb 2002 10:33:43 +0100 (CET)

It seems thomas.petazzoni@enix.org wrote:
> Hi,
> Again me with a few questions concerning CHS and LBA.
> 1) There's seems to be two CHS configuration for a hard drive. A
>    Physical CHS configuration (used by the ATA device, where head<15,
>    cylinder up to 65536, and up to 63 sectors/track). And a logical
>    CHS configuration, which can be found in the values returned by a
>    IDENTIFY DRIVE command. 
>    For instance on my harddirve (a Quantum 810Mb), I have the
>    following configurations :
>         - Logicial : 822 cylinders, 32 heads, 63 sectors/track
>         - Physical : 1644 cylinders, 16 heads, 63 sectors/track
>    At the beginning of my test, I tried to directly address the disk
>    using the Logical CHS configuration, but that's not possible :
>    there's 32 heads, and the space for Head is 4 bit (in the
>    register). So I looked at my drive and saw the Physical CHS
>    configuration. ANd it worked. But now THE QUESTION : how can I
>    detect this Physical CHS configuration ?
>    On this drive, the conversion is pretty easy (too much head =>
>    multiply the number of cylinders), but on other harddrives ? For
>    instance I can see a harddrive which is 1010/16/51 (51
>    sectors/track). How can I know that without looking directly inside
>    the computer.
>    In some documentations I saw it is not possible to get this
>    information without calling INT 13 (which actually uses Physical
>    CHS translation for adressing the disk, and can returns this
>    configuration).
>    I'm sure you're doing in an other way. But I looked at the code,
>    and couldn't find anything about it.

Well, the whole geometry thing is a many headed monster, and there is
many solutions to the problems all with good and bad sides.
In FreeBSD I *always* use LBA mode if at all possible, and where
geometry is needed I use the physical layout of the disk.
The problem is only when dealing with FDISK or other partition 
systems, that might have a different view on the geometry...
Luckily this is not a driver issue, the driver only should
now how to address sector X, and that is always doen with LBA
if at all possible, else the physical geometry is used.

> 2) My second question is about LBA. On my Quantum 810 Mb, LBA seems to
>    be present : it's configured in the BIOS, and the information
>    returned by the IDENTIFY DRIVE Command says that LBA is activated.
>    But when I try the following piece of code :
> for(i = 1; i < 1002; i++)
> {
>   memset(buffer2, 0xBB, 512);
> if(add_ide_op_polled_mode(harddisk, /* the harddrive */
>                           READ,     /* type of operation */
>                           (i>>8)&0xffff, /* cylinder */
>                           ((i>>24)&0xf)|0x40, /* head | 0x40 (LBA) */
>                           i&0xff, /* sector number */
>                           buffer2) < 0)
>     break;
> }
>    It fails for sector 64. So just the sector after the sectors/track
>    limit, just as if I had to increment head by one. But this
>    harddrive should be LBA compliant (and says it is !). I activate
>    LBA, and use this mode, but nothing works !
>    For a long time, I thought my code was very wrong. So I tried on a
>    more recent PC : a laptop (Fujitsu). And this code worked. It
>    didn't failed at reading the 1001 first sectors using LBA
>    addressing.
>    So what's the deal ? It is possible to have a harddrive which
>    claims to be LBA Compliant, and which is not LBA compliant ? That
>    would sucks a lot !

Well, welcome to the wonderfull world of ATA versions :)
Now some older driver can report their size in LBA sectors, but
they dont understand LBA mode as such..
This code does the magic in FreeBSD:

    /* does this device need oldstyle CHS addressing */
    if (!ad_version(atadev->param->version_major) ||
        !(atadev->param->atavalid & ATA_FLAG_54_58) || !atadev->param->lba_size)
        adp->flags |= AD_F_CHS_USED;

> 3) Last question, for the detection of hard drives and CD-ROMs I used
>    your code taken from FreeBSD. It works fine on every machine I
>    tried it, except onmy laptop. On my laptop there's a CD-ROM on hdc
>    (secondary master), and your code detects it on Secondary Master
>    AND on Secondary Slave.
>    So it seems that there's something to do in this code :
>    /* check what is the type of the device */
>    outb(ATA_D_IBM | ATA_MASTER, ctrl->ioaddr + ATA_DRIVE);
>    usleep(10);
>    if(inb(ctrl->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
>       inb(ctrl->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB)
>      {
>        ctrl->devices |= ATA_ATAPI_MASTER;
>      }
>    ANOTHER VALUE ? (0 for instance). So I suggest :
>             outb(0, ctrl->ioaddr + ATA_CYL_LSB);
>             outb(0, ctrl->ioaddr + ATA_CYL_MSB); */
>    outb(ATA_D_IBM | ATA_SLAVE, ctrl->ioaddr + ATA_DRIVE);
>    usleep(10);
>    if(inb(ctrl->ioaddr + ATA_CYL_LSB) == ATAPI_MAGIC_LSB &&
>       inb(ctrl->ioaddr + ATA_CYL_MSB) == ATAPI_MAGIC_MSB)
>      {
>        ctrl->devices |= ATA_ATAPI_SLAVE;
>      }
>    What do you think about it ?

Congrats, you found a device that exhibits the "fake slave" problem,
there is no reliable way to solve this problem, or at least I know
of nobody that has. The problem is that some bogus ATAPI devices
reacts on both master and slave requests when you access the register
file, it is only when you try to give it a command it fails, ie there
is no way to tell before you have a command time out on you...