title: What is the proper way to acknowledge an ATA/IDE interrupt?
body: <p>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.</p>
  
  <p>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.</p>
  
  <p>So what is the proper way acknowledge an interrupt issued by an ATA device?</p>
  
  <p>In this example I issue a READ MULTIPLE command, and then my ISR does the following:</p>
  
  <ol>
  <li>disables CPU interrupts, sets nIEN</li>
  <li>Read a single data block (not sector!) fro the DATA register,</li>
  <li>If all data has been read, read the STATUS register to clear the 'extra' interrupt</li>
  <li>Exit by clearing nIEN, and sending EOI's to both the master and slave PICs</li>
  </ol>
  
  <p>The ATA specs for the PIO data-in command protocol don't indicate that you <em>need</em> 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.</p>