ATA TRIM command (low-level programming)

Programming, for all ages and all languages.
Post Reply
RayeR
Posts: 22
Joined: Wed Feb 23, 2011 6:36 pm
Location: Czech Republic
Contact:

ATA TRIM command (low-level programming)

Post by RayeR »

Hi,
I'm trying to execute ATA TRIM command on my SSD. It's Samsung SATA3 SSD but I use it in IDE legacy mode for compatability and simplicity so I control it via legacy I/O port 1F0h. I already had written a simple ATA driver so I can execute various ATA commands, read/write sectors etc. But I have a problem with TRIM command. I studied the description in ACS-2 and ACS-4 and I have some doubts if I set all parameters correctly, e.g. data register and features.
I already did a simple test:
ide_exec_command: I/O=1F0h, drv=0-W, cmd=06h, data=00h, feat=01h, LBA=0, scnt=1
rangelist[0] = 0001000000000003 (LBA start=3, sectors=1)
(rest of range 512B list sector was zeroed)

Code: Select all

outportb(io_base+IDE_CMR_DATA, 0); // set data reg.
outportb(io_base+IDE_CMR_FEAT_ERR, 0x01); // set features reg.
outportb(io_base+IDE_CMR_SECCNT, 1); // set sector count reg.
outportb(io_base+IDE_CMR_SECNUM, 0); // set sector number reg.
outportb(io_base+IDE_CMR_CYLLO, 0); // set cylinder low reg.
outportb(io_base+IDE_CMR_CYLHI, 0); // set cylinder high reg.
outportb(io_base+IDE_CMR_DRVSEL_HD, 0|(0<<4)|0xA0|0x40); // bit3:0 = head=0, bit4 = drive=0, bit5 = sect. size (1=512B), bit6 LBA/CHS (1=LBA), bit7 = 1
outportb(io_base+IDE_CMR_CMD_STAT, 0x06); // send IDE command (will be performed immediatelly)
But it doesn't work, I got:
ERROR: CMD_ABORT
STATUS: ERROR SEEK_DONE DRV_READY
RETURN: LBA=00000000h, scnt=00h, err=04h

The SSD ended in a bad state (wait busy timeout) where disk activity LED was lighting and I have to restart PC. When I looked at test LBA sector 3 with disk editor the content remained unchanged. Please can someone tell me what I'm doing wrong?
My SSD reports to support TRIM, DRAT, RZAT in device identify data and it works fine under Linux (fstrim).
RayeR
Posts: 22
Joined: Wed Feb 23, 2011 6:36 pm
Location: Czech Republic
Contact:

Re: ATA TRIM command (low-level programming)

Post by RayeR »

I discovered in ACS-4 spec, that DATA SET MANAGEMENT command requires LBA48 parameters. So I further implemented LBA48 addressing scheme to feed IDE controller registers. Then I checked that it works using READ SECTOR(S) EXT command and I can read sectors beyond 128GB limit with it. Unfortunately it still fails with TRIM command but in different way - now I got the device busy timeout after writing the command code 06h even before I can start transfer sector data with the range list. The drive remains in busy state until I reset the controller via reset bit in I/O port 3F6h.
RayeR
Posts: 22
Joined: Wed Feb 23, 2011 6:36 pm
Location: Czech Republic
Contact:

Re: ATA TRIM command (low-level programming)

Post by RayeR »

Sigh, the DSM/TRIM command cannot be performed via PIO mode only. I have to implement IDE busmaster controller support and DMA transfer to send just one stupid sector with range list :(
Post Reply