aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Goodwin <markgw@sgi.com>2005-04-25 16:04:22 -0400
committerTony Luck <tony.luck@intel.com>2005-04-25 16:04:22 -0400
commit4a5c13c7eb0d55bfd2cf3100c55f1e3d8df37576 (patch)
tree400e51f79f9ba6d34c66401e1760a51e792d14aa
parent30325d17715302a60c9afdaacaafaeb056b7e880 (diff)
[IA64-SGI] Altix SN topology support for new chipsets and pci topology
please accept this patch to the Altix SN platform topology export interface to support new chipsets and to export PCI topology. This follows on top of Jack Steiner's patch dated March 1st ("New chipset support for SN platform"). Signed-off-by: Mark Goodwin <markgw@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c133
-rw-r--r--include/asm-ia64/sn/sn_sal.h11
2 files changed, 135 insertions, 9 deletions
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index 197356460ee1..3bff99130d5e 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -28,6 +28,7 @@
28#include <linux/vmalloc.h> 28#include <linux/vmalloc.h>
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/miscdevice.h> 30#include <linux/miscdevice.h>
31#include <linux/utsname.h>
31#include <linux/cpumask.h> 32#include <linux/cpumask.h>
32#include <linux/smp_lock.h> 33#include <linux/smp_lock.h>
33#include <linux/nodemask.h> 34#include <linux/nodemask.h>
@@ -43,6 +44,7 @@
43#include <asm/sn/module.h> 44#include <asm/sn/module.h>
44#include <asm/sn/geo.h> 45#include <asm/sn/geo.h>
45#include <asm/sn/sn2/sn_hwperf.h> 46#include <asm/sn/sn2/sn_hwperf.h>
47#include <asm/sn/addrs.h>
46 48
47static void *sn_hwperf_salheap = NULL; 49static void *sn_hwperf_salheap = NULL;
48static int sn_hwperf_obj_cnt = 0; 50static int sn_hwperf_obj_cnt = 0;
@@ -81,26 +83,45 @@ out:
81 return e; 83 return e;
82} 84}
83 85
86static int sn_hwperf_location_to_bpos(char *location,
87 int *rack, int *bay, int *slot, int *slab)
88{
89 char type;
90
91 /* first scan for an old style geoid string */
92 if (sscanf(location, "%03d%c%02d#%d",
93 rack, &type, bay, slab) == 4)
94 *slot = 0;
95 else /* scan for a new bladed geoid string */
96 if (sscanf(location, "%03d%c%02d^%02d#%d",
97 rack, &type, bay, slot, slab) != 5)
98 return -1;
99 /* success */
100 return 0;
101}
102
84static int sn_hwperf_geoid_to_cnode(char *location) 103static int sn_hwperf_geoid_to_cnode(char *location)
85{ 104{
86 int cnode; 105 int cnode;
87 geoid_t geoid; 106 geoid_t geoid;
88 moduleid_t module_id; 107 moduleid_t module_id;
89 char type; 108 int rack, bay, slot, slab;
90 int rack, slot, slab; 109 int this_rack, this_bay, this_slot, this_slab;
91 int this_rack, this_slot, this_slab;
92 110
93 if (sscanf(location, "%03d%c%02d#%d", &rack, &type, &slot, &slab) != 4) 111 if (sn_hwperf_location_to_bpos(location, &rack, &bay, &slot, &slab))
94 return -1; 112 return -1;
95 113
96 for (cnode = 0; cnode < numionodes; cnode++) { 114 for (cnode = 0; cnode < numionodes; cnode++) {
97 geoid = cnodeid_get_geoid(cnode); 115 geoid = cnodeid_get_geoid(cnode);
98 module_id = geo_module(geoid); 116 module_id = geo_module(geoid);
99 this_rack = MODULE_GET_RACK(module_id); 117 this_rack = MODULE_GET_RACK(module_id);
100 this_slot = MODULE_GET_BPOS(module_id); 118 this_bay = MODULE_GET_BPOS(module_id);
119 this_slot = 0; /* XXX */
101 this_slab = geo_slab(geoid); 120 this_slab = geo_slab(geoid);
102 if (rack == this_rack && slot == this_slot && slab == this_slab) 121 if (rack == this_rack && bay == this_bay &&
122 slot == this_slot && slab == this_slab) {
103 break; 123 break;
124 }
104 } 125 }
105 126
106 return cnode < numionodes ? cnode : -1; 127 return cnode < numionodes ? cnode : -1;
@@ -153,11 +174,29 @@ static const char *sn_hwperf_get_slabname(struct sn_hwperf_object_info *obj,
153 return slabname; 174 return slabname;
154} 175}
155 176
177static void print_pci_topology(struct seq_file *s,
178 struct sn_hwperf_object_info *obj, int *ordinal,
179 char *pci_topo_buf, int len)
180{
181 char *p1;
182 char *p2;
183
184 for (p1=pci_topo_buf; *p1 && p1 < pci_topo_buf + len;) {
185 if (!(p2 = strchr(p1, '\n')))
186 break;
187 *p2 = '\0';
188 seq_printf(s, "pcibus %d %s-%s\n",
189 *ordinal, obj->location, p1);
190 (*ordinal)++;
191 p1 = p2 + 1;
192 }
193}
194
156static int sn_topology_show(struct seq_file *s, void *d) 195static int sn_topology_show(struct seq_file *s, void *d)
157{ 196{
158 int sz; 197 int sz;
159 int pt; 198 int pt;
160 int e; 199 int e = 0;
161 int i; 200 int i;
162 int j; 201 int j;
163 const char *slabname; 202 const char *slabname;
@@ -169,11 +208,46 @@ static int sn_topology_show(struct seq_file *s, void *d)
169 struct sn_hwperf_object_info *p; 208 struct sn_hwperf_object_info *p;
170 struct sn_hwperf_object_info *obj = d; /* this object */ 209 struct sn_hwperf_object_info *obj = d; /* this object */
171 struct sn_hwperf_object_info *objs = s->private; /* all objects */ 210 struct sn_hwperf_object_info *objs = s->private; /* all objects */
211 int rack, bay, slot, slab;
212 u8 shubtype;
213 u8 system_size;
214 u8 sharing_size;
215 u8 partid;
216 u8 coher;
217 u8 nasid_shift;
218 u8 region_size;
219 u16 nasid_mask;
220 int nasid_msb;
221 char *pci_topo_buf;
222 int pci_bus_ordinal = 0;
223 static int pci_topo_buf_len = 256;
172 224
173 if (obj == objs) { 225 if (obj == objs) {
174 seq_printf(s, "# sn_topology version 1\n"); 226 seq_printf(s, "# sn_topology version 2\n");
175 seq_printf(s, "# objtype ordinal location partition" 227 seq_printf(s, "# objtype ordinal location partition"
176 " [attribute value [, ...]]\n"); 228 " [attribute value [, ...]]\n");
229
230 if (ia64_sn_get_sn_info(0,
231 &shubtype, &nasid_mask, &nasid_shift, &system_size,
232 &sharing_size, &partid, &coher, &region_size))
233 BUG();
234 for (nasid_msb=63; nasid_msb > 0; nasid_msb--) {
235 if (((u64)nasid_mask << nasid_shift) & (1ULL << nasid_msb))
236 break;
237 }
238 seq_printf(s, "partition %u %s local "
239 "shubtype %s, "
240 "nasid_mask 0x%016lx, "
241 "nasid_bits %d:%d, "
242 "system_size %d, "
243 "sharing_size %d, "
244 "coherency_domain %d, "
245 "region_size %d\n",
246
247 partid, system_utsname.nodename,
248 shubtype ? "shub2" : "shub1",
249 (u64)nasid_mask << nasid_shift, nasid_msb, nasid_shift,
250 system_size, sharing_size, coher, region_size);
177 } 251 }
178 252
179 if (SN_HWPERF_FOREIGN(obj)) { 253 if (SN_HWPERF_FOREIGN(obj)) {
@@ -181,7 +255,7 @@ static int sn_topology_show(struct seq_file *s, void *d)
181 return 0; 255 return 0;
182 } 256 }
183 257
184 for (i = 0; obj->name[i]; i++) { 258 for (i = 0; i < SN_HWPERF_MAXSTRING && obj->name[i]; i++) {
185 if (obj->name[i] == ' ') 259 if (obj->name[i] == ' ')
186 obj->name[i] = '_'; 260 obj->name[i] = '_';
187 } 261 }
@@ -221,6 +295,43 @@ static int sn_topology_show(struct seq_file *s, void *d)
221 seq_putc(s, '\n'); 295 seq_putc(s, '\n');
222 } 296 }
223 } 297 }
298
299 /*
300 * PCI busses attached to this node, if any
301 */
302 do {
303 if (!(pci_topo_buf = vmalloc(pci_topo_buf_len))) {
304 printk("sn_topology_show: kmalloc failed\n");
305 break;
306 }
307
308 if (sn_hwperf_location_to_bpos(obj->location,
309 &rack, &bay, &slot, &slab) != 0)
310 continue;
311
312 e = ia64_sn_ioif_get_pci_topology(rack, bay, slot, slab,
313 pci_topo_buf, pci_topo_buf_len);
314
315 switch (e) {
316 case SALRET_NOT_IMPLEMENTED:
317 case SALRET_INVALID_ARG:
318 /* ignore, don't print anything */
319 e = SN_HWPERF_OP_OK;
320 break;
321
322 case SALRET_ERROR:
323 /* retry with a bigger buffer */
324 pci_topo_buf_len += 256;
325 break;
326
327 case SN_HWPERF_OP_OK:
328 /* export pci bus info */
329 print_pci_topology(s, obj, &pci_bus_ordinal,
330 pci_topo_buf, pci_topo_buf_len);
331 break;
332 }
333 vfree(pci_topo_buf);
334 } while (e != SN_HWPERF_OP_OK && pci_topo_buf_len < 0x200000);
224 } 335 }
225 336
226 if (obj->ports) { 337 if (obj->ports) {
@@ -397,6 +508,9 @@ static int sn_hwperf_map_err(int hwperf_err)
397 break; 508 break;
398 509
399 case SN_HWPERF_OP_BUSY: 510 case SN_HWPERF_OP_BUSY:
511 e = -EBUSY;
512 break;
513
400 case SN_HWPERF_OP_RECONFIGURE: 514 case SN_HWPERF_OP_RECONFIGURE:
401 e = -EAGAIN; 515 e = -EAGAIN;
402 break; 516 break;
@@ -549,6 +663,7 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg)
549 r = sn_hwperf_op_cpu(&op_info); 663 r = sn_hwperf_op_cpu(&op_info);
550 if (r) { 664 if (r) {
551 r = sn_hwperf_map_err(r); 665 r = sn_hwperf_map_err(r);
666 a.v0 = v0;
552 goto error; 667 goto error;
553 } 668 }
554 break; 669 break;
diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
index 81a1cf1e4f5a..410d356b40da 100644
--- a/include/asm-ia64/sn/sn_sal.h
+++ b/include/asm-ia64/sn/sn_sal.h
@@ -74,6 +74,7 @@
74#define SN_SAL_IOIF_GET_PCIBUS_INFO 0x02000056 74#define SN_SAL_IOIF_GET_PCIBUS_INFO 0x02000056
75#define SN_SAL_IOIF_GET_PCIDEV_INFO 0x02000057 75#define SN_SAL_IOIF_GET_PCIDEV_INFO 0x02000057
76#define SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST 0x02000058 76#define SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST 0x02000058
77#define SN_SAL_IOIF_GET_PCI_TOPOLOGY 0x02000059
77 78
78#define SN_SAL_HUB_ERROR_INTERRUPT 0x02000060 79#define SN_SAL_HUB_ERROR_INTERRUPT 0x02000060
79 80
@@ -1012,4 +1013,14 @@ ia64_sn_hwperf_op(nasid_t nasid, u64 opcode, u64 a0, u64 a1, u64 a2,
1012 return (int) rv.status; 1013 return (int) rv.status;
1013} 1014}
1014 1015
1016static inline int
1017ia64_sn_ioif_get_pci_topology(u64 rack, u64 bay, u64 slot, u64 slab,
1018 char *buf, u64 len)
1019{
1020 struct ia64_sal_retval rv;
1021 SAL_CALL_NOLOCK(rv, SN_SAL_IOIF_GET_PCI_TOPOLOGY,
1022 rack, bay, slot, slab, buf, len, 0);
1023 return (int) rv.status;
1024}
1025
1015#endif /* _ASM_IA64_SN_SN_SAL_H */ 1026#endif /* _ASM_IA64_SN_SN_SAL_H */