Page 1 of 1

Ultra DMA puzzles me ...

Posted: Wed Feb 15, 2006 5:35 am
by Pype.Clicker
i'm still far from having UltraDMA ready, but i'm trying to have required framework up so that UDMA-based drivers can later be developed.

What puzzles me is the so-called "Ultra DMA mode" byte in "ATA IDENTIFY" block. According to http://www.t13.org/technical/e00159r2.pdf, i decode the "extension" word (#53), which succesfully reports UDMA modes available on word #88. Problem is, i cannot make sense of the retrieved content of word #88.

E.g. on my "maxtor" drives, it reports dma mode = 8319 (e.g. UDMA mode 0 and 1 selected, UDMA mode 0,3 and 4 supported) ...
My "quantum" drives report 8255 (which would translate into UDMAn mode 1 selected, UDMA modes 6,4,2 and 0 supported).

i'm quite puzzled. my guess was if mode X was supported, all modes *below* X also had to be supported, and that only 1 mode could be selected...

Has anyone read those bytes already ? Do you know of a way to know what value Linux found there ?

I have an experimental disk image at http://clicker.sf.net/c32-diskscan-094.img.gz if someone wants to try my method on his disk (in which case i'm interrested by "UDMA mode" report in the log).
I'm also interrested in other disk images from your OS that would do similar detection to cross-check the values obtained on my machines.

and unfortunately, neither BOCHS nor QEMU disks have DMA support :P

----
More on my attemps to have UDMA working on my wiki
Snapshot of the log after ioman module is available in the newz.

Re:Ultra DMA puzzles me ...

Posted: Wed Feb 15, 2006 5:46 am
by nick8325
hdparm -I /dev/hda (needs to be run as root) will print all sorts of stuff about the drive, including, it seems, the UDMA mode.

I think your decodings of the UDMA words might be wrong. I make 8319 to be 0x207f, which has bits 13 and 0-6 set, which seems to indicate that UDMA 5 is selected and 0-5 are supported, along with reserved bit 6 (UDMA 6?). 8255 is 0x203f, which has UDMA 5 selected and 0-5 supported.

Re:Ultra DMA puzzles me ...

Posted: Wed Feb 15, 2006 5:52 am
by Pype.Clicker
::)

Code: Select all

    log(KLOG_DEBUG,0,"ATA ver %4x.%i @%x: extensions: %4x, UDMA mode %i",
   info->ata_version_major, info->ata_version_minor,nfo->raw,
   info->extensions, info->udma_mode);
 
Omg. you're right ... llama mistake :P

(hit ESC now to laugh at Pype ...)

-- tnx, btw. I could have spent days on it ...

Re:Ultra DMA puzzles me ...

Posted: Wed Feb 15, 2006 6:09 am
by distantvoices
@Pype: such stuff happens sometimes. Sometimes one hunts a small bug and "doesn't see the wood coz of the trees"

What interrests me is then: how does one use these modes?

Re:Ultra DMA puzzles me ...

Posted: Wed Feb 15, 2006 7:11 am
by Pype.Clicker
well, first you have to define a "list of physical region descriptor" that will tell the PCI IDE busmaster where data should end. You then "activate" that list (bm_start, that is) for the transfer and issue a "ATACMD_READ_DMA_EXT" command (or a regular ATACMD_PACKET command with DMA bit set in the features register) and voil?.

The actual procedure is detailed in "ataiopci.c" of Hale's driver, in functions exec_pci_ata_cmd and dma_pci_packet respectively.

Now if you meant "how do you select UDMA mode 4 instead of UDMA mode 5", that's something i haven't investigated so far. i suspect the "SET FEATURE" ATA command could be used, but iiuc, the device will select the highest appropriate mode at startup (e.g. degrade to UDMA mode 2 if 40-wire connector only is present) so you don't have to worry.

Re:Ultra DMA puzzles me ...

Posted: Wed Feb 15, 2006 7:22 am
by distantvoices
it sounds like assigning physical regions of memory to a NIC for use as ringbuffer. Hm. Then, writing a block would include droping the bulk of data to a given region in that buffer, fill in a descriptor like thing for the ide controller to gnaw at and voila, here we go. And if data has been read we have to fetch it from such a region.

Have I under stood this right?

Re:Ultra DMA puzzles me ...

