1
2
3
4
5
6#include <linux/kernel.h>
7#include <linux/types.h>
8#include <linux/string.h>
9
10#include <asm/io.h>
11
12u8 _inb(unsigned long addr)
13{
14 return __inb(addr);
15}
16
17u16 _inw(unsigned long addr)
18{
19 return __inw(addr);
20}
21
22u32 _inl(unsigned long addr)
23{
24 return __inl(addr);
25}
26
27
28void _outb(u8 b, unsigned long addr)
29{
30 __outb(b, addr);
31}
32
33void _outw(u16 b, unsigned long addr)
34{
35 __outw(b, addr);
36}
37
38void _outl(u32 b, unsigned long addr)
39{
40 __outl(b, addr);
41}
42
43u8 ___raw_readb(unsigned long addr)
44{
45 return __readb(addr);
46}
47
48u16 ___raw_readw(unsigned long addr)
49{
50 return __readw(addr);
51}
52
53u32 ___raw_readl(unsigned long addr)
54{
55 return __readl(addr);
56}
57
58u64 ___raw_readq(unsigned long addr)
59{
60 return __readq(addr);
61}
62
63u8 _readb(unsigned long addr)
64{
65 unsigned long r = __readb(addr);
66 mb();
67 return r;
68}
69
70u16 _readw(unsigned long addr)
71{
72 unsigned long r = __readw(addr);
73 mb();
74 return r;
75}
76
77u32 _readl(unsigned long addr)
78{
79 unsigned long r = __readl(addr);
80 mb();
81 return r;
82}
83
84u64 _readq(unsigned long addr)
85{
86 unsigned long r = __readq(addr);
87 mb();
88 return r;
89}
90
91void ___raw_writeb(u8 b, unsigned long addr)
92{
93 __writeb(b, addr);
94}
95
96void ___raw_writew(u16 b, unsigned long addr)
97{
98 __writew(b, addr);
99}
100
101void ___raw_writel(u32 b, unsigned long addr)
102{
103 __writel(b, addr);
104}
105
106void ___raw_writeq(u64 b, unsigned long addr)
107{
108 __writeq(b, addr);
109}
110
111void _writeb(u8 b, unsigned long addr)
112{
113 __writeb(b, addr);
114 mb();
115}
116
117void _writew(u16 b, unsigned long addr)
118{
119 __writew(b, addr);
120 mb();
121}
122
123void _writel(u32 b, unsigned long addr)
124{
125 __writel(b, addr);
126 mb();
127}
128
129void _writeq(u64 b, unsigned long addr)
130{
131 __writeq(b, addr);
132 mb();
133}
134
135
136
137
138
139void insb (unsigned long port, void *dst, unsigned long count)
140{
141 while (((unsigned long)dst) & 0x3) {
142 if (!count)
143 return;
144 count--;
145 *(unsigned char *) dst = inb(port);
146 ((unsigned char *) dst)++;
147 }
148
149 while (count >= 4) {
150 unsigned int w;
151 count -= 4;
152 w = inb(port);
153 w |= inb(port) << 8;
154 w |= inb(port) << 16;
155 w |= inb(port) << 24;
156 *(unsigned int *) dst = w;
157 ((unsigned int *) dst)++;
158 }
159
160 while (count) {
161 --count;
162 *(unsigned char *) dst = inb(port);
163 ((unsigned char *) dst)++;
164 }
165}
166
167
168
169
170
171
172
173
174
175void insw (unsigned long port, void *dst, unsigned long count)
176{
177 if (((unsigned long)dst) & 0x3) {
178 if (((unsigned long)dst) & 0x1) {
179 panic("insw: memory not short aligned");
180 }
181 if (!count)
182 return;
183 count--;
184 *(unsigned short* ) dst = inw(port);
185 ((unsigned short *) dst)++;
186 }
187
188 while (count >= 2) {
189 unsigned int w;
190 count -= 2;
191 w = inw(port);
192 w |= inw(port) << 16;
193 *(unsigned int *) dst = w;
194 ((unsigned int *) dst)++;
195 }
196
197 if (count) {
198 *(unsigned short*) dst = inw(port);
199 }
200}
201
202
203
204
205
206
207
208
209void insl (unsigned long port, void *dst, unsigned long count)
210{
211 unsigned int l = 0, l2;
212
213 if (!count)
214 return;
215
216 switch (((unsigned long) dst) & 0x3)
217 {
218 case 0x00:
219 while (count--)
220 {
221 *(unsigned int *) dst = inl(port);
222 ((unsigned int *) dst)++;
223 }
224 break;
225
226
227
228 case 0x02:
229 --count;
230
231 l = inl(port);
232 *(unsigned short *) dst = l;
233 ((unsigned short *) dst)++;
234
235 while (count--)
236 {
237 l2 = inl(port);
238 *(unsigned int *) dst = l >> 16 | l2 << 16;
239 ((unsigned int *) dst)++;
240 l = l2;
241 }
242 *(unsigned short *) dst = l >> 16;
243 break;
244 case 0x01:
245 --count;
246
247 l = inl(port);
248 *(unsigned char *) dst = l;
249 ((unsigned char *) dst)++;
250 *(unsigned short *) dst = l >> 8;
251 ((unsigned short *) dst)++;
252 while (count--)
253 {
254 l2 = inl(port);
255 *(unsigned int *) dst = l >> 24 | l2 << 8;
256 ((unsigned int *) dst)++;
257 l = l2;
258 }
259 *(unsigned char *) dst = l >> 24;
260 break;
261 case 0x03:
262 --count;
263
264 l = inl(port);
265 *(unsigned char *) dst = l;
266 ((unsigned char *) dst)++;
267 while (count--)
268 {
269 l2 = inl(port);
270 *(unsigned int *) dst = l << 24 | l2 >> 8;
271 ((unsigned int *) dst)++;
272 l = l2;
273 }
274 *(unsigned short *) dst = l >> 8;
275 ((unsigned short *) dst)++;
276 *(unsigned char *) dst = l >> 24;
277 break;
278 }
279}
280
281
282
283
284
285
286
287
288void outsb(unsigned long port, const void * src, unsigned long count)
289{
290 while (count) {
291 count--;
292 outb(*(char *)src, port);
293 ((char *) src)++;
294 }
295}
296
297
298
299
300
301
302
303void outsw (unsigned long port, const void *src, unsigned long count)
304{
305 if (((unsigned long)src) & 0x3) {
306 if (((unsigned long)src) & 0x1) {
307 panic("outsw: memory not short aligned");
308 }
309 outw(*(unsigned short*)src, port);
310 ((unsigned short *) src)++;
311 --count;
312 }
313
314 while (count >= 2) {
315 unsigned int w;
316 count -= 2;
317 w = *(unsigned int *) src;
318 ((unsigned int *) src)++;
319 outw(w >> 0, port);
320 outw(w >> 16, port);
321 }
322
323 if (count) {
324 outw(*(unsigned short *) src, port);
325 }
326}
327
328
329
330
331
332
333
334
335void outsl (unsigned long port, const void *src, unsigned long count)
336{
337 unsigned int l = 0, l2;
338
339 if (!count)
340 return;
341
342 switch (((unsigned long) src) & 0x3)
343 {
344 case 0x00:
345 while (count--)
346 {
347 outl(*(unsigned int *) src, port);
348 ((unsigned int *) src)++;
349 }
350 break;
351
352
353
354 case 0x02:
355 --count;
356
357 l = *(unsigned short *) src << 16;
358 ((unsigned short *) src)++;
359
360 while (count--)
361 {
362 l2 = *(unsigned int *) src;
363 ((unsigned int *) src)++;
364 outl (l >> 16 | l2 << 16, port);
365 l = l2;
366 }
367 l2 = *(unsigned short *) src;
368 outl (l >> 16 | l2 << 16, port);
369 break;
370 case 0x01:
371 --count;
372
373 l = *(unsigned char *) src << 8;
374 ((unsigned char *) src)++;
375 l |= *(unsigned short *) src << 16;
376 ((unsigned short *) src)++;
377 while (count--)
378 {
379 l2 = *(unsigned int *) src;
380 ((unsigned int *) src)++;
381 outl (l >> 8 | l2 << 24, port);
382 l = l2;
383 }
384 l2 = *(unsigned char *) src;
385 outl (l >> 8 | l2 << 24, port);
386 break;
387 case 0x03:
388 --count;
389
390 l = *(unsigned char *) src << 24;
391 ((unsigned char *) src)++;
392 while (count--)
393 {
394 l2 = *(unsigned int *) src;
395 ((unsigned int *) src)++;
396 outl (l >> 24 | l2 << 8, port);
397 l = l2;
398 }
399 l2 = *(unsigned short *) src;
400 ((unsigned short *) src)++;
401 l2 |= *(unsigned char *) src << 16;
402 outl (l >> 24 | l2 << 8, port);
403 break;
404 }
405}
406
407
408
409
410
411
412void _memcpy_fromio(void * to, unsigned long from, long count)
413{
414
415
416
417 if (count >= 8 && ((long)to & 7) == (from & 7)) {
418 count -= 8;
419 do {
420 *(u64 *)to = __raw_readq(from);
421 count -= 8;
422 to += 8;
423 from += 8;
424 } while (count >= 0);
425 count += 8;
426 }
427
428 if (count >= 4 && ((long)to & 3) == (from & 3)) {
429 count -= 4;
430 do {
431 *(u32 *)to = __raw_readl(from);
432 count -= 4;
433 to += 4;
434 from += 4;
435 } while (count >= 0);
436 count += 4;
437 }
438
439 if (count >= 2 && ((long)to & 1) == (from & 1)) {
440 count -= 2;
441 do {
442 *(u16 *)to = __raw_readw(from);
443 count -= 2;
444 to += 2;
445 from += 2;
446 } while (count >= 0);
447 count += 2;
448 }
449
450 while (count > 0) {
451 *(u8 *) to = __raw_readb(from);
452 count--;
453 to++;
454 from++;
455 }
456}
457
458
459
460
461
462void _memcpy_toio(unsigned long to, const void * from, long count)
463{
464
465
466
467
468 if (count >= 8 && (to & 7) == ((long)from & 7)) {
469 count -= 8;
470 do {
471 __raw_writeq(*(const u64 *)from, to);
472 count -= 8;
473 to += 8;
474 from += 8;
475 } while (count >= 0);
476 count += 8;
477 }
478
479 if (count >= 4 && (to & 3) == ((long)from & 3)) {
480 count -= 4;
481 do {
482 __raw_writel(*(const u32 *)from, to);
483 count -= 4;
484 to += 4;
485 from += 4;
486 } while (count >= 0);
487 count += 4;
488 }
489
490 if (count >= 2 && (to & 1) == ((long)from & 1)) {
491 count -= 2;
492 do {
493 __raw_writew(*(const u16 *)from, to);
494 count -= 2;
495 to += 2;
496 from += 2;
497 } while (count >= 0);
498 count += 2;
499 }
500
501 while (count > 0) {
502 __raw_writeb(*(const u8 *) from, to);
503 count--;
504 to++;
505 from++;
506 }
507 mb();
508}
509
510
511
512
513void _memset_c_io(unsigned long to, unsigned long c, long count)
514{
515
516 if (count > 0 && (to & 1)) {
517 __raw_writeb(c, to);
518 to++;
519 count--;
520 }
521
522
523 if (count >= 2 && (to & 2)) {
524 __raw_writew(c, to);
525 to += 2;
526 count -= 2;
527 }
528
529
530 if (count >= 4 && (to & 4)) {
531 __raw_writel(c, to);
532 to += 4;
533 count -= 4;
534 }
535
536
537
538 count -= 8;
539 if (count >= 0) {
540 do {
541 __raw_writeq(c, to);
542 to += 8;
543 count -= 8;
544 } while (count >= 0);
545 }
546 count += 8;
547
548
549 if (count >= 4) {
550 __raw_writel(c, to);
551 to += 4;
552 count -= 4;
553 }
554
555
556 if (count >= 2) {
557 __raw_writew(c, to);
558 to += 2;
559 count -= 2;
560 }
561
562
563 if (count) {
564 __raw_writeb(c, to);
565 }
566 mb();
567}
568
569void
570scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
571{
572 if (! __is_ioaddr((unsigned long) s)) {
573
574 if (! __is_ioaddr((unsigned long) d))
575 memcpy(d, s, count);
576 else
577 memcpy_toio(d, s, count);
578 } else {
579
580 if (! __is_ioaddr((unsigned long) d))
581 memcpy_fromio(d, s, count);
582 else {
583
584
585 count /= 2;
586 while (count--) {
587 u16 tmp = __raw_readw((unsigned long)(s++));
588 __raw_writew(tmp, (unsigned long)(d++));
589 }
590 }
591 }
592}
593