diff options
author | Alex Chiang <achiang@hp.com> | 2009-03-31 11:24:02 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-06-11 15:04:14 -0400 |
commit | b019ee679afde950f2d01b1af0530453aa60af3f (patch) | |
tree | d6f2cea2323cbd0b8b403ab59eec9f527a0ab026 /drivers | |
parent | 1d2e8b1c58ef96b8834b139caf4357effedcb5ab (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')
-rw-r--r-- | drivers/pci/hotplug/cpqphp.h | 9 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_core.c | 72 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_pci.c | 36 |
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; | |||
455 | extern int cpqhp_legacy_mode; | 455 | extern int cpqhp_legacy_mode; |
456 | extern struct controller *cpqhp_ctrl_list; | 456 | extern struct controller *cpqhp_ctrl_list; |
457 | extern struct pci_func *cpqhp_slot_list[256]; | 457 | extern struct pci_func *cpqhp_slot_list[256]; |
458 | extern 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 */ |
460 | extern u8 cpqhp_nic_irq; | 461 | extern 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> | ||
738 | static 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; | |||
52 | int cpqhp_legacy_mode; | 51 | int cpqhp_legacy_mode; |
53 | struct controller *cpqhp_ctrl_list; /* = NULL */ | 52 | struct controller *cpqhp_ctrl_list; /* = NULL */ |
54 | struct pci_func *cpqhp_slot_list[256]; | 53 | struct pci_func *cpqhp_slot_list[256]; |
54 | struct irq_routing_table *cpqhp_routing_table; | ||
55 | 55 | ||
56 | /* local variables */ | 56 | /* local variables */ |
57 | static void __iomem *smbios_table; | 57 | static 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 */ | 157 | static int init_cpqhp_routing_table(void) |
158 | static 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 */ | ||
176 | static 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) | |||
331 | static int | 333 | static int |
332 | get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot) | 334 | get_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 | ||
43 | u8 cpqhp_nic_irq; | 42 | u8 cpqhp_nic_irq; |
@@ -244,39 +243,23 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev | |||
244 | 243 | ||
245 | static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge) | 244 | static 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 | ||