PeeCeeI.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * PeeCeeI.c: The emerging standard...
  3. *
  4. * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
  5. */
  6. #include <asm/io.h>
  7. #include <asm/byteorder.h>
  8. void outsb(unsigned long __addr, const void *src, unsigned long count)
  9. {
  10. void __iomem *addr = (void __iomem *) __addr;
  11. const u8 *p = src;
  12. while (count--)
  13. outb(*p++, addr);
  14. }
  15. void outsw(unsigned long __addr, const void *src, unsigned long count)
  16. {
  17. void __iomem *addr = (void __iomem *) __addr;
  18. while (count--) {
  19. __raw_writew(*(u16 *)src, addr);
  20. src += sizeof(u16);
  21. }
  22. }
  23. void outsl(unsigned long __addr, const void *src, unsigned long count)
  24. {
  25. void __iomem *addr = (void __iomem *) __addr;
  26. u32 l, l2;
  27. if (!count)
  28. return;
  29. switch (((unsigned long)src) & 0x3) {
  30. case 0x0:
  31. /* src is naturally aligned */
  32. while (count--) {
  33. __raw_writel(*(u32 *)src, addr);
  34. src += sizeof(u32);
  35. }
  36. break;
  37. case 0x2:
  38. /* 2-byte alignment */
  39. while (count--) {
  40. l = (*(u16 *)src) << 16;
  41. l |= *(u16 *)(src + sizeof(u16));
  42. __raw_writel(l, addr);
  43. src += sizeof(u32);
  44. }
  45. break;
  46. case 0x1:
  47. /* Hold three bytes in l each time, grab a byte from l2 */
  48. l = (*(u8 *)src) << 24;
  49. l |= (*(u16 *)(src + sizeof(u8))) << 8;
  50. src += sizeof(u8) + sizeof(u16);
  51. while (count--) {
  52. l2 = *(u32 *)src;
  53. l |= (l2 >> 24);
  54. __raw_writel(l, addr);
  55. l = l2 << 8;
  56. src += sizeof(u32);
  57. }
  58. break;
  59. case 0x3:
  60. /* Hold a byte in l each time, grab 3 bytes from l2 */
  61. l = (*(u8 *)src) << 24;
  62. src += sizeof(u8);
  63. while (count--) {
  64. l2 = *(u32 *)src;
  65. l |= (l2 >> 8);
  66. __raw_writel(l, addr);
  67. l = l2 << 24;
  68. src += sizeof(u32);
  69. }
  70. break;
  71. }
  72. }
  73. void insb(unsigned long __addr, void *dst, unsigned long count)
  74. {
  75. void __iomem *addr = (void __iomem *) __addr;
  76. if (count) {
  77. u32 *pi;
  78. u8 *pb = dst;
  79. while ((((unsigned long)pb) & 0x3) && count--)
  80. *pb++ = inb(addr);
  81. pi = (u32 *)pb;
  82. while (count >= 4) {
  83. u32 w;
  84. w = (inb(addr) << 24);
  85. w |= (inb(addr) << 16);
  86. w |= (inb(addr) << 8);
  87. w |= (inb(addr) << 0);
  88. *pi++ = w;
  89. count -= 4;
  90. }
  91. pb = (u8 *)pi;
  92. while (count--)
  93. *pb++ = inb(addr);
  94. }
  95. }
  96. void insw(unsigned long __addr, void *dst, unsigned long count)
  97. {
  98. void __iomem *addr = (void __iomem *) __addr;
  99. if (count) {
  100. u16 *ps = dst;
  101. u32 *pi;
  102. if (((unsigned long)ps) & 0x2) {
  103. *ps++ = le16_to_cpu(inw(addr));
  104. count--;
  105. }
  106. pi = (u32 *)ps;
  107. while (count >= 2) {
  108. u32 w;
  109. w = (le16_to_cpu(inw(addr)) << 16);
  110. w |= (le16_to_cpu(inw(addr)) << 0);
  111. *pi++ = w;
  112. count -= 2;
  113. }
  114. ps = (u16 *)pi;
  115. if (count)
  116. *ps = le16_to_cpu(inw(addr));
  117. }
  118. }
  119. void insl(unsigned long __addr, void *dst, unsigned long count)
  120. {
  121. void __iomem *addr = (void __iomem *) __addr;
  122. if (count) {
  123. if ((((unsigned long)dst) & 0x3) == 0) {
  124. u32 *pi = dst;
  125. while (count--)
  126. *pi++ = le32_to_cpu(inl(addr));
  127. } else {
  128. u32 l = 0, l2, *pi;
  129. u16 *ps;
  130. u8 *pb;
  131. switch (((unsigned long)dst) & 3) {
  132. case 0x2:
  133. ps = dst;
  134. count -= 1;
  135. l = le32_to_cpu(inl(addr));
  136. *ps++ = l;
  137. pi = (u32 *)ps;
  138. while (count--) {
  139. l2 = le32_to_cpu(inl(addr));
  140. *pi++ = (l << 16) | (l2 >> 16);
  141. l = l2;
  142. }
  143. ps = (u16 *)pi;
  144. *ps = l;
  145. break;
  146. case 0x1:
  147. pb = dst;
  148. count -= 1;
  149. l = le32_to_cpu(inl(addr));
  150. *pb++ = l >> 24;
  151. ps = (u16 *)pb;
  152. *ps++ = ((l >> 8) & 0xffff);
  153. pi = (u32 *)ps;
  154. while (count--) {
  155. l2 = le32_to_cpu(inl(addr));
  156. *pi++ = (l << 24) | (l2 >> 8);
  157. l = l2;
  158. }
  159. pb = (u8 *)pi;
  160. *pb = l;
  161. break;
  162. case 0x3:
  163. pb = (u8 *)dst;
  164. count -= 1;
  165. l = le32_to_cpu(inl(addr));
  166. *pb++ = l >> 24;
  167. pi = (u32 *)pb;
  168. while (count--) {
  169. l2 = le32_to_cpu(inl(addr));
  170. *pi++ = (l << 8) | (l2 >> 24);
  171. l = l2;
  172. }
  173. ps = (u16 *)pi;
  174. *ps++ = ((l >> 8) & 0xffff);
  175. pb = (u8 *)ps;
  176. *pb = l;
  177. break;
  178. }
  179. }
  180. }
  181. }