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
7 * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
10 #include <linux/types.h>
11 #include <linux/slab.h>
12 #include <asm/sn/sgi.h>
13 #include <asm/sn/driver.h>
14 #include <asm/sn/iograph.h>
15 #include <asm/sn/invent.h>
16 #include <asm/sn/hcl.h>
17 #include <asm/sn/labelcl.h>
18 #include <asm/sn/xtalk/xtalk.h>
19 #include <asm/sn/xtalk/xswitch.h>
20 #include <asm/sn/xtalk/xwidget.h>
21 #include <asm/sn/xtalk/xtalk_private.h>
23 #define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
24 #define DEL(ptr) (kfree(ptr))
27 * This file provides generic support for Crosstalk
28 * Switches, in a way that insulates crosstalk providers
29 * from specifics about the switch chips being used.
32 #include <asm/sn/xtalk/xbow.h>
33 #define DEV_FUNC(dev,func) xbow_##func
35 #if !defined(DEV_FUNC)
37 * There is more than one possible provider
38 * for this platform. We need to examine the
39 * master vertex of the current vertex for
40 * a provider function structure, and indirect
41 * through the appropriately named member.
43 #define DEV_FUNC(dev,func) xwidget_to_provider_fns(dev)->func
45 static xswitch_provider_t *
46 xwidget_to_provider_fns(vertex_hdl_t xconn)
49 xswitch_info_t xswitch_info;
50 xswitch_provider_t provider_fns;
52 busv = hwgraph_connectpt_get(xconn_vhdl);
53 ASSERT(busv != GRAPH_VERTEX_NONE);
55 xswitch_info = xswitch_info_get(busv);
56 ASSERT(xswitch_info != NULL);
58 provider_fns = xswitch_info->xswitch_fns;
59 ASSERT(provider_fns != NULL);
65 #define XSWITCH_CENSUS_BIT(port) (1<<(port))
66 #define XSWITCH_CENSUS_PORT_MIN (0x0)
67 #define XSWITCH_CENSUS_PORT_MAX (0xF)
68 #define XSWITCH_CENSUS_PORTS (0x10)
69 #define XSWITCH_WIDGET_PRESENT(infop,port) ((infop)->census & XSWITCH_CENSUS_BIT(port))
71 static char xswitch_info_fingerprint[] = "xswitch_info";
73 struct xswitch_info_s {
76 vertex_hdl_t vhdl[XSWITCH_CENSUS_PORTS];
77 vertex_hdl_t master_vhdl[XSWITCH_CENSUS_PORTS];
78 xswitch_provider_t *xswitch_fns;
82 xswitch_info_get(vertex_hdl_t xwidget)
84 xswitch_info_t xswitch_info;
86 xswitch_info = (xswitch_info_t)
87 hwgraph_fastinfo_get(xwidget);
89 return (xswitch_info);
93 xswitch_info_vhdl_set(xswitch_info_t xswitch_info,
97 #if XSWITCH_CENSUS_PORT_MIN
98 if (port < XSWITCH_CENSUS_PORT_MIN)
101 if (port > XSWITCH_CENSUS_PORT_MAX)
104 xswitch_info->vhdl[port - XSWITCH_CENSUS_PORT_MIN] = xwidget;
108 xswitch_info_vhdl_get(xswitch_info_t xswitch_info,
111 #if XSWITCH_CENSUS_PORT_MIN
112 if (port < XSWITCH_CENSUS_PORT_MIN)
113 return GRAPH_VERTEX_NONE;
115 if (port > XSWITCH_CENSUS_PORT_MAX)
116 return GRAPH_VERTEX_NONE;
118 return xswitch_info->vhdl[port - XSWITCH_CENSUS_PORT_MIN];
122 * Some systems may allow for multiple switch masters. On such systems,
123 * we assign a master for each port on the switch. These interfaces
124 * establish and retrieve that assignment.
127 xswitch_info_master_assignment_set(xswitch_info_t xswitch_info,
129 vertex_hdl_t master_vhdl)
131 #if XSWITCH_CENSUS_PORT_MIN
132 if (port < XSWITCH_CENSUS_PORT_MIN)
135 if (port > XSWITCH_CENSUS_PORT_MAX)
138 xswitch_info->master_vhdl[port - XSWITCH_CENSUS_PORT_MIN] = master_vhdl;
142 xswitch_info_master_assignment_get(xswitch_info_t xswitch_info,
145 #if XSWITCH_CENSUS_PORT_MIN
146 if (port < XSWITCH_CENSUS_PORT_MIN)
147 return GRAPH_VERTEX_NONE;
149 if (port > XSWITCH_CENSUS_PORT_MAX)
150 return GRAPH_VERTEX_NONE;
152 return xswitch_info->master_vhdl[port - XSWITCH_CENSUS_PORT_MIN];
156 xswitch_info_set(vertex_hdl_t xwidget, xswitch_info_t xswitch_info)
158 xswitch_info->fingerprint = xswitch_info_fingerprint;
159 hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) xswitch_info);
163 xswitch_info_new(vertex_hdl_t xwidget)
165 xswitch_info_t xswitch_info;
167 xswitch_info = xswitch_info_get(xwidget);
168 if (xswitch_info == NULL) {
172 xswitch_info->census = 0;
173 for (port = XSWITCH_CENSUS_PORT_MIN;
174 port <= XSWITCH_CENSUS_PORT_MAX;
176 xswitch_info_vhdl_set(xswitch_info, port,
179 xswitch_info_master_assignment_set(xswitch_info,
183 xswitch_info_set(xwidget, xswitch_info);
189 xswitch_provider_register(vertex_hdl_t busv,
190 xswitch_provider_t * xswitch_fns)
192 xswitch_info_t xswitch_info = xswitch_info_get(busv);
194 ASSERT(xswitch_info);
195 xswitch_info->xswitch_fns = xswitch_fns;
199 xswitch_info_link_is_ok(xswitch_info_t xswitch_info, xwidgetnum_t port)
201 xswitch_info->census |= XSWITCH_CENSUS_BIT(port);
205 xswitch_info_link_ok(xswitch_info_t xswitch_info, xwidgetnum_t port)
207 #if XSWITCH_CENSUS_PORT_MIN
208 if (port < XSWITCH_CENSUS_PORT_MIN)
212 if (port > XSWITCH_CENSUS_PORT_MAX)
215 return (xswitch_info->census & XSWITCH_CENSUS_BIT(port));
219 xswitch_reset_link(vertex_hdl_t xconn_vhdl)
221 return DEV_FUNC(xconn_vhdl, reset_link)