Import 2.3.18pre1
[davej-history.git] / arch / sparc64 / lib / PeeCeeI.c
blob56c005dfe623c044cc01d7c76c31b77a5a63c91d
1 /* $Id: PeeCeeI.c,v 1.4 1999/09/06 01:17:35 davem Exp $
2 * PeeCeeI.c: The emerging standard...
4 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
5 */
7 #include <linux/config.h>
9 #ifdef CONFIG_PCI
11 #include <asm/io.h>
12 #include <asm/byteorder.h>
14 void outsb(unsigned long addr, const void *src, unsigned long count)
16 const u8 *p = src;
18 while(count--)
19 outb(*p++, addr);
22 void outsw(unsigned long addr, const void *src, unsigned long count)
24 if(count) {
25 u16 *ps = (u16 *)src;
26 u32 *pi;
28 if(((u64)src) & 0x2) {
29 u16 val = le16_to_cpup(ps);
30 outw(val, addr);
31 ps++;
32 count--;
34 pi = (u32 *)ps;
35 while(count >= 2) {
36 u32 w = le32_to_cpup(pi);
38 pi++;
39 outw(w >> 0, addr);
40 outw(w >> 16, addr);
41 count -= 2;
43 ps = (u16 *)pi;
44 if(count) {
45 u16 val = le16_to_cpup(ps);
46 outw(val, addr);
51 void outsl(unsigned long addr, const void *src, unsigned long count)
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++;
61 } else {
62 u8 *pb;
63 u16 *ps = (u16 *)src;
64 u32 l = 0, l2;
65 u32 *pi;
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;
79 ps = (u16 *)pi;
80 l2 = cpu_to_le16p(ps);
81 outl(((l >> 16) | (l2 << 16)), addr);
82 break;
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;
99 pb = (u8 *)pi;
100 outl(((l >> 8) | (*pb << 24)), addr);
101 break;
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;
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;
126 void insb(unsigned long addr, void *dst, unsigned long count)
128 if(count) {
129 u32 *pi;
130 u8 *pb = dst;
132 while((((unsigned long)pb) & 0x3) && count--)
133 *pb++ = inb(addr);
134 pi = (u32 *)pb;
135 while(count >= 4) {
136 u32 w;
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;
145 pb = (u8 *)pi;
146 while(count--)
147 *pb++ = inb(addr);
151 void insw(unsigned long addr, void *dst, unsigned long count)
153 if(count) {
154 u16 *ps = dst;
155 u32 *pi;
157 if(((unsigned long)ps) & 0x2) {
158 *ps++ = le16_to_cpu(inw(addr));
159 count--;
161 pi = (u32 *)ps;
162 while(count >= 2) {
163 u32 w;
165 w = (le16_to_cpu(inw(addr)) << 16);
166 w |= (le16_to_cpu(inw(addr)) << 0);
167 *pi++ = w;
168 count -= 2;
170 ps = (u16 *)pi;
171 if(count)
172 *ps = le16_to_cpu(inw(addr));
176 void insl(unsigned long addr, void *dst, unsigned long count)
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;
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;
200 ps = (u16 *)pi;
201 *ps = l;
202 break;
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;
217 pb = (u8 *)pi;
218 *pb = l;
219 break;
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;
232 ps = (u16 *)pi;
233 *ps++ = ((l >> 8) & 0xffff);
234 pb = (u8 *)ps;
235 *pb = l;
236 break;
242 #endif /* CONFIG_PCI */