Page 1 of 1

[ATA DMA and qemu] "dma: command 0x9 not supported"

Posted: Wed Aug 31, 2011 10:16 am
by fiveayem
Hello,

I am currently developping an ATA DMA driver for my OS, and I'd like you to help me, because I'm facing quite a great problem...

Indeed, when I try to issue any DMA command to the command port (according to the method described in this article : http://wiki.osdev.org/ATA/ATAPI_using_D ... mmand_Byte), I always get an error message in the console while running my OS on qemu. This says that dma command 0x8 or 0x9 is not supported.

According to what I have understood from the article : 0x8 means "write" (bit 3 = start set, and bit 0 unset) and 0x9 means "write" (both bit 3 and bit 0 set). In fact, as mentionned in the tutorial, I proceed in the following way :

Code: Select all

// Here, I'm trying to issue a read command :
outb(commandPort, 0); // Clearing all the bits, including the start/stop bit
outb(commandPort, 1); // Setting the read bit
outb(commandPort, 8 | 1 = 9); // Reenabling the start/stop bit, keeping the read bit enabled
According to you, what's wrong with my code or my reasoning ?

Thanks for reading me !

Re: [ATA DMA and qemu] "dma: command 0x9 not supported"

Posted: Wed Aug 31, 2011 2:25 pm
by gerryg400
According to the article, you have your bit definitions incorrect. Bit 0 is the start/stop bit. Bit 3 is the read/write control. You must set bit 3 to the correct direction before setting bit 0.

Re: [ATA DMA and qemu] "dma: command 0x9 not supported"

Posted: Thu Sep 01, 2011 4:47 am
by fiveayem
Thanks, now I do not get any DMA error. Except that when I send the ATA_DMA_READ or ATA_DMA_WRITE command (via I/O ports, in exactly the same way that I would send a read/write command using PIO and not DMA), I get the error bit set in the status register.

I would like to mention that my IDE I/O manager using PIO works very well, so I reused the code replacing the ATA_PIO_READ and ATA_PIO_WRITE commands with corresponding DMA commands. And of course, I do not poll to get data in the buffer...

Thus, as this part seems correct to me, I wondered if there was something wrong while sending the PRDT address. Actually, I make it in the following way :
  • Send the lowest byte of the physical address of the buffer to port (bus master reg + 0x4).
  • Send the next byte to port (bus master reg + 0x5).
  • Send the following to (bus master reg + 0x6).
  • Send the highest byte to (bus master reg + 0x7).
(Note that this example is for the first IDE controller)