All of lore.kernel.org
 help / color / mirror / Atom feed
* [parisc-linux] The new iomap interface
@ 2004-09-17 12:46 Matthew Wilcox
  2004-09-17 16:24 ` Grant Grundler
  0 siblings, 1 reply; 7+ messages in thread
From: Matthew Wilcox @ 2004-09-17 12:46 UTC (permalink / raw)
  To: parisc-linux


Shortly after 2.6.9-rc2, Linus introduced a new way of accessing IO devices
called iomap.  This gives us the opportunity to overhaul our device IO
accessors.  Let's go over how this works:

There are various ways to get hold of an iomem cookie, such as calling
pci_iomap() or ioport_map().  One then passes this cookie to a different
set of functions ioread8(), ioread16(), ioread32(), iowrite8(),
iowrite16() and iowrite32().  When one is done with it, one calls something
like pci_iounmap() or ioport_unmap().

There are several cases we have to be able to handle.  Obviously,
we have to handle PCI/EISA/ISA io memory and PCI/EISA/ISA io ports.
It'd also be good to handle native PA io memory.  I'd like to resurrect
the USE_HPPA_IOREMAP code that Helge worked on at one point (it's really
time to do away with the rsm/mtsm around byte loads/stores).

So here's the hardware constraints.  All the EISA and PCI adapters map
IO memory space into PA memory space, but we have to do byte swapping.
The EISA adapter maps IO port space into PA memory space, but does so in
such a convoluted way that we may not be able to fulfill a request for
a contiguous chunk of ports.  The Dino PCI adapter requires reads and writes
to control registers to access port space.  Astro-based systems have a
dense mapping for IO ports into memory ... but sometimes require
additional hacks to work around bugs.  PAT-based systems have a sparse
mapping for IO ports into memory, but require an additional read to flush
the write.

Phew.  OK.  How to make that lot work?  Well .. looks to me like we want:

/*
 * Technically, this should be 'if (VMALLOC_START < addr < VMALLOC_END),
 * but that's slow and we know it'll be within the first 2GB.
 */
#define INDIRECT_ADDR(addr)     (((unsigned long)(addr) & 0x80000000) != 0)

static inline int ioread16(void __iomem *addr)
{
        if (unlikely(INDIRECT_ADDR(addr)))
                return __ioread16(addr);
        return le16_to_cpup((u16 *)addr);
}

This should be a test, a non-executed branch and a load in the direct-load
case.

Then __ioread16() can look something like ... 

struct iomem_ops {
        int (*read8)(void __iomem *addr);
        int (*read16)(void __iomem *addr);
        int (*read32)(void __iomem *addr);
        void (*write8)(u8, void __iomem *addr);
        void (*write16)(u16, void __iomem *addr);
        void (*write32)(u32, void __iomem *addr);
};

struct iomem_ops *iomem_ops[8]; 

#define ADDR_TO_REGION(addr)    (((unsigned long)addr >> 28) & 7)

int __ioread16(void __iomem *addr)
{
        return iomem_ops[ADDR_TO_REGION(addr)]->read16(addr);
}

That gives us 256MB of io space in each handler, and 8 possible handlers.
Anything that can be directly mapped like PCI io memory will be, and therefore
much quicker than the current io port ops mess.  We'll need handlers for:

0 -- ISA/EISA port space that isn't contiguous
1 -- PCI port space for Dino
2 -- PCI port space for Astro w/Elroy < 2.2
3 -- PCI port space for PAT PDC
4 -- Non-byteswapped GSC IO memory
7 -- Legacy drivers that are passing an old-style readX() cookie to the
     new-style ioreadX() functions.  Doh.

Note that these interfaces give us the opportunity to do much more work
at IO map time, and much less mucking around at IO access time.  The
design here is clearly 32-bit centric, but the macros can be ifdeffed to
work differently on 64-bit.

Comments, suggestions, alternative designs?

-- 
"Next the statesmen will invent cheap lies, putting the blame upon 
the nation that is attacked, and every man will be glad of those
conscience-soothing falsities, and will diligently study them, and refuse
to examine any refutations of them; and thus he will by and by convince 
himself that the war is just, and will thank God for the better sleep 
he enjoys after this process of grotesque self-deception." -- Mark Twain
_______________________________________________
parisc-linux mailing list
parisc-linux@lists.parisc-linux.org
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2004-09-19 13:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-17 12:46 [parisc-linux] The new iomap interface Matthew Wilcox
2004-09-17 16:24 ` Grant Grundler
2004-09-17 16:50   ` Matthew Wilcox
2004-09-17 18:17     ` Grant Grundler
     [not found]     ` <1095436838.26146.22.camel@localhost.localdomain>
2004-09-19  9:22       ` Christoph Hellwig
2004-09-19 13:10         ` Matthew Wilcox
2004-09-19 13:10         ` Matthew Wilcox

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.