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