Well, here are a few pointers.
First, if you have not spun-up the disc yet, the system will need a few seconds to allow it to spin-up. Your code doesn't need to tell it to spin-up, it will do this automatically. However, you must wait for it if it hasn't yet.
Second, what is it you are trying to read? Sectors or IDENTIFY BLOCK?
If you are trying to read the IDENTIFY BLOCK, you must do it in a specific sequence. You must first send the ATA_IDENTIFY command. An ATAPI device will purposely fail, which will indicate that you can send the ATAPI_IDENTIFY command. If I remember correctly, some devices won't work until you get the IDENTIFY BLOCK using this method. After failing the ATA_IDENTIFY command, the controller will place 0x01, 0x01, 0x14, 0xEB in the parameter registers indicating an ATAPI device. You then request the ATAPI_IDENTIFY.
Next, are you assuming 16-byte packets? The packet size can be 12- or 16-bytes.
Sending the ATA_IDENTIFY command, you must wait for drive to be ready. The ATAPI_IDENTIFY command does not need to wait.
The command packet, a 12- or 16-byte packet, does not get sent via DMA. It gets sent PIO.
The IDENTIFY command, both ATA and ATAPI, must also be read using PIO. These two commands do not work if you try using DMA to read the data.
Before writing to the controller, I use the following (see the function's source below):
Code:
ata_wait(ata, ATA_STATUS_RDY, wait)
Once this returns TRUE, I write my parameters and then the command to the controller. Then I do:
Code:
ata_wait(ata, ATA_STATUS_DRQ, wait)
Once it returns TRUE, I can then read or write from/to the drive either using PIO or starting the DMA.
Here is my wait for ready code:
Code:
#define ATA_STATUS_BSY (1 << 7) // busy bit
#define ATA_STATUS_RDY (1 << 6) // Ready bit
#define ATA_STATUS_DF (1 << 5) // Drive Fault Error
#define ATA_STATUS_DSC (1 << 4) // Seek Complete ?
#define ATA_STATUS_DRQ (1 << 3) // Data Ready
#define ATA_STATUS_CORR (1 << 2) // Data corrected ?
#define ATA_STATUS_IDX (1 << 1) // Index Mark ?
#define ATA_STATUS_ERR (1 << 0) // Error
// wait for the controller to return a 'not busy'
// if bit 7 is set, bits 6-0 are undefined
bool ata_wait(const struct S_ATA *ata, const bit8u ch, int timeout) {
// we should always delay at least 400nS after sending a COMMAND and reading the (alt)Status register
// therefore, read it once, ignoring the return
inportb(ata->cntrlr->alt_base + ATA_ALT_STATUS);
while (timeout) {
bit8u status = inportb(ata->cntrlr->alt_base + ATA_ALT_STATUS);
if (!(status & ATA_STATUS_BSY)) {
if (status & (ATA_STATUS_ERR | ATA_STATUS_DF))
return FALSE;
// can be any bit of specified in ch
if (status & ch) return TRUE;
}
mdelay(1);
timeout--;
}
}
If you will notice, if bit 7 (busy) is set, all other bits are undefined. In other words, if bit 7 is set, you must ignore all other bits.
This code is from my book (listed below). This book explains everything you need to do to detect, identify, read and write ATA and ATAPI type devices. It also (ironically) contains a cd-rom (upon proof of purchase and request) with detailed source code to read and write these devices.
On a different note, it also contains details about Floppy Disk Controllers and how to read and write from them.
I hope this helps. Let me know if you are still stuck.
Ben
http://www.fysnet.net/media_storage_devices.htm