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

嵌入式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/kernel.h>
  12. #include <linux/devfs_fs.h>
  13. #include <linux/devfs_fs_kernel.h>
  14. #include <asm/sn/sgi.h>
  15. #include <asm/io.h>
  16. #include <asm/sn/iograph.h>
  17. #include <asm/sn/invent.h>
  18. #include <asm/sn/hcl.h>
  19. #include <asm/sn/labelcl.h>
  20. #include <asm/sn/hcl_util.h>
  21. #include <asm/sn/nodepda.h>
  22. static devfs_handle_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE;
  23. extern devfs_handle_t hwgraph_root;
  24. /*
  25. ** Return the "master" for a given vertex.  A master vertex is a
  26. ** controller or adapter or other piece of hardware that the given
  27. ** vertex passes through on the way to the rest of the system.
  28. */
  29. devfs_handle_t
  30. device_master_get(devfs_handle_t vhdl)
  31. {
  32. graph_error_t rc;
  33. devfs_handle_t master;
  34. rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master);
  35. if (rc == GRAPH_SUCCESS)
  36. return(master);
  37. else
  38. return(GRAPH_VERTEX_NONE);
  39. }
  40. /*
  41. ** Set the master for a given vertex.
  42. ** Returns 0 on success, non-0 indicates failure
  43. */
  44. int
  45. device_master_set(devfs_handle_t vhdl, devfs_handle_t master)
  46. {
  47. graph_error_t rc;
  48. rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER);
  49. return(rc != GRAPH_SUCCESS);
  50. }
  51. /*
  52. ** Return the compact node id of the node that ultimately "owns" the specified
  53. ** vertex.  In order to do this, we walk back through masters and connect points
  54. ** until we reach a vertex that represents a node.
  55. */
  56. cnodeid_t
  57. master_node_get(devfs_handle_t vhdl)
  58. {
  59. cnodeid_t cnodeid;
  60. devfs_handle_t master;
  61. for (;;) {
  62. cnodeid = nodevertex_to_cnodeid(vhdl);
  63. if (cnodeid != CNODEID_NONE)
  64. return(cnodeid);
  65. master = device_master_get(vhdl);
  66. /* Check for exceptional cases */
  67. if (master == vhdl) {
  68. /* Since we got a reference to the "master" thru
  69.  * device_master_get() we should decrement
  70.  * its reference count by 1
  71.  */
  72. return(CNODEID_NONE);
  73. }
  74. if (master == GRAPH_VERTEX_NONE) {
  75. master = hwgraph_connectpt_get(vhdl);
  76. if ((master == GRAPH_VERTEX_NONE) ||
  77.     (master == vhdl)) {
  78. return(CNODEID_NONE);
  79. }
  80. }
  81. vhdl = master;
  82. }
  83. }
  84. /*
  85. ** If the specified device represents a node, return its
  86. ** compact node ID; otherwise, return CNODEID_NONE.
  87. */
  88. cnodeid_t
  89. nodevertex_to_cnodeid(devfs_handle_t vhdl)
  90. {
  91. int rv = 0;
  92. arbitrary_info_t cnodeid = CNODEID_NONE;
  93. rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid);
  94. return((cnodeid_t)cnodeid);
  95. }
  96. void
  97. mark_nodevertex_as_node(devfs_handle_t vhdl, cnodeid_t cnodeid)
  98. {
  99. if (cnodeid == CNODEID_NONE)
  100. return;
  101. cnodeid_to_vertex(cnodeid) = vhdl;
  102. labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, 
  103. (arbitrary_info_t)cnodeid);
  104. {
  105. char cnodeid_buffer[10];
  106. if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) {
  107. (void)hwgraph_path_add( hwgraph_root,
  108. EDGE_LBL_NODENUM,
  109. &hwgraph_all_cnodes);
  110. }
  111. sprintf(cnodeid_buffer, "%d", cnodeid);
  112. (void)hwgraph_edge_add( hwgraph_all_cnodes,
  113. vhdl,
  114. cnodeid_buffer);
  115. }
  116. }
  117. /*
  118. ** If the specified device represents a CPU, return its cpuid;
  119. ** otherwise, return CPU_NONE.
  120. */
  121. cpuid_t
  122. cpuvertex_to_cpuid(devfs_handle_t vhdl)
  123. {
  124. arbitrary_info_t cpuid = CPU_NONE;
  125. (void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid);
  126. return((cpuid_t)cpuid);
  127. }
  128. /*
  129. ** dev_to_name converts a devfs_handle_t into a canonical name.  If the devfs_handle_t
  130. ** represents a vertex in the hardware graph, it is converted in the
  131. ** normal way for vertices.  If the devfs_handle_t is an old devfs_handle_t (one which
  132. ** does not represent a hwgraph vertex), we synthesize a name based
  133. ** on major/minor number.
  134. **
  135. ** Usually returns a pointer to the original buffer, filled in as
  136. ** appropriate.  If the buffer is too small to hold the entire name,
  137. ** or if anything goes wrong while determining the name, dev_to_name
  138. ** returns "UnknownDevice".
  139. */
  140. char *
  141. dev_to_name(devfs_handle_t dev, char *buf, uint buflen)
  142. {
  143.         return(vertex_to_name(dev, buf, buflen));
  144. }