Skip to content

Commit

Permalink
PCI Hotplug: cpqphp: clean up accesses to pcibios_get_irq_routing_tab…
Browse files Browse the repository at this point in the history
…le()

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>
  • Loading branch information
Alex Chiang authored and Jesse Barnes committed Jun 11, 2009
1 parent 1d2e8b1 commit b019ee6
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 70 deletions.
9 changes: 9 additions & 0 deletions drivers/pci/hotplug/cpqphp.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ extern int cpqhp_debug;
extern int cpqhp_legacy_mode;
extern struct controller *cpqhp_ctrl_list;
extern struct pci_func *cpqhp_slot_list[256];
extern struct irq_routing_table *cpqhp_routing_table;

/* these can be gotten rid of, but for debugging they are purty */
extern u8 cpqhp_nic_irq;
Expand Down Expand Up @@ -733,4 +734,12 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
return retval;
}

#include <asm/pci_x86.h>
static inline int cpqhp_routing_table_length(void)
{
BUG_ON(cpqhp_routing_table == NULL);
return ((cpqhp_routing_table->size - sizeof(struct irq_routing_table)) /
sizeof(struct irq_info));
}

#endif
72 changes: 31 additions & 41 deletions drivers/pci/hotplug/cpqphp_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@

#include "cpqphp.h"
#include "cpqphp_nvram.h"
#include <asm/pci_x86.h>


/* Global variables */
int cpqhp_debug;
int cpqhp_legacy_mode;
struct controller *cpqhp_ctrl_list; /* = NULL */
struct pci_func *cpqhp_slot_list[256];
struct irq_routing_table *cpqhp_routing_table;

/* local variables */
static void __iomem *smbios_table;
Expand Down Expand Up @@ -154,40 +154,42 @@ static int init_SERR(struct controller * ctrl)
return 0;
}

/* nice debugging output */
static int pci_print_IRQ_route (void)
static int init_cpqhp_routing_table(void)
{
struct irq_routing_table *routing_table;
int len;
int loop;

u8 tbus, tdevice, tslot;

routing_table = pcibios_get_irq_routing_table();
if (routing_table == NULL) {
err("No BIOS Routing Table??? Not good\n");
cpqhp_routing_table = pcibios_get_irq_routing_table();
if (cpqhp_routing_table == NULL)
return -ENOMEM;
}

len = (routing_table->size - sizeof(struct irq_routing_table)) /
sizeof(struct irq_info);
/* Make sure I got at least one entry */
len = cpqhp_routing_table_length();
if (len == 0) {
kfree(routing_table);
kfree(cpqhp_routing_table);
cpqhp_routing_table = NULL;
return -1;
}

dbg("bus dev func slot\n");
return 0;
}

/* nice debugging output */
static void pci_print_IRQ_route(void)
{
int len;
int loop;
u8 tbus, tdevice, tslot;

len = cpqhp_routing_table_length();

dbg("bus dev func slot\n");
for (loop = 0; loop < len; ++loop) {
tbus = routing_table->slots[loop].bus;
tdevice = routing_table->slots[loop].devfn;
tslot = routing_table->slots[loop].slot;
tbus = cpqhp_routing_table->slots[loop].bus;
tdevice = cpqhp_routing_table->slots[loop].devfn;
tslot = cpqhp_routing_table->slots[loop].slot;
dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot);

}
kfree(routing_table);
return 0;
return;
}


Expand Down Expand Up @@ -331,7 +333,6 @@ static int ctrl_slot_cleanup (struct controller * ctrl)
static int
get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
{
struct irq_routing_table *PCIIRQRoutingInfoLength;
u32 work;
long len;
long loop;
Expand All @@ -342,26 +343,14 @@ get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)

bridgeSlot = 0xFF;

PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
if (!PCIIRQRoutingInfoLength)
return -1;

len = (PCIIRQRoutingInfoLength->size -
sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
/* Make sure I got at least one entry */
if (len == 0) {
kfree(PCIIRQRoutingInfoLength);
return -1;
}

len = cpqhp_routing_table_length();
for (loop = 0; loop < len; ++loop) {
tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
tbus = cpqhp_routing_table->slots[loop].bus;
tdevice = cpqhp_routing_table->slots[loop].devfn >> 3;
tslot = cpqhp_routing_table->slots[loop].slot;

if ((tbus == bus_num) && (tdevice == dev_num)) {
*slot = tslot;
kfree(PCIIRQRoutingInfoLength);
return 0;
} else {
/* Did not get a match on the target PCI device. Check
Expand Down Expand Up @@ -396,10 +385,8 @@ get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
*/
if (bridgeSlot != 0xFF) {
*slot = bridgeSlot;
kfree(PCIIRQRoutingInfoLength);
return 0;
}
kfree(PCIIRQRoutingInfoLength);
/* Couldn't find an entry in the routing table for this PCI device */
return -1;
}
Expand Down Expand Up @@ -782,10 +769,13 @@ static int one_time_init(void)

power_mode = 0;

retval = pci_print_IRQ_route();
retval = init_cpqhp_routing_table();
if (retval)
goto error;

if (cpqhp_debug)
pci_print_IRQ_route();

dbg("Initialize + Start the notification mechanism \n");

retval = cpqhp_event_start_thread();
Expand Down
36 changes: 7 additions & 29 deletions drivers/pci/hotplug/cpqphp_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
#include "../pci.h"
#include "cpqphp.h"
#include "cpqphp_nvram.h"
#include <asm/pci_x86.h>


u8 cpqhp_nic_irq;
Expand Down Expand Up @@ -244,39 +243,23 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev

static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge)
{
struct irq_routing_table *PCIIRQRoutingInfoLength;
long len;
long loop;
int loop, len;
u32 work;

u8 tbus, tdevice, tslot;

PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
if (!PCIIRQRoutingInfoLength)
return -1;

len = (PCIIRQRoutingInfoLength->size -
sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
/* Make sure I got at least one entry */
if (len == 0) {
kfree(PCIIRQRoutingInfoLength );
return -1;
}

len = cpqhp_routing_table_length();
for (loop = 0; loop < len; ++loop) {
tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn;
tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
tbus = cpqhp_routing_table->slots[loop].bus;
tdevice = cpqhp_routing_table->slots[loop].devfn;
tslot = cpqhp_routing_table->slots[loop].slot;

if (tslot == slot) {
*bus_num = tbus;
*dev_num = tdevice;
ctrl->pci_bus->number = tbus;
pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
if (!nobridge || (work == 0xffffffff)) {
kfree(PCIIRQRoutingInfoLength );
if (!nobridge || (work == 0xffffffff))
return 0;
}

dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
Expand All @@ -287,17 +270,12 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
dbg("Scan bus for Non Bridge: bus %d\n", tbus);
if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
*bus_num = tbus;
kfree(PCIIRQRoutingInfoLength );
return 0;
}
} else {
kfree(PCIIRQRoutingInfoLength );
} else
return 0;
}

}
}
kfree(PCIIRQRoutingInfoLength );
return -1;
}

Expand Down

0 comments on commit b019ee6

Please sign in to comment.