2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
9 #include <linux/types.h>
10 #include <linux/slab.h>
11 #include <asm/errno.h>
12 #include <asm/sn/sgi.h>
13 #include <asm/sn/driver.h>
14 #include <asm/sn/hcl.h>
15 #include <asm/sn/labelcl.h>
16 #include <asm/sn/xtalk/xtalk.h>
17 #include <asm/sn/xtalk/xswitch.h>
18 #include <asm/sn/xtalk/xwidget.h>
19 #include <asm/sn/xtalk/xtalk_private.h>
23 * This file provides generic support for Crosstalk
24 * Switches, in a way that insulates crosstalk providers
25 * from specifics about the switch chips being used.
28 #include <asm/sn/xtalk/xbow.h>
30 #define XSWITCH_CENSUS_BIT(port) (1<<(port))
31 #define XSWITCH_CENSUS_PORT_MAX (0xF)
32 #define XSWITCH_CENSUS_PORTS (0x10)
33 #define XSWITCH_WIDGET_PRESENT(infop,port) ((infop)->census & XSWITCH_CENSUS_BIT(port))
35 static char xswitch_info_fingerprint[] = "xswitch_info";
37 struct xswitch_info_s {
40 vertex_hdl_t vhdl[XSWITCH_CENSUS_PORTS];
41 vertex_hdl_t master_vhdl[XSWITCH_CENSUS_PORTS];
42 xswitch_provider_t *xswitch_fns;
46 xswitch_info_get(vertex_hdl_t xwidget)
48 xswitch_info_t xswitch_info;
50 xswitch_info = (xswitch_info_t)
51 hwgraph_fastinfo_get(xwidget);
53 return (xswitch_info);
57 xswitch_info_vhdl_set(xswitch_info_t xswitch_info,
61 if (port > XSWITCH_CENSUS_PORT_MAX)
64 xswitch_info->vhdl[(int)port] = xwidget;
68 xswitch_info_vhdl_get(xswitch_info_t xswitch_info,
71 if (port > XSWITCH_CENSUS_PORT_MAX)
72 return GRAPH_VERTEX_NONE;
74 return xswitch_info->vhdl[(int)port];
78 * Some systems may allow for multiple switch masters. On such systems,
79 * we assign a master for each port on the switch. These interfaces
80 * establish and retrieve that assignment.
83 xswitch_info_master_assignment_set(xswitch_info_t xswitch_info,
85 vertex_hdl_t master_vhdl)
87 if (port > XSWITCH_CENSUS_PORT_MAX)
90 xswitch_info->master_vhdl[(int)port] = master_vhdl;
94 xswitch_info_master_assignment_get(xswitch_info_t xswitch_info,
97 if (port > XSWITCH_CENSUS_PORT_MAX)
98 return GRAPH_VERTEX_NONE;
100 return xswitch_info->master_vhdl[(int)port];
104 xswitch_info_set(vertex_hdl_t xwidget, xswitch_info_t xswitch_info)
106 xswitch_info->fingerprint = xswitch_info_fingerprint;
107 hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) xswitch_info);
111 xswitch_info_new(vertex_hdl_t xwidget)
113 xswitch_info_t xswitch_info;
115 xswitch_info = xswitch_info_get(xwidget);
116 if (xswitch_info == NULL) {
119 xswitch_info = kmalloc(sizeof(*xswitch_info), GFP_KERNEL);
121 printk(KERN_WARNING "xswitch_info_new(): Unable to "
122 "allocate memory\n");
125 xswitch_info->census = 0;
126 for (port = 0; port <= XSWITCH_CENSUS_PORT_MAX; port++) {
127 xswitch_info_vhdl_set(xswitch_info, port,
130 xswitch_info_master_assignment_set(xswitch_info,
134 xswitch_info_set(xwidget, xswitch_info);
140 xswitch_provider_register(vertex_hdl_t busv,
141 xswitch_provider_t * xswitch_fns)
143 xswitch_info_t xswitch_info = xswitch_info_get(busv);
145 ASSERT(xswitch_info);
146 xswitch_info->xswitch_fns = xswitch_fns;
150 xswitch_info_link_is_ok(xswitch_info_t xswitch_info, xwidgetnum_t port)
152 xswitch_info->census |= XSWITCH_CENSUS_BIT(port);
156 xswitch_info_link_ok(xswitch_info_t xswitch_info, xwidgetnum_t port)
158 if (port > XSWITCH_CENSUS_PORT_MAX)
161 return (xswitch_info->census & XSWITCH_CENSUS_BIT(port));
165 xswitch_reset_link(vertex_hdl_t xconn_vhdl)
167 return xbow_reset_link(xconn_vhdl);