diff options
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/Kconfig | 24 | ||||
-rw-r--r-- | drivers/pci/hotplug/Makefile | 3 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 46 | ||||
-rw-r--r-- | drivers/pci/hotplug/fakephp.c | 164 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_acpi.c | 6 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 28 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 12 | ||||
-rw-r--r-- | drivers/pci/hotplug/pcihp_slot.c | 20 |
8 files changed, 26 insertions, 277 deletions
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index 66f29bc00be4..b0e46dede1a9 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig | |||
@@ -17,28 +17,6 @@ menuconfig HOTPLUG_PCI | |||
17 | 17 | ||
18 | if HOTPLUG_PCI | 18 | if HOTPLUG_PCI |
19 | 19 | ||
20 | config HOTPLUG_PCI_FAKE | ||
21 | tristate "Fake PCI Hotplug driver" | ||
22 | help | ||
23 | Say Y here if you want to use the fake PCI hotplug driver. It can | ||
24 | be used to simulate PCI hotplug events if even if your system is | ||
25 | not PCI hotplug capable. | ||
26 | |||
27 | This driver will "emulate" removing PCI devices from the system. | ||
28 | If the "power" file is written to with "0" then the specified PCI | ||
29 | device will be completely removed from the kernel. | ||
30 | |||
31 | WARNING, this does NOT turn off the power to the PCI device. | ||
32 | This is a "logical" removal, not a physical or electrical | ||
33 | removal. | ||
34 | |||
35 | Use this module at your own risk. You have been warned! | ||
36 | |||
37 | To compile this driver as a module, choose M here: the | ||
38 | module will be called fakephp. | ||
39 | |||
40 | When in doubt, say N. | ||
41 | |||
42 | config HOTPLUG_PCI_COMPAQ | 20 | config HOTPLUG_PCI_COMPAQ |
43 | tristate "Compaq PCI Hotplug driver" | 21 | tristate "Compaq PCI Hotplug driver" |
44 | depends on X86 && PCI_BIOS | 22 | depends on X86 && PCI_BIOS |
@@ -143,7 +121,7 @@ config HOTPLUG_PCI_SHPC | |||
143 | 121 | ||
144 | config HOTPLUG_PCI_RPA | 122 | config HOTPLUG_PCI_RPA |
145 | tristate "RPA PCI Hotplug driver" | 123 | tristate "RPA PCI Hotplug driver" |
146 | depends on PPC_PSERIES && EEH && !HOTPLUG_PCI_FAKE | 124 | depends on PPC_PSERIES && EEH |
147 | help | 125 | help |
148 | Say Y here if you have a RPA system that supports PCI Hotplug. | 126 | Say Y here if you have a RPA system that supports PCI Hotplug. |
149 | 127 | ||
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 6cd9f3c9887d..c459cd4e39c2 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile | |||
@@ -23,9 +23,6 @@ obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o | |||
23 | 23 | ||
24 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o | 24 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o |
25 | 25 | ||
26 | # Link this last so it doesn't claim devices that have a real hotplug driver | ||
27 | obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o | ||
28 | |||
29 | pci_hotplug-objs := pci_hotplug_core.o pcihp_slot.o | 26 | pci_hotplug-objs := pci_hotplug_core.o pcihp_slot.o |
30 | 27 | ||
31 | ifdef CONFIG_HOTPLUG_PCI_CPCI | 28 | ifdef CONFIG_HOTPLUG_PCI_CPCI |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index ad6fd6695495..7be4ca5e1f4c 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -869,17 +869,6 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
869 | return retval; | 869 | return retval; |
870 | } | 870 | } |
871 | 871 | ||
872 | static void disable_bridges(struct pci_bus *bus) | ||
873 | { | ||
874 | struct pci_dev *dev; | ||
875 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
876 | if (dev->subordinate) { | ||
877 | disable_bridges(dev->subordinate); | ||
878 | pci_disable_device(dev); | ||
879 | } | ||
880 | } | ||
881 | } | ||
882 | |||
883 | /* return first device in slot, acquiring a reference on it */ | 872 | /* return first device in slot, acquiring a reference on it */ |
884 | static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) | 873 | static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) |
885 | { | 874 | { |
@@ -931,12 +920,7 @@ static int disable_device(struct acpiphp_slot *slot) | |||
931 | * here. | 920 | * here. |
932 | */ | 921 | */ |
933 | while ((pdev = dev_in_slot(slot))) { | 922 | while ((pdev = dev_in_slot(slot))) { |
934 | pci_stop_bus_device(pdev); | 923 | pci_stop_and_remove_bus_device(pdev); |
935 | if (pdev->subordinate) { | ||
936 | disable_bridges(pdev->subordinate); | ||
937 | pci_disable_device(pdev); | ||
938 | } | ||
939 | __pci_remove_bus_device(pdev); | ||
940 | pci_dev_put(pdev); | 924 | pci_dev_put(pdev); |
941 | } | 925 | } |
942 | 926 | ||
@@ -1477,34 +1461,6 @@ int __init acpiphp_get_num_slots(void) | |||
1477 | } | 1461 | } |
1478 | 1462 | ||
1479 | 1463 | ||
1480 | #if 0 | ||
1481 | /** | ||
1482 | * acpiphp_for_each_slot - call function for each slot | ||
1483 | * @fn: callback function | ||
1484 | * @data: context to be passed to callback function | ||
1485 | */ | ||
1486 | static int acpiphp_for_each_slot(acpiphp_callback fn, void *data) | ||
1487 | { | ||
1488 | struct list_head *node; | ||
1489 | struct acpiphp_bridge *bridge; | ||
1490 | struct acpiphp_slot *slot; | ||
1491 | int retval = 0; | ||
1492 | |||
1493 | list_for_each (node, &bridge_list) { | ||
1494 | bridge = (struct acpiphp_bridge *)node; | ||
1495 | for (slot = bridge->slots; slot; slot = slot->next) { | ||
1496 | retval = fn(slot, data); | ||
1497 | if (!retval) | ||
1498 | goto err_exit; | ||
1499 | } | ||
1500 | } | ||
1501 | |||
1502 | err_exit: | ||
1503 | return retval; | ||
1504 | } | ||
1505 | #endif | ||
1506 | |||
1507 | |||
1508 | /** | 1464 | /** |
1509 | * acpiphp_enable_slot - power on slot | 1465 | * acpiphp_enable_slot - power on slot |
1510 | * @slot: ACPI PHP slot | 1466 | * @slot: ACPI PHP slot |
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c deleted file mode 100644 index a019c9a712be..000000000000 --- a/drivers/pci/hotplug/fakephp.c +++ /dev/null | |||
@@ -1,164 +0,0 @@ | |||
1 | /* Works like the fakephp driver used to, except a little better. | ||
2 | * | ||
3 | * - It's possible to remove devices with subordinate busses. | ||
4 | * - New PCI devices that appear via any method, not just a fakephp triggered | ||
5 | * rescan, will be noticed. | ||
6 | * - Devices that are removed via any method, not just a fakephp triggered | ||
7 | * removal, will also be noticed. | ||
8 | * | ||
9 | * Uses nothing from the pci-hotplug subsystem. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/list.h> | ||
17 | #include <linux/kobject.h> | ||
18 | #include <linux/sysfs.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include "../pci.h" | ||
24 | |||
25 | struct legacy_slot { | ||
26 | struct kobject kobj; | ||
27 | struct pci_dev *dev; | ||
28 | struct list_head list; | ||
29 | }; | ||
30 | |||
31 | static LIST_HEAD(legacy_list); | ||
32 | |||
33 | static ssize_t legacy_show(struct kobject *kobj, struct attribute *attr, | ||
34 | char *buf) | ||
35 | { | ||
36 | struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj); | ||
37 | strcpy(buf, "1\n"); | ||
38 | return 2; | ||
39 | } | ||
40 | |||
41 | static void remove_callback(void *data) | ||
42 | { | ||
43 | pci_stop_and_remove_bus_device((struct pci_dev *)data); | ||
44 | } | ||
45 | |||
46 | static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr, | ||
47 | const char *buf, size_t len) | ||
48 | { | ||
49 | struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj); | ||
50 | unsigned long val; | ||
51 | |||
52 | if (strict_strtoul(buf, 0, &val) < 0) | ||
53 | return -EINVAL; | ||
54 | |||
55 | if (val) | ||
56 | pci_rescan_bus(slot->dev->bus); | ||
57 | else | ||
58 | sysfs_schedule_callback(&slot->dev->dev.kobj, remove_callback, | ||
59 | slot->dev, THIS_MODULE); | ||
60 | return len; | ||
61 | } | ||
62 | |||
63 | static struct attribute *legacy_attrs[] = { | ||
64 | &(struct attribute){ .name = "power", .mode = 0644 }, | ||
65 | NULL, | ||
66 | }; | ||
67 | |||
68 | static void legacy_release(struct kobject *kobj) | ||
69 | { | ||
70 | struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj); | ||
71 | |||
72 | pci_dev_put(slot->dev); | ||
73 | kfree(slot); | ||
74 | } | ||
75 | |||
76 | static struct kobj_type legacy_ktype = { | ||
77 | .sysfs_ops = &(const struct sysfs_ops){ | ||
78 | .store = legacy_store, .show = legacy_show | ||
79 | }, | ||
80 | .release = &legacy_release, | ||
81 | .default_attrs = legacy_attrs, | ||
82 | }; | ||
83 | |||
84 | static int legacy_add_slot(struct pci_dev *pdev) | ||
85 | { | ||
86 | struct legacy_slot *slot = kzalloc(sizeof(*slot), GFP_KERNEL); | ||
87 | |||
88 | if (!slot) | ||
89 | return -ENOMEM; | ||
90 | |||
91 | if (kobject_init_and_add(&slot->kobj, &legacy_ktype, | ||
92 | &pci_slots_kset->kobj, "%s", | ||
93 | dev_name(&pdev->dev))) { | ||
94 | dev_warn(&pdev->dev, "Failed to created legacy fake slot\n"); | ||
95 | return -EINVAL; | ||
96 | } | ||
97 | slot->dev = pci_dev_get(pdev); | ||
98 | |||
99 | list_add(&slot->list, &legacy_list); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int legacy_notify(struct notifier_block *nb, | ||
105 | unsigned long action, void *data) | ||
106 | { | ||
107 | struct pci_dev *pdev = to_pci_dev(data); | ||
108 | |||
109 | if (action == BUS_NOTIFY_ADD_DEVICE) { | ||
110 | legacy_add_slot(pdev); | ||
111 | } else if (action == BUS_NOTIFY_DEL_DEVICE) { | ||
112 | struct legacy_slot *slot; | ||
113 | |||
114 | list_for_each_entry(slot, &legacy_list, list) | ||
115 | if (slot->dev == pdev) | ||
116 | goto found; | ||
117 | |||
118 | dev_warn(&pdev->dev, "Missing legacy fake slot?"); | ||
119 | return -ENODEV; | ||
120 | found: | ||
121 | kobject_del(&slot->kobj); | ||
122 | list_del(&slot->list); | ||
123 | kobject_put(&slot->kobj); | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static struct notifier_block legacy_notifier = { | ||
130 | .notifier_call = legacy_notify | ||
131 | }; | ||
132 | |||
133 | static int __init init_legacy(void) | ||
134 | { | ||
135 | struct pci_dev *pdev = NULL; | ||
136 | |||
137 | /* Add existing devices */ | ||
138 | for_each_pci_dev(pdev) | ||
139 | legacy_add_slot(pdev); | ||
140 | |||
141 | /* Be alerted of any new ones */ | ||
142 | bus_register_notifier(&pci_bus_type, &legacy_notifier); | ||
143 | return 0; | ||
144 | } | ||
145 | module_init(init_legacy); | ||
146 | |||
147 | static void __exit remove_legacy(void) | ||
148 | { | ||
149 | struct legacy_slot *slot, *tmp; | ||
150 | |||
151 | bus_unregister_notifier(&pci_bus_type, &legacy_notifier); | ||
152 | |||
153 | list_for_each_entry_safe(slot, tmp, &legacy_list, list) { | ||
154 | list_del(&slot->list); | ||
155 | kobject_del(&slot->kobj); | ||
156 | kobject_put(&slot->kobj); | ||
157 | } | ||
158 | } | ||
159 | module_exit(remove_legacy); | ||
160 | |||
161 | |||
162 | MODULE_AUTHOR("Trent Piepho <xyzzy@speakeasy.org>"); | ||
163 | MODULE_DESCRIPTION("Legacy version of the fakephp interface"); | ||
164 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 376d70d17176..24d709b7388c 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -81,16 +81,12 @@ static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots); | |||
81 | /* Dummy driver for dumplicate name detection */ | 81 | /* Dummy driver for dumplicate name detection */ |
82 | static int __init dummy_probe(struct pcie_device *dev) | 82 | static int __init dummy_probe(struct pcie_device *dev) |
83 | { | 83 | { |
84 | int pos; | ||
85 | u32 slot_cap; | 84 | u32 slot_cap; |
86 | acpi_handle handle; | 85 | acpi_handle handle; |
87 | struct dummy_slot *slot, *tmp; | 86 | struct dummy_slot *slot, *tmp; |
88 | struct pci_dev *pdev = dev->port; | 87 | struct pci_dev *pdev = dev->port; |
89 | 88 | ||
90 | pos = pci_pcie_cap(pdev); | 89 | pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap); |
91 | if (!pos) | ||
92 | return -ENODEV; | ||
93 | pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap); | ||
94 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); | 90 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); |
95 | if (!slot) | 91 | if (!slot) |
96 | return -ENOMEM; | 92 | return -ENOMEM; |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 365c6b96c642..916bf4f53aba 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -300,24 +300,24 @@ static int pciehp_suspend (struct pcie_device *dev) | |||
300 | 300 | ||
301 | static int pciehp_resume (struct pcie_device *dev) | 301 | static int pciehp_resume (struct pcie_device *dev) |
302 | { | 302 | { |
303 | struct controller *ctrl; | ||
304 | struct slot *slot; | ||
305 | u8 status; | ||
306 | |||
303 | dev_info(&dev->device, "%s ENTRY\n", __func__); | 307 | dev_info(&dev->device, "%s ENTRY\n", __func__); |
304 | if (pciehp_force) { | 308 | ctrl = get_service_data(dev); |
305 | struct controller *ctrl = get_service_data(dev); | ||
306 | struct slot *slot; | ||
307 | u8 status; | ||
308 | 309 | ||
309 | /* reinitialize the chipset's event detection logic */ | 310 | /* reinitialize the chipset's event detection logic */ |
310 | pcie_enable_notification(ctrl); | 311 | pcie_enable_notification(ctrl); |
311 | 312 | ||
312 | slot = ctrl->slot; | 313 | slot = ctrl->slot; |
313 | 314 | ||
314 | /* Check if slot is occupied */ | 315 | /* Check if slot is occupied */ |
315 | pciehp_get_adapter_status(slot, &status); | 316 | pciehp_get_adapter_status(slot, &status); |
316 | if (status) | 317 | if (status) |
317 | pciehp_enable_slot(slot); | 318 | pciehp_enable_slot(slot); |
318 | else | 319 | else |
319 | pciehp_disable_slot(slot); | 320 | pciehp_disable_slot(slot); |
320 | } | ||
321 | return 0; | 321 | return 0; |
322 | } | 322 | } |
323 | #endif /* PM */ | 323 | #endif /* PM */ |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 302451e8289d..13b2eaf7ba43 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -44,25 +44,25 @@ | |||
44 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) | 44 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) |
45 | { | 45 | { |
46 | struct pci_dev *dev = ctrl->pcie->port; | 46 | struct pci_dev *dev = ctrl->pcie->port; |
47 | return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value); | 47 | return pcie_capability_read_word(dev, reg, value); |
48 | } | 48 | } |
49 | 49 | ||
50 | static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) | 50 | static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) |
51 | { | 51 | { |
52 | struct pci_dev *dev = ctrl->pcie->port; | 52 | struct pci_dev *dev = ctrl->pcie->port; |
53 | return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg, value); | 53 | return pcie_capability_read_dword(dev, reg, value); |
54 | } | 54 | } |
55 | 55 | ||
56 | static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) | 56 | static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) |
57 | { | 57 | { |
58 | struct pci_dev *dev = ctrl->pcie->port; | 58 | struct pci_dev *dev = ctrl->pcie->port; |
59 | return pci_write_config_word(dev, pci_pcie_cap(dev) + reg, value); | 59 | return pcie_capability_write_word(dev, reg, value); |
60 | } | 60 | } |
61 | 61 | ||
62 | static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) | 62 | static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) |
63 | { | 63 | { |
64 | struct pci_dev *dev = ctrl->pcie->port; | 64 | struct pci_dev *dev = ctrl->pcie->port; |
65 | return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg, value); | 65 | return pcie_capability_write_dword(dev, reg, value); |
66 | } | 66 | } |
67 | 67 | ||
68 | /* Power Control Command */ | 68 | /* Power Control Command */ |
@@ -855,10 +855,6 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
855 | goto abort; | 855 | goto abort; |
856 | } | 856 | } |
857 | ctrl->pcie = dev; | 857 | ctrl->pcie = dev; |
858 | if (!pci_pcie_cap(pdev)) { | ||
859 | ctrl_err(ctrl, "Cannot find PCI Express capability\n"); | ||
860 | goto abort_ctrl; | ||
861 | } | ||
862 | if (pciehp_readl(ctrl, PCI_EXP_SLTCAP, &slot_cap)) { | 858 | if (pciehp_readl(ctrl, PCI_EXP_SLTCAP, &slot_cap)) { |
863 | ctrl_err(ctrl, "Cannot read SLOTCAP register\n"); | 859 | ctrl_err(ctrl, "Cannot read SLOTCAP register\n"); |
864 | goto abort_ctrl; | 860 | goto abort_ctrl; |
diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c index 8c05a18c9770..fec2d5b75440 100644 --- a/drivers/pci/hotplug/pcihp_slot.c +++ b/drivers/pci/hotplug/pcihp_slot.c | |||
@@ -96,17 +96,11 @@ static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp) | |||
96 | static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | 96 | static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) |
97 | { | 97 | { |
98 | int pos; | 98 | int pos; |
99 | u16 reg16; | ||
100 | u32 reg32; | 99 | u32 reg32; |
101 | 100 | ||
102 | if (!hpp) | 101 | if (!hpp) |
103 | return; | 102 | return; |
104 | 103 | ||
105 | /* Find PCI Express capability */ | ||
106 | pos = pci_pcie_cap(dev); | ||
107 | if (!pos) | ||
108 | return; | ||
109 | |||
110 | if (hpp->revision > 1) { | 104 | if (hpp->revision > 1) { |
111 | dev_warn(&dev->dev, "PCIe settings rev %d not supported\n", | 105 | dev_warn(&dev->dev, "PCIe settings rev %d not supported\n", |
112 | hpp->revision); | 106 | hpp->revision); |
@@ -114,17 +108,13 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | |||
114 | } | 108 | } |
115 | 109 | ||
116 | /* Initialize Device Control Register */ | 110 | /* Initialize Device Control Register */ |
117 | pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); | 111 | pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, |
118 | reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or; | 112 | ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or); |
119 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16); | ||
120 | 113 | ||
121 | /* Initialize Link Control Register */ | 114 | /* Initialize Link Control Register */ |
122 | if (dev->subordinate) { | 115 | if (dev->subordinate) |
123 | pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, ®16); | 116 | pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL, |
124 | reg16 = (reg16 & hpp->pci_exp_lnkctl_and) | 117 | ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or); |
125 | | hpp->pci_exp_lnkctl_or; | ||
126 | pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16); | ||
127 | } | ||
128 | 118 | ||
129 | /* Find Advanced Error Reporting Enhanced Capability */ | 119 | /* Find Advanced Error Reporting Enhanced Capability */ |
130 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 120 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |