Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the board
Thread view  Mix view  Order
RayeR(R)

Homepage

CZ,
08.08.2017, 20:19
 

ATA TRIM (Developers)

Hi,
I'm studying the ATA TRIM command to try it under DOS. Currently I successfully implemented detection of TRIM capability in my SMB tool. My SSD supports TRIM, DRAT, RZAT. ATA TRIM is described in ACS-4 page 112. The ATA command code is 06h. Before ATA command code is executed some parameters have to be set, in my case named:
ide_current_cmr.data; // set data
ide_current_cmr.feat_err; // set features
ide_current_cmr.seccnt; // set sector count
ide_current_cmr.secnum; // set sector number
ide_current_cmr.cyllo; // set cylinder low
ide_current_cmr.cylhi; // set cylinder high
ide_current_cmr.drvsel_hd // bit3:0 = head, bit4 = drive, bit5 = sect. size (1~512B), bit6 LBA/CHS (0~CHS), bit7 = 1
ide_current_cmr.cmd_stat; // set IDE command
In ASC-4 specs there's no description for data field (maybe assume to be 0) and I'm trying to figure out the difference between TRIM bit set to 0 or 1 in features word (bit 0). If TRIM bit is 1 then LBA (CHS) fields are not used (reserved) if TRIM bit is 0 there should be something. Also DSM FUNCTION field bits 15:8 have different meaning according to TRIM bit.
Then if I understand well I have to prepare at least one sector with TRIM range list - 64 QWord entries where each contains LBA start and number of sectors to trim. So for the simplest case I need to create one 64b entry with LBA and count, e.g. number of sectors per cluster (I should find some LBA of unused disk area, fill it with a test pattern and then examine if it was trimmed). I'm not sure if something else need to be set and how to set DSM FUNCTION field and TRIM bit, any idea?

---
DOS gives me freedom to unlimited HW access.

RayeR(R)

Homepage

CZ,
09.08.2017, 14:24
(edited by RayeR, 09.08.2017, 16:54)

@ RayeR

ATA TRIM

So I tried to test TRIM command with this parameters:
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)

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 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.

---
DOS gives me freedom to unlimited HW access.

RayeR(R)

Homepage

CZ,
11.08.2017, 15:45

@ RayeR

ATA TRIM

I discovered in ACS-4 spec, that DATA SET MANAGEMENT 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 sectores beyond 128GB limit with it. Unfortunately it still fails with TRIM command but in different way - now I got the device busy timeout after writting 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.

---
DOS gives me freedom to unlimited HW access.

roytam(R)

12.08.2017, 17:05

@ RayeR

ATA TRIM

> I discovered in ACS-4 spec, that DATA SET MANAGEMENT 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 sectores beyond 128GB limit with it. Unfortunately
> it still fails with TRIM command but in different way - now I got the
> device busy timeout after writting 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.

Did you check these out as well?
http://t13.org/Documents/UploadedDocuments/docs200...6-Data_Set_Management_Proposal_for_ATA-ACS2.doc
http://t13.org/Documents/UploadedDocuments/docs2010/e09158r2-Trim_Clarifications.doc

RayeR(R)

Homepage

CZ,
13.08.2017, 03:43

@ roytam

ATA TRIM

> Did you check these out as well?
> http://t13.org/Documents/UploadedDocuments/docs200...6-Data_Set_Management_Proposal_for_ATA-ACS2.doc
> http://t13.org/Documents/UploadedDocuments/docs2010/e09158r2-Trim_Clarifications.doc

I read it but nothing helpful... I found a call in Linux kernel source of libata-scsi.c:
tf->protocol = ATA_PROT_DMA;
tf->hob_feature = 0;
tf->feature = ATA_DSM_TRIM;
tf->hob_nsect = (size / 512) >> 8;
tf->nsect = size / 512;
tf->command = ATA_CMD_DSM;
so they use features15:0=0x0001 - I implemented also 16bit features for LBA48 and set it to 1 but still doesn't work.
I have a bad feeling that it seems the TRIM command is not allowed via PIO protocol but only DMA (aslo noted in ACS)
Table A.1 Command codes (sorted by command code) (part 1 of 5)
DATA SET MANAGEMENT cmd=06h O protocol=DM argument=48-bit
It's going much more complex I don't know how DMA protocol looks at all...yet

---
DOS gives me freedom to unlimited HW access.

Back to the board
Thread view  Mix view  Order
15189 Postings in 1365 Threads, 250 registered users, 13 users online (0 registered, 13 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum