PeeCeeI.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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