Logo Search packages:      
Sourcecode: linux version File versions

PeeCeeI.c

/*
 * PeeCeeI.c: The emerging standard...
 *
 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
 */

#include <asm/io.h>
#include <asm/byteorder.h>

void outsb(unsigned long __addr, const void *src, unsigned long count)
{
      void __iomem *addr = (void __iomem *) __addr;
      const u8 *p = src;

      while (count--)
            outb(*p++, addr);
}

void outsw(unsigned long __addr, const void *src, unsigned long count)
{
      void __iomem *addr = (void __iomem *) __addr;

      if (count) {
            u16 *ps = (u16 *)src;
            u32 *pi;

            if (((u64)src) & 0x2) {
                  u16 val = le16_to_cpup(ps);
                  outw(val, addr);
                  ps++;
                  count--;
            }
            pi = (u32 *)ps;
            while (count >= 2) {
                  u32 w = le32_to_cpup(pi);

                  pi++;
                  outw(w >> 0, addr);
                  outw(w >> 16, addr);
                  count -= 2;
            }
            ps = (u16 *)pi;
            if (count) {
                  u16 val = le16_to_cpup(ps);
                  outw(val, addr);
            }
      }
}

void outsl(unsigned long __addr, const void *src, unsigned long count)
{
      void __iomem *addr = (void __iomem *) __addr;

      if (count) {
            if ((((u64)src) & 0x3) == 0) {
                  u32 *p = (u32 *)src;
                  while (count--) {
                        u32 val = cpu_to_le32p(p);
                        outl(val, addr);
                        p++;
                  }
            } else {
                  u8 *pb;
                  u16 *ps = (u16 *)src;
                  u32 l = 0, l2;
                  u32 *pi;

                  switch (((u64)src) & 0x3) {
                  case 0x2:
                        count -= 1;
                        l = cpu_to_le16p(ps) << 16;
                        ps++;
                        pi = (u32 *)ps;
                        while (count--) {
                              l2 = cpu_to_le32p(pi);
                              pi++;
                              outl(((l >> 16) | (l2 << 16)), addr);
                              l = l2;
                        }
                        ps = (u16 *)pi;
                        l2 = cpu_to_le16p(ps);
                        outl(((l >> 16) | (l2 << 16)), addr);
                        break;

                  case 0x1:
                        count -= 1;
                        pb = (u8 *)src;
                        l = (*pb++ << 8);
                        ps = (u16 *)pb;
                        l2 = cpu_to_le16p(ps);
                        ps++;
                        l |= (l2 << 16);
                        pi = (u32 *)ps;
                        while (count--) {
                              l2 = cpu_to_le32p(pi);
                              pi++;
                              outl(((l >> 8) | (l2 << 24)), addr);
                              l = l2;
                        }
                        pb = (u8 *)pi;
                        outl(((l >> 8) | (*pb << 24)), addr);
                        break;

                  case 0x3:
                        count -= 1;
                        pb = (u8 *)src;
                        l = (*pb++ << 24);
                        pi = (u32 *)pb;
                        while (count--) {
                              l2 = cpu_to_le32p(pi);
                              pi++;
                              outl(((l >> 24) | (l2 << 8)), addr);
                              l = l2;
                        }
                        ps = (u16 *)pi;
                        l2 = cpu_to_le16p(ps);
                        ps++;
                        pb = (u8 *)ps;
                        l2 |= (*pb << 16);
                        outl(((l >> 24) | (l2 << 8)), addr);
                        break;
                  }
            }
      }
}

void insb(unsigned long __addr, void *dst, unsigned long count)
{
      void __iomem *addr = (void __iomem *) __addr;

      if (count) {
            u32 *pi;
            u8 *pb = dst;

            while ((((unsigned long)pb) & 0x3) && count--)
                  *pb++ = inb(addr);
            pi = (u32 *)pb;
            while (count >= 4) {
                  u32 w;

                  w  = (inb(addr) << 24);
                  w |= (inb(addr) << 16);
                  w |= (inb(addr) << 8);
                  w |= (inb(addr) << 0);
                  *pi++ = w;
                  count -= 4;
            }
            pb = (u8 *)pi;
            while (count--)
                  *pb++ = inb(addr);
      }
}

void insw(unsigned long __addr, void *dst, unsigned long count)
{
      void __iomem *addr = (void __iomem *) __addr;

      if (count) {
            u16 *ps = dst;
            u32 *pi;

            if (((unsigned long)ps) & 0x2) {
                  *ps++ = le16_to_cpu(inw(addr));
                  count--;
            }
            pi = (u32 *)ps;
            while (count >= 2) {
                  u32 w;

                  w  = (le16_to_cpu(inw(addr)) << 16);
                  w |= (le16_to_cpu(inw(addr)) << 0);
                  *pi++ = w;
                  count -= 2;
            }
            ps = (u16 *)pi;
            if (count)
                  *ps = le16_to_cpu(inw(addr));
      }
}

void insl(unsigned long __addr, void *dst, unsigned long count)
{
      void __iomem *addr = (void __iomem *) __addr;

      if (count) {
            if ((((unsigned long)dst) & 0x3) == 0) {
                  u32 *pi = dst;
                  while (count--)
                        *pi++ = le32_to_cpu(inl(addr));
            } else {
                  u32 l = 0, l2, *pi;
                  u16 *ps;
                  u8 *pb;

                  switch (((unsigned long)dst) & 3) {
                  case 0x2:
                        ps = dst;
                        count -= 1;
                        l = le32_to_cpu(inl(addr));
                        *ps++ = l;
                        pi = (u32 *)ps;
                        while (count--) {
                              l2 = le32_to_cpu(inl(addr));
                              *pi++ = (l << 16) | (l2 >> 16);
                              l = l2;
                        }
                        ps = (u16 *)pi;
                        *ps = l;
                        break;

                  case 0x1:
                        pb = dst;
                        count -= 1;
                        l = le32_to_cpu(inl(addr));
                        *pb++ = l >> 24;
                        ps = (u16 *)pb;
                        *ps++ = ((l >> 8) & 0xffff);
                        pi = (u32 *)ps;
                        while (count--) {
                              l2 = le32_to_cpu(inl(addr));
                              *pi++ = (l << 24) | (l2 >> 8);
                              l = l2;
                        }
                        pb = (u8 *)pi;
                        *pb = l;
                        break;

                  case 0x3:
                        pb = (u8 *)dst;
                        count -= 1;
                        l = le32_to_cpu(inl(addr));
                        *pb++ = l >> 24;
                        pi = (u32 *)pb;
                        while (count--) {
                              l2 = le32_to_cpu(inl(addr));
                              *pi++ = (l << 8) | (l2 >> 24);
                              l = l2;
                        }
                        ps = (u16 *)pi;
                        *ps++ = ((l >> 8) & 0xffff);
                        pb = (u8 *)ps;
                        *pb = l;
                        break;
                  }
            }
      }
}


Generated by  Doxygen 1.6.0   Back to index