From 536c8cb49eccd4f753b4782e7e975ef87359cb44 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 13 Dec 2009 08:11:31 -0500 Subject: PCI: Unify pcie_link_speed and pci_bus_speed These enums must not overlap anyway, since we only have a single pci_bus_speed_strings array. Use a single enum, and move it to pci.h. Add 'SPEED' to the pcie names to make it clear what they are. Signed-off-by: Matthew Wilcox Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/pciehp_hpc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 10040d58c8ef..6744ca1d8d01 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -613,7 +613,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) int pciehp_get_max_link_speed(struct slot *slot, enum pci_bus_speed *value) { struct controller *ctrl = slot->ctrl; - enum pcie_link_speed lnk_speed; + enum pci_bus_speed lnk_speed; u32 lnk_cap; int retval = 0; @@ -625,13 +625,13 @@ int pciehp_get_max_link_speed(struct slot *slot, enum pci_bus_speed *value) switch (lnk_cap & 0x000F) { case 1: - lnk_speed = PCIE_2_5GB; + lnk_speed = PCIE_SPEED_2_5GT; break; case 2: - lnk_speed = PCIE_5_0GB; + lnk_speed = PCIE_SPEED_5_0GT; break; default: - lnk_speed = PCIE_LNK_SPEED_UNKNOWN; + lnk_speed = PCI_SPEED_UNKNOWN; break; } @@ -694,7 +694,7 @@ int pciehp_get_max_lnk_width(struct slot *slot, int pciehp_get_cur_link_speed(struct slot *slot, enum pci_bus_speed *value) { struct controller *ctrl = slot->ctrl; - enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN; + enum pci_bus_speed lnk_speed = PCI_SPEED_UNKNOWN; int retval = 0; u16 lnk_status; @@ -707,13 +707,13 @@ int pciehp_get_cur_link_speed(struct slot *slot, enum pci_bus_speed *value) switch (lnk_status & PCI_EXP_LNKSTA_CLS) { case 1: - lnk_speed = PCIE_2_5GB; + lnk_speed = PCIE_SPEED_2_5GT; break; case 2: - lnk_speed = PCIE_5_0GB; + lnk_speed = PCIE_SPEED_5_0GT; break; default: - lnk_speed = PCIE_LNK_SPEED_UNKNOWN; + lnk_speed = PCI_SPEED_UNKNOWN; break; } -- cgit v1.2.3 From 3749c51ac6c1560aa1cb1520066bed84c6f8152a Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sun, 13 Dec 2009 08:11:32 -0500 Subject: PCI: Make current and maximum bus speeds part of the PCI core Move the max_bus_speed and cur_bus_speed into the pci_bus. Expose the values through the PCI slot driver instead of the hotplug slot driver. Update all the hotplug drivers to use the pci_bus instead of their own data structures. Signed-off-by: Matthew Wilcox Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/acpiphp_core.c | 2 - drivers/pci/hotplug/cpqphp.h | 2 - drivers/pci/hotplug/cpqphp_core.c | 57 ++++--------- drivers/pci/hotplug/cpqphp_ctrl.c | 27 +++--- drivers/pci/hotplug/ibmphp_core.c | 106 +++++++---------------- drivers/pci/hotplug/pci_hotplug_core.c | 132 ----------------------------- drivers/pci/hotplug/pciehp_core.c | 25 ------ drivers/pci/hotplug/pciehp_hpc.c | 72 ++-------------- drivers/pci/hotplug/rpaphp_core.c | 23 ++--- drivers/pci/hotplug/shpchp.h | 2 - drivers/pci/hotplug/shpchp_core.c | 35 -------- drivers/pci/hotplug/shpchp_ctrl.c | 13 +-- drivers/pci/hotplug/shpchp_hpc.c | 149 +++++++++++++++++---------------- drivers/pci/probe.c | 27 ++++++ drivers/pci/slot.c | 54 ++++++++++++ include/linux/pci.h | 3 + include/linux/pci_hotplug.h | 15 +--- 17 files changed, 246 insertions(+), 498 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 4dd7114964ac..efa9f2de51c1 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -332,8 +332,6 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot) slot->hotplug_slot->info->attention_status = 0; slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot); slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); - slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN; - slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; acpiphp_slot->slot = slot; snprintf(name, SLOT_NAME_SIZE, "%llu", slot->acpi_slot->sun); diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index 9c6a9fd26812..d8ffc7366801 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h @@ -310,8 +310,6 @@ struct controller { u8 first_slot; u8 add_support; u8 push_flag; - enum pci_bus_speed speed; - enum pci_bus_speed speed_capability; u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */ u8 slot_switch_type; /* 0 = no switch, 1 = switch present */ u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */ diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 075b4f4b6e0d..f184d1d2ecbe 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -583,30 +583,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) return 0; } -static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) -{ - struct slot *slot = hotplug_slot->private; - struct controller *ctrl = slot->ctrl; - - dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); - - *value = ctrl->speed_capability; - - return 0; -} - -static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) -{ - struct slot *slot = hotplug_slot->private; - struct controller *ctrl = slot->ctrl; - - dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); - - *value = ctrl->speed; - - return 0; -} - static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { .set_attention_status = set_attention_status, .enable_slot = process_SI, @@ -616,8 +592,6 @@ static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { .get_attention_status = get_attention_status, .get_latch_status = get_latch_status, .get_adapter_status = get_adapter_status, - .get_max_bus_speed = get_max_bus_speed, - .get_cur_bus_speed = get_cur_bus_speed, }; #define SLOT_NAME_SIZE 10 @@ -629,6 +603,7 @@ static int ctrl_slot_setup(struct controller *ctrl, struct slot *slot; struct hotplug_slot *hotplug_slot; struct hotplug_slot_info *hotplug_slot_info; + struct pci_bus *bus = ctrl->pci_bus; u8 number_of_slots; u8 slot_device; u8 slot_number; @@ -694,7 +669,7 @@ static int ctrl_slot_setup(struct controller *ctrl, slot->capabilities |= PCISLOT_64_BIT_SUPPORTED; if (is_slot66mhz(slot)) slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED; - if (ctrl->speed == PCI_SPEED_66MHz) + if (bus->cur_bus_speed == PCI_SPEED_66MHz) slot->capabilities |= PCISLOT_66_MHZ_OPERATION; ctrl_slot = @@ -844,6 +819,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) u32 rc; struct controller *ctrl; struct pci_func *func; + struct pci_bus *bus; int err; err = pci_enable_device(pdev); @@ -852,6 +828,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_name(pdev), err); return err; } + bus = pdev->subordinate; /* Need to read VID early b/c it's used to differentiate CPQ and INTC * discovery @@ -929,22 +906,22 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_read_config_byte(pdev, 0x41, &bus_cap); if (bus_cap & 0x80) { dbg("bus max supports 133MHz PCI-X\n"); - ctrl->speed_capability = PCI_SPEED_133MHz_PCIX; + bus->max_bus_speed = PCI_SPEED_133MHz_PCIX; break; } if (bus_cap & 0x40) { dbg("bus max supports 100MHz PCI-X\n"); - ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; + bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; break; } if (bus_cap & 20) { dbg("bus max supports 66MHz PCI-X\n"); - ctrl->speed_capability = PCI_SPEED_66MHz_PCIX; + bus->max_bus_speed = PCI_SPEED_66MHz_PCIX; break; } if (bus_cap & 10) { dbg("bus max supports 66MHz PCI\n"); - ctrl->speed_capability = PCI_SPEED_66MHz; + bus->max_bus_speed = PCI_SPEED_66MHz; break; } @@ -955,7 +932,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) case PCI_SUB_HPC_ID: /* Original 6500/7000 implementation */ ctrl->slot_switch_type = 1; - ctrl->speed_capability = PCI_SPEED_33MHz; + bus->max_bus_speed = PCI_SPEED_33MHz; ctrl->push_button = 0; ctrl->pci_config_space = 1; ctrl->defeature_PHP = 1; @@ -966,7 +943,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* First Pushbutton implementation */ ctrl->push_flag = 1; ctrl->slot_switch_type = 1; - ctrl->speed_capability = PCI_SPEED_33MHz; + bus->max_bus_speed = PCI_SPEED_33MHz; ctrl->push_button = 1; ctrl->pci_config_space = 1; ctrl->defeature_PHP = 1; @@ -976,7 +953,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) case PCI_SUB_HPC_ID_INTC: /* Third party (6500/7000) */ ctrl->slot_switch_type = 1; - ctrl->speed_capability = PCI_SPEED_33MHz; + bus->max_bus_speed = PCI_SPEED_33MHz; ctrl->push_button = 0; ctrl->pci_config_space = 1; ctrl->defeature_PHP = 1; @@ -987,7 +964,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* First 66 Mhz implementation */ ctrl->push_flag = 1; ctrl->slot_switch_type = 1; - ctrl->speed_capability = PCI_SPEED_66MHz; + bus->max_bus_speed = PCI_SPEED_66MHz; ctrl->push_button = 1; ctrl->pci_config_space = 1; ctrl->defeature_PHP = 1; @@ -998,7 +975,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* First PCI-X implementation, 100MHz */ ctrl->push_flag = 1; ctrl->slot_switch_type = 1; - ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; + bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; ctrl->push_button = 1; ctrl->pci_config_space = 1; ctrl->defeature_PHP = 1; @@ -1015,9 +992,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) case PCI_VENDOR_ID_INTEL: /* Check for speed capability (0=33, 1=66) */ if (subsystem_deviceid & 0x0001) - ctrl->speed_capability = PCI_SPEED_66MHz; + bus->max_bus_speed = PCI_SPEED_66MHz; else - ctrl->speed_capability = PCI_SPEED_33MHz; + bus->max_bus_speed = PCI_SPEED_33MHz; /* Check for push button */ if (subsystem_deviceid & 0x0002) @@ -1079,7 +1056,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pdev->bus->number); dbg("Hotplug controller capabilities:\n"); - dbg(" speed_capability %d\n", ctrl->speed_capability); + dbg(" speed_capability %d\n", bus->max_bus_speed); dbg(" slot_switch_type %s\n", ctrl->slot_switch_type ? "switch present" : "no switch"); dbg(" defeature_PHP %s\n", ctrl->defeature_PHP ? @@ -1142,7 +1119,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } /* Check for 66Mhz operation */ - ctrl->speed = get_controller_speed(ctrl); + bus->cur_bus_speed = get_controller_speed(ctrl); /******************************************************** diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 0ff689afa757..e43908d9b5df 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -1130,12 +1130,13 @@ static int is_bridge(struct pci_func * func) static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot) { struct slot *slot; + struct pci_bus *bus = ctrl->pci_bus; u8 reg; u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER); u16 reg16; u32 leds = readl(ctrl->hpc_reg + LED_CONTROL); - if (ctrl->speed == adapter_speed) + if (bus->cur_bus_speed == adapter_speed) return 0; /* We don't allow freq/mode changes if we find another adapter running @@ -1152,7 +1153,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ * lower speed/mode, we allow the new adapter to function at * this rate if supported */ - if (ctrl->speed < adapter_speed) + if (bus->cur_bus_speed < adapter_speed) return 0; return 1; @@ -1161,20 +1162,20 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ /* If the controller doesn't support freq/mode changes and the * controller is running at a higher mode, we bail */ - if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability)) + if ((bus->cur_bus_speed > adapter_speed) && (!ctrl->pcix_speed_capability)) return 1; /* But we allow the adapter to run at a lower rate if possible */ - if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability)) + if ((bus->cur_bus_speed < adapter_speed) && (!ctrl->pcix_speed_capability)) return 0; /* We try to set the max speed supported by both the adapter and * controller */ - if (ctrl->speed_capability < adapter_speed) { - if (ctrl->speed == ctrl->speed_capability) + if (bus->max_bus_speed < adapter_speed) { + if (bus->cur_bus_speed == bus->max_bus_speed) return 0; - adapter_speed = ctrl->speed_capability; + adapter_speed = bus->max_bus_speed; } writel(0x0L, ctrl->hpc_reg + LED_CONTROL); @@ -1229,8 +1230,8 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ pci_write_config_byte(ctrl->pci_dev, 0x43, reg); /* Only if mode change...*/ - if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || - ((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) + if (((bus->cur_bus_speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || + ((bus->cur_bus_speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) set_SOGO(ctrl); wait_for_ctrl_irq(ctrl); @@ -1243,7 +1244,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ set_SOGO(ctrl); wait_for_ctrl_irq(ctrl); - ctrl->speed = adapter_speed; + bus->cur_bus_speed = adapter_speed; slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); info("Successfully changed frequency/mode for adapter in slot %d\n", @@ -1269,6 +1270,7 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ */ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) { + struct pci_bus *bus = ctrl->pci_bus; u8 hp_slot; u8 temp_byte; u8 adapter_speed; @@ -1309,7 +1311,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) wait_for_ctrl_irq (ctrl); adapter_speed = get_adapter_speed(ctrl, hp_slot); - if (ctrl->speed != adapter_speed) + if (bus->cur_bus_speed != adapter_speed) if (set_controller_speed(ctrl, adapter_speed, hp_slot)) rc = WRONG_BUS_FREQUENCY; @@ -1426,6 +1428,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) u32 temp_register = 0xFFFFFFFF; u32 rc = 0; struct pci_func *new_slot = NULL; + struct pci_bus *bus = ctrl->pci_bus; struct slot *p_slot; struct resource_lists res_lists; @@ -1456,7 +1459,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) wait_for_ctrl_irq (ctrl); adapter_speed = get_adapter_speed(ctrl, hp_slot); - if (ctrl->speed != adapter_speed) + if (bus->cur_bus_speed != adapter_speed) if (set_controller_speed(ctrl, adapter_speed, hp_slot)) rc = WRONG_BUS_FREQUENCY; diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 7485ffda950c..d934dd4fa873 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -395,89 +395,40 @@ static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value) return rc; } -static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) +static int get_max_bus_speed(struct slot *slot) { - int rc = -ENODEV; - struct slot *pslot; + int rc; u8 mode = 0; + enum pci_bus_speed speed; + struct pci_bus *bus = slot->hotplug_slot->pci_slot->bus; - debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__, - hotplug_slot, value); + debug("%s - Entry slot[%p]\n", __func__, slot); ibmphp_lock_operations(); - - if (hotplug_slot) { - pslot = hotplug_slot->private; - if (pslot) { - rc = 0; - mode = pslot->supported_bus_mode; - *value = pslot->supported_speed; - switch (*value) { - case BUS_SPEED_33: - break; - case BUS_SPEED_66: - if (mode == BUS_MODE_PCIX) - *value += 0x01; - break; - case BUS_SPEED_100: - case BUS_SPEED_133: - *value = pslot->supported_speed + 0x01; - break; - default: - /* Note (will need to change): there would be soon 256, 512 also */ - rc = -ENODEV; - } - } - } - + mode = slot->supported_bus_mode; + speed = slot->supported_speed; ibmphp_unlock_operations(); - debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value); - return rc; -} -static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) -{ - int rc = -ENODEV; - struct slot *pslot; - u8 mode = 0; - - debug("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __func__, - hotplug_slot, value); - - ibmphp_lock_operations(); - - if (hotplug_slot) { - pslot = hotplug_slot->private; - if (pslot) { - rc = get_cur_bus_info(&pslot); - if (!rc) { - mode = pslot->bus_on->current_bus_mode; - *value = pslot->bus_on->current_speed; - switch (*value) { - case BUS_SPEED_33: - break; - case BUS_SPEED_66: - if (mode == BUS_MODE_PCIX) - *value += 0x01; - else if (mode == BUS_MODE_PCI) - ; - else - *value = PCI_SPEED_UNKNOWN; - break; - case BUS_SPEED_100: - case BUS_SPEED_133: - *value += 0x01; - break; - default: - /* Note of change: there would also be 256, 512 soon */ - rc = -ENODEV; - } - } - } + switch (speed) { + case BUS_SPEED_33: + break; + case BUS_SPEED_66: + if (mode == BUS_MODE_PCIX) + speed += 0x01; + break; + case BUS_SPEED_100: + case BUS_SPEED_133: + speed += 0x01; + break; + default: + /* Note (will need to change): there would be soon 256, 512 also */ + rc = -ENODEV; } - ibmphp_unlock_operations(); - debug("%s - Exit rc[%d] value[%x]\n", __func__, rc, *value); + if (!rc) + bus->max_bus_speed = speed; + + debug("%s - Exit rc[%d] speed[%x]\n", __func__, rc, speed); return rc; } @@ -572,6 +523,7 @@ static int __init init_ops(void) if (slot_cur->bus_on->current_speed == 0xFF) if (get_cur_bus_info(&slot_cur)) return -1; + get_max_bus_speed(slot_cur); if (slot_cur->ctrl->options == 0xFF) if (get_hpc_options(slot_cur, &slot_cur->ctrl->options)) @@ -655,6 +607,7 @@ static int validate(struct slot *slot_cur, int opn) int ibmphp_update_slot_info(struct slot *slot_cur) { struct hotplug_slot_info *info; + struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus; int rc; u8 bus_speed; u8 mode; @@ -700,8 +653,7 @@ int ibmphp_update_slot_info(struct slot *slot_cur) bus_speed = PCI_SPEED_UNKNOWN; } - info->cur_bus_speed = bus_speed; - info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed; + bus->cur_bus_speed = bus_speed; // To do: bus_names rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info); @@ -1326,8 +1278,6 @@ struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { .get_attention_status = get_attention_status, .get_latch_status = get_latch_status, .get_adapter_status = get_adapter_present, - .get_max_bus_speed = get_max_bus_speed, - .get_cur_bus_speed = get_cur_bus_speed, /* .get_max_adapter_speed = get_max_adapter_speed, .get_bus_name_status = get_bus_name, */ diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 38183a534b65..728b119f71ad 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -64,32 +64,6 @@ static int debug; static LIST_HEAD(pci_hotplug_slot_list); static DEFINE_MUTEX(pci_hp_mutex); -/* these strings match up with the values in pci_bus_speed */ -static char *pci_bus_speed_strings[] = { - "33 MHz PCI", /* 0x00 */ - "66 MHz PCI", /* 0x01 */ - "66 MHz PCI-X", /* 0x02 */ - "100 MHz PCI-X", /* 0x03 */ - "133 MHz PCI-X", /* 0x04 */ - NULL, /* 0x05 */ - NULL, /* 0x06 */ - NULL, /* 0x07 */ - NULL, /* 0x08 */ - "66 MHz PCI-X 266", /* 0x09 */ - "100 MHz PCI-X 266", /* 0x0a */ - "133 MHz PCI-X 266", /* 0x0b */ - NULL, /* 0x0c */ - NULL, /* 0x0d */ - NULL, /* 0x0e */ - NULL, /* 0x0f */ - NULL, /* 0x10 */ - "66 MHz PCI-X 533", /* 0x11 */ - "100 MHz PCI-X 533", /* 0x12 */ - "133 MHz PCI-X 533", /* 0x13 */ - "2.5 GT/s PCIe", /* 0x14 */ - "5.0 GT/s PCIe", /* 0x15 */ -}; - #ifdef CONFIG_HOTPLUG_PCI_CPCI extern int cpci_hotplug_init(int debug); extern void cpci_hotplug_exit(void); @@ -118,8 +92,6 @@ GET_STATUS(power_status, u8) GET_STATUS(attention_status, u8) GET_STATUS(latch_status, u8) GET_STATUS(adapter_status, u8) -GET_STATUS(max_bus_speed, enum pci_bus_speed) -GET_STATUS(cur_bus_speed, enum pci_bus_speed) static ssize_t power_read_file(struct pci_slot *slot, char *buf) { @@ -263,60 +235,6 @@ static struct pci_slot_attribute hotplug_slot_attr_presence = { .show = presence_read_file, }; -static char *unknown_speed = "Unknown bus speed"; - -static ssize_t max_bus_speed_read_file(struct pci_slot *slot, char *buf) -{ - char *speed_string; - int retval; - enum pci_bus_speed value; - - retval = get_max_bus_speed(slot->hotplug, &value); - if (retval) - goto exit; - - if (value == PCI_SPEED_UNKNOWN) - speed_string = unknown_speed; - else - speed_string = pci_bus_speed_strings[value]; - - retval = sprintf (buf, "%s\n", speed_string); - -exit: - return retval; -} - -static struct pci_slot_attribute hotplug_slot_attr_max_bus_speed = { - .attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO}, - .show = max_bus_speed_read_file, -}; - -static ssize_t cur_bus_speed_read_file(struct pci_slot *slot, char *buf) -{ - char *speed_string; - int retval; - enum pci_bus_speed value; - - retval = get_cur_bus_speed(slot->hotplug, &value); - if (retval) - goto exit; - - if (value == PCI_SPEED_UNKNOWN) - speed_string = unknown_speed; - else - speed_string = pci_bus_speed_strings[value]; - - retval = sprintf (buf, "%s\n", speed_string); - -exit: - return retval; -} - -static struct pci_slot_attribute hotplug_slot_attr_cur_bus_speed = { - .attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO}, - .show = cur_bus_speed_read_file, -}; - static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf, size_t count) { @@ -391,26 +309,6 @@ static bool has_adapter_file(struct pci_slot *pci_slot) return false; } -static bool has_max_bus_speed_file(struct pci_slot *pci_slot) -{ - struct hotplug_slot *slot = pci_slot->hotplug; - if ((!slot) || (!slot->ops)) - return false; - if (slot->ops->get_max_bus_speed) - return true; - return false; -} - -static bool has_cur_bus_speed_file(struct pci_slot *pci_slot) -{ - struct hotplug_slot *slot = pci_slot->hotplug; - if ((!slot) || (!slot->ops)) - return false; - if (slot->ops->get_cur_bus_speed) - return true; - return false; -} - static bool has_test_file(struct pci_slot *pci_slot) { struct hotplug_slot *slot = pci_slot->hotplug; @@ -456,20 +354,6 @@ static int fs_add_slot(struct pci_slot *slot) goto exit_adapter; } - if (has_max_bus_speed_file(slot)) { - retval = sysfs_create_file(&slot->kobj, - &hotplug_slot_attr_max_bus_speed.attr); - if (retval) - goto exit_max_speed; - } - - if (has_cur_bus_speed_file(slot)) { - retval = sysfs_create_file(&slot->kobj, - &hotplug_slot_attr_cur_bus_speed.attr); - if (retval) - goto exit_cur_speed; - } - if (has_test_file(slot)) { retval = sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr); @@ -480,14 +364,6 @@ static int fs_add_slot(struct pci_slot *slot) goto exit; exit_test: - if (has_cur_bus_speed_file(slot)) - sysfs_remove_file(&slot->kobj, - &hotplug_slot_attr_cur_bus_speed.attr); -exit_cur_speed: - if (has_max_bus_speed_file(slot)) - sysfs_remove_file(&slot->kobj, - &hotplug_slot_attr_max_bus_speed.attr); -exit_max_speed: if (has_adapter_file(slot)) sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr); @@ -523,14 +399,6 @@ static void fs_remove_slot(struct pci_slot *slot) sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr); - if (has_max_bus_speed_file(slot)) - sysfs_remove_file(&slot->kobj, - &hotplug_slot_attr_max_bus_speed.attr); - - if (has_cur_bus_speed_file(slot)) - sysfs_remove_file(&slot->kobj, - &hotplug_slot_attr_cur_bus_speed.attr); - if (has_test_file(slot)) sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 5674b2075bdc..920f820edf87 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -69,8 +69,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); static int get_attention_status (struct hotplug_slot *slot, u8 *value); static int get_latch_status (struct hotplug_slot *slot, u8 *value); static int get_adapter_status (struct hotplug_slot *slot, u8 *value); -static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); -static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); /** * release_slot - free up the memory used by a slot @@ -113,8 +111,6 @@ static int init_slot(struct controller *ctrl) ops->disable_slot = disable_slot; ops->get_power_status = get_power_status; ops->get_adapter_status = get_adapter_status; - ops->get_max_bus_speed = get_max_bus_speed; - ops->get_cur_bus_speed = get_cur_bus_speed; if (MRL_SENS(ctrl)) ops->get_latch_status = get_latch_status; if (ATTN_LED(ctrl)) { @@ -227,27 +223,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) return pciehp_get_adapter_status(slot, value); } -static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, - enum pci_bus_speed *value) -{ - struct slot *slot = hotplug_slot->private; - - ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", - __func__, slot_name(slot)); - - return pciehp_get_max_link_speed(slot, value); -} - -static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) -{ - struct slot *slot = hotplug_slot->private; - - ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", - __func__, slot_name(slot)); - - return pciehp_get_cur_link_speed(slot, value); -} - static int pciehp_probe(struct pcie_device *dev) { int rc; diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 6744ca1d8d01..40b48f569b1e 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -492,6 +492,7 @@ int pciehp_power_on_slot(struct slot * slot) u16 slot_cmd; u16 cmd_mask; u16 slot_status; + u16 lnk_status; int retval = 0; /* Clear sticky power-fault bit from previous power failures */ @@ -523,6 +524,14 @@ int pciehp_power_on_slot(struct slot * slot) ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); + retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); + if (retval) { + ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n", + __func__); + return retval; + } + pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); + return retval; } @@ -610,37 +619,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) return IRQ_HANDLED; } -int pciehp_get_max_link_speed(struct slot *slot, enum pci_bus_speed *value) -{ - struct controller *ctrl = slot->ctrl; - enum pci_bus_speed lnk_speed; - u32 lnk_cap; - int retval = 0; - - retval = pciehp_readl(ctrl, PCI_EXP_LNKCAP, &lnk_cap); - if (retval) { - ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); - return retval; - } - - switch (lnk_cap & 0x000F) { - case 1: - lnk_speed = PCIE_SPEED_2_5GT; - break; - case 2: - lnk_speed = PCIE_SPEED_5_0GT; - break; - default: - lnk_speed = PCI_SPEED_UNKNOWN; - break; - } - - *value = lnk_speed; - ctrl_dbg(ctrl, "Max link speed = %d\n", lnk_speed); - - return retval; -} - int pciehp_get_max_lnk_width(struct slot *slot, enum pcie_link_width *value) { @@ -691,38 +669,6 @@ int pciehp_get_max_lnk_width(struct slot *slot, return retval; } -int pciehp_get_cur_link_speed(struct slot *slot, enum pci_bus_speed *value) -{ - struct controller *ctrl = slot->ctrl; - enum pci_bus_speed lnk_speed = PCI_SPEED_UNKNOWN; - int retval = 0; - u16 lnk_status; - - retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); - if (retval) { - ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", - __func__); - return retval; - } - - switch (lnk_status & PCI_EXP_LNKSTA_CLS) { - case 1: - lnk_speed = PCIE_SPEED_2_5GT; - break; - case 2: - lnk_speed = PCIE_SPEED_5_0GT; - break; - default: - lnk_speed = PCI_SPEED_UNKNOWN; - break; - } - - *value = lnk_speed; - ctrl_dbg(ctrl, "Current link speed = %d\n", lnk_speed); - - return retval; -} - int pciehp_get_cur_lnk_width(struct slot *slot, enum pcie_link_width *value) { diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index c159223389ec..b14e5e66a92c 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -130,10 +130,9 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) return 0; } -static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) +static enum pci_bus_speed get_max_bus_speed(struct slot *slot) { - struct slot *slot = (struct slot *)hotplug_slot->private; - + enum pci_bus_speed speed; switch (slot->type) { case 1: case 2: @@ -141,30 +140,30 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe case 4: case 5: case 6: - *value = PCI_SPEED_33MHz; /* speed for case 1-6 */ + speed = PCI_SPEED_33MHz; /* speed for case 1-6 */ break; case 7: case 8: - *value = PCI_SPEED_66MHz; + speed = PCI_SPEED_66MHz; break; case 11: case 14: - *value = PCI_SPEED_66MHz_PCIX; + speed = PCI_SPEED_66MHz_PCIX; break; case 12: case 15: - *value = PCI_SPEED_100MHz_PCIX; + speed = PCI_SPEED_100MHz_PCIX; break; case 13: case 16: - *value = PCI_SPEED_133MHz_PCIX; + speed = PCI_SPEED_133MHz_PCIX; break; default: - *value = PCI_SPEED_UNKNOWN; + speed = PCI_SPEED_UNKNOWN; break; - } - return 0; + + return speed; } static int get_children_props(struct device_node *dn, const int **drc_indexes, @@ -408,6 +407,8 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) slot->state = NOT_VALID; return -EINVAL; } + + slot->bus->max_bus_speed = get_max_bus_speed(slot); return 0; } diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 8e210cd76e55..d2627e1c3ac1 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -333,8 +333,6 @@ struct hpc_ops { int (*set_attention_status)(struct slot *slot, u8 status); int (*get_latch_status)(struct slot *slot, u8 *status); int (*get_adapter_status)(struct slot *slot, u8 *status); - int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); - int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed); int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode); int (*get_prog_int)(struct slot *slot, u8 *prog_int); diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 8a520a3d0f59..a5062297f488 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -65,8 +65,6 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value); static int get_attention_status (struct hotplug_slot *slot, u8 *value); static int get_latch_status (struct hotplug_slot *slot, u8 *value); static int get_adapter_status (struct hotplug_slot *slot, u8 *value); -static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); -static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { .set_attention_status = set_attention_status, @@ -76,8 +74,6 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { .get_attention_status = get_attention_status, .get_latch_status = get_latch_status, .get_adapter_status = get_adapter_status, - .get_max_bus_speed = get_max_bus_speed, - .get_cur_bus_speed = get_cur_bus_speed, }; /** @@ -279,37 +275,6 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) return 0; } -static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, - enum pci_bus_speed *value) -{ - struct slot *slot = get_slot(hotplug_slot); - int retval; - - ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", - __func__, slot_name(slot)); - - retval = slot->hpc_ops->get_max_bus_speed(slot, value); - if (retval < 0) - *value = PCI_SPEED_UNKNOWN; - - return 0; -} - -static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) -{ - struct slot *slot = get_slot(hotplug_slot); - int retval; - - ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", - __func__, slot_name(slot)); - - retval = slot->hpc_ops->get_cur_bus_speed(slot, value); - if (retval < 0) - *value = PCI_SPEED_UNKNOWN; - - return 0; -} - static int is_shpc_capable(struct pci_dev *dev) { if ((dev->vendor == PCI_VENDOR_ID_AMD) || (dev->device == diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index b8ab2796e66a..179b1c1cb99b 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -285,17 +285,8 @@ static int board_added(struct slot *p_slot) return WRONG_BUS_FREQUENCY; } - rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bsp); - if (rc) { - ctrl_err(ctrl, "Can't get bus operation speed\n"); - return WRONG_BUS_FREQUENCY; - } - - rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &msp); - if (rc) { - ctrl_err(ctrl, "Can't get max bus operation speed\n"); - msp = bsp; - } + bsp = ctrl->pci_dev->bus->cur_bus_speed; + msp = ctrl->pci_dev->bus->max_bus_speed; /* Check if there are other slots or devices on the same bus */ if (!list_empty(&ctrl->pci_dev->subordinate->devices)) diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 86dc39847769..5f5e8d2e3552 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -660,6 +660,75 @@ static int hpc_slot_disable(struct slot * slot) return retval; } +static int shpc_get_cur_bus_speed(struct controller *ctrl) +{ + int retval = 0; + struct pci_bus *bus = ctrl->pci_dev->subordinate; + enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; + u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); + u8 pi = shpc_readb(ctrl, PROG_INTERFACE); + u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); + + if ((pi == 1) && (speed_mode > 4)) { + retval = -ENODEV; + goto out; + } + + switch (speed_mode) { + case 0x0: + bus_speed = PCI_SPEED_33MHz; + break; + case 0x1: + bus_speed = PCI_SPEED_66MHz; + break; + case 0x2: + bus_speed = PCI_SPEED_66MHz_PCIX; + break; + case 0x3: + bus_speed = PCI_SPEED_100MHz_PCIX; + break; + case 0x4: + bus_speed = PCI_SPEED_133MHz_PCIX; + break; + case 0x5: + bus_speed = PCI_SPEED_66MHz_PCIX_ECC; + break; + case 0x6: + bus_speed = PCI_SPEED_100MHz_PCIX_ECC; + break; + case 0x7: + bus_speed = PCI_SPEED_133MHz_PCIX_ECC; + break; + case 0x8: + bus_speed = PCI_SPEED_66MHz_PCIX_266; + break; + case 0x9: + bus_speed = PCI_SPEED_100MHz_PCIX_266; + break; + case 0xa: + bus_speed = PCI_SPEED_133MHz_PCIX_266; + break; + case 0xb: + bus_speed = PCI_SPEED_66MHz_PCIX_533; + break; + case 0xc: + bus_speed = PCI_SPEED_100MHz_PCIX_533; + break; + case 0xd: + bus_speed = PCI_SPEED_133MHz_PCIX_533; + break; + default: + retval = -ENODEV; + break; + } + + out: + bus->cur_bus_speed = bus_speed; + dbg("Current bus speed = %d\n", bus_speed); + return retval; +} + + static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) { int retval; @@ -720,6 +789,8 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) retval = shpc_write_cmd(slot, 0, cmd); if (retval) ctrl_err(ctrl, "%s: Write command failed!\n", __func__); + else + shpc_get_cur_bus_speed(ctrl); return retval; } @@ -803,10 +874,10 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) +static int shpc_get_max_bus_speed(struct controller *ctrl) { int retval = 0; - struct controller *ctrl = slot->ctrl; + struct pci_bus *bus = ctrl->pci_dev->subordinate; enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; u8 pi = shpc_readb(ctrl, PROG_INTERFACE); u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); @@ -842,79 +913,12 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) retval = -ENODEV; } - *value = bus_speed; + bus->max_bus_speed = bus_speed; ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed); return retval; } -static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) -{ - int retval = 0; - struct controller *ctrl = slot->ctrl; - enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; - u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); - u8 pi = shpc_readb(ctrl, PROG_INTERFACE); - u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); - - if ((pi == 1) && (speed_mode > 4)) { - *value = PCI_SPEED_UNKNOWN; - return -ENODEV; - } - - switch (speed_mode) { - case 0x0: - *value = PCI_SPEED_33MHz; - break; - case 0x1: - *value = PCI_SPEED_66MHz; - break; - case 0x2: - *value = PCI_SPEED_66MHz_PCIX; - break; - case 0x3: - *value = PCI_SPEED_100MHz_PCIX; - break; - case 0x4: - *value = PCI_SPEED_133MHz_PCIX; - break; - case 0x5: - *value = PCI_SPEED_66MHz_PCIX_ECC; - break; - case 0x6: - *value = PCI_SPEED_100MHz_PCIX_ECC; - break; - case 0x7: - *value = PCI_SPEED_133MHz_PCIX_ECC; - break; - case 0x8: - *value = PCI_SPEED_66MHz_PCIX_266; - break; - case 0x9: - *value = PCI_SPEED_100MHz_PCIX_266; - break; - case 0xa: - *value = PCI_SPEED_133MHz_PCIX_266; - break; - case 0xb: - *value = PCI_SPEED_66MHz_PCIX_533; - break; - case 0xc: - *value = PCI_SPEED_100MHz_PCIX_533; - break; - case 0xd: - *value = PCI_SPEED_133MHz_PCIX_533; - break; - default: - *value = PCI_SPEED_UNKNOWN; - retval = -ENODEV; - break; - } - - ctrl_dbg(ctrl, "Current bus speed = %d\n", bus_speed); - return retval; -} - static struct hpc_ops shpchp_hpc_ops = { .power_on_slot = hpc_power_on_slot, .slot_enable = hpc_slot_enable, @@ -926,8 +930,6 @@ static struct hpc_ops shpchp_hpc_ops = { .get_latch_status = hpc_get_latch_status, .get_adapter_status = hpc_get_adapter_status, - .get_max_bus_speed = hpc_get_max_bus_speed, - .get_cur_bus_speed = hpc_get_cur_bus_speed, .get_adapter_speed = hpc_get_adapter_speed, .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap, .get_prog_int = hpc_get_prog_int, @@ -1086,6 +1088,9 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) } ctrl_dbg(ctrl, "HPC at %s irq=%x\n", pci_name(pdev), pdev->irq); + shpc_get_max_bus_speed(ctrl); + shpc_get_cur_bus_speed(ctrl); + /* * If this is the first controller to be initialized, * initialize the shpchpd work queue diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index dd64310a735e..51cf8982fec7 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -387,10 +387,37 @@ static struct pci_bus * pci_alloc_bus(void) INIT_LIST_HEAD(&b->children); INIT_LIST_HEAD(&b->devices); INIT_LIST_HEAD(&b->slots); + b->max_bus_speed = PCI_SPEED_UNKNOWN; + b->cur_bus_speed = PCI_SPEED_UNKNOWN; } return b; } +static unsigned char pcie_link_speed[] = { + PCI_SPEED_UNKNOWN, /* 0 */ + PCIE_SPEED_2_5GT, /* 1 */ + PCIE_SPEED_5_0GT, /* 2 */ + PCI_SPEED_UNKNOWN, /* 3 */ + PCI_SPEED_UNKNOWN, /* 4 */ + PCI_SPEED_UNKNOWN, /* 5 */ + PCI_SPEED_UNKNOWN, /* 6 */ + PCI_SPEED_UNKNOWN, /* 7 */ + PCI_SPEED_UNKNOWN, /* 8 */ + PCI_SPEED_UNKNOWN, /* 9 */ + PCI_SPEED_UNKNOWN, /* A */ + PCI_SPEED_UNKNOWN, /* B */ + PCI_SPEED_UNKNOWN, /* C */ + PCI_SPEED_UNKNOWN, /* D */ + PCI_SPEED_UNKNOWN, /* E */ + PCI_SPEED_UNKNOWN /* F */ +}; + +void pcie_update_link_speed(struct pci_bus *bus, u16 linksta) +{ + bus->cur_bus_speed = pcie_link_speed[linksta & 0xf]; +} +EXPORT_SYMBOL_GPL(pcie_update_link_speed); + static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) { diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 8c02b6c53bdb..6f6b8d24786a 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -47,6 +47,54 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf) slot->number); } +/* these strings match up with the values in pci_bus_speed */ +static char *pci_bus_speed_strings[] = { + "33 MHz PCI", /* 0x00 */ + "66 MHz PCI", /* 0x01 */ + "66 MHz PCI-X", /* 0x02 */ + "100 MHz PCI-X", /* 0x03 */ + "133 MHz PCI-X", /* 0x04 */ + NULL, /* 0x05 */ + NULL, /* 0x06 */ + NULL, /* 0x07 */ + NULL, /* 0x08 */ + "66 MHz PCI-X 266", /* 0x09 */ + "100 MHz PCI-X 266", /* 0x0a */ + "133 MHz PCI-X 266", /* 0x0b */ + NULL, /* 0x0c */ + NULL, /* 0x0d */ + NULL, /* 0x0e */ + NULL, /* 0x0f */ + NULL, /* 0x10 */ + "66 MHz PCI-X 533", /* 0x11 */ + "100 MHz PCI-X 533", /* 0x12 */ + "133 MHz PCI-X 533", /* 0x13 */ + "2.5 GT/s PCIe", /* 0x14 */ + "5.0 GT/s PCIe", /* 0x15 */ +}; + +static ssize_t bus_speed_read(enum pci_bus_speed speed, char *buf) +{ + const char *speed_string; + + if (speed < ARRAY_SIZE(pci_bus_speed_strings)) + speed_string = pci_bus_speed_strings[speed]; + else + speed_string = "Unknown"; + + return sprintf(buf, "%s\n", speed_string); +} + +static ssize_t max_speed_read_file(struct pci_slot *slot, char *buf) +{ + return bus_speed_read(slot->bus->max_bus_speed, buf); +} + +static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf) +{ + return bus_speed_read(slot->bus->cur_bus_speed, buf); +} + static void pci_slot_release(struct kobject *kobj) { struct pci_dev *dev; @@ -66,9 +114,15 @@ static void pci_slot_release(struct kobject *kobj) static struct pci_slot_attribute pci_slot_attr_address = __ATTR(address, (S_IFREG | S_IRUGO), address_read_file, NULL); +static struct pci_slot_attribute pci_slot_attr_max_speed = + __ATTR(max_bus_speed, (S_IFREG | S_IRUGO), max_speed_read_file, NULL); +static struct pci_slot_attribute pci_slot_attr_cur_speed = + __ATTR(cur_bus_speed, (S_IFREG | S_IRUGO), cur_speed_read_file, NULL); static struct attribute *pci_slot_default_attrs[] = { &pci_slot_attr_address.attr, + &pci_slot_attr_max_speed.attr, + &pci_slot_attr_cur_speed.attr, NULL, }; diff --git a/include/linux/pci.h b/include/linux/pci.h index d76a8a0b6b53..a446097a9f68 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -380,6 +380,8 @@ struct pci_bus { unsigned char primary; /* number of primary bridge */ unsigned char secondary; /* number of secondary bridge */ unsigned char subordinate; /* max number of subordinate buses */ + unsigned char max_bus_speed; /* enum pci_bus_speed */ + unsigned char cur_bus_speed; /* enum pci_bus_speed */ char name[48]; @@ -610,6 +612,7 @@ struct pci_bus *pci_create_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr); +void pcie_update_link_speed(struct pci_bus *bus, u16 link_status); struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, const char *name, struct hotplug_slot *hotplug); diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index 56251ac385e9..5d09cbafa7db 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -63,12 +63,6 @@ enum pcie_link_width { * @get_adapter_status: Called to get see if an adapter is present in the slot or not. * If this field is NULL, the value passed in the struct hotplug_slot_info * will be used when this value is requested by a user. - * @get_max_bus_speed: Called to get the max bus speed for a slot. - * If this field is NULL, the value passed in the struct hotplug_slot_info - * will be used when this value is requested by a user. - * @get_cur_bus_speed: Called to get the current bus speed for a slot. - * If this field is NULL, the value passed in the struct hotplug_slot_info - * will be used when this value is requested by a user. * * The table of function pointers that is passed to the hotplug pci core by a * hotplug pci driver. These functions are called by the hotplug pci core when @@ -86,17 +80,14 @@ struct hotplug_slot_ops { int (*get_attention_status) (struct hotplug_slot *slot, u8 *value); int (*get_latch_status) (struct hotplug_slot *slot, u8 *value); int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value); - int (*get_max_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value); - int (*get_cur_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value); }; /** * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot - * @power: if power is enabled or not (1/0) + * @power_status: if power is enabled or not (1/0) * @attention_status: if the attention light is enabled or not (1/0) * @latch_status: if the latch (if any) is open or closed (1/0) - * @adapter_present: if there is a pci board present in the slot or not (1/0) - * @address: (domain << 16 | bus << 8 | dev) + * @adapter_status: if there is a pci board present in the slot or not (1/0) * * Used to notify the hotplug pci core of the status of a specific slot. */ @@ -105,8 +96,6 @@ struct hotplug_slot_info { u8 attention_status; u8 latch_status; u8 adapter_status; - enum pci_bus_speed max_bus_speed; - enum pci_bus_speed cur_bus_speed; }; /** -- cgit v1.2.3 From 3804259475314a50e4d7a8a974a22fddb6ac7dd7 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 4 Jan 2010 15:44:10 -0800 Subject: PCI hotplug: remove obsolete usage of get_bus_speed from rpaphp hotplug ops No longer needed and causes build breakage. Reported-by: Stephen Rothwell Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/rpaphp_core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index b14e5e66a92c..dcaae725fd79 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -430,7 +430,6 @@ struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { .get_power_status = get_power_status, .get_attention_status = get_attention_status, .get_adapter_status = get_adapter_status, - .get_max_bus_speed = get_max_bus_speed, }; module_init(rpaphp_init); -- cgit v1.2.3 From 6fcaf17ac7a512227112ac81c0e1a5862bab57a6 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 6 Jan 2010 17:47:56 +0100 Subject: PCI hotplug: fix memory leaks Stanse found a cut&pasted memory leak in pciehp_queue_pushbutton_work and shpchp_queue_pushbutton_work. info is not freed/assigned on all paths. Fix that. Reviewed-by: Kenji Kaneshige Signed-off-by: Jiri Slaby Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/pciehp_ctrl.c | 1 + drivers/pci/hotplug/shpchp_ctrl.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index d6ac1b261dd9..9a7f247e8ac1 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -341,6 +341,7 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) p_slot->state = POWERON_STATE; break; default: + kfree(info); goto out; } queue_work(pciehp_wq, &info->work); diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 179b1c1cb99b..3bba0c0888ff 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -453,6 +453,7 @@ void shpchp_queue_pushbutton_work(struct work_struct *work) p_slot->state = POWERON_STATE; break; default: + kfree(info); goto out; } queue_work(shpchp_wq, &info->work); -- cgit v1.2.3 From b0fc889c4311835ae7d02f433154bc20cad9ee11 Mon Sep 17 00:00:00 2001 From: Chandru Date: Mon, 11 Jan 2010 11:49:21 +0530 Subject: PCI hotplug: ibmphp: read the length of ebda and map entire ebda region ibmphp driver currently maps only 1KB of ebda memory area into kernel address space during driver initialization. This causes kernel oops when the driver is modprobe'd and it accesses memory beyond 1KB within ebda segment. The first byte of ebda segment actually stores the length of the ebda region in Kilobytes. Hence make use of the length parameter and map the entire ebda region. Signed-off-by: Chandru Siddalingappa Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/ibmphp_ebda.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index c1abac8ab5c3..7d3bf31d224d 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c @@ -245,7 +245,7 @@ static void __init print_ebda_hpc (void) int __init ibmphp_access_ebda (void) { - u8 format, num_ctlrs, rio_complete, hs_complete; + u8 format, num_ctlrs, rio_complete, hs_complete, ebda_sz; u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, re, rc_id, re_id, base; int rc = 0; @@ -260,7 +260,14 @@ int __init ibmphp_access_ebda (void) iounmap (io_mem); debug ("returned ebda segment: %x\n", ebda_seg); - io_mem = ioremap(ebda_seg<<4, 1024); + io_mem = ioremap(ebda_seg<<4, 1); + ebda_sz = readb(io_mem); + iounmap(io_mem); + debug("ebda size: %d(KiB)\n", ebda_sz); + if (ebda_sz == 0) + return -ENOMEM; + + io_mem = ioremap(ebda_seg<<4, (ebda_sz * 1024)); if (!io_mem ) return -ENOMEM; next_offset = 0x180; -- cgit v1.2.3 From 0bf01c3c86d4b9ea279d6215420484db887f5db5 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 20 Jan 2010 14:15:54 +0100 Subject: PCI: hotplug/cpcihp, fix pci device refcounting Stanse found an ommitted pci_dev_put on one error path in cpcihp_generic_init. The path is taken on !dev, but also when dev->hdr_type != PCI_HEADER_TYPE_BRIDGE. However it omits to pci_dev_put on the latter. As it is fine to pass NULL to pci_dev_put, put it in there uncoditionally. Signed-off-by: Jiri Slaby Cc: Scott Murray Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/cpcihp_generic.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c index 148fb463b81c..fb3f84661bdc 100644 --- a/drivers/pci/hotplug/cpcihp_generic.c +++ b/drivers/pci/hotplug/cpcihp_generic.c @@ -162,6 +162,7 @@ static int __init cpcihp_generic_init(void) dev = pci_get_slot(bus, PCI_DEVFN(bridge_slot, 0)); if(!dev || dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { err("Invalid bridge device %s", bridge); + pci_dev_put(dev); return -EINVAL; } bus = dev->subordinate; -- cgit v1.2.3 From 939fdc67350e15aeeea70457d5b4bc1116bb4fd5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 4 Feb 2010 12:12:23 -0800 Subject: PCI hotplug: fix ibmphp build error Add header file to fix build error: drivers/pci/hotplug/ibmphp_hpc.c:135: error: implicit declaration of function 'init_MUTEX' drivers/pci/hotplug/ibmphp_hpc.c:136: error: implicit declaration of function 'init_MUTEX_LOCKED' drivers/pci/hotplug/ibmphp_hpc.c:797: error: implicit declaration of function 'down' drivers/pci/hotplug/ibmphp_hpc.c:807: error: implicit declaration of function 'up' Signed-off-by: Randy Dunlap Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/ibmphp_hpc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index c7084f0eca5a..1aaf3f32d3cd 100644 --- a/drivers/pci/hotplug/ibmphp_hpc.c +++ b/drivers/pci/hotplug/ibmphp_hpc.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "ibmphp.h" -- cgit v1.2.3 From ba02b242bbf8e4e1bc63d62e8ccec33b4e5ea132 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 2 Feb 2010 14:45:54 -0800 Subject: PCI hotplug: check ioremap() return value in ibmphp_ebda.c check ioremap() return value. Cc: Signed-off-by: Andrew Morton Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/ibmphp_ebda.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 7d3bf31d224d..5becbdee4027 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c @@ -261,6 +261,8 @@ int __init ibmphp_access_ebda (void) debug ("returned ebda segment: %x\n", ebda_seg); io_mem = ioremap(ebda_seg<<4, 1); + if (!io_mem) + return -ENOMEM; ebda_sz = readb(io_mem); iounmap(io_mem); debug("ebda size: %d(KiB)\n", ebda_sz); -- cgit v1.2.3 From 9789ac979b6b6ae6cc09f7b29c88e95ecb14ec39 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Fri, 22 Jan 2010 01:02:26 -0800 Subject: PCI: pciehp: cleanup flow in pciehp_configure_device Move bus_size_bridges and assign resources out of pciehp_add_bridge() and do them all together, one time, including slot bridge, to avoid to calling assign resources several times when there are several bridges under the slot bridge. Using pci_assign_unassigned_bridge_resources. Signed-off-by: Yinghai Lu Reviewed-by: Alex Chiang Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/pciehp_pci.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 21733108adde..0a16444c14c9 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -53,17 +53,15 @@ static int __ref pciehp_add_bridge(struct pci_dev *dev) busnr = pci_scan_bridge(parent, dev, busnr, pass); if (!dev->subordinate) return -1; - pci_bus_size_bridges(dev->subordinate); - pci_bus_assign_resources(parent); - pci_enable_bridges(parent); - pci_bus_add_devices(parent); + return 0; } int pciehp_configure_device(struct slot *p_slot) { struct pci_dev *dev; - struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; + struct pci_dev *bridge = p_slot->ctrl->pcie->port; + struct pci_bus *parent = bridge->subordinate; int num, fn; struct controller *ctrl = p_slot->ctrl; @@ -96,12 +94,25 @@ int pciehp_configure_device(struct slot *p_slot) (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { pciehp_add_bridge(dev); } + pci_dev_put(dev); + } + + pci_assign_unassigned_bridge_resources(bridge); + + for (fn = 0; fn < 8; fn++) { + dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); + if (!dev) + continue; + if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { + pci_dev_put(dev); + continue; + } pci_configure_slot(dev); pci_dev_put(dev); } - pci_bus_assign_resources(parent); pci_bus_add_devices(parent); + return 0; } -- cgit v1.2.3 From 89a74ecccd1f78e51faf6287e5c0e93a92ac096e Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 23 Feb 2010 10:24:31 -0700 Subject: PCI: add pci_bus_for_each_resource(), remove direct bus->resource[] refs No functional change; this converts loops that iterate from 0 to PCI_BUS_NUM_RESOURCES through pci_bus resource[] table to use the pci_bus_for_each_resource() iterator instead. This doesn't change the way resources are stored; it merely removes dependencies on the fact that they're in a table. Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes --- arch/ia64/pci/pci.c | 5 ++--- arch/mn10300/unit-asb2305/pci.c | 6 ++---- arch/powerpc/kernel/pci-common.c | 11 ++++------- arch/powerpc/platforms/fsl_uli1575.c | 12 ++++++------ drivers/pci/bus.c | 4 ++-- drivers/pci/hotplug/shpchp_sysfs.c | 9 +++------ drivers/pci/pci.c | 5 ++--- drivers/pci/setup-bus.c | 10 ++++------ drivers/pcmcia/rsrc_nonstatic.c | 3 +-- drivers/pcmcia/yenta_socket.c | 5 +++-- include/linux/pci.h | 3 +++ 11 files changed, 32 insertions(+), 41 deletions(-) (limited to 'drivers/pci/hotplug') diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 783c83bb2b49..89f957ca3eb2 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -452,13 +452,12 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); static int __devinit is_valid_resource(struct pci_dev *dev, int idx) { unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; - struct resource *devr = &dev->resource[idx]; + struct resource *devr = &dev->resource[idx], *busr; if (!dev->bus) return 0; - for (i=0; ibus->resource[i]; + pci_bus_for_each_resource(dev->bus, busr, i) { if (!busr || ((busr->flags ^ devr->flags) & type_mask)) continue; if ((devr->start) && (devr->start >= busr->start) && diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index 2cb7e75ba1c0..6d8720a0a599 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c @@ -331,12 +331,10 @@ static int __init pci_check_direct(void) static int __devinit is_valid_resource(struct pci_dev *dev, int idx) { unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; - struct resource *devr = &dev->resource[idx]; + struct resource *devr = &dev->resource[idx], *busr; if (dev->bus) { - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - struct resource *busr = dev->bus->resource[i]; - + pci_bus_for_each_resource(dev->bus, busr, i) { if (!busr || (busr->flags ^ devr->flags) & type_mask) continue; diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index e640810e813f..2597f9545d8a 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1047,10 +1047,8 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) struct pci_dev *dev = bus->self; - for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { - if ((res = bus->resource[i]) == NULL) - continue; - if (!res->flags) + pci_bus_for_each_resource(bus, res, i) { + if (!res || !res->flags) continue; if (i >= 3 && bus->self->transparent) continue; @@ -1277,9 +1275,8 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) pr_debug("PCI: Allocating bus resources for %04x:%02x...\n", pci_domain_nr(bus), bus->number); - for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { - if ((res = bus->resource[i]) == NULL || !res->flags - || res->start > res->end || res->parent) + pci_bus_for_each_resource(bus, res, i) { + if (!res || !res->flags || res->start > res->end || res->parent) continue; if (bus->parent == NULL) pr = (res->flags & IORESOURCE_IO) ? diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c index fd23a1d4b39d..8b0c2082a783 100644 --- a/arch/powerpc/platforms/fsl_uli1575.c +++ b/arch/powerpc/platforms/fsl_uli1575.c @@ -222,6 +222,7 @@ static void __devinit quirk_final_uli5249(struct pci_dev *dev) int i; u8 *dummy; struct pci_bus *bus = dev->bus; + struct resource *res; resource_size_t end = 0; for (i = PCI_BRIDGE_RESOURCES; i < PCI_BRIDGE_RESOURCES+3; i++) { @@ -230,13 +231,12 @@ static void __devinit quirk_final_uli5249(struct pci_dev *dev) end = pci_resource_end(dev, i); } - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - if ((bus->resource[i]) && - (bus->resource[i]->flags & IORESOURCE_MEM)) { - if (bus->resource[i]->end == end) - dummy = ioremap(bus->resource[i]->start, 0x4); + pci_bus_for_each_resource(bus, res, i) { + if (res && res->flags & IORESOURCE_MEM) { + if (res->end == end) + dummy = ioremap(res->start, 0x4); else - dummy = ioremap(bus->resource[i]->end - 3, 0x4); + dummy = ioremap(res->end - 3, 0x4); if (dummy) { in_8(dummy); iounmap(dummy); diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index a26135bb0ffd..e75d219fd107 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -43,6 +43,7 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, void *alignf_data) { int i, ret = -ENOMEM; + struct resource *r; resource_size_t max = -1; type_mask |= IORESOURCE_IO | IORESOURCE_MEM; @@ -51,8 +52,7 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, if (!(res->flags & IORESOURCE_MEM_64)) max = PCIBIOS_MAX_MEM_32; - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - struct resource *r = bus->resource[i]; + pci_bus_for_each_resource(bus, r, i) { if (!r) continue; diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index 29fa9d26adae..071b7dc0094b 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c @@ -47,8 +47,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha bus = pdev->subordinate; out += sprintf(buf, "Free resources: memory\n"); - for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { - res = bus->resource[index]; + pci_bus_for_each_resource(bus, res, index) { if (res && (res->flags & IORESOURCE_MEM) && !(res->flags & IORESOURCE_PREFETCH)) { out += sprintf(out, "start = %8.8llx, " @@ -58,8 +57,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha } } out += sprintf(out, "Free resources: prefetchable memory\n"); - for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { - res = bus->resource[index]; + pci_bus_for_each_resource(bus, res, index) { if (res && (res->flags & IORESOURCE_MEM) && (res->flags & IORESOURCE_PREFETCH)) { out += sprintf(out, "start = %8.8llx, " @@ -69,8 +67,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha } } out += sprintf(out, "Free resources: IO\n"); - for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { - res = bus->resource[index]; + pci_bus_for_each_resource(bus, res, index) { if (res && (res->flags & IORESOURCE_IO)) { out += sprintf(out, "start = %8.8llx, " "length = %8.8llx\n", diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d62a5de81672..f4a2738bf0bf 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -386,10 +386,9 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) { const struct pci_bus *bus = dev->bus; int i; - struct resource *best = NULL; + struct resource *best = NULL, *r; - for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - struct resource *r = bus->resource[i]; + pci_bus_for_each_resource(bus, r, i) { if (!r) continue; if (res->start && !(res->start >= r->start && res->end <= r->end)) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 743ed8c48b9c..bf32f07c4efb 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -387,8 +387,7 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned lon unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH; - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - r = bus->resource[i]; + pci_bus_for_each_resource(bus, r, i) { if (r == &ioport_resource || r == &iomem_resource) continue; if (r && (r->flags & type_mask) == type && !r->parent) @@ -803,11 +802,10 @@ static void __ref pci_bus_release_bridge_resources(struct pci_bus *bus, static void pci_bus_dump_res(struct pci_bus *bus) { - int i; - - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - struct resource *res = bus->resource[i]; + struct resource *res; + int i; + pci_bus_for_each_resource(bus, res, i) { if (!res || !res->end || !res->flags) continue; diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 45d75dc452f0..c67638fe6914 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -803,8 +803,7 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) return -EINVAL; #endif - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - res = s->cb_dev->bus->resource[i]; + pci_bus_for_each_resource(s->cb_dev->bus, res, i) { if (!res) continue; diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index e4d12acdd525..1f2039d5e966 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -649,9 +649,10 @@ static int yenta_search_one_res(struct resource *root, struct resource *res, static int yenta_search_res(struct yenta_socket *socket, struct resource *res, u32 min) { + struct resource *root; int i; - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - struct resource *root = socket->dev->bus->resource[i]; + + pci_bus_for_each_resource(socket->dev->bus, root, i) { if (!root) continue; diff --git a/include/linux/pci.h b/include/linux/pci.h index 1a29f9f6b2dc..2ff9d26a078f 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -829,6 +829,9 @@ int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *); void pci_release_selected_regions(struct pci_dev *, int); /* drivers/pci/bus.c */ +#define pci_bus_for_each_resource(bus, res, i) \ + for (i = 0; res = bus->resource[i], i < PCI_BUS_NUM_RESOURCES; i++) + int __must_check pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, resource_size_t size, resource_size_t align, resource_size_t min, -- cgit v1.2.3