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

Linux/Unix编程

开发平台:

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-2001 Silicon Graphics, Inc. All rights reserved.
  8.  */
  9. #include <linux/types.h>
  10. #include <linux/slab.h>
  11. #include <asm/sn/sgi.h>
  12. #include <asm/sn/driver.h>
  13. #include <asm/sn/iograph.h>
  14. #include <asm/sn/invent.h>
  15. #include <asm/sn/hcl.h>
  16. #include <asm/sn/labelcl.h>
  17. #include <asm/sn/xtalk/xtalk.h>
  18. #include <asm/sn/xtalk/xswitch.h>
  19. #include <asm/sn/xtalk/xwidget.h>
  20. #include <asm/sn/xtalk/xtalk_private.h>
  21. #define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
  22. #define DEL(ptr) (kfree(ptr))
  23. int                     xswitch_devflag = D_MP;
  24. /*
  25.  * This file provides generic support for Crosstalk
  26.  * Switches, in a way that insulates crosstalk providers
  27.  * from specifics about the switch chips being used.
  28.  */
  29. #include <asm/sn/xtalk/xbow.h>
  30. #define DEV_FUNC(dev,func)      xbow_##func
  31. #if !defined(DEV_FUNC)
  32. /*
  33.  * There is more than one possible provider
  34.  * for this platform. We need to examine the
  35.  * master vertex of the current vertex for
  36.  * a provider function structure, and indirect
  37.  * through the appropriately named member.
  38.  */
  39. #define DEV_FUNC(dev,func) xwidget_to_provider_fns(dev)->func
  40. static xswitch_provider_t *
  41. xwidget_to_provider_fns(devfs_handle_t xconn)
  42. {
  43.     devfs_handle_t            busv;
  44.     xswitch_info_t          xswitch_info;
  45.     xswitch_provider_t      provider_fns;
  46.     busv = hwgraph_connectpt_get(xconn_vhdl);
  47.     ASSERT(busv != GRAPH_VERTEX_NONE);
  48.     xswitch_info = xswitch_info_get(busv);
  49.     ASSERT(xswitch_info != NULL);
  50.     provider_fns = xswitch_info->xswitch_fns;
  51.     ASSERT(provider_fns != NULL);
  52.     return provider_fns;
  53. }
  54. #endif
  55. #define XSWITCH_CENSUS_BIT(port) (1<<(port))
  56. #define XSWITCH_CENSUS_PORT_MIN (0x0)
  57. #define XSWITCH_CENSUS_PORT_MAX (0xF)
  58. #define XSWITCH_CENSUS_PORTS (0x10)
  59. #define XSWITCH_WIDGET_PRESENT(infop,port) ((infop)->census & XSWITCH_CENSUS_BIT(port))
  60. static char             xswitch_info_fingerprint[] = "xswitch_info";
  61. struct xswitch_info_s {
  62.     char                   *fingerprint;
  63.     unsigned                census;
  64.     devfs_handle_t            vhdl[XSWITCH_CENSUS_PORTS];
  65.     devfs_handle_t            master_vhdl[XSWITCH_CENSUS_PORTS];
  66.     xswitch_provider_t     *xswitch_fns;
  67. };
  68. xswitch_info_t
  69. xswitch_info_get(devfs_handle_t xwidget)
  70. {
  71.     xswitch_info_t          xswitch_info;
  72.     xswitch_info = (xswitch_info_t)
  73. hwgraph_fastinfo_get(xwidget);
  74. #ifdef LATER
  75.     if ((xswitch_info != NULL) &&
  76. (xswitch_info->fingerprint != xswitch_info_fingerprint))
  77. #ifdef SUPPORT_PRINTING_V_FORMAT
  78. PRINT_PANIC("%v xswitch_info_get bad fingerprint", xwidget);
  79. #else
  80. PRINT_PANIC("%x xswitch_info_get bad fingerprint", xwidget);
  81. #endif
  82. #endif /* LATER */
  83.     return (xswitch_info);
  84. }
  85. void
  86. xswitch_info_vhdl_set(xswitch_info_t xswitch_info,
  87.       xwidgetnum_t port,
  88.       devfs_handle_t xwidget)
  89. {
  90. #if XSWITCH_CENSUS_PORT_MIN
  91.     if (port < XSWITCH_CENSUS_PORT_MIN)
  92. return;
  93. #endif
  94.     if (port > XSWITCH_CENSUS_PORT_MAX)
  95. return;
  96.     xswitch_info->vhdl[port - XSWITCH_CENSUS_PORT_MIN] = xwidget;
  97. }
  98. devfs_handle_t
  99. xswitch_info_vhdl_get(xswitch_info_t xswitch_info,
  100.       xwidgetnum_t port)
  101. {
  102. #ifdef LATER
  103.     if (xswitch_info == NULL)
  104. PRINT_PANIC("xswitch_info_vhdl_get: null xswitch_info");
  105. #endif
  106. #if XSWITCH_CENSUS_PORT_MIN
  107.     if (port < XSWITCH_CENSUS_PORT_MIN)
  108. return GRAPH_VERTEX_NONE;
  109. #endif
  110.     if (port > XSWITCH_CENSUS_PORT_MAX)
  111. return GRAPH_VERTEX_NONE;
  112.     return xswitch_info->vhdl[port - XSWITCH_CENSUS_PORT_MIN];
  113. }
  114. /*
  115.  * Some systems may allow for multiple switch masters.  On such systems,
  116.  * we assign a master for each port on the switch.  These interfaces
  117.  * establish and retrieve that assignment.
  118.  */
  119. void
  120. xswitch_info_master_assignment_set(xswitch_info_t xswitch_info,
  121.    xwidgetnum_t port,
  122.    devfs_handle_t master_vhdl)
  123. {
  124. #if XSWITCH_CENSUS_PORT_MIN
  125.     if (port < XSWITCH_CENSUS_PORT_MIN)
  126. return;
  127. #endif
  128.     if (port > XSWITCH_CENSUS_PORT_MAX)
  129. return;
  130.     xswitch_info->master_vhdl[port - XSWITCH_CENSUS_PORT_MIN] = master_vhdl;
  131. }
  132. devfs_handle_t
  133. xswitch_info_master_assignment_get(xswitch_info_t xswitch_info,
  134.    xwidgetnum_t port)
  135. {
  136. #if XSWITCH_CENSUS_PORT_MIN
  137.     if (port < XSWITCH_CENSUS_PORT_MIN)
  138. return GRAPH_VERTEX_NONE;
  139. #endif
  140.     if (port > XSWITCH_CENSUS_PORT_MAX)
  141. return GRAPH_VERTEX_NONE;
  142.     return xswitch_info->master_vhdl[port - XSWITCH_CENSUS_PORT_MIN];
  143. }
  144. void
  145. xswitch_info_set(devfs_handle_t xwidget, xswitch_info_t xswitch_info)
  146. {
  147.     xswitch_info->fingerprint = xswitch_info_fingerprint;
  148.     hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) xswitch_info);
  149. }
  150. xswitch_info_t
  151. xswitch_info_new(devfs_handle_t xwidget)
  152. {
  153.     xswitch_info_t          xswitch_info;
  154.     xswitch_info = xswitch_info_get(xwidget);
  155.     if (xswitch_info == NULL) {
  156. int                     port;
  157. NEW(xswitch_info);
  158. xswitch_info->census = 0;
  159. for (port = XSWITCH_CENSUS_PORT_MIN;
  160.      port <= XSWITCH_CENSUS_PORT_MAX;
  161.      port++) {
  162.     xswitch_info_vhdl_set(xswitch_info, port,
  163.   GRAPH_VERTEX_NONE);
  164.     xswitch_info_master_assignment_set(xswitch_info,
  165.        port,
  166.        GRAPH_VERTEX_NONE);
  167. }
  168. xswitch_info_set(xwidget, xswitch_info);
  169.     }
  170.     return xswitch_info;
  171. }
  172. void
  173. xswitch_provider_register(devfs_handle_t busv,
  174.   xswitch_provider_t * xswitch_fns)
  175. {
  176.     xswitch_info_t          xswitch_info = xswitch_info_get(busv);
  177.     ASSERT(xswitch_info);
  178.     xswitch_info->xswitch_fns = xswitch_fns;
  179. }
  180. void
  181. xswitch_info_link_is_ok(xswitch_info_t xswitch_info, xwidgetnum_t port)
  182. {
  183.     xswitch_info->census |= XSWITCH_CENSUS_BIT(port);
  184. }
  185. int
  186. xswitch_info_link_ok(xswitch_info_t xswitch_info, xwidgetnum_t port)
  187. {
  188. #if XSWITCH_CENSUS_PORT_MIN
  189.     if (port < XSWITCH_CENSUS_PORT_MIN)
  190. return 0;
  191. #endif
  192.     if (port > XSWITCH_CENSUS_PORT_MAX)
  193. return 0;
  194.     return (xswitch_info->census & XSWITCH_CENSUS_BIT(port));
  195. }
  196. int
  197. xswitch_reset_link(devfs_handle_t xconn_vhdl)
  198. {
  199.     return DEV_FUNC(xconn_vhdl, reset_link)
  200. (xconn_vhdl);
  201. }
  202. /* Given a vertex handle to the xswitch get its logical
  203.  * id.
  204.  */
  205. int
  206. xswitch_id_get(devfs_handle_t xconn_vhdl)
  207. {
  208.     arbitrary_info_t  xbow_num;
  209.     graph_error_t rv;
  210.     rv = hwgraph_info_get_LBL(xconn_vhdl,INFO_LBL_XSWITCH_ID,&xbow_num);
  211.     ASSERT(rv == GRAPH_SUCCESS);
  212.     return(xbow_num);
  213. }
  214. /* Given a vertex handle to the xswitch set its logical
  215.  * id.
  216.  */
  217. void
  218. xswitch_id_set(devfs_handle_t xconn_vhdl,int xbow_num)
  219. {
  220.     graph_error_t rv;
  221.     rv = hwgraph_info_add_LBL(xconn_vhdl,INFO_LBL_XSWITCH_ID,
  222.       (arbitrary_info_t)xbow_num);
  223.     ASSERT(rv == GRAPH_SUCCESS);
  224. }