tc.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * tc-init: We assume the TURBOchannel to be up and running so
  3.  * just probe for Modules and fill in the global data structure
  4.  * tc_bus.
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file "COPYING" in the main directory of this archive
  8.  * for more details.
  9.  *
  10.  * Copyright (c) Harald Koerfgen, 1998
  11.  * Copyright (c) 2001  Maciej W. Rozycki
  12.  */
  13. #include <linux/string.h>
  14. #include <linux/init.h>
  15. #include <linux/ioport.h>
  16. #include <linux/kernel.h>
  17. #include <linux/module.h>
  18. #include <asm/addrspace.h>
  19. #include <asm/errno.h>
  20. #include <asm/dec/machtype.h>
  21. #include <asm/dec/tcinfo.h>
  22. #include <asm/dec/tcmodule.h>
  23. #include <asm/dec/interrupts.h>
  24. #include <asm/paccess.h>
  25. #include <asm/ptrace.h>
  26. #define TC_DEBUG
  27. MODULE_LICENSE("GPL");
  28. slot_info tc_bus[MAX_SLOT];
  29. static int max_tcslot;
  30. static tcinfo *info;
  31. unsigned long system_base;
  32. extern unsigned long *(*rex_slot_address)(int);
  33. extern void *(*rex_gettcinfo)(void);
  34. /*
  35.  * Interface to the world. Read comment in include/asm-mips/tc.h.
  36.  */
  37. int search_tc_card(const char *name)
  38. {
  39. int slot;
  40. slot_info *sip;
  41. for (slot = 0; slot <= max_tcslot; slot++) {
  42. sip = &tc_bus[slot];
  43. if ((sip->flags & FREE) && (strncmp(sip->name, name, strlen(name)) == 0)) {
  44. return slot;
  45. }
  46. }
  47. return -ENODEV;
  48. }
  49. void claim_tc_card(int slot)
  50. {
  51. if (tc_bus[slot].flags & IN_USE) {
  52. printk("claim_tc_card: attempting to claim a card already in usen");
  53. return;
  54. }
  55. tc_bus[slot].flags &= ~FREE;
  56. tc_bus[slot].flags |= IN_USE;
  57. }
  58. void release_tc_card(int slot)
  59. {
  60. if (tc_bus[slot].flags & FREE) {
  61. printk("release_tc_card: attempting to release a card already freen");
  62. return;
  63. }
  64. tc_bus[slot].flags &= ~IN_USE;
  65. tc_bus[slot].flags |= FREE;
  66. }
  67. unsigned long get_tc_base_addr(int slot)
  68. {
  69. return tc_bus[slot].base_addr;
  70. }
  71. unsigned long get_tc_irq_nr(int slot)
  72. {
  73. return tc_bus[slot].interrupt;
  74. }
  75. unsigned long get_tc_speed(void)
  76. {
  77. return 100000 * (10000 / (unsigned long)info->clk_period);
  78. }
  79. /*
  80.  * Probing for TURBOchannel modules
  81.  */
  82. static void __init tc_probe(unsigned long startaddr, unsigned long size, int max_slot)
  83. {
  84. int i, slot, err;
  85. long offset;
  86. unsigned char pattern[4];
  87. unsigned char *module;
  88. for (slot = 0; slot <= max_slot; slot++) {
  89. module = (char *)(startaddr + slot * size);
  90. offset = OLDCARD;
  91. err = 0;
  92. err |= get_dbe(pattern[0], module + OLDCARD + TC_PATTERN0);
  93. err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1);
  94. err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2);
  95. err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3);
  96. if (err)
  97. continue;
  98. if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
  99.     pattern[2] != 0xaa || pattern[3] != 0xff) {
  100. offset = NEWCARD;
  101. err = 0;
  102. err |= get_dbe(pattern[0], module + TC_PATTERN0);
  103. err |= get_dbe(pattern[1], module + TC_PATTERN1);
  104. err |= get_dbe(pattern[2], module + TC_PATTERN2);
  105. err |= get_dbe(pattern[3], module + TC_PATTERN3);
  106. if (err)
  107. continue;
  108. }
  109. if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
  110.     pattern[2] != 0xaa || pattern[3] != 0xff)
  111. continue;
  112. tc_bus[slot].base_addr = (unsigned long)module;
  113. for(i = 0; i < 8; i++) {
  114. tc_bus[slot].firmware[i] =
  115. module[TC_FIRM_VER + offset + 4 * i];
  116. tc_bus[slot].vendor[i] =
  117. module[TC_VENDOR + offset + 4 * i];
  118. tc_bus[slot].name[i] =
  119. module[TC_MODULE + offset + 4 * i];
  120. }
  121. tc_bus[slot].firmware[8] = 0;
  122. tc_bus[slot].vendor[8] = 0;
  123. tc_bus[slot].name[8] = 0;
  124. /*
  125.  * Looks unneccesary, but we may change
  126.  * TC? in the future
  127.  */
  128. switch (slot) {
  129. case 0:
  130. tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC0];
  131. break;
  132. case 1:
  133. tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC1];
  134. break;
  135. case 2:
  136. tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC2];
  137. break;
  138. /*
  139.  * Yuck! DS5000/200 onboard devices
  140.  */
  141. case 5:
  142. tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC5];
  143. break;
  144. case 6:
  145. tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC6];
  146. break;
  147. default:
  148. tc_bus[slot].interrupt = -1;
  149. break;
  150. }
  151. }
  152. }
  153. /*
  154.  * the main entry
  155.  */
  156. void __init tc_init(void)
  157. {
  158. int tc_clock;
  159. int i;
  160. unsigned long slot0addr;
  161. unsigned long slot_size;
  162. if (!TURBOCHANNEL)
  163. return;
  164. for (i = 0; i < MAX_SLOT; i++) {
  165. tc_bus[i].base_addr = 0;
  166. tc_bus[i].name[0] = 0;
  167. tc_bus[i].vendor[0] = 0;
  168. tc_bus[i].firmware[0] = 0;
  169. tc_bus[i].interrupt = -1;
  170. tc_bus[i].flags = FREE;
  171. }
  172. info = (tcinfo *) rex_gettcinfo();
  173. slot0addr = (unsigned long)KSEG1ADDR(rex_slot_address(0));
  174. switch (mips_machtype) {
  175. case MACH_DS5000_200:
  176. max_tcslot = 6;
  177. break;
  178. case MACH_DS5000_1XX:
  179. case MACH_DS5000_2X0:
  180. max_tcslot = 2;
  181. break;
  182. case MACH_DS5000_XX:
  183. default:
  184. max_tcslot = 1;
  185. break;
  186. }
  187. tc_clock = 10000 / info->clk_period;
  188. if (TURBOCHANNEL && info->slot_size && slot0addr) {
  189. printk("TURBOchannel rev. %1d at %2d.%1d MHz ", info->revision,
  190. tc_clock / 10, tc_clock % 10);
  191. printk("(with%s parity)n", info->parity ? "" : "out");
  192. slot_size = info->slot_size << 20;
  193. tc_probe(slot0addr, slot_size, max_tcslot);
  194.    /*
  195.     * All TURBOchannel DECstations have the onboard devices
  196.    * where the (max_tcslot + 1 or 2 on DS5k/xx) Option Module
  197.    * would be.
  198.    */
  199.   if(mips_machtype == MACH_DS5000_XX)
  200.   i = 2;
  201. else
  202.   i = 1;
  203.           system_base = slot0addr + slot_size * (max_tcslot + i);
  204. #ifdef TC_DEBUG
  205. for (i = 0; i <= max_tcslot; i++)
  206. if (tc_bus[i].base_addr) {
  207. printk("    slot %d: ", i);
  208. printk("%s %s %sn", tc_bus[i].vendor,
  209. tc_bus[i].name, tc_bus[i].firmware);
  210. }
  211. #endif
  212. ioport_resource.end = KSEG2 - 1;
  213. }
  214. }
  215. EXPORT_SYMBOL(search_tc_card);
  216. EXPORT_SYMBOL(claim_tc_card);
  217. EXPORT_SYMBOL(release_tc_card);
  218. EXPORT_SYMBOL(get_tc_base_addr);
  219. EXPORT_SYMBOL(get_tc_irq_nr);
  220. EXPORT_SYMBOL(get_tc_speed);
  221. EXPORT_SYMBOL(system_base);