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.
14 * This file contains routines for manipulating and generating
15 * Geographic IDs. They are in a file by themself since they have
16 * no dependencies on other modules.
23 #include <linux/types.h>
24 #include <linux/slab.h>
25 #include <linux/interrupt.h>
28 #include <asm/hw_irq.h>
29 #include <asm/sn/types.h>
30 #include <asm/sn/sgi.h>
31 #include <asm/sn/iograph.h>
32 #include <asm/sn/invent.h>
33 #include <asm/sn/hcl.h>
34 #include <asm/sn/labelcl.h>
35 #include <asm/sn/io.h>
36 #include <asm/sn/sn_private.h>
37 #include <asm/sn/klconfig.h>
38 #include <asm/sn/sn_cpuid.h>
39 #include <asm/sn/pci/pciio.h>
40 #include <asm/sn/pci/pcibr.h>
41 #include <asm/sn/xtalk/xtalk.h>
42 #include <asm/sn/pci/pcibr_private.h>
43 #include <asm/sn/intr.h>
44 #include <asm/sn/sn2/shub_mmr_t.h>
45 #include <asm/sn/sn2/shubio.h>
47 #include <asm/sn/sn_sal.h>
48 #include <asm/sn/module.h>
49 #include <asm/sn/geo.h>
51 /********** Global functions and data (visible outside the module) ***********/
56 * moduleid_t geo_module(geoid_t g)
60 * Return the moduleid component of a geoid.
64 * Return INVALID_MODULE for an invalid geoid. Otherwise extract the
65 * moduleid from the structure, and return it.
75 if (g.any.type == GEO_TYPE_INVALID)
76 return INVALID_MODULE;
85 * slabid_t geo_slab(geoid_t g)
89 * Return the slabid component of a geoid.
93 * Return INVALID_SLAB for an invalid geoid. Otherwise extract the
94 * slabid from the structure, and return it.
104 if (g.any.type == GEO_TYPE_INVALID)
114 * geo_type_t geo_type(geoid_t g)
118 * Return the type component of a geoid.
122 * Extract the type from the structure, and return it.
139 * int geo_valid(geoid_t g)
143 * Return nonzero if g has a valid geoid type.
147 * Test the type against GEO_TYPE_INVALID, and return the result.
157 return g.any.type != GEO_TYPE_INVALID;
164 * int geo_cmp(geoid_t g0, geoid_t g1)
168 * Compare two geoid_t values, from the coarsest field to the finest.
169 * The comparison should be consistent with the physical locations of
170 * of the hardware named by the geoids.
174 * First compare the module, then the slab, type, and type-specific fields.
182 geo_cmp(geoid_t g0, geoid_t g1)
186 /* Compare the common fields */
187 rv = MODULE_CMP(geo_module(g0), geo_module(g1));
191 rv = geo_slab(g0) - geo_slab(g1);
195 /* Within a slab, sort by type */
196 rv = geo_type(g0) - geo_type(g1);
200 switch(geo_type(g0)) {
202 rv = g0.cpu.slice - g1.cpu.slice;
205 case GEO_TYPE_IOCARD:
206 rv = g0.pcicard.bus - g1.pcicard.bus;
208 rv = SLOTNUM_GETSLOT(g0.pcicard.slot) -
209 SLOTNUM_GETSLOT(g1.pcicard.slot);
213 rv = g0.mem.membus - g1.mem.membus;
215 rv = g0.mem.memslot - g1.mem.memslot;
229 * geoid_t geo_new(geo_type_t type, ...)
233 * Generate a new geoid_t value of the given type from its components.
234 * Expected calling sequences:
237 * \@code\{geo_new(GEO_TYPE_INVALID)\}
239 * \@code\{geo_new(GEO_TYPE_MODULE, moduleid_t m)\}
241 * \@code\{geo_new(GEO_TYPE_NODE, moduleid_t m, slabid_t s)\}
243 * \@code\{geo_new(GEO_TYPE_RTR, moduleid_t m, slabid_t s)\}
245 * \@code\{geo_new(GEO_TYPE_IOCNTL, moduleid_t m, slabid_t s)\}
247 * \@code\{geo_new(GEO_TYPE_IOCARD, moduleid_t m, slabid_t s, char bus, slotid_t slot)\}
249 * \@code\{geo_new(GEO_TYPE_CPU, moduleid_t m, slabid_t s, char slice)\}
251 * \@code\{geo_new(GEO_TYPE_MEM, moduleid_t m, slabid_t s, char membus, char slot)\}
254 * Invalid types return a GEO_TYPE_INVALID geoid_t.
258 * Use the type to determine which fields to expect. Write the fields into
259 * a new geoid_t and return it. Note: scalars smaller than an "int" are
260 * promoted to "int" by the "..." operator, so we need extra casts on "char",
261 * "slotid_t", and "slabid_t".
269 geo_new(geo_type_t type, ...)
273 memset(&g, 0, sizeof(g));
277 /* Make sure the type is sane */
278 if (type >= GEO_TYPE_MAX)
279 type = GEO_TYPE_INVALID;
282 if (type == GEO_TYPE_INVALID)
283 goto done; /* invalid geoids have no components at all */
285 g.any.module = va_arg(al, moduleid_t);
286 if (type == GEO_TYPE_MODULE)
289 g.any.slab = (slabid_t)va_arg(al, int);
291 /* Some types have additional components */
294 g.cpu.slice = (char)va_arg(al, int);
297 case GEO_TYPE_IOCARD:
298 g.pcicard.bus = (char)va_arg(al, int);
299 g.pcicard.slot = (slotid_t)va_arg(al, int);
303 g.mem.membus = (char)va_arg(al, int);
304 g.mem.memslot = (char)va_arg(al, int);