QESTION For Real Kernel Hackers. ATA IDENTIFY DATA & NT/2K

Hi, dear all!

I have written the device driver which reads
the ATA Identify Device Data through ports(on Windows NT/2k).

I have looked as my FreeBSD 4.2 determines real size HDD in
her ATA dev(ice) driver at boot time:

==cut here==
total_secs = cylinders * heads * sectors;
if (cylinders == 16383 && total_secs < lbasize)
total_secs = lbasize;
==cut here==

Where: ATA offset ATA description
cylinders - // 1 number of fixed cyls
heads - // 3 number of heads
sectors - // 4 bytes/track
lbasize - // 60 total number of user addressable sectors (LBA mode)

At booting FreeBSD correctly determines HDD size.
For my 15GB HDD lbasize(at boot time)= 30021632

But! When i read lbasize at Windows NT(SP6a)/ Windows 2000
it always = 0x70000 ~ 224 MB.
On any HDD…

Why?

Best Reards,
Dmitry Koptelov


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> At booting FreeBSD correctly determines HDD size.

For my 15GB HDD lbasize(at boot time)= 30021632

But! When i read lbasize at Windows NT(SP6a)/ Windows 2000
it always = 0x70000 ~ 224 MB.

NT4/late SPs logic for ATA disk sizing:

if( ( NumberOfCylinders == 16383 ) && ( NumberOfHeads == 16 ) &&
( SectorsPerTrack == 63 ) )

  • then consider this disk as LBA and use LBA mode to work with it.

This occur only for >8GB drives.
For LBA disks, the disk size is UserAddressableSectors field of IDENTIFY
DATA structure.
For CHS disks, it is the multiple of CHS values.

NT4/no SPs (the ATAPI source is provided) do not use LBA at all and talks
CHS to any disks. The disk size is a multiple of CHS values.

Max


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

U wanted actual size of HDD, I mean in ur case u should get 15GB right ?

how are u reading the size to detrmine the HDD size ?

Regards,
Satish K.S

----- Original Message -----
From: “D. K.”
To: “NT Developers Interest List”
Sent: Thursday, March 29, 2001 2:50 PM
Subject: [ntdev] QESTION For Real Kernel Hackers. ATA IDENTIFY DATA & NT/2K

> Hi, dear all!
>
> I have written the device driver which reads
> the ATA Identify Device Data through ports(on Windows NT/2k).
>
> I have looked as my FreeBSD 4.2 determines real size HDD in
> her ATA dev(ice) driver at boot time:
>
> ==cut here==
> total_secs = cylinders * heads * sectors;
> if (cylinders == 16383 && total_secs < lbasize)
> total_secs = lbasize;
> ==cut here==
>
> Where: ATA offset ATA description
> cylinders - // 1 number of fixed cyls
> heads - // 3 number of heads
> sectors - // 4 bytes/track
> lbasize - // 60 total number of user addressable sectors
(LBA mode)
>
> At booting FreeBSD correctly determines HDD size.
> For my 15GB HDD lbasize(at boot time)= 30021632
>
> But! When i read lbasize at Windows NT(SP6a)/ Windows 2000
> it always = 0x70000 ~ 224 MB.
> On any HDD…
>
> Why?
>
> Best Reards,
> Dmitry Koptelov
>
> —
> You are currently subscribed to ntdev as: xxxxx@aalayance.com
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Why dont u try by Reading MBR Sector Directly and calculate Total size of
HDD ?

Regards,
Satish K.S

----- Original Message -----
From: “D. K.”
To: “NT Developers Interest List”
Sent: Saturday, March 31, 2001 4:22 PM
Subject: [ntdev] Re: QESTION For Real Kernel Hackers. ATA IDENTIFY DATA &
NT/2K

