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.
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.
22 #include <linux/types.h>
23 #include <linux/slab.h>
24 #include <linux/interrupt.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>
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) ***********/
53 * moduleid_t geo_module(geoid_t g)
57 * Return the moduleid component of a geoid.
61 * Return INVALID_MODULE for an invalid geoid. Otherwise extract the
62 * moduleid from the structure, and return it.
72 if (g
.any
.type
== GEO_TYPE_INVALID
)
73 return INVALID_MODULE
;
82 * slabid_t geo_slab(geoid_t g)
86 * Return the slabid component of a geoid.
90 * Return INVALID_SLAB for an invalid geoid. Otherwise extract the
91 * slabid from the structure, and return it.
101 if (g
.any
.type
== GEO_TYPE_INVALID
)
111 * geo_type_t geo_type(geoid_t g)
115 * Return the type component of a geoid.
119 * Extract the type from the structure, and return it.
136 * int geo_valid(geoid_t g)
140 * Return nonzero if g has a valid geoid type.
144 * Test the type against GEO_TYPE_INVALID, and return the result.
154 return g
.any
.type
!= GEO_TYPE_INVALID
;
161 * int geo_cmp(geoid_t g0, geoid_t g1)
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.
171 * First compare the module, then the slab, type, and type-specific fields.
179 geo_cmp(geoid_t g0
, geoid_t g1
)
183 /* Compare the common fields */
184 rv
= MODULE_CMP(geo_module(g0
), geo_module(g1
));
188 rv
= geo_slab(g0
) - geo_slab(g1
);
192 /* Within a slab, sort by type */
193 rv
= geo_type(g0
) - geo_type(g1
);
197 switch(geo_type(g0
)) {
199 rv
= g0
.cpu
.slice
- g1
.cpu
.slice
;
202 case GEO_TYPE_IOCARD
:
203 rv
= g0
.pcicard
.bus
- g1
.pcicard
.bus
;
205 rv
= SLOTNUM_GETSLOT(g0
.pcicard
.slot
) -
206 SLOTNUM_GETSLOT(g1
.pcicard
.slot
);
210 rv
= g0
.mem
.membus
- g1
.mem
.membus
;
212 rv
= g0
.mem
.memslot
- g1
.mem
.memslot
;
226 * geoid_t geo_new(geo_type_t type, ...)
230 * Generate a new geoid_t value of the given type from its components.
231 * Expected calling sequences:
234 * \@code\{geo_new(GEO_TYPE_INVALID)\}
236 * \@code\{geo_new(GEO_TYPE_MODULE, moduleid_t m)\}
238 * \@code\{geo_new(GEO_TYPE_NODE, moduleid_t m, slabid_t s)\}
240 * \@code\{geo_new(GEO_TYPE_RTR, moduleid_t m, slabid_t s)\}
242 * \@code\{geo_new(GEO_TYPE_IOCNTL, moduleid_t m, slabid_t s)\}
244 * \@code\{geo_new(GEO_TYPE_IOCARD, moduleid_t m, slabid_t s, char bus, slotid_t slot)\}
246 * \@code\{geo_new(GEO_TYPE_CPU, moduleid_t m, slabid_t s, char slice)\}
248 * \@code\{geo_new(GEO_TYPE_MEM, moduleid_t m, slabid_t s, char membus, char slot)\}
251 * Invalid types return a GEO_TYPE_INVALID geoid_t.
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".
266 geo_new(geo_type_t type
, ...)
270 memset(&g
, 0, sizeof(g
));
274 /* Make sure the type is sane */
275 if (type
>= GEO_TYPE_MAX
)
276 type
= GEO_TYPE_INVALID
;
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
)
286 g
.any
.slab
= (slabid_t
)va_arg(al
, int);
288 /* Some types have additional components */
291 g
.cpu
.slice
= (char)va_arg(al
, int);
294 case GEO_TYPE_IOCARD
:
295 g
.pcicard
.bus
= (char)va_arg(al
, int);
296 g
.pcicard
.slot
= (slotid_t
)va_arg(al
, int);
300 g
.mem
.membus
= (char)va_arg(al
, int);
301 g
.mem
.memslot
= (char)va_arg(al
, int);