Page 1 of 1

Help with the 'Identify' ATA command

Posted: Wed Jun 29, 2011 6:43 pm
by Luns
So far, I have been able to identify that the CD drive is a PATA master drive on the secondary controller - which seems right, since QEMU reports that the drive is 'ide1-cd0'.

After I identify all that stuff, I set ports 0x172 through 0x175 to 0, and send the 'Identify' command (0xEC) on the command register port (0x177). Then I read the status port (0x177) until the BSY bit is no longer set.

Here is where I start losing it - according to the ATA PIO Mode wiki, I should wait until DRK or ERR (bits 0 and 7 from the status port) is set. DRK never sets, but ERR does. Then, the wiki says that if ERR is clear, I can read my 512 bytes from the data port. So I guess I should loop again until ERR goes clear? I tried that, but then when I try reading my data all I get are zeros. Does anyone know what might be wrong?

Thank you!

e: I guess I'll post my code, in case it will help -

snip

Re: Help with the 'Identify' ATA command

Posted: Thu Jun 30, 2011 1:16 am
by pranays

Code: Select all

outb (0x1F3, 0x88);
   outb (0x1F2, 0x88);   //write to another port to give the original time to settle
   if ((unsigned char) inb (0x1F3) == 0x88) {
   
Shouldn't you wait for sometime before reading back the value? 400ns was it?

Code: Select all

outb (bus+2, 0);
   outb (bus+3, 0);
   outb (bus+4, 0);
   outb (bus+5, 0);
   outb (bus+7, 0xEC);      //identify command
no drive select here. you are saving it in drive variable bt you shld outb it to (0x1f6 or 0x176) first.

Re: Help with the 'Identify' ATA command

Posted: Thu Jun 30, 2011 1:33 am
by Combuster
You do know that CD drives do not support the Identify command, and that the error return is the correct response?
wiki wrote:ATAPI or SATA devices are supposed to respond to an ATA IDENTIFY command by immediately reporting an error in the Status Register, rather than setting BSY, then DRQ, then sending 256 words of PIO data.

Re: Help with the 'Identify' ATA command

Posted: Thu Jun 30, 2011 1:33 am
by Kevin
Luns wrote:Here is where I start losing it - according to the ATA PIO Mode wiki, I should wait until DRK or ERR (bits 0 and 7 from the status port) is set. DRK never sets, but ERR does. Then, the wiki says that if ERR is clear, I can read my 512 bytes from the data port. So I guess I should loop again until ERR goes clear? I tried that, but then when I try reading my data all I get are zeros. Does anyone know what might be wrong?
Yes. You're trying to read data that isn't there. After all, the drive told you that an error happened, not that everything's fine and you can read out the data.

The reason for your error is probably that IDENTIFY doesn't work for ATAPI devices:
In response to this command, ATAPI devices shall return command aborted and place the PACKET feature set
signature in the appropriate fields (see table 102).
Try IDENTIFY PACKET DEVICE for CD-ROMs.

Re: Help with the 'Identify' ATA command

Posted: Thu Jun 30, 2011 11:22 am
by Luns
Oops, I must have missed that line. I've rewritten everything now, but I'm still having trouble. I figure out what devices exist and whether they're ATAPI, SATA, or PATA. Then I select the ATAPI device, wait 400ns, and zero ports 0x172 through 0x175. Then I send the IDENTIFY PACKET DEVICE command, loop until the BSY bit in the status register clears, and then loop until the DRQ bit in the status register sets. The DRQ bit never sets though. Does anyone know why that might happen?

And thanks for all the help :)

e: Oops, another stupid mistake. I got past that now, but I still only receive zeros.

e2: I printed out the status register before, after, and during reading in the information. Before and during it's 0x58 - RDY, SRV, and DRQ are all set. RDY and DRQ should be set, and I found another post here that says I can just ignore SRV (it's meaningless during the IDENTIFY command). The status register remains 0x58 for all 256 times I read in a word, and then changes to 0x50 - same as before, but without DRQ being set. This all seems right - after issuing the IDENTIFY PACKET DEVICE command, DRQ is set until I've finished reading the 256 bytes, and is then cleared. So why would it be sending me zeros?

