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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id$
  2.  *
  3.  * This file is subject to the terms and conditions of the GNU General Public
  4.  * License.  See the file "COPYING" in the main directory of this archive
  5.  * for more details.
  6.  *
  7.  * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
  8.  * Copyright (C) 2000 by Colin Ngam
  9.  */
  10. #include <linux/types.h>
  11. #include <linux/slab.h>
  12. #include <asm/sn/sgi.h>
  13. #include <asm/sn/invent.h>
  14. #include <asm/sn/hcl.h>
  15. #include <asm/sn/labelcl.h>
  16. #include <asm/sn/xtalk/xbow.h>
  17. #include <asm/sn/pci/bridge.h>
  18. #include <asm/sn/klconfig.h>
  19. #include <asm/sn/sn1/hubdev.h>
  20. #include <asm/sn/module.h>
  21. #include <asm/sn/pci/pcibr.h>
  22. #include <asm/sn/xtalk/xswitch.h>
  23. #include <asm/sn/nodepda.h>
  24. #include <asm/sn/sn_cpuid.h>
  25. /* #define LDEBUG 1 */
  26. #ifdef LDEBUG
  27. #define DPRINTF printk
  28. #define printf printk
  29. #else
  30. #define DPRINTF(x...)
  31. #endif
  32. module_t        *modules[MODULE_MAX];
  33. int nummodules;
  34. #define SN00_SERIAL_FUDGE 0x3b1af409d513c2
  35. #define SN0_SERIAL_FUDGE 0x6e
  36. void
  37. encode_int_serial(uint64_t src,uint64_t *dest)
  38. {
  39.     uint64_t val;
  40.     int i;
  41.     val = src + SN00_SERIAL_FUDGE;
  42.     for (i = 0; i < sizeof(long long); i++) {
  43. ((char*)dest)[i] =
  44.     ((char*)&val)[sizeof(long long)/2 +
  45.  ((i%2) ? ((i/2 * -1) - 1) : (i/2))];
  46.     }
  47. }
  48. void
  49. decode_int_serial(uint64_t src, uint64_t *dest)
  50. {
  51.     uint64_t val;
  52.     int i;
  53.     for (i = 0; i < sizeof(long long); i++) {
  54. ((char*)&val)[sizeof(long long)/2 +
  55.      ((i%2) ? ((i/2 * -1) - 1) : (i/2))] =
  56.     ((char*)&src)[i];
  57.     }
  58.     *dest = val - SN00_SERIAL_FUDGE;
  59. }
  60. void
  61. encode_str_serial(const char *src, char *dest)
  62. {
  63.     int i;
  64.     for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) {
  65. dest[i] = src[MAX_SERIAL_NUM_SIZE/2 +
  66.      ((i%2) ? ((i/2 * -1) - 1) : (i/2))] +
  67.     SN0_SERIAL_FUDGE;
  68.     }
  69. }
  70. void
  71. decode_str_serial(const char *src, char *dest)
  72. {
  73.     int i;
  74.     for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) {
  75. dest[MAX_SERIAL_NUM_SIZE/2 +
  76.     ((i%2) ? ((i/2 * -1) - 1) : (i/2))] = src[i] -
  77.     SN0_SERIAL_FUDGE;
  78.     }
  79. }
  80. module_t *module_lookup(moduleid_t id)
  81. {
  82.     int i;
  83.     for (i = 0; i < nummodules; i++)
  84. if (modules[i]->id == id) {
  85.     DPRINTF("module_lookup: found m=0x%pn", modules[i]);
  86.     return modules[i];
  87. }
  88.     return NULL;
  89. }
  90. /*
  91.  * module_add_node
  92.  *
  93.  *   The first time a new module number is seen, a module structure is
  94.  *   inserted into the module list in order sorted by module number
  95.  *   and the structure is initialized.
  96.  *
  97.  *   The node number is added to the list of nodes in the module.
  98.  */
  99. module_t *module_add_node(moduleid_t id, cnodeid_t n)
  100. {
  101.     module_t        *m;
  102.     int i;
  103.     char buffer[16];
  104. #ifdef __ia64
  105.     memset(buffer, 0, 16);
  106.     format_module_id(buffer, id, MODULE_FORMAT_BRIEF);
  107.     DPRINTF("module_add_node: id=%s node=%dn", buffer, n);
  108. #endif
  109.     if ((m = module_lookup(id)) == 0) {
  110. #ifdef LATER
  111. m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n);
  112. #else
  113. m = kmalloc(sizeof (module_t), GFP_KERNEL);
  114. memset(m, 0 , sizeof(module_t));
  115. #endif
  116. ASSERT_ALWAYS(m);
  117. m->id = id;
  118. spin_lock_init(&m->lock);
  119. mutex_init_locked(&m->thdcnt);
  120. // set_elsc(&m->elsc);
  121. elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n));
  122. spin_lock_init(&m->elsclock);
  123. /* Insert in sorted order by module number */
  124. for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--)
  125.     modules[i] = modules[i - 1];
  126. modules[i] = m;
  127. nummodules++;
  128.     }
  129.     m->nodes[m->nodecnt++] = n;
  130.     DPRINTF("module_add_node: module %s now has %d nodesn", buffer, m->nodecnt);
  131.     return m;
  132. }
  133. int module_probe_snum(module_t *m, nasid_t nasid)
  134. {
  135.     lboard_t        *board;
  136.     klmod_serial_num_t *comp;
  137.     char * bcopy(const char * src, char * dest, int count);
  138.     board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
  139. KLTYPE_MIDPLANE8);
  140.     if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
  141. return 0;
  142.     comp = GET_SNUM_COMP(board);
  143.     if (comp) {
  144. #if LDEBUG
  145.     int i;
  146.     printf("********found module with id %x and string", m->id);
  147.     for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++)
  148. printf(" %x ", comp->snum.snum_str[i]);
  149.     printf("n"); /* Fudged string is not ASCII */
  150. #endif
  151.     if (comp->snum.snum_str[0] != '') {
  152. bcopy(comp->snum.snum_str,
  153.       m->snum.snum_str,
  154.       MAX_SERIAL_NUM_SIZE);
  155. m->snum_valid = 1;
  156.     }
  157.     }
  158.     if (m->snum_valid)
  159. return 1;
  160.     else {
  161. DPRINTF("Invalid serial number for module %d, "
  162. "possible missing or invalid NIC.", m->id);
  163. return 0;
  164.     }
  165. }
  166. void
  167. io_module_init(void)
  168. {
  169.     cnodeid_t node;
  170.     lboard_t        *board;
  171.     nasid_t nasid;
  172.     int nserial;
  173.     module_t        *m;
  174.     DPRINTF("*******module_initn");
  175.     nserial = 0;
  176.     for (node = 0; node < numnodes; node++) {
  177. nasid = COMPACT_TO_NASID_NODEID(node);
  178. board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
  179.     KLTYPE_IP27);
  180. ASSERT(board);
  181. m = module_add_node(board->brd_module, node);
  182. if (! m->snum_valid && module_probe_snum(m, nasid))
  183.     nserial++;
  184.     }
  185.     DPRINTF("********found total of %d serial numbers in the systemn",
  186.     nserial);
  187.     if (nserial == 0)
  188. PRINT_WARNING("io_module_init: No serial number found.n");
  189. }
  190. elsc_t *get_elsc(void)
  191. {
  192. return &NODEPDA(cpuid_to_cnodeid(smp_processor_id()))->module->elsc;
  193. }
  194. int
  195. get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info)
  196. {
  197.     int i;
  198.     if (cmod < 0 || cmod >= nummodules)
  199. return EINVAL;
  200.     if (! modules[cmod]->snum_valid)
  201. return ENXIO;
  202.     mod_info->mod_num = modules[cmod]->id;
  203.     {
  204. char temp[MAX_SERIAL_NUM_SIZE];
  205. decode_str_serial(modules[cmod]->snum.snum_str, temp);
  206. /* if this is an invalid serial number return an error */
  207. if (temp[0] != 'K')
  208.     return ENXIO;
  209. mod_info->serial_num = 0;
  210. for (i = 0; i < MAX_SERIAL_NUM_SIZE && temp[i] != ''; i++) {
  211.     mod_info->serial_num <<= 4;
  212.     mod_info->serial_num |= (temp[i] & 0xf);
  213.     mod_info->serial_str[i] = temp[i];
  214. }
  215. mod_info->serial_str[i] = '';
  216.     }
  217.     return 0;
  218. }