> Satish wrote:
> >
> > U wanted actual size of HDD, I mean in ur case u should get 15GB right ?
>
> Yes!
>
> > how are u reading the size to detrmine the HDD size ?
>
> driver.c
> === cut here ===
>
> #define ATA_PRI_M 0x1f0 // base address of primary
controller
> #define ATA_SEC_M 0x170 // base address of secondary
controller
>
> #define ATA_REG_DATA 0 // data register
> #define ATA_REG_DEV 6 // device register
> #define ATA_REG_CMD 7 // command register
> #define ATA_REG_STATUS 7 // status register
>
> #define DEV_OFF 4
> #define ATA_DEV_NUM(dev) (0xA0 + ((dev)<<dev_off>>
> #define ATA_CMD_GETP 0xec // get drive parameters
>
> #define DEVICE ATA_DEV_NUM(0) // <<< Set IDE to read here >>>
> #define ADAPTER ATA_PRI_M // <<< Set IDE to read here >>>
>
> #define DRQ 8 // DRQ status mask
>
> union idbuf {
> ID_PARMS parms;
> USHORT data[256];
> };
>
> /* […] /
>
> NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
> IN PUNICODE_STRING RegistryPath) {
> UCHAR sreg;
> int i;
>
> /
[…] /
>
> //
> // Select the adapter
> //
> WRITE_PORT_UCHAR((PUCHAR)(ADAPTER + ATA_REG_DEV), DEVICE);
> Wait400ns();
> //
> // The Identify Device Command
> //
> WRITE_PORT_UCHAR((PUCHAR)(ADAPTER + ATA_REG_CMD), ATA_CMD_GETP);
> Wait400ns();
>
> //
> // Read status register
> //
> sreg = READ_PORT_UCHAR((PUCHAR)(ADAPTER + ATA_REG_STATUS));
>
> if (!(sreg & DRQ)) {
>
> DbgPrint((“%s: Data not ready! Status= %#x\n”, DEVICE_NAME,
sreg));
>
> IoDeleteSymbolicLink(&uniWin32NameString);
> IoDeleteDevice(DriverObject->DeviceObject);
> return STATUS_UNSUCCESSFUL;
> }
> //
> // Read Identify Device data
> //
> for (i = 0; i < 256; i++)
> iddata.data[i] = (USHORT)READ_PORT_USHORT((PUSHORT)(ADAPTER +
ATA_REG_DATA));
>
> /
[…] */
>
> return STATUS_SUCCESS;
> }
>
> VOID Wait400ns(VOID){
>
> LARGE_INTEGER start, current;
> ULONG k = KeQueryTimeIncrement();
>
> KeQuerySystemTime(&start);
>
> do {
>
> KeQuerySystemTime(&current);
>
> } while((current.QuadPart - start.QuadPart) < 4 * k);
> }
>
> === cut here ===
> test.c
> === cut here ===
>
> cyl = id_params.fcyl; // 1 offset at id_params(IDENTIFY DATA)
> heads = id_params.hds; // 3
> sects = id_params.spt; // 6 sectors/track
> // id_params.tsecs // 60 total number of user addressable sectors
(LBA mode)
>
> total_secs = cyl * heads * sects;
>
> if (cyl == 16383 && total_secs < id_params.tsecs)
> total_secs = id_params.tsecs;
>
> printf(“HDD C/H/S : %lu/%lu/%lu [%luMB]\n\n”,
> total_secs / (heads * sects), heads, sects,
> total_secs / (1024L * 1024L / 512));
> === cut here ===
>
> >


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com</dev_off>

MBR dosent always contain the size. IDENTIFY data is the best.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Satish
Sent: Saturday, March 31, 2001 4:30 AM
To: NT Developers Interest List
Subject: [ntdev] Re: QESTION For Real Kernel Hackers. ATA IDENTIFY DATA
& NT/2K

Why dont u try by Reading MBR Sector Directly and calculate Total size of
HDD ?

Regards,
Satish K.S

