initial commit with v2.6.9
[linux-2.6.9-moxart.git] / arch / ia64 / sn / io / sn2 / geo_op.c
blobda46a15f896d341c4261fc3e0ca357413cc1de4b
1 /*
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
4 * for more details.
6 * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
7 */
9 /*
10 * @doc file m:hwcfg
11 * DESCRIPTION:
13 * This file contains routines for manipulating and generating
14 * Geographic IDs. They are in a file by themself since they have
15 * no dependencies on other modules.
17 * ORIGIN:
19 * New for SN2
22 #include <linux/types.h>
23 #include <linux/slab.h>
24 #include <linux/interrupt.h>
25 #include <asm/smp.h>
26 #include <asm/irq.h>
27 #include <asm/hw_irq.h>
28 #include <asm/sn/types.h>
29 #include <asm/sn/sgi.h>
30 #include <asm/sn/hcl.h>
31 #include <asm/sn/labelcl.h>
32 #include <asm/sn/io.h>
33 #include <asm/sn/sn_private.h>
34 #include <asm/sn/klconfig.h>
35 #include <asm/sn/sn_cpuid.h>
36 #include <asm/sn/pci/pciio.h>
37 #include <asm/sn/pci/pcibr.h>
38 #include <asm/sn/xtalk/xtalk.h>
39 #include <asm/sn/pci/pcibr_private.h>
40 #include <asm/sn/intr.h>
41 #include <asm/sn/sn2/shub_mmr_t.h>
42 #include <asm/sn/sn2/shubio.h>
43 #include <asm/sal.h>
44 #include <asm/sn/sn_sal.h>
45 #include <asm/sn/module.h>
46 #include <asm/sn/geo.h>
48 /********** Global functions and data (visible outside the module) ***********/
51 * @doc gf:geo_module
53 * moduleid_t geo_module(geoid_t g)
55 * DESCRIPTION:
57 * Return the moduleid component of a geoid.
59 * INTERNALS:
61 * Return INVALID_MODULE for an invalid geoid. Otherwise extract the
62 * moduleid from the structure, and return it.
64 * ORIGIN:
66 * New for SN2
69 moduleid_t
70 geo_module(geoid_t g)
72 if (g.any.type == GEO_TYPE_INVALID)
73 return INVALID_MODULE;
74 else
75 return g.any.module;
80 * @doc gf:geo_slab
82 * slabid_t geo_slab(geoid_t g)
84 * DESCRIPTION:
86 * Return the slabid component of a geoid.
88 * INTERNALS:
90 * Return INVALID_SLAB for an invalid geoid. Otherwise extract the
91 * slabid from the structure, and return it.
93 * ORIGIN:
95 * New for SN2
98 slabid_t
99 geo_slab(geoid_t g)
101 if (g.any.type == GEO_TYPE_INVALID)
102 return INVALID_SLAB;
103 else
104 return g.any.slab;
109 * @doc gf:geo_type
111 * geo_type_t geo_type(geoid_t g)
113 * DESCRIPTION:
115 * Return the type component of a geoid.
117 * INTERNALS:
119 * Extract the type from the structure, and return it.
121 * ORIGIN:
123 * New for SN2
126 geo_type_t
127 geo_type(geoid_t g)
129 return g.any.type;
134 * @doc gf:geo_valid
136 * int geo_valid(geoid_t g)
138 * DESCRIPTION:
140 * Return nonzero if g has a valid geoid type.
142 * INTERNALS:
144 * Test the type against GEO_TYPE_INVALID, and return the result.
146 * ORIGIN:
148 * New for SN2
152 geo_valid(geoid_t g)
154 return g.any.type != GEO_TYPE_INVALID;
159 * @doc gf:geo_cmp
161 * int geo_cmp(geoid_t g0, geoid_t g1)
163 * DESCRIPTION:
165 * Compare two geoid_t values, from the coarsest field to the finest.
166 * The comparison should be consistent with the physical locations of
167 * of the hardware named by the geoids.
169 * INTERNALS:
171 * First compare the module, then the slab, type, and type-specific fields.
173 * ORIGIN:
175 * New for SN2
179 geo_cmp(geoid_t g0, geoid_t g1)
181 int rv;
183 /* Compare the common fields */
184 rv = MODULE_CMP(geo_module(g0), geo_module(g1));
185 if (rv != 0)
186 return rv;
188 rv = geo_slab(g0) - geo_slab(g1);
189 if (rv != 0)
190 return rv;
192 /* Within a slab, sort by type */
193 rv = geo_type(g0) - geo_type(g1);
194 if (rv != 0)
195 return rv;
197 switch(geo_type(g0)) {
198 case GEO_TYPE_CPU:
199 rv = g0.cpu.slice - g1.cpu.slice;
200 break;
202 case GEO_TYPE_IOCARD:
203 rv = g0.pcicard.bus - g1.pcicard.bus;
204 if (rv) break;
205 rv = SLOTNUM_GETSLOT(g0.pcicard.slot) -
206 SLOTNUM_GETSLOT(g1.pcicard.slot);
207 break;
209 case GEO_TYPE_MEM:
210 rv = g0.mem.membus - g1.mem.membus;
211 if (rv) break;
212 rv = g0.mem.memslot - g1.mem.memslot;
213 break;
215 default:
216 rv = 0;
219 return rv;
224 * @doc gf:geo_new
226 * geoid_t geo_new(geo_type_t type, ...)
228 * DESCRIPTION:
230 * Generate a new geoid_t value of the given type from its components.
231 * Expected calling sequences:
232 * \@itemize \@bullet
233 * \@item
234 * \@code\{geo_new(GEO_TYPE_INVALID)\}
235 * \@item
236 * \@code\{geo_new(GEO_TYPE_MODULE, moduleid_t m)\}
237 * \@item
238 * \@code\{geo_new(GEO_TYPE_NODE, moduleid_t m, slabid_t s)\}
239 * \@item
240 * \@code\{geo_new(GEO_TYPE_RTR, moduleid_t m, slabid_t s)\}
241 * \@item
242 * \@code\{geo_new(GEO_TYPE_IOCNTL, moduleid_t m, slabid_t s)\}
243 * \@item
244 * \@code\{geo_new(GEO_TYPE_IOCARD, moduleid_t m, slabid_t s, char bus, slotid_t slot)\}
245 * \@item
246 * \@code\{geo_new(GEO_TYPE_CPU, moduleid_t m, slabid_t s, char slice)\}
247 * \@item
248 * \@code\{geo_new(GEO_TYPE_MEM, moduleid_t m, slabid_t s, char membus, char slot)\}
249 * \@end itemize
251 * Invalid types return a GEO_TYPE_INVALID geoid_t.
253 * INTERNALS:
255 * Use the type to determine which fields to expect. Write the fields into
256 * a new geoid_t and return it. Note: scalars smaller than an "int" are
257 * promoted to "int" by the "..." operator, so we need extra casts on "char",
258 * "slotid_t", and "slabid_t".
260 * ORIGIN:
262 * New for SN2
265 geoid_t
266 geo_new(geo_type_t type, ...)
268 va_list al;
269 geoid_t g;
270 memset(&g, 0, sizeof(g));
272 va_start(al, type);
274 /* Make sure the type is sane */
275 if (type >= GEO_TYPE_MAX)
276 type = GEO_TYPE_INVALID;
278 g.any.type = type;
279 if (type == GEO_TYPE_INVALID)
280 goto done; /* invalid geoids have no components at all */
282 g.any.module = va_arg(al, moduleid_t);
283 if (type == GEO_TYPE_MODULE)
284 goto done;
286 g.any.slab = (slabid_t)va_arg(al, int);
288 /* Some types have additional components */
289 switch(type) {
290 case GEO_TYPE_CPU:
291 g.cpu.slice = (char)va_arg(al, int);
292 break;
294 case GEO_TYPE_IOCARD:
295 g.pcicard.bus = (char)va_arg(al, int);
296 g.pcicard.slot = (slotid_t)va_arg(al, int);
297 break;
299 case GEO_TYPE_MEM:
300 g.mem.membus = (char)va_arg(al, int);
301 g.mem.memslot = (char)va_arg(al, int);
302 break;
304 default:
305 break;
308 done:
309 va_end(al);
310 return g;