I am currently working on a hobby OS, specifically the ATA driver. I am having some issues with PIO data-in commands with interrupts. I am trying to execute the READ MULTIPLE command to read multiple sectors from the drive, block by block, with an interrupt firing for each block.
If I request a read of 4 blocks (1 sector per block). I expect to get 4 interrupts, one for each data block. Upon receiving the 4th interrupt I can identify that I've transferred all data and update my request structure accordingly. However, in VirtualBox I've found that after the last data block has been transferred I received yet another interrupt (STATUS = 0x50, READY, OVERLAPPED MODE SERVER REQ). I can simply read the STATUS register then to clear it, but I don't think I should ever receive the 5th interrupt according to the specs.
So what is the proper way acknowledge an interrupt issued by an ATA device?
In this example I issue a READ MULTIPLE command, and then my ISR does the following:
- disables CPU interrupts, sets nIEN
- Read a single data block (not sector!) fro the DATA register,
- If all data has been read, read the STATUS register to clear the 'extra' interrupt
- Exit by clearing nIEN, and sending EOI's to both the master and slave PICs
The ATA specs for the PIO data-in command protocol don't indicate that you need to read the status register. From that I assumed that when I receive an interrupt all I have to do is follow the protocol and finish by sending the EOIs to the PICs. As for the setting/clearing of nIEN, in dealing with VirtualBox I've found that if I don't do this I don't receive any interrupts past the first one. So I set nIEN when entering the ISR, then clear it before I leave. I'd think that wouldn't have any effect, but it must be related to reading/writing that specific register.