diff options
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/sn/kernel/sn2/sn_hwperf.c | 71 |
1 files changed, 24 insertions, 47 deletions
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index e731fcb95f90..833e700fdac9 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c | |||
@@ -116,7 +116,7 @@ static int sn_hwperf_geoid_to_cnode(char *location) | |||
116 | module_id = geo_module(geoid); | 116 | module_id = geo_module(geoid); |
117 | this_rack = MODULE_GET_RACK(module_id); | 117 | this_rack = MODULE_GET_RACK(module_id); |
118 | this_bay = MODULE_GET_BPOS(module_id); | 118 | this_bay = MODULE_GET_BPOS(module_id); |
119 | this_slot = 0; /* XXX */ | 119 | this_slot = geo_slot(geoid); |
120 | this_slab = geo_slab(geoid); | 120 | this_slab = geo_slab(geoid); |
121 | if (rack == this_rack && bay == this_bay && | 121 | if (rack == this_rack && bay == this_bay && |
122 | slot == this_slot && slab == this_slab) { | 122 | slot == this_slot && slab == this_slab) { |
@@ -176,20 +176,27 @@ static const char *sn_hwperf_get_slabname(struct sn_hwperf_object_info *obj, | |||
176 | 176 | ||
177 | static void print_pci_topology(struct seq_file *s, | 177 | static void print_pci_topology(struct seq_file *s, |
178 | struct sn_hwperf_object_info *obj, int *ordinal, | 178 | struct sn_hwperf_object_info *obj, int *ordinal, |
179 | char *pci_topo_buf, int len) | 179 | u64 rack, u64 bay, u64 slot, u64 slab) |
180 | { | 180 | { |
181 | char *p1; | 181 | char *p1; |
182 | char *p2; | 182 | char *p2; |
183 | 183 | char *pg; | |
184 | for (p1=pci_topo_buf; *p1 && p1 < pci_topo_buf + len;) { | 184 | |
185 | if (!(p2 = strchr(p1, '\n'))) | 185 | if (!(pg = (char *)get_zeroed_page(GFP_KERNEL))) |
186 | break; | 186 | return; /* ignore */ |
187 | *p2 = '\0'; | 187 | if (ia64_sn_ioif_get_pci_topology(rack, bay, slot, slab, |
188 | seq_printf(s, "pcibus %d %s-%s\n", | 188 | __pa(pg), PAGE_SIZE) == SN_HWPERF_OP_OK) { |
189 | *ordinal, obj->location, p1); | 189 | for (p1=pg; *p1 && p1 < pg + PAGE_SIZE;) { |
190 | (*ordinal)++; | 190 | if (!(p2 = strchr(p1, '\n'))) |
191 | p1 = p2 + 1; | 191 | break; |
192 | *p2 = '\0'; | ||
193 | seq_printf(s, "pcibus %d %s-%s\n", | ||
194 | *ordinal, obj->location, p1); | ||
195 | (*ordinal)++; | ||
196 | p1 = p2 + 1; | ||
197 | } | ||
192 | } | 198 | } |
199 | free_page((unsigned long)pg); | ||
193 | } | 200 | } |
194 | 201 | ||
195 | static int sn_topology_show(struct seq_file *s, void *d) | 202 | static int sn_topology_show(struct seq_file *s, void *d) |
@@ -218,9 +225,7 @@ static int sn_topology_show(struct seq_file *s, void *d) | |||
218 | u8 region_size; | 225 | u8 region_size; |
219 | u16 nasid_mask; | 226 | u16 nasid_mask; |
220 | int nasid_msb; | 227 | int nasid_msb; |
221 | char *pci_topo_buf; | ||
222 | int pci_bus_ordinal = 0; | 228 | int pci_bus_ordinal = 0; |
223 | static int pci_topo_buf_len = 256; | ||
224 | 229 | ||
225 | if (obj == objs) { | 230 | if (obj == objs) { |
226 | seq_printf(s, "# sn_topology version 2\n"); | 231 | seq_printf(s, "# sn_topology version 2\n"); |
@@ -299,41 +304,13 @@ static int sn_topology_show(struct seq_file *s, void *d) | |||
299 | /* | 304 | /* |
300 | * PCI busses attached to this node, if any | 305 | * PCI busses attached to this node, if any |
301 | */ | 306 | */ |
302 | do { | 307 | if (sn_hwperf_location_to_bpos(obj->location, |
303 | if (sn_hwperf_location_to_bpos(obj->location, | 308 | &rack, &bay, &slot, &slab)) { |
304 | &rack, &bay, &slot, &slab)) { | 309 | /* export pci bus info */ |
305 | break; | 310 | print_pci_topology(s, obj, &pci_bus_ordinal, |
306 | } | 311 | rack, bay, slot, slab); |
307 | |||
308 | if (!(pci_topo_buf = vmalloc(pci_topo_buf_len))) { | ||
309 | printk("sn_topology_show: vmalloc failed\n"); | ||
310 | break; | ||
311 | } | ||
312 | 312 | ||
313 | e = ia64_sn_ioif_get_pci_topology(rack, bay, slot, slab, | 313 | } |
314 | pci_topo_buf, pci_topo_buf_len); | ||
315 | |||
316 | switch (e) { | ||
317 | case SALRET_NOT_IMPLEMENTED: | ||
318 | case SALRET_INVALID_ARG: | ||
319 | /* ignore, don't print anything */ | ||
320 | e = SN_HWPERF_OP_OK; | ||
321 | break; | ||
322 | |||
323 | case SALRET_ERROR: | ||
324 | /* retry with a bigger buffer */ | ||
325 | pci_topo_buf_len += 256; | ||
326 | break; | ||
327 | |||
328 | case SN_HWPERF_OP_OK: | ||
329 | default: | ||
330 | /* export pci bus info */ | ||
331 | print_pci_topology(s, obj, &pci_bus_ordinal, | ||
332 | pci_topo_buf, pci_topo_buf_len); | ||
333 | break; | ||
334 | } | ||
335 | vfree(pci_topo_buf); | ||
336 | } while (e != SN_HWPERF_OP_OK && pci_topo_buf_len < 0x200000); | ||
337 | } | 314 | } |
338 | 315 | ||
339 | if (obj->ports) { | 316 | if (obj->ports) { |