I need to issue the TRIM command to a solid state drive that I am streaming data to.
I am running Windows XP and a solid state drive that I know supports TRIM. I have searched Google and these forums and have found the documentation for IOCTL_ATA_PASS_THROUGH and the ATA command set from T13.
The questions I have after reading all of this are:
- If Count in the command structure refers to the number of 512 byte blocks to be transferred, how does the drive know how many LBA entries I have included in the list?
- Is the command structure itself part of the 512 bytes that Count refers to?
- For the LBA range entry itself, 1 block is 512 bytes? A single range entry can only refer to 65535 * 512 bytes worth of “disk space?”
I have more questions than this really, but knowing the answer to these things would be a good start.
Thanks Pradeep.
So then do I have to fill the 512 bytes with entries even if they have a length of zero?
For the DATA SET MANAGEMENT (TRIM) command they have the following note:
“DATA SET MANAGEMENT Request Data is a list of one or more LBA Range Entries (see 4.17.3.2) . If the Trim bit is set to one, then LBA Range Entries may overlap and are not required to be sorted . See table 73.”
Do I have an out of date document? The LBA entries that I give it must be sorted?
OK. probably my spec is not the latest. I have a draft. 
I only have a draft also. It seems that’s all you get without paying $800 a year.
I can figure out later whether or not they need to be sorted, but do I need to fill the entire 512 bytes with LBA entries?
Thanks again for your responses.
no i don’t think that is a requirement. Atleast with other NVCache commands I just zero the entire buffer and then fill the entries I need starting from begning of the block.
So I can now issue the TRIM command to the drive and both Windows and the drive itself seem to return with no error codes (DeviceIoControl returnsTURE and the ATA Status and Error registers do not indicate and error.)
However I am not getting the behavior I expected after issuing the TRIM command. I expected that I would at least read something other than what was written to that location before the TRIM.
One problem may be that I am not formatting the LBA Range properly. I use this defiine to make an LBA Range value:
#define MAKE_LBA_RANGE(lba, range) (((ULONGLONG)range << 48) | ((ULONGLONG)lba & 0xFFFFFFFFFFFF))
Does that get the bits in the right order for the drive?