----- Original Message -----
From: “D. K.”
> To: “NT Developers Interest List”
> Sent: Saturday, March 31, 2001 4:22 PM
> Subject: [ntdev] Re: QESTION For Real Kernel Hackers. ATA IDENTIFY DATA &
> NT/2K
>
>
> > Satish wrote:
> > >
> > > U wanted actual size of HDD, I mean in ur case u should get
> 15GB right ?
> >
> > Yes!
> >
> > > how are u reading the size to detrmine the HDD size ?
> >
> > driver.c
> > === cut here ===
> >
> > #define ATA_PRI_M 0x1f0 // base address of primary
> controller
> > #define ATA_SEC_M 0x170 // base address of secondary
> controller
> >
> > #define ATA_REG_DATA 0 // data register
> > #define ATA_REG_DEV 6 // device register
> > #define ATA_REG_CMD 7 // command register
> > #define ATA_REG_STATUS 7 // status register
> >
> > #define DEV_OFF 4
> > #define ATA_DEV_NUM(dev) (0xA0 + ((dev)<<dev_off>> >
> > #define ATA_CMD_GETP 0xec // get drive parameters
> >
> > #define DEVICE ATA_DEV_NUM(0) // <<< Set IDE to read here >>>
> > #define ADAPTER ATA_PRI_M // <<< Set IDE to read here >>>
> >
> > #define DRQ 8 // DRQ status mask
> >
> > union idbuf {
> > ID_PARMS parms;
> > USHORT data[256];
> > };
> >
> > /* […] /
> >
> > NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
> > IN PUNICODE_STRING RegistryPath) {
> > UCHAR sreg;
> > int i;
> >
> > /
[…] /
> >
> > //
> > // Select the adapter
> > //
> > WRITE_PORT_UCHAR((PUCHAR)(ADAPTER + ATA_REG_DEV), DEVICE);
> > Wait400ns();
> > //
> > // The Identify Device Command
> > //
> > WRITE_PORT_UCHAR((PUCHAR)(ADAPTER + ATA_REG_CMD), ATA_CMD_GETP);
> > Wait400ns();
> >
> > //
> > // Read status register
> > //
> > sreg = READ_PORT_UCHAR((PUCHAR)(ADAPTER + ATA_REG_STATUS));
> >
> > if (!(sreg & DRQ)) {
> >
> > DbgPrint((“%s: Data not ready! Status= %#x\n”, DEVICE_NAME,
> sreg));
> >
> > IoDeleteSymbolicLink(&uniWin32NameString);
> > IoDeleteDevice(DriverObject->DeviceObject);
> > return STATUS_UNSUCCESSFUL;
> > }
> > //
> > // Read Identify Device data
> > //
> > for (i = 0; i < 256; i++)
> > iddata.data[i] = (USHORT)READ_PORT_USHORT((PUSHORT)(ADAPTER +
> ATA_REG_DATA));
> >
> > /
[…] */
> >
> > return STATUS_SUCCESS;
> > }
> >
> > VOID Wait400ns(VOID){
> >
> > LARGE_INTEGER start, current;
> > ULONG k = KeQueryTimeIncrement();
> >
> > KeQuerySystemTime(&start);
> >
> > do {
> >
> > KeQuerySystemTime(&current);
> >
> > } while((current.QuadPart - start.QuadPart) < 4 * k);
> > }
> >
> > === cut here ===
> > test.c
> > === cut here ===
> >
> > cyl = id_params.fcyl; // 1 offset at id_params(IDENTIFY DATA)
> > heads = id_params.hds; // 3
> > sects = id_params.spt; // 6 sectors/track
> > // id_params.tsecs // 60 total number of user
> addressable sectors
> (LBA mode)
> >
> > total_secs = cyl * heads * sects;
> >
> > if (cyl == 16383 && total_secs < id_params.tsecs)
> > total_secs = id_params.tsecs;
> >
> > printf(“HDD C/H/S : %lu/%lu/%lu [%luMB]\n\n”,
> > total_secs / (heads * sects), heads, sects,
> > total_secs / (1024L * 1024L / 512));
> > === cut here ===
> >
> > >
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
>


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com</dev_off>

Using partation Info u can always get the size of HardDisk. OS will also
use the samething after partationing the HardDisk.

If not, then does OS will get the size of Partation ?

Regards,
Satish K.S

----- Original Message -----
From: “Jamey Kirby”
To: “NT Developers Interest List”
Sent: Saturday, March 31, 2001 9:31 PM
Subject: [ntdev] Re: QESTION For Real Kernel Hackers. ATA IDENTIFY DATA &
NT/2K

