1/* $Id: PeeCeeI.c,v 1.1.1.1 2007/08/03 18:52:18 Exp $ 2 * PeeCeeI.c: The emerging standard... 3 * 4 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) 5 */ 6 7#include <asm/io.h> 8#include <asm/byteorder.h> 9 10void outsb(unsigned long __addr, const void *src, unsigned long count) 11{ 12 void __iomem *addr = (void __iomem *) __addr; 13 const u8 *p = src; 14 15 while (count--) 16 outb(*p++, addr); 17} 18 19void outsw(unsigned long __addr, const void *src, unsigned long count) 20{ 21 void __iomem *addr = (void __iomem *) __addr; 22 23 if (count) { 24 u16 *ps = (u16 *)src; 25 u32 *pi; 26 27 if (((u64)src) & 0x2) { 28 u16 val = le16_to_cpup(ps); 29 outw(val, addr); 30 ps++; 31 count--; 32 } 33 pi = (u32 *)ps; 34 while (count >= 2) { 35 u32 w = le32_to_cpup(pi); 36 37 pi++; 38 outw(w >> 0, addr); 39 outw(w >> 16, addr); 40 count -= 2; 41 } 42 ps = (u16 *)pi; 43 if (count) { 44 u16 val = le16_to_cpup(ps); 45 outw(val, addr); 46 } 47 } 48} 49 50void outsl(unsigned long __addr, const void *src, unsigned long count) 51{ 52 void __iomem *addr = (void __iomem *) __addr; 53 54 if (count) { 55 if ((((u64)src) & 0x3) == 0) { 56 u32 *p = (u32 *)src; 57 while (count--) { 58 u32 val = cpu_to_le32p(p); 59 outl(val, addr); 60 p++; 61 } 62 } else { 63 u8 *pb; 64 u16 *ps = (u16 *)src; 65 u32 l = 0, l2; 66 u32 *pi; 67 68 switch (((u64)src) & 0x3) { 69 case 0x2: 70 count -= 1; 71 l = cpu_to_le16p(ps) << 16; 72 ps++; 73 pi = (u32 *)ps; 74 while (count--) { 75 l2 = cpu_to_le32p(pi); 76 pi++; 77 outl(((l >> 16) | (l2 << 16)), addr); 78 l = l2; 79 } 80 ps = (u16 *)pi; 81 l2 = cpu_to_le16p(ps); 82 outl(((l >> 16) | (l2 << 16)), addr); 83 break; 84 85 case 0x1: 86 count -= 1; 87 pb = (u8 *)src; 88 l = (*pb++ << 8); 89 ps = (u16 *)pb; 90 l2 = cpu_to_le16p(ps); 91 ps++; 92 l |= (l2 << 16); 93 pi = (u32 *)ps; 94 while (count--) { 95 l2 = cpu_to_le32p(pi); 96 pi++; 97 outl(((l >> 8) | (l2 << 24)), addr); 98 l = l2; 99 } 100 pb = (u8 *)pi; 101 outl(((l >> 8) | (*pb << 24)), addr); 102 break; 103 104 case 0x3: 105 count -= 1; 106 pb = (u8 *)src; 107 l = (*pb++ << 24); 108 pi = (u32 *)pb; 109 while (count--) { 110 l2 = cpu_to_le32p(pi); 111 pi++; 112 outl(((l >> 24) | (l2 << 8)), addr); 113 l = l2; 114 } 115 ps = (u16 *)pi; 116 l2 = cpu_to_le16p(ps); 117 ps++; 118 pb = (u8 *)ps; 119 l2 |= (*pb << 16); 120 outl(((l >> 24) | (l2 << 8)), addr); 121 break; 122 } 123 } 124 } 125} 126 127void insb(unsigned long __addr, void *dst, unsigned long count) 128{ 129 void __iomem *addr = (void __iomem *) __addr; 130 131 if (count) { 132 u32 *pi; 133 u8 *pb = dst; 134 135 while ((((unsigned long)pb) & 0x3) && count--) 136 *pb++ = inb(addr); 137 pi = (u32 *)pb; 138 while (count >= 4) { 139 u32 w; 140 141 w = (inb(addr) << 24); 142 w |= (inb(addr) << 16); 143 w |= (inb(addr) << 8); 144 w |= (inb(addr) << 0); 145 *pi++ = w; 146 count -= 4; 147 } 148 pb = (u8 *)pi; 149 while (count--) 150 *pb++ = inb(addr); 151 } 152} 153 154void insw(unsigned long __addr, void *dst, unsigned long count) 155{ 156 void __iomem *addr = (void __iomem *) __addr; 157 158 if (count) { 159 u16 *ps = dst; 160 u32 *pi; 161 162 if (((unsigned long)ps) & 0x2) { 163 *ps++ = le16_to_cpu(inw(addr)); 164 count--; 165 } 166 pi = (u32 *)ps; 167 while (count >= 2) { 168 u32 w; 169 170 w = (le16_to_cpu(inw(addr)) << 16); 171 w |= (le16_to_cpu(inw(addr)) << 0); 172 *pi++ = w; 173 count -= 2; 174 } 175 ps = (u16 *)pi; 176 if (count) 177 *ps = le16_to_cpu(inw(addr)); 178 } 179} 180 181void insl(unsigned long __addr, void *dst, unsigned long count) 182{ 183 void __iomem *addr = (void __iomem *) __addr; 184 185 if (count) { 186 if ((((unsigned long)dst) & 0x3) == 0) { 187 u32 *pi = dst; 188 while (count--) 189 *pi++ = le32_to_cpu(inl(addr)); 190 } else { 191 u32 l = 0, l2, *pi; 192 u16 *ps; 193 u8 *pb; 194 195 switch (((unsigned long)dst) & 3) { 196 case 0x2: 197 ps = dst; 198 count -= 1; 199 l = le32_to_cpu(inl(addr)); 200 *ps++ = l; 201 pi = (u32 *)ps; 202 while (count--) { 203 l2 = le32_to_cpu(inl(addr)); 204 *pi++ = (l << 16) | (l2 >> 16); 205 l = l2; 206 } 207 ps = (u16 *)pi; 208 *ps = l; 209 break; 210 211 case 0x1: 212 pb = dst; 213 count -= 1; 214 l = le32_to_cpu(inl(addr)); 215 *pb++ = l >> 24; 216 ps = (u16 *)pb; 217 *ps++ = ((l >> 8) & 0xffff); 218 pi = (u32 *)ps; 219 while (count--) { 220 l2 = le32_to_cpu(inl(addr)); 221 *pi++ = (l << 24) | (l2 >> 8); 222 l = l2; 223 } 224 pb = (u8 *)pi; 225 *pb = l; 226 break; 227 228 case 0x3: 229 pb = (u8 *)dst; 230 count -= 1; 231 l = le32_to_cpu(inl(addr)); 232 *pb++ = l >> 24; 233 pi = (u32 *)pb; 234 while (count--) { 235 l2 = le32_to_cpu(inl(addr)); 236 *pi++ = (l << 8) | (l2 >> 24); 237 l = l2; 238 } 239 ps = (u16 *)pi; 240 *ps++ = ((l >> 8) & 0xffff); 241 pb = (u8 *)ps; 242 *pb = l; 243 break; 244 } 245 } 246 } 247} 248