RHEL4/lib/iomap.c
<<
>>
Prefs
   1/*
   2 * Implement the default iomap interfaces
   3 */
   4#include <linux/pci.h>
   5#include <linux/module.h>
   6#include <asm/io.h>
   7
   8/*
   9 * Read/write from/to an (offsettable) iomem cookie. It might be a PIO
  10 * access or a MMIO access, these functions don't care. The info is
  11 * encoded in the hardware mapping set up by the mapping functions
  12 * (or the cookie itself, depending on implementation and hw).
  13 *
  14 * The generic routines don't assume any hardware mappings, and just
  15 * encode the PIO/MMIO as part of the cookie. They coldly assume that
  16 * the MMIO IO mappings are not in the low address range.
  17 *
  18 * Architectures for which this is not true can't use this generic
  19 * implementation and should do their own copy.
  20 */
  21
  22#ifndef HAVE_ARCH_PIO_SIZE
  23/*
  24 * We encode the physical PIO addresses (0-0xffff) into the
  25 * pointer by offsetting them with a constant (0x10000) and
  26 * assuming that all the low addresses are always PIO. That means
  27 * we can do some sanity checks on the low bits, and don't
  28 * need to just take things for granted.
  29 */
  30#define PIO_OFFSET      0x10000UL
  31#define PIO_MASK        0x0ffffUL
  32#define PIO_RESERVED    0x40000UL
  33#endif
  34
  35/*
  36 * Ugly macros are a way of life.
  37 */
  38#define VERIFY_PIO(port) BUG_ON((port & ~PIO_MASK) != PIO_OFFSET)
  39
  40#define IO_COND(addr, is_pio, is_mmio) do {                     \
  41        unsigned long port = (unsigned long __force)addr;       \
  42        if (port < PIO_RESERVED) {                              \
  43                VERIFY_PIO(port);                               \
  44                port &= PIO_MASK;                               \
  45                is_pio;                                         \
  46        } else {                                                \
  47                is_mmio;                                        \
  48        }                                                       \
  49} while (0)
  50
  51unsigned int fastcall ioread8(void __iomem *addr)
  52{
  53        IO_COND(addr, return inb(port), return readb(addr));
  54}
  55unsigned int fastcall ioread16(void __iomem *addr)
  56{
  57        IO_COND(addr, return inw(port), return readw(addr));
  58}
  59unsigned int fastcall ioread32(void __iomem *addr)
  60{
  61        IO_COND(addr, return inl(port), return readl(addr));
  62}
  63EXPORT_SYMBOL(ioread8);
  64EXPORT_SYMBOL(ioread16);
  65EXPORT_SYMBOL(ioread32);
  66
  67void fastcall iowrite8(u8 val, void __iomem *addr)
  68{
  69        IO_COND(addr, outb(val,port), writeb(val, addr));
  70}
  71void fastcall iowrite16(u16 val, void __iomem *addr)
  72{
  73        IO_COND(addr, outw(val,port), writew(val, addr));
  74}
  75void fastcall iowrite32(u32 val, void __iomem *addr)
  76{
  77        IO_COND(addr, outl(val,port), writel(val, addr));
  78}
  79EXPORT_SYMBOL(iowrite8);
  80EXPORT_SYMBOL(iowrite16);
  81EXPORT_SYMBOL(iowrite32);
  82
  83/*
  84 * These are the "repeat MMIO read/write" functions.
  85 * Note the "__raw" accesses, since we don't want to
  86 * convert to CPU byte order. We write in "IO byte
  87 * order" (we also don't have IO barriers).
  88 */
  89static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
  90{
  91        while (--count >= 0) {
  92                u8 data = __raw_readb(addr);
  93                *dst = data;
  94                dst++;
  95        }
  96}
  97static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
  98{
  99        while (--count >= 0) {
 100                u16 data = __raw_readw(addr);
 101                *dst = data;
 102                dst++;
 103        }
 104}
 105static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
 106{
 107        while (--count >= 0) {
 108                u32 data = __raw_readl(addr);
 109                *dst = data;
 110                dst++;
 111        }
 112}
 113
 114static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
 115{
 116        while (--count >= 0) {
 117                __raw_writeb(*src, addr);
 118                src++;
 119        }
 120}
 121static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
 122{
 123        while (--count >= 0) {
 124                __raw_writew(*src, addr);
 125                src++;
 126        }
 127}
 128static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
 129{
 130        while (--count >= 0) {
 131                __raw_writel(*src, addr);
 132                src++;
 133        }
 134}
 135
 136void fastcall ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
 137{
 138        IO_COND(addr, insb(port,dst,count), mmio_insb(addr, dst, count));
 139}
 140void fastcall ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
 141{
 142        IO_COND(addr, insw(port,dst,count), mmio_insw(addr, dst, count));
 143}
 144void fastcall ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
 145{
 146        IO_COND(addr, insl(port,dst,count), mmio_insl(addr, dst, count));
 147}
 148EXPORT_SYMBOL(ioread8_rep);
 149EXPORT_SYMBOL(ioread16_rep);
 150EXPORT_SYMBOL(ioread32_rep);
 151
 152void fastcall iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
 153{
 154        IO_COND(addr, outsb(port, src, count), mmio_outsb(addr, src, count));
 155}
 156void fastcall iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
 157{
 158        IO_COND(addr, outsw(port, src, count), mmio_outsw(addr, src, count));
 159}
 160void fastcall iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
 161{
 162        IO_COND(addr, outsl(port, src,count), mmio_outsl(addr, src, count));
 163}
 164EXPORT_SYMBOL(iowrite8_rep);
 165EXPORT_SYMBOL(iowrite16_rep);
 166EXPORT_SYMBOL(iowrite32_rep);
 167
 168/* Create a virtual mapping cookie for an IO port range */
 169void __iomem *ioport_map(unsigned long port, unsigned int nr)
 170{
 171        if (port > PIO_MASK)
 172                return NULL;
 173        return (void __iomem *) (unsigned long) (port + PIO_OFFSET);
 174}
 175
 176void ioport_unmap(void __iomem *addr)
 177{
 178        /* Nothing to do */
 179}
 180EXPORT_SYMBOL(ioport_map);
 181EXPORT_SYMBOL(ioport_unmap);
 182
 183/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
 184void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
 185{
 186        unsigned long start = pci_resource_start(dev, bar);
 187        unsigned long len = pci_resource_len(dev, bar);
 188        unsigned long flags = pci_resource_flags(dev, bar);
 189
 190        if (!len || !start)
 191                return NULL;
 192        if (maxlen && len > maxlen)
 193                len = maxlen;
 194        if (flags & IORESOURCE_IO)
 195                return ioport_map(start, len);
 196        if (flags & IORESOURCE_MEM) {
 197                if (flags & IORESOURCE_CACHEABLE)
 198                        return ioremap(start, len);
 199                return ioremap_nocache(start, len);
 200        }
 201        /* What? */
 202        return NULL;
 203}
 204
 205void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
 206{
 207        IO_COND(addr, /* nothing */, iounmap(addr));
 208}
 209EXPORT_SYMBOL(pci_iomap);
 210EXPORT_SYMBOL(pci_iounmap);
 211