diff options
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/acpiphp.h | 14 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_core.c | 23 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 266 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_pci.c | 29 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_ctrl.c | 57 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_pci.c | 44 | ||||
-rw-r--r-- | drivers/pci/hotplug/sgi_hotplug.c | 63 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_pci.c | 36 |
9 files changed, 151 insertions, 383 deletions
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index a1afb5b39ad..b70ac00a117 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -79,7 +79,6 @@ struct acpiphp_bridge { /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ struct acpiphp_func *func; - int type; int nr_slots; u32 flags; @@ -146,10 +145,6 @@ struct acpiphp_attention_info /* PCI bus bridge HID */ #define ACPI_PCI_HOST_HID "PNP0A03" -/* PCI BRIDGE type */ -#define BRIDGE_TYPE_HOST 0 -#define BRIDGE_TYPE_P2P 1 - /* ACPI _STA method value (ignore bit 4; battery present) */ #define ACPI_STA_PRESENT (0x00000001) #define ACPI_STA_ENABLED (0x00000002) @@ -158,13 +153,7 @@ struct acpiphp_attention_info #define ACPI_STA_ALL (0x0000000f) /* bridge flags */ -#define BRIDGE_HAS_STA (0x00000001) -#define BRIDGE_HAS_EJ0 (0x00000002) -#define BRIDGE_HAS_HPP (0x00000004) -#define BRIDGE_HAS_PS0 (0x00000010) -#define BRIDGE_HAS_PS1 (0x00000020) -#define BRIDGE_HAS_PS2 (0x00000040) -#define BRIDGE_HAS_PS3 (0x00000080) +#define BRIDGE_HAS_EJ0 (0x00000001) /* slot flags */ @@ -193,7 +182,6 @@ extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); /* acpiphp_glue.c */ extern int acpiphp_glue_init (void); extern void acpiphp_glue_exit (void); -extern int acpiphp_get_num_slots (void); typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); extern int acpiphp_enable_slot (struct acpiphp_slot *slot); diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 96316b74969..c2fd3095701 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -50,7 +50,6 @@ bool acpiphp_debug; /* local variables */ -static int num_slots; static struct acpiphp_attention_info *attention_info; #define DRIVER_VERSION "0.5" @@ -272,25 +271,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) return 0; } -static int __init init_acpi(void) -{ - int retval; - - /* initialize internal data structure etc. */ - retval = acpiphp_glue_init(); - - /* read initial number of slots */ - if (!retval) { - num_slots = acpiphp_get_num_slots(); - if (num_slots == 0) { - acpiphp_glue_exit(); - retval = -ENODEV; - } - } - - return retval; -} - /** * release_slot - free up the memory used by a slot * @hotplug_slot: slot to free @@ -379,7 +359,8 @@ static int __init acpiphp_init(void) return 0; /* read all the ACPI info from the system */ - return init_acpi(); + /* initialize internal data structure etc. */ + return acpiphp_glue_init(); } diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index a951c22921d..270fdbadc19 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -325,8 +325,8 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) return; } - /* install notify handler */ - if (bridge->type != BRIDGE_TYPE_HOST) { + /* install notify handler for P2P bridges */ + if (!pci_is_root_bus(bridge->pci_bus)) { if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) { status = acpi_remove_notify_handler(bridge->func->handle, ACPI_SYSTEM_NOTIFY, @@ -369,27 +369,12 @@ static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge) { acpi_handle dummy_handle; + struct acpiphp_func *func; if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, - "_STA", &dummy_handle))) - bridge->flags |= BRIDGE_HAS_STA; - - if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, - "_EJ0", &dummy_handle))) + "_EJ0", &dummy_handle))) { bridge->flags |= BRIDGE_HAS_EJ0; - if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, - "_PS0", &dummy_handle))) - bridge->flags |= BRIDGE_HAS_PS0; - - if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, - "_PS3", &dummy_handle))) - bridge->flags |= BRIDGE_HAS_PS3; - - /* is this ejectable p2p bridge? */ - if (bridge->flags & BRIDGE_HAS_EJ0) { - struct acpiphp_func *func; - dbg("found ejectable p2p bridge\n"); /* make link between PCI bridge and PCI function */ @@ -412,7 +397,6 @@ static void add_host_bridge(struct acpi_pci_root *root) if (bridge == NULL) return; - bridge->type = BRIDGE_TYPE_HOST; bridge->handle = handle; bridge->pci_bus = root->bus; @@ -432,7 +416,6 @@ static void add_p2p_bridge(acpi_handle *handle) return; } - bridge->type = BRIDGE_TYPE_P2P; bridge->handle = handle; config_p2p_bridge_flags(bridge); @@ -543,13 +526,15 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) acpi_status status; acpi_handle handle = bridge->handle; - status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + if (!pci_is_root_bus(bridge->pci_bus)) { + status = acpi_remove_notify_handler(handle, + ACPI_SYSTEM_NOTIFY, handle_hotplug_event_bridge); - if (ACPI_FAILURE(status)) - err("failed to remove notify handler\n"); + if (ACPI_FAILURE(status)) + err("failed to remove notify handler\n"); + } - if ((bridge->type != BRIDGE_TYPE_HOST) && - ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) { + if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) { status = acpi_install_notify_handler(bridge->func->handle, ACPI_SYSTEM_NOTIFY, handle_hotplug_event_func, @@ -630,9 +615,6 @@ static void remove_bridge(struct acpi_pci_root *root) bridge = acpiphp_handle_to_bridge(handle); if (bridge) cleanup_bridge(bridge); - else - acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_bridge); } static int power_on_slot(struct acpiphp_slot *slot) @@ -793,6 +775,29 @@ static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) } } +static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev) +{ + struct acpiphp_func *func; + + if (!dev->subordinate) + return; + + /* quirk, or pcie could set it already */ + if (dev->is_hotplug_bridge) + return; + + if (PCI_SLOT(dev->devfn) != slot->device) + return; + + list_for_each_entry(func, &slot->funcs, sibling) { + if (PCI_FUNC(dev->devfn) == func->function) { + /* check if this bridge has ejectable slots */ + if ((detect_ejectable_slots(func->handle) > 0)) + dev->is_hotplug_bridge = 1; + break; + } + } +} /** * enable_device - enable, configure a slot * @slot: slot to be enabled @@ -812,6 +817,9 @@ static int __ref enable_device(struct acpiphp_slot *slot) if (slot->flags & SLOT_ENABLED) goto err_exit; + list_for_each_entry(func, &slot->funcs, sibling) + acpiphp_bus_add(func); + num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); if (num == 0) { /* Maybe only part of funcs are added. */ @@ -827,15 +835,14 @@ static int __ref enable_device(struct acpiphp_slot *slot) if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { max = pci_scan_bridge(bus, dev, max, pass); - if (pass && dev->subordinate) + if (pass && dev->subordinate) { + check_hotplug_bridge(slot, dev); pci_bus_size_bridges(dev->subordinate); + } } } } - list_for_each_entry(func, &slot->funcs, sibling) - acpiphp_bus_add(func); - pci_bus_assign_resources(bus); acpiphp_sanitize_bus(bus); acpiphp_set_hpp_values(bus); @@ -1093,70 +1100,11 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) } } -/* Program resources in newly inserted bridge */ -static int acpiphp_configure_bridge (acpi_handle handle) -{ - struct pci_bus *bus; - - if (acpi_is_root_bridge(handle)) { - struct acpi_pci_root *root = acpi_pci_find_root(handle); - bus = root->bus; - } else { - struct pci_dev *pdev = acpi_get_pci_dev(handle); - bus = pdev->subordinate; - pci_dev_put(pdev); - } - - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - acpiphp_sanitize_bus(bus); - acpiphp_set_hpp_values(bus); - pci_enable_bridges(bus); - return 0; -} - -static void handle_bridge_insertion(acpi_handle handle, u32 type) -{ - struct acpi_device *device; - - if ((type != ACPI_NOTIFY_BUS_CHECK) && - (type != ACPI_NOTIFY_DEVICE_CHECK)) { - err("unexpected notification type %d\n", type); - return; - } - - if (acpi_bus_scan(handle)) { - err("cannot add bridge to acpi list\n"); - return; - } - if (acpi_bus_get_device(handle, &device)) { - err("ACPI device object missing\n"); - return; - } - if (!acpiphp_configure_bridge(handle)) - add_bridge(handle); - else - err("cannot configure and start bridge\n"); - -} - /* * ACPI event handlers */ static acpi_status -count_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - int *count = (int *)context; - struct acpiphp_bridge *bridge; - - bridge = acpiphp_handle_to_bridge(handle); - if (bridge) - (*count)++; - return AE_OK ; -} - -static acpi_status check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) { struct acpiphp_bridge *bridge; @@ -1174,83 +1122,33 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK ; } -struct acpiphp_hp_work { - struct work_struct work; - acpi_handle handle; - u32 type; - void *context; -}; - -static void alloc_acpiphp_hp_work(acpi_handle handle, u32 type, - void *context, - void (*func)(struct work_struct *work)) -{ - struct acpiphp_hp_work *hp_work; - int ret; - - hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL); - if (!hp_work) - return; - - hp_work->handle = handle; - hp_work->type = type; - hp_work->context = context; - - INIT_WORK(&hp_work->work, func); - ret = queue_work(kacpi_hotplug_wq, &hp_work->work); - if (!ret) - kfree(hp_work); -} - static void _handle_hotplug_event_bridge(struct work_struct *work) { struct acpiphp_bridge *bridge; char objname[64]; struct acpi_buffer buffer = { .length = sizeof(objname), .pointer = objname }; - struct acpi_device *device; - int num_sub_bridges = 0; - struct acpiphp_hp_work *hp_work; + struct acpi_hp_work *hp_work; acpi_handle handle; u32 type; - hp_work = container_of(work, struct acpiphp_hp_work, work); + hp_work = container_of(work, struct acpi_hp_work, work); handle = hp_work->handle; type = hp_work->type; + bridge = (struct acpiphp_bridge *)hp_work->context; acpi_scan_lock_acquire(); - if (acpi_bus_get_device(handle, &device)) { - /* This bridge must have just been physically inserted */ - handle_bridge_insertion(handle, type); - goto out; - } - - bridge = acpiphp_handle_to_bridge(handle); - if (type == ACPI_NOTIFY_BUS_CHECK) { - acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX, - count_sub_bridges, NULL, &num_sub_bridges, NULL); - } - - if (!bridge && !num_sub_bridges) { - err("cannot get bridge info\n"); - goto out; - } - acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); switch (type) { case ACPI_NOTIFY_BUS_CHECK: /* bus re-enumerate */ dbg("%s: Bus check notify on %s\n", __func__, objname); - if (bridge) { - dbg("%s: re-enumerating slots under %s\n", - __func__, objname); - acpiphp_check_bridge(bridge); - } - if (num_sub_bridges) - acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, - ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL); + dbg("%s: re-enumerating slots under %s\n", __func__, objname); + acpiphp_check_bridge(bridge); + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, + ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL); break; case ACPI_NOTIFY_DEVICE_CHECK: @@ -1267,8 +1165,7 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) case ACPI_NOTIFY_EJECT_REQUEST: /* request device eject */ dbg("%s: Device eject notify on %s\n", __func__, objname); - if ((bridge->type != BRIDGE_TYPE_HOST) && - (bridge->flags & BRIDGE_HAS_EJ0)) { + if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) { struct acpiphp_slot *slot; slot = bridge->func->slot; if (!acpiphp_disable_slot(slot)) @@ -1296,7 +1193,6 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) break; } -out: acpi_scan_lock_release(); kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ } @@ -1320,8 +1216,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, * For now just re-add this work to the kacpi_hotplug_wq so we * don't deadlock on hotplug actions. */ - alloc_acpiphp_hp_work(handle, type, context, - _handle_hotplug_event_bridge); + alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); } static void _handle_hotplug_event_func(struct work_struct *work) @@ -1330,22 +1225,19 @@ static void _handle_hotplug_event_func(struct work_struct *work) char objname[64]; struct acpi_buffer buffer = { .length = sizeof(objname), .pointer = objname }; - struct acpiphp_hp_work *hp_work; + struct acpi_hp_work *hp_work; acpi_handle handle; u32 type; - void *context; - hp_work = container_of(work, struct acpiphp_hp_work, work); + hp_work = container_of(work, struct acpi_hp_work, work); handle = hp_work->handle; type = hp_work->type; - context = hp_work->context; - - acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); - - func = (struct acpiphp_func *)context; + func = (struct acpiphp_func *)hp_work->context; acpi_scan_lock_acquire(); + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); + switch (type) { case ACPI_NOTIFY_BUS_CHECK: /* bus re-enumerate */ @@ -1399,23 +1291,7 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, * For now just re-add this work to the kacpi_hotplug_wq so we * don't deadlock on hotplug actions. */ - alloc_acpiphp_hp_work(handle, type, context, - _handle_hotplug_event_func); -} - -static acpi_status -find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - int *count = (int *)context; - - if (!acpi_is_root_bridge(handle)) - return AE_OK; - - (*count)++; - acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_bridge, NULL); - - return AE_OK ; + alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func); } static struct acpi_pci_driver acpi_pci_hp_driver = { @@ -1428,15 +1304,7 @@ static struct acpi_pci_driver acpi_pci_hp_driver = { */ int __init acpiphp_glue_init(void) { - int num = 0; - - acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL); - - if (num <= 0) - return -1; - else - acpi_pci_register_driver(&acpi_pci_hp_driver); + acpi_pci_register_driver(&acpi_pci_hp_driver); return 0; } @@ -1452,28 +1320,6 @@ void acpiphp_glue_exit(void) acpi_pci_unregister_driver(&acpi_pci_hp_driver); } - -/** - * acpiphp_get_num_slots - count number of slots in a system - */ -int __init acpiphp_get_num_slots(void) -{ - struct acpiphp_bridge *bridge; - int num_slots = 0; - - list_for_each_entry(bridge, &bridge_list, list) { - dbg("Bus %04x:%02x has %d slot%s\n", - pci_domain_nr(bridge->pci_bus), - bridge->pci_bus->number, bridge->nr_slots, - bridge->nr_slots == 1 ? "" : "s"); - num_slots += bridge->nr_slots; - } - - dbg("Total %d slots\n", num_slots); - return num_slots; -} - - /** * acpiphp_enable_slot - power on slot * @slot: ACPI PHP slot diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index dcc75c78544..d8add34177f 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -252,8 +252,8 @@ int cpci_led_off(struct slot* slot) int __ref cpci_configure_slot(struct slot *slot) { + struct pci_dev *dev; struct pci_bus *parent; - int fn; dbg("%s - enter", __func__); @@ -282,18 +282,13 @@ int __ref cpci_configure_slot(struct slot *slot) } parent = slot->dev->bus; - for (fn = 0; fn < 8; fn++) { - struct pci_dev *dev; - - dev = pci_get_slot(parent, - PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); - if (!dev) + list_for_each_entry(dev, &parent->devices, bus_list) + if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn)) continue; if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) pci_hp_add_bridge(dev); - pci_dev_put(dev); - } + pci_assign_unassigned_bridge_resources(parent->self); @@ -305,8 +300,7 @@ int __ref cpci_configure_slot(struct slot *slot) int cpci_unconfigure_slot(struct slot* slot) { - int i; - struct pci_dev *dev; + struct pci_dev *dev, *temp; dbg("%s - enter", __func__); if (!slot->dev) { @@ -314,13 +308,12 @@ int cpci_unconfigure_slot(struct slot* slot) return -ENODEV; } - for (i = 0; i < 8; i++) { - dev = pci_get_slot(slot->bus, - PCI_DEVFN(PCI_SLOT(slot->devfn), i)); - if (dev) { - pci_stop_and_remove_bus_device(dev); - pci_dev_put(dev); - } + list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) { + if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn)) + continue; + pci_dev_get(dev); + pci_stop_and_remove_bus_device(dev); + pci_dev_put(dev); } pci_dev_put(slot->dev); slot->dev = NULL; diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 36112fe212d..d282019cda5 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -1900,8 +1900,7 @@ static void interrupt_event_handler(struct controller *ctrl) dbg("power fault\n"); } else { /* refresh notification */ - if (p_slot) - update_slot_info(ctrl, p_slot); + update_slot_info(ctrl, p_slot); } ctrl->event_queue[loop].event_type = 0; @@ -2520,44 +2519,28 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func /* If we have IO resources copy them and fill in the bridge's * IO range registers */ - if (io_node) { - memcpy(hold_IO_node, io_node, sizeof(struct pci_resource)); - io_node->next = NULL; + memcpy(hold_IO_node, io_node, sizeof(struct pci_resource)); + io_node->next = NULL; - /* set IO base and Limit registers */ - temp_byte = io_node->base >> 8; - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte); + /* set IO base and Limit registers */ + temp_byte = io_node->base >> 8; + rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte); - temp_byte = (io_node->base + io_node->length - 1) >> 8; - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte); - } else { - kfree(hold_IO_node); - hold_IO_node = NULL; - } - - /* If we have memory resources copy them and fill in the - * bridge's memory range registers. Otherwise, fill in the - * range registers with values that disable them. */ - if (mem_node) { - memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource)); - mem_node->next = NULL; - - /* set Mem base and Limit registers */ - temp_word = mem_node->base >> 16; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); + temp_byte = (io_node->base + io_node->length - 1) >> 8; + rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte); - temp_word = (mem_node->base + mem_node->length - 1) >> 16; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); - } else { - temp_word = 0xFFFF; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); + /* Copy the memory resources and fill in the bridge's memory + * range registers. + */ + memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource)); + mem_node->next = NULL; - temp_word = 0x0000; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); + /* set Mem base and Limit registers */ + temp_word = mem_node->base >> 16; + rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); - kfree(hold_mem_node); - hold_mem_node = NULL; - } + temp_word = (mem_node->base + mem_node->length - 1) >> 16; + rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource)); p_mem_node->next = NULL; @@ -2627,7 +2610,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func /* Return unused bus resources * First use the temporary node to store information for * the board */ - if (hold_bus_node && bus_node && temp_resources.bus_head) { + if (bus_node && temp_resources.bus_head) { hold_bus_node->length = bus_node->base - hold_bus_node->base; hold_bus_node->next = func->bus_head; @@ -2751,7 +2734,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func } /* If we have prefetchable memory space available and there * is some left at the end, return the unused portion */ - if (hold_p_mem_node && temp_resources.p_mem_head) { + if (temp_resources.p_mem_head) { p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head), &hold_p_mem_node, 0x100000); diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 939bd1d4b5b..7d72c5e2eba 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -293,7 +293,6 @@ static void pciehp_remove(struct pcie_device *dev) #ifdef CONFIG_PM static int pciehp_suspend (struct pcie_device *dev) { - dev_info(&dev->device, "%s ENTRY\n", __func__); return 0; } @@ -303,7 +302,6 @@ static int pciehp_resume (struct pcie_device *dev) struct slot *slot; u8 status; - dev_info(&dev->device, "%s ENTRY\n", __func__); ctrl = get_service_data(dev); /* reinitialize the chipset's event detection logic */ diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 09cecaf450c..aac7a40e4a4 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -39,7 +39,7 @@ int pciehp_configure_device(struct slot *p_slot) struct pci_dev *dev; struct pci_dev *bridge = p_slot->ctrl->pcie->port; struct pci_bus *parent = bridge->subordinate; - int num, fn; + int num; struct controller *ctrl = p_slot->ctrl; dev = pci_get_slot(parent, PCI_DEVFN(0, 0)); @@ -57,28 +57,18 @@ int pciehp_configure_device(struct slot *p_slot) return -ENODEV; } - for (fn = 0; fn < 8; fn++) { - dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); - if (!dev) - continue; + list_for_each_entry(dev, &parent->devices, bus_list) if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) pci_hp_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) + list_for_each_entry(dev, &parent->devices, bus_list) { + if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) continue; - if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { - pci_dev_put(dev); - continue; - } + pci_configure_slot(dev); - pci_dev_put(dev); } pci_bus_add_devices(parent); @@ -89,9 +79,9 @@ int pciehp_configure_device(struct slot *p_slot) int pciehp_unconfigure_device(struct slot *p_slot) { int ret, rc = 0; - int j; u8 bctl = 0; u8 presence = 0; + struct pci_dev *dev, *temp; struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; u16 command; struct controller *ctrl = p_slot->ctrl; @@ -102,33 +92,31 @@ int pciehp_unconfigure_device(struct slot *p_slot) if (ret) presence = 0; - for (j = 0; j < 8; j++) { - struct pci_dev *temp = pci_get_slot(parent, PCI_DEVFN(0, j)); - if (!temp) - continue; - if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { - pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); + list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) { + pci_dev_get(dev); + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { + pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl); if (bctl & PCI_BRIDGE_CTL_VGA) { ctrl_err(ctrl, "Cannot remove display device %s\n", - pci_name(temp)); - pci_dev_put(temp); + pci_name(dev)); + pci_dev_put(dev); rc = -EINVAL; break; } } - pci_stop_and_remove_bus_device(temp); + pci_stop_and_remove_bus_device(dev); /* * Ensure that no new Requests will be generated from * the device. */ if (presence) { - pci_read_config_word(temp, PCI_COMMAND, &command); + pci_read_config_word(dev, PCI_COMMAND, &command); command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR); command |= PCI_COMMAND_INTX_DISABLE; - pci_write_config_word(temp, PCI_COMMAND, command); + pci_write_config_word(dev, PCI_COMMAND, command); } - pci_dev_put(temp); + pci_dev_put(dev); } return rc; diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index 574421bc2fa..b2781dfe60e 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -334,7 +334,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) struct slot *slot = bss_hotplug_slot->private; struct pci_bus *new_bus = NULL; struct pci_dev *dev; - int func, num_funcs; + int num_funcs; int new_ppb = 0; int rc; char *ssdt = NULL; @@ -381,29 +381,26 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) * to the Linux PCI interface and tell the drivers * about them. */ - for (func = 0; func < num_funcs; func++) { - dev = pci_get_slot(slot->pci_bus, - PCI_DEVFN(slot->device_num + 1, - PCI_FUNC(func))); - if (dev) { - /* Need to do slot fixup on PPB before fixup of children - * (PPB's pcidev_info needs to be in pcidev_info list - * before child's SN_PCIDEV_INFO() call to setup - * pdi_host_pcidev_info). - */ - pcibios_fixup_device_resources(dev); - if (SN_ACPI_BASE_SUPPORT()) - sn_acpi_slot_fixup(dev); - else - sn_io_slot_fixup(dev); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - pci_hp_add_bridge(dev); - if (dev->subordinate) { - new_bus = dev->subordinate; - new_ppb = 1; - } + list_for_each_entry(dev, &slot->pci_bus->devices, bus_list) { + if (PCI_SLOT(dev->devfn) != slot->device_num + 1) + continue; + + /* Need to do slot fixup on PPB before fixup of children + * (PPB's pcidev_info needs to be in pcidev_info list + * before child's SN_PCIDEV_INFO() call to setup + * pdi_host_pcidev_info). + */ + pcibios_fixup_device_resources(dev); + if (SN_ACPI_BASE_SUPPORT()) + sn_acpi_slot_fixup(dev); + else + sn_io_slot_fixup(dev); + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + pci_hp_add_bridge(dev); + if (dev->subordinate) { + new_bus = dev->subordinate; + new_ppb = 1; } - pci_dev_put(dev); } } @@ -483,8 +480,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) static int disable_slot(struct hotplug_slot *bss_hotplug_slot) { struct slot *slot = bss_hotplug_slot->private; - struct pci_dev *dev; - int func; + struct pci_dev *dev, *temp; int rc; acpi_owner_id ssdt_id = 0; @@ -545,15 +541,14 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) } /* Free the SN resources assigned to the Linux device.*/ - for (func = 0; func < 8; func++) { - dev = pci_get_slot(slot->pci_bus, - PCI_DEVFN(slot->device_num + 1, - PCI_FUNC(func))); - if (dev) { - sn_bus_free_data(dev); - pci_stop_and_remove_bus_device(dev); - pci_dev_put(dev); - } + list_for_each_entry_safe(dev, temp, &slot->pci_bus->devices, bus_list) { + if (PCI_SLOT(dev->devfn) != slot->device_num + 1) + continue; + + pci_dev_get(dev); + sn_bus_free_data(dev); + pci_stop_and_remove_bus_device(dev); + pci_dev_put(dev); } /* Remove the SSDT for the slot from the ACPI namespace */ diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index c627ed9957d..b0e83132542 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -40,7 +40,7 @@ int __ref shpchp_configure_device(struct slot *p_slot) struct controller *ctrl = p_slot->ctrl; struct pci_dev *bridge = ctrl->pci_dev; struct pci_bus *parent = bridge->subordinate; - int num, fn; + int num; dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); if (dev) { @@ -57,24 +57,20 @@ int __ref shpchp_configure_device(struct slot *p_slot) return -ENODEV; } - for (fn = 0; fn < 8; fn++) { - dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); - if (!dev) + list_for_each_entry(dev, &parent->devices, bus_list) { + if (PCI_SLOT(dev->devfn) != p_slot->device) continue; if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) pci_hp_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(p_slot->device, fn)); - if (!dev) + list_for_each_entry(dev, &parent->devices, bus_list) { + if (PCI_SLOT(dev->devfn) != p_slot->device) continue; pci_configure_slot(dev); - pci_dev_put(dev); } pci_bus_add_devices(parent); @@ -85,32 +81,32 @@ int __ref shpchp_configure_device(struct slot *p_slot) int shpchp_unconfigure_device(struct slot *p_slot) { int rc = 0; - int j; u8 bctl = 0; struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; + struct pci_dev *dev, *temp; struct controller *ctrl = p_slot->ctrl; ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n", __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device); - for (j = 0; j < 8 ; j++) { - struct pci_dev *temp = pci_get_slot(parent, - (p_slot->device << 3) | j); - if (!temp) + list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) { + if (PCI_SLOT(dev->devfn) != p_slot->device) continue; - if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); + + pci_dev_get(dev); + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl); if (bctl & PCI_BRIDGE_CTL_VGA) { ctrl_err(ctrl, "Cannot remove display device %s\n", - pci_name(temp)); - pci_dev_put(temp); + pci_name(dev)); + pci_dev_put(dev); rc = -EINVAL; break; } } - pci_stop_and_remove_bus_device(temp); - pci_dev_put(temp); + pci_stop_and_remove_bus_device(dev); + pci_dev_put(dev); } return rc; } |