aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
authorAlex Chiang <achiang@hp.com>2009-03-31 11:24:02 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-06-11 15:04:14 -0400
commitb019ee679afde950f2d01b1af0530453aa60af3f (patch)
treed6f2cea2323cbd0b8b403ab59eec9f527a0ab026 /drivers/pci/hotplug
parent1d2e8b1c58ef96b8834b139caf4357effedcb5ab (diff)
PCI Hotplug: cpqphp: clean up accesses to pcibios_get_irq_routing_table()
Instead of making multiple calls to pcibios_get_irq_routing_table, let's just do it once and save the answer. The reason we were making multiple calls is because we liked to calculate its length and perform some loop over it. Instead of open-coding the length calculation every time, provide it in an inline helper function. Finally, since pci_print_IRQ_route() is used only for debug, let's only do it when cpqhp_debug is set. Signed-off-by: Alex Chiang <achiang@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/hotplug')
-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