e3: I tried it on a real machine, with two drives - a SATA HDD and SATA CD drive. My program initially identifies them as PATA (they respond to the first IDENTIFY command by setting the status register to 0xD0). Later on, I try actually reading the info from the IDENTIFY command - again, after sending the command, the status register is set to 0xD0. After the busy bit clears though, the status register is set to 0x51 - so now there's an error. Since the drive is SATA, shouldn't I be getting this error immediately after issuing the IDENTIFY command?

Here's my updated code - snip

e4 - Mixed success! It works fine now in QEMU. On real hardware, I get some oddities. On one computer, the ERR bit was never set after the ATAPI drive aborted from the IDENTIFY command. The ABRT bit (bit 2) in the error register (0x1F1 or 0x171) did set however, so now I check for that before checking the ERR bit, and assume that if it sets it's an ATAPI device. Even still, I have some trouble detecting all the drives - on one computer with two CD drives on the same IDE cable and one SATA hard drive, I detect one ATAPI device and one PATA device. Another computer with a SATA CD drive and SATA hard drive reports two PATA drives - after one IDENTIFY command, a drive responds but doesn't set an ERR bit, after another the ERR bit is set but after reading the IO ports to determine what type the drive is, both ports (0x1_4 and 0x1_5) are zero - which the Wiki says indicates a normal ATA drive aborted from the IDENTIFY command.

Re: Help with the 'Identify' ATA command

Posted: Wed Jul 06, 2011 8:50 am
by Luns
I'm sorry for bumping this, but I'm really at a loss as to how to detect what drives are present on real hardware. The ATA documentation says this about detecting packet devices -
In addition, the IDENTIFY DEVICE command shall not be executed but shall be command aborted and shall
return a signature unique to devices implementing the PACKET Command feature set. The IDENTIFY
PACKET DEVICE command is used by the host to get identifying parameter information for a device
implementing the PACKET Command feature set (See X78H7.17.5X and X789H7.18X).
In QEMU, upon issuing an IDENTIFY DEVICE command to a packet device the ABRT bit in the error register is set, and the "signature unique to devices implementing the packet command feature set" is present. I.e., the cylinder low and cylinder high registers contain the ATAPI specific values, 0x14 and 0xEB.

On real hardware though, none of that happens. Upon issuing the IDENTIFY DEVICE command, the cd-drive neither sets the ABRT bit nor sets any values in the cl/ch registers (they both remain 0). What else can I do to detect the drives as ATAPI? The wiki page had two other options, but it said they're non standardized and not recommended. Should I try them anyway, as a fallback in case detecting with the IDENTIFY DEVICE command doesn't work?

Re: Help with the 'Identify' ATA command

Posted: Wed Jul 06, 2011 9:27 am
by Combuster
Are you sure you have an ATAPI CD-rom drive (and not SATA), and that you are talking to the right master/slave on the right bus?

Re: Help with the 'Identify' ATA command

Posted: Wed Jul 06, 2011 9:36 am
by Luns
On one computer, I have two CD-drives connected by IDE cable - so I'm sure those are ATAPI. On another computer, the CD-drive is SATA, but the BIOS detects it as an IDE master drive. I assumed that meant the drive was "pretending" to be a regular ATAPI drive, but maybe that's not correct?

I loop through all the master/slave bus1/bus2 combinations, so I'm sure that during at least one iteration of the loop I'm talking to the right drives.

e: Some progress. Now after issuing the IDENTIFY DEVICE command and seeing that ABRT is not set, instead of immediately checking the values of cylander highl/cylander low I do a software reset, reselect the drive, wait 400ns, and then check the values. According to the specs, after a software reset the packet device will leave the "packet device specific values" in the cylinder high/low registers. On the computer with two IDE CD-drives, this works for detecting one of the two drives as ATAPI. I then have the problem that when I try issuing the IDENTIFY PACKET DEVICE command and reading the info, it never sets DRQ. Baby steps...

e2: Got it! Not sure what it was, but I took a break, tried starting over again, and it works now. Thanks for the help :)