> MBR dosent always contain the size. IDENTIFY data is the best.
>
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
> > [mailto:xxxxx@lists.osr.com]On Behalf Of Satish
> > Sent: Saturday, March 31, 2001 4:30 AM
> > To: NT Developers Interest List
> > Subject: [ntdev] Re: QESTION For Real Kernel Hackers. ATA IDENTIFY DATA
> > & NT/2K
> >
> >
> > Why dont u try by Reading MBR Sector Directly and calculate Total size
of
> > HDD ?
> >
> > Regards,
> > Satish K.S
> >
> > ----- Original Message -----
> > From: “D. K.”
> > To: “NT Developers Interest List”
> > Sent: Saturday, March 31, 2001 4:22 PM
> > Subject: [ntdev] Re: QESTION For Real Kernel Hackers. ATA IDENTIFY DATA
&
> > NT/2K
> >
> >
> > > Satish wrote:
> > > >
> > > > U wanted actual size of HDD, I mean in ur case u should get
> > 15GB right ?
> > >
> > > Yes!
> > >
> > > > how are u reading the size to detrmine the HDD size ?
> > >
> > > driver.c
> > > === cut here ===
> > >
> > > #define ATA_PRI_M 0x1f0 // base address of primary
> > controller
> > > #define ATA_SEC_M 0x170 // base address of secondary
> > controller
> > >
> > > #define ATA_REG_DATA 0 // data register
> > > #define ATA_REG_DEV 6 // device register
> > > #define ATA_REG_CMD 7 // command register
> > > #define ATA_REG_STATUS 7 // status register
> > >
> > > #define DEV_OFF 4
> > > #define ATA_DEV_NUM(dev) (0xA0 + ((dev)<<dev_off>> > >
> > > #define ATA_CMD_GETP 0xec // get drive parameters
> > >
> > > #define DEVICE ATA_DEV_NUM(0) // <<< Set IDE to read here
>>>
> > > #define ADAPTER ATA_PRI_M // <<< Set IDE to read here
>>>
> > >
> > > #define DRQ 8 // DRQ status mask
> > >
> > > union idbuf {
> > > ID_PARMS parms;
> > > USHORT data[256];
> > > };
> > >
> > > /* […] /
> > >
> > > NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
> > > IN PUNICODE_STRING RegistryPath) {
> > > UCHAR sreg;
> > > int i;
> > >
> > > /
[…] /
> > >
> > > //
> > > // Select the adapter
> > > //
> > > WRITE_PORT_UCHAR((PUCHAR)(ADAPTER + ATA_REG_DEV), DEVICE);
> > > Wait400ns();
> > > //
> > > // The Identify Device Command
> > > //
> > > WRITE_PORT_UCHAR((PUCHAR)(ADAPTER + ATA_REG_CMD), ATA_CMD_GETP);
> > > Wait400ns();
> > >
> > > //
> > > // Read status register
> > > //
> > > sreg = READ_PORT_UCHAR((PUCHAR)(ADAPTER + ATA_REG_STATUS));
> > >
> > > if (!(sreg & DRQ)) {
> > >
> > > DbgPrint((“%s: Data not ready! Status= %#x\n”, DEVICE_NAME,
> > sreg));
> > >
> > > IoDeleteSymbolicLink(&uniWin32NameString);
> > > IoDeleteDevice(DriverObject->DeviceObject);
> > > return STATUS_UNSUCCESSFUL;
> > > }
> > > //
> > > // Read Identify Device data
> > > //
> > > for (i = 0; i < 256; i++)
> > > iddata.data[i] = (USHORT)READ_PORT_USHORT((PUSHORT)(ADAPTER +
> > ATA_REG_DATA));
> > >
> > > /
[…] */
> > >
> > > return STATUS_SUCCESS;
> > > }
> > >
> > > VOID Wait400ns(VOID){
> > >
> > > LARGE_INTEGER start, current;
> > > ULONG k = KeQueryTimeIncrement();
> > >
> > > KeQuerySystemTime(&start);
> > >
> > > do {
> > >
> > > KeQuerySystemTime(&current);
> > >
> > > } while((current.QuadPart - start.QuadPart) < 4 * k);
> > > }
> > >
> > > === cut here ===
> > > test.c
> > > === cut here ===
> > >
> > > cyl = id_params.fcyl; // 1 offset at id_params(IDENTIFY DATA)
> > > heads = id_params.hds; // 3
> > > sects = id_params.spt; // 6 sectors/track
> > > // id_params.tsecs // 60 total number of user
> > addressable sectors
> > (LBA mode)
> > >
> > > total_secs = cyl * heads * sects;
> > >
> > > if (cyl == 16383 && total_secs < id_params.tsecs)
> > > total_secs = id_params.tsecs;
> > >
> > > printf(“HDD C/H/S : %lu/%lu/%lu [%luMB]\n\n”,
> > > total_secs / (heads * sects), heads, sects,
> > > total_secs / (1024L * 1024L / 512));
> > > === cut here ===
> > >
> > > >
> >
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> > To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
> >
>
> —
> You are currently subscribed to ntdev as: xxxxx@aalayance.com
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com</dev_off>