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