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

The following code works in NT4.0.

===========================
//
// See if the device supports LBA mode translation. Word 60 & 61.
// If the first condition is met then check Word 1, Word 3 & Word 6.
// Note: FullIdentifyData + 60 == FullIdentifyData.UserAddressableSectors
//

if (*(PULONG)((PUSHORT)&deviceExtension->FullIdentifyData + 60) > 0x00FBFFFF
&& (deviceExtension->FullIdentifyData.NumberOfCylinders == 0x3FFF &&
deviceExtension->FullIdentifyData.NumberOfHeads == 0x10 &&
deviceExtension->FullIdentifyData.SectorsPerTrack == 0x3F)) {

DebugPrint((0,“IssueIdentify: IDE drive %d supports LBA\n”,
Channel * 2 + DeviceNumber));

deviceExtension->DeviceFlags[(Channel * 2) + DeviceNumber] |= IDENTIFY_CAPABILITIES_LBA_SUPPORTED;

//
// Copy UserAddressableSectors to DeviceExtension
//

deviceExtension->UserAddressableSectors[(Channel * 2) + DeviceNumber] =
*(PULONG)((PUSHORT)&deviceExtension->FullIdentifyData + 60);
}

=============================

case SCSIOP_READ_CAPACITY:

//
// Claim 512 byte blocks (big-endian).
//

((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock = 0x20000;

//
// Calculate last sector.
//

//
// See whether the device supports LBA mode Translation
// otherwise wrong data will be passed on to the disk class driver
// and Disk Administrator will not show the correct size of the
// physical harddisk.
//

if (deviceExtension->DeviceFlags[Srb->TargetId] & IDENTIFY_CAPABILITIES_LBA_SUPPORTED) {
i = (deviceExtension->UserAddressableSectors[Srb->TargetId]) - 1;
} else {
i = (deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads *
deviceExtension->IdentifyData[Srb->TargetId].NumberOfCylinders *
deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack) - 1;
}

((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress =
(((PUCHAR)&i)[0] << 24) | (((PUCHAR)&i)[1] << 16) |
(((PUCHAR)&i)[2] << 8) | ((PUCHAR)&i)[3];

if (deviceExtension->DeviceFlags[Srb->TargetId] & IDENTIFY_CAPABILITIES_LBA_SUPPORTED) {
DebugPrint((0,
“IDE LBA disk %x - total # of sectors 0x%x\n”,
Srb->TargetId,
deviceExtension->UserAddressableSectors[Srb->TargetId]));
} else {
DebugPrint((0,
“IDE CHS disk %x - #sectors %x, #heads %x, #cylinders %x\n”,
Srb->TargetId,
deviceExtension->IdentifyData[Srb->TargetId].SectorsPerTrack,
deviceExtension->IdentifyData[Srb->TargetId].NumberOfHeads,
deviceExtension->IdentifyData[Srb->TargetId].NumberOfCylinders));
}

status = SRB_STATUS_SUCCESS;
break;

===================================

-----Original Message-----
From: Barila, Phil [mailto:xxxxx@intel.com]
Sent: Monday, April 02, 2001 5:19 PM
To: NT Developers Interest List
Subject: [ntdev] Re: QESTION For Real Kernel Hackers. ATA IDENTIFY DAT A & NT/2K

-----Original Message-----
From: D. K. [mailto:xxxxx@homepage.ru]
Sent: Monday, April 02, 2001 2:35 PM
To: NT Developers Interest List
Subject: [ntdev] Re: QESTION For Real Kernel Hackers. ATA
IDENTIFY DATA & NT/2K

“Maxim S. Shatskih” wrote:
>
> > 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 ===
>
> Are you replacing the system-supplied ATA driver?

No.

If no - then why not query
the system’s ATA driver for the disk IDENTIFY data?

My method is faster.
As I have understood from your last message, result will be different?
In my case UserAddressableSectors have not true value…

If you aren’t the ATAPI driver, you really shouldn’t be twiddling the bits
on the ATAPI hardware. How often do you do this, that speed is an issue?
You should only be doing this at startup, and the startup time will be
dominated by other activities. The IDENTIFY_DEVICE data doesn’t come off
the spindle, so it’s a very fast operation, anyway. The driver will return
it in approximately the same amount of time that you can attach directly to
the hardware and get it from there. So the right approach is to query the
driver for it.

In a previous message, I detailed where to find the information you need.
If you really must twiddle bits you shouldn’t twiddle, then you might have a
look at the spec I referenced in my earlier message. In answer to your
earlier question, no, you can’t use CHS at all for a drive larger than 8 GB.
You have to use LBA. Since LBA is faster than CHS, you should use it any
time you can. I offer a hint: The legacy value, for any drive > 8.4 GB, is
a DWORD with value 0xFBFC10, which is 0x3FFF * 0x10 * 0x3F. Conversion to
decimal values is left as an exercise for the reader. Since your original
post referred to a value of 0x7000 somewhere further up in the NT4 ATAPI
stack, I would first look at your own code to see if you are corrupting the
IDENTIFY_DEVICE data. Are you properly byte swapping everything that needs
to be byte swapped? Not everything needs to be swapped when you use it, but
some of it does.

In my vast ( :slight_smile: for the humor impaired ) 1 year plus of doing ATAPI driver
work, the smallest and oldest drive I have had available to test on was 800
MB. Even that one returned the correct number of LBAs in both of the
locations I mentioned in my earlier message. I know that there are older
drives that don’t do LBA right, and must be addressed with CHS, but I
haven’t used any. But do it right, use the existing ATAPI driver.

Phil
* Philip D. Barila | (503) 264-8386
* Intel Corp. | M/S JF2-53 Office JF2-2-G6
* Storage Architecture and Performance
* Internet Systems Lab


You are currently subscribed to ntdev as: xxxxx@netapp.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