diff options
Diffstat (limited to 'drivers/pci')
37 files changed, 598 insertions, 796 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 8647dc6f52d0..748f8f3e9ff5 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
| @@ -202,20 +202,16 @@ void pci_bus_add_devices(const struct pci_bus *bus) | |||
| 202 | if (dev->is_added) | 202 | if (dev->is_added) |
| 203 | continue; | 203 | continue; |
| 204 | retval = pci_bus_add_device(dev); | 204 | retval = pci_bus_add_device(dev); |
| 205 | if (retval) | ||
| 206 | dev_err(&dev->dev, "Error adding device (%d)\n", | ||
| 207 | retval); | ||
| 205 | } | 208 | } |
| 206 | 209 | ||
| 207 | list_for_each_entry(dev, &bus->devices, bus_list) { | 210 | list_for_each_entry(dev, &bus->devices, bus_list) { |
| 208 | BUG_ON(!dev->is_added); | 211 | BUG_ON(!dev->is_added); |
| 209 | |||
| 210 | child = dev->subordinate; | 212 | child = dev->subordinate; |
| 211 | 213 | if (child) | |
| 212 | if (!child) | 214 | pci_bus_add_devices(child); |
| 213 | continue; | ||
| 214 | pci_bus_add_devices(child); | ||
| 215 | |||
| 216 | if (child->is_added) | ||
| 217 | continue; | ||
| 218 | child->is_added = 1; | ||
| 219 | } | 215 | } |
| 220 | } | 216 | } |
| 221 | 217 | ||
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index 13e9e63a7266..9fcb87f353d4 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig | |||
| @@ -52,15 +52,12 @@ config HOTPLUG_PCI_IBM | |||
| 52 | When in doubt, say N. | 52 | When in doubt, say N. |
| 53 | 53 | ||
| 54 | config HOTPLUG_PCI_ACPI | 54 | config HOTPLUG_PCI_ACPI |
| 55 | tristate "ACPI PCI Hotplug driver" | 55 | bool "ACPI PCI Hotplug driver" |
| 56 | depends on (!ACPI_DOCK && ACPI) || (ACPI_DOCK) | 56 | depends on HOTPLUG_PCI=y && ((!ACPI_DOCK && ACPI) || (ACPI_DOCK)) |
| 57 | help | 57 | help |
| 58 | Say Y here if you have a system that supports PCI Hotplug using | 58 | Say Y here if you have a system that supports PCI Hotplug using |
| 59 | ACPI. | 59 | ACPI. |
| 60 | 60 | ||
| 61 | To compile this driver as a module, choose M here: the | ||
| 62 | module will be called acpiphp. | ||
| 63 | |||
| 64 | When in doubt, say N. | 61 | When in doubt, say N. |
| 65 | 62 | ||
| 66 | config HOTPLUG_PCI_ACPI_IBM | 63 | config HOTPLUG_PCI_ACPI_IBM |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index b70ac00a117e..6fdd49c6f0b9 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
| @@ -73,8 +73,9 @@ static inline const char *slot_name(struct slot *slot) | |||
| 73 | */ | 73 | */ |
| 74 | struct acpiphp_bridge { | 74 | struct acpiphp_bridge { |
| 75 | struct list_head list; | 75 | struct list_head list; |
| 76 | struct list_head slots; | ||
| 77 | struct kref ref; | ||
| 76 | acpi_handle handle; | 78 | acpi_handle handle; |
| 77 | struct acpiphp_slot *slots; | ||
| 78 | 79 | ||
| 79 | /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ | 80 | /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ |
| 80 | struct acpiphp_func *func; | 81 | struct acpiphp_func *func; |
| @@ -97,7 +98,7 @@ struct acpiphp_bridge { | |||
| 97 | * PCI slot information for each *physical* PCI slot | 98 | * PCI slot information for each *physical* PCI slot |
| 98 | */ | 99 | */ |
| 99 | struct acpiphp_slot { | 100 | struct acpiphp_slot { |
| 100 | struct acpiphp_slot *next; | 101 | struct list_head node; |
| 101 | struct acpiphp_bridge *bridge; /* parent */ | 102 | struct acpiphp_bridge *bridge; /* parent */ |
| 102 | struct list_head funcs; /* one slot may have different | 103 | struct list_head funcs; /* one slot may have different |
| 103 | objects (i.e. for each function) */ | 104 | objects (i.e. for each function) */ |
| @@ -119,7 +120,6 @@ struct acpiphp_slot { | |||
| 119 | */ | 120 | */ |
| 120 | struct acpiphp_func { | 121 | struct acpiphp_func { |
| 121 | struct acpiphp_slot *slot; /* parent */ | 122 | struct acpiphp_slot *slot; /* parent */ |
| 122 | struct acpiphp_bridge *bridge; /* Ejectable PCI-to-PCI bridge */ | ||
| 123 | 123 | ||
| 124 | struct list_head sibling; | 124 | struct list_head sibling; |
| 125 | struct notifier_block nb; | 125 | struct notifier_block nb; |
| @@ -146,10 +146,6 @@ struct acpiphp_attention_info | |||
| 146 | #define ACPI_PCI_HOST_HID "PNP0A03" | 146 | #define ACPI_PCI_HOST_HID "PNP0A03" |
| 147 | 147 | ||
| 148 | /* ACPI _STA method value (ignore bit 4; battery present) */ | 148 | /* ACPI _STA method value (ignore bit 4; battery present) */ |
| 149 | #define ACPI_STA_PRESENT (0x00000001) | ||
| 150 | #define ACPI_STA_ENABLED (0x00000002) | ||
| 151 | #define ACPI_STA_SHOW_IN_UI (0x00000004) | ||
| 152 | #define ACPI_STA_FUNCTIONING (0x00000008) | ||
| 153 | #define ACPI_STA_ALL (0x0000000f) | 149 | #define ACPI_STA_ALL (0x0000000f) |
| 154 | 150 | ||
| 155 | /* bridge flags */ | 151 | /* bridge flags */ |
| @@ -174,25 +170,24 @@ struct acpiphp_attention_info | |||
| 174 | /* function prototypes */ | 170 | /* function prototypes */ |
| 175 | 171 | ||
| 176 | /* acpiphp_core.c */ | 172 | /* acpiphp_core.c */ |
| 177 | extern int acpiphp_register_attention(struct acpiphp_attention_info*info); | 173 | int acpiphp_register_attention(struct acpiphp_attention_info*info); |
| 178 | extern int acpiphp_unregister_attention(struct acpiphp_attention_info *info); | 174 | int acpiphp_unregister_attention(struct acpiphp_attention_info *info); |
| 179 | extern int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); | 175 | int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); |
| 180 | extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); | 176 | void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); |
| 181 | 177 | ||
| 182 | /* acpiphp_glue.c */ | 178 | /* acpiphp_glue.c */ |
| 183 | extern int acpiphp_glue_init (void); | ||
| 184 | extern void acpiphp_glue_exit (void); | ||
| 185 | typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); | 179 | typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); |
| 186 | 180 | ||
| 187 | extern int acpiphp_enable_slot (struct acpiphp_slot *slot); | 181 | int acpiphp_enable_slot(struct acpiphp_slot *slot); |
| 188 | extern int acpiphp_disable_slot (struct acpiphp_slot *slot); | 182 | int acpiphp_disable_slot(struct acpiphp_slot *slot); |
| 189 | extern int acpiphp_eject_slot (struct acpiphp_slot *slot); | 183 | int acpiphp_eject_slot(struct acpiphp_slot *slot); |
| 190 | extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot); | 184 | u8 acpiphp_get_power_status(struct acpiphp_slot *slot); |
| 191 | extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot); | 185 | u8 acpiphp_get_attention_status(struct acpiphp_slot *slot); |
| 192 | extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); | 186 | u8 acpiphp_get_latch_status(struct acpiphp_slot *slot); |
| 193 | extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); | 187 | u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot); |
| 194 | 188 | ||
| 195 | /* variables */ | 189 | /* variables */ |
| 196 | extern bool acpiphp_debug; | 190 | extern bool acpiphp_debug; |
| 191 | extern bool acpiphp_disabled; | ||
| 197 | 192 | ||
| 198 | #endif /* _ACPIPHP_H */ | 193 | #endif /* _ACPIPHP_H */ |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index c2fd3095701f..ca8127950fcd 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | #include <linux/kernel.h> | 38 | #include <linux/kernel.h> |
| 39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
| 40 | #include <linux/pci-acpi.h> | ||
| 40 | #include <linux/pci_hotplug.h> | 41 | #include <linux/pci_hotplug.h> |
| 41 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
| 42 | #include <linux/smp.h> | 43 | #include <linux/smp.h> |
| @@ -48,6 +49,7 @@ | |||
| 48 | #define SLOT_NAME_SIZE 21 /* {_SUN} */ | 49 | #define SLOT_NAME_SIZE 21 /* {_SUN} */ |
| 49 | 50 | ||
| 50 | bool acpiphp_debug; | 51 | bool acpiphp_debug; |
| 52 | bool acpiphp_disabled; | ||
| 51 | 53 | ||
| 52 | /* local variables */ | 54 | /* local variables */ |
| 53 | static struct acpiphp_attention_info *attention_info; | 55 | static struct acpiphp_attention_info *attention_info; |
| @@ -60,7 +62,9 @@ MODULE_AUTHOR(DRIVER_AUTHOR); | |||
| 60 | MODULE_DESCRIPTION(DRIVER_DESC); | 62 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 61 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
| 62 | MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); | 64 | MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); |
| 65 | MODULE_PARM_DESC(disable, "disable acpiphp driver"); | ||
| 63 | module_param_named(debug, acpiphp_debug, bool, 0644); | 66 | module_param_named(debug, acpiphp_debug, bool, 0644); |
| 67 | module_param_named(disable, acpiphp_disabled, bool, 0444); | ||
| 64 | 68 | ||
| 65 | /* export the attention callback registration methods */ | 69 | /* export the attention callback registration methods */ |
| 66 | EXPORT_SYMBOL_GPL(acpiphp_register_attention); | 70 | EXPORT_SYMBOL_GPL(acpiphp_register_attention); |
| @@ -351,27 +355,9 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot) | |||
| 351 | } | 355 | } |
| 352 | 356 | ||
| 353 | 357 | ||
| 354 | static int __init acpiphp_init(void) | 358 | void __init acpiphp_init(void) |
| 355 | { | 359 | { |
| 356 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); | 360 | info(DRIVER_DESC " version: " DRIVER_VERSION "%s\n", |
| 357 | 361 | acpiphp_disabled ? ", disabled by user; please report a bug" | |
| 358 | if (acpi_pci_disabled) | 362 | : ""); |
| 359 | return 0; | ||
| 360 | |||
| 361 | /* read all the ACPI info from the system */ | ||
| 362 | /* initialize internal data structure etc. */ | ||
| 363 | return acpiphp_glue_init(); | ||
| 364 | } | ||
| 365 | |||
| 366 | |||
| 367 | static void __exit acpiphp_exit(void) | ||
| 368 | { | ||
| 369 | if (acpi_pci_disabled) | ||
| 370 | return; | ||
| 371 | |||
| 372 | /* deallocate internal data structures etc. */ | ||
| 373 | acpiphp_glue_exit(); | ||
| 374 | } | 363 | } |
| 375 | |||
| 376 | module_init(acpiphp_init); | ||
| 377 | module_exit(acpiphp_exit); | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 270fdbadc19c..96fed19c6d90 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
| @@ -54,6 +54,7 @@ | |||
| 54 | #include "acpiphp.h" | 54 | #include "acpiphp.h" |
| 55 | 55 | ||
| 56 | static LIST_HEAD(bridge_list); | 56 | static LIST_HEAD(bridge_list); |
| 57 | static DEFINE_MUTEX(bridge_mutex); | ||
| 57 | 58 | ||
| 58 | #define MY_NAME "acpiphp_glue" | 59 | #define MY_NAME "acpiphp_glue" |
| 59 | 60 | ||
| @@ -61,6 +62,7 @@ static void handle_hotplug_event_bridge (acpi_handle, u32, void *); | |||
| 61 | static void acpiphp_sanitize_bus(struct pci_bus *bus); | 62 | static void acpiphp_sanitize_bus(struct pci_bus *bus); |
| 62 | static void acpiphp_set_hpp_values(struct pci_bus *bus); | 63 | static void acpiphp_set_hpp_values(struct pci_bus *bus); |
| 63 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); | 64 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); |
| 65 | static void free_bridge(struct kref *kref); | ||
| 64 | 66 | ||
| 65 | /* callback routine to check for the existence of a pci dock device */ | 67 | /* callback routine to check for the existence of a pci dock device */ |
| 66 | static acpi_status | 68 | static acpi_status |
| @@ -76,6 +78,39 @@ is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 76 | } | 78 | } |
| 77 | } | 79 | } |
| 78 | 80 | ||
| 81 | static inline void get_bridge(struct acpiphp_bridge *bridge) | ||
| 82 | { | ||
| 83 | kref_get(&bridge->ref); | ||
| 84 | } | ||
| 85 | |||
| 86 | static inline void put_bridge(struct acpiphp_bridge *bridge) | ||
| 87 | { | ||
| 88 | kref_put(&bridge->ref, free_bridge); | ||
| 89 | } | ||
| 90 | |||
| 91 | static void free_bridge(struct kref *kref) | ||
| 92 | { | ||
| 93 | struct acpiphp_bridge *bridge; | ||
| 94 | struct acpiphp_slot *slot, *next; | ||
| 95 | struct acpiphp_func *func, *tmp; | ||
| 96 | |||
| 97 | bridge = container_of(kref, struct acpiphp_bridge, ref); | ||
| 98 | |||
| 99 | list_for_each_entry_safe(slot, next, &bridge->slots, node) { | ||
| 100 | list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { | ||
| 101 | kfree(func); | ||
| 102 | } | ||
| 103 | kfree(slot); | ||
| 104 | } | ||
| 105 | |||
| 106 | /* Release reference acquired by acpiphp_bridge_handle_to_function() */ | ||
| 107 | if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) | ||
| 108 | put_bridge(bridge->func->slot->bridge); | ||
| 109 | put_device(&bridge->pci_bus->dev); | ||
| 110 | pci_dev_put(bridge->pci_dev); | ||
| 111 | kfree(bridge); | ||
| 112 | } | ||
| 113 | |||
| 79 | /* | 114 | /* |
| 80 | * the _DCK method can do funny things... and sometimes not | 115 | * the _DCK method can do funny things... and sometimes not |
| 81 | * hah-hah funny. | 116 | * hah-hah funny. |
| @@ -154,9 +189,10 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 154 | acpi_handle tmp; | 189 | acpi_handle tmp; |
| 155 | acpi_status status = AE_OK; | 190 | acpi_status status = AE_OK; |
| 156 | unsigned long long adr, sun; | 191 | unsigned long long adr, sun; |
| 157 | int device, function, retval; | 192 | int device, function, retval, found = 0; |
| 158 | struct pci_bus *pbus = bridge->pci_bus; | 193 | struct pci_bus *pbus = bridge->pci_bus; |
| 159 | struct pci_dev *pdev; | 194 | struct pci_dev *pdev; |
| 195 | u32 val; | ||
| 160 | 196 | ||
| 161 | if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) | 197 | if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) |
| 162 | return AE_OK; | 198 | return AE_OK; |
| @@ -170,7 +206,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 170 | device = (adr >> 16) & 0xffff; | 206 | device = (adr >> 16) & 0xffff; |
| 171 | function = adr & 0xffff; | 207 | function = adr & 0xffff; |
| 172 | 208 | ||
| 173 | pdev = pbus->self; | 209 | pdev = bridge->pci_dev; |
| 174 | if (pdev && device_is_managed_by_native_pciehp(pdev)) | 210 | if (pdev && device_is_managed_by_native_pciehp(pdev)) |
| 175 | return AE_OK; | 211 | return AE_OK; |
| 176 | 212 | ||
| @@ -178,7 +214,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 178 | if (!newfunc) | 214 | if (!newfunc) |
| 179 | return AE_NO_MEMORY; | 215 | return AE_NO_MEMORY; |
| 180 | 216 | ||
| 181 | INIT_LIST_HEAD(&newfunc->sibling); | ||
| 182 | newfunc->handle = handle; | 217 | newfunc->handle = handle; |
| 183 | newfunc->function = function; | 218 | newfunc->function = function; |
| 184 | 219 | ||
| @@ -207,14 +242,15 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 207 | } | 242 | } |
| 208 | 243 | ||
| 209 | /* search for objects that share the same slot */ | 244 | /* search for objects that share the same slot */ |
| 210 | for (slot = bridge->slots; slot; slot = slot->next) | 245 | list_for_each_entry(slot, &bridge->slots, node) |
| 211 | if (slot->device == device) { | 246 | if (slot->device == device) { |
| 212 | if (slot->sun != sun) | 247 | if (slot->sun != sun) |
| 213 | warn("sibling found, but _SUN doesn't match!\n"); | 248 | warn("sibling found, but _SUN doesn't match!\n"); |
| 249 | found = 1; | ||
| 214 | break; | 250 | break; |
| 215 | } | 251 | } |
| 216 | 252 | ||
| 217 | if (!slot) { | 253 | if (!found) { |
| 218 | slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); | 254 | slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); |
| 219 | if (!slot) { | 255 | if (!slot) { |
| 220 | kfree(newfunc); | 256 | kfree(newfunc); |
| @@ -227,9 +263,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 227 | INIT_LIST_HEAD(&slot->funcs); | 263 | INIT_LIST_HEAD(&slot->funcs); |
| 228 | mutex_init(&slot->crit_sect); | 264 | mutex_init(&slot->crit_sect); |
| 229 | 265 | ||
| 230 | slot->next = bridge->slots; | 266 | mutex_lock(&bridge_mutex); |
| 231 | bridge->slots = slot; | 267 | list_add_tail(&slot->node, &bridge->slots); |
| 232 | 268 | mutex_unlock(&bridge_mutex); | |
| 233 | bridge->nr_slots++; | 269 | bridge->nr_slots++; |
| 234 | 270 | ||
| 235 | dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", | 271 | dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", |
| @@ -247,13 +283,13 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 247 | } | 283 | } |
| 248 | 284 | ||
| 249 | newfunc->slot = slot; | 285 | newfunc->slot = slot; |
| 286 | mutex_lock(&bridge_mutex); | ||
| 250 | list_add_tail(&newfunc->sibling, &slot->funcs); | 287 | list_add_tail(&newfunc->sibling, &slot->funcs); |
| 288 | mutex_unlock(&bridge_mutex); | ||
| 251 | 289 | ||
| 252 | pdev = pci_get_slot(pbus, PCI_DEVFN(device, function)); | 290 | if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function), |
| 253 | if (pdev) { | 291 | &val, 60*1000)) |
| 254 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); | 292 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); |
| 255 | pci_dev_put(pdev); | ||
| 256 | } | ||
| 257 | 293 | ||
| 258 | if (is_dock_device(handle)) { | 294 | if (is_dock_device(handle)) { |
| 259 | /* we don't want to call this device's _EJ0 | 295 | /* we don't want to call this device's _EJ0 |
| @@ -290,7 +326,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 290 | 326 | ||
| 291 | err_exit: | 327 | err_exit: |
| 292 | bridge->nr_slots--; | 328 | bridge->nr_slots--; |
| 293 | bridge->slots = slot->next; | 329 | mutex_lock(&bridge_mutex); |
| 330 | list_del(&slot->node); | ||
| 331 | mutex_unlock(&bridge_mutex); | ||
| 294 | kfree(slot); | 332 | kfree(slot); |
| 295 | kfree(newfunc); | 333 | kfree(newfunc); |
| 296 | 334 | ||
| @@ -315,13 +353,17 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) | |||
| 315 | acpi_status status; | 353 | acpi_status status; |
| 316 | 354 | ||
| 317 | /* must be added to the list prior to calling register_slot */ | 355 | /* must be added to the list prior to calling register_slot */ |
| 356 | mutex_lock(&bridge_mutex); | ||
| 318 | list_add(&bridge->list, &bridge_list); | 357 | list_add(&bridge->list, &bridge_list); |
| 358 | mutex_unlock(&bridge_mutex); | ||
| 319 | 359 | ||
| 320 | /* register all slot objects under this bridge */ | 360 | /* register all slot objects under this bridge */ |
| 321 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, | 361 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, |
| 322 | register_slot, NULL, bridge, NULL); | 362 | register_slot, NULL, bridge, NULL); |
| 323 | if (ACPI_FAILURE(status)) { | 363 | if (ACPI_FAILURE(status)) { |
| 364 | mutex_lock(&bridge_mutex); | ||
| 324 | list_del(&bridge->list); | 365 | list_del(&bridge->list); |
| 366 | mutex_unlock(&bridge_mutex); | ||
| 325 | return; | 367 | return; |
| 326 | } | 368 | } |
| 327 | 369 | ||
| @@ -351,178 +393,46 @@ static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle | |||
| 351 | { | 393 | { |
| 352 | struct acpiphp_bridge *bridge; | 394 | struct acpiphp_bridge *bridge; |
| 353 | struct acpiphp_slot *slot; | 395 | struct acpiphp_slot *slot; |
| 354 | struct acpiphp_func *func; | 396 | struct acpiphp_func *func = NULL; |
| 355 | 397 | ||
| 398 | mutex_lock(&bridge_mutex); | ||
| 356 | list_for_each_entry(bridge, &bridge_list, list) { | 399 | list_for_each_entry(bridge, &bridge_list, list) { |
| 357 | for (slot = bridge->slots; slot; slot = slot->next) { | 400 | list_for_each_entry(slot, &bridge->slots, node) { |
| 358 | list_for_each_entry(func, &slot->funcs, sibling) { | 401 | list_for_each_entry(func, &slot->funcs, sibling) { |
| 359 | if (func->handle == handle) | 402 | if (func->handle == handle) { |
| 403 | get_bridge(func->slot->bridge); | ||
| 404 | mutex_unlock(&bridge_mutex); | ||
| 360 | return func; | 405 | return func; |
| 406 | } | ||
| 361 | } | 407 | } |
| 362 | } | 408 | } |
| 363 | } | 409 | } |
| 410 | mutex_unlock(&bridge_mutex); | ||
| 364 | 411 | ||
| 365 | return NULL; | 412 | return NULL; |
| 366 | } | 413 | } |
| 367 | 414 | ||
| 368 | 415 | ||
| 369 | static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge) | ||
| 370 | { | ||
| 371 | acpi_handle dummy_handle; | ||
| 372 | struct acpiphp_func *func; | ||
| 373 | |||
| 374 | if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, | ||
| 375 | "_EJ0", &dummy_handle))) { | ||
| 376 | bridge->flags |= BRIDGE_HAS_EJ0; | ||
| 377 | |||
| 378 | dbg("found ejectable p2p bridge\n"); | ||
| 379 | |||
| 380 | /* make link between PCI bridge and PCI function */ | ||
| 381 | func = acpiphp_bridge_handle_to_function(bridge->handle); | ||
| 382 | if (!func) | ||
| 383 | return; | ||
| 384 | bridge->func = func; | ||
| 385 | func->bridge = bridge; | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | |||
| 390 | /* allocate and initialize host bridge data structure */ | ||
| 391 | static void add_host_bridge(struct acpi_pci_root *root) | ||
| 392 | { | ||
| 393 | struct acpiphp_bridge *bridge; | ||
| 394 | acpi_handle handle = root->device->handle; | ||
| 395 | |||
| 396 | bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); | ||
| 397 | if (bridge == NULL) | ||
| 398 | return; | ||
| 399 | |||
| 400 | bridge->handle = handle; | ||
| 401 | |||
| 402 | bridge->pci_bus = root->bus; | ||
| 403 | |||
| 404 | init_bridge_misc(bridge); | ||
| 405 | } | ||
| 406 | |||
| 407 | |||
| 408 | /* allocate and initialize PCI-to-PCI bridge data structure */ | ||
| 409 | static void add_p2p_bridge(acpi_handle *handle) | ||
| 410 | { | ||
| 411 | struct acpiphp_bridge *bridge; | ||
| 412 | |||
| 413 | bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); | ||
| 414 | if (bridge == NULL) { | ||
| 415 | err("out of memory\n"); | ||
| 416 | return; | ||
| 417 | } | ||
| 418 | |||
| 419 | bridge->handle = handle; | ||
| 420 | config_p2p_bridge_flags(bridge); | ||
| 421 | |||
| 422 | bridge->pci_dev = acpi_get_pci_dev(handle); | ||
| 423 | bridge->pci_bus = bridge->pci_dev->subordinate; | ||
| 424 | if (!bridge->pci_bus) { | ||
| 425 | err("This is not a PCI-to-PCI bridge!\n"); | ||
| 426 | goto err; | ||
| 427 | } | ||
| 428 | |||
| 429 | /* | ||
| 430 | * Grab a ref to the subordinate PCI bus in case the bus is | ||
| 431 | * removed via PCI core logical hotplug. The ref pins the bus | ||
| 432 | * (which we access during module unload). | ||
| 433 | */ | ||
| 434 | get_device(&bridge->pci_bus->dev); | ||
| 435 | |||
| 436 | init_bridge_misc(bridge); | ||
| 437 | return; | ||
| 438 | err: | ||
| 439 | pci_dev_put(bridge->pci_dev); | ||
| 440 | kfree(bridge); | ||
| 441 | return; | ||
| 442 | } | ||
| 443 | |||
| 444 | |||
| 445 | /* callback routine to find P2P bridges */ | ||
| 446 | static acpi_status | ||
| 447 | find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
| 448 | { | ||
| 449 | acpi_status status; | ||
| 450 | struct pci_dev *dev; | ||
| 451 | |||
| 452 | dev = acpi_get_pci_dev(handle); | ||
| 453 | if (!dev || !dev->subordinate) | ||
| 454 | goto out; | ||
| 455 | |||
| 456 | /* check if this bridge has ejectable slots */ | ||
| 457 | if ((detect_ejectable_slots(handle) > 0)) { | ||
| 458 | dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); | ||
| 459 | add_p2p_bridge(handle); | ||
| 460 | } | ||
| 461 | |||
| 462 | /* search P2P bridges under this p2p bridge */ | ||
| 463 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
| 464 | find_p2p_bridge, NULL, NULL, NULL); | ||
| 465 | if (ACPI_FAILURE(status)) | ||
| 466 | warn("find_p2p_bridge failed (error code = 0x%x)\n", status); | ||
| 467 | |||
| 468 | out: | ||
| 469 | pci_dev_put(dev); | ||
| 470 | return AE_OK; | ||
| 471 | } | ||
| 472 | |||
| 473 | |||
| 474 | /* find hot-pluggable slots, and then find P2P bridge */ | ||
| 475 | static int add_bridge(struct acpi_pci_root *root) | ||
| 476 | { | ||
| 477 | acpi_status status; | ||
| 478 | unsigned long long tmp; | ||
| 479 | acpi_handle dummy_handle; | ||
| 480 | acpi_handle handle = root->device->handle; | ||
| 481 | |||
| 482 | /* if the bridge doesn't have _STA, we assume it is always there */ | ||
| 483 | status = acpi_get_handle(handle, "_STA", &dummy_handle); | ||
| 484 | if (ACPI_SUCCESS(status)) { | ||
| 485 | status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp); | ||
| 486 | if (ACPI_FAILURE(status)) { | ||
| 487 | dbg("%s: _STA evaluation failure\n", __func__); | ||
| 488 | return 0; | ||
| 489 | } | ||
| 490 | if ((tmp & ACPI_STA_FUNCTIONING) == 0) | ||
| 491 | /* don't register this object */ | ||
| 492 | return 0; | ||
| 493 | } | ||
| 494 | |||
| 495 | /* check if this bridge has ejectable slots */ | ||
| 496 | if (detect_ejectable_slots(handle) > 0) { | ||
| 497 | dbg("found PCI host-bus bridge with hot-pluggable slots\n"); | ||
| 498 | add_host_bridge(root); | ||
| 499 | } | ||
| 500 | |||
| 501 | /* search P2P bridges under this host bridge */ | ||
| 502 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
| 503 | find_p2p_bridge, NULL, NULL, NULL); | ||
| 504 | |||
| 505 | if (ACPI_FAILURE(status)) | ||
| 506 | warn("find_p2p_bridge failed (error code = 0x%x)\n", status); | ||
| 507 | |||
| 508 | return 0; | ||
| 509 | } | ||
| 510 | |||
| 511 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) | 416 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) |
| 512 | { | 417 | { |
| 513 | struct acpiphp_bridge *bridge; | 418 | struct acpiphp_bridge *bridge; |
| 514 | 419 | ||
| 420 | mutex_lock(&bridge_mutex); | ||
| 515 | list_for_each_entry(bridge, &bridge_list, list) | 421 | list_for_each_entry(bridge, &bridge_list, list) |
| 516 | if (bridge->handle == handle) | 422 | if (bridge->handle == handle) { |
| 423 | get_bridge(bridge); | ||
| 424 | mutex_unlock(&bridge_mutex); | ||
| 517 | return bridge; | 425 | return bridge; |
| 426 | } | ||
| 427 | mutex_unlock(&bridge_mutex); | ||
| 518 | 428 | ||
| 519 | return NULL; | 429 | return NULL; |
| 520 | } | 430 | } |
| 521 | 431 | ||
| 522 | static void cleanup_bridge(struct acpiphp_bridge *bridge) | 432 | static void cleanup_bridge(struct acpiphp_bridge *bridge) |
| 523 | { | 433 | { |
| 524 | struct acpiphp_slot *slot, *next; | 434 | struct acpiphp_slot *slot; |
| 525 | struct acpiphp_func *func, *tmp; | 435 | struct acpiphp_func *func; |
| 526 | acpi_status status; | 436 | acpi_status status; |
| 527 | acpi_handle handle = bridge->handle; | 437 | acpi_handle handle = bridge->handle; |
| 528 | 438 | ||
| @@ -543,10 +453,8 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
| 543 | err("failed to install interrupt notify handler\n"); | 453 | err("failed to install interrupt notify handler\n"); |
| 544 | } | 454 | } |
| 545 | 455 | ||
| 546 | slot = bridge->slots; | 456 | list_for_each_entry(slot, &bridge->slots, node) { |
| 547 | while (slot) { | 457 | list_for_each_entry(func, &slot->funcs, sibling) { |
| 548 | next = slot->next; | ||
| 549 | list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { | ||
| 550 | if (is_dock_device(func->handle)) { | 458 | if (is_dock_device(func->handle)) { |
| 551 | unregister_hotplug_dock_device(func->handle); | 459 | unregister_hotplug_dock_device(func->handle); |
| 552 | unregister_dock_notifier(&func->nb); | 460 | unregister_dock_notifier(&func->nb); |
| @@ -558,63 +466,13 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
| 558 | if (ACPI_FAILURE(status)) | 466 | if (ACPI_FAILURE(status)) |
| 559 | err("failed to remove notify handler\n"); | 467 | err("failed to remove notify handler\n"); |
| 560 | } | 468 | } |
| 561 | list_del(&func->sibling); | ||
| 562 | kfree(func); | ||
| 563 | } | 469 | } |
| 564 | acpiphp_unregister_hotplug_slot(slot); | 470 | acpiphp_unregister_hotplug_slot(slot); |
| 565 | list_del(&slot->funcs); | ||
| 566 | kfree(slot); | ||
| 567 | slot = next; | ||
| 568 | } | 471 | } |
| 569 | 472 | ||
| 570 | /* | 473 | mutex_lock(&bridge_mutex); |
| 571 | * Only P2P bridges have a pci_dev | ||
| 572 | */ | ||
| 573 | if (bridge->pci_dev) | ||
| 574 | put_device(&bridge->pci_bus->dev); | ||
| 575 | |||
| 576 | pci_dev_put(bridge->pci_dev); | ||
| 577 | list_del(&bridge->list); | 474 | list_del(&bridge->list); |
| 578 | kfree(bridge); | 475 | mutex_unlock(&bridge_mutex); |
| 579 | } | ||
| 580 | |||
| 581 | static acpi_status | ||
| 582 | cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
| 583 | { | ||
| 584 | struct acpiphp_bridge *bridge; | ||
| 585 | |||
| 586 | /* cleanup p2p bridges under this P2P bridge | ||
| 587 | in a depth-first manner */ | ||
| 588 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
| 589 | cleanup_p2p_bridge, NULL, NULL, NULL); | ||
| 590 | |||
| 591 | bridge = acpiphp_handle_to_bridge(handle); | ||
| 592 | if (bridge) | ||
| 593 | cleanup_bridge(bridge); | ||
| 594 | |||
| 595 | return AE_OK; | ||
| 596 | } | ||
| 597 | |||
| 598 | static void remove_bridge(struct acpi_pci_root *root) | ||
| 599 | { | ||
| 600 | struct acpiphp_bridge *bridge; | ||
| 601 | acpi_handle handle = root->device->handle; | ||
| 602 | |||
| 603 | /* cleanup p2p bridges under this host bridge | ||
| 604 | in a depth-first manner */ | ||
| 605 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
| 606 | (u32)1, cleanup_p2p_bridge, NULL, NULL, NULL); | ||
| 607 | |||
| 608 | /* | ||
| 609 | * On root bridges with hotplug slots directly underneath (ie, | ||
| 610 | * no p2p bridge between), we call cleanup_bridge(). | ||
| 611 | * | ||
| 612 | * The else clause cleans up root bridges that either had no | ||
| 613 | * hotplug slots at all, or had a p2p bridge underneath. | ||
| 614 | */ | ||
| 615 | bridge = acpiphp_handle_to_bridge(handle); | ||
| 616 | if (bridge) | ||
| 617 | cleanup_bridge(bridge); | ||
| 618 | } | 476 | } |
| 619 | 477 | ||
| 620 | static int power_on_slot(struct acpiphp_slot *slot) | 478 | static int power_on_slot(struct acpiphp_slot *slot) |
| @@ -798,6 +656,7 @@ static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev) | |||
| 798 | } | 656 | } |
| 799 | } | 657 | } |
| 800 | } | 658 | } |
| 659 | |||
| 801 | /** | 660 | /** |
| 802 | * enable_device - enable, configure a slot | 661 | * enable_device - enable, configure a slot |
| 803 | * @slot: slot to be enabled | 662 | * @slot: slot to be enabled |
| @@ -810,9 +669,7 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
| 810 | struct pci_dev *dev; | 669 | struct pci_dev *dev; |
| 811 | struct pci_bus *bus = slot->bridge->pci_bus; | 670 | struct pci_bus *bus = slot->bridge->pci_bus; |
| 812 | struct acpiphp_func *func; | 671 | struct acpiphp_func *func; |
| 813 | int retval = 0; | ||
| 814 | int num, max, pass; | 672 | int num, max, pass; |
| 815 | acpi_status status; | ||
| 816 | 673 | ||
| 817 | if (slot->flags & SLOT_ENABLED) | 674 | if (slot->flags & SLOT_ENABLED) |
| 818 | goto err_exit; | 675 | goto err_exit; |
| @@ -867,23 +724,11 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
| 867 | slot->flags &= (~SLOT_ENABLED); | 724 | slot->flags &= (~SLOT_ENABLED); |
| 868 | continue; | 725 | continue; |
| 869 | } | 726 | } |
| 870 | |||
| 871 | if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && | ||
| 872 | dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) { | ||
| 873 | pci_dev_put(dev); | ||
| 874 | continue; | ||
| 875 | } | ||
| 876 | |||
| 877 | status = find_p2p_bridge(func->handle, (u32)1, bus, NULL); | ||
| 878 | if (ACPI_FAILURE(status)) | ||
| 879 | warn("find_p2p_bridge failed (error code = 0x%x)\n", | ||
| 880 | status); | ||
| 881 | pci_dev_put(dev); | ||
| 882 | } | 727 | } |
| 883 | 728 | ||
| 884 | 729 | ||
| 885 | err_exit: | 730 | err_exit: |
| 886 | return retval; | 731 | return 0; |
| 887 | } | 732 | } |
| 888 | 733 | ||
| 889 | /* return first device in slot, acquiring a reference on it */ | 734 | /* return first device in slot, acquiring a reference on it */ |
| @@ -912,23 +757,6 @@ static int disable_device(struct acpiphp_slot *slot) | |||
| 912 | { | 757 | { |
| 913 | struct acpiphp_func *func; | 758 | struct acpiphp_func *func; |
| 914 | struct pci_dev *pdev; | 759 | struct pci_dev *pdev; |
| 915 | struct pci_bus *bus = slot->bridge->pci_bus; | ||
| 916 | |||
| 917 | /* The slot will be enabled when func 0 is added, so check | ||
| 918 | func 0 before disable the slot. */ | ||
| 919 | pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); | ||
| 920 | if (!pdev) | ||
| 921 | goto err_exit; | ||
| 922 | pci_dev_put(pdev); | ||
| 923 | |||
| 924 | list_for_each_entry(func, &slot->funcs, sibling) { | ||
| 925 | if (func->bridge) { | ||
| 926 | /* cleanup p2p bridges under this P2P bridge */ | ||
| 927 | cleanup_p2p_bridge(func->bridge->handle, | ||
| 928 | (u32)1, NULL, NULL); | ||
| 929 | func->bridge = NULL; | ||
| 930 | } | ||
| 931 | } | ||
| 932 | 760 | ||
| 933 | /* | 761 | /* |
| 934 | * enable_device() enumerates all functions in this device via | 762 | * enable_device() enumerates all functions in this device via |
| @@ -947,7 +775,6 @@ static int disable_device(struct acpiphp_slot *slot) | |||
| 947 | 775 | ||
| 948 | slot->flags &= (~SLOT_ENABLED); | 776 | slot->flags &= (~SLOT_ENABLED); |
| 949 | 777 | ||
| 950 | err_exit: | ||
| 951 | return 0; | 778 | return 0; |
| 952 | } | 779 | } |
| 953 | 780 | ||
| @@ -1037,7 +864,7 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
| 1037 | 864 | ||
| 1038 | enabled = disabled = 0; | 865 | enabled = disabled = 0; |
| 1039 | 866 | ||
| 1040 | for (slot = bridge->slots; slot; slot = slot->next) { | 867 | list_for_each_entry(slot, &bridge->slots, node) { |
| 1041 | unsigned int status = get_slot_status(slot); | 868 | unsigned int status = get_slot_status(slot); |
| 1042 | if (slot->flags & SLOT_ENABLED) { | 869 | if (slot->flags & SLOT_ENABLED) { |
| 1043 | if (status == ACPI_STA_ALL) | 870 | if (status == ACPI_STA_ALL) |
| @@ -1082,11 +909,11 @@ static void acpiphp_set_hpp_values(struct pci_bus *bus) | |||
| 1082 | */ | 909 | */ |
| 1083 | static void acpiphp_sanitize_bus(struct pci_bus *bus) | 910 | static void acpiphp_sanitize_bus(struct pci_bus *bus) |
| 1084 | { | 911 | { |
| 1085 | struct pci_dev *dev; | 912 | struct pci_dev *dev, *tmp; |
| 1086 | int i; | 913 | int i; |
| 1087 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; | 914 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; |
| 1088 | 915 | ||
| 1089 | list_for_each_entry(dev, &bus->devices, bus_list) { | 916 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { |
| 1090 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { | 917 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { |
| 1091 | struct resource *res = &dev->resource[i]; | 918 | struct resource *res = &dev->resource[i]; |
| 1092 | if ((res->flags & type_mask) && !res->start && | 919 | if ((res->flags & type_mask) && !res->start && |
| @@ -1118,6 +945,7 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 1118 | dbg("%s: re-enumerating slots under %s\n", | 945 | dbg("%s: re-enumerating slots under %s\n", |
| 1119 | __func__, objname); | 946 | __func__, objname); |
| 1120 | acpiphp_check_bridge(bridge); | 947 | acpiphp_check_bridge(bridge); |
| 948 | put_bridge(bridge); | ||
| 1121 | } | 949 | } |
| 1122 | return AE_OK ; | 950 | return AE_OK ; |
| 1123 | } | 951 | } |
| @@ -1195,6 +1023,7 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) | |||
| 1195 | 1023 | ||
| 1196 | acpi_scan_lock_release(); | 1024 | acpi_scan_lock_release(); |
| 1197 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ | 1025 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ |
| 1026 | put_bridge(bridge); | ||
| 1198 | } | 1027 | } |
| 1199 | 1028 | ||
| 1200 | /** | 1029 | /** |
| @@ -1208,6 +1037,8 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) | |||
| 1208 | static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, | 1037 | static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, |
| 1209 | void *context) | 1038 | void *context) |
| 1210 | { | 1039 | { |
| 1040 | struct acpiphp_bridge *bridge = context; | ||
| 1041 | |||
| 1211 | /* | 1042 | /* |
| 1212 | * Currently the code adds all hotplug events to the kacpid_wq | 1043 | * Currently the code adds all hotplug events to the kacpid_wq |
| 1213 | * queue when it should add hotplug events to the kacpi_hotplug_wq. | 1044 | * queue when it should add hotplug events to the kacpi_hotplug_wq. |
| @@ -1216,6 +1047,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, | |||
| 1216 | * For now just re-add this work to the kacpi_hotplug_wq so we | 1047 | * For now just re-add this work to the kacpi_hotplug_wq so we |
| 1217 | * don't deadlock on hotplug actions. | 1048 | * don't deadlock on hotplug actions. |
| 1218 | */ | 1049 | */ |
| 1050 | get_bridge(bridge); | ||
| 1219 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); | 1051 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); |
| 1220 | } | 1052 | } |
| 1221 | 1053 | ||
| @@ -1270,6 +1102,7 @@ static void _handle_hotplug_event_func(struct work_struct *work) | |||
| 1270 | 1102 | ||
| 1271 | acpi_scan_lock_release(); | 1103 | acpi_scan_lock_release(); |
| 1272 | kfree(hp_work); /* allocated in handle_hotplug_event_func */ | 1104 | kfree(hp_work); /* allocated in handle_hotplug_event_func */ |
| 1105 | put_bridge(func->slot->bridge); | ||
| 1273 | } | 1106 | } |
| 1274 | 1107 | ||
| 1275 | /** | 1108 | /** |
| @@ -1283,6 +1116,8 @@ static void _handle_hotplug_event_func(struct work_struct *work) | |||
| 1283 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, | 1116 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, |
| 1284 | void *context) | 1117 | void *context) |
| 1285 | { | 1118 | { |
| 1119 | struct acpiphp_func *func = context; | ||
| 1120 | |||
| 1286 | /* | 1121 | /* |
| 1287 | * Currently the code adds all hotplug events to the kacpid_wq | 1122 | * Currently the code adds all hotplug events to the kacpid_wq |
| 1288 | * queue when it should add hotplug events to the kacpi_hotplug_wq. | 1123 | * queue when it should add hotplug events to the kacpi_hotplug_wq. |
| @@ -1291,33 +1126,69 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, | |||
| 1291 | * For now just re-add this work to the kacpi_hotplug_wq so we | 1126 | * For now just re-add this work to the kacpi_hotplug_wq so we |
| 1292 | * don't deadlock on hotplug actions. | 1127 | * don't deadlock on hotplug actions. |
| 1293 | */ | 1128 | */ |
| 1129 | get_bridge(func->slot->bridge); | ||
| 1294 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func); | 1130 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func); |
| 1295 | } | 1131 | } |
| 1296 | 1132 | ||
| 1297 | static struct acpi_pci_driver acpi_pci_hp_driver = { | 1133 | /* |
| 1298 | .add = add_bridge, | 1134 | * Create hotplug slots for the PCI bus. |
| 1299 | .remove = remove_bridge, | 1135 | * It should always return 0 to avoid skipping following notifiers. |
| 1300 | }; | ||
| 1301 | |||
| 1302 | /** | ||
| 1303 | * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures | ||
| 1304 | */ | 1136 | */ |
| 1305 | int __init acpiphp_glue_init(void) | 1137 | void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle) |
| 1306 | { | 1138 | { |
| 1307 | acpi_pci_register_driver(&acpi_pci_hp_driver); | 1139 | acpi_handle dummy_handle; |
| 1140 | struct acpiphp_bridge *bridge; | ||
| 1308 | 1141 | ||
| 1309 | return 0; | 1142 | if (acpiphp_disabled) |
| 1310 | } | 1143 | return; |
| 1311 | 1144 | ||
| 1145 | if (detect_ejectable_slots(handle) <= 0) | ||
| 1146 | return; | ||
| 1312 | 1147 | ||
| 1313 | /** | 1148 | bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); |
| 1314 | * acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures | 1149 | if (bridge == NULL) { |
| 1315 | * | 1150 | err("out of memory\n"); |
| 1316 | * This function frees all data allocated in acpiphp_glue_init(). | 1151 | return; |
| 1317 | */ | 1152 | } |
| 1318 | void acpiphp_glue_exit(void) | 1153 | |
| 1154 | INIT_LIST_HEAD(&bridge->slots); | ||
| 1155 | kref_init(&bridge->ref); | ||
| 1156 | bridge->handle = handle; | ||
| 1157 | bridge->pci_dev = pci_dev_get(bus->self); | ||
| 1158 | bridge->pci_bus = bus; | ||
| 1159 | |||
| 1160 | /* | ||
| 1161 | * Grab a ref to the subordinate PCI bus in case the bus is | ||
| 1162 | * removed via PCI core logical hotplug. The ref pins the bus | ||
| 1163 | * (which we access during module unload). | ||
| 1164 | */ | ||
| 1165 | get_device(&bus->dev); | ||
| 1166 | |||
| 1167 | if (!pci_is_root_bus(bridge->pci_bus) && | ||
| 1168 | ACPI_SUCCESS(acpi_get_handle(bridge->handle, | ||
| 1169 | "_EJ0", &dummy_handle))) { | ||
| 1170 | dbg("found ejectable p2p bridge\n"); | ||
| 1171 | bridge->flags |= BRIDGE_HAS_EJ0; | ||
| 1172 | bridge->func = acpiphp_bridge_handle_to_function(handle); | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | init_bridge_misc(bridge); | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | /* Destroy hotplug slots associated with the PCI bus */ | ||
| 1179 | void acpiphp_remove_slots(struct pci_bus *bus) | ||
| 1319 | { | 1180 | { |
| 1320 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); | 1181 | struct acpiphp_bridge *bridge, *tmp; |
| 1182 | |||
| 1183 | if (acpiphp_disabled) | ||
| 1184 | return; | ||
| 1185 | |||
| 1186 | list_for_each_entry_safe(bridge, tmp, &bridge_list, list) | ||
| 1187 | if (bridge->pci_bus == bus) { | ||
| 1188 | cleanup_bridge(bridge); | ||
| 1189 | put_bridge(bridge); | ||
| 1190 | break; | ||
| 1191 | } | ||
| 1321 | } | 1192 | } |
| 1322 | 1193 | ||
| 1323 | /** | 1194 | /** |
| @@ -1396,7 +1267,7 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) | |||
| 1396 | 1267 | ||
| 1397 | sta = get_slot_status(slot); | 1268 | sta = get_slot_status(slot); |
| 1398 | 1269 | ||
| 1399 | return (sta & ACPI_STA_SHOW_IN_UI) ? 0 : 1; | 1270 | return (sta & ACPI_STA_DEVICE_UI) ? 0 : 1; |
| 1400 | } | 1271 | } |
| 1401 | 1272 | ||
| 1402 | 1273 | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h index 9fff878cf026..1356211431d0 100644 --- a/drivers/pci/hotplug/cpci_hotplug.h +++ b/drivers/pci/hotplug/cpci_hotplug.h | |||
| @@ -75,28 +75,36 @@ static inline const char *slot_name(struct slot *slot) | |||
| 75 | return hotplug_slot_name(slot->hotplug_slot); | 75 | return hotplug_slot_name(slot->hotplug_slot); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | extern int cpci_hp_register_controller(struct cpci_hp_controller *controller); | 78 | int cpci_hp_register_controller(struct cpci_hp_controller *controller); |
| 79 | extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); | 79 | int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); |
| 80 | extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); | 80 | int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); |
| 81 | extern int cpci_hp_unregister_bus(struct pci_bus *bus); | 81 | int cpci_hp_unregister_bus(struct pci_bus *bus); |
| 82 | extern int cpci_hp_start(void); | 82 | int cpci_hp_start(void); |
| 83 | extern int cpci_hp_stop(void); | 83 | int cpci_hp_stop(void); |
| 84 | 84 | ||
| 85 | /* | 85 | /* |
| 86 | * Internal function prototypes, these functions should not be used by | 86 | * Internal function prototypes, these functions should not be used by |
| 87 | * board/chassis drivers. | 87 | * board/chassis drivers. |
| 88 | */ | 88 | */ |
| 89 | extern u8 cpci_get_attention_status(struct slot *slot); | 89 | u8 cpci_get_attention_status(struct slot *slot); |
| 90 | extern u8 cpci_get_latch_status(struct slot *slot); | 90 | u8 cpci_get_latch_status(struct slot *slot); |
| 91 | extern u8 cpci_get_adapter_status(struct slot *slot); | 91 | u8 cpci_get_adapter_status(struct slot *slot); |
| 92 | extern u16 cpci_get_hs_csr(struct slot * slot); | 92 | u16 cpci_get_hs_csr(struct slot * slot); |
| 93 | extern int cpci_set_attention_status(struct slot *slot, int status); | 93 | int cpci_set_attention_status(struct slot *slot, int status); |
| 94 | extern int cpci_check_and_clear_ins(struct slot * slot); | 94 | int cpci_check_and_clear_ins(struct slot * slot); |
| 95 | extern int cpci_check_ext(struct slot * slot); | 95 | int cpci_check_ext(struct slot * slot); |
| 96 | extern int cpci_clear_ext(struct slot * slot); | 96 | int cpci_clear_ext(struct slot * slot); |
| 97 | extern int cpci_led_on(struct slot * slot); | 97 | int cpci_led_on(struct slot * slot); |
| 98 | extern int cpci_led_off(struct slot * slot); | 98 | int cpci_led_off(struct slot * slot); |
| 99 | extern int cpci_configure_slot(struct slot *slot); | 99 | int cpci_configure_slot(struct slot *slot); |
| 100 | extern int cpci_unconfigure_slot(struct slot *slot); | 100 | int cpci_unconfigure_slot(struct slot *slot); |
| 101 | |||
| 102 | #ifdef CONFIG_HOTPLUG_PCI_CPCI | ||
| 103 | int cpci_hotplug_init(int debug); | ||
| 104 | void cpci_hotplug_exit(void); | ||
| 105 | #else | ||
| 106 | static inline int cpci_hotplug_init(int debug) { return 0; } | ||
| 107 | static inline void cpci_hotplug_exit(void) { } | ||
| 108 | #endif | ||
| 101 | 109 | ||
| 102 | #endif /* _CPCI_HOTPLUG_H */ | 110 | #endif /* _CPCI_HOTPLUG_H */ |
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index d8ffc7366801..516b87738b6e 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h | |||
| @@ -404,50 +404,44 @@ struct resource_lists { | |||
| 404 | 404 | ||
| 405 | 405 | ||
| 406 | /* debugfs functions for the hotplug controller info */ | 406 | /* debugfs functions for the hotplug controller info */ |
| 407 | extern void cpqhp_initialize_debugfs(void); | 407 | void cpqhp_initialize_debugfs(void); |
| 408 | extern void cpqhp_shutdown_debugfs(void); | 408 | void cpqhp_shutdown_debugfs(void); |
| 409 | extern void cpqhp_create_debugfs_files(struct controller *ctrl); | 409 | void cpqhp_create_debugfs_files(struct controller *ctrl); |
| 410 | extern void cpqhp_remove_debugfs_files(struct controller *ctrl); | 410 | void cpqhp_remove_debugfs_files(struct controller *ctrl); |
| 411 | 411 | ||
| 412 | /* controller functions */ | 412 | /* controller functions */ |
| 413 | extern void cpqhp_pushbutton_thread(unsigned long event_pointer); | 413 | void cpqhp_pushbutton_thread(unsigned long event_pointer); |
| 414 | extern irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); | 414 | irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); |
| 415 | extern int cpqhp_find_available_resources(struct controller *ctrl, | 415 | int cpqhp_find_available_resources(struct controller *ctrl, |
| 416 | void __iomem *rom_start); | 416 | void __iomem *rom_start); |
| 417 | extern int cpqhp_event_start_thread(void); | 417 | int cpqhp_event_start_thread(void); |
| 418 | extern void cpqhp_event_stop_thread(void); | 418 | void cpqhp_event_stop_thread(void); |
| 419 | extern struct pci_func *cpqhp_slot_create(unsigned char busnumber); | 419 | struct pci_func *cpqhp_slot_create(unsigned char busnumber); |
| 420 | extern struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, | 420 | struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, |
| 421 | unsigned char index); | 421 | unsigned char index); |
| 422 | extern int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); | 422 | int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); |
| 423 | extern int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); | 423 | int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); |
| 424 | extern int cpqhp_hardware_test(struct controller *ctrl, int test_num); | 424 | int cpqhp_hardware_test(struct controller *ctrl, int test_num); |
| 425 | 425 | ||
| 426 | /* resource functions */ | 426 | /* resource functions */ |
| 427 | extern int cpqhp_resource_sort_and_combine (struct pci_resource **head); | 427 | int cpqhp_resource_sort_and_combine (struct pci_resource **head); |
| 428 | 428 | ||
| 429 | /* pci functions */ | 429 | /* pci functions */ |
| 430 | extern int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); | 430 | int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); |
| 431 | extern int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, | 431 | int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, |
| 432 | u8 slot); | 432 | u8 slot); |
| 433 | extern int cpqhp_save_config(struct controller *ctrl, int busnumber, | 433 | int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug); |
| 434 | int is_hot_plug); | 434 | int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func); |
| 435 | extern int cpqhp_save_base_addr_length(struct controller *ctrl, | 435 | int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func); |
| 436 | struct pci_func *func); | 436 | int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func); |
| 437 | extern int cpqhp_save_used_resources(struct controller *ctrl, | 437 | int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot); |
| 438 | struct pci_func *func); | 438 | int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); |
| 439 | extern int cpqhp_configure_board(struct controller *ctrl, | 439 | void cpqhp_destroy_board_resources(struct pci_func *func); |
| 440 | struct pci_func *func); | 440 | int cpqhp_return_board_resources(struct pci_func *func, |
| 441 | extern int cpqhp_save_slot_config(struct controller *ctrl, | 441 | struct resource_lists *resources); |
| 442 | struct pci_func *new_slot); | 442 | void cpqhp_destroy_resource_list(struct resource_lists *resources); |
| 443 | extern int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); | 443 | int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func); |
| 444 | extern void cpqhp_destroy_board_resources(struct pci_func *func); | 444 | int cpqhp_unconfigure_device(struct pci_func *func); |
| 445 | extern int cpqhp_return_board_resources (struct pci_func *func, | ||
| 446 | struct resource_lists *resources); | ||
| 447 | extern void cpqhp_destroy_resource_list(struct resource_lists *resources); | ||
| 448 | extern int cpqhp_configure_device(struct controller *ctrl, | ||
| 449 | struct pci_func *func); | ||
| 450 | extern int cpqhp_unconfigure_device(struct pci_func *func); | ||
| 451 | 445 | ||
| 452 | /* Global variables */ | 446 | /* Global variables */ |
| 453 | extern int cpqhp_debug; | 447 | extern int cpqhp_debug; |
diff --git a/drivers/pci/hotplug/cpqphp_nvram.h b/drivers/pci/hotplug/cpqphp_nvram.h index e89c0702119d..34e4e54fcf15 100644 --- a/drivers/pci/hotplug/cpqphp_nvram.h +++ b/drivers/pci/hotplug/cpqphp_nvram.h | |||
| @@ -30,26 +30,26 @@ | |||
| 30 | 30 | ||
| 31 | #ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM | 31 | #ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM |
| 32 | 32 | ||
| 33 | static inline void compaq_nvram_init (void __iomem *rom_start) | 33 | static inline void compaq_nvram_init(void __iomem *rom_start) |
| 34 | { | 34 | { |
| 35 | return; | 35 | return; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | static inline int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) | 38 | static inline int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl) |
| 39 | { | 39 | { |
| 40 | return 0; | 40 | return 0; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | static inline int compaq_nvram_store (void __iomem *rom_start) | 43 | static inline int compaq_nvram_store(void __iomem *rom_start) |
| 44 | { | 44 | { |
| 45 | return 0; | 45 | return 0; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | #else | 48 | #else |
| 49 | 49 | ||
| 50 | extern void compaq_nvram_init (void __iomem *rom_start); | 50 | void compaq_nvram_init(void __iomem *rom_start); |
| 51 | extern int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl); | 51 | int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl); |
| 52 | extern int compaq_nvram_store (void __iomem *rom_start); | 52 | int compaq_nvram_store(void __iomem *rom_start); |
| 53 | 53 | ||
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h index a8d391a4957d..8c5b25871d02 100644 --- a/drivers/pci/hotplug/ibmphp.h +++ b/drivers/pci/hotplug/ibmphp.h | |||
| @@ -275,17 +275,17 @@ extern struct list_head ibmphp_slot_head; | |||
| 275 | * FUNCTION PROTOTYPES * | 275 | * FUNCTION PROTOTYPES * |
| 276 | ***********************************************************/ | 276 | ***********************************************************/ |
| 277 | 277 | ||
| 278 | extern void ibmphp_free_ebda_hpc_queue (void); | 278 | void ibmphp_free_ebda_hpc_queue(void); |
| 279 | extern int ibmphp_access_ebda (void); | 279 | int ibmphp_access_ebda(void); |
| 280 | extern struct slot *ibmphp_get_slot_from_physical_num (u8); | 280 | struct slot *ibmphp_get_slot_from_physical_num(u8); |
| 281 | extern int ibmphp_get_total_hp_slots (void); | 281 | int ibmphp_get_total_hp_slots(void); |
| 282 | extern void ibmphp_free_ibm_slot (struct slot *); | 282 | void ibmphp_free_ibm_slot(struct slot *); |
| 283 | extern void ibmphp_free_bus_info_queue (void); | 283 | void ibmphp_free_bus_info_queue(void); |
| 284 | extern void ibmphp_free_ebda_pci_rsrc_queue (void); | 284 | void ibmphp_free_ebda_pci_rsrc_queue(void); |
| 285 | extern struct bus_info *ibmphp_find_same_bus_num (u32); | 285 | struct bus_info *ibmphp_find_same_bus_num(u32); |
| 286 | extern int ibmphp_get_bus_index (u8); | 286 | int ibmphp_get_bus_index(u8); |
| 287 | extern u16 ibmphp_get_total_controllers (void); | 287 | u16 ibmphp_get_total_controllers(void); |
| 288 | extern int ibmphp_register_pci (void); | 288 | int ibmphp_register_pci(void); |
| 289 | 289 | ||
| 290 | /* passed parameters */ | 290 | /* passed parameters */ |
| 291 | #define MEM 0 | 291 | #define MEM 0 |
| @@ -381,24 +381,24 @@ struct res_needed { | |||
| 381 | 381 | ||
| 382 | /* functions */ | 382 | /* functions */ |
| 383 | 383 | ||
| 384 | extern int ibmphp_rsrc_init (void); | 384 | int ibmphp_rsrc_init(void); |
| 385 | extern int ibmphp_add_resource (struct resource_node *); | 385 | int ibmphp_add_resource(struct resource_node *); |
| 386 | extern int ibmphp_remove_resource (struct resource_node *); | 386 | int ibmphp_remove_resource(struct resource_node *); |
| 387 | extern int ibmphp_find_resource (struct bus_node *, u32, struct resource_node **, int); | 387 | int ibmphp_find_resource(struct bus_node *, u32, struct resource_node **, int); |
| 388 | extern int ibmphp_check_resource (struct resource_node *, u8); | 388 | int ibmphp_check_resource(struct resource_node *, u8); |
| 389 | extern int ibmphp_remove_bus (struct bus_node *, u8); | 389 | int ibmphp_remove_bus(struct bus_node *, u8); |
| 390 | extern void ibmphp_free_resources (void); | 390 | void ibmphp_free_resources(void); |
| 391 | extern int ibmphp_add_pfmem_from_mem (struct resource_node *); | 391 | int ibmphp_add_pfmem_from_mem(struct resource_node *); |
| 392 | extern struct bus_node *ibmphp_find_res_bus (u8); | 392 | struct bus_node *ibmphp_find_res_bus(u8); |
| 393 | extern void ibmphp_print_test (void); /* for debugging purposes */ | 393 | void ibmphp_print_test(void); /* for debugging purposes */ |
| 394 | 394 | ||
| 395 | extern void ibmphp_hpc_initvars (void); | 395 | void ibmphp_hpc_initvars(void); |
| 396 | extern int ibmphp_hpc_readslot (struct slot *, u8, u8 *); | 396 | int ibmphp_hpc_readslot(struct slot *, u8, u8 *); |
| 397 | extern int ibmphp_hpc_writeslot (struct slot *, u8); | 397 | int ibmphp_hpc_writeslot(struct slot *, u8); |
| 398 | extern void ibmphp_lock_operations (void); | 398 | void ibmphp_lock_operations(void); |
| 399 | extern void ibmphp_unlock_operations (void); | 399 | void ibmphp_unlock_operations(void); |
| 400 | extern int ibmphp_hpc_start_poll_thread (void); | 400 | int ibmphp_hpc_start_poll_thread(void); |
| 401 | extern void ibmphp_hpc_stop_poll_thread (void); | 401 | void ibmphp_hpc_stop_poll_thread(void); |
| 402 | 402 | ||
| 403 | //---------------------------------------------------------------------------- | 403 | //---------------------------------------------------------------------------- |
| 404 | 404 | ||
| @@ -749,11 +749,11 @@ struct controller { | |||
| 749 | 749 | ||
| 750 | /* Functions */ | 750 | /* Functions */ |
| 751 | 751 | ||
| 752 | extern int ibmphp_init_devno (struct slot **); /* This function is called from EBDA, so we need it not be static */ | 752 | int ibmphp_init_devno(struct slot **); /* This function is called from EBDA, so we need it not be static */ |
| 753 | extern int ibmphp_do_disable_slot (struct slot *slot_cur); | 753 | int ibmphp_do_disable_slot(struct slot *slot_cur); |
| 754 | extern int ibmphp_update_slot_info (struct slot *); /* This function is called from HPC, so we need it to not be be static */ | 754 | int ibmphp_update_slot_info(struct slot *); /* This function is called from HPC, so we need it to not be be static */ |
| 755 | extern int ibmphp_configure_card (struct pci_func *, u8); | 755 | int ibmphp_configure_card(struct pci_func *, u8); |
| 756 | extern int ibmphp_unconfigure_card (struct slot **, int); | 756 | int ibmphp_unconfigure_card(struct slot **, int); |
| 757 | extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops; | 757 | extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops; |
| 758 | 758 | ||
| 759 | #endif //__IBMPHP_H | 759 | #endif //__IBMPHP_H |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 202f4a969eb5..ec20f74c8981 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/pci_hotplug.h> | 41 | #include <linux/pci_hotplug.h> |
| 42 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
| 43 | #include "../pci.h" | 43 | #include "../pci.h" |
| 44 | #include "cpci_hotplug.h" | ||
| 44 | 45 | ||
| 45 | #define MY_NAME "pci_hotplug" | 46 | #define MY_NAME "pci_hotplug" |
| 46 | 47 | ||
| @@ -63,14 +64,6 @@ static bool debug; | |||
| 63 | static LIST_HEAD(pci_hotplug_slot_list); | 64 | static LIST_HEAD(pci_hotplug_slot_list); |
| 64 | static DEFINE_MUTEX(pci_hp_mutex); | 65 | static DEFINE_MUTEX(pci_hp_mutex); |
| 65 | 66 | ||
| 66 | #ifdef CONFIG_HOTPLUG_PCI_CPCI | ||
| 67 | extern int cpci_hotplug_init(int debug); | ||
| 68 | extern void cpci_hotplug_exit(void); | ||
| 69 | #else | ||
| 70 | static inline int cpci_hotplug_init(int debug) { return 0; } | ||
| 71 | static inline void cpci_hotplug_exit(void) { } | ||
| 72 | #endif | ||
| 73 | |||
| 74 | /* Weee, fun with macros... */ | 67 | /* Weee, fun with macros... */ |
| 75 | #define GET_STATUS(name,type) \ | 68 | #define GET_STATUS(name,type) \ |
| 76 | static int get_##name (struct hotplug_slot *slot, type *value) \ | 69 | static int get_##name (struct hotplug_slot *slot, type *value) \ |
| @@ -524,13 +517,11 @@ int pci_hp_deregister(struct hotplug_slot *hotplug) | |||
| 524 | * | 517 | * |
| 525 | * Returns 0 if successful, anything else for an error. | 518 | * Returns 0 if successful, anything else for an error. |
| 526 | */ | 519 | */ |
| 527 | int __must_check pci_hp_change_slot_info(struct hotplug_slot *hotplug, | 520 | int pci_hp_change_slot_info(struct hotplug_slot *hotplug, |
| 528 | struct hotplug_slot_info *info) | 521 | struct hotplug_slot_info *info) |
| 529 | { | 522 | { |
| 530 | struct pci_slot *slot; | ||
| 531 | if (!hotplug || !info) | 523 | if (!hotplug || !info) |
| 532 | return -ENODEV; | 524 | return -ENODEV; |
| 533 | slot = hotplug->pci_slot; | ||
| 534 | 525 | ||
| 535 | memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info)); | 526 | memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info)); |
| 536 | 527 | ||
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 2c113de94323..7fb326983ed6 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
| @@ -127,15 +127,15 @@ struct controller { | |||
| 127 | #define NO_CMD_CMPL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_NCCS) | 127 | #define NO_CMD_CMPL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_NCCS) |
| 128 | #define PSN(ctrl) ((ctrl)->slot_cap >> 19) | 128 | #define PSN(ctrl) ((ctrl)->slot_cap >> 19) |
| 129 | 129 | ||
| 130 | extern int pciehp_sysfs_enable_slot(struct slot *slot); | 130 | int pciehp_sysfs_enable_slot(struct slot *slot); |
| 131 | extern int pciehp_sysfs_disable_slot(struct slot *slot); | 131 | int pciehp_sysfs_disable_slot(struct slot *slot); |
| 132 | extern u8 pciehp_handle_attention_button(struct slot *p_slot); | 132 | u8 pciehp_handle_attention_button(struct slot *p_slot); |
| 133 | extern u8 pciehp_handle_switch_change(struct slot *p_slot); | 133 | u8 pciehp_handle_switch_change(struct slot *p_slot); |
| 134 | extern u8 pciehp_handle_presence_change(struct slot *p_slot); | 134 | u8 pciehp_handle_presence_change(struct slot *p_slot); |
| 135 | extern u8 pciehp_handle_power_fault(struct slot *p_slot); | 135 | u8 pciehp_handle_power_fault(struct slot *p_slot); |
| 136 | extern int pciehp_configure_device(struct slot *p_slot); | 136 | int pciehp_configure_device(struct slot *p_slot); |
| 137 | extern int pciehp_unconfigure_device(struct slot *p_slot); | 137 | int pciehp_unconfigure_device(struct slot *p_slot); |
| 138 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); | 138 | void pciehp_queue_pushbutton_work(struct work_struct *work); |
| 139 | struct controller *pcie_init(struct pcie_device *dev); | 139 | struct controller *pcie_init(struct pcie_device *dev); |
| 140 | int pcie_init_notification(struct controller *ctrl); | 140 | int pcie_init_notification(struct controller *ctrl); |
| 141 | int pciehp_enable_slot(struct slot *p_slot); | 141 | int pciehp_enable_slot(struct slot *p_slot); |
| @@ -166,8 +166,8 @@ static inline const char *slot_name(struct slot *slot) | |||
| 166 | #include <acpi/acpi_bus.h> | 166 | #include <acpi/acpi_bus.h> |
| 167 | #include <linux/pci-acpi.h> | 167 | #include <linux/pci-acpi.h> |
| 168 | 168 | ||
| 169 | extern void __init pciehp_acpi_slot_detection_init(void); | 169 | void __init pciehp_acpi_slot_detection_init(void); |
| 170 | extern int pciehp_acpi_slot_detection_check(struct pci_dev *dev); | 170 | int pciehp_acpi_slot_detection_check(struct pci_dev *dev); |
| 171 | 171 | ||
| 172 | static inline void pciehp_firmware_init(void) | 172 | static inline void pciehp_firmware_init(void) |
| 173 | { | 173 | { |
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 24d709b7388c..ead7c534095e 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
| @@ -90,7 +90,7 @@ static int __init dummy_probe(struct pcie_device *dev) | |||
| 90 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); | 90 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); |
| 91 | if (!slot) | 91 | if (!slot) |
| 92 | return -ENOMEM; | 92 | return -ENOMEM; |
| 93 | slot->number = slot_cap >> 19; | 93 | slot->number = (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19; |
| 94 | list_for_each_entry(tmp, &dummy_slots, list) { | 94 | list_for_each_entry(tmp, &dummy_slots, list) { |
| 95 | if (tmp->number == slot->number) | 95 | if (tmp->number == slot->number) |
| 96 | dup_slot_id++; | 96 | dup_slot_id++; |
diff --git a/drivers/pci/hotplug/rpadlpar.h b/drivers/pci/hotplug/rpadlpar.h index 4a0a59b82eae..81df93931ad0 100644 --- a/drivers/pci/hotplug/rpadlpar.h +++ b/drivers/pci/hotplug/rpadlpar.h | |||
| @@ -15,10 +15,10 @@ | |||
| 15 | #ifndef _RPADLPAR_IO_H_ | 15 | #ifndef _RPADLPAR_IO_H_ |
| 16 | #define _RPADLPAR_IO_H_ | 16 | #define _RPADLPAR_IO_H_ |
| 17 | 17 | ||
| 18 | extern int dlpar_sysfs_init(void); | 18 | int dlpar_sysfs_init(void); |
| 19 | extern void dlpar_sysfs_exit(void); | 19 | void dlpar_sysfs_exit(void); |
| 20 | 20 | ||
| 21 | extern int dlpar_add_slot(char *drc_name); | 21 | int dlpar_add_slot(char *drc_name); |
| 22 | extern int dlpar_remove_slot(char *drc_name); | 22 | int dlpar_remove_slot(char *drc_name); |
| 23 | 23 | ||
| 24 | #endif | 24 | #endif |
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index df5677440a08..3135856e5e1c 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h | |||
| @@ -86,18 +86,18 @@ extern struct list_head rpaphp_slot_head; | |||
| 86 | /* function prototypes */ | 86 | /* function prototypes */ |
| 87 | 87 | ||
| 88 | /* rpaphp_pci.c */ | 88 | /* rpaphp_pci.c */ |
| 89 | extern int rpaphp_enable_slot(struct slot *slot); | 89 | int rpaphp_enable_slot(struct slot *slot); |
| 90 | extern int rpaphp_get_sensor_state(struct slot *slot, int *state); | 90 | int rpaphp_get_sensor_state(struct slot *slot, int *state); |
| 91 | 91 | ||
| 92 | /* rpaphp_core.c */ | 92 | /* rpaphp_core.c */ |
| 93 | extern int rpaphp_add_slot(struct device_node *dn); | 93 | int rpaphp_add_slot(struct device_node *dn); |
| 94 | extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, | 94 | int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, |
| 95 | char **drc_name, char **drc_type, int *drc_power_domain); | 95 | char **drc_name, char **drc_type, int *drc_power_domain); |
| 96 | 96 | ||
| 97 | /* rpaphp_slot.c */ | 97 | /* rpaphp_slot.c */ |
| 98 | extern void dealloc_slot_struct(struct slot *slot); | 98 | void dealloc_slot_struct(struct slot *slot); |
| 99 | extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); | 99 | struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); |
| 100 | extern int rpaphp_register_slot(struct slot *slot); | 100 | int rpaphp_register_slot(struct slot *slot); |
| 101 | extern int rpaphp_deregister_slot(struct slot *slot); | 101 | int rpaphp_deregister_slot(struct slot *slot); |
| 102 | 102 | ||
| 103 | #endif /* _PPC64PHP_H */ | 103 | #endif /* _PPC64PHP_H */ |
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index 7db249a25016..46a7b738f61f 100644 --- a/drivers/pci/hotplug/s390_pci_hpc.c +++ b/drivers/pci/hotplug/s390_pci_hpc.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
| 17 | #include <linux/pci_hotplug.h> | 17 | #include <linux/pci_hotplug.h> |
| 18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | #include <asm/pci_debug.h> | ||
| 19 | #include <asm/sclp.h> | 20 | #include <asm/sclp.h> |
| 20 | 21 | ||
| 21 | #define SLOT_NAME_SIZE 10 | 22 | #define SLOT_NAME_SIZE 10 |
| @@ -49,6 +50,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) | |||
| 49 | return -EIO; | 50 | return -EIO; |
| 50 | 51 | ||
| 51 | rc = sclp_pci_configure(slot->zdev->fid); | 52 | rc = sclp_pci_configure(slot->zdev->fid); |
| 53 | zpci_dbg(3, "conf fid:%x, rc:%d\n", slot->zdev->fid, rc); | ||
| 52 | if (!rc) { | 54 | if (!rc) { |
| 53 | slot->zdev->state = ZPCI_FN_STATE_CONFIGURED; | 55 | slot->zdev->state = ZPCI_FN_STATE_CONFIGURED; |
| 54 | /* automatically scan the device after is was configured */ | 56 | /* automatically scan the device after is was configured */ |
| @@ -66,16 +68,16 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) | |||
| 66 | if (!zpci_fn_configured(slot->zdev->state)) | 68 | if (!zpci_fn_configured(slot->zdev->state)) |
| 67 | return -EIO; | 69 | return -EIO; |
| 68 | 70 | ||
| 71 | rc = zpci_disable_device(slot->zdev); | ||
| 72 | if (rc) | ||
| 73 | return rc; | ||
| 69 | /* TODO: we rely on the user to unbind/remove the device, is that plausible | 74 | /* TODO: we rely on the user to unbind/remove the device, is that plausible |
| 70 | * or do we need to trigger that here? | 75 | * or do we need to trigger that here? |
| 71 | */ | 76 | */ |
| 72 | rc = sclp_pci_deconfigure(slot->zdev->fid); | 77 | rc = sclp_pci_deconfigure(slot->zdev->fid); |
| 73 | if (!rc) { | 78 | zpci_dbg(3, "deconf fid:%x, rc:%d\n", slot->zdev->fid, rc); |
| 74 | /* Fixme: better call List-PCI to find the disabled FH | 79 | if (!rc) |
| 75 | for the FID since the FH should be opaque... */ | ||
| 76 | slot->zdev->fh &= 0x7fffffff; | ||
| 77 | slot->zdev->state = ZPCI_FN_STATE_STANDBY; | 80 | slot->zdev->state = ZPCI_FN_STATE_STANDBY; |
| 78 | } | ||
| 79 | return rc; | 81 | return rc; |
| 80 | } | 82 | } |
| 81 | 83 | ||
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index b849f995075a..e260f207a90e 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
| @@ -168,19 +168,19 @@ struct controller { | |||
| 168 | #define WRONG_BUS_FREQUENCY 0x0000000D | 168 | #define WRONG_BUS_FREQUENCY 0x0000000D |
| 169 | #define POWER_FAILURE 0x0000000E | 169 | #define POWER_FAILURE 0x0000000E |
| 170 | 170 | ||
| 171 | extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); | 171 | int __must_check shpchp_create_ctrl_files(struct controller *ctrl); |
| 172 | extern void shpchp_remove_ctrl_files(struct controller *ctrl); | 172 | void shpchp_remove_ctrl_files(struct controller *ctrl); |
| 173 | extern int shpchp_sysfs_enable_slot(struct slot *slot); | 173 | int shpchp_sysfs_enable_slot(struct slot *slot); |
| 174 | extern int shpchp_sysfs_disable_slot(struct slot *slot); | 174 | int shpchp_sysfs_disable_slot(struct slot *slot); |
| 175 | extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); | 175 | u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); |
| 176 | extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); | 176 | u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); |
| 177 | extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); | 177 | u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); |
| 178 | extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); | 178 | u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); |
| 179 | extern int shpchp_configure_device(struct slot *p_slot); | 179 | int shpchp_configure_device(struct slot *p_slot); |
| 180 | extern int shpchp_unconfigure_device(struct slot *p_slot); | 180 | int shpchp_unconfigure_device(struct slot *p_slot); |
| 181 | extern void cleanup_slots(struct controller *ctrl); | 181 | void cleanup_slots(struct controller *ctrl); |
| 182 | extern void shpchp_queue_pushbutton_work(struct work_struct *work); | 182 | void shpchp_queue_pushbutton_work(struct work_struct *work); |
| 183 | extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev); | 183 | int shpc_init( struct controller *ctrl, struct pci_dev *pdev); |
| 184 | 184 | ||
| 185 | static inline const char *slot_name(struct slot *slot) | 185 | static inline const char *slot_name(struct slot *slot) |
| 186 | { | 186 | { |
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index eeb23ceae4a8..e8c31fe20566 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c | |||
| @@ -85,7 +85,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
| 85 | } | 85 | } |
| 86 | static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); | 86 | static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); |
| 87 | 87 | ||
| 88 | int __must_check shpchp_create_ctrl_files (struct controller *ctrl) | 88 | int shpchp_create_ctrl_files (struct controller *ctrl) |
| 89 | { | 89 | { |
| 90 | return device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); | 90 | return device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); |
| 91 | } | 91 | } |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 00cc78c7aa04..d40bed726769 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
| @@ -22,10 +22,12 @@ | |||
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | 23 | ||
| 24 | #include "pci.h" | 24 | #include "pci.h" |
| 25 | #include "msi.h" | ||
| 26 | 25 | ||
| 27 | static int pci_msi_enable = 1; | 26 | static int pci_msi_enable = 1; |
| 28 | 27 | ||
| 28 | #define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1) | ||
| 29 | |||
| 30 | |||
| 29 | /* Arch hooks */ | 31 | /* Arch hooks */ |
| 30 | 32 | ||
| 31 | #ifndef arch_msi_check_device | 33 | #ifndef arch_msi_check_device |
| @@ -111,32 +113,26 @@ void default_restore_msi_irqs(struct pci_dev *dev, int irq) | |||
| 111 | } | 113 | } |
| 112 | #endif | 114 | #endif |
| 113 | 115 | ||
| 114 | static void msi_set_enable(struct pci_dev *dev, int pos, int enable) | 116 | static void msi_set_enable(struct pci_dev *dev, int enable) |
| 115 | { | 117 | { |
| 116 | u16 control; | 118 | u16 control; |
| 117 | 119 | ||
| 118 | BUG_ON(!pos); | 120 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); |
| 119 | |||
| 120 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); | ||
| 121 | control &= ~PCI_MSI_FLAGS_ENABLE; | 121 | control &= ~PCI_MSI_FLAGS_ENABLE; |
| 122 | if (enable) | 122 | if (enable) |
| 123 | control |= PCI_MSI_FLAGS_ENABLE; | 123 | control |= PCI_MSI_FLAGS_ENABLE; |
| 124 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); | 124 | pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | static void msix_set_enable(struct pci_dev *dev, int enable) | 127 | static void msix_set_enable(struct pci_dev *dev, int enable) |
| 128 | { | 128 | { |
| 129 | int pos; | ||
| 130 | u16 control; | 129 | u16 control; |
| 131 | 130 | ||
| 132 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | 131 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); |
| 133 | if (pos) { | 132 | control &= ~PCI_MSIX_FLAGS_ENABLE; |
| 134 | pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); | 133 | if (enable) |
| 135 | control &= ~PCI_MSIX_FLAGS_ENABLE; | 134 | control |= PCI_MSIX_FLAGS_ENABLE; |
| 136 | if (enable) | 135 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); |
| 137 | control |= PCI_MSIX_FLAGS_ENABLE; | ||
| 138 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | ||
| 139 | } | ||
| 140 | } | 136 | } |
| 141 | 137 | ||
| 142 | static inline __attribute_const__ u32 msi_mask(unsigned x) | 138 | static inline __attribute_const__ u32 msi_mask(unsigned x) |
| @@ -247,18 +243,18 @@ void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | |||
| 247 | msg->data = readl(base + PCI_MSIX_ENTRY_DATA); | 243 | msg->data = readl(base + PCI_MSIX_ENTRY_DATA); |
| 248 | } else { | 244 | } else { |
| 249 | struct pci_dev *dev = entry->dev; | 245 | struct pci_dev *dev = entry->dev; |
| 250 | int pos = entry->msi_attrib.pos; | 246 | int pos = dev->msi_cap; |
| 251 | u16 data; | 247 | u16 data; |
| 252 | 248 | ||
| 253 | pci_read_config_dword(dev, msi_lower_address_reg(pos), | 249 | pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, |
| 254 | &msg->address_lo); | 250 | &msg->address_lo); |
| 255 | if (entry->msi_attrib.is_64) { | 251 | if (entry->msi_attrib.is_64) { |
| 256 | pci_read_config_dword(dev, msi_upper_address_reg(pos), | 252 | pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, |
| 257 | &msg->address_hi); | 253 | &msg->address_hi); |
| 258 | pci_read_config_word(dev, msi_data_reg(pos, 1), &data); | 254 | pci_read_config_word(dev, pos + PCI_MSI_DATA_64, &data); |
| 259 | } else { | 255 | } else { |
| 260 | msg->address_hi = 0; | 256 | msg->address_hi = 0; |
| 261 | pci_read_config_word(dev, msi_data_reg(pos, 0), &data); | 257 | pci_read_config_word(dev, pos + PCI_MSI_DATA_32, &data); |
| 262 | } | 258 | } |
| 263 | msg->data = data; | 259 | msg->data = data; |
| 264 | } | 260 | } |
| @@ -302,24 +298,24 @@ void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | |||
| 302 | writel(msg->data, base + PCI_MSIX_ENTRY_DATA); | 298 | writel(msg->data, base + PCI_MSIX_ENTRY_DATA); |
| 303 | } else { | 299 | } else { |
| 304 | struct pci_dev *dev = entry->dev; | 300 | struct pci_dev *dev = entry->dev; |
| 305 | int pos = entry->msi_attrib.pos; | 301 | int pos = dev->msi_cap; |
| 306 | u16 msgctl; | 302 | u16 msgctl; |
| 307 | 303 | ||
| 308 | pci_read_config_word(dev, msi_control_reg(pos), &msgctl); | 304 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); |
| 309 | msgctl &= ~PCI_MSI_FLAGS_QSIZE; | 305 | msgctl &= ~PCI_MSI_FLAGS_QSIZE; |
| 310 | msgctl |= entry->msi_attrib.multiple << 4; | 306 | msgctl |= entry->msi_attrib.multiple << 4; |
| 311 | pci_write_config_word(dev, msi_control_reg(pos), msgctl); | 307 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, msgctl); |
| 312 | 308 | ||
| 313 | pci_write_config_dword(dev, msi_lower_address_reg(pos), | 309 | pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, |
| 314 | msg->address_lo); | 310 | msg->address_lo); |
| 315 | if (entry->msi_attrib.is_64) { | 311 | if (entry->msi_attrib.is_64) { |
| 316 | pci_write_config_dword(dev, msi_upper_address_reg(pos), | 312 | pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, |
| 317 | msg->address_hi); | 313 | msg->address_hi); |
| 318 | pci_write_config_word(dev, msi_data_reg(pos, 1), | 314 | pci_write_config_word(dev, pos + PCI_MSI_DATA_64, |
| 319 | msg->data); | 315 | msg->data); |
| 320 | } else { | 316 | } else { |
| 321 | pci_write_config_word(dev, msi_data_reg(pos, 0), | 317 | pci_write_config_word(dev, pos + PCI_MSI_DATA_32, |
| 322 | msg->data); | 318 | msg->data); |
| 323 | } | 319 | } |
| 324 | } | 320 | } |
| 325 | entry->msg = *msg; | 321 | entry->msg = *msg; |
| @@ -391,7 +387,6 @@ static void pci_intx_for_msi(struct pci_dev *dev, int enable) | |||
| 391 | 387 | ||
| 392 | static void __pci_restore_msi_state(struct pci_dev *dev) | 388 | static void __pci_restore_msi_state(struct pci_dev *dev) |
| 393 | { | 389 | { |
| 394 | int pos; | ||
| 395 | u16 control; | 390 | u16 control; |
| 396 | struct msi_desc *entry; | 391 | struct msi_desc *entry; |
| 397 | 392 | ||
| @@ -399,22 +394,20 @@ static void __pci_restore_msi_state(struct pci_dev *dev) | |||
| 399 | return; | 394 | return; |
| 400 | 395 | ||
| 401 | entry = irq_get_msi_desc(dev->irq); | 396 | entry = irq_get_msi_desc(dev->irq); |
| 402 | pos = entry->msi_attrib.pos; | ||
| 403 | 397 | ||
| 404 | pci_intx_for_msi(dev, 0); | 398 | pci_intx_for_msi(dev, 0); |
| 405 | msi_set_enable(dev, pos, 0); | 399 | msi_set_enable(dev, 0); |
| 406 | arch_restore_msi_irqs(dev, dev->irq); | 400 | arch_restore_msi_irqs(dev, dev->irq); |
| 407 | 401 | ||
| 408 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); | 402 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); |
| 409 | msi_mask_irq(entry, msi_capable_mask(control), entry->masked); | 403 | msi_mask_irq(entry, msi_capable_mask(control), entry->masked); |
| 410 | control &= ~PCI_MSI_FLAGS_QSIZE; | 404 | control &= ~PCI_MSI_FLAGS_QSIZE; |
| 411 | control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE; | 405 | control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE; |
| 412 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); | 406 | pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); |
| 413 | } | 407 | } |
| 414 | 408 | ||
| 415 | static void __pci_restore_msix_state(struct pci_dev *dev) | 409 | static void __pci_restore_msix_state(struct pci_dev *dev) |
| 416 | { | 410 | { |
| 417 | int pos; | ||
| 418 | struct msi_desc *entry; | 411 | struct msi_desc *entry; |
| 419 | u16 control; | 412 | u16 control; |
| 420 | 413 | ||
| @@ -422,13 +415,12 @@ static void __pci_restore_msix_state(struct pci_dev *dev) | |||
| 422 | return; | 415 | return; |
| 423 | BUG_ON(list_empty(&dev->msi_list)); | 416 | BUG_ON(list_empty(&dev->msi_list)); |
| 424 | entry = list_first_entry(&dev->msi_list, struct msi_desc, list); | 417 | entry = list_first_entry(&dev->msi_list, struct msi_desc, list); |
| 425 | pos = entry->msi_attrib.pos; | 418 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); |
| 426 | pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); | ||
| 427 | 419 | ||
| 428 | /* route the table */ | 420 | /* route the table */ |
| 429 | pci_intx_for_msi(dev, 0); | 421 | pci_intx_for_msi(dev, 0); |
| 430 | control |= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL; | 422 | control |= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL; |
| 431 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | 423 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); |
| 432 | 424 | ||
| 433 | list_for_each_entry(entry, &dev->msi_list, list) { | 425 | list_for_each_entry(entry, &dev->msi_list, list) { |
| 434 | arch_restore_msi_irqs(dev, entry->irq); | 426 | arch_restore_msi_irqs(dev, entry->irq); |
| @@ -436,7 +428,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev) | |||
| 436 | } | 428 | } |
| 437 | 429 | ||
| 438 | control &= ~PCI_MSIX_FLAGS_MASKALL; | 430 | control &= ~PCI_MSIX_FLAGS_MASKALL; |
| 439 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | 431 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); |
| 440 | } | 432 | } |
| 441 | 433 | ||
| 442 | void pci_restore_msi_state(struct pci_dev *dev) | 434 | void pci_restore_msi_state(struct pci_dev *dev) |
| @@ -484,12 +476,12 @@ static struct msi_attribute mode_attribute = | |||
| 484 | __ATTR(mode, S_IRUGO, show_msi_mode, NULL); | 476 | __ATTR(mode, S_IRUGO, show_msi_mode, NULL); |
| 485 | 477 | ||
| 486 | 478 | ||
| 487 | struct attribute *msi_irq_default_attrs[] = { | 479 | static struct attribute *msi_irq_default_attrs[] = { |
| 488 | &mode_attribute.attr, | 480 | &mode_attribute.attr, |
| 489 | NULL | 481 | NULL |
| 490 | }; | 482 | }; |
| 491 | 483 | ||
| 492 | void msi_kobj_release(struct kobject *kobj) | 484 | static void msi_kobj_release(struct kobject *kobj) |
| 493 | { | 485 | { |
| 494 | struct msi_desc *entry = to_msi_desc(kobj); | 486 | struct msi_desc *entry = to_msi_desc(kobj); |
| 495 | 487 | ||
| @@ -552,27 +544,27 @@ out_unroll: | |||
| 552 | static int msi_capability_init(struct pci_dev *dev, int nvec) | 544 | static int msi_capability_init(struct pci_dev *dev, int nvec) |
| 553 | { | 545 | { |
| 554 | struct msi_desc *entry; | 546 | struct msi_desc *entry; |
| 555 | int pos, ret; | 547 | int ret; |
| 556 | u16 control; | 548 | u16 control; |
| 557 | unsigned mask; | 549 | unsigned mask; |
| 558 | 550 | ||
| 559 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 551 | msi_set_enable(dev, 0); /* Disable MSI during set up */ |
| 560 | msi_set_enable(dev, pos, 0); /* Disable MSI during set up */ | ||
| 561 | 552 | ||
| 562 | pci_read_config_word(dev, msi_control_reg(pos), &control); | 553 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); |
| 563 | /* MSI Entry Initialization */ | 554 | /* MSI Entry Initialization */ |
| 564 | entry = alloc_msi_entry(dev); | 555 | entry = alloc_msi_entry(dev); |
| 565 | if (!entry) | 556 | if (!entry) |
| 566 | return -ENOMEM; | 557 | return -ENOMEM; |
| 567 | 558 | ||
| 568 | entry->msi_attrib.is_msix = 0; | 559 | entry->msi_attrib.is_msix = 0; |
| 569 | entry->msi_attrib.is_64 = is_64bit_address(control); | 560 | entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT); |
| 570 | entry->msi_attrib.entry_nr = 0; | 561 | entry->msi_attrib.entry_nr = 0; |
| 571 | entry->msi_attrib.maskbit = is_mask_bit_support(control); | 562 | entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT); |
| 572 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ | 563 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ |
| 573 | entry->msi_attrib.pos = pos; | 564 | entry->msi_attrib.pos = dev->msi_cap; |
| 574 | 565 | ||
| 575 | entry->mask_pos = msi_mask_reg(pos, entry->msi_attrib.is_64); | 566 | entry->mask_pos = dev->msi_cap + (control & PCI_MSI_FLAGS_64BIT) ? |
| 567 | PCI_MSI_MASK_64 : PCI_MSI_MASK_32; | ||
| 576 | /* All MSIs are unmasked by default, Mask them all */ | 568 | /* All MSIs are unmasked by default, Mask them all */ |
| 577 | if (entry->msi_attrib.maskbit) | 569 | if (entry->msi_attrib.maskbit) |
| 578 | pci_read_config_dword(dev, entry->mask_pos, &entry->masked); | 570 | pci_read_config_dword(dev, entry->mask_pos, &entry->masked); |
| @@ -598,31 +590,30 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) | |||
| 598 | 590 | ||
| 599 | /* Set MSI enabled bits */ | 591 | /* Set MSI enabled bits */ |
| 600 | pci_intx_for_msi(dev, 0); | 592 | pci_intx_for_msi(dev, 0); |
| 601 | msi_set_enable(dev, pos, 1); | 593 | msi_set_enable(dev, 1); |
| 602 | dev->msi_enabled = 1; | 594 | dev->msi_enabled = 1; |
| 603 | 595 | ||
| 604 | dev->irq = entry->irq; | 596 | dev->irq = entry->irq; |
| 605 | return 0; | 597 | return 0; |
| 606 | } | 598 | } |
| 607 | 599 | ||
| 608 | static void __iomem *msix_map_region(struct pci_dev *dev, unsigned pos, | 600 | static void __iomem *msix_map_region(struct pci_dev *dev, unsigned nr_entries) |
| 609 | unsigned nr_entries) | ||
| 610 | { | 601 | { |
| 611 | resource_size_t phys_addr; | 602 | resource_size_t phys_addr; |
| 612 | u32 table_offset; | 603 | u32 table_offset; |
| 613 | u8 bir; | 604 | u8 bir; |
| 614 | 605 | ||
| 615 | pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset); | 606 | pci_read_config_dword(dev, dev->msix_cap + PCI_MSIX_TABLE, |
| 616 | bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); | 607 | &table_offset); |
| 617 | table_offset &= ~PCI_MSIX_FLAGS_BIRMASK; | 608 | bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); |
| 609 | table_offset &= PCI_MSIX_TABLE_OFFSET; | ||
| 618 | phys_addr = pci_resource_start(dev, bir) + table_offset; | 610 | phys_addr = pci_resource_start(dev, bir) + table_offset; |
| 619 | 611 | ||
| 620 | return ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); | 612 | return ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); |
| 621 | } | 613 | } |
| 622 | 614 | ||
| 623 | static int msix_setup_entries(struct pci_dev *dev, unsigned pos, | 615 | static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, |
| 624 | void __iomem *base, struct msix_entry *entries, | 616 | struct msix_entry *entries, int nvec) |
| 625 | int nvec) | ||
| 626 | { | 617 | { |
| 627 | struct msi_desc *entry; | 618 | struct msi_desc *entry; |
| 628 | int i; | 619 | int i; |
| @@ -642,7 +633,7 @@ static int msix_setup_entries(struct pci_dev *dev, unsigned pos, | |||
| 642 | entry->msi_attrib.is_64 = 1; | 633 | entry->msi_attrib.is_64 = 1; |
| 643 | entry->msi_attrib.entry_nr = entries[i].entry; | 634 | entry->msi_attrib.entry_nr = entries[i].entry; |
| 644 | entry->msi_attrib.default_irq = dev->irq; | 635 | entry->msi_attrib.default_irq = dev->irq; |
| 645 | entry->msi_attrib.pos = pos; | 636 | entry->msi_attrib.pos = dev->msix_cap; |
| 646 | entry->mask_base = base; | 637 | entry->mask_base = base; |
| 647 | 638 | ||
| 648 | list_add_tail(&entry->list, &dev->msi_list); | 639 | list_add_tail(&entry->list, &dev->msi_list); |
| @@ -652,7 +643,7 @@ static int msix_setup_entries(struct pci_dev *dev, unsigned pos, | |||
| 652 | } | 643 | } |
| 653 | 644 | ||
| 654 | static void msix_program_entries(struct pci_dev *dev, | 645 | static void msix_program_entries(struct pci_dev *dev, |
| 655 | struct msix_entry *entries) | 646 | struct msix_entry *entries) |
| 656 | { | 647 | { |
| 657 | struct msi_desc *entry; | 648 | struct msi_desc *entry; |
| 658 | int i = 0; | 649 | int i = 0; |
| @@ -682,23 +673,22 @@ static void msix_program_entries(struct pci_dev *dev, | |||
| 682 | static int msix_capability_init(struct pci_dev *dev, | 673 | static int msix_capability_init(struct pci_dev *dev, |
| 683 | struct msix_entry *entries, int nvec) | 674 | struct msix_entry *entries, int nvec) |
| 684 | { | 675 | { |
| 685 | int pos, ret; | 676 | int ret; |
| 686 | u16 control; | 677 | u16 control; |
| 687 | void __iomem *base; | 678 | void __iomem *base; |
| 688 | 679 | ||
| 689 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | 680 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); |
| 690 | pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); | ||
| 691 | 681 | ||
| 692 | /* Ensure MSI-X is disabled while it is set up */ | 682 | /* Ensure MSI-X is disabled while it is set up */ |
| 693 | control &= ~PCI_MSIX_FLAGS_ENABLE; | 683 | control &= ~PCI_MSIX_FLAGS_ENABLE; |
| 694 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | 684 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); |
| 695 | 685 | ||
| 696 | /* Request & Map MSI-X table region */ | 686 | /* Request & Map MSI-X table region */ |
| 697 | base = msix_map_region(dev, pos, multi_msix_capable(control)); | 687 | base = msix_map_region(dev, msix_table_size(control)); |
| 698 | if (!base) | 688 | if (!base) |
| 699 | return -ENOMEM; | 689 | return -ENOMEM; |
| 700 | 690 | ||
| 701 | ret = msix_setup_entries(dev, pos, base, entries, nvec); | 691 | ret = msix_setup_entries(dev, base, entries, nvec); |
| 702 | if (ret) | 692 | if (ret) |
| 703 | return ret; | 693 | return ret; |
| 704 | 694 | ||
| @@ -712,7 +702,7 @@ static int msix_capability_init(struct pci_dev *dev, | |||
| 712 | * interrupts coming in before they're fully set up. | 702 | * interrupts coming in before they're fully set up. |
| 713 | */ | 703 | */ |
| 714 | control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE; | 704 | control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE; |
| 715 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | 705 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); |
| 716 | 706 | ||
| 717 | msix_program_entries(dev, entries); | 707 | msix_program_entries(dev, entries); |
| 718 | 708 | ||
| @@ -727,7 +717,7 @@ static int msix_capability_init(struct pci_dev *dev, | |||
| 727 | dev->msix_enabled = 1; | 717 | dev->msix_enabled = 1; |
| 728 | 718 | ||
| 729 | control &= ~PCI_MSIX_FLAGS_MASKALL; | 719 | control &= ~PCI_MSIX_FLAGS_MASKALL; |
| 730 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | 720 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); |
| 731 | 721 | ||
| 732 | return 0; | 722 | return 0; |
| 733 | 723 | ||
| @@ -795,9 +785,6 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) | |||
| 795 | if (ret) | 785 | if (ret) |
| 796 | return ret; | 786 | return ret; |
| 797 | 787 | ||
| 798 | if (!pci_find_capability(dev, type)) | ||
| 799 | return -EINVAL; | ||
| 800 | |||
| 801 | return 0; | 788 | return 0; |
| 802 | } | 789 | } |
| 803 | 790 | ||
| @@ -816,13 +803,13 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) | |||
| 816 | */ | 803 | */ |
| 817 | int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) | 804 | int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) |
| 818 | { | 805 | { |
| 819 | int status, pos, maxvec; | 806 | int status, maxvec; |
| 820 | u16 msgctl; | 807 | u16 msgctl; |
| 821 | 808 | ||
| 822 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 809 | if (!dev->msi_cap) |
| 823 | if (!pos) | ||
| 824 | return -EINVAL; | 810 | return -EINVAL; |
| 825 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); | 811 | |
| 812 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); | ||
| 826 | maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); | 813 | maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); |
| 827 | if (nvec > maxvec) | 814 | if (nvec > maxvec) |
| 828 | return maxvec; | 815 | return maxvec; |
| @@ -847,14 +834,13 @@ EXPORT_SYMBOL(pci_enable_msi_block); | |||
| 847 | 834 | ||
| 848 | int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec) | 835 | int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec) |
| 849 | { | 836 | { |
| 850 | int ret, pos, nvec; | 837 | int ret, nvec; |
| 851 | u16 msgctl; | 838 | u16 msgctl; |
| 852 | 839 | ||
| 853 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 840 | if (!dev->msi_cap) |
| 854 | if (!pos) | ||
| 855 | return -EINVAL; | 841 | return -EINVAL; |
| 856 | 842 | ||
| 857 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); | 843 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); |
| 858 | ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); | 844 | ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); |
| 859 | 845 | ||
| 860 | if (maxvec) | 846 | if (maxvec) |
| @@ -876,21 +862,19 @@ void pci_msi_shutdown(struct pci_dev *dev) | |||
| 876 | struct msi_desc *desc; | 862 | struct msi_desc *desc; |
| 877 | u32 mask; | 863 | u32 mask; |
| 878 | u16 ctrl; | 864 | u16 ctrl; |
| 879 | unsigned pos; | ||
| 880 | 865 | ||
| 881 | if (!pci_msi_enable || !dev || !dev->msi_enabled) | 866 | if (!pci_msi_enable || !dev || !dev->msi_enabled) |
| 882 | return; | 867 | return; |
| 883 | 868 | ||
| 884 | BUG_ON(list_empty(&dev->msi_list)); | 869 | BUG_ON(list_empty(&dev->msi_list)); |
| 885 | desc = list_first_entry(&dev->msi_list, struct msi_desc, list); | 870 | desc = list_first_entry(&dev->msi_list, struct msi_desc, list); |
| 886 | pos = desc->msi_attrib.pos; | ||
| 887 | 871 | ||
| 888 | msi_set_enable(dev, pos, 0); | 872 | msi_set_enable(dev, 0); |
| 889 | pci_intx_for_msi(dev, 1); | 873 | pci_intx_for_msi(dev, 1); |
| 890 | dev->msi_enabled = 0; | 874 | dev->msi_enabled = 0; |
| 891 | 875 | ||
| 892 | /* Return the device with MSI unmasked as initial states */ | 876 | /* Return the device with MSI unmasked as initial states */ |
| 893 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &ctrl); | 877 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &ctrl); |
| 894 | mask = msi_capable_mask(ctrl); | 878 | mask = msi_capable_mask(ctrl); |
| 895 | /* Keep cached state to be restored */ | 879 | /* Keep cached state to be restored */ |
| 896 | __msi_mask_irq(desc, mask, ~mask); | 880 | __msi_mask_irq(desc, mask, ~mask); |
| @@ -917,15 +901,13 @@ EXPORT_SYMBOL(pci_disable_msi); | |||
| 917 | */ | 901 | */ |
| 918 | int pci_msix_table_size(struct pci_dev *dev) | 902 | int pci_msix_table_size(struct pci_dev *dev) |
| 919 | { | 903 | { |
| 920 | int pos; | ||
| 921 | u16 control; | 904 | u16 control; |
| 922 | 905 | ||
| 923 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | 906 | if (!dev->msix_cap) |
| 924 | if (!pos) | ||
| 925 | return 0; | 907 | return 0; |
| 926 | 908 | ||
| 927 | pci_read_config_word(dev, msi_control_reg(pos), &control); | 909 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); |
| 928 | return multi_msix_capable(control); | 910 | return msix_table_size(control); |
| 929 | } | 911 | } |
| 930 | 912 | ||
| 931 | /** | 913 | /** |
| @@ -948,7 +930,7 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) | |||
| 948 | int status, nr_entries; | 930 | int status, nr_entries; |
| 949 | int i, j; | 931 | int i, j; |
| 950 | 932 | ||
| 951 | if (!entries) | 933 | if (!entries || !dev->msix_cap) |
| 952 | return -EINVAL; | 934 | return -EINVAL; |
| 953 | 935 | ||
| 954 | status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX); | 936 | status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX); |
| @@ -1048,15 +1030,17 @@ EXPORT_SYMBOL(pci_msi_enabled); | |||
| 1048 | 1030 | ||
| 1049 | void pci_msi_init_pci_dev(struct pci_dev *dev) | 1031 | void pci_msi_init_pci_dev(struct pci_dev *dev) |
| 1050 | { | 1032 | { |
| 1051 | int pos; | ||
| 1052 | INIT_LIST_HEAD(&dev->msi_list); | 1033 | INIT_LIST_HEAD(&dev->msi_list); |
| 1053 | 1034 | ||
| 1054 | /* Disable the msi hardware to avoid screaming interrupts | 1035 | /* Disable the msi hardware to avoid screaming interrupts |
| 1055 | * during boot. This is the power on reset default so | 1036 | * during boot. This is the power on reset default so |
| 1056 | * usually this should be a noop. | 1037 | * usually this should be a noop. |
| 1057 | */ | 1038 | */ |
| 1058 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 1039 | dev->msi_cap = pci_find_capability(dev, PCI_CAP_ID_MSI); |
| 1059 | if (pos) | 1040 | if (dev->msi_cap) |
| 1060 | msi_set_enable(dev, pos, 0); | 1041 | msi_set_enable(dev, 0); |
| 1061 | msix_set_enable(dev, 0); | 1042 | |
| 1043 | dev->msix_cap = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
| 1044 | if (dev->msix_cap) | ||
| 1045 | msix_set_enable(dev, 0); | ||
| 1062 | } | 1046 | } |
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h deleted file mode 100644 index 65c42f80f23e..000000000000 --- a/drivers/pci/msi.h +++ /dev/null | |||
| @@ -1,24 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2003-2004 Intel | ||
| 3 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef MSI_H | ||
| 7 | #define MSI_H | ||
| 8 | |||
| 9 | #define msi_control_reg(base) (base + PCI_MSI_FLAGS) | ||
| 10 | #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) | ||
| 11 | #define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) | ||
| 12 | #define msi_data_reg(base, is64bit) \ | ||
| 13 | (base + ((is64bit == 1) ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32)) | ||
| 14 | #define msi_mask_reg(base, is64bit) \ | ||
| 15 | (base + ((is64bit == 1) ? PCI_MSI_MASK_64 : PCI_MSI_MASK_32)) | ||
| 16 | #define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT)) | ||
| 17 | #define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT)) | ||
| 18 | |||
| 19 | #define msix_table_offset_reg(base) (base + PCI_MSIX_TABLE) | ||
| 20 | #define msix_pba_offset_reg(base) (base + PCI_MSIX_PBA) | ||
| 21 | #define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) | ||
| 22 | #define multi_msix_capable(control) msix_table_size((control)) | ||
| 23 | |||
| 24 | #endif /* MSI_H */ | ||
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 5147c210df52..e4b1fb2c0f5d 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
| @@ -288,6 +288,32 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { | |||
| 288 | .run_wake = acpi_pci_run_wake, | 288 | .run_wake = acpi_pci_run_wake, |
| 289 | }; | 289 | }; |
| 290 | 290 | ||
| 291 | void acpi_pci_add_bus(struct pci_bus *bus) | ||
| 292 | { | ||
| 293 | acpi_handle handle = NULL; | ||
| 294 | |||
| 295 | if (bus->bridge) | ||
| 296 | handle = ACPI_HANDLE(bus->bridge); | ||
| 297 | if (acpi_pci_disabled || handle == NULL) | ||
| 298 | return; | ||
| 299 | |||
| 300 | acpi_pci_slot_enumerate(bus, handle); | ||
| 301 | acpiphp_enumerate_slots(bus, handle); | ||
| 302 | } | ||
| 303 | |||
| 304 | void acpi_pci_remove_bus(struct pci_bus *bus) | ||
| 305 | { | ||
| 306 | /* | ||
| 307 | * bus->bridge->acpi_node.handle has already been reset to NULL | ||
| 308 | * when acpi_pci_remove_bus() is called, so don't check ACPI handle. | ||
| 309 | */ | ||
| 310 | if (acpi_pci_disabled) | ||
| 311 | return; | ||
| 312 | |||
| 313 | acpiphp_remove_slots(bus); | ||
| 314 | acpi_pci_slot_remove(bus); | ||
| 315 | } | ||
| 316 | |||
| 291 | /* ACPI bus type */ | 317 | /* ACPI bus type */ |
| 292 | static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) | 318 | static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) |
| 293 | { | 319 | { |
| @@ -362,7 +388,11 @@ static int __init acpi_pci_init(void) | |||
| 362 | ret = register_acpi_bus_type(&acpi_pci_bus); | 388 | ret = register_acpi_bus_type(&acpi_pci_bus); |
| 363 | if (ret) | 389 | if (ret) |
| 364 | return 0; | 390 | return 0; |
| 391 | |||
| 365 | pci_set_platform_pm(&acpi_pci_platform_pm); | 392 | pci_set_platform_pm(&acpi_pci_platform_pm); |
| 393 | acpi_pci_slot_init(); | ||
| 394 | acpiphp_init(); | ||
| 395 | |||
| 366 | return 0; | 396 | return 0; |
| 367 | } | 397 | } |
| 368 | arch_initcall(acpi_pci_init); | 398 | arch_initcall(acpi_pci_init); |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 9c6e9bb674ec..5b4a9d9cd200 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
| @@ -897,7 +897,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma, | |||
| 897 | 897 | ||
| 898 | if (pci_resource_len(pdev, resno) == 0) | 898 | if (pci_resource_len(pdev, resno) == 0) |
| 899 | return 0; | 899 | return 0; |
| 900 | nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | 900 | nr = vma_pages(vma); |
| 901 | start = vma->vm_pgoff; | 901 | start = vma->vm_pgoff; |
| 902 | size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; | 902 | size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; |
| 903 | pci_start = (mmap_api == PCI_MMAP_PROCFS) ? | 903 | pci_start = (mmap_api == PCI_MMAP_PROCFS) ? |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b099e0025d2b..a899d8bb190d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -646,15 +646,11 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) | |||
| 646 | error = platform_pci_set_power_state(dev, state); | 646 | error = platform_pci_set_power_state(dev, state); |
| 647 | if (!error) | 647 | if (!error) |
| 648 | pci_update_current_state(dev, state); | 648 | pci_update_current_state(dev, state); |
| 649 | /* Fall back to PCI_D0 if native PM is not supported */ | 649 | } else |
| 650 | if (!dev->pm_cap) | ||
| 651 | dev->current_state = PCI_D0; | ||
| 652 | } else { | ||
| 653 | error = -ENODEV; | 650 | error = -ENODEV; |
| 654 | /* Fall back to PCI_D0 if native PM is not supported */ | 651 | |
| 655 | if (!dev->pm_cap) | 652 | if (error && !dev->pm_cap) /* Fall back to PCI_D0 */ |
| 656 | dev->current_state = PCI_D0; | 653 | dev->current_state = PCI_D0; |
| 657 | } | ||
| 658 | 654 | ||
| 659 | return error; | 655 | return error; |
| 660 | } | 656 | } |
| @@ -1575,7 +1571,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
| 1575 | { | 1571 | { |
| 1576 | u16 pmcsr; | 1572 | u16 pmcsr; |
| 1577 | 1573 | ||
| 1578 | if (!dev->pm_cap) | 1574 | if (!dev->pme_support) |
| 1579 | return; | 1575 | return; |
| 1580 | 1576 | ||
| 1581 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); | 1577 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); |
| @@ -1924,6 +1920,7 @@ void pci_pm_init(struct pci_dev *dev) | |||
| 1924 | dev->wakeup_prepared = false; | 1920 | dev->wakeup_prepared = false; |
| 1925 | 1921 | ||
| 1926 | dev->pm_cap = 0; | 1922 | dev->pm_cap = 0; |
| 1923 | dev->pme_support = 0; | ||
| 1927 | 1924 | ||
| 1928 | /* find PCI PM capability in list */ | 1925 | /* find PCI PM capability in list */ |
| 1929 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); | 1926 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); |
| @@ -1975,8 +1972,6 @@ void pci_pm_init(struct pci_dev *dev) | |||
| 1975 | device_set_wakeup_capable(&dev->dev, true); | 1972 | device_set_wakeup_capable(&dev->dev, true); |
| 1976 | /* Disable the PME# generation functionality */ | 1973 | /* Disable the PME# generation functionality */ |
| 1977 | pci_pme_active(dev, false); | 1974 | pci_pme_active(dev, false); |
| 1978 | } else { | ||
| 1979 | dev->pme_support = 0; | ||
| 1980 | } | 1975 | } |
| 1981 | } | 1976 | } |
| 1982 | 1977 | ||
| @@ -2619,7 +2614,7 @@ void pci_release_selected_regions(struct pci_dev *pdev, int bars) | |||
| 2619 | pci_release_region(pdev, i); | 2614 | pci_release_region(pdev, i); |
| 2620 | } | 2615 | } |
| 2621 | 2616 | ||
| 2622 | int __pci_request_selected_regions(struct pci_dev *pdev, int bars, | 2617 | static int __pci_request_selected_regions(struct pci_dev *pdev, int bars, |
| 2623 | const char *res_name, int excl) | 2618 | const char *res_name, int excl) |
| 2624 | { | 2619 | { |
| 2625 | int i; | 2620 | int i; |
| @@ -3699,7 +3694,7 @@ static DEFINE_SPINLOCK(resource_alignment_lock); | |||
| 3699 | * RETURNS: Resource alignment if it is specified. | 3694 | * RETURNS: Resource alignment if it is specified. |
| 3700 | * Zero if it is not specified. | 3695 | * Zero if it is not specified. |
| 3701 | */ | 3696 | */ |
| 3702 | resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) | 3697 | static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) |
| 3703 | { | 3698 | { |
| 3704 | int seg, bus, slot, func, align_order, count; | 3699 | int seg, bus, slot, func, align_order, count; |
| 3705 | resource_size_t align = 0; | 3700 | resource_size_t align = 0; |
| @@ -3812,7 +3807,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) | |||
| 3812 | } | 3807 | } |
| 3813 | } | 3808 | } |
| 3814 | 3809 | ||
| 3815 | ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) | 3810 | static ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) |
| 3816 | { | 3811 | { |
| 3817 | if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) | 3812 | if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) |
| 3818 | count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1; | 3813 | count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1; |
| @@ -3823,7 +3818,7 @@ ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) | |||
| 3823 | return count; | 3818 | return count; |
| 3824 | } | 3819 | } |
| 3825 | 3820 | ||
| 3826 | ssize_t pci_get_resource_alignment_param(char *buf, size_t size) | 3821 | static ssize_t pci_get_resource_alignment_param(char *buf, size_t size) |
| 3827 | { | 3822 | { |
| 3828 | size_t count; | 3823 | size_t count; |
| 3829 | spin_lock(&resource_alignment_lock); | 3824 | spin_lock(&resource_alignment_lock); |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 7346ee68f47d..68678ed76b0d 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -8,26 +8,25 @@ | |||
| 8 | 8 | ||
| 9 | /* Functions internal to the PCI core code */ | 9 | /* Functions internal to the PCI core code */ |
| 10 | 10 | ||
| 11 | extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); | 11 | int pci_create_sysfs_dev_files(struct pci_dev *pdev); |
| 12 | extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); | 12 | void pci_remove_sysfs_dev_files(struct pci_dev *pdev); |
| 13 | #if !defined(CONFIG_DMI) && !defined(CONFIG_ACPI) | 13 | #if !defined(CONFIG_DMI) && !defined(CONFIG_ACPI) |
| 14 | static inline void pci_create_firmware_label_files(struct pci_dev *pdev) | 14 | static inline void pci_create_firmware_label_files(struct pci_dev *pdev) |
| 15 | { return; } | 15 | { return; } |
| 16 | static inline void pci_remove_firmware_label_files(struct pci_dev *pdev) | 16 | static inline void pci_remove_firmware_label_files(struct pci_dev *pdev) |
| 17 | { return; } | 17 | { return; } |
| 18 | #else | 18 | #else |
| 19 | extern void pci_create_firmware_label_files(struct pci_dev *pdev); | 19 | void pci_create_firmware_label_files(struct pci_dev *pdev); |
| 20 | extern void pci_remove_firmware_label_files(struct pci_dev *pdev); | 20 | void pci_remove_firmware_label_files(struct pci_dev *pdev); |
| 21 | #endif | 21 | #endif |
| 22 | extern void pci_cleanup_rom(struct pci_dev *dev); | 22 | void pci_cleanup_rom(struct pci_dev *dev); |
| 23 | #ifdef HAVE_PCI_MMAP | 23 | #ifdef HAVE_PCI_MMAP |
| 24 | enum pci_mmap_api { | 24 | enum pci_mmap_api { |
| 25 | PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */ | 25 | PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */ |
| 26 | PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/<BDF> */ | 26 | PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/<BDF> */ |
| 27 | }; | 27 | }; |
| 28 | extern int pci_mmap_fits(struct pci_dev *pdev, int resno, | 28 | int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vmai, |
| 29 | struct vm_area_struct *vmai, | 29 | enum pci_mmap_api mmap_api); |
| 30 | enum pci_mmap_api mmap_api); | ||
| 31 | #endif | 30 | #endif |
| 32 | int pci_probe_reset_function(struct pci_dev *dev); | 31 | int pci_probe_reset_function(struct pci_dev *dev); |
| 33 | 32 | ||
| @@ -60,17 +59,17 @@ struct pci_platform_pm_ops { | |||
| 60 | int (*run_wake)(struct pci_dev *dev, bool enable); | 59 | int (*run_wake)(struct pci_dev *dev, bool enable); |
| 61 | }; | 60 | }; |
| 62 | 61 | ||
| 63 | extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); | 62 | int pci_set_platform_pm(struct pci_platform_pm_ops *ops); |
| 64 | extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); | 63 | void pci_update_current_state(struct pci_dev *dev, pci_power_t state); |
| 65 | extern void pci_power_up(struct pci_dev *dev); | 64 | void pci_power_up(struct pci_dev *dev); |
| 66 | extern void pci_disable_enabled_device(struct pci_dev *dev); | 65 | void pci_disable_enabled_device(struct pci_dev *dev); |
| 67 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); | 66 | int pci_finish_runtime_suspend(struct pci_dev *dev); |
| 68 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); | 67 | int __pci_pme_wakeup(struct pci_dev *dev, void *ign); |
| 69 | extern void pci_wakeup_bus(struct pci_bus *bus); | 68 | void pci_wakeup_bus(struct pci_bus *bus); |
| 70 | extern void pci_config_pm_runtime_get(struct pci_dev *dev); | 69 | void pci_config_pm_runtime_get(struct pci_dev *dev); |
| 71 | extern void pci_config_pm_runtime_put(struct pci_dev *dev); | 70 | void pci_config_pm_runtime_put(struct pci_dev *dev); |
| 72 | extern void pci_pm_init(struct pci_dev *dev); | 71 | void pci_pm_init(struct pci_dev *dev); |
| 73 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 72 | void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
| 74 | void pci_free_cap_save_buffers(struct pci_dev *dev); | 73 | void pci_free_cap_save_buffers(struct pci_dev *dev); |
| 75 | 74 | ||
| 76 | static inline void pci_wakeup_event(struct pci_dev *dev) | 75 | static inline void pci_wakeup_event(struct pci_dev *dev) |
| @@ -96,7 +95,7 @@ struct pci_vpd { | |||
| 96 | struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ | 95 | struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ |
| 97 | }; | 96 | }; |
| 98 | 97 | ||
| 99 | extern int pci_vpd_pci22_init(struct pci_dev *dev); | 98 | int pci_vpd_pci22_init(struct pci_dev *dev); |
| 100 | static inline void pci_vpd_release(struct pci_dev *dev) | 99 | static inline void pci_vpd_release(struct pci_dev *dev) |
| 101 | { | 100 | { |
| 102 | if (dev->vpd) | 101 | if (dev->vpd) |
| @@ -105,9 +104,9 @@ static inline void pci_vpd_release(struct pci_dev *dev) | |||
| 105 | 104 | ||
| 106 | /* PCI /proc functions */ | 105 | /* PCI /proc functions */ |
| 107 | #ifdef CONFIG_PROC_FS | 106 | #ifdef CONFIG_PROC_FS |
| 108 | extern int pci_proc_attach_device(struct pci_dev *dev); | 107 | int pci_proc_attach_device(struct pci_dev *dev); |
| 109 | extern int pci_proc_detach_device(struct pci_dev *dev); | 108 | int pci_proc_detach_device(struct pci_dev *dev); |
| 110 | extern int pci_proc_detach_bus(struct pci_bus *bus); | 109 | int pci_proc_detach_bus(struct pci_bus *bus); |
| 111 | #else | 110 | #else |
| 112 | static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; } | 111 | static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; } |
| 113 | static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; } | 112 | static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; } |
| @@ -118,8 +117,8 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } | |||
| 118 | int pci_hp_add_bridge(struct pci_dev *dev); | 117 | int pci_hp_add_bridge(struct pci_dev *dev); |
| 119 | 118 | ||
| 120 | #ifdef HAVE_PCI_LEGACY | 119 | #ifdef HAVE_PCI_LEGACY |
| 121 | extern void pci_create_legacy_files(struct pci_bus *bus); | 120 | void pci_create_legacy_files(struct pci_bus *bus); |
| 122 | extern void pci_remove_legacy_files(struct pci_bus *bus); | 121 | void pci_remove_legacy_files(struct pci_bus *bus); |
| 123 | #else | 122 | #else |
| 124 | static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } | 123 | static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } |
| 125 | static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; } | 124 | static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; } |
| @@ -134,7 +133,7 @@ extern unsigned int pci_pm_d3_delay; | |||
| 134 | 133 | ||
| 135 | #ifdef CONFIG_PCI_MSI | 134 | #ifdef CONFIG_PCI_MSI |
| 136 | void pci_no_msi(void); | 135 | void pci_no_msi(void); |
| 137 | extern void pci_msi_init_pci_dev(struct pci_dev *dev); | 136 | void pci_msi_init_pci_dev(struct pci_dev *dev); |
| 138 | #else | 137 | #else |
| 139 | static inline void pci_no_msi(void) { } | 138 | static inline void pci_no_msi(void) { } |
| 140 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } | 139 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } |
| @@ -198,12 +197,11 @@ enum pci_bar_type { | |||
| 198 | 197 | ||
| 199 | bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, | 198 | bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, |
| 200 | int crs_timeout); | 199 | int crs_timeout); |
| 201 | extern int pci_setup_device(struct pci_dev *dev); | 200 | int pci_setup_device(struct pci_dev *dev); |
| 202 | extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | 201 | int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, |
| 203 | struct resource *res, unsigned int reg); | 202 | struct resource *res, unsigned int reg); |
| 204 | extern int pci_resource_bar(struct pci_dev *dev, int resno, | 203 | int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); |
| 205 | enum pci_bar_type *type); | 204 | void pci_configure_ari(struct pci_dev *dev); |
| 206 | extern void pci_configure_ari(struct pci_dev *dev); | ||
| 207 | 205 | ||
| 208 | /** | 206 | /** |
| 209 | * pci_ari_enabled - query ARI forwarding status | 207 | * pci_ari_enabled - query ARI forwarding status |
| @@ -217,7 +215,7 @@ static inline int pci_ari_enabled(struct pci_bus *bus) | |||
| 217 | } | 215 | } |
| 218 | 216 | ||
| 219 | void pci_reassigndev_resource_alignment(struct pci_dev *dev); | 217 | void pci_reassigndev_resource_alignment(struct pci_dev *dev); |
| 220 | extern void pci_disable_bridge_window(struct pci_dev *dev); | 218 | void pci_disable_bridge_window(struct pci_dev *dev); |
| 221 | 219 | ||
| 222 | /* Single Root I/O Virtualization */ | 220 | /* Single Root I/O Virtualization */ |
| 223 | struct pci_sriov { | 221 | struct pci_sriov { |
| @@ -241,7 +239,7 @@ struct pci_sriov { | |||
| 241 | }; | 239 | }; |
| 242 | 240 | ||
| 243 | #ifdef CONFIG_PCI_ATS | 241 | #ifdef CONFIG_PCI_ATS |
| 244 | extern void pci_restore_ats_state(struct pci_dev *dev); | 242 | void pci_restore_ats_state(struct pci_dev *dev); |
| 245 | #else | 243 | #else |
| 246 | static inline void pci_restore_ats_state(struct pci_dev *dev) | 244 | static inline void pci_restore_ats_state(struct pci_dev *dev) |
| 247 | { | 245 | { |
| @@ -249,14 +247,13 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) | |||
| 249 | #endif /* CONFIG_PCI_ATS */ | 247 | #endif /* CONFIG_PCI_ATS */ |
| 250 | 248 | ||
| 251 | #ifdef CONFIG_PCI_IOV | 249 | #ifdef CONFIG_PCI_IOV |
| 252 | extern int pci_iov_init(struct pci_dev *dev); | 250 | int pci_iov_init(struct pci_dev *dev); |
| 253 | extern void pci_iov_release(struct pci_dev *dev); | 251 | void pci_iov_release(struct pci_dev *dev); |
| 254 | extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, | 252 | int pci_iov_resource_bar(struct pci_dev *dev, int resno, |
| 255 | enum pci_bar_type *type); | 253 | enum pci_bar_type *type); |
| 256 | extern resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, | 254 | resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); |
| 257 | int resno); | 255 | void pci_restore_iov_state(struct pci_dev *dev); |
| 258 | extern void pci_restore_iov_state(struct pci_dev *dev); | 256 | int pci_iov_bus_range(struct pci_bus *bus); |
| 259 | extern int pci_iov_bus_range(struct pci_bus *bus); | ||
| 260 | 257 | ||
| 261 | #else | 258 | #else |
| 262 | static inline int pci_iov_init(struct pci_dev *dev) | 259 | static inline int pci_iov_init(struct pci_dev *dev) |
| @@ -282,10 +279,10 @@ static inline int pci_iov_bus_range(struct pci_bus *bus) | |||
| 282 | 279 | ||
| 283 | #endif /* CONFIG_PCI_IOV */ | 280 | #endif /* CONFIG_PCI_IOV */ |
| 284 | 281 | ||
| 285 | extern unsigned long pci_cardbus_resource_alignment(struct resource *); | 282 | unsigned long pci_cardbus_resource_alignment(struct resource *); |
| 286 | 283 | ||
| 287 | static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, | 284 | static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, |
| 288 | struct resource *res) | 285 | struct resource *res) |
| 289 | { | 286 | { |
| 290 | #ifdef CONFIG_PCI_IOV | 287 | #ifdef CONFIG_PCI_IOV |
| 291 | int resno = res - dev->resource; | 288 | int resno = res - dev->resource; |
| @@ -298,7 +295,7 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, | |||
| 298 | return resource_alignment(res); | 295 | return resource_alignment(res); |
| 299 | } | 296 | } |
| 300 | 297 | ||
| 301 | extern void pci_enable_acs(struct pci_dev *dev); | 298 | void pci_enable_acs(struct pci_dev *dev); |
| 302 | 299 | ||
| 303 | struct pci_dev_reset_methods { | 300 | struct pci_dev_reset_methods { |
| 304 | u16 vendor; | 301 | u16 vendor; |
| @@ -307,7 +304,7 @@ struct pci_dev_reset_methods { | |||
| 307 | }; | 304 | }; |
| 308 | 305 | ||
| 309 | #ifdef CONFIG_PCI_QUIRKS | 306 | #ifdef CONFIG_PCI_QUIRKS |
| 310 | extern int pci_dev_specific_reset(struct pci_dev *dev, int probe); | 307 | int pci_dev_specific_reset(struct pci_dev *dev, int probe); |
| 311 | #else | 308 | #else |
| 312 | static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) | 309 | static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) |
| 313 | { | 310 | { |
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index fde4a32a0295..569f82fc9e22 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig | |||
| @@ -82,4 +82,4 @@ endchoice | |||
| 82 | 82 | ||
| 83 | config PCIE_PME | 83 | config PCIE_PME |
| 84 | def_bool y | 84 | def_bool y |
| 85 | depends on PCIEPORTBUS && PM_RUNTIME && ACPI | 85 | depends on PCIEPORTBUS && PM_RUNTIME |
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 4e24cb8a94ae..587e7e853107 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c | |||
| @@ -212,8 +212,8 @@ out: | |||
| 212 | return ops->read(bus, devfn, where, size, val); | 212 | return ops->read(bus, devfn, where, size, val); |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, int size, | 215 | static int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, |
| 216 | u32 val) | 216 | int size, u32 val) |
| 217 | { | 217 | { |
| 218 | u32 *sim; | 218 | u32 *sim; |
| 219 | struct aer_error *err; | 219 | struct aer_error *err; |
| @@ -334,13 +334,13 @@ static int aer_inject(struct aer_error_inj *einj) | |||
| 334 | return -ENODEV; | 334 | return -ENODEV; |
| 335 | rpdev = pcie_find_root_port(dev); | 335 | rpdev = pcie_find_root_port(dev); |
| 336 | if (!rpdev) { | 336 | if (!rpdev) { |
| 337 | ret = -ENOTTY; | 337 | ret = -ENODEV; |
| 338 | goto out_put; | 338 | goto out_put; |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 341 | pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
| 342 | if (!pos_cap_err) { | 342 | if (!pos_cap_err) { |
| 343 | ret = -ENOTTY; | 343 | ret = -EPERM; |
| 344 | goto out_put; | 344 | goto out_put; |
| 345 | } | 345 | } |
| 346 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); | 346 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); |
| @@ -350,7 +350,7 @@ static int aer_inject(struct aer_error_inj *einj) | |||
| 350 | 350 | ||
| 351 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); | 351 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); |
| 352 | if (!rp_pos_cap_err) { | 352 | if (!rp_pos_cap_err) { |
| 353 | ret = -ENOTTY; | 353 | ret = -EPERM; |
| 354 | goto out_put; | 354 | goto out_put; |
| 355 | } | 355 | } |
| 356 | 356 | ||
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index 22f840f4dda1..d12c77cd6991 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h | |||
| @@ -110,15 +110,15 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig, | |||
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | extern struct bus_type pcie_port_bus_type; | 112 | extern struct bus_type pcie_port_bus_type; |
| 113 | extern void aer_do_secondary_bus_reset(struct pci_dev *dev); | 113 | void aer_do_secondary_bus_reset(struct pci_dev *dev); |
| 114 | extern int aer_init(struct pcie_device *dev); | 114 | int aer_init(struct pcie_device *dev); |
| 115 | extern void aer_isr(struct work_struct *work); | 115 | void aer_isr(struct work_struct *work); |
| 116 | extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); | 116 | void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); |
| 117 | extern void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); | 117 | void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); |
| 118 | extern irqreturn_t aer_irq(int irq, void *context); | 118 | irqreturn_t aer_irq(int irq, void *context); |
| 119 | 119 | ||
| 120 | #ifdef CONFIG_ACPI_APEI | 120 | #ifdef CONFIG_ACPI_APEI |
| 121 | extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); | 121 | int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); |
| 122 | #else | 122 | #else |
| 123 | static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) | 123 | static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) |
| 124 | { | 124 | { |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 564d97f94b6c..8ec8b4f48560 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
| @@ -89,8 +89,6 @@ static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev) | |||
| 89 | return -ENOSPC; | 89 | return -ENOSPC; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | #define PCI_BUS(x) (((x) >> 8) & 0xff) | ||
| 93 | |||
| 94 | /** | 92 | /** |
| 95 | * is_error_source - check whether the device is source of reported error | 93 | * is_error_source - check whether the device is source of reported error |
| 96 | * @dev: pointer to pci_dev to be checked | 94 | * @dev: pointer to pci_dev to be checked |
| @@ -106,7 +104,7 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info) | |||
| 106 | * When bus id is equal to 0, it might be a bad id | 104 | * When bus id is equal to 0, it might be a bad id |
| 107 | * reported by root port. | 105 | * reported by root port. |
| 108 | */ | 106 | */ |
| 109 | if (!nosourceid && (PCI_BUS(e_info->id) != 0)) { | 107 | if (!nosourceid && (PCI_BUS_NUM(e_info->id) != 0)) { |
| 110 | /* Device ID match? */ | 108 | /* Device ID match? */ |
| 111 | if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) | 109 | if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) |
| 112 | return true; | 110 | return true; |
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 9ca0dc9ffd84..795db1f9d50c 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c | |||
| @@ -19,8 +19,6 @@ | |||
| 19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
| 21 | #include <linux/pcieport_if.h> | 21 | #include <linux/pcieport_if.h> |
| 22 | #include <linux/acpi.h> | ||
| 23 | #include <linux/pci-acpi.h> | ||
| 24 | #include <linux/pm_runtime.h> | 22 | #include <linux/pm_runtime.h> |
| 25 | 23 | ||
| 26 | #include "../pci.h" | 24 | #include "../pci.h" |
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index eea2ca2375e6..d2eb80aab569 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
| @@ -21,18 +21,18 @@ | |||
| 21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) | 21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) |
| 22 | 22 | ||
| 23 | extern struct bus_type pcie_port_bus_type; | 23 | extern struct bus_type pcie_port_bus_type; |
| 24 | extern int pcie_port_device_register(struct pci_dev *dev); | 24 | int pcie_port_device_register(struct pci_dev *dev); |
| 25 | #ifdef CONFIG_PM | 25 | #ifdef CONFIG_PM |
| 26 | extern int pcie_port_device_suspend(struct device *dev); | 26 | int pcie_port_device_suspend(struct device *dev); |
| 27 | extern int pcie_port_device_resume(struct device *dev); | 27 | int pcie_port_device_resume(struct device *dev); |
| 28 | #endif | 28 | #endif |
| 29 | extern void pcie_port_device_remove(struct pci_dev *dev); | 29 | void pcie_port_device_remove(struct pci_dev *dev); |
| 30 | extern int __must_check pcie_port_bus_register(void); | 30 | int __must_check pcie_port_bus_register(void); |
| 31 | extern void pcie_port_bus_unregister(void); | 31 | void pcie_port_bus_unregister(void); |
| 32 | 32 | ||
| 33 | struct pci_dev; | 33 | struct pci_dev; |
| 34 | 34 | ||
| 35 | extern void pcie_clear_root_pme_status(struct pci_dev *dev); | 35 | void pcie_clear_root_pme_status(struct pci_dev *dev); |
| 36 | 36 | ||
| 37 | #ifdef CONFIG_HOTPLUG_PCI_PCIE | 37 | #ifdef CONFIG_HOTPLUG_PCI_PCIE |
| 38 | extern bool pciehp_msi_disabled; | 38 | extern bool pciehp_msi_disabled; |
| @@ -59,7 +59,7 @@ static inline bool pcie_pme_no_msi(void) | |||
| 59 | return pcie_pme_msi_disabled; | 59 | return pcie_pme_msi_disabled; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | extern void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable); | 62 | void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable); |
| 63 | #else /* !CONFIG_PCIE_PME */ | 63 | #else /* !CONFIG_PCIE_PME */ |
| 64 | static inline void pcie_pme_disable_msi(void) {} | 64 | static inline void pcie_pme_disable_msi(void) {} |
| 65 | static inline bool pcie_pme_no_msi(void) { return false; } | 65 | static inline bool pcie_pme_no_msi(void) { return false; } |
| @@ -67,7 +67,7 @@ static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {} | |||
| 67 | #endif /* !CONFIG_PCIE_PME */ | 67 | #endif /* !CONFIG_PCIE_PME */ |
| 68 | 68 | ||
| 69 | #ifdef CONFIG_ACPI | 69 | #ifdef CONFIG_ACPI |
| 70 | extern int pcie_port_acpi_setup(struct pci_dev *port, int *mask); | 70 | int pcie_port_acpi_setup(struct pci_dev *port, int *mask); |
| 71 | 71 | ||
| 72 | static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask) | 72 | static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask) |
| 73 | { | 73 | { |
diff --git a/drivers/pci/pcie/portdrv_acpi.c b/drivers/pci/pcie/portdrv_acpi.c index a86b56e5f2f2..b4d2894ee3fc 100644 --- a/drivers/pci/pcie/portdrv_acpi.c +++ b/drivers/pci/pcie/portdrv_acpi.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | #include "aer/aerdrv.h" | 18 | #include "aer/aerdrv.h" |
| 19 | #include "../pci.h" | 19 | #include "../pci.h" |
| 20 | #include "portdrv.h" | ||
| 20 | 21 | ||
| 21 | /** | 22 | /** |
| 22 | * pcie_port_acpi_setup - Request the BIOS to release control of PCIe services. | 23 | * pcie_port_acpi_setup - Request the BIOS to release control of PCIe services. |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index ed4d09498337..696caed5fdf5 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
| @@ -259,11 +259,9 @@ static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, | |||
| 259 | enum pci_channel_state error) | 259 | enum pci_channel_state error) |
| 260 | { | 260 | { |
| 261 | struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; | 261 | struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; |
| 262 | int ret; | ||
| 263 | |||
| 264 | /* can not fail */ | ||
| 265 | ret = device_for_each_child(&dev->dev, &data, error_detected_iter); | ||
| 266 | 262 | ||
| 263 | /* get true return value from &data */ | ||
| 264 | device_for_each_child(&dev->dev, &data, error_detected_iter); | ||
| 267 | return data.result; | 265 | return data.result; |
| 268 | } | 266 | } |
| 269 | 267 | ||
| @@ -295,10 +293,9 @@ static int mmio_enabled_iter(struct device *device, void *data) | |||
| 295 | static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev) | 293 | static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev) |
| 296 | { | 294 | { |
| 297 | pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; | 295 | pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; |
| 298 | int retval; | ||
| 299 | 296 | ||
| 300 | /* get true return value from &status */ | 297 | /* get true return value from &status */ |
| 301 | retval = device_for_each_child(&dev->dev, &status, mmio_enabled_iter); | 298 | device_for_each_child(&dev->dev, &status, mmio_enabled_iter); |
| 302 | return status; | 299 | return status; |
| 303 | } | 300 | } |
| 304 | 301 | ||
| @@ -330,7 +327,6 @@ static int slot_reset_iter(struct device *device, void *data) | |||
| 330 | static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) | 327 | static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) |
| 331 | { | 328 | { |
| 332 | pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; | 329 | pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; |
| 333 | int retval; | ||
| 334 | 330 | ||
| 335 | /* If fatal, restore cfg space for possible link reset at upstream */ | 331 | /* If fatal, restore cfg space for possible link reset at upstream */ |
| 336 | if (dev->error_state == pci_channel_io_frozen) { | 332 | if (dev->error_state == pci_channel_io_frozen) { |
| @@ -341,8 +337,7 @@ static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) | |||
| 341 | } | 337 | } |
| 342 | 338 | ||
| 343 | /* get true return value from &status */ | 339 | /* get true return value from &status */ |
| 344 | retval = device_for_each_child(&dev->dev, &status, slot_reset_iter); | 340 | device_for_each_child(&dev->dev, &status, slot_reset_iter); |
| 345 | |||
| 346 | return status; | 341 | return status; |
| 347 | } | 342 | } |
| 348 | 343 | ||
| @@ -368,9 +363,7 @@ static int resume_iter(struct device *device, void *data) | |||
| 368 | 363 | ||
| 369 | static void pcie_portdrv_err_resume(struct pci_dev *dev) | 364 | static void pcie_portdrv_err_resume(struct pci_dev *dev) |
| 370 | { | 365 | { |
| 371 | int retval; | 366 | device_for_each_child(&dev->dev, NULL, resume_iter); |
| 372 | /* nothing to do with error value, if it ever happens */ | ||
| 373 | retval = device_for_each_child(&dev->dev, NULL, resume_iter); | ||
| 374 | } | 367 | } |
| 375 | 368 | ||
| 376 | /* | 369 | /* |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index b494066ef32f..43ece5d41d36 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
| @@ -673,6 +673,8 @@ add_dev: | |||
| 673 | ret = device_register(&child->dev); | 673 | ret = device_register(&child->dev); |
| 674 | WARN_ON(ret < 0); | 674 | WARN_ON(ret < 0); |
| 675 | 675 | ||
| 676 | pcibios_add_bus(child); | ||
| 677 | |||
| 676 | /* Create legacy_io and legacy_mem files for this bus */ | 678 | /* Create legacy_io and legacy_mem files for this bus */ |
| 677 | pci_create_legacy_files(child); | 679 | pci_create_legacy_files(child); |
| 678 | 680 | ||
| @@ -1627,8 +1629,7 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus) | |||
| 1627 | if (!bus->is_added) { | 1629 | if (!bus->is_added) { |
| 1628 | dev_dbg(&bus->dev, "fixups for bus\n"); | 1630 | dev_dbg(&bus->dev, "fixups for bus\n"); |
| 1629 | pcibios_fixup_bus(bus); | 1631 | pcibios_fixup_bus(bus); |
| 1630 | if (pci_is_root_bus(bus)) | 1632 | bus->is_added = 1; |
| 1631 | bus->is_added = 1; | ||
| 1632 | } | 1633 | } |
| 1633 | 1634 | ||
| 1634 | for (pass=0; pass < 2; pass++) | 1635 | for (pass=0; pass < 2; pass++) |
| @@ -1661,6 +1662,14 @@ int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) | |||
| 1661 | return 0; | 1662 | return 0; |
| 1662 | } | 1663 | } |
| 1663 | 1664 | ||
| 1665 | void __weak pcibios_add_bus(struct pci_bus *bus) | ||
| 1666 | { | ||
| 1667 | } | ||
| 1668 | |||
| 1669 | void __weak pcibios_remove_bus(struct pci_bus *bus) | ||
| 1670 | { | ||
| 1671 | } | ||
| 1672 | |||
| 1664 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | 1673 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, |
| 1665 | struct pci_ops *ops, void *sysdata, struct list_head *resources) | 1674 | struct pci_ops *ops, void *sysdata, struct list_head *resources) |
| 1666 | { | 1675 | { |
| @@ -1715,6 +1724,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
| 1715 | if (error) | 1724 | if (error) |
| 1716 | goto class_dev_reg_err; | 1725 | goto class_dev_reg_err; |
| 1717 | 1726 | ||
| 1727 | pcibios_add_bus(b); | ||
| 1728 | |||
| 1718 | /* Create legacy_io and legacy_mem files for this bus */ | 1729 | /* Create legacy_io and legacy_mem files for this bus */ |
| 1719 | pci_create_legacy_files(b); | 1730 | pci_create_legacy_files(b); |
| 1720 | 1731 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 0369fb6fc1da..7d68aeebf56b 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -324,29 +324,30 @@ static void quirk_cs5536_vsa(struct pci_dev *dev) | |||
| 324 | } | 324 | } |
| 325 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa); | 325 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa); |
| 326 | 326 | ||
| 327 | static void quirk_io_region(struct pci_dev *dev, unsigned region, | 327 | static void quirk_io_region(struct pci_dev *dev, int port, |
| 328 | unsigned size, int nr, const char *name) | 328 | unsigned size, int nr, const char *name) |
| 329 | { | 329 | { |
| 330 | region &= ~(size-1); | 330 | u16 region; |
| 331 | if (region) { | 331 | struct pci_bus_region bus_region; |
| 332 | struct pci_bus_region bus_region; | 332 | struct resource *res = dev->resource + nr; |
| 333 | struct resource *res = dev->resource + nr; | ||
| 334 | 333 | ||
| 335 | res->name = pci_name(dev); | 334 | pci_read_config_word(dev, port, ®ion); |
| 336 | res->start = region; | 335 | region &= ~(size - 1); |
| 337 | res->end = region + size - 1; | ||
| 338 | res->flags = IORESOURCE_IO; | ||
| 339 | 336 | ||
| 340 | /* Convert from PCI bus to resource space. */ | 337 | if (!region) |
| 341 | bus_region.start = res->start; | 338 | return; |
| 342 | bus_region.end = res->end; | ||
| 343 | pcibios_bus_to_resource(dev, res, &bus_region); | ||
| 344 | 339 | ||
| 345 | if (pci_claim_resource(dev, nr) == 0) | 340 | res->name = pci_name(dev); |
| 346 | dev_info(&dev->dev, "quirk: %pR claimed by %s\n", | 341 | res->flags = IORESOURCE_IO; |
| 347 | res, name); | 342 | |
| 348 | } | 343 | /* Convert from PCI bus to resource space */ |
| 349 | } | 344 | bus_region.start = region; |
| 345 | bus_region.end = region + size - 1; | ||
| 346 | pcibios_bus_to_resource(dev, res, &bus_region); | ||
| 347 | |||
| 348 | if (!pci_claim_resource(dev, nr)) | ||
| 349 | dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name); | ||
| 350 | } | ||
| 350 | 351 | ||
| 351 | /* | 352 | /* |
| 352 | * ATI Northbridge setups MCE the processor if you even | 353 | * ATI Northbridge setups MCE the processor if you even |
| @@ -374,12 +375,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_ | |||
| 374 | */ | 375 | */ |
| 375 | static void quirk_ali7101_acpi(struct pci_dev *dev) | 376 | static void quirk_ali7101_acpi(struct pci_dev *dev) |
| 376 | { | 377 | { |
| 377 | u16 region; | 378 | quirk_io_region(dev, 0xE0, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI"); |
| 378 | 379 | quirk_io_region(dev, 0xE2, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB"); | |
| 379 | pci_read_config_word(dev, 0xE0, ®ion); | ||
| 380 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI"); | ||
| 381 | pci_read_config_word(dev, 0xE2, ®ion); | ||
| 382 | quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB"); | ||
| 383 | } | 380 | } |
| 384 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi); | 381 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi); |
| 385 | 382 | ||
| @@ -442,12 +439,10 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int | |||
| 442 | */ | 439 | */ |
| 443 | static void quirk_piix4_acpi(struct pci_dev *dev) | 440 | static void quirk_piix4_acpi(struct pci_dev *dev) |
| 444 | { | 441 | { |
| 445 | u32 region, res_a; | 442 | u32 res_a; |
| 446 | 443 | ||
| 447 | pci_read_config_dword(dev, 0x40, ®ion); | 444 | quirk_io_region(dev, 0x40, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); |
| 448 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); | 445 | quirk_io_region(dev, 0x90, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); |
| 449 | pci_read_config_dword(dev, 0x90, ®ion); | ||
| 450 | quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); | ||
| 451 | 446 | ||
| 452 | /* Device resource A has enables for some of the other ones */ | 447 | /* Device resource A has enables for some of the other ones */ |
| 453 | pci_read_config_dword(dev, 0x5c, &res_a); | 448 | pci_read_config_dword(dev, 0x5c, &res_a); |
| @@ -491,7 +486,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3, qui | |||
| 491 | */ | 486 | */ |
| 492 | static void quirk_ich4_lpc_acpi(struct pci_dev *dev) | 487 | static void quirk_ich4_lpc_acpi(struct pci_dev *dev) |
| 493 | { | 488 | { |
| 494 | u32 region; | ||
| 495 | u8 enable; | 489 | u8 enable; |
| 496 | 490 | ||
| 497 | /* | 491 | /* |
| @@ -503,22 +497,14 @@ static void quirk_ich4_lpc_acpi(struct pci_dev *dev) | |||
| 503 | */ | 497 | */ |
| 504 | 498 | ||
| 505 | pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); | 499 | pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); |
| 506 | if (enable & ICH4_ACPI_EN) { | 500 | if (enable & ICH4_ACPI_EN) |
| 507 | pci_read_config_dword(dev, ICH_PMBASE, ®ion); | 501 | quirk_io_region(dev, ICH_PMBASE, 128, PCI_BRIDGE_RESOURCES, |
| 508 | region &= PCI_BASE_ADDRESS_IO_MASK; | 502 | "ICH4 ACPI/GPIO/TCO"); |
| 509 | if (region >= PCIBIOS_MIN_IO) | ||
| 510 | quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, | ||
| 511 | "ICH4 ACPI/GPIO/TCO"); | ||
| 512 | } | ||
| 513 | 503 | ||
| 514 | pci_read_config_byte(dev, ICH4_GPIO_CNTL, &enable); | 504 | pci_read_config_byte(dev, ICH4_GPIO_CNTL, &enable); |
| 515 | if (enable & ICH4_GPIO_EN) { | 505 | if (enable & ICH4_GPIO_EN) |
| 516 | pci_read_config_dword(dev, ICH4_GPIOBASE, ®ion); | 506 | quirk_io_region(dev, ICH4_GPIOBASE, 64, PCI_BRIDGE_RESOURCES+1, |
| 517 | region &= PCI_BASE_ADDRESS_IO_MASK; | 507 | "ICH4 GPIO"); |
| 518 | if (region >= PCIBIOS_MIN_IO) | ||
| 519 | quirk_io_region(dev, region, 64, | ||
| 520 | PCI_BRIDGE_RESOURCES + 1, "ICH4 GPIO"); | ||
| 521 | } | ||
| 522 | } | 508 | } |
| 523 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, quirk_ich4_lpc_acpi); | 509 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, quirk_ich4_lpc_acpi); |
| 524 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, quirk_ich4_lpc_acpi); | 510 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, quirk_ich4_lpc_acpi); |
| @@ -533,26 +519,17 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, qui | |||
| 533 | 519 | ||
| 534 | static void ich6_lpc_acpi_gpio(struct pci_dev *dev) | 520 | static void ich6_lpc_acpi_gpio(struct pci_dev *dev) |
| 535 | { | 521 | { |
| 536 | u32 region; | ||
| 537 | u8 enable; | 522 | u8 enable; |
| 538 | 523 | ||
| 539 | pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); | 524 | pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); |
| 540 | if (enable & ICH6_ACPI_EN) { | 525 | if (enable & ICH6_ACPI_EN) |
| 541 | pci_read_config_dword(dev, ICH_PMBASE, ®ion); | 526 | quirk_io_region(dev, ICH_PMBASE, 128, PCI_BRIDGE_RESOURCES, |
| 542 | region &= PCI_BASE_ADDRESS_IO_MASK; | 527 | "ICH6 ACPI/GPIO/TCO"); |
| 543 | if (region >= PCIBIOS_MIN_IO) | ||
| 544 | quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, | ||
| 545 | "ICH6 ACPI/GPIO/TCO"); | ||
| 546 | } | ||
| 547 | 528 | ||
| 548 | pci_read_config_byte(dev, ICH6_GPIO_CNTL, &enable); | 529 | pci_read_config_byte(dev, ICH6_GPIO_CNTL, &enable); |
| 549 | if (enable & ICH6_GPIO_EN) { | 530 | if (enable & ICH6_GPIO_EN) |
| 550 | pci_read_config_dword(dev, ICH6_GPIOBASE, ®ion); | 531 | quirk_io_region(dev, ICH6_GPIOBASE, 64, PCI_BRIDGE_RESOURCES+1, |
| 551 | region &= PCI_BASE_ADDRESS_IO_MASK; | 532 | "ICH6 GPIO"); |
| 552 | if (region >= PCIBIOS_MIN_IO) | ||
| 553 | quirk_io_region(dev, region, 64, | ||
| 554 | PCI_BRIDGE_RESOURCES + 1, "ICH6 GPIO"); | ||
| 555 | } | ||
| 556 | } | 533 | } |
| 557 | 534 | ||
| 558 | static void ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name, int dynsize) | 535 | static void ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name, int dynsize) |
| @@ -650,13 +627,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_1, qui | |||
| 650 | */ | 627 | */ |
| 651 | static void quirk_vt82c586_acpi(struct pci_dev *dev) | 628 | static void quirk_vt82c586_acpi(struct pci_dev *dev) |
| 652 | { | 629 | { |
| 653 | u32 region; | 630 | if (dev->revision & 0x10) |
| 654 | 631 | quirk_io_region(dev, 0x48, 256, PCI_BRIDGE_RESOURCES, | |
| 655 | if (dev->revision & 0x10) { | 632 | "vt82c586 ACPI"); |
| 656 | pci_read_config_dword(dev, 0x48, ®ion); | ||
| 657 | region &= PCI_BASE_ADDRESS_IO_MASK; | ||
| 658 | quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES, "vt82c586 ACPI"); | ||
| 659 | } | ||
| 660 | } | 633 | } |
| 661 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt82c586_acpi); | 634 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt82c586_acpi); |
| 662 | 635 | ||
| @@ -668,18 +641,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt | |||
| 668 | */ | 641 | */ |
| 669 | static void quirk_vt82c686_acpi(struct pci_dev *dev) | 642 | static void quirk_vt82c686_acpi(struct pci_dev *dev) |
| 670 | { | 643 | { |
| 671 | u16 hm; | ||
| 672 | u32 smb; | ||
| 673 | |||
| 674 | quirk_vt82c586_acpi(dev); | 644 | quirk_vt82c586_acpi(dev); |
| 675 | 645 | ||
| 676 | pci_read_config_word(dev, 0x70, &hm); | 646 | quirk_io_region(dev, 0x70, 128, PCI_BRIDGE_RESOURCES+1, |
| 677 | hm &= PCI_BASE_ADDRESS_IO_MASK; | 647 | "vt82c686 HW-mon"); |
| 678 | quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c686 HW-mon"); | ||
| 679 | 648 | ||
| 680 | pci_read_config_dword(dev, 0x90, &smb); | 649 | quirk_io_region(dev, 0x90, 16, PCI_BRIDGE_RESOURCES+2, "vt82c686 SMB"); |
| 681 | smb &= PCI_BASE_ADDRESS_IO_MASK; | ||
| 682 | quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB"); | ||
| 683 | } | 650 | } |
| 684 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi); | 651 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi); |
| 685 | 652 | ||
| @@ -690,15 +657,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt | |||
| 690 | */ | 657 | */ |
| 691 | static void quirk_vt8235_acpi(struct pci_dev *dev) | 658 | static void quirk_vt8235_acpi(struct pci_dev *dev) |
| 692 | { | 659 | { |
| 693 | u16 pm, smb; | 660 | quirk_io_region(dev, 0x88, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM"); |
| 694 | 661 | quirk_io_region(dev, 0xd0, 16, PCI_BRIDGE_RESOURCES+1, "vt8235 SMB"); | |
| 695 | pci_read_config_word(dev, 0x88, &pm); | ||
| 696 | pm &= PCI_BASE_ADDRESS_IO_MASK; | ||
| 697 | quirk_io_region(dev, pm, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM"); | ||
| 698 | |||
| 699 | pci_read_config_word(dev, 0xd0, &smb); | ||
| 700 | smb &= PCI_BASE_ADDRESS_IO_MASK; | ||
| 701 | quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 1, "vt8235 SMB"); | ||
| 702 | } | 662 | } |
| 703 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235_acpi); | 663 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235_acpi); |
| 704 | 664 | ||
| @@ -2594,6 +2554,14 @@ static void quirk_msi_intx_disable_ati_bug(struct pci_dev *dev) | |||
| 2594 | dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; | 2554 | dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; |
| 2595 | pci_dev_put(p); | 2555 | pci_dev_put(p); |
| 2596 | } | 2556 | } |
| 2557 | static void quirk_msi_intx_disable_qca_bug(struct pci_dev *dev) | ||
| 2558 | { | ||
| 2559 | /* AR816X/AR817X/E210X MSI is fixed at HW level from revision 0x18 */ | ||
| 2560 | if (dev->revision < 0x18) { | ||
| 2561 | dev_info(&dev->dev, "set MSI_INTX_DISABLE_BUG flag\n"); | ||
| 2562 | dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; | ||
| 2563 | } | ||
| 2564 | } | ||
| 2597 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, | 2565 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
| 2598 | PCI_DEVICE_ID_TIGON3_5780, | 2566 | PCI_DEVICE_ID_TIGON3_5780, |
| 2599 | quirk_msi_intx_disable_bug); | 2567 | quirk_msi_intx_disable_bug); |
| @@ -2643,6 +2611,16 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1073, | |||
| 2643 | quirk_msi_intx_disable_bug); | 2611 | quirk_msi_intx_disable_bug); |
| 2644 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1083, | 2612 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1083, |
| 2645 | quirk_msi_intx_disable_bug); | 2613 | quirk_msi_intx_disable_bug); |
| 2614 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1090, | ||
| 2615 | quirk_msi_intx_disable_qca_bug); | ||
| 2616 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1091, | ||
| 2617 | quirk_msi_intx_disable_qca_bug); | ||
| 2618 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x10a0, | ||
| 2619 | quirk_msi_intx_disable_qca_bug); | ||
| 2620 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x10a1, | ||
| 2621 | quirk_msi_intx_disable_qca_bug); | ||
| 2622 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0xe091, | ||
| 2623 | quirk_msi_intx_disable_qca_bug); | ||
| 2646 | #endif /* CONFIG_PCI_MSI */ | 2624 | #endif /* CONFIG_PCI_MSI */ |
| 2647 | 2625 | ||
| 2648 | /* Allow manual resource allocation for PCI hotplug bridges | 2626 | /* Allow manual resource allocation for PCI hotplug bridges |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index cc875e6ed159..8fc54b7327bc 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
| @@ -50,10 +50,8 @@ void pci_remove_bus(struct pci_bus *bus) | |||
| 50 | list_del(&bus->node); | 50 | list_del(&bus->node); |
| 51 | pci_bus_release_busn_res(bus); | 51 | pci_bus_release_busn_res(bus); |
| 52 | up_write(&pci_bus_sem); | 52 | up_write(&pci_bus_sem); |
| 53 | if (!bus->is_added) | ||
| 54 | return; | ||
| 55 | |||
| 56 | pci_remove_legacy_files(bus); | 53 | pci_remove_legacy_files(bus); |
| 54 | pcibios_remove_bus(bus); | ||
| 57 | device_unregister(&bus->dev); | 55 | device_unregister(&bus->dev); |
| 58 | } | 56 | } |
| 59 | EXPORT_SYMBOL(pci_remove_bus); | 57 | EXPORT_SYMBOL(pci_remove_bus); |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 7e8739e25b9e..16abaaa1f83c 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
| @@ -1044,7 +1044,7 @@ handle_done: | |||
| 1044 | ; | 1044 | ; |
| 1045 | } | 1045 | } |
| 1046 | 1046 | ||
| 1047 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, | 1047 | static void __ref __pci_bus_size_bridges(struct pci_bus *bus, |
| 1048 | struct list_head *realloc_head) | 1048 | struct list_head *realloc_head) |
| 1049 | { | 1049 | { |
| 1050 | struct pci_dev *dev; | 1050 | struct pci_dev *dev; |
| @@ -1545,6 +1545,8 @@ again: | |||
| 1545 | 1545 | ||
| 1546 | enable_all: | 1546 | enable_all: |
| 1547 | retval = pci_reenable_device(bridge); | 1547 | retval = pci_reenable_device(bridge); |
| 1548 | if (retval) | ||
| 1549 | dev_err(&bridge->dev, "Error reenabling bridge (%d)\n", retval); | ||
| 1548 | pci_set_master(bridge); | 1550 | pci_set_master(bridge); |
| 1549 | pci_enable_bridges(parent); | 1551 | pci_enable_bridges(parent); |
| 1550 | } | 1552 | } |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 81b88bda7930..07f2eddc09ce 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
| @@ -261,7 +261,6 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
| 261 | { | 261 | { |
| 262 | struct resource *res = dev->resource + resno; | 262 | struct resource *res = dev->resource + resno; |
| 263 | resource_size_t align, size; | 263 | resource_size_t align, size; |
| 264 | struct pci_bus *bus; | ||
| 265 | int ret; | 264 | int ret; |
| 266 | 265 | ||
| 267 | align = pci_resource_alignment(dev, res); | 266 | align = pci_resource_alignment(dev, res); |
| @@ -271,7 +270,6 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
| 271 | return -EINVAL; | 270 | return -EINVAL; |
| 272 | } | 271 | } |
| 273 | 272 | ||
| 274 | bus = dev->bus; | ||
| 275 | size = resource_size(res); | 273 | size = resource_size(res); |
| 276 | ret = _pci_assign_resource(dev, resno, size, align); | 274 | ret = _pci_assign_resource(dev, resno, size, align); |
| 277 | 275 | ||
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index ac6412fb8d6f..c1e9284a677b 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
| @@ -377,14 +377,17 @@ void pci_hp_create_module_link(struct pci_slot *pci_slot) | |||
| 377 | { | 377 | { |
| 378 | struct hotplug_slot *slot = pci_slot->hotplug; | 378 | struct hotplug_slot *slot = pci_slot->hotplug; |
| 379 | struct kobject *kobj = NULL; | 379 | struct kobject *kobj = NULL; |
| 380 | int no_warn; | 380 | int ret; |
| 381 | 381 | ||
| 382 | if (!slot || !slot->ops) | 382 | if (!slot || !slot->ops) |
| 383 | return; | 383 | return; |
| 384 | kobj = kset_find_obj(module_kset, slot->ops->mod_name); | 384 | kobj = kset_find_obj(module_kset, slot->ops->mod_name); |
| 385 | if (!kobj) | 385 | if (!kobj) |
| 386 | return; | 386 | return; |
| 387 | no_warn = sysfs_create_link(&pci_slot->kobj, kobj, "module"); | 387 | ret = sysfs_create_link(&pci_slot->kobj, kobj, "module"); |
| 388 | if (ret) | ||
| 389 | dev_err(&pci_slot->bus->dev, "Error creating sysfs link (%d)\n", | ||
| 390 | ret); | ||
| 388 | kobject_put(kobj); | 391 | kobject_put(kobj); |
| 389 | } | 392 | } |
| 390 | EXPORT_SYMBOL_GPL(pci_hp_create_module_link); | 393 | EXPORT_SYMBOL_GPL(pci_hp_create_module_link); |
