[Solved]Problem with IDE Detection via PIO

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
Almamu
Member
Member
Posts: 47
Joined: Wed Jul 07, 2010 9:41 am

[Solved]Problem with IDE Detection via PIO

Post by Almamu »

Im working on LBA28/48 support. Im trying to detect how many drivers are connected at the moment you run the SO. I have no problem to detect all of them in the real Hardware, but when i'm trying to test it in a Virtual Machine(VirtualBox)i get: No drives detected and i have one connected to the Master...
This is my code:

Code: Select all

int HDD_find_drives(){
	outb(0x1F3, 0x88);//Write some data to see if there are any drive
	unsigned short status = inb(0x1F3);//Read the data
	if(status & 0x88){//Compare with the data we write
		printf("Drives detected");
		outb(0x1F6, 0xA0);//Find primary Master
		sleep(1);//Wait the device to be ready
		unsigned short word = inb(0x1F7);//Read the data
		if(word & 0x40){//If drive is present
			printf("Primary Master detected\n");
		}
		outb(0x176, 0xB0);//Find primary Slave
		sleep(1);//Whait the device to be ready
		word = inb(0x177);//Read the data
		if(word & 0x40){//If drive is present
			printf("Primary Slave detected\n");
		}
		printf("LBA test completed\n");
	}else{//No drives detected
		printf("No drives detected\n");
	}
	return 1;
}
If i set a Slave primary device in the virtual machine it reports: Drives detected, but it doesnt seem to detect any Master and/or Slave, any help ?
Last edited by Almamu on Fri Oct 15, 2010 12:53 pm, edited 1 time in total.
Image
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: Problem with IDE Detection via PIO

Post by ~ »

You can see this topic. Maybe or maybe not you'll need to read some further details in the ATA manuals:

http://forum.osdev.org/viewtopic.php?f=1&t=20690

If you can use DOS, you can use the following .COM program as a proof of concept of the topic above to see if it detects properly the devices, and the source code of it against yours:

http://126.sytes.net/tmp/atadiskdetect.zip
Image

Remember that all machines have subtle differences in this aspect, and to accurately detect all combinations attached ATA/ATAPI devices you have to take those differences into account.
User avatar
Almamu
Member
Member
Posts: 47
Joined: Wed Jul 07, 2010 9:41 am

Re: Problem with IDE Detection via PIO

Post by Almamu »

Im using the "write & read data to the port" method, as it's supossed to work with most of the drives. It seems to be the most "universal" way to detect them, maybe my code is wrong...

EDIT: I've been doing some test and if I connect two drives to the first IDE it only detects the Master, and not the Slave.
Image
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: Problem with IDE Detection via PIO

Post by ~ »

You might try the DOS .COM program I included in the previous post and see if it works as expected. It uses 2 or 3 different detection methods. It's because different methods of detection are successful in some machines, or are unstable, or just fail to detect drives properly. If one fails, the other will succeed.

Note that this program still seems to have a small bug with an old 24X Creative CD-ROM in an HP Vectra, which is something that needs to be fixed, but in all other cases has worked flawless for me so far.

The biggest problem aren't the drives, although they don't all return signatures exactly as stated by the standards or set/clear status bits straightforwardly; but the motherboard ATA controllers themselves also differ in behavior.
User avatar
Almamu
Member
Member
Posts: 47
Joined: Wed Jul 07, 2010 9:41 am

Re: Problem with IDE Detection via PIO

Post by Almamu »

Ive tested the .com file in DOS 6.22 and it detects the two HDD's. Image of the output:

Dont care about the CDROM drive, its only for start DOS,
Attachments
result.png
result.png (8.2 KiB) Viewed 2662 times
Image
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: Problem with IDE Detection via PIO

Post by ~ »

Well, if it's what your machine/emulator actually has connected, you can compare results and study your sources and the forum explanations for corrections to be integrated.

If you need some help, make sure you read the explanations, the standard and whatever you need, and see what you are able to fix, and if there's something unclear, ask and maybe I'll try to clarify, but it all should be already in the explanation of the algorithm.

Keep in mind that the actual sources are crafted to be specific to display the results of this program, so they would need some rewriting for generalizing them (and fix the HP Vectra bug).

The more actual tests and combinations you do will give you more certainty that you won't be losing work with bogus sources, to integrate this method.
User avatar
Almamu
Member
Member
Posts: 47
Joined: Wed Jul 07, 2010 9:41 am

Re: Problem with IDE Detection via PIO

Post by Almamu »

Ok, i've been doing some more test and if i read the Regular Status port(1F7h)i can determine if there is any Master drive(as the post says), but, atm i'm a bit confused. How can i know if there is any Slave in the first/second port? I've been able to read the First Master and Second Master, and determine if it is connected or not. But atm i don't know how to detect the slave from both ports...
This is my actual code:

Code: Select all

    outb(0x1F3, 0x88);
    unsigned short status = inb(0x1F3);
    unsigned short bus = inb(0x1F7);
    unsigned short word;
    if((status & 0x88) || ((bus == 0xFF) || (bus == 0x00) || (bus == 0x7F))){
        printf("Drives detected\nExtra test begin now\n");
        outb(0x1F6, 0xA0);
        sleep(1);
        word = inb(0x1F7);
        if(word & 0x40){
            d_hdd_info->primary.master = 1;
            printf("Primary Master detected\n");
        }
    }
    outb(0x173, 0x88);
    status = inb(0x173);
    bus = inb(0x177);
    if((status & 0x88) || ((bus == 0xFF) || (bus == 0x00) || (bus == 0x7F))){
        outb(0x176, 0xB0);
        sleep(1);
        word = inb(0x177);
        if(word & 0x40){
            d_hdd_info->secondary.master = 1;
            printf("Secondary Master detected\n");
        }
    }
    printf("LBA Test completed\n");
    return 1;
}
Image
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: Problem with IDE Detection via PIO

Post by ~ »

Almamu wrote:Ok, i've been doing some more test and if i read the Regular Status port(1F7h)i can determine if there is any Master drive(as the post says), but, atm i'm a bit confused.
What part of the explanation are you quoting? Is it the part that says that just reading the status port for a "valid" value is enough? If that's the part, then you must know that detection will work in some drive/machines combinations but not in others.

Almamu wrote:How can i know if there is any Slave in the first/second port? I've been able to read the First Master and Second Master, and determine if it is connected or not. But atm i don't know how to detect the slave from both ports...
Try encapsulating the snippet that allows you to detect the Primary Master with the testings, and try to pass the base I/O port (170h, 1F0h) and alternate register port and the DEV bit as parameters (3 parameters in total). In this way you only need to add from 0 to 7 to the base port parameter for the different registers of the Task File.

The DEV bit is located at bit 4 of register #6 (e.g, 1F6h or 176h). You clear it to reach the Master (00000000b) and set it to reach the slave (00010000b). You should always write/AND/OR either 0 or 16 for Slave to that port to be sure which device is selected, and you should be set. Then more tests should be done.

The Alternate Status register is located at 3F6h, 376h, 3E6h and 366h, for the Primary, Secondary, 3rd and 4th IDE channels.
User avatar
Almamu
Member
Member
Posts: 47
Joined: Wed Jul 07, 2010 9:41 am

Re: Problem with IDE Detection via PIO

Post by Almamu »

Ok, now the code seems to work correctly. Here is the code if anyone need it:

Code: Select all

/* You need the functions: printf, inb, outb*/
typedef struct{
	int master, slave;
}_HDD_DRIVE_INFO;

typedef struct{
	_HDD_DRIVE_INFO primary;
	_HDD_DRIVE_INFO secondary;
}_HDD_SYSTEM_INFO;

_HDD_SYSTEM_INFO* d_hdd_info;

int HDD_find_drives(){
	outb(0x1F3, 0x88);
	unsigned short status = inb(0x1F3);
	unsigned short bus = inb(0x1F7);
	unsigned short word;
	if((status & 0x88) || ((bus == 0xFF) || (bus == 0x00) || (bus == 0x7F))){
                //Test for primary master
		printf("Drives detected\nExtra test begins now\n");
		outb(0x1F6, 0xA0);
		sleep(1);
		word = inb(0x1F7);
		if(word & 0x40){
			d_hdd_info->primary.master = 1;
			printf("Primary master detected\n");
		}
                //Test for primary slave
		outb(0x1F6, 0xB0);
		sleep(1);
		word = inb(0x1F7);
		if(word & 0x40){
			d_hdd_info->primary.slave = 1;
			printf("Primary slave detected\n");
		}
	}
	outb(0x173, 0x88);
	status = inb(0x173);
	bus = inb(0x177);
	if((status & 0x88) || ((bus == 0xFF) || (bus == 0x00) || (bus == 0x7F))){
                //Test for secondary master
		outb(0x176, 0xA0);
		sleep(1);
		word = inb(0x177);
		if(word & 0x40){
			d_hdd_info->secondary.master = 1;
			printf("Secondary master detected\n");
		}
                //Test for secondary slave
		outb(0x176, 0xB0);
		sleep(1);
		word = inb(0x177);
		if(word & 0x40){
			d_hdd_info->secondary.slave = 1;
			printf("Secondary slave detected\n");
		}
	}
	printf("LBA Test completed\n");
	return 1;
}
It works correctly for HDD.
Thanks for the help.

P.D: I write 0xA0 in 0x1F6 to let the hardware know that i want to get data from primary master and 0xB0 to get data from primary slave as the doc i have says.
Image
Post Reply