Subject: ATA devices attached to arbitary busses

From: "Bryan Althouse" <[email-masked]>
Date: Thu, 5 May 2005 13:56:57 -0400

[email-masked]  wrote on 8/19/2002:

> We support ATA devices attached to arbitary busses. The newest ATA code
> supports arbitary mmio/pio addressing mechanisms. You don't need ISA or
> an ISA like bus.

This is good news!  We want to connect an IDE flash drive to the local bus
of an rm9224.  Of course we will have to make an IDE host adapter with an
FPGA.  Right now, I'm a bit clueless as to how to get the linux kernel to
support this.  Could someone please point me in the right direction?  What
kernel source files should I be looking at?  Is there any documentation?
Many thanks!

Bryan

---

From: Alan Cox <[email-masked]>
Date: Thu, 05 May 2005 19:05:39 +0100

> kernel source files should I be looking at?  Is there any documentation?

It really depends on the complexity of your controller. If you are just
doing PIO with generic IDE interfacing then its simply a matter of
telling Linux that there is an interface at these addresses with these
port operations and it'll just do the rest for you, except hotplug.

Basically for the standard port layouts.

	hw_regs_t hw;
	ide_hwif_t *hwif;

	memset(&hw, 0, sizeof(hw));
	ide_std_init_ports(&hw, base_port_num, ctrl_port);
	hw.irq = IRQ_LINE;
	hw.dma = NO_DMA;

	index = ide_register_hw(&hw, &hwif);

If the port layout is non standard and you use mmio etc then you need to
set hw up by hand. drivers/ide/legacy/macide.c is a good example of
interfacing a non standard controller.

Alan

---

From: "Bryan Althouse" <[email-masked]>
Date: Fri, 6 May 2005 11:19:47 -0400

Alan,

Thank you, that is very helpful.  I think I understand, but let me ramble a
bit so that you can correct me if I am wrong.  

All IDE drives should have the identical memory map.  But, the kernel does
not communicate directly with the drive, it communicates though an IDE host
adaptor (which may have different implementations).  If the host adaptor's
memory map "matches" that of the IDE drive spec, then you consider it to be
a "standard port layout"?  Since my host adaptor will be implemented in an
FPGA, if I give it the IDE memory map defined in ide.h, then your example
code will be applicable.

The memory map defined in ide.h makes sense to me (it seems to match the IDE
drive memory map) until we get down to offset 6 (IDE_SELECT_OFFSET).  From
here down, I have trouble matching the #define names with the register
names/descriptions from the IDE spec.  Also, I am puzzled as to why there
are 10 registers defined in ide.h when my IDE spec only shows 9.  The IDE
spec that I am referencing looks like this:

CS0   CS1    DA2   DA1   DA0   READ              WRITE
A     N      0     0     0     Data              Data
A     N      0     0     1     Error             Features
A     N      0     1     0     Sector Count      Sector Count
A     N      0     1     1     Sector Number     Sector Number
A     N      1     0     0     Cylinder Low      Cylinder Low
A     N      1     0     1     Cylinder High     Cylinder High
A     N      1     1     0     Device/Head       Device/Head
A     N      1     1     1     Status            Command
N     A      1     1     0     Alternate Status  Device Control (IRQ en/dis)

ide.h shows the following offsets:

#define IDE_DATA_OFFSET		(0)
#define IDE_ERROR_OFFSET	(1)
#define IDE_NSECTOR_OFFSET	(2)
#define IDE_SECTOR_OFFSET	(3)
#define IDE_LCYL_OFFSET		(4)
#define IDE_HCYL_OFFSET		(5)
#define IDE_SELECT_OFFSET	(6)
#define IDE_STATUS_OFFSET	(7)
#define IDE_CONTROL_OFFSET	(8)
#define IDE_IRQ_OFFSET		(9)

Do you know of an IDE host adapter chipset which is standard?  If someone
knows of a part number, I could look up its datasheet.  This would probably
clear up my confusion.  Thanks again!  

Bryan

---

From: Geert Uytterhoeven <[email-masked]>
Date: Fri, 6 May 2005 18:47:41 +0200 (CEST)

> clear up my confusion.  Thanks again!  

This is not the direct `memory map' of the IDE drive's registers! It's an
indirect map, cfr. e.g.

    #define IDE_DATA_REG            (HWIF(drive)->io_ports[IDE_DATA_OFFSET])

So the actual register is found by looking up offset IDE_DATA_OFFSET in the
array HWIF(drive)->io_ports[].

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email-masked]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

---

From: "Bryan Althouse" <[email-masked]>
Date: Fri, 6 May 2005 13:09:03 -0400

> So the actual register is found by looking up offset IDE_DATA_OFFSET in
> the array HWIF(drive)->io_ports[].

Yes, I understand.  This is starting to make more sense.  Here is what I
have figured out:  The first 8 offsets are normally 0-7, just like their
array indexes.  Index 8 and 9, IDE_CONTROLL_OFFSET and IDE_IRQ_OFFSET, were
confusing me because I was expecting them to be the actual offset 8 and 9 --
and I could not find any IDE adapter data sheets that showed them located as
such.  Now that I take a second look at ide_std_init_ports(), I see that the
CONTROL register is treated as a special case, i.e. it is not expected to
follow the STATUS register in address space.  This jives with what I have
seen in data sheets.  

It looks like the example that Alan contributed does not update
HWIF(drive)->io_ports[IDE_IRQ_OFFSET].  Or at least I cant figure out where.
I am having trouble identifying this register in IDE data sheets.  Is it one
of the "not used" or obsolete registers?  Do I need to be conserned with it?
Thanks again.

Bryan