aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/cpqphp.h9
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c72
-rw-r--r--drivers/pci/hotplug/cpqphp_pci.c36
3 files changed, 47 insertions, 70 deletions
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h
index 308f82b1fc9a..1d5561c6bad4 100644
--- a/drivers/pci/hotplug/cpqphp.h
+++ b/drivers/pci/hotplug/cpqphp.h
@@ -455,6 +455,7 @@ extern int cpqhp_debug;
455extern int cpqhp_legacy_mode; 455extern int cpqhp_legacy_mode;
456extern struct controller *cpqhp_ctrl_list; 456extern struct controller *cpqhp_ctrl_list;
457extern struct pci_func *cpqhp_slot_list[256]; 457extern struct pci_func *cpqhp_slot_list[256];
458extern struct irq_routing_table *cpqhp_routing_table;
458 459
459/* these can be gotten rid of, but for debugging they are purty */ 460/* these can be gotten rid of, but for debugging they are purty */
460extern u8 cpqhp_nic_irq; 461extern u8 cpqhp_nic_irq;
@@ -733,4 +734,12 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
733 return retval; 734 return retval;
734} 735}
735 736
737#include <asm/pci_x86.h>
738static inline int cpqhp_routing_table_length(void)
739{
740 BUG_ON(cpqhp_routing_table == NULL);
741 return ((cpqhp_routing_table->size - sizeof(struct irq_routing_table)) /
742 sizeof(struct irq_info));
743}
744
736#endif 745#endif
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index 857e466df71d..7888b37c6c8e 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -44,7 +44,6 @@
44 44
45#include "cpqphp.h" 45#include "cpqphp.h"
46#include "cpqphp_nvram.h" 46#include "cpqphp_nvram.h"
47#include <asm/pci_x86.h>
48 47
49 48
50/* Global variables */ 49/* Global variables */
@@ -52,6 +51,7 @@ int cpqhp_debug;
52int cpqhp_legacy_mode; 51int cpqhp_legacy_mode;
53struct controller *cpqhp_ctrl_list; /* = NULL */ 52struct controller *cpqhp_ctrl_list; /* = NULL */
54struct pci_func *cpqhp_slot_list[256]; 53struct pci_func *cpqhp_slot_list[256];
54struct irq_routing_table *cpqhp_routing_table;
55 55
56/* local variables */ 56/* local variables */
57static void __iomem *smbios_table; 57static void __iomem *smbios_table;
@@ -154,40 +154,42 @@ static int init_SERR(struct controller * ctrl)
154 return 0; 154 return 0;
155} 155}
156 156
157/* nice debugging output */ 157static int init_cpqhp_routing_table(void)
158static int pci_print_IRQ_route (void)
159{ 158{
160 struct irq_routing_table *routing_table;
161 int len; 159 int len;
162 int loop;
163
164 u8 tbus, tdevice, tslot;
165 160
166 routing_table = pcibios_get_irq_routing_table(); 161 cpqhp_routing_table = pcibios_get_irq_routing_table();
167 if (routing_table == NULL) { 162 if (cpqhp_routing_table == NULL)
168 err("No BIOS Routing Table??? Not good\n");
169 return -ENOMEM; 163 return -ENOMEM;
170 }
171 164
172 len = (routing_table->size - sizeof(struct irq_routing_table)) / 165 len = cpqhp_routing_table_length();
173 sizeof(struct irq_info);
174 /* Make sure I got at least one entry */
175 if (len == 0) { 166 if (len == 0) {
176 kfree(routing_table); 167 kfree(cpqhp_routing_table);
168 cpqhp_routing_table = NULL;
177 return -1; 169 return -1;
178 } 170 }
179 171
180 dbg("bus dev func slot\n"); 172 return 0;
173}
174
175/* nice debugging output */
176static void pci_print_IRQ_route(void)
177{
178 int len;
179 int loop;
180 u8 tbus, tdevice, tslot;
181
182 len = cpqhp_routing_table_length();
181 183
184 dbg("bus dev func slot\n");
182 for (loop = 0; loop < len; ++loop) { 185 for (loop = 0; loop < len; ++loop) {
183 tbus = routing_table->slots[loop].bus; 186 tbus = cpqhp_routing_table->slots[loop].bus;
184 tdevice = routing_table->slots[loop].devfn; 187 tdevice = cpqhp_routing_table->slots[loop].devfn;
185 tslot = routing_table->slots[loop].slot; 188 tslot = cpqhp_routing_table->slots[loop].slot;
186 dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot); 189 dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot);
187 190
188 } 191 }
189 kfree(routing_table); 192 return;
190 return 0;
191} 193}
192 194
193 195
@@ -331,7 +333,6 @@ static int ctrl_slot_cleanup (struct controller * ctrl)
331static int 333static int
332get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot) 334get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
333{ 335{
334 struct irq_routing_table *PCIIRQRoutingInfoLength;
335 u32 work; 336 u32 work;
336 long len; 337 long len;
337 long loop; 338 long loop;
@@ -342,26 +343,14 @@ get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
342 343
343 bridgeSlot = 0xFF; 344 bridgeSlot = 0xFF;
344 345
345 PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table(); 346 len = cpqhp_routing_table_length();
346 if (!PCIIRQRoutingInfoLength)
347 return -1;
348
349 len = (PCIIRQRoutingInfoLength->size -
350 sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
351 /* Make sure I got at least one entry */
352 if (len == 0) {
353 kfree(PCIIRQRoutingInfoLength);
354 return -1;
355 }
356
357 for (loop = 0; loop < len; ++loop) { 347 for (loop = 0; loop < len; ++loop) {
358 tbus = PCIIRQRoutingInfoLength->slots[loop].bus; 348 tbus = cpqhp_routing_table->slots[loop].bus;
359 tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3; 349 tdevice = cpqhp_routing_table->slots[loop].devfn >> 3;
360 tslot = PCIIRQRoutingInfoLength->slots[loop].slot; 350 tslot = cpqhp_routing_table->slots[loop].slot;
361 351
362 if ((tbus == bus_num) && (tdevice == dev_num)) { 352 if ((tbus == bus_num) && (tdevice == dev_num)) {
363 *slot = tslot; 353 *slot = tslot;
364 kfree(PCIIRQRoutingInfoLength);
365 return 0; 354 return 0;
366 } else { 355 } else {
367 /* Did not get a match on the target PCI device. Check 356 /* Did not get a match on the target PCI device. Check
@@ -396,10 +385,8 @@ get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
396 */ 385 */
397 if (bridgeSlot != 0xFF) { 386 if (bridgeSlot != 0xFF) {
398 *slot = bridgeSlot; 387 *slot = bridgeSlot;
399 kfree(PCIIRQRoutingInfoLength);
400 return 0; 388 return 0;
401 } 389 }
402 kfree(PCIIRQRoutingInfoLength);
403 /* Couldn't find an entry in the routing table for this PCI device */ 390 /* Couldn't find an entry in the routing table for this PCI device */
404 return -1; 391 return -1;
405} 392}
@@ -782,10 +769,13 @@ static int one_time_init(void)
782 769
783 power_mode = 0; 770 power_mode = 0;
784 771
785 retval = pci_print_IRQ_route(); 772 retval = init_cpqhp_routing_table();
786 if (retval) 773 if (retval)
787 goto error; 774 goto error;
788 775
776 if (cpqhp_debug)
777 pci_print_IRQ_route();
778
789 dbg("Initialize + Start the notification mechanism \n"); 779 dbg("Initialize + Start the notification mechanism \n");
790 780
791 retval = cpqhp_event_start_thread(); 781 retval = cpqhp_event_start_thread();
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index 2909e3f6caa7..6201281b9dab 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -37,7 +37,6 @@
37#include "../pci.h" 37#include "../pci.h"
38#include "cpqphp.h" 38#include "cpqphp.h"
39#include "cpqphp_nvram.h" 39#include "cpqphp_nvram.h"
40#include <asm/pci_x86.h>
41 40
42 41
43u8 cpqhp_nic_irq; 42u8 cpqhp_nic_irq;
@@ -244,39 +243,23 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
244 243
245static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge) 244static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge)
246{ 245{
247 struct irq_routing_table *PCIIRQRoutingInfoLength; 246 int loop, len;
248 long len;
249 long loop;
250 u32 work; 247 u32 work;
251
252 u8 tbus, tdevice, tslot; 248 u8 tbus, tdevice, tslot;
253 249
254 PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table(); 250 len = cpqhp_routing_table_length();
255 if (!PCIIRQRoutingInfoLength)
256 return -1;
257
258 len = (PCIIRQRoutingInfoLength->size -
259 sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
260 /* Make sure I got at least one entry */
261 if (len == 0) {
262 kfree(PCIIRQRoutingInfoLength );
263 return -1;
264 }
265
266 for (loop = 0; loop < len; ++loop) { 251 for (loop = 0; loop < len; ++loop) {
267 tbus = PCIIRQRoutingInfoLength->slots[loop].bus; 252 tbus = cpqhp_routing_table->slots[loop].bus;
268 tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn; 253 tdevice = cpqhp_routing_table->slots[loop].devfn;
269 tslot = PCIIRQRoutingInfoLength->slots[loop].slot; 254 tslot = cpqhp_routing_table->slots[loop].slot;
270 255
271 if (tslot == slot) { 256 if (tslot == slot) {
272 *bus_num = tbus; 257 *bus_num = tbus;
273 *dev_num = tdevice; 258 *dev_num = tdevice;
274 ctrl->pci_bus->number = tbus; 259 ctrl->pci_bus->number = tbus;
275 pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work); 260 pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
276 if (!nobridge || (work == 0xffffffff)) { 261 if (!nobridge || (work == 0xffffffff))
277 kfree(PCIIRQRoutingInfoLength );
278 return 0; 262 return 0;
279 }
280 263
281 dbg("bus_num %d devfn %d\n", *bus_num, *dev_num); 264 dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
282 pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work); 265 pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
@@ -287,17 +270,12 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
287 dbg("Scan bus for Non Bridge: bus %d\n", tbus); 270 dbg("Scan bus for Non Bridge: bus %d\n", tbus);
288 if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) { 271 if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
289 *bus_num = tbus; 272 *bus_num = tbus;
290 kfree(PCIIRQRoutingInfoLength );
291 return 0; 273 return 0;
292 } 274 }
293 } else { 275 } else
294 kfree(PCIIRQRoutingInfoLength );
295 return 0; 276 return 0;
296 }
297
298 } 277 }
299 } 278 }
300 kfree(PCIIRQRoutingInfoLength );
301 return -1; 279 return -1;
302} 280}
303 281