commented early_printk patch because of rejects.
[linux-flexiantxendom0-3.2.10.git] / arch / ia64 / sn / io / xswitch.c
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-2003 Silicon Graphics, Inc. All rights reserved.
8  */
9
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>
22
23 #define NEW(ptr)        (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
24 #define DEL(ptr)        (kfree(ptr))
25
26 /*
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.
30  */
31
32 #include <asm/sn/xtalk/xbow.h>
33
34 #define XSWITCH_CENSUS_BIT(port)                (1<<(port))
35 #define XSWITCH_CENSUS_PORT_MAX                 (0xF)
36 #define XSWITCH_CENSUS_PORTS                    (0x10)
37 #define XSWITCH_WIDGET_PRESENT(infop,port)      ((infop)->census & XSWITCH_CENSUS_BIT(port))
38
39 static char             xswitch_info_fingerprint[] = "xswitch_info";
40
41 struct xswitch_info_s {
42     char                   *fingerprint;
43     unsigned                census;
44     vertex_hdl_t            vhdl[XSWITCH_CENSUS_PORTS];
45     vertex_hdl_t            master_vhdl[XSWITCH_CENSUS_PORTS];
46     xswitch_provider_t     *xswitch_fns;
47 };
48
49 xswitch_info_t
50 xswitch_info_get(vertex_hdl_t xwidget)
51 {
52     xswitch_info_t          xswitch_info;
53
54     xswitch_info = (xswitch_info_t)
55         hwgraph_fastinfo_get(xwidget);
56
57     return (xswitch_info);
58 }
59
60 void
61 xswitch_info_vhdl_set(xswitch_info_t xswitch_info,
62                       xwidgetnum_t port,
63                       vertex_hdl_t xwidget)
64 {
65     if (port > XSWITCH_CENSUS_PORT_MAX)
66         return;
67
68     xswitch_info->vhdl[port] = xwidget;
69 }
70
71 vertex_hdl_t
72 xswitch_info_vhdl_get(xswitch_info_t xswitch_info,
73                       xwidgetnum_t port)
74 {
75     if (port > XSWITCH_CENSUS_PORT_MAX)
76         return GRAPH_VERTEX_NONE;
77
78     return xswitch_info->vhdl[port];
79 }
80
81 /*
82  * Some systems may allow for multiple switch masters.  On such systems,
83  * we assign a master for each port on the switch.  These interfaces
84  * establish and retrieve that assignment.
85  */
86 void
87 xswitch_info_master_assignment_set(xswitch_info_t xswitch_info,
88                                    xwidgetnum_t port,
89                                    vertex_hdl_t master_vhdl)
90 {
91     if (port > XSWITCH_CENSUS_PORT_MAX)
92         return;
93
94     xswitch_info->master_vhdl[port] = master_vhdl;
95 }
96
97 vertex_hdl_t
98 xswitch_info_master_assignment_get(xswitch_info_t xswitch_info,
99                                    xwidgetnum_t port)
100 {
101     if (port > XSWITCH_CENSUS_PORT_MAX)
102         return GRAPH_VERTEX_NONE;
103
104     return xswitch_info->master_vhdl[port];
105 }
106
107 void
108 xswitch_info_set(vertex_hdl_t xwidget, xswitch_info_t xswitch_info)
109 {
110     xswitch_info->fingerprint = xswitch_info_fingerprint;
111     hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) xswitch_info);
112 }
113
114 xswitch_info_t
115 xswitch_info_new(vertex_hdl_t xwidget)
116 {
117     xswitch_info_t          xswitch_info;
118
119     xswitch_info = xswitch_info_get(xwidget);
120     if (xswitch_info == NULL) {
121         int                     port;
122
123         NEW(xswitch_info);
124         xswitch_info->census = 0;
125         for (port = 0; port <= XSWITCH_CENSUS_PORT_MAX; port++) {
126             xswitch_info_vhdl_set(xswitch_info, port,
127                                   GRAPH_VERTEX_NONE);
128
129             xswitch_info_master_assignment_set(xswitch_info,
130                                                port,
131                                                GRAPH_VERTEX_NONE);
132         }
133         xswitch_info_set(xwidget, xswitch_info);
134     }
135     return xswitch_info;
136 }
137
138 void
139 xswitch_provider_register(vertex_hdl_t busv,
140                           xswitch_provider_t * xswitch_fns)
141 {
142     xswitch_info_t          xswitch_info = xswitch_info_get(busv);
143
144     ASSERT(xswitch_info);
145     xswitch_info->xswitch_fns = xswitch_fns;
146 }
147
148 void
149 xswitch_info_link_is_ok(xswitch_info_t xswitch_info, xwidgetnum_t port)
150 {
151     xswitch_info->census |= XSWITCH_CENSUS_BIT(port);
152 }
153
154 int
155 xswitch_info_link_ok(xswitch_info_t xswitch_info, xwidgetnum_t port)
156 {
157     if (port > XSWITCH_CENSUS_PORT_MAX)
158         return 0;
159
160     return (xswitch_info->census & XSWITCH_CENSUS_BIT(port));
161 }
162
163 int
164 xswitch_reset_link(vertex_hdl_t xconn_vhdl)
165 {
166     return xbow_reset_link(xconn_vhdl);
167 }