Posted: Wed Feb 15, 2006 7:51 am
by Pype.Clicker
It is indeed very close to the NIC ringbuffer thing, with one strong difference which is that the PRD lists is a "scatter/gather" list. The way it will usually work is that you assign a 64K contiguous and 64K-aligned region as PRD array. Let's say it is

Code: Select all

   ata_prd_entry* prd_primary=kalloc(64K,64,MEM_ALIGNED|MEM_CONTIGUOUS),
*prd_secondary=kalloc(64K,64,MEM_ALIGNED|MEM_CONTIGUOUS);

  bm_set_prd(prim,phys_addr_of(prd_primary));
  bm_set_prd(secn,phys_addr_of(prd_secondary));
when a read request will be issued, the busmaster will read the descriptors in prd_primary[ 0 ], prd_primary[ 1 ], etc. to know where data should be placed. Each entry in the scatter/gather list tells the start of a physical area and the size of that area.

Let's say i want data to be written to (physical) pages 0xcaffe000, 0xc0ffe000, 0xc0fff000, 0xc1000000... that is, 4 pages.

according to "T13/1510D revision 0a, section 6.9",
region cannot straddle a 64K boundary
so i can make c0ffe--- and c0fff--- a 8K region based at c0ffe000, but i cannot include 0xc1000--- in it.

The entries of the PRD would then be

Code: Select all

prd = {
   {base: 0xcaffe000, size: 4K},
   {base: 0xc0ffe000, size: 8K},
   {base: 0xc100000, size: 4K, endoflist:1}
};
and voil?, i'm now ready to issue the 16K (32 sectors) request to the disk ...

Note that if i feel so, the remaining PRD entries could be prepared in a ringbuffer fashion to accomodate further transfers (in which case i would re-define the PRD list pointer within the same area) or i could keep the pre-digested PRD lists anywhere, just writing them to the "committed" area on demand when the previous command completes. You're just strongly hint'd not to modify the content of the running PRD list ...

Re:Ultra DMA puzzles me ...

Posted: Sun Feb 19, 2006 7:46 am
by distantvoices
ok, so this is rather a list of "Here are some memory regions: Write them" or "Here are some memory regions: Read stuff into them"?

That's interresting. It'd involve less repeating of inport's/outports to the Data port of the IDE controller to write/read data - as inport/outport accesses a slow device, these operations are kinda slow compared to a memcpyd iiuc.

So, thinking in this context, we might as well have some upper layer to the UDMA ata driver which schedules the io-requests and builds accordng gather/scatter lists to commit to the harddrive.

Can gather/scatter operations be mixed? say
READ block XX to 0xcafe;
WRITE 0xbabe to block YY;
WRITE 0xbeef to block ZZ;

Re:Ultra DMA puzzles me ...

Posted: Sun Feb 19, 2006 12:25 pm
by Pype.Clicker
the list is used for one command and one command is either read or write ... so in one ATA command you can move data between a contiguous set of disk block and a list of regions in memory. One direction per command...

Re:Ultra DMA puzzles me ...

Posted: Sun Feb 19, 2006 12:56 pm
by Brendan
Hi,
Pype.Clicker wrote:the list is used for one command and one command is either read or write ... so in one ATA command you can move data between a contiguous set of disk block and a list of regions in memory. One direction per command...
Of course we're not forgetting NCQ (or Native Command Queuing), where (AFAIK) there's one "scatter gather" list for each command.

Because NGQ allows commands to be mixed (i.e. done asynchronously in hardware, where several commands can be partially completed at the same time), I'd say scatter/gather operations can definately be mixed (IFF NCQ is supported).


Cheers,

Brendan

Re:Ultra DMA puzzles me ...

Posted: Sun Feb 19, 2006 3:03 pm
by Pype.Clicker
yes ... the command-queueing stuff ... I think there is something called "ADMA" in ATA drafts, around page 30 that covers this, but it's no longer ultra-dma proper ...
The ADMA command chain is a linked-list of command parameters known as a Command Parameter Block
(CPB). The CPB contains all the information needed to control both the ADMA and the ATA device.
Additionally, the CPB points to a second linked-list that defines the scatter-gather relationship of the memory
buffers to be used for data transfer. This second chain is termed a Physical Region Descriptor (PRD).
I shall admit that i plan to focus on implementing UDMA first, and then i'll see for ADMA ... i don't think i have any ADMA-capable drive for testing anyway .. the fact neither QEMU nor bochs is UDMA-capable is already a sufficient challenge for me.