Over the last couple of days, I've been working on getting IDE DMA support into my OS. You can see my in-progress, messy and broken code here.
I already have a fully operational PIO ATA driver, so I'm mainly doing this to improve performance and lower CPU load. The only complication of the code is that I'm allowing the ATA driver to load before the PCI driver (so that the PCI driver can be stored on the HDD), so it needs to lazy-initialize PCI-based DMA.
I've been following the "IDEMS100" document and am able to send the read command to the HDD, but IRQ 14 then fires with bits 0 (active) and 2 (interrupt) set in the status byte. According to the document "This is a valid completion case where the size of the physical memory regions was larger than the IDE device transfer size." While the document doesn't say how to determine the "IDE device transfer size", I'm only requesting one sector...
Nothing is loaded into buffer set up in the PRDT (which consists of only one entry, with the EOT bit set).
The behaviour is identical in both QEMU and Bochs. I've even tried reading the Bochs source code to get an idea of what's going wrong, with no success.
The only thing I can guess at is that I need to configure a valid transfer mode for the device and controller, but considering the complexity of that according to the documentation (linked in the wiki), I don't know where to start (also, the document talks about a lot of features that are specific to certain models of Intel IDE controllers, but I want to write something as generic as possible)... Also, the Bochs source code doesn't seem to be doing any sort of config check, so I'm not sure why it wouldn't work there.
Does anybody have any experience with this?