diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-10-22 19:34:09 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-10-22 19:34:09 +0100 |
commit | f20e3b5fe7ead0615309433260b9784d8da0bbbd (patch) | |
tree | eabb2e47a0355ac4e8024b7087b4e7cb9f324358 /drivers/pci | |
parent | bcbfe664e7af019e698cef2feb85ac2b4f1ac11d (diff) | |
parent | f030d7b65e4e6399f23de2a41a58d1b607b6bd89 (diff) |
Merge branch 'for-rmk' of git://git.android.com/kernel into devel
Diffstat (limited to 'drivers/pci')
33 files changed, 927 insertions, 734 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 529d9d7727b..999cc4088b5 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -151,6 +151,13 @@ void pci_bus_add_devices(struct pci_bus *bus) if (retval) dev_err(&dev->dev, "Error creating cpuaffinity" " file, continuing...\n"); + + retval = device_create_file(&child_bus->dev, + &dev_attr_cpulistaffinity); + if (retval) + dev_err(&dev->dev, + "Error creating cpulistaffinity" + " file, continuing...\n"); } } } diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index e842e756308..8b29c307f1a 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -193,7 +193,7 @@ dmar_parse_dev(struct dmar_drhd_unit *dmaru) { struct acpi_dmar_hardware_unit *drhd; static int include_all; - int ret; + int ret = 0; drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr; @@ -212,7 +212,7 @@ dmar_parse_dev(struct dmar_drhd_unit *dmaru) include_all = 1; } - if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all)) { + if (ret) { list_del(&dmaru->list); kfree(dmaru); } @@ -289,6 +289,24 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header) } } +/** + * dmar_table_detect - checks to see if the platform supports DMAR devices + */ +static int __init dmar_table_detect(void) +{ + acpi_status status = AE_OK; + + /* if we could find DMAR table, then there are DMAR devices */ + status = acpi_get_table(ACPI_SIG_DMAR, 0, + (struct acpi_table_header **)&dmar_tbl); + + if (ACPI_SUCCESS(status) && !dmar_tbl) { + printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); + status = AE_NOT_FOUND; + } + + return (ACPI_SUCCESS(status) ? 1 : 0); +} /** * parse_dmar_table - parses the DMA reporting table @@ -300,6 +318,12 @@ parse_dmar_table(void) struct acpi_dmar_header *entry_header; int ret = 0; + /* + * Do it again, earlier dmar_tbl mapping could be mapped with + * fixed map. + */ + dmar_table_detect(); + dmar = (struct acpi_table_dmar *)dmar_tbl; if (!dmar) return -ENODEV; @@ -373,10 +397,10 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev) int __init dmar_dev_scope_init(void) { - struct dmar_drhd_unit *drhd; + struct dmar_drhd_unit *drhd, *drhd_n; int ret = -ENODEV; - for_each_drhd_unit(drhd) { + list_for_each_entry_safe(drhd, drhd_n, &dmar_drhd_units, list) { ret = dmar_parse_dev(drhd); if (ret) return ret; @@ -384,8 +408,8 @@ int __init dmar_dev_scope_init(void) #ifdef CONFIG_DMAR { - struct dmar_rmrr_unit *rmrr; - for_each_rmrr_units(rmrr) { + struct dmar_rmrr_unit *rmrr, *rmrr_n; + list_for_each_entry_safe(rmrr, rmrr_n, &dmar_rmrr_units, list) { ret = rmrr_parse_dev(rmrr); if (ret) return ret; @@ -430,30 +454,11 @@ int __init dmar_table_init(void) return 0; } -/** - * early_dmar_detect - checks to see if the platform supports DMAR devices - */ -int __init early_dmar_detect(void) -{ - acpi_status status = AE_OK; - - /* if we could find DMAR table, then there are DMAR devices */ - status = acpi_get_table(ACPI_SIG_DMAR, 0, - (struct acpi_table_header **)&dmar_tbl); - - if (ACPI_SUCCESS(status) && !dmar_tbl) { - printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); - status = AE_NOT_FOUND; - } - - return (ACPI_SUCCESS(status) ? 1 : 0); -} - void __init detect_intel_iommu(void) { int ret; - ret = early_dmar_detect(); + ret = dmar_table_detect(); #ifdef CONFIG_DMAR { @@ -479,14 +484,16 @@ void __init detect_intel_iommu(void) " x2apic support\n"); dmar_disabled = 1; - return; + goto end; } if (ret && !no_iommu && !iommu_detected && !swiotlb && !dmar_disabled) iommu_detected = 1; } +end: #endif + dmar_tbl = NULL; } diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 7d27631e6e6..8cfd1c4926c 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c @@ -123,10 +123,8 @@ static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void) static void __init print_bus_info (void) { struct bus_info *ptr; - struct list_head *ptr1; - list_for_each (ptr1, &bus_info_head) { - ptr = list_entry (ptr1, struct bus_info, bus_info_list); + list_for_each_entry(ptr, &bus_info_head, bus_info_list) { debug ("%s - slot_min = %x\n", __func__, ptr->slot_min); debug ("%s - slot_max = %x\n", __func__, ptr->slot_max); debug ("%s - slot_count = %x\n", __func__, ptr->slot_count); @@ -146,10 +144,8 @@ static void __init print_bus_info (void) static void print_lo_info (void) { struct rio_detail *ptr; - struct list_head *ptr1; debug ("print_lo_info ----\n"); - list_for_each (ptr1, &rio_lo_head) { - ptr = list_entry (ptr1, struct rio_detail, rio_detail_list); + list_for_each_entry(ptr, &rio_lo_head, rio_detail_list) { debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id); debug ("%s - rio_type = %x\n", __func__, ptr->rio_type); debug ("%s - owner_id = %x\n", __func__, ptr->owner_id); @@ -163,10 +159,8 @@ static void print_lo_info (void) static void print_vg_info (void) { struct rio_detail *ptr; - struct list_head *ptr1; debug ("%s ---\n", __func__); - list_for_each (ptr1, &rio_vg_head) { - ptr = list_entry (ptr1, struct rio_detail, rio_detail_list); + list_for_each_entry(ptr, &rio_vg_head, rio_detail_list) { debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id); debug ("%s - rio_type = %x\n", __func__, ptr->rio_type); debug ("%s - owner_id = %x\n", __func__, ptr->owner_id); @@ -180,10 +174,8 @@ static void print_vg_info (void) static void __init print_ebda_pci_rsrc (void) { struct ebda_pci_rsrc *ptr; - struct list_head *ptr1; - list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) { - ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list); + list_for_each_entry(ptr, &ibmphp_ebda_pci_rsrc_head, ebda_pci_rsrc_list) { debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n", __func__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr); } @@ -192,10 +184,8 @@ static void __init print_ebda_pci_rsrc (void) static void __init print_ibm_slot (void) { struct slot *ptr; - struct list_head *ptr1; - list_for_each (ptr1, &ibmphp_slot_head) { - ptr = list_entry (ptr1, struct slot, ibm_slot_list); + list_for_each_entry(ptr, &ibmphp_slot_head, ibm_slot_list) { debug ("%s - slot_number: %x\n", __func__, ptr->number); } } @@ -203,10 +193,8 @@ static void __init print_ibm_slot (void) static void __init print_opt_vg (void) { struct opt_rio *ptr; - struct list_head *ptr1; debug ("%s ---\n", __func__); - list_for_each (ptr1, &opt_vg_head) { - ptr = list_entry (ptr1, struct opt_rio, opt_rio_list); + list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) { debug ("%s - rio_type %x\n", __func__, ptr->rio_type); debug ("%s - chassis_num: %x\n", __func__, ptr->chassis_num); debug ("%s - first_slot_num: %x\n", __func__, ptr->first_slot_num); @@ -217,13 +205,9 @@ static void __init print_opt_vg (void) static void __init print_ebda_hpc (void) { struct controller *hpc_ptr; - struct list_head *ptr1; u16 index; - list_for_each (ptr1, &ebda_hpc_head) { - - hpc_ptr = list_entry (ptr1, struct controller, ebda_hpc_list); - + list_for_each_entry(hpc_ptr, &ebda_hpc_head, ebda_hpc_list) { for (index = 0; index < hpc_ptr->slot_count; index++) { debug ("%s - physical slot#: %x\n", __func__, hpc_ptr->slots[index].slot_num); debug ("%s - pci bus# of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_bus_num); @@ -460,9 +444,7 @@ static int __init ebda_rio_table (void) static struct opt_rio *search_opt_vg (u8 chassis_num) { struct opt_rio *ptr; - struct list_head *ptr1; - list_for_each (ptr1, &opt_vg_head) { - ptr = list_entry (ptr1, struct opt_rio, opt_rio_list); + list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) { if (ptr->chassis_num == chassis_num) return ptr; } @@ -473,10 +455,8 @@ static int __init combine_wpg_for_chassis (void) { struct opt_rio *opt_rio_ptr = NULL; struct rio_detail *rio_detail_ptr = NULL; - struct list_head *list_head_ptr = NULL; - list_for_each (list_head_ptr, &rio_vg_head) { - rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list); + list_for_each_entry(rio_detail_ptr, &rio_vg_head, rio_detail_list) { opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num); if (!opt_rio_ptr) { opt_rio_ptr = kzalloc(sizeof(struct opt_rio), GFP_KERNEL); @@ -497,14 +477,12 @@ static int __init combine_wpg_for_chassis (void) } /* - * reorgnizing linked list of expansion box + * reorganizing linked list of expansion box */ static struct opt_rio_lo *search_opt_lo (u8 chassis_num) { struct opt_rio_lo *ptr; - struct list_head *ptr1; - list_for_each (ptr1, &opt_lo_head) { - ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list); + list_for_each_entry(ptr, &opt_lo_head, opt_rio_lo_list) { if (ptr->chassis_num == chassis_num) return ptr; } @@ -515,10 +493,8 @@ static int combine_wpg_for_expansion (void) { struct opt_rio_lo *opt_rio_lo_ptr = NULL; struct rio_detail *rio_detail_ptr = NULL; - struct list_head *list_head_ptr = NULL; - list_for_each (list_head_ptr, &rio_lo_head) { - rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list); + list_for_each_entry(rio_detail_ptr, &rio_lo_head, rio_detail_list) { opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num); if (!opt_rio_lo_ptr) { opt_rio_lo_ptr = kzalloc(sizeof(struct opt_rio_lo), GFP_KERNEL); @@ -550,20 +526,17 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var) { struct opt_rio *opt_vg_ptr = NULL; struct opt_rio_lo *opt_lo_ptr = NULL; - struct list_head *ptr = NULL; int rc = 0; if (!var) { - list_for_each (ptr, &opt_vg_head) { - opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list); + list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) { if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) { rc = -ENODEV; break; } } } else { - list_for_each (ptr, &opt_lo_head) { - opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list); + list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) { if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) { rc = -ENODEV; break; @@ -576,10 +549,8 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var) static struct opt_rio_lo * find_rxe_num (u8 slot_num) { struct opt_rio_lo *opt_lo_ptr; - struct list_head *ptr; - list_for_each (ptr, &opt_lo_head) { - opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list); + list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) { //check to see if this slot_num belongs to expansion box if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1))) return opt_lo_ptr; @@ -590,10 +561,8 @@ static struct opt_rio_lo * find_rxe_num (u8 slot_num) static struct opt_rio * find_chassis_num (u8 slot_num) { struct opt_rio *opt_vg_ptr; - struct list_head *ptr; - list_for_each (ptr, &opt_vg_head) { - opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list); + list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) { //check to see if this slot_num belongs to chassis if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0))) return opt_vg_ptr; @@ -607,11 +576,9 @@ static struct opt_rio * find_chassis_num (u8 slot_num) static u8 calculate_first_slot (u8 slot_num) { u8 first_slot = 1; - struct list_head * list; struct slot * slot_cur; - list_for_each (list, &ibmphp_slot_head) { - slot_cur = list_entry (list, struct slot, ibm_slot_list); + list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) { if (slot_cur->ctrl) { if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num)) first_slot = slot_cur->ctrl->ending_slot_num; @@ -767,7 +734,6 @@ static int __init ebda_rsrc_controller (void) struct bus_info *bus_info_ptr1, *bus_info_ptr2; int rc; struct slot *tmp_slot; - struct list_head *list; addr = hpc_list_ptr->phys_addr; for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) { @@ -997,9 +963,7 @@ static int __init ebda_rsrc_controller (void) } /* each hpc */ - list_for_each (list, &ibmphp_slot_head) { - tmp_slot = list_entry (list, struct slot, ibm_slot_list); - + list_for_each_entry(tmp_slot, &ibmphp_slot_head, ibm_slot_list) { snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot)); pci_hp_register(tmp_slot->hotplug_slot, pci_find_bus(0, tmp_slot->bus), tmp_slot->device); @@ -1101,10 +1065,8 @@ u16 ibmphp_get_total_controllers (void) struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num) { struct slot *slot; - struct list_head *list; - list_for_each (list, &ibmphp_slot_head) { - slot = list_entry (list, struct slot, ibm_slot_list); + list_for_each_entry(slot, &ibmphp_slot_head, ibm_slot_list) { if (slot->number == physical_num) return slot; } @@ -1120,10 +1082,8 @@ struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num) struct bus_info *ibmphp_find_same_bus_num (u32 num) { struct bus_info *ptr; - struct list_head *ptr1; - list_for_each (ptr1, &bus_info_head) { - ptr = list_entry (ptr1, struct bus_info, bus_info_list); + list_for_each_entry(ptr, &bus_info_head, bus_info_list) { if (ptr->busno == num) return ptr; } @@ -1136,10 +1096,8 @@ struct bus_info *ibmphp_find_same_bus_num (u32 num) int ibmphp_get_bus_index (u8 num) { struct bus_info *ptr; - struct list_head *ptr1; - list_for_each (ptr1, &bus_info_head) { - ptr = list_entry (ptr1, struct bus_info, bus_info_list); + list_for_each_entry(ptr, &bus_info_head, bus_info_list) { if (ptr->busno == num) return ptr->index; } @@ -1212,11 +1170,9 @@ static struct pci_driver ibmphp_driver = { int ibmphp_register_pci (void) { struct controller *ctrl; - struct list_head *tmp; int rc = 0; - list_for_each (tmp, &ebda_hpc_head) { - ctrl = list_entry (tmp, struct controller, ebda_hpc_list); + list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) { if (ctrl->ctlr_type == 1) { rc = pci_register_driver(&ibmphp_driver); break; @@ -1227,12 +1183,10 @@ int ibmphp_register_pci (void) static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids) { struct controller *ctrl; - struct list_head *tmp; debug ("inside ibmphp_probe\n"); - list_for_each (tmp, &ebda_hpc_head) { - ctrl = list_entry (tmp, struct controller, ebda_hpc_list); + list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) { if (ctrl->ctlr_type == 1) { if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) { ctrl->ctrl_dev = dev; diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 5f85b1b120e..2e6c4474644 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -102,13 +102,13 @@ static int get_##name (struct hotplug_slot *slot, type *value) \ { \ struct hotplug_slot_ops *ops = slot->ops; \ int retval = 0; \ - if (try_module_get(ops->owner)) { \ - if (ops->get_##name) \ - retval = ops->get_##name(slot, value); \ - else \ - *value = slot->info->name; \ - module_put(ops->owner); \ - } \ + if (!try_module_get(ops->owner)) \ + return -ENODEV; \ + if (ops->get_##name) \ + retval = ops->get_##name(slot, value); \ + else \ + *value = slot->info->name; \ + module_put(ops->owner); \ return retval; \ } diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 9e6cec67e1c..c367978bd7f 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -57,6 +57,19 @@ extern struct workqueue_struct *pciehp_wq; #define warn(format, arg...) \ printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) +#define ctrl_dbg(ctrl, format, arg...) \ + do { \ + if (pciehp_debug) \ + dev_printk(, &ctrl->pcie->device, \ + format, ## arg); \ + } while (0) +#define ctrl_err(ctrl, format, arg...) \ + dev_err(&ctrl->pcie->device, format, ## arg) +#define ctrl_info(ctrl, format, arg...) \ + dev_info(&ctrl->pcie->device, format, ## arg) +#define ctrl_warn(ctrl, format, arg...) \ + dev_warn(&ctrl->pcie->device, format, ## arg) + #define SLOT_NAME_SIZE 10 struct slot { u8 bus; @@ -87,6 +100,7 @@ struct controller { int num_slots; /* Number of slots on ctlr */ int slot_num_inc; /* 1 or -1 */ struct pci_dev *pci_dev; + struct pcie_device *pcie; /* PCI Express port service */ struct list_head slot_list; struct hpc_ops *hpc_ops; wait_queue_head_t queue; /* sleep & wake process */ @@ -170,7 +184,7 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) return slot; } - err("%s: slot (device=0x%x) not found\n", __func__, device); + ctrl_err(ctrl, "%s: slot (device=0x%x) not found\n", __func__, device); return NULL; } diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 4fd5355bc3b..c748a19db89 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -144,9 +144,10 @@ set_lock_exit: * sysfs interface which allows the user to toggle the Electro Mechanical * Interlock. Valid values are either 0 or 1. 0 == unlock, 1 == lock */ -static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf, - size_t count) +static ssize_t lock_write_file(struct hotplug_slot *hotplug_slot, + const char *buf, size_t count) { + struct slot *slot = hotplug_slot->private; unsigned long llock; u8 lock; int retval = 0; @@ -157,10 +158,11 @@ static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf, switch (lock) { case 0: case 1: - retval = set_lock_status(slot, lock); + retval = set_lock_status(hotplug_slot, lock); break; default: - err ("%d is an invalid lock value\n", lock); + ctrl_err(slot->ctrl, "%d is an invalid lock value\n", + lock); retval = -EINVAL; } if (retval) @@ -180,7 +182,10 @@ static struct hotplug_slot_attribute hotplug_slot_attr_lock = { */ static void release_slot(struct hotplug_slot *hotplug_slot) { - dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); + struct slot *slot = hotplug_slot->private; + + ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", + __func__, hotplug_slot->name); kfree(hotplug_slot->info); kfree(hotplug_slot); @@ -215,9 +220,9 @@ static int init_slots(struct controller *ctrl) get_adapter_status(hotplug_slot, &info->adapter_status); slot->hotplug_slot = hotplug_slot; - dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x " - "slot_device_offset=%x\n", slot->bus, slot->device, - slot->hp_slot, slot->number, ctrl->slot_device_offset); + ctrl_dbg(ctrl, "Registering bus=%x dev=%x hp_slot=%x sun=%x " + "slot_device_offset=%x\n", slot->bus, slot->device, + slot->hp_slot, slot->number, ctrl->slot_device_offset); duplicate_name: retval = pci_hp_register(hotplug_slot, ctrl->pci_dev->subordinate, @@ -233,9 +238,11 @@ duplicate_name: if (len < SLOT_NAME_SIZE) goto duplicate_name; else - err("duplicate slot name overflow\n"); + ctrl_err(ctrl, "duplicate slot name " + "overflow\n"); } - err("pci_hp_register failed with error %d\n", retval); + ctrl_err(ctrl, "pci_hp_register failed with error %d\n", + retval); goto error_info; } /* create additional sysfs entries */ @@ -244,7 +251,8 @@ duplicate_name: &hotplug_slot_attr_lock.attr); if (retval) { pci_hp_deregister(hotplug_slot); - err("cannot create additional sysfs entries\n"); + ctrl_err(ctrl, "cannot create additional sysfs " + "entries\n"); goto error_info; } } @@ -278,7 +286,8 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) { struct slot *slot = hotplug_slot->private; - dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); + ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", + __func__, hotplug_slot->name); hotplug_slot->info->attention_status = status; @@ -293,7 +302,8 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = hotplug_slot->private; - dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); + ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", + __func__, hotplug_slot->name); return pciehp_sysfs_enable_slot(slot); } @@ -303,7 +313,8 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = hotplug_slot->private; - dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); + ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", + __func__, hotplug_slot->name); return pciehp_sysfs_disable_slot(slot); } @@ -313,7 +324,8 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) struct slot *slot = hotplug_slot->private; int retval; - dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); + ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", + __func__, hotplug_slot->name); retval = slot->hpc_ops->get_power_status(slot, value); if (retval < 0) @@ -327,7 +339,8 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) struct slot *slot = hotplug_slot->private; int retval; - dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); + ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", + __func__, hotplug_slot->name); retval = slot->hpc_ops->get_attention_status(slot, value); if (retval < 0) @@ -341,7 +354,8 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) struct slot *slot = hotplug_slot->private; int retval; - dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); + ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", + __func__, hotplug_slot->name); retval = slot->hpc_ops->get_latch_status(slot, value); if (retval < 0) @@ -355,7 +369,8 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) struct slot *slot = hotplug_slot->private; int retval; - dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); + ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", + __func__, hotplug_slot->name); retval = slot->hpc_ops->get_adapter_status(slot, value); if (retval < 0) @@ -370,7 +385,8 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, struct slot *slot = hotplug_slot->private; int retval; - dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); + ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", + __func__, hotplug_slot->name); retval = slot->hpc_ops->get_max_bus_speed(slot, value); if (retval < 0) @@ -384,7 +400,8 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe struct slot *slot = hotplug_slot->private; int retval; - dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); + ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", + __func__, hotplug_slot->name); retval = slot->hpc_ops->get_cur_bus_speed(slot, value); if (retval < 0) @@ -402,14 +419,15 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ struct pci_dev *pdev = dev->port; if (pciehp_force) - dbg("Bypassing BIOS check for pciehp use on %s\n", - pci_name(pdev)); + dev_info(&dev->device, + "Bypassing BIOS check for pciehp use on %s\n", + pci_name(pdev)); else if (pciehp_get_hp_hw_control_from_firmware(pdev)) goto err_out_none; ctrl = pcie_init(dev); if (!ctrl) { - dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME); + dev_err(&dev->device, "controller initialization failed\n"); goto err_out_none; } set_service_data(dev, ctrl); @@ -418,11 +436,10 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ rc = init_slots(ctrl); if (rc) { if (rc == -EBUSY) - warn("%s: slot already registered by another " - "hotplug driver\n", PCIE_MODULE_NAME); + ctrl_warn(ctrl, "slot already registered by another " + "hotplug driver\n"); else - err("%s: slot initialization failed\n", - PCIE_MODULE_NAME); + ctrl_err(ctrl, "slot initialization failed\n"); goto err_out_release_ctlr; } @@ -461,13 +478,13 @@ static void pciehp_remove (struct pcie_device *dev) #ifdef CONFIG_PM static int pciehp_suspend (struct pcie_device *dev, pm_message_t state) { - printk("%s ENTRY\n", __func__); + dev_info(&dev->device, "%s ENTRY\n", __func__); return 0; } static int pciehp_resume (struct pcie_device *dev) { - printk("%s ENTRY\n", __func__); + dev_info(&dev->device, "%s ENTRY\n", __func__); if (pciehp_force) { struct controller *ctrl = get_service_data(dev); struct slot *t_slot; @@ -497,10 +514,9 @@ static struct pcie_port_service_id port_pci_ids[] = { { .driver_data = 0, }, { /* end: all zeroes */ } }; -static const char device_name[] = "hpdriver"; static struct pcie_port_service_driver hpdriver_portdrv = { - .name = (char *)device_name, + .name = PCIE_MODULE_NAME, .id_table = &port_pci_ids[0], .probe = pciehp_probe, diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 96a5d55a498..acb7f9efd18 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -58,14 +58,15 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) u8 pciehp_handle_attention_button(struct slot *p_slot) { u32 event_type; + struct controller *ctrl = p_slot->ctrl; /* Attention Button Change */ - dbg("pciehp: Attention button interrupt received.\n"); + ctrl_dbg(ctrl, "Attention button interrupt received.\n"); /* * Button pressed - See if need to TAKE ACTION!!! */ - info("Button pressed on Slot(%s)\n", p_slot->name); + ctrl_info(ctrl, "Button pressed on Slot(%s)\n", p_slot->name); event_type = INT_BUTTON_PRESS; queue_interrupt_event(p_slot, event_type); @@ -77,22 +78,23 @@ u8 pciehp_handle_switch_change(struct slot *p_slot) { u8 getstatus; u32 event_type; + struct controller *ctrl = p_slot->ctrl; /* Switch Change */ - dbg("pciehp: Switch interrupt received.\n"); + ctrl_dbg(ctrl, "Switch interrupt received.\n"); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (getstatus) { /* * Switch opened */ - info("Latch open on Slot(%s)\n", p_slot->name); + ctrl_info(ctrl, "Latch open on Slot(%s)\n", p_slot->name); event_type = INT_SWITCH_OPEN; } else { /* * Switch closed */ - info("Latch close on Slot(%s)\n", p_slot->name); + ctrl_info(ctrl, "Latch close on Slot(%s)\n", p_slot->name); event_type = INT_SWITCH_CLOSE; } @@ -105,9 +107,10 @@ u8 pciehp_handle_presence_change(struct slot *p_slot) { u32 event_type; u8 presence_save; + struct controller *ctrl = p_slot->ctrl; /* Presence Change */ - dbg("pciehp: Presence/Notify input change.\n"); + ctrl_dbg(ctrl, "Presence/Notify input change.\n"); /* Switch is open, assume a presence change * Save the presence state @@ -117,13 +120,13 @@ u8 pciehp_handle_presence_change(struct slot *p_slot) /* * Card Present */ - info("Card present on Slot(%s)\n", p_slot->name); + ctrl_info(ctrl, "Card present on Slot(%s)\n", p_slot->name); event_type = INT_PRESENCE_ON; } else { /* * Not Present */ - info("Card not present on Slot(%s)\n", p_slot->name); + ctrl_info(ctrl, "Card not present on Slot(%s)\n", p_slot->name); event_type = INT_PRESENCE_OFF; } @@ -135,23 +138,25 @@ u8 pciehp_handle_presence_change(struct slot *p_slot) u8 pciehp_handle_power_fault(struct slot *p_slot) { u32 event_type; + struct controller *ctrl = p_slot->ctrl; /* power fault */ - dbg("pciehp: Power fault interrupt received.\n"); + ctrl_dbg(ctrl, "Power fault interrupt received.\n"); if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { /* * power fault Cleared */ - info("Power fault cleared on Slot(%s)\n", p_slot->name); + ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n", + p_slot->name); event_type = INT_POWER_FAULT_CLEAR; } else { /* * power fault */ - info("Power fault on Slot(%s)\n", p_slot->name); + ctrl_info(ctrl, "Power fault on Slot(%s)\n", p_slot->name); event_type = INT_POWER_FAULT; - info("power fault bit %x set\n", 0); + ctrl_info(ctrl, "power fault bit %x set\n", 0); } queue_interrupt_event(p_slot, event_type); @@ -168,8 +173,9 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ if (POWER_CTRL(ctrl)) { if (pslot->hpc_ops->power_off_slot(pslot)) { - err("%s: Issue of Slot Power Off command failed\n", - __func__); + ctrl_err(ctrl, + "%s: Issue of Slot Power Off command failed\n", + __func__); return; } } @@ -186,8 +192,8 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) if (ATTN_LED(ctrl)) { if (pslot->hpc_ops->set_attention_status(pslot, 1)) { - err("%s: Issue of Set Attention Led command failed\n", - __func__); + ctrl_err(ctrl, "%s: Issue of Set Attention " + "Led command failed\n", __func__); return; } } @@ -205,9 +211,9 @@ static int board_added(struct slot *p_slot) int retval = 0; struct controller *ctrl = p_slot->ctrl; - dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n", - __func__, p_slot->device, - ctrl->slot_device_offset, p_slot->hp_slot); + ctrl_dbg(ctrl, "%s: slot device, slot offset, hp slot = %d, %d ,%d\n", + __func__, p_slot->device, ctrl->slot_device_offset, + p_slot->hp_slot); if (POWER_CTRL(ctrl)) { /* Power on slot */ @@ -225,22 +231,22 @@ static int board_added(struct slot *p_slot) /* Check link training status */ retval = p_slot->hpc_ops->check_lnk_status(ctrl); if (retval) { - err("%s: Failed to check link status\n", __func__); + ctrl_err(ctrl, "%s: Failed to check link status\n", __func__); set_slot_off(ctrl, p_slot); return retval; } /* Check for a power fault */ if (p_slot->hpc_ops->query_power_fault(p_slot)) { - dbg("%s: power fault detected\n", __func__); + ctrl_dbg(ctrl, "%s: power fault detected\n", __func__); retval = POWER_FAILURE; goto err_exit; } retval = pciehp_configure_device(p_slot); if (retval) { - err("Cannot add device 0x%x:%x\n", p_slot->bus, - p_slot->device); + ctrl_err(ctrl, "Cannot add device 0x%x:%x\n", + p_slot->bus, p_slot->device); goto err_exit; } @@ -272,14 +278,14 @@ static int remove_board(struct slot *p_slot) if (retval) return retval; - dbg("In %s, hp_slot = %d\n", __func__, p_slot->hp_slot); + ctrl_dbg(ctrl, "In %s, hp_slot = %d\n", __func__, p_slot->hp_slot); if (POWER_CTRL(ctrl)) { /* power off slot */ retval = p_slot->hpc_ops->power_off_slot(p_slot); if (retval) { - err("%s: Issue of Slot Disable command failed\n", - __func__); + ctrl_err(ctrl, "%s: Issue of Slot Disable command " + "failed\n", __func__); return retval; } } @@ -320,8 +326,8 @@ static void pciehp_power_thread(struct work_struct *work) switch (p_slot->state) { case POWEROFF_STATE: mutex_unlock(&p_slot->lock); - dbg("%s: disabling bus:device(%x:%x)\n", - __func__, p_slot->bus, p_slot->device); + ctrl_dbg(p_slot->ctrl, "%s: disabling bus:device(%x:%x)\n", + __func__, p_slot->bus, p_slot->device); pciehp_disable_slot(p_slot); mutex_lock(&p_slot->lock); p_slot->state = STATIC_STATE; @@ -349,7 +355,8 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) { - err("%s: Cannot allocate memory\n", __func__); + ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", + __func__); return; } info->p_slot = p_slot; @@ -403,12 +410,14 @@ static void handle_button_press_event(struct slot *p_slot) p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (getstatus) { p_slot->state = BLINKINGOFF_STATE; - info("PCI slot #%s - powering off due to button " - "press.\n", p_slot->name); + ctrl_info(ctrl, + "PCI slot #%s - powering off due to button " + "press.\n", p_slot->name); } else { p_slot->state = BLINKINGON_STATE; - info("PCI slot #%s - powering on due to button " - "press.\n", p_slot->name); + ctrl_info(ctrl, + "PCI slot #%s - powering on due to button " + "press.\n", p_slot->name); } /* blink green LED and turn off amber */ if (PWR_LED(ctrl)) @@ -425,8 +434,8 @@ static void handle_button_press_event(struct slot *p_slot) * press the attention again before the 5 sec. limit * expires to cancel hot-add or hot-remove */ - info("Button cancel on Slot(%s)\n", p_slot->name); - dbg("%s: button cancel\n", __func__); + ctrl_info(ctrl, "Button cancel on Slot(%s)\n", p_slot->name); + ctrl_dbg(ctrl, "%s: button cancel\n", __func__); cancel_delayed_work(&p_slot->work); if (p_slot->state == BLINKINGOFF_STATE) { if (PWR_LED(ctrl)) @@ -437,8 +446,8 @@ static void handle_button_press_event(struct slot *p_slot) } if (ATTN_LED(ctrl)) p_slot->hpc_ops->set_attention_status(p_slot, 0); - info("PCI slot #%s - action canceled due to button press\n", - p_slot->name); + ctrl_info(ctrl, "PCI slot #%s - action canceled " + "due to button press\n", p_slot->name); p_slot->state = STATIC_STATE; break; case POWEROFF_STATE: @@ -448,11 +457,11 @@ static void handle_button_press_event(struct slot *p_slot) * this means that the previous attention button action * to hot-add or hot-remove is undergoing */ - info("Button ignore on Slot(%s)\n", p_slot->name); + ctrl_info(ctrl, "Button ignore on Slot(%s)\n", p_slot->name); update_slot_info(p_slot); break; default: - warn("Not a valid state\n"); + ctrl_warn(ctrl, "Not a valid state\n"); break; } } @@ -467,7 +476,8 @@ static void handle_surprise_event(struct slot *p_slot) info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) { - err("%s: Cannot allocate memory\n", __func__); + ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", + __func__); return; } info->p_slot = p_slot; @@ -505,7 +515,7 @@ static void interrupt_event_handler(struct work_struct *work) case INT_PRESENCE_OFF: if (!HP_SUPR_RM(ctrl)) break; - dbg("Surprise Removal\n"); + ctrl_dbg(ctrl, "Surprise Removal\n"); update_slot_info(p_slot); handle_surprise_event(p_slot); break; @@ -522,22 +532,23 @@ int pciehp_enable_slot(struct slot *p_slot) { u8 getstatus = 0; int rc; + struct controller *ctrl = p_slot->ctrl; /* Check to see if (latch closed, card present, power off) */ mutex_lock(&p_slot->ctrl->crit_sect); rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (rc || !getstatus) { - info("%s: no adapter on slot(%s)\n", __func__, - p_slot->name); + ctrl_info(ctrl, "%s: no adapter on slot(%s)\n", + __func__, p_slot->name); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } if (MRL_SENS(p_slot->ctrl)) { rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { - info("%s: latch open on slot(%s)\n", __func__, - p_slot->name); + ctrl_info(ctrl, "%s: latch open on slot(%s)\n", + __func__, p_slot->name); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -546,8 +557,8 @@ int pciehp_enable_slot(struct slot *p_slot) if (POWER_CTRL(p_slot->ctrl)) { rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { - info("%s: already enabled on slot(%s)\n", __func__, - p_slot->name); + ctrl_info(ctrl, "%s: already enabled on slot(%s)\n", + __func__, p_slot->name); mutex_unlock(&p_slot->ctrl->crit_sect); return -EINVAL; } @@ -571,6 +582,7 @@ int pciehp_disable_slot(struct slot *p_slot) { u8 getstatus = 0; int ret = 0; + struct controller *ctrl = p_slot->ctrl; if (!p_slot->ctrl) return 1; @@ -581,8 +593,8 @@ int pciehp_disable_slot(struct slot *p_slot) if (!HP_SUPR_RM(p_slot->ctrl)) { ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (ret || !getstatus) { - info("%s: no adapter on slot(%s)\n", __func__, - p_slot->name); + ctrl_info(ctrl, "%s: no adapter on slot(%s)\n", + __func__, p_slot->name); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -591,8 +603,8 @@ int pciehp_disable_slot(struct slot *p_slot) if (MRL_SENS(p_slot->ctrl)) { ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (ret || getstatus) { - info("%s: latch open on slot(%s)\n", __func__, - p_slot->name); + ctrl_info(ctrl, "%s: latch open on slot(%s)\n", + __func__, p_slot->name); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -601,8 +613,8 @@ int pciehp_disable_slot(struct slot *p_slot) if (POWER_CTRL(p_slot->ctrl)) { ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (ret || !getstatus) { - info("%s: already disabled slot(%s)\n", __func__, - p_slot->name); + ctrl_info(ctrl, "%s: already disabled slot(%s)\n", + __func__, p_slot->name); mutex_unlock(&p_slot->ctrl->crit_sect); return -EINVAL; } @@ -618,6 +630,7 @@ int pciehp_disable_slot(struct slot *p_slot) int pciehp_sysfs_enable_slot(struct slot *p_slot) { int retval = -ENODEV; + struct controller *ctrl = p_slot->ctrl; mutex_lock(&p_slot->lock); switch (p_slot->state) { @@ -631,15 +644,15 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot) p_slot->state = STATIC_STATE; break; case POWERON_STATE: - info("Slot %s is already in powering on state\n", - p_slot->name); + ctrl_info(ctrl, "Slot %s is already in powering on state\n", + p_slot->name); break; case BLINKINGOFF_STATE: case POWEROFF_STATE: - info("Already enabled on slot %s\n", p_slot->name); + ctrl_info(ctrl, "Already enabled on slot %s\n", p_slot->name); break; default: - err("Not a valid state on slot %s\n", p_slot->name); + ctrl_err(ctrl, "Not a valid state on slot %s\n", p_slot->name); break; } mutex_unlock(&p_slot->lock); @@ -650,6 +663,7 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot) int pciehp_sysfs_disable_slot(struct slot *p_slot) { int retval = -ENODEV; + struct controller *ctrl = p_slot->ctrl; mutex_lock(&p_slot->lock); switch (p_slot->state) { @@ -663,15 +677,15 @@ int pciehp_sysfs_disable_slot(struct slot *p_slot) p_slot->state = STATIC_STATE; break; case POWEROFF_STATE: - info("Slot %s is already in powering off state\n", - p_slot->name); + ctrl_info(ctrl, "Slot %s is already in powering off state\n", + p_slot->name); break; case BLINKINGON_STATE: case POWERON_STATE: - info("Already disabled on slot %s\n", p_slot->name); + ctrl_info(ctrl, "Already disabled on slot %s\n", p_slot->name); break; default: - err("Not a valid state on slot %s\n", p_slot->name); + ctrl_err(ctrl, "Not a valid state on slot %s\n", p_slot->name); break; } mutex_unlock(&p_slot->lock); diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9d934ddee95..8e9530c4c36 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -223,7 +223,7 @@ static void start_int_poll_timer(struct controller *ctrl, int sec) static inline int pciehp_request_irq(struct controller *ctrl) { - int retval, irq = ctrl->pci_dev->irq; + int retval, irq = ctrl->pcie->irq; /* Install interrupt polling timer. Start with 10 sec delay */ if (pciehp_poll_mode) { @@ -235,7 +235,8 @@ static inline int pciehp_request_irq(struct controller *ctrl) /* Installs the interrupt handler */ retval = request_irq(irq, pcie_isr, IRQF_SHARED, MY_NAME, ctrl); if (retval) - err("Cannot get irq %d for the hotplug controller\n", irq); + ctrl_err(ctrl, "Cannot get irq %d for the hotplug controller\n", + irq); return retval; } @@ -244,7 +245,7 @@ static inline void pciehp_free_irq(struct controller *ctrl) if (pciehp_poll_mode) del_timer_sync(&ctrl->poll_timer); else - free_irq(ctrl->pci_dev->irq, ctrl); + free_irq(ctrl->pcie->irq, ctrl); } static int pcie_poll_cmd(struct controller *ctrl) @@ -282,7 +283,7 @@ static void pcie_wait_cmd(struct controller *ctrl, int poll) else rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout); if (!rc) - dbg("Command not completed in 1000 msec\n"); + ctrl_dbg(ctrl, "Command not completed in 1000 msec\n"); } /** @@ -301,7 +302,8 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (retval) { - err("%s: Cannot read SLOTSTATUS register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", + __func__); goto out; } @@ -312,26 +314,28 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) * proceed forward to issue the next command according * to spec. Just print out the error message. */ - dbg("%s: CMD_COMPLETED not clear after 1 sec.\n", - __func__); + ctrl_dbg(ctrl, + "%s: CMD_COMPLETED not clear after 1 sec.\n", + __func__); } else if (!NO_CMD_CMPL(ctrl)) { /* * This controller semms to notify of command completed * event even though it supports none of power * controller, attention led, power led and EMI. */ - dbg("%s: Unexpected CMD_COMPLETED. Need to wait for " - "command completed event.\n", __func__); + ctrl_dbg(ctrl, "%s: Unexpected CMD_COMPLETED. Need to " + "wait for command completed event.\n", + __func__); ctrl->no_cmd_complete = 0; } else { - dbg("%s: Unexpected CMD_COMPLETED. Maybe the " - "controller is broken.\n", __func__); + ctrl_dbg(ctrl, "%s: Unexpected CMD_COMPLETED. Maybe " + "the controller is broken.\n", __func__); } } retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (retval) { - err("%s: Cannot read SLOTCTRL register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); goto out; } @@ -341,7 +345,8 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) smp_mb(); retval = pciehp_writew(ctrl, SLOTCTRL, slot_ctrl); if (retval) - err("%s: Cannot write to SLOTCTRL register\n", __func__); + ctrl_err(ctrl, "%s: Cannot write to SLOTCTRL register\n", + __func__); /* * Wait for command completion. @@ -370,14 +375,15 @@ static int hpc_check_lnk_status(struct controller *ctrl) retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); if (retval) { - err("%s: Cannot read LNKSTATUS register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", + __func__); return retval; } - dbg("%s: lnk_status = %x\n", __func__, lnk_status); + ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) || !(lnk_status & NEG_LINK_WD)) { - err("%s : Link Training Error occurs \n", __func__); + ctrl_err(ctrl, "%s : Link Training Error occurs \n", __func__); retval = -1; return retval; } @@ -394,12 +400,12 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (retval) { - err("%s: Cannot read SLOTCTRL register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); return retval; } - dbg("%s: SLOTCTRL %x, value read %x\n", - __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl); + ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", + __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl); atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; @@ -433,11 +439,11 @@ static int hpc_get_power_status(struct slot *slot, u8 *status) retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); if (retval) { - err("%s: Cannot read SLOTCTRL register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); return retval; } - dbg("%s: SLOTCTRL %x value read %x\n", - __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl); + ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", + __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl); pwr_state = (slot_ctrl & PWR_CTRL) >> 10; @@ -464,7 +470,8 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (retval) { - err("%s: Cannot read SLOTSTATUS register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", + __func__); return retval; } @@ -482,7 +489,8 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (retval) { - err("%s: Cannot read SLOTSTATUS register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", + __func__); return retval; } card_state = (u8)((slot_status & PRSN_STATE) >> 6); @@ -500,7 +508,7 @@ static int hpc_query_power_fault(struct slot *slot) retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (retval) { - err("%s: Cannot check for power fault\n", __func__); + ctrl_err(ctrl, "%s: Cannot check for power fault\n", __func__); return retval; } pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1); @@ -516,7 +524,7 @@ static int hpc_get_emi_status(struct slot *slot, u8 *status) retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (retval) { - err("%s : Cannot check EMI status\n", __func__); + ctrl_err(ctrl, "%s : Cannot check EMI status\n", __func__); return retval; } *status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT; @@ -560,8 +568,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) return -1; } rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); - dbg("%s: SLOTCTRL %x write cmd %x\n", - __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); + ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", + __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); return rc; } @@ -575,8 +583,8 @@ static void hpc_set_green_led_on(struct slot *slot) slot_cmd = 0x0100; cmd_mask = PWR_LED_CTRL; pcie_write_cmd(ctrl, slot_cmd, cmd_mask); - dbg("%s: SLOTCTRL %x write cmd %x\n", - __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); + ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", + __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); } static void hpc_set_green_led_off(struct slot *slot) @@ -588,8 +596,8 @@ static void hpc_set_green_led_off(struct slot *slot) slot_cmd = 0x0300; cmd_mask = PWR_LED_CTRL; pcie_write_cmd(ctrl, slot_cmd, cmd_mask); - dbg("%s: SLOTCTRL %x write cmd %x\n", - __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); + ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", + __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); } static void hpc_set_green_led_blink(struct slot *slot) @@ -601,8 +609,8 @@ static void hpc_set_green_led_blink(struct slot *slot) slot_cmd = 0x0200; cmd_mask = PWR_LED_CTRL; pcie_write_cmd(ctrl, slot_cmd, cmd_mask); - dbg("%s: SLOTCTRL %x write cmd %x\n", - __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); + ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", + __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); } static int hpc_power_on_slot(struct slot * slot) @@ -613,20 +621,22 @@ static int hpc_power_on_slot(struct slot * slot) u16 slot_status; int retval = 0; - dbg("%s: slot->hp_slot %x\n", __func__, slot->hp_slot); + ctrl_dbg(ctrl, "%s: slot->hp_slot %x\n", __func__, slot->hp_slot); /* Clear sticky power-fault bit from previous power failures */ retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); if (retval) { - err("%s: Cannot read SLOTSTATUS register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", + __func__); return retval; } slot_status &= PWR_FAULT_DETECTED; if (slot_status) { retval = pciehp_writew(ctrl, SLOTSTATUS, slot_status); if (retval) { - err("%s: Cannot write to SLOTSTATUS register\n", - __func__); + ctrl_err(ctrl, + "%s: Cannot write to SLOTSTATUS register\n", + __func__); return retval; } } @@ -644,11 +654,12 @@ static int hpc_power_on_slot(struct slot * slot) retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); if (retval) { - err("%s: Write %x command failed!\n", __func__, slot_cmd); + ctrl_err(ctrl, "%s: Write %x command failed!\n", + __func__, slot_cmd); return -1; } - dbg("%s: SLOTCTRL %x write cmd %x\n", - __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); + ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", + __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); return retval; } @@ -694,7 +705,7 @@ static int hpc_power_off_slot(struct slot * slot) int retval = 0; int changed; - dbg("%s: slot->hp_slot %x\n", __func__, slot->hp_slot); + ctrl_dbg(ctrl, "%s: slot->hp_slot %x\n", __func__, slot->hp_slot); /* * Set Bad DLLP Mask bit in Correctable Error Mask @@ -722,12 +733,12 @@ static int hpc_power_off_slot(struct slot * slot) retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); if (retval) { - err("%s: Write command failed!\n", __func__); + ctrl_err(ctrl, "%s: Write command failed!\n", __func__); retval = -1; goto out; } - dbg("%s: SLOTCTRL %x write cmd %x\n", - __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); + ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", + __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); out: if (changed) pcie_unmask_bad_dllp(ctrl); @@ -749,7 +760,8 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) intr_loc = 0; do { if (pciehp_readw(ctrl, SLOTSTATUS, &detected)) { - err("%s: Cannot read SLOTSTATUS\n", __func__); + ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS\n", + __func__); return IRQ_NONE; } @@ -760,12 +772,13 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) if (!intr_loc) return IRQ_NONE; if (detected && pciehp_writew(ctrl, SLOTSTATUS, detected)) { - err("%s: Cannot write to SLOTSTATUS\n", __func__); + ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n", + __func__); return IRQ_NONE; } } while (detected); - dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); + ctrl_dbg(ctrl, "%s: intr_loc %x\n", __func__, intr_loc); /* Check Command Complete Interrupt Pending */ if (intr_loc & CMD_COMPLETED) { @@ -807,7 +820,7 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value) retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); if (retval) { - err("%s: Cannot read LNKCAP register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); return retval; } @@ -821,7 +834,7 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value) } *value = lnk_speed; - dbg("Max link speed = %d\n", lnk_speed); + ctrl_dbg(ctrl, "Max link speed = %d\n", lnk_speed); return retval; } @@ -836,7 +849,7 @@ static int hpc_get_max_lnk_width(struct slot *slot, retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); if (retval) { - err("%s: Cannot read LNKCAP register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); return retval; } @@ -871,7 +884,7 @@ static int hpc_get_max_lnk_width(struct slot *slot, } *value = lnk_wdth; - dbg("Max link width = %d\n", lnk_wdth); + ctrl_dbg(ctrl, "Max link width = %d\n", lnk_wdth); return retval; } @@ -885,7 +898,8 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value) retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); if (retval) { - err("%s: Cannot read LNKSTATUS register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", + __func__); return retval; } @@ -899,7 +913,7 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value) } *value = lnk_speed; - dbg("Current link speed = %d\n", lnk_speed); + ctrl_dbg(ctrl, "Current link speed = %d\n", lnk_speed); return retval; } @@ -914,7 +928,8 @@ static int hpc_get_cur_lnk_width(struct slot *slot, retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); if (retval) { - err("%s: Cannot read LNKSTATUS register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", + __func__); return retval; } @@ -949,7 +964,7 @@ static int hpc_get_cur_lnk_width(struct slot *slot, } *value = lnk_wdth; - dbg("Current link width = %d\n", lnk_wdth); + ctrl_dbg(ctrl, "Current link width = %d\n", lnk_wdth); return retval; } @@ -998,7 +1013,8 @@ int pcie_enable_notification(struct controller *ctrl) PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE; if (pcie_write_cmd(ctrl, cmd, mask)) { - err("%s: Cannot enable software notification\n", __func__); + ctrl_err(ctrl, "%s: Cannot enable software notification\n", + __func__); return -1; } return 0; @@ -1010,7 +1026,8 @@ static void pcie_disable_notification(struct controller *ctrl) mask = PRSN_DETECT_ENABLE | ATTN_BUTTN_ENABLE | MRL_DETECT_ENABLE | PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE; if (pcie_write_cmd(ctrl, 0, mask)) - warn("%s: Cannot disable software notification\n", __func__); + ctrl_warn(ctrl, "%s: Cannot disable software notification\n", + __func__); } static int pcie_init_notification(struct controller *ctrl) @@ -1071,34 +1088,45 @@ static inline void dbg_ctrl(struct controller *ctrl) if (!pciehp_debug) return; - dbg("Hotplug Controller:\n"); - dbg(" Seg/Bus/Dev/Func/IRQ : %s IRQ %d\n", pci_name(pdev), pdev->irq); - dbg(" Vendor ID : 0x%04x\n", pdev->vendor); - dbg(" Device ID : 0x%04x\n", pdev->device); - dbg(" Subsystem ID : 0x%04x\n", pdev->subsystem_device); - dbg(" Subsystem Vendor ID : 0x%04x\n", pdev->subsystem_vendor); - dbg(" PCIe Cap offset : 0x%02x\n", ctrl->cap_base); + ctrl_info(ctrl, "Hotplug Controller:\n"); + ctrl_info(ctrl, " Seg/Bus/Dev/Func/IRQ : %s IRQ %d\n", + pci_name(pdev), pdev->irq); + ctrl_info(ctrl, " Vendor ID : 0x%04x\n", pdev->vendor); + ctrl_info(ctrl, " Device ID : 0x%04x\n", pdev->device); + ctrl_info(ctrl, " Subsystem ID : 0x%04x\n", + pdev->subsystem_device); + ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n", + pdev->subsystem_vendor); + ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n", ctrl->cap_base); for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { if (!pci_resource_len(pdev, i)) continue; - dbg(" PCI resource [%d] : 0x%llx@0x%llx\n", i, - (unsigned long long)pci_resource_len(pdev, i), - (unsigned long long)pci_resource_start(pdev, i)); + ctrl_info(ctrl, " PCI resource [%d] : 0x%llx@0x%llx\n", + i, (unsigned long long)pci_resource_len(pdev, i), + (unsigned long long)pci_resource_start(pdev, i)); } - dbg("Slot Capabilities : 0x%08x\n", ctrl->slot_cap); - dbg(" Physical Slot Number : %d\n", ctrl->first_slot); - dbg(" Attention Button : %3s\n", ATTN_BUTTN(ctrl) ? "yes" : "no"); - dbg(" Power Controller : %3s\n", POWER_CTRL(ctrl) ? "yes" : "no"); - dbg(" MRL Sensor : %3s\n", MRL_SENS(ctrl) ? "yes" : "no"); - dbg(" Attention Indicator : %3s\n", ATTN_LED(ctrl) ? "yes" : "no"); - dbg(" Power Indicator : %3s\n", PWR_LED(ctrl) ? "yes" : "no"); - dbg(" Hot-Plug Surprise : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no"); - dbg(" EMI Present : %3s\n", EMI(ctrl) ? "yes" : "no"); - dbg(" Command Completed : %3s\n", NO_CMD_CMPL(ctrl)? "no" : "yes"); + ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); + ctrl_info(ctrl, " Physical Slot Number : %d\n", ctrl->first_slot); + ctrl_info(ctrl, " Attention Button : %3s\n", + ATTN_BUTTN(ctrl) ? "yes" : "no"); + ctrl_info(ctrl, " Power Controller : %3s\n", + POWER_CTRL(ctrl) ? "yes" : "no"); + ctrl_info(ctrl, " MRL Sensor : %3s\n", + MRL_SENS(ctrl) ? "yes" : "no"); + ctrl_info(ctrl, " Attention Indicator : %3s\n", + ATTN_LED(ctrl) ? "yes" : "no"); + ctrl_info(ctrl, " Power Indicator : %3s\n", + PWR_LED(ctrl) ? "yes" : "no"); + ctrl_info(ctrl, " Hot-Plug Surprise : %3s\n", + HP_SUPR_RM(ctrl) ? "yes" : "no"); + ctrl_info(ctrl, " EMI Present : %3s\n", + EMI(ctrl) ? "yes" : "no"); + ctrl_info(ctrl, " Command Completed : %3s\n", + NO_CMD_CMPL(ctrl) ? "no" : "yes"); pciehp_readw(ctrl, SLOTSTATUS, ®16); - dbg("Slot Status : 0x%04x\n", reg16); + ctrl_info(ctrl, "Slot Status : 0x%04x\n", reg16); pciehp_readw(ctrl, SLOTCTRL, ®16); - dbg("Slot Control : 0x%04x\n", reg16); + ctrl_info(ctrl, "Slot Control : 0x%04x\n", reg16); } struct controller *pcie_init(struct pcie_device *dev) @@ -1109,19 +1137,21 @@ struct controller *pcie_init(struct pcie_device *dev) ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); if (!ctrl) { - err("%s : out of memory\n", __func__); + dev_err(&dev->device, "%s : out of memory\n", __func__); goto abort; } INIT_LIST_HEAD(&ctrl->slot_list); + ctrl->pcie = dev; ctrl->pci_dev = pdev; ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP); if (!ctrl->cap_base) { - err("%s: Cannot find PCI Express capability\n", __func__); + ctrl_err(ctrl, "%s: Cannot find PCI Express capability\n", + __func__); goto abort; } if (pciehp_readl(ctrl, SLOTCAP, &slot_cap)) { - err("%s: Cannot read SLOTCAP register\n", __func__); + ctrl_err(ctrl, "%s: Cannot read SLOTCAP register\n", __func__); goto abort; } @@ -1161,9 +1191,9 @@ struct controller *pcie_init(struct pcie_device *dev) goto abort_ctrl; } - info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", - pdev->vendor, pdev->device, - pdev->subsystem_vendor, pdev->subsystem_device); + ctrl_info(ctrl, "HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", + pdev->vendor, pdev->device, pdev->subsystem_vendor, + pdev->subsystem_device); if (pcie_init_slot(ctrl)) goto abort_ctrl; diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 6040dcceb25..ffd11148fbe 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -198,18 +198,20 @@ int pciehp_configure_device(struct slot *p_slot) struct pci_dev *dev; struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; int num, fn; + struct controller *ctrl = p_slot->ctrl; dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); if (dev) { - err("Device %s already exists at %x:%x, cannot hot-add\n", - pci_name(dev), p_slot->bus, p_slot->device); + ctrl_err(ctrl, + "Device %s already exists at %x:%x, cannot hot-add\n", + pci_name(dev), p_slot->bus, p_slot->device); pci_dev_put(dev); return -EINVAL; } num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0)); if (num == 0) { - err("No new device found\n"); + ctrl_err(ctrl, "No new device found\n"); return -ENODEV; } @@ -218,8 +220,8 @@ int pciehp_configure_device(struct slot *p_slot) if (!dev) continue; if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { - err("Cannot hot-add display device %s\n", - pci_name(dev)); + ctrl_err(ctrl, "Cannot hot-add display device %s\n", + pci_name(dev)); pci_dev_put(dev); continue; } @@ -244,9 +246,10 @@ int pciehp_unconfigure_device(struct slot *p_slot) u8 presence = 0; struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; u16 command; + struct controller *ctrl = p_slot->ctrl; - dbg("%s: bus/dev = %x/%x\n", __func__, p_slot->bus, - p_slot->device); + ctrl_dbg(ctrl, "%s: bus/dev = %x/%x\n", __func__, + p_slot->bus, p_slot->device); ret = p_slot->hpc_ops->get_adapter_status(p_slot, &presence); if (ret) presence = 0; @@ -257,16 +260,17 @@ int pciehp_unconfigure_device(struct slot *p_slot) if (!temp) continue; if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) { - err("Cannot remove display device %s\n", - pci_name(temp)); + ctrl_err(ctrl, "Cannot remove display device %s\n", + pci_name(temp)); pci_dev_put(temp); continue; } if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); if (bctl & PCI_BRIDGE_CTL_VGA) { - err("Cannot remove display device %s\n", - pci_name(temp)); + ctrl_err(ctrl, + "Cannot remove display device %s\n", + pci_name(temp)); pci_dev_put(temp); continue; } diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 7d5921b1ee7..419919a87b0 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -46,10 +46,10 @@ #define PRESENT 1 /* Card in slot */ #define MY_NAME "rpaphp" -extern int debug; +extern int rpaphp_debug; #define dbg(format, arg...) \ do { \ - if (debug) \ + if (rpaphp_debug) \ printk(KERN_DEBUG "%s: " format, \ MY_NAME , ## arg); \ } while (0) diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 1f84f402acd..95d02a08fdc 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -37,7 +37,7 @@ /* and pci_do_scan_bus */ #include "rpaphp.h" -int debug; +int rpaphp_debug; LIST_HEAD(rpaphp_slot_head); #define DRIVER_VERSION "0.1" @@ -50,7 +50,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -module_param(debug, bool, 0644); +module_param_named(debug, rpaphp_debug, bool, 0644); /** * set_attention_status - set attention LED diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 5acfd4f3d4c..513e1e28239 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -123,7 +123,7 @@ int rpaphp_enable_slot(struct slot *slot) slot->state = CONFIGURED; } - if (debug) { + if (rpaphp_debug) { struct pci_dev *dev; dbg("%s: pci_devs of slot[%s]\n", __func__, slot->dn->full_name); list_for_each_entry (dev, &bus->devices, bus_list) diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index 279c940a003..bf7d6ce9bbb 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c @@ -126,7 +126,8 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) cfg->msg.address_hi = 0xffffffff; irq = create_irq(); - if (irq < 0) { + + if (irq <= 0) { kfree(cfg); return -EBUSY; } diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index fc5f2dbf532..8b51e10b778 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -563,7 +563,7 @@ static int __iommu_flush_context(struct intel_iommu *iommu, spin_unlock_irqrestore(&iommu->register_lock, flag); - /* flush context entry will implictly flush write buffer */ + /* flush context entry will implicitly flush write buffer */ return 0; } @@ -656,7 +656,7 @@ static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did, if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type)) pr_debug("IOMMU: tlb flush request %Lx, actual %Lx\n", DMA_TLB_IIRG(type), DMA_TLB_IAIG(val)); - /* flush context entry will implictly flush write buffer */ + /* flush iotlb entry will implicitly flush write buffer */ return 0; } diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 738d4c89581..2de5a3238c9 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c @@ -1,3 +1,4 @@ +#include <linux/interrupt.h> #include <linux/dmar.h> #include <linux/spinlock.h> #include <linux/jiffies.h> @@ -11,41 +12,64 @@ static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; static int ir_ioapic_num; int intr_remapping_enabled; -static struct { +struct irq_2_iommu { struct intel_iommu *iommu; u16 irte_index; u16 sub_handle; u8 irte_mask; -} irq_2_iommu[NR_IRQS]; +}; + +static struct irq_2_iommu irq_2_iommuX[NR_IRQS]; + +static struct irq_2_iommu *irq_2_iommu(unsigned int irq) +{ + return (irq < nr_irqs) ? irq_2_iommuX + irq : NULL; +} + +static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq) +{ + return irq_2_iommu(irq); +} static DEFINE_SPINLOCK(irq_2_ir_lock); -int irq_remapped(int irq) +static struct irq_2_iommu *valid_irq_2_iommu(unsigned int irq) { - if (irq > NR_IRQS) - return 0; + struct irq_2_iommu *irq_iommu; + + irq_iommu = irq_2_iommu(irq); + + if (!irq_iommu) + return NULL; + + if (!irq_iommu->iommu) + return NULL; - if (!irq_2_iommu[irq].iommu) - return 0; + return irq_iommu; +} - return 1; +int irq_remapped(int irq) +{ + return valid_irq_2_iommu(irq) != NULL; } int get_irte(int irq, struct irte *entry) { int index; + struct irq_2_iommu *irq_iommu; - if (!entry || irq > NR_IRQS) + if (!entry) return -1; spin_lock(&irq_2_ir_lock); - if (!irq_2_iommu[irq].iommu) { + irq_iommu = valid_irq_2_iommu(irq); + if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); return -1; } - index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle; - *entry = *(irq_2_iommu[irq].iommu->ir_table->base + index); + index = irq_iommu->irte_index + irq_iommu->sub_handle; + *entry = *(irq_iommu->iommu->ir_table->base + index); spin_unlock(&irq_2_ir_lock); return 0; @@ -54,6 +78,7 @@ int get_irte(int irq, struct irte *entry) int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) { struct ir_table *table = iommu->ir_table; + struct irq_2_iommu *irq_iommu; u16 index, start_index; unsigned int mask = 0; int i; @@ -61,6 +86,10 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) if (!count) return -1; + /* protect irq_2_iommu_alloc later */ + if (irq >= nr_irqs) + return -1; + /* * start the IRTE search from index 0. */ @@ -100,10 +129,11 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) for (i = index; i < index + count; i++) table->base[i].present = 1; - irq_2_iommu[irq].iommu = iommu; - irq_2_iommu[irq].irte_index = index; - irq_2_iommu[irq].sub_handle = 0; - irq_2_iommu[irq].irte_mask = mask; + irq_iommu = irq_2_iommu_alloc(irq); + irq_iommu->iommu = iommu; + irq_iommu->irte_index = index; + irq_iommu->sub_handle = 0; + irq_iommu->irte_mask = mask; spin_unlock(&irq_2_ir_lock); @@ -124,31 +154,33 @@ static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask) int map_irq_to_irte_handle(int irq, u16 *sub_handle) { int index; + struct irq_2_iommu *irq_iommu; spin_lock(&irq_2_ir_lock); - if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { + irq_iommu = valid_irq_2_iommu(irq); + if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); return -1; } - *sub_handle = irq_2_iommu[irq].sub_handle; - index = irq_2_iommu[irq].irte_index; + *sub_handle = irq_iommu->sub_handle; + index = irq_iommu->irte_index; spin_unlock(&irq_2_ir_lock); return index; } int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) { + struct irq_2_iommu *irq_iommu; + spin_lock(&irq_2_ir_lock); - if (irq >= NR_IRQS || irq_2_iommu[irq].iommu) { - spin_unlock(&irq_2_ir_lock); - return -1; - } - irq_2_iommu[irq].iommu = iommu; - irq_2_iommu[irq].irte_index = index; - irq_2_iommu[irq].sub_handle = subhandle; - irq_2_iommu[irq].irte_mask = 0; + irq_iommu = irq_2_iommu_alloc(irq); + + irq_iommu->iommu = iommu; + irq_iommu->irte_index = index; + irq_iommu->sub_handle = subhandle; + irq_iommu->irte_mask = 0; spin_unlock(&irq_2_ir_lock); @@ -157,16 +189,19 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index) { + struct irq_2_iommu *irq_iommu; + spin_lock(&irq_2_ir_lock); - if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { + irq_iommu = valid_irq_2_iommu(irq); + if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); return -1; } - irq_2_iommu[irq].iommu = NULL; - irq_2_iommu[irq].irte_index = 0; - irq_2_iommu[irq].sub_handle = 0; - irq_2_iommu[irq].irte_mask = 0; + irq_iommu->iommu = NULL; + irq_iommu->irte_index = 0; + irq_iommu->sub_handle = 0; + irq_2_iommu(irq)->irte_mask = 0; spin_unlock(&irq_2_ir_lock); @@ -178,16 +213,18 @@ int modify_irte(int irq, struct irte *irte_modified) int index; struct irte *irte; struct intel_iommu *iommu; + struct irq_2_iommu *irq_iommu; spin_lock(&irq_2_ir_lock); - if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { + irq_iommu = valid_irq_2_iommu(irq); + if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); return -1; } - iommu = irq_2_iommu[irq].iommu; + iommu = irq_iommu->iommu; - index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle; + index = irq_iommu->irte_index + irq_iommu->sub_handle; irte = &iommu->ir_table->base[index]; set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); @@ -203,18 +240,20 @@ int flush_irte(int irq) { int index; struct intel_iommu *iommu; + struct irq_2_iommu *irq_iommu; spin_lock(&irq_2_ir_lock); - if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { + irq_iommu = valid_irq_2_iommu(irq); + if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); return -1; } - iommu = irq_2_iommu[irq].iommu; + iommu = irq_iommu->iommu; - index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle; + index = irq_iommu->irte_index + irq_iommu->sub_handle; - qi_flush_iec(iommu, index, irq_2_iommu[irq].irte_mask); + qi_flush_iec(iommu, index, irq_iommu->irte_mask); spin_unlock(&irq_2_ir_lock); return 0; @@ -246,28 +285,30 @@ int free_irte(int irq) int index, i; struct irte *irte; struct intel_iommu *iommu; + struct irq_2_iommu *irq_iommu; spin_lock(&irq_2_ir_lock); - if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { + irq_iommu = valid_irq_2_iommu(irq); + if (!irq_iommu) { spin_unlock(&irq_2_ir_lock); return -1; } - iommu = irq_2_iommu[irq].iommu; + iommu = irq_iommu->iommu; - index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle; + index = irq_iommu->irte_index + irq_iommu->sub_handle; irte = &iommu->ir_table->base[index]; - if (!irq_2_iommu[irq].sub_handle) { - for (i = 0; i < (1 << irq_2_iommu[irq].irte_mask); i++) + if (!irq_iommu->sub_handle) { + for (i = 0; i < (1 << irq_iommu->irte_mask); i++) set_64bit((unsigned long *)irte, 0); - qi_flush_iec(iommu, index, irq_2_iommu[irq].irte_mask); + qi_flush_iec(iommu, index, irq_iommu->irte_mask); } - irq_2_iommu[irq].iommu = NULL; - irq_2_iommu[irq].irte_index = 0; - irq_2_iommu[irq].sub_handle = 0; - irq_2_iommu[irq].irte_mask = 0; + irq_iommu->iommu = NULL; + irq_iommu->irte_index = 0; + irq_iommu->sub_handle = 0; + irq_iommu->irte_mask = 0; spin_unlock(&irq_2_ir_lock); diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 4a10b5624f7..d2812013fd2 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -378,23 +378,21 @@ static int msi_capability_init(struct pci_dev *dev) entry->msi_attrib.masked = 1; entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ entry->msi_attrib.pos = pos; - if (is_mask_bit_support(control)) { + if (entry->msi_attrib.maskbit) { entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, - is_64bit_address(control)); + entry->msi_attrib.is_64); } entry->dev = dev; if (entry->msi_attrib.maskbit) { unsigned int maskbits, temp; /* All MSIs are unmasked by default, Mask them all */ pci_read_config_dword(dev, - msi_mask_bits_reg(pos, is_64bit_address(control)), + msi_mask_bits_reg(pos, entry->msi_attrib.is_64), &maskbits); temp = (1 << multi_msi_capable(control)); temp = ((temp - 1) & ~temp); maskbits |= temp; - pci_write_config_dword(dev, - msi_mask_bits_reg(pos, is_64bit_address(control)), - maskbits); + pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits); entry->msi_attrib.maskbits_mask = temp; } list_add_tail(&entry->list, &dev->msi_list); diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index a13f5348611..b4cdd690ae7 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -43,18 +43,32 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) { struct pci_dynid *dynid; struct pci_driver *pdrv = to_pci_driver(driver); + const struct pci_device_id *ids = pdrv->id_table; __u32 vendor, device, subvendor=PCI_ANY_ID, subdevice=PCI_ANY_ID, class=0, class_mask=0; unsigned long driver_data=0; int fields=0; - int retval = 0; + int retval; - fields = sscanf(buf, "%x %x %x %x %x %x %lux", + fields = sscanf(buf, "%x %x %x %x %x %x %lx", &vendor, &device, &subvendor, &subdevice, &class, &class_mask, &driver_data); if (fields < 2) return -EINVAL; + /* Only accept driver_data values that match an existing id_table + entry */ + retval = -EINVAL; + while (ids->vendor || ids->subvendor || ids->class_mask) { + if (driver_data == ids->driver_data) { + retval = 0; + break; + } + ids++; + } + if (retval) /* No match */ + return retval; + dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); if (!dynid) return -ENOMEM; @@ -65,8 +79,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) dynid->id.subdevice = subdevice; dynid->id.class = class; dynid->id.class_mask = class_mask; - dynid->id.driver_data = pdrv->dynids.use_driver_data ? - driver_data : 0UL; + dynid->id.driver_data = driver_data; spin_lock(&pdrv->dynids.lock); list_add_tail(&dynid->node, &pdrv->dynids.list); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 77baff022f7..110022d7868 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -423,7 +423,7 @@ pci_write_vpd(struct kobject *kobj, struct bin_attribute *bin_attr, * Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific * callback routine (pci_legacy_read). */ -ssize_t +static ssize_t pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -448,7 +448,7 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, * Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific * callback routine (pci_legacy_write). */ -ssize_t +static ssize_t pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { @@ -468,11 +468,11 @@ pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, * @attr: struct bin_attribute for this file * @vma: struct vm_area_struct passed to mmap * - * Uses an arch specific callback, pci_mmap_legacy_page_range, to mmap + * Uses an arch specific callback, pci_mmap_legacy_mem_page_range, to mmap * legacy memory space (first meg of bus space) into application virtual * memory space. */ -int +static int pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, struct vm_area_struct *vma) { @@ -480,7 +480,90 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, struct device, kobj)); - return pci_mmap_legacy_page_range(bus, vma); + return pci_mmap_legacy_page_range(bus, vma, pci_mmap_mem); +} + +/** + * pci_mmap_legacy_io - map legacy PCI IO into user memory space + * @kobj: kobject corresponding to device to be mapped + * @attr: struct bin_attribute for this file + * @vma: struct vm_area_struct passed to mmap + * + * Uses an arch specific callback, pci_mmap_legacy_io_page_range, to mmap + * legacy IO space (first meg of bus space) into application virtual + * memory space. Returns -ENOSYS if the operation isn't supported + */ +static int +pci_mmap_legacy_io(struct kobject *kobj, struct bin_attribute *attr, + struct vm_area_struct *vma) +{ + struct pci_bus *bus = to_pci_bus(container_of(kobj, + struct device, + kobj)); + + return pci_mmap_legacy_page_range(bus, vma, pci_mmap_io); +} + +/** + * pci_create_legacy_files - create legacy I/O port and memory files + * @b: bus to create files under + * + * Some platforms allow access to legacy I/O port and ISA memory space on + * a per-bus basis. This routine creates the files and ties them into + * their associated read, write and mmap files from pci-sysfs.c + * + * On error unwind, but don't propogate the error to the caller + * as it is ok to set up the PCI bus without these files. + */ +void pci_create_legacy_files(struct pci_bus *b) +{ + int error; + + b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2, + GFP_ATOMIC); + if (!b->legacy_io) + goto kzalloc_err; + + b->legacy_io->attr.name = "legacy_io"; + b->legacy_io->size = 0xffff; + b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; + b->legacy_io->read = pci_read_legacy_io; + b->legacy_io->write = pci_write_legacy_io; + b->legacy_io->mmap = pci_mmap_legacy_io; + error = device_create_bin_file(&b->dev, b->legacy_io); + if (error) + goto legacy_io_err; + + /* Allocated above after the legacy_io struct */ + b->legacy_mem = b->legacy_io + 1; + b->legacy_mem->attr.name = "legacy_mem"; + b->legacy_mem->size = 1024*1024; + b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; + b->legacy_mem->mmap = pci_mmap_legacy_mem; + error = device_create_bin_file(&b->dev, b->legacy_mem); + if (error) + goto legacy_mem_err; + + return; + +legacy_mem_err: + device_remove_bin_file(&b->dev, b->legacy_io); +legacy_io_err: + kfree(b->legacy_io); + b->legacy_io = NULL; +kzalloc_err: + printk(KERN_WARNING "pci: warning: could not create legacy I/O port " + "and ISA memory resources to sysfs\n"); + return; +} + +void pci_remove_legacy_files(struct pci_bus *b) +{ + if (b->legacy_io) { + device_remove_bin_file(&b->dev, b->legacy_io); + device_remove_bin_file(&b->dev, b->legacy_mem); + kfree(b->legacy_io); /* both are allocated here */ + } } #endif /* HAVE_PCI_LEGACY */ @@ -715,7 +798,7 @@ static struct bin_attribute pci_config_attr = { .name = "config", .mode = S_IRUGO | S_IWUSR, }, - .size = 256, + .size = PCI_CFG_SPACE_SIZE, .read = pci_read_config, .write = pci_write_config, }; @@ -725,7 +808,7 @@ static struct bin_attribute pcie_config_attr = { .name = "config", .mode = S_IRUGO | S_IWUSR, }, - .size = 4096, + .size = PCI_CFG_SPACE_EXP_SIZE, .read = pci_read_config, .write = pci_write_config, }; @@ -735,86 +818,103 @@ int __attribute__ ((weak)) pcibios_add_platform_entries(struct pci_dev *dev) return 0; } +static int pci_create_capabilities_sysfs(struct pci_dev *dev) +{ + int retval; + struct bin_attribute *attr; + + /* If the device has VPD, try to expose it in sysfs. */ + if (dev->vpd) { + attr = kzalloc(sizeof(*attr), GFP_ATOMIC); + if (!attr) + return -ENOMEM; + + attr->size = dev->vpd->len; + attr->attr.name = "vpd"; + attr->attr.mode = S_IRUSR | S_IWUSR; + attr->read = pci_read_vpd; + attr->write = pci_write_vpd; + retval = sysfs_create_bin_file(&dev->dev.kobj, attr); + if (retval) { + kfree(dev->vpd->attr); + return retval; + } + dev->vpd->attr = attr; + } + + /* Active State Power Management */ + pcie_aspm_create_sysfs_dev_files(dev); + + return 0; +} + int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) { - struct bin_attribute *attr = NULL; int retval; + int rom_size = 0; + struct bin_attribute *attr; if (!sysfs_initialized) return -EACCES; - if (pdev->cfg_size < 4096) + if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr); else retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr); if (retval) goto err; - /* If the device has VPD, try to expose it in sysfs. */ - if (pdev->vpd) { - attr = kzalloc(sizeof(*attr), GFP_ATOMIC); - if (attr) { - pdev->vpd->attr = attr; - attr->size = pdev->vpd->len; - attr->attr.name = "vpd"; - attr->attr.mode = S_IRUSR | S_IWUSR; - attr->read = pci_read_vpd; - attr->write = pci_write_vpd; - retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); - if (retval) - goto err_vpd; - } else { - retval = -ENOMEM; - goto err_config_file; - } - } - retval = pci_create_resource_files(pdev); if (retval) - goto err_vpd_file; + goto err_config_file; + + if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) + rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE); + else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) + rom_size = 0x20000; /* If the device has a ROM, try to expose it in sysfs. */ - if (pci_resource_len(pdev, PCI_ROM_RESOURCE) || - (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)) { + if (rom_size) { attr = kzalloc(sizeof(*attr), GFP_ATOMIC); - if (attr) { - pdev->rom_attr = attr; - attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE); - attr->attr.name = "rom"; - attr->attr.mode = S_IRUSR; - attr->read = pci_read_rom; - attr->write = pci_write_rom; - retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); - if (retval) - goto err_rom; - } else { + if (!attr) { retval = -ENOMEM; goto err_resource_files; } + attr->size = rom_size; + attr->attr.name = "rom"; + attr->attr.mode = S_IRUSR; + attr->read = pci_read_rom; + attr->write = pci_write_rom; + retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); + if (retval) { + kfree(attr); + goto err_resource_files; + } + pdev->rom_attr = attr; } + /* add platform-specific attributes */ - if (pcibios_add_platform_entries(pdev)) + retval = pcibios_add_platform_entries(pdev); + if (retval) goto err_rom_file; - pcie_aspm_create_sysfs_dev_files(pdev); + /* add sysfs entries for various capabilities */ + retval = pci_create_capabilities_sysfs(pdev); + if (retval) + goto err_rom_file; return 0; err_rom_file: - if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) + if (rom_size) { sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); -err_rom: - kfree(pdev->rom_attr); + kfree(pdev->rom_attr); + pdev->rom_attr = NULL; + } err_resource_files: pci_remove_resource_files(pdev); -err_vpd_file: - if (pdev->vpd) { - sysfs_remove_bin_file(&pdev->dev.kobj, pdev->vpd->attr); -err_vpd: - kfree(pdev->vpd->attr); - } err_config_file: - if (pdev->cfg_size < 4096) + if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); else sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr); @@ -822,6 +922,16 @@ err: return retval; } +static void pci_remove_capabilities_sysfs(struct pci_dev *dev) +{ + if (dev->vpd && dev->vpd->attr) { + sysfs_remove_bin_file(&dev->dev.kobj, dev->vpd->attr); + kfree(dev->vpd->attr); + } + + pcie_aspm_remove_sysfs_dev_files(dev); +} + /** * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files * @pdev: device whose entries we should free @@ -830,27 +940,28 @@ err: */ void pci_remove_sysfs_dev_files(struct pci_dev *pdev) { + int rom_size = 0; + if (!sysfs_initialized) return; - pcie_aspm_remove_sysfs_dev_files(pdev); + pci_remove_capabilities_sysfs(pdev); - if (pdev->vpd) { - sysfs_remove_bin_file(&pdev->dev.kobj, pdev->vpd->attr); - kfree(pdev->vpd->attr); - } - if (pdev->cfg_size < 4096) + if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); else sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr); pci_remove_resource_files(pdev); - if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) { - if (pdev->rom_attr) { - sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); - kfree(pdev->rom_attr); - } + if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) + rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE); + else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) + rom_size = 0x20000; + + if (rom_size && pdev->rom_attr) { + sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); + kfree(pdev->rom_attr); } } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c9884bba22d..4db261e13e6 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -213,10 +213,13 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap) int pci_find_ext_capability(struct pci_dev *dev, int cap) { u32 header; - int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */ - int pos = 0x100; + int ttl; + int pos = PCI_CFG_SPACE_SIZE; - if (dev->cfg_size <= 256) + /* minimum 8 bytes per capability */ + ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; + + if (dev->cfg_size <= PCI_CFG_SPACE_SIZE) return 0; if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) @@ -234,7 +237,7 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) return pos; pos = PCI_EXT_CAP_NEXT(header); - if (pos < 0x100) + if (pos < PCI_CFG_SPACE_SIZE) break; if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) @@ -1127,6 +1130,27 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) } /** + * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold + * @dev: PCI device to prepare + * @enable: True to enable wake-up event generation; false to disable + * + * Many drivers want the device to wake up the system from D3_hot or D3_cold + * and this function allows them to set that up cleanly - pci_enable_wake() + * should not be called twice in a row to enable wake-up due to PCI PM vs ACPI + * ordering constraints. + * + * This function only returns error code if the device is not capable of + * generating PME# from both D3_hot and D3_cold, and the platform is unable to + * enable wake-up power for it. + */ +int pci_wake_from_d3(struct pci_dev *dev, bool enable) +{ + return pci_pme_capable(dev, PCI_D3cold) ? + pci_enable_wake(dev, PCI_D3cold, enable) : + pci_enable_wake(dev, PCI_D3hot, enable); +} + +/** * pci_target_state - find an appropriate low power state for a given PCI dev * @dev: PCI device * @@ -1242,25 +1266,25 @@ void pci_pm_init(struct pci_dev *dev) dev->d1_support = false; dev->d2_support = false; if (!pci_no_d1d2(dev)) { - if (pmc & PCI_PM_CAP_D1) { - dev_printk(KERN_DEBUG, &dev->dev, "supports D1\n"); + if (pmc & PCI_PM_CAP_D1) dev->d1_support = true; - } - if (pmc & PCI_PM_CAP_D2) { - dev_printk(KERN_DEBUG, &dev->dev, "supports D2\n"); + if (pmc & PCI_PM_CAP_D2) dev->d2_support = true; - } + + if (dev->d1_support || dev->d2_support) + dev_printk(KERN_DEBUG, &dev->dev, "supports%s%s\n", + dev->d1_support ? " D1" : "", + dev->d2_support ? " D2" : ""); } pmc &= PCI_PM_CAP_PME_MASK; if (pmc) { - dev_printk(KERN_INFO, &dev->dev, - "PME# supported from%s%s%s%s%s\n", - (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", - (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", - (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", - (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "", - (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : ""); + dev_info(&dev->dev, "PME# supported from%s%s%s%s%s\n", + (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", + (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", + (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", + (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "", + (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : ""); dev->pme_support = pmc >> PCI_PM_CAP_PME_SHIFT; /* * Make device's PM flags reflect the wake-up capability, but @@ -1275,6 +1299,38 @@ void pci_pm_init(struct pci_dev *dev) } } +/** + * pci_enable_ari - enable ARI forwarding if hardware support it + * @dev: the PCI device + */ +void pci_enable_ari(struct pci_dev *dev) +{ + int pos; + u32 cap; + u16 ctrl; + + if (!dev->is_pcie) + return; + + if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && + dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) + return; + + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!pos) + return; + + pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap); + if (!(cap & PCI_EXP_DEVCAP2_ARI)) + return; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); + ctrl |= PCI_EXP_DEVCTL2_ARI; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); + + dev->ari_enabled = 1; +} + int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) { @@ -1358,11 +1414,10 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) return 0; err_out: - dev_warn(&pdev->dev, "BAR %d: can't reserve %s region [%#llx-%#llx]\n", + dev_warn(&pdev->dev, "BAR %d: can't reserve %s region %pR\n", bar, pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem", - (unsigned long long)pci_resource_start(pdev, bar), - (unsigned long long)pci_resource_end(pdev, bar)); + &pdev->resource[bar]); return -EBUSY; } @@ -1943,6 +1998,7 @@ EXPORT_SYMBOL(pci_restore_state); EXPORT_SYMBOL(pci_pme_capable); EXPORT_SYMBOL(pci_pme_active); EXPORT_SYMBOL(pci_enable_wake); +EXPORT_SYMBOL(pci_wake_from_d3); EXPORT_SYMBOL(pci_target_state); EXPORT_SYMBOL(pci_prepare_to_sleep); EXPORT_SYMBOL(pci_back_from_sleep); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d807cd786f2..b205ab866a1 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -1,3 +1,9 @@ +#ifndef DRIVERS_PCI_H +#define DRIVERS_PCI_H + +#define PCI_CFG_SPACE_SIZE 256 +#define PCI_CFG_SPACE_EXP_SIZE 4096 + /* Functions internal to the PCI core code */ extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env); @@ -76,7 +82,13 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } /* Functions for PCI Hotplug drivers to use */ extern unsigned int pci_do_scan_bus(struct pci_bus *bus); +#ifdef HAVE_PCI_LEGACY +extern void pci_create_legacy_files(struct pci_bus *bus); extern void pci_remove_legacy_files(struct pci_bus *bus); +#else +static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } +static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; } +#endif /* Lock for read/write access to pci device and bus lists */ extern struct rw_semaphore pci_bus_sem; @@ -109,6 +121,7 @@ static inline int pci_no_d1d2(struct pci_dev *dev) extern int pcie_mch_quirk; extern struct device_attribute pci_dev_attrs[]; extern struct device_attribute dev_attr_cpuaffinity; +extern struct device_attribute dev_attr_cpulistaffinity; /** * pci_match_one_device - Tell if a PCI device structure has a matching @@ -144,3 +157,16 @@ struct pci_slot_attribute { }; #define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) +extern void pci_enable_ari(struct pci_dev *dev); +/** + * pci_ari_enabled - query ARI forwarding status + * @dev: the PCI device + * + * Returns 1 if ARI forwarding is enabled, or 0 if not enabled; + */ +static inline int pci_ari_enabled(struct pci_dev *dev) +{ + return dev->ari_enabled; +} + +#endif /* DRIVERS_PCI_H */ diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 77036f46acf..e390707661d 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -105,7 +105,7 @@ static irqreturn_t aer_irq(int irq, void *context) unsigned long flags; int pos; - pos = pci_find_aer_capability(pdev->port); + pos = pci_find_ext_capability(pdev->port, PCI_EXT_CAP_ID_ERR); /* * Must lock access to Root Error Status Reg, Root Error ID Reg, * and Root error producer/consumer index @@ -252,7 +252,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) u32 status; int pos; - pos = pci_find_aer_capability(dev); + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); /* Disable Root's interrupt in response to error messages */ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, 0); @@ -316,7 +316,7 @@ static void aer_error_resume(struct pci_dev *dev) pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); /* Clean AER Root Error Status */ - pos = pci_find_aer_capability(dev); + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); if (dev->error_state == pci_channel_io_normal) diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index ee5e7b5176d..dfc63d01f20 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -28,41 +28,15 @@ static int forceload; module_param(forceload, bool, 0); -#define PCI_CFG_SPACE_SIZE (0x100) -int pci_find_aer_capability(struct pci_dev *dev) -{ - int pos; - u32 reg32 = 0; - - /* Check if it's a pci-express device */ - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); - if (!pos) - return 0; - - /* Check if it supports pci-express AER */ - pos = PCI_CFG_SPACE_SIZE; - while (pos) { - if (pci_read_config_dword(dev, pos, ®32)) - return 0; - - /* some broken boards return ~0 */ - if (reg32 == 0xffffffff) - return 0; - - if (PCI_EXT_CAP_ID(reg32) == PCI_EXT_CAP_ID_ERR) - break; - - pos = reg32 >> 20; - } - - return pos; -} - int pci_enable_pcie_error_reporting(struct pci_dev *dev) { u16 reg16 = 0; int pos; + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); + if (!pos) + return -EIO; + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); if (!pos) return -EIO; @@ -102,7 +76,7 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) int pos; u32 status, mask; - pos = pci_find_aer_capability(dev); + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos) return -EIO; @@ -123,7 +97,7 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev) int pos; u32 status; - pos = pci_find_aer_capability(dev); + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos) return -EIO; @@ -502,7 +476,7 @@ static void handle_error_source(struct pcie_device * aerdev, * Correctable error does not need software intevention. * No need to go through error recovery process. */ - pos = pci_find_aer_capability(dev); + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (pos) pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, info.status); @@ -542,7 +516,7 @@ void aer_enable_rootport(struct aer_rpc *rpc) reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK); pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16); - aer_pos = pci_find_aer_capability(pdev); + aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); /* Clear error status */ pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, ®32); pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32); @@ -579,7 +553,7 @@ static void disable_root_aer(struct aer_rpc *rpc) u32 reg32; int pos; - pos = pci_find_aer_capability(pdev); + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); /* Disable Root's interrupt in response to error messages */ pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); @@ -618,7 +592,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) { int pos; - pos = pci_find_aer_capability(dev); + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); /* The device might not support AER */ if (!pos) @@ -755,7 +729,6 @@ int aer_init(struct pcie_device *dev) return AER_SUCCESS; } -EXPORT_SYMBOL_GPL(pci_find_aer_capability); EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting); EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 851f5b83cdb..8f63f4c6b85 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -528,9 +528,9 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP, ®32); if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) { - printk("Pre-1.1 PCIe device detected, " - "disable ASPM for %s. It can be enabled forcedly" - " with 'pcie_aspm=force'\n", pci_name(pdev)); + dev_printk(KERN_INFO, &child_dev->dev, "disabling ASPM" + " on pre-1.1 PCIe device. You can enable it" + " with 'pcie_aspm=force'\n"); return -EINVAL; } } diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 3656e0349dd..2529f3f2ea5 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h @@ -25,7 +25,6 @@ #define PCIE_CAPABILITIES_REG 0x2 #define PCIE_SLOT_CAPABILITIES_REG 0x14 #define PCIE_PORT_DEVICE_MAXSERVICES 4 -#define PCI_CFG_SPACE_SIZE 256 #define get_descriptor_id(type, service) (((type - 4) << 4) | service) diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 890f0d2b370..2e091e01482 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -195,24 +195,11 @@ static int get_port_device_capability(struct pci_dev *dev) /* PME Capable - root port capability */ if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT) services |= PCIE_PORT_SERVICE_PME; - - pos = PCI_CFG_SPACE_SIZE; - while (pos) { - pci_read_config_dword(dev, pos, ®32); - switch (reg32 & 0xffff) { - case PCI_EXT_CAP_ID_ERR: - services |= PCIE_PORT_SERVICE_AER; - pos = reg32 >> 20; - break; - case PCI_EXT_CAP_ID_VC: - services |= PCIE_PORT_SERVICE_VC; - pos = reg32 >> 20; - break; - default: - pos = 0; - break; - } - } + + if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) + services |= PCIE_PORT_SERVICE_AER; + if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) + services |= PCIE_PORT_SERVICE_VC; return services; } diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 367c9c20000..584422da8d8 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -91,7 +91,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, pci_set_master(dev); if (!dev->irq && dev->pin) { - dev_warn(&dev->dev, "device [%04x/%04x] has invalid IRQ; " + dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " "check vendor BIOS\n", dev->vendor, dev->device); } if (pcie_port_device_register(dev)) { diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index dd9161a054e..aaaf0a1fed2 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -14,8 +14,6 @@ #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ #define CARDBUS_RESERVE_BUSNR 3 -#define PCI_CFG_SPACE_SIZE 256 -#define PCI_CFG_SPACE_EXP_SIZE 4096 /* Ugh. Need to stop exporting this to modules. */ LIST_HEAD(pci_root_buses); @@ -44,72 +42,6 @@ int no_pci_devices(void) } EXPORT_SYMBOL(no_pci_devices); -#ifdef HAVE_PCI_LEGACY -/** - * pci_create_legacy_files - create legacy I/O port and memory files - * @b: bus to create files under - * - * Some platforms allow access to legacy I/O port and ISA memory space on - * a per-bus basis. This routine creates the files and ties them into - * their associated read, write and mmap files from pci-sysfs.c - * - * On error unwind, but don't propogate the error to the caller - * as it is ok to set up the PCI bus without these files. - */ -static void pci_create_legacy_files(struct pci_bus *b) -{ - int error; - - b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2, - GFP_ATOMIC); - if (!b->legacy_io) - goto kzalloc_err; - - b->legacy_io->attr.name = "legacy_io"; - b->legacy_io->size = 0xffff; - b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; - b->legacy_io->read = pci_read_legacy_io; - b->legacy_io->write = pci_write_legacy_io; - error = device_create_bin_file(&b->dev, b->legacy_io); - if (error) - goto legacy_io_err; - - /* Allocated above after the legacy_io struct */ - b->legacy_mem = b->legacy_io + 1; - b->legacy_mem->attr.name = "legacy_mem"; - b->legacy_mem->size = 1024*1024; - b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; - b->legacy_mem->mmap = pci_mmap_legacy_mem; - error = device_create_bin_file(&b->dev, b->legacy_mem); - if (error) - goto legacy_mem_err; - - return; - -legacy_mem_err: - device_remove_bin_file(&b->dev, b->legacy_io); -legacy_io_err: - kfree(b->legacy_io); - b->legacy_io = NULL; -kzalloc_err: - printk(KERN_WARNING "pci: warning: could not create legacy I/O port " - "and ISA memory resources to sysfs\n"); - return; -} - -void pci_remove_legacy_files(struct pci_bus *b) -{ - if (b->legacy_io) { - device_remove_bin_file(&b->dev, b->legacy_io); - device_remove_bin_file(&b->dev, b->legacy_mem); - kfree(b->legacy_io); /* both are allocated here */ - } -} -#else /* !HAVE_PCI_LEGACY */ -static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } -void pci_remove_legacy_files(struct pci_bus *bus) { return; } -#endif /* HAVE_PCI_LEGACY */ - /* * PCI Bus Class Devices */ @@ -219,7 +151,7 @@ static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar) res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK; - if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64) + if (res->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) return pci_bar_mem64; return pci_bar_mem32; } @@ -304,9 +236,8 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, } else { res->start = l64; res->end = l64 + sz64; - printk(KERN_DEBUG "PCI: %s reg %x 64bit mmio: [%llx, %llx]\n", - pci_name(dev), pos, (unsigned long long)res->start, - (unsigned long long)res->end); + dev_printk(KERN_DEBUG, &dev->dev, + "reg %x 64bit mmio: %pR\n", pos, res); } } else { sz = pci_size(l, sz, mask); @@ -316,9 +247,10 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, res->start = l; res->end = l + sz; - printk(KERN_DEBUG "PCI: %s reg %x %s: [%llx, %llx]\n", pci_name(dev), - pos, (res->flags & IORESOURCE_IO) ? "io port":"32bit mmio", - (unsigned long long)res->start, (unsigned long long)res->end); + + dev_printk(KERN_DEBUG, &dev->dev, "reg %x %s: %pR\n", pos, + (res->flags & IORESOURCE_IO) ? "io port" : "32bit mmio", + res); } out: @@ -389,9 +321,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) res->start = base; if (!res->end) res->end = limit + 0xfff; - printk(KERN_DEBUG "PCI: bridge %s io port: [%llx, %llx]\n", - pci_name(dev), (unsigned long long) res->start, - (unsigned long long) res->end); + dev_printk(KERN_DEBUG, &dev->dev, "bridge io port: %pR\n", res); } res = child->resource[1]; @@ -403,9 +333,8 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; res->start = base; res->end = limit + 0xfffff; - printk(KERN_DEBUG "PCI: bridge %s 32bit mmio: [%llx, %llx]\n", - pci_name(dev), (unsigned long long) res->start, - (unsigned long long) res->end); + dev_printk(KERN_DEBUG, &dev->dev, "bridge 32bit mmio: %pR\n", + res); } res = child->resource[2]; @@ -441,9 +370,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH; res->start = base; res->end = limit + 0xfffff; - printk(KERN_DEBUG "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n", - pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32", - (unsigned long long) res->start, (unsigned long long) res->end); + dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n", + (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32", + res); } } @@ -764,7 +693,7 @@ static int pci_setup_device(struct pci_dev * dev) dev->class = class; class >>= 8; - dev_dbg(&dev->dev, "found [%04x/%04x] class %06x header type %02x\n", + dev_dbg(&dev->dev, "found [%04x:%04x] class %06x header type %02x\n", dev->vendor, dev->device, class, dev->hdr_type); /* "Unknown power state" */ @@ -846,6 +775,11 @@ static int pci_setup_device(struct pci_dev * dev) return 0; } +static void pci_release_capabilities(struct pci_dev *dev) +{ + pci_vpd_release(dev); +} + /** * pci_release_dev - free a pci device structure when all users of it are finished. * @dev: device that's been disconnected @@ -858,7 +792,7 @@ static void pci_release_dev(struct device *dev) struct pci_dev *pci_dev; pci_dev = to_pci_dev(dev); - pci_vpd_release(pci_dev); + pci_release_capabilities(pci_dev); kfree(pci_dev); } @@ -889,8 +823,9 @@ static void set_pcie_port_type(struct pci_dev *pdev) int pci_cfg_space_size_ext(struct pci_dev *dev) { u32 status; + int pos = PCI_CFG_SPACE_SIZE; - if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL) + if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL) goto fail; if (status == 0xffffffff) goto fail; @@ -938,8 +873,6 @@ struct pci_dev *alloc_pci_dev(void) INIT_LIST_HEAD(&dev->bus_list); - pci_msi_init_pci_dev(dev); - return dev; } EXPORT_SYMBOL(alloc_pci_dev); @@ -951,6 +884,7 @@ EXPORT_SYMBOL(alloc_pci_dev); static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) { struct pci_dev *dev; + struct pci_slot *slot; u32 l; u8 hdr_type; int delay = 1; @@ -999,6 +933,10 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) dev->error_state = pci_channel_io_normal; set_pcie_port_type(dev); + list_for_each_entry(slot, &bus->slots, list) + if (PCI_SLOT(devfn) == slot->number) + dev->slot = slot; + /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) set this higher, assuming the system even supports it. */ dev->dma_mask = 0xffffffff; @@ -1007,9 +945,22 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) return NULL; } + return dev; +} + +static void pci_init_capabilities(struct pci_dev *dev) +{ + /* MSI/MSI-X list */ + pci_msi_init_pci_dev(dev); + + /* Power Management */ + pci_pm_init(dev); + + /* Vital Product Data */ pci_vpd_pci22_init(dev); - return dev; + /* Alternative Routing-ID Forwarding */ + pci_enable_ari(dev); } void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) @@ -1028,8 +979,8 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) /* Fix up broken headers */ pci_fixup_device(pci_fixup_header, dev); - /* Initialize power management of the device */ - pci_pm_init(dev); + /* Initialize various capabilities */ + pci_init_capabilities(dev); /* * Add the device to our list of discovered devices diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e872ac925b4..bbf66ea8fd8 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -24,6 +24,14 @@ #include <linux/kallsyms.h> #include "pci.h" +int isa_dma_bridge_buggy; +EXPORT_SYMBOL(isa_dma_bridge_buggy); +int pci_pci_problems; +EXPORT_SYMBOL(pci_pci_problems); +int pcie_mch_quirk; +EXPORT_SYMBOL(pcie_mch_quirk); + +#ifdef CONFIG_PCI_QUIRKS /* The Mellanox Tavor device gives false positive parity errors * Mark this device with a broken_parity_status, to allow * PCI scanning code to "skip" this now blacklisted device. @@ -62,8 +70,6 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_p This appears to be BIOS not version dependent. So presumably there is a chipset level fix */ -int isa_dma_bridge_buggy; -EXPORT_SYMBOL(isa_dma_bridge_buggy); static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev) { @@ -84,9 +90,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_1, quirk_isa_d DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_dma_hangs); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); -int pci_pci_problems; -EXPORT_SYMBOL(pci_pci_problems); - /* * Chipsets where PCI->PCI transfers vanish or hang */ @@ -1362,9 +1365,6 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic); #endif -int pcie_mch_quirk; -EXPORT_SYMBOL(pcie_mch_quirk); - static void __devinit quirk_pcie_mch(struct pci_dev *pdev) { pcie_mch_quirk = 1; @@ -1555,84 +1555,6 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); -static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) -{ - while (f < end) { - if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) && - (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { -#ifdef DEBUG - dev_dbg(&dev->dev, "calling %pF\n", f->hook); -#endif - f->hook(dev); - } - f++; - } -} - -extern struct pci_fixup __start_pci_fixups_early[]; -extern struct pci_fixup __end_pci_fixups_early[]; -extern struct pci_fixup __start_pci_fixups_header[]; -extern struct pci_fixup __end_pci_fixups_header[]; -extern struct pci_fixup __start_pci_fixups_final[]; -extern struct pci_fixup __end_pci_fixups_final[]; -extern struct pci_fixup __start_pci_fixups_enable[]; -extern struct pci_fixup __end_pci_fixups_enable[]; -extern struct pci_fixup __start_pci_fixups_resume[]; -extern struct pci_fixup __end_pci_fixups_resume[]; -extern struct pci_fixup __start_pci_fixups_resume_early[]; -extern struct pci_fixup __end_pci_fixups_resume_early[]; -extern struct pci_fixup __start_pci_fixups_suspend[]; -extern struct pci_fixup __end_pci_fixups_suspend[]; - - -void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) -{ - struct pci_fixup *start, *end; - - switch(pass) { - case pci_fixup_early: - start = __start_pci_fixups_early; - end = __end_pci_fixups_early; - break; - - case pci_fixup_header: - start = __start_pci_fixups_header; - end = __end_pci_fixups_header; - break; - - case pci_fixup_final: - start = __start_pci_fixups_final; - end = __end_pci_fixups_final; - break; - - case pci_fixup_enable: - start = __start_pci_fixups_enable; - end = __end_pci_fixups_enable; - break; - - case pci_fixup_resume: - start = __start_pci_fixups_resume; - end = __end_pci_fixups_resume; - break; - - case pci_fixup_resume_early: - start = __start_pci_fixups_resume_early; - end = __end_pci_fixups_resume_early; - break; - - case pci_fixup_suspend: - start = __start_pci_fixups_suspend; - end = __end_pci_fixups_suspend; - break; - - default: - /* stupid compiler warning, you would think with an enum... */ - return; - } - pci_do_fixups(dev, start, end); -} -EXPORT_SYMBOL(pci_fixup_device); - /* Enable 1k I/O space granularity on the Intel P64H2 */ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) { @@ -2006,3 +1928,82 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375, quirk_msi_intx_disable_bug); #endif /* CONFIG_PCI_MSI */ + +static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) +{ + while (f < end) { + if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) && + (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { + dev_dbg(&dev->dev, "calling %pF\n", f->hook); + f->hook(dev); + } + f++; + } +} + +extern struct pci_fixup __start_pci_fixups_early[]; +extern struct pci_fixup __end_pci_fixups_early[]; +extern struct pci_fixup __start_pci_fixups_header[]; +extern struct pci_fixup __end_pci_fixups_header[]; +extern struct pci_fixup __start_pci_fixups_final[]; +extern struct pci_fixup __end_pci_fixups_final[]; +extern struct pci_fixup __start_pci_fixups_enable[]; +extern struct pci_fixup __end_pci_fixups_enable[]; +extern struct pci_fixup __start_pci_fixups_resume[]; +extern struct pci_fixup __end_pci_fixups_resume[]; +extern struct pci_fixup __start_pci_fixups_resume_early[]; +extern struct pci_fixup __end_pci_fixups_resume_early[]; +extern struct pci_fixup __start_pci_fixups_suspend[]; +extern struct pci_fixup __end_pci_fixups_suspend[]; + + +void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) +{ + struct pci_fixup *start, *end; + + switch(pass) { + case pci_fixup_early: + start = __start_pci_fixups_early; + end = __end_pci_fixups_early; + break; + + case pci_fixup_header: + start = __start_pci_fixups_header; + end = __end_pci_fixups_header; + break; + + case pci_fixup_final: + start = __start_pci_fixups_final; + end = __end_pci_fixups_final; + break; + + case pci_fixup_enable: + start = __start_pci_fixups_enable; + end = __end_pci_fixups_enable; + break; + + case pci_fixup_resume: + start = __start_pci_fixups_resume; + end = __end_pci_fixups_resume; + break; + + case pci_fixup_resume_early: + start = __start_pci_fixups_resume_early; + end = __end_pci_fixups_resume_early; + break; + + case pci_fixup_suspend: + start = __start_pci_fixups_suspend; + end = __end_pci_fixups_suspend; + break; + + default: + /* stupid compiler warning, you would think with an enum... */ + return; + } + pci_do_fixups(dev, start, end); +} +#else +void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {} +#endif +EXPORT_SYMBOL(pci_fixup_device); diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index bdc2a44d68e..042e0892442 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -73,6 +73,7 @@ void pci_remove_bus(struct pci_bus *pci_bus) up_write(&pci_bus_sem); pci_remove_legacy_files(pci_bus); device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity); + device_remove_file(&pci_bus->dev, &dev_attr_cpulistaffinity); device_unregister(&pci_bus->dev); } EXPORT_SYMBOL(pci_remove_bus); @@ -114,13 +115,9 @@ void pci_remove_behind_bridge(struct pci_dev *dev) { struct list_head *l, *n; - if (dev->subordinate) { - list_for_each_safe(l, n, &dev->subordinate->devices) { - struct pci_dev *dev = pci_dev_b(l); - - pci_remove_bus_device(dev); - } - } + if (dev->subordinate) + list_for_each_safe(l, n, &dev->subordinate->devices) + pci_remove_bus_device(pci_dev_b(l)); } static void pci_stop_bus_devices(struct pci_bus *bus) diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index bd5c0e03139..1f5f6143f35 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -21,7 +21,7 @@ * between the ROM and other resources, so enabling it may disable access * to MMIO registers or other card memory. */ -static int pci_enable_rom(struct pci_dev *pdev) +int pci_enable_rom(struct pci_dev *pdev) { struct resource *res = pdev->resource + PCI_ROM_RESOURCE; struct pci_bus_region region; @@ -45,7 +45,7 @@ static int pci_enable_rom(struct pci_dev *pdev) * Disable ROM decoding on a PCI device by turning off the last bit in the * ROM BAR. */ -static void pci_disable_rom(struct pci_dev *pdev) +void pci_disable_rom(struct pci_dev *pdev) { u32 rom_addr; pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); @@ -260,3 +260,5 @@ void pci_cleanup_rom(struct pci_dev *pdev) EXPORT_SYMBOL(pci_map_rom); EXPORT_SYMBOL(pci_unmap_rom); +EXPORT_SYMBOL_GPL(pci_enable_rom); +EXPORT_SYMBOL_GPL(pci_disable_rom); diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index d5e2106760f..ea979f2bc6d 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -299,7 +299,7 @@ static void pbus_size_io(struct pci_bus *bus) if (r->parent || !(r->flags & IORESOURCE_IO)) continue; - r_size = r->end - r->start + 1; + r_size = resource_size(r); if (r_size < 0x400) /* Might be re-aligned for ISA */ @@ -350,16 +350,13 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long if (r->parent || (r->flags & mask) != type) continue; - r_size = r->end - r->start + 1; + r_size = resource_size(r); /* For bridges size != alignment */ align = resource_alignment(r); order = __ffs(align) - 20; if (order > 11) { dev_warn(&dev->dev, "BAR %d bad alignment %llx: " - "%#016llx-%#016llx\n", i, - (unsigned long long)align, - (unsigned long long)r->start, - (unsigned long long)r->end); + "%pR\n", i, (unsigned long long)align, r); r->flags = 0; continue; } @@ -539,11 +536,9 @@ static void pci_bus_dump_res(struct pci_bus *bus) if (!res) continue; - printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n", - bus->number, i, - (res->flags & IORESOURCE_IO) ? "io port" : "mmio", - (unsigned long long) res->start, - (unsigned long long) res->end); + printk(KERN_INFO "bus: %02x index %x %s: %pR\n", + bus->number, i, + (res->flags & IORESOURCE_IO) ? "io port" : "mmio", res); } } diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 1a5fc83c71b..2dbd96cce2d 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -49,10 +49,8 @@ void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) pcibios_resource_to_bus(dev, ®ion, res); - dev_dbg(&dev->dev, "BAR %d: got res [%#llx-%#llx] bus [%#llx-%#llx] " - "flags %#lx\n", resno, - (unsigned long long)res->start, - (unsigned long long)res->end, + dev_dbg(&dev->dev, "BAR %d: got res %pR bus [%#llx-%#llx] " + "flags %#lx\n", resno, res, (unsigned long long)region.start, (unsigned long long)region.end, (unsigned long)res->flags); @@ -114,13 +112,11 @@ int pci_claim_resource(struct pci_dev *dev, int resource) err = insert_resource(root, res); if (err) { - dev_err(&dev->dev, "BAR %d: %s of %s [%#llx-%#llx]\n", + dev_err(&dev->dev, "BAR %d: %s of %s %pR\n", resource, root ? "address space collision on" : "no parent found for", - dtype, - (unsigned long long)res->start, - (unsigned long long)res->end); + dtype, res); } return err; @@ -133,15 +129,14 @@ int pci_assign_resource(struct pci_dev *dev, int resno) resource_size_t size, min, align; int ret; - size = res->end - res->start + 1; + size = resource_size(res); min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; align = resource_alignment(res); if (!align) { dev_err(&dev->dev, "BAR %d: can't allocate resource (bogus " - "alignment) [%#llx-%#llx] flags %#lx\n", - resno, (unsigned long long)res->start, - (unsigned long long)res->end, res->flags); + "alignment) %pR flags %#lx\n", + resno, res, res->flags); return -EINVAL; } @@ -162,11 +157,8 @@ int pci_assign_resource(struct pci_dev *dev, int resno) } if (ret) { - dev_err(&dev->dev, "BAR %d: can't allocate %s resource " - "[%#llx-%#llx]\n", resno, - res->flags & IORESOURCE_IO ? "I/O" : "mem", - (unsigned long long)res->start, - (unsigned long long)res->end); + dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", + resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); } else { res->flags &= ~IORESOURCE_STARTALIGN; if (resno < PCI_BRIDGE_RESOURCES) @@ -202,11 +194,8 @@ int pci_assign_resource_fixed(struct pci_dev *dev, int resno) } if (ret) { - dev_err(&dev->dev, "BAR %d: can't allocate %s resource " - "[%#llx-%#llx\n]", resno, - res->flags & IORESOURCE_IO ? "I/O" : "mem", - (unsigned long long)res->start, - (unsigned long long)res->end); + dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", + resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); } else if (resno < PCI_BRIDGE_RESOURCES) { pci_update_resource(dev, res, resno); } @@ -237,9 +226,8 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) r_align = resource_alignment(r); if (!r_align) { dev_warn(&dev->dev, "BAR %d: bogus alignment " - "[%#llx-%#llx] flags %#lx\n", - i, (unsigned long long)r->start, - (unsigned long long)r->end, r->flags); + "%pR flags %#lx\n", + i, r, r->flags); continue; } for (list = head; ; list = list->next) { @@ -287,9 +275,7 @@ int pci_enable_resources(struct pci_dev *dev, int mask) if (!r->parent) { dev_err(&dev->dev, "device not available because of " - "BAR %d [%#llx-%#llx] collisions\n", i, - (unsigned long long) r->start, - (unsigned long long) r->end); + "BAR %d %pR collisions\n", i, r); return -EINVAL; } diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 7e5b85cbd94..0c6db03698e 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -49,11 +49,16 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf) static void pci_slot_release(struct kobject *kobj) { + struct pci_dev *dev; struct pci_slot *slot = to_pci_slot(kobj); pr_debug("%s: releasing pci_slot on %x:%d\n", __func__, slot->bus->number, slot->number); + list_for_each_entry(dev, &slot->bus->devices, bus_list) + if (PCI_SLOT(dev->devfn) == slot->number) + dev->slot = NULL; + list_del(&slot->list); kfree(slot); @@ -108,6 +113,7 @@ static struct kobj_type pci_slot_ktype = { struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, const char *name) { + struct pci_dev *dev; struct pci_slot *slot; int err; @@ -150,6 +156,10 @@ placeholder: INIT_LIST_HEAD(&slot->list); list_add(&slot->list, &parent->slots); + list_for_each_entry(dev, &parent->devices, bus_list) + if (PCI_SLOT(dev->devfn) == slot_nr) + dev->slot = slot; + /* Don't care if debug printk has a -1 for slot_nr */ pr_debug("%s: created pci_slot on %04x:%02x:%02x\n", __func__, pci_domain_nr(parent), parent->number, slot_nr); |