Switch to full style
Tools for hard drive diagnostics, repair, and data recovery
Post a reply

SATA programming

January 15th, 2007, 14:12

I'm currently trying to send ATA commands to a SATA HDD. I thought I'd dedicate a thread to this, so every info related to this can be dumped here.

As I understand, from looking to MHDD, it seems that there are 2 steps:
1. Find the SATA controller on the PCI bus
2. Send the ATA commands to the specific controller.

I just found the following resources myself already:

* http://www.waste.org/~winkles/hardware/pci.htm => a nice tutorial on scanning the PCI bus
* http://www.pci-card.com/pci_pas.zip => A PCI bus scanner for dos.

Now, I think finding the hardware isn't going to be that hard after reading an analyzing the above (still busy on that though). However, how to proceed if a SATA controller had been identified ? Can you just program it like the IDE controllers, in the exact same way ?

Any info on this will be greatly appreciated !

January 15th, 2007, 15:29

Lol, I've already found it :) To document it so the info can be useful to somebody else:

1. Find the SATA controller in your system. You can use the info in the links above to do this.
2. Once you have found the controller, you should list which I/O ports it has. The PCI_PAS.zip source explains how u can do this.

After you've found the I/O ports on the controller, one of the ports is the port you should use to send the ATA packets to. For example, for my controller, there are 5 ports, at adresses:

0xA800
0xA400
0XA000
0X9800
0x9400

I've tested them, and if I write to the first port, I communicate with the HDD ! So, to make clear, instead of using registers 0x170, 0x171, 0x172 etc (for the first IDE controller), i used 0xA800, 0xA801, 0xA802 etc.

Re: SATA programming

June 8th, 2008, 15:52

aimtrading, I realise this post is very old now.. but I'm having trouble working out how to scan for the sata device and retrieve its ports.. any help would be appreciated

Re: SATA programming

June 17th, 2008, 6:24

What's exactly your problem ?

Re: SATA programming

December 20th, 2011, 22:25

So many years ago, Can any guy tell me how to detect a SATA adapter that isn't attached at PCI bus ?

Any info on this will be greatly appreciated !

Re: SATA programming

December 21st, 2011, 14:08

corner wrote:Can any guy tell me how to detect a SATA adapter that isn't attached at PCI bus ?

What exactly do you mean? Do you mean a USB-SATA adapter? Or an IDE-SATA adapter? Or something else? If you can include a link to the manufacturer's webpage for the adapter you are asking about, that would be helpful :)

Re: SATA programming

March 13th, 2012, 22:10

Vulcan, that's my mind, thank u (smart), I think scan the BUS that the harddisk attached to could resolved the above problem that I asked.
and now I got another problem...
I read the SATA SPEC, try to send SATA commond to a SATA HDD, my code like:
#define _STATUS_BSY_ 0x80
#define _STATUS_DRDY_ 0x40
#define _STATUS_DF_ 0x20
#define _STATUS_DRQ_ 0x08
#define _STATUS_ERR_ 0x01
void wait_until_ready(WORD portBase)
{
__asm
{
L_READ:
mov dx, word ptr[portBase]
xor eax, eax
add dx, 0x7 //status
in al, dx
test al, (_STATUS_BSY_ | _STATUS_DRQ_)
jz L_RET
nop
nop
nop
jmp L_READ
}
L_RET:
return;
}
//------------------------IDENTIFY DEVICE
struct IDENTIFY_DEVICE //part of data returned
{
WORD word0;
WORD word1;
WORD word2;
WORD word3;
};
void identify_device(IDENTIFY_DEVICE* buff, WORD portBase)
{
__asm cli
wait_until_ready(portBase);
__asm
{
mov dx, word ptr[portBase]
add dx, 0x7
mov al, 0xEC
out dx, al
}
wait_until_ready(portBase);
__asm
{
mov dx, word ptr[portBase]
mov edi, dword ptr[buff]
xor ecx, ecx
L_LOOP:
cmp ecx, 8
je L_BREAK
in al, dx
stosb
inc ecx
jmp L_LOOP
}
L_BREAK:
__asm sti
return;
}
1. Is my code got some error?
2. Where's the content in SATA SPEC introduction how to send a SATA command?
any help would be appreciated!

Re: SATA programming

March 20th, 2012, 1:37

hi,all
with the code:
add dx, 0x7 //status
in al, dx
test al, (_STATUS_BSY_ | _STATUS_DRQ_)
I got the _STATUS_DRQ always is 0x1, never be cleared to ZERO..

What's wrong with my code ?
thx!

Re: SATA programming

May 7th, 2012, 5:19

corner wrote:hi,all
with the code:
add dx, 0x7 //status
in al, dx
test al, (_STATUS_BSY_ | _STATUS_DRQ_)
I got the _STATUS_DRQ always is 0x1, never be cleared to ZERO..

What's wrong with my code ?
thx!


I want to help you but it is difficult to understand assembler code. This is a simple program to read HDD information, I think you should use C programing because with complex function in PC3000, a assembler code will very very long.
Post a reply