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
Help with the 'Identify' ATA command
Help with the 'Identify' ATA command
Last edited by Luns on Thu Jun 30, 2011 12:14 pm, edited 1 time in total.
Re: Help with the 'Identify' ATA command
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) {
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
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Help with the 'Identify' ATA command
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.
Last edited by Combuster on Thu Jun 30, 2011 1:34 am, edited 1 time in total.
Re: Help with the 'Identify' ATA command
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.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?
The reason for your error is probably that IDENTIFY doesn't work for ATAPI devices:
Try IDENTIFY PACKET DEVICE for CD-ROMs.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).
Re: Help with the 'Identify' ATA command
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.
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.
Last edited by Luns on Wed Jul 06, 2011 8:55 am, edited 1 time in total.
Re: Help with the 'Identify' ATA command
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 -
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?
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.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).
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?
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Help with the 'Identify' ATA command
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
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
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