aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 21:58:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 21:58:52 -0400
commit6109e2ce2600e2db26cd0424bb9c6ed019723288 (patch)
tree54b5d347bf12e0a987edfb52f287399f748a9a38 /drivers/pci
parent0961d6581c870850342ad6ea25263763433d666f (diff)
parentac81860ea073daed50246af54db706c6e491f240 (diff)
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (36 commits) PCI: hotplug: pciehp: Removed check for hotplug of display devices PCI: read memory ranges out of Broadcom CNB20LE host bridge PCI: Allow manual resource allocation for PCI hotplug bridges x86/PCI: make ACPI MCFG reserved error messages ACPI specific PCI hotplug: Use kmemdup PM/PCI: Update PCI power management documentation PCI: output FW warning in pci_read/write_vpd PCI: fix typos pci_device_dis/enable to pci_dis/enable_device in comments PCI quirks: disable msi on AMD rs4xx internal gfx bridges PCI: Disable MSI for MCP55 on P5N32-E SLI x86/PCI: irq and pci_ids patch for additional Intel Cougar Point DeviceIDs PCI: aerdrv: trivial cleanup for aerdrv_core.c PCI: aerdrv: trivial cleanup for aerdrv.c PCI: aerdrv: introduce default_downstream_reset_link PCI: aerdrv: rework find_aer_service PCI: aerdrv: remove is_downstream PCI: aerdrv: remove magical ROOT_ERR_STATUS_MASKS PCI: aerdrv: redefine PCI_ERR_ROOT_*_SRC PCI: aerdrv: rework do_recovery PCI: aerdrv: rework get_e_source() ...
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/Kconfig2
-rw-r--r--drivers/pci/access.c41
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c3
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c17
-rw-r--r--drivers/pci/pci-sysfs.c44
-rw-r--r--drivers/pci/pci.c4
-rw-r--r--drivers/pci/pcie/aer/aer_inject.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c179
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h6
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c558
-rw-r--r--drivers/pci/quirks.c21
-rw-r--r--drivers/pci/slot.c48
12 files changed, 508 insertions, 417 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 7858a117e80b..34ef70d562b2 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -19,7 +19,7 @@ config PCI_MSI
19 by using the 'pci=nomsi' option. This disables MSI for the 19 by using the 'pci=nomsi' option. This disables MSI for the
20 entire system. 20 entire system.
21 21
22 If you don't know what to do here, say N. 22 If you don't know what to do here, say Y.
23 23
24config PCI_DEBUG 24config PCI_DEBUG
25 bool "PCI Debugging" 25 bool "PCI Debugging"
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 2f646fe1260f..531bc697d800 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -13,7 +13,7 @@
13 * configuration space. 13 * configuration space.
14 */ 14 */
15 15
16static DEFINE_SPINLOCK(pci_lock); 16static DEFINE_RAW_SPINLOCK(pci_lock);
17 17
18/* 18/*
19 * Wrappers for all PCI configuration access functions. They just check 19 * Wrappers for all PCI configuration access functions. They just check
@@ -33,10 +33,10 @@ int pci_bus_read_config_##size \
33 unsigned long flags; \ 33 unsigned long flags; \
34 u32 data = 0; \ 34 u32 data = 0; \
35 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ 35 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
36 spin_lock_irqsave(&pci_lock, flags); \ 36 raw_spin_lock_irqsave(&pci_lock, flags); \
37 res = bus->ops->read(bus, devfn, pos, len, &data); \ 37 res = bus->ops->read(bus, devfn, pos, len, &data); \
38 *value = (type)data; \ 38 *value = (type)data; \
39 spin_unlock_irqrestore(&pci_lock, flags); \ 39 raw_spin_unlock_irqrestore(&pci_lock, flags); \
40 return res; \ 40 return res; \
41} 41}
42 42
@@ -47,9 +47,9 @@ int pci_bus_write_config_##size \
47 int res; \ 47 int res; \
48 unsigned long flags; \ 48 unsigned long flags; \
49 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ 49 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
50 spin_lock_irqsave(&pci_lock, flags); \ 50 raw_spin_lock_irqsave(&pci_lock, flags); \
51 res = bus->ops->write(bus, devfn, pos, len, value); \ 51 res = bus->ops->write(bus, devfn, pos, len, value); \
52 spin_unlock_irqrestore(&pci_lock, flags); \ 52 raw_spin_unlock_irqrestore(&pci_lock, flags); \
53 return res; \ 53 return res; \
54} 54}
55 55
@@ -79,10 +79,10 @@ struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops)
79 struct pci_ops *old_ops; 79 struct pci_ops *old_ops;
80 unsigned long flags; 80 unsigned long flags;
81 81
82 spin_lock_irqsave(&pci_lock, flags); 82 raw_spin_lock_irqsave(&pci_lock, flags);
83 old_ops = bus->ops; 83 old_ops = bus->ops;
84 bus->ops = ops; 84 bus->ops = ops;
85 spin_unlock_irqrestore(&pci_lock, flags); 85 raw_spin_unlock_irqrestore(&pci_lock, flags);
86 return old_ops; 86 return old_ops;
87} 87}
88EXPORT_SYMBOL(pci_bus_set_ops); 88EXPORT_SYMBOL(pci_bus_set_ops);
@@ -136,9 +136,9 @@ static noinline void pci_wait_ucfg(struct pci_dev *dev)
136 __add_wait_queue(&pci_ucfg_wait, &wait); 136 __add_wait_queue(&pci_ucfg_wait, &wait);
137 do { 137 do {
138 set_current_state(TASK_UNINTERRUPTIBLE); 138 set_current_state(TASK_UNINTERRUPTIBLE);
139 spin_unlock_irq(&pci_lock); 139 raw_spin_unlock_irq(&pci_lock);
140 schedule(); 140 schedule();
141 spin_lock_irq(&pci_lock); 141 raw_spin_lock_irq(&pci_lock);
142 } while (dev->block_ucfg_access); 142 } while (dev->block_ucfg_access);
143 __remove_wait_queue(&pci_ucfg_wait, &wait); 143 __remove_wait_queue(&pci_ucfg_wait, &wait);
144} 144}
@@ -150,11 +150,11 @@ int pci_user_read_config_##size \
150 int ret = 0; \ 150 int ret = 0; \
151 u32 data = -1; \ 151 u32 data = -1; \
152 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ 152 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
153 spin_lock_irq(&pci_lock); \ 153 raw_spin_lock_irq(&pci_lock); \
154 if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ 154 if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \
155 ret = dev->bus->ops->read(dev->bus, dev->devfn, \ 155 ret = dev->bus->ops->read(dev->bus, dev->devfn, \
156 pos, sizeof(type), &data); \ 156 pos, sizeof(type), &data); \
157 spin_unlock_irq(&pci_lock); \ 157 raw_spin_unlock_irq(&pci_lock); \
158 *val = (type)data; \ 158 *val = (type)data; \
159 return ret; \ 159 return ret; \
160} 160}
@@ -165,11 +165,11 @@ int pci_user_write_config_##size \
165{ \ 165{ \
166 int ret = -EIO; \ 166 int ret = -EIO; \
167 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ 167 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
168 spin_lock_irq(&pci_lock); \ 168 raw_spin_lock_irq(&pci_lock); \
169 if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ 169 if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \
170 ret = dev->bus->ops->write(dev->bus, dev->devfn, \ 170 ret = dev->bus->ops->write(dev->bus, dev->devfn, \
171 pos, sizeof(type), val); \ 171 pos, sizeof(type), val); \
172 spin_unlock_irq(&pci_lock); \ 172 raw_spin_unlock_irq(&pci_lock); \
173 return ret; \ 173 return ret; \
174} 174}
175 175
@@ -220,8 +220,13 @@ static int pci_vpd_pci22_wait(struct pci_dev *dev)
220 return 0; 220 return 0;
221 } 221 }
222 222
223 if (time_after(jiffies, timeout)) 223 if (time_after(jiffies, timeout)) {
224 dev_printk(KERN_DEBUG, &dev->dev,
225 "vpd r/w failed. This is likely a firmware "
226 "bug on this device. Contact the card "
227 "vendor for a firmware update.");
224 return -ETIMEDOUT; 228 return -ETIMEDOUT;
229 }
225 if (fatal_signal_pending(current)) 230 if (fatal_signal_pending(current))
226 return -EINTR; 231 return -EINTR;
227 if (!cond_resched()) 232 if (!cond_resched())
@@ -396,10 +401,10 @@ void pci_block_user_cfg_access(struct pci_dev *dev)
396 unsigned long flags; 401 unsigned long flags;
397 int was_blocked; 402 int was_blocked;
398 403
399 spin_lock_irqsave(&pci_lock, flags); 404 raw_spin_lock_irqsave(&pci_lock, flags);
400 was_blocked = dev->block_ucfg_access; 405 was_blocked = dev->block_ucfg_access;
401 dev->block_ucfg_access = 1; 406 dev->block_ucfg_access = 1;
402 spin_unlock_irqrestore(&pci_lock, flags); 407 raw_spin_unlock_irqrestore(&pci_lock, flags);
403 408
404 /* If we BUG() inside the pci_lock, we're guaranteed to hose 409 /* If we BUG() inside the pci_lock, we're guaranteed to hose
405 * the machine */ 410 * the machine */
@@ -417,7 +422,7 @@ void pci_unblock_user_cfg_access(struct pci_dev *dev)
417{ 422{
418 unsigned long flags; 423 unsigned long flags;
419 424
420 spin_lock_irqsave(&pci_lock, flags); 425 raw_spin_lock_irqsave(&pci_lock, flags);
421 426
422 /* This indicates a problem in the caller, but we don't need 427 /* This indicates a problem in the caller, but we don't need
423 * to kill them, unlike a double-block above. */ 428 * to kill them, unlike a double-block above. */
@@ -425,6 +430,6 @@ void pci_unblock_user_cfg_access(struct pci_dev *dev)
425 430
426 dev->block_ucfg_access = 0; 431 dev->block_ucfg_access = 0;
427 wake_up_all(&pci_ucfg_wait); 432 wake_up_all(&pci_ucfg_wait);
428 spin_unlock_irqrestore(&pci_lock, flags); 433 raw_spin_unlock_irqrestore(&pci_lock, flags);
429} 434}
430EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access); 435EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access);
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index 6644337d63d6..b3e5580c837b 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -1075,13 +1075,12 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1075 1075
1076 /* make our own copy of the pci bus structure, 1076 /* make our own copy of the pci bus structure,
1077 * as we like tweaking it a lot */ 1077 * as we like tweaking it a lot */
1078 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); 1078 ctrl->pci_bus = kmemdup(pdev->bus, sizeof(*ctrl->pci_bus), GFP_KERNEL);
1079 if (!ctrl->pci_bus) { 1079 if (!ctrl->pci_bus) {
1080 err("out of memory\n"); 1080 err("out of memory\n");
1081 rc = -ENOMEM; 1081 rc = -ENOMEM;
1082 goto err_free_ctrl; 1082 goto err_free_ctrl;
1083 } 1083 }
1084 memcpy(ctrl->pci_bus, pdev->bus, sizeof(*ctrl->pci_bus));
1085 1084
1086 ctrl->bus = pdev->bus->number; 1085 ctrl->bus = pdev->bus->number;
1087 ctrl->rev = pdev->revision; 1086 ctrl->rev = pdev->revision;
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 0a16444c14c9..2fce726758d2 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -84,12 +84,6 @@ int pciehp_configure_device(struct slot *p_slot)
84 dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); 84 dev = pci_get_slot(parent, PCI_DEVFN(0, fn));
85 if (!dev) 85 if (!dev)
86 continue; 86 continue;
87 if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
88 ctrl_err(ctrl, "Cannot hot-add display device %s\n",
89 pci_name(dev));
90 pci_dev_put(dev);
91 continue;
92 }
93 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || 87 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
94 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { 88 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
95 pciehp_add_bridge(dev); 89 pciehp_add_bridge(dev);
@@ -133,15 +127,9 @@ int pciehp_unconfigure_device(struct slot *p_slot)
133 presence = 0; 127 presence = 0;
134 128
135 for (j = 0; j < 8; j++) { 129 for (j = 0; j < 8; j++) {
136 struct pci_dev* temp = pci_get_slot(parent, PCI_DEVFN(0, j)); 130 struct pci_dev *temp = pci_get_slot(parent, PCI_DEVFN(0, j));
137 if (!temp) 131 if (!temp)
138 continue; 132 continue;
139 if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
140 ctrl_err(ctrl, "Cannot remove display device %s\n",
141 pci_name(temp));
142 pci_dev_put(temp);
143 continue;
144 }
145 if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { 133 if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
146 pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); 134 pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
147 if (bctl & PCI_BRIDGE_CTL_VGA) { 135 if (bctl & PCI_BRIDGE_CTL_VGA) {
@@ -149,7 +137,8 @@ int pciehp_unconfigure_device(struct slot *p_slot)
149 "Cannot remove display device %s\n", 137 "Cannot remove display device %s\n",
150 pci_name(temp)); 138 pci_name(temp));
151 pci_dev_put(temp); 139 pci_dev_put(temp);
152 continue; 140 rc = EINVAL;
141 break;
153 } 142 }
154 } 143 }
155 pci_remove_bus_device(temp); 144 pci_remove_bus_device(temp);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 6309c5a2528f..afd2fbf7d797 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -979,7 +979,12 @@ static ssize_t reset_store(struct device *dev,
979 979
980 if (val != 1) 980 if (val != 1)
981 return -EINVAL; 981 return -EINVAL;
982 return pci_reset_function(pdev); 982
983 result = pci_reset_function(pdev);
984 if (result < 0)
985 return result;
986
987 return count;
983} 988}
984 989
985static struct device_attribute reset_attr = __ATTR(reset, 0200, NULL, reset_store); 990static struct device_attribute reset_attr = __ATTR(reset, 0200, NULL, reset_store);
@@ -1030,6 +1035,39 @@ error:
1030 return retval; 1035 return retval;
1031} 1036}
1032 1037
1038static void pci_remove_slot_links(struct pci_dev *dev)
1039{
1040 char func[10];
1041 struct pci_slot *slot;
1042
1043 sysfs_remove_link(&dev->dev.kobj, "slot");
1044 list_for_each_entry(slot, &dev->bus->slots, list) {
1045 if (slot->number != PCI_SLOT(dev->devfn))
1046 continue;
1047 snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn));
1048 sysfs_remove_link(&slot->kobj, func);
1049 }
1050}
1051
1052static int pci_create_slot_links(struct pci_dev *dev)
1053{
1054 int result = 0;
1055 char func[10];
1056 struct pci_slot *slot;
1057
1058 list_for_each_entry(slot, &dev->bus->slots, list) {
1059 if (slot->number != PCI_SLOT(dev->devfn))
1060 continue;
1061 result = sysfs_create_link(&dev->dev.kobj, &slot->kobj, "slot");
1062 if (result)
1063 goto out;
1064 snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn));
1065 result = sysfs_create_link(&slot->kobj, &dev->dev.kobj, func);
1066 }
1067out:
1068 return result;
1069}
1070
1033int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) 1071int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
1034{ 1072{
1035 int retval; 1073 int retval;
@@ -1092,6 +1130,8 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
1092 if (retval) 1130 if (retval)
1093 goto err_vga_file; 1131 goto err_vga_file;
1094 1132
1133 pci_create_slot_links(pdev);
1134
1095 return 0; 1135 return 0;
1096 1136
1097err_vga_file: 1137err_vga_file:
@@ -1141,6 +1181,8 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
1141 if (!sysfs_initialized) 1181 if (!sysfs_initialized)
1142 return; 1182 return;
1143 1183
1184 pci_remove_slot_links(pdev);
1185
1144 pci_remove_capabilities_sysfs(pdev); 1186 pci_remove_capabilities_sysfs(pdev);
1145 1187
1146 if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) 1188 if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 1df7c508814e..60f30e7f1c8c 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1193,7 +1193,7 @@ void pci_disable_enabled_device(struct pci_dev *dev)
1193 * anymore. This only involves disabling PCI bus-mastering, if active. 1193 * anymore. This only involves disabling PCI bus-mastering, if active.
1194 * 1194 *
1195 * Note we don't actually disable the device until all callers of 1195 * Note we don't actually disable the device until all callers of
1196 * pci_device_enable() have called pci_device_disable(). 1196 * pci_enable_device() have called pci_disable_device().
1197 */ 1197 */
1198void 1198void
1199pci_disable_device(struct pci_dev *dev) 1199pci_disable_device(struct pci_dev *dev)
@@ -1631,7 +1631,6 @@ void pci_pm_init(struct pci_dev *dev)
1631 * let the user space enable it to wake up the system as needed. 1631 * let the user space enable it to wake up the system as needed.
1632 */ 1632 */
1633 device_set_wakeup_capable(&dev->dev, true); 1633 device_set_wakeup_capable(&dev->dev, true);
1634 device_set_wakeup_enable(&dev->dev, false);
1635 /* Disable the PME# generation functionality */ 1634 /* Disable the PME# generation functionality */
1636 pci_pme_active(dev, false); 1635 pci_pme_active(dev, false);
1637 } else { 1636 } else {
@@ -1655,7 +1654,6 @@ void platform_pci_wakeup_init(struct pci_dev *dev)
1655 return; 1654 return;
1656 1655
1657 device_set_wakeup_capable(&dev->dev, true); 1656 device_set_wakeup_capable(&dev->dev, true);
1658 device_set_wakeup_enable(&dev->dev, false);
1659 platform_pci_sleep_wake(dev, false); 1657 platform_pci_sleep_wake(dev, false);
1660} 1658}
1661 1659
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index f8f425b8731d..909924692b8a 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -168,7 +168,7 @@ static u32 *find_pci_config_dword(struct aer_error *err, int where,
168 target = &err->root_status; 168 target = &err->root_status;
169 rw1cs = 1; 169 rw1cs = 1;
170 break; 170 break;
171 case PCI_ERR_ROOT_COR_SRC: 171 case PCI_ERR_ROOT_ERR_SRC:
172 target = &err->source_id; 172 target = &err->source_id;
173 break; 173 break;
174 } 174 }
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 7a711ee314b7..484cc55194b8 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -72,13 +72,120 @@ void pci_no_aer(void)
72 pcie_aer_disable = 1; /* has priority over 'forceload' */ 72 pcie_aer_disable = 1; /* has priority over 'forceload' */
73} 73}
74 74
75static int set_device_error_reporting(struct pci_dev *dev, void *data)
76{
77 bool enable = *((bool *)data);
78
79 if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) ||
80 (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) ||
81 (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) {
82 if (enable)
83 pci_enable_pcie_error_reporting(dev);
84 else
85 pci_disable_pcie_error_reporting(dev);
86 }
87
88 if (enable)
89 pcie_set_ecrc_checking(dev);
90
91 return 0;
92}
93
94/**
95 * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports.
96 * @dev: pointer to root port's pci_dev data structure
97 * @enable: true = enable error reporting, false = disable error reporting.
98 */
99static void set_downstream_devices_error_reporting(struct pci_dev *dev,
100 bool enable)
101{
102 set_device_error_reporting(dev, &enable);
103
104 if (!dev->subordinate)
105 return;
106 pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable);
107}
108
109/**
110 * aer_enable_rootport - enable Root Port's interrupts when receiving messages
111 * @rpc: pointer to a Root Port data structure
112 *
113 * Invoked when PCIe bus loads AER service driver.
114 */
115static void aer_enable_rootport(struct aer_rpc *rpc)
116{
117 struct pci_dev *pdev = rpc->rpd->port;
118 int pos, aer_pos;
119 u16 reg16;
120 u32 reg32;
121
122 pos = pci_pcie_cap(pdev);
123 /* Clear PCIe Capability's Device Status */
124 pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, &reg16);
125 pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16);
126
127 /* Disable system error generation in response to error messages */
128 pci_read_config_word(pdev, pos + PCI_EXP_RTCTL, &reg16);
129 reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK);
130 pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16);
131
132 aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
133 /* Clear error status */
134 pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32);
135 pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32);
136 pci_read_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, &reg32);
137 pci_write_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, reg32);
138 pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, &reg32);
139 pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32);
140
141 /*
142 * Enable error reporting for the root port device and downstream port
143 * devices.
144 */
145 set_downstream_devices_error_reporting(pdev, true);
146
147 /* Enable Root Port's interrupt in response to error messages */
148 pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, &reg32);
149 reg32 |= ROOT_PORT_INTR_ON_MESG_MASK;
150 pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, reg32);
151}
152
153/**
154 * aer_disable_rootport - disable Root Port's interrupts when receiving messages
155 * @rpc: pointer to a Root Port data structure
156 *
157 * Invoked when PCIe bus unloads AER service driver.
158 */
159static void aer_disable_rootport(struct aer_rpc *rpc)
160{
161 struct pci_dev *pdev = rpc->rpd->port;
162 u32 reg32;
163 int pos;
164
165 /*
166 * Disable error reporting for the root port device and downstream port
167 * devices.
168 */
169 set_downstream_devices_error_reporting(pdev, false);
170
171 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
172 /* Disable Root's interrupt in response to error messages */
173 pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
174 reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
175 pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, reg32);
176
177 /* Clear Root's error status reg */
178 pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, &reg32);
179 pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, reg32);
180}
181
75/** 182/**
76 * aer_irq - Root Port's ISR 183 * aer_irq - Root Port's ISR
77 * @irq: IRQ assigned to Root Port 184 * @irq: IRQ assigned to Root Port
78 * @context: pointer to Root Port data structure 185 * @context: pointer to Root Port data structure
79 * 186 *
80 * Invoked when Root Port detects AER messages. 187 * Invoked when Root Port detects AER messages.
81 **/ 188 */
82irqreturn_t aer_irq(int irq, void *context) 189irqreturn_t aer_irq(int irq, void *context)
83{ 190{
84 unsigned int status, id; 191 unsigned int status, id;
@@ -97,13 +204,13 @@ irqreturn_t aer_irq(int irq, void *context)
97 204
98 /* Read error status */ 205 /* Read error status */
99 pci_read_config_dword(pdev->port, pos + PCI_ERR_ROOT_STATUS, &status); 206 pci_read_config_dword(pdev->port, pos + PCI_ERR_ROOT_STATUS, &status);
100 if (!(status & ROOT_ERR_STATUS_MASKS)) { 207 if (!(status & (PCI_ERR_ROOT_UNCOR_RCV|PCI_ERR_ROOT_COR_RCV))) {
101 spin_unlock_irqrestore(&rpc->e_lock, flags); 208 spin_unlock_irqrestore(&rpc->e_lock, flags);
102 return IRQ_NONE; 209 return IRQ_NONE;
103 } 210 }
104 211
105 /* Read error source and clear error status */ 212 /* Read error source and clear error status */
106 pci_read_config_dword(pdev->port, pos + PCI_ERR_ROOT_COR_SRC, &id); 213 pci_read_config_dword(pdev->port, pos + PCI_ERR_ROOT_ERR_SRC, &id);
107 pci_write_config_dword(pdev->port, pos + PCI_ERR_ROOT_STATUS, status); 214 pci_write_config_dword(pdev->port, pos + PCI_ERR_ROOT_STATUS, status);
108 215
109 /* Store error source for later DPC handler */ 216 /* Store error source for later DPC handler */
@@ -135,7 +242,7 @@ EXPORT_SYMBOL_GPL(aer_irq);
135 * @dev: pointer to the pcie_dev data structure 242 * @dev: pointer to the pcie_dev data structure
136 * 243 *
137 * Invoked when Root Port's AER service is loaded. 244 * Invoked when Root Port's AER service is loaded.
138 **/ 245 */
139static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev) 246static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev)
140{ 247{
141 struct aer_rpc *rpc; 248 struct aer_rpc *rpc;
@@ -144,15 +251,11 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev)
144 if (!rpc) 251 if (!rpc)
145 return NULL; 252 return NULL;
146 253
147 /* 254 /* Initialize Root lock access, e_lock, to Root Error Status Reg */
148 * Initialize Root lock access, e_lock, to Root Error Status Reg,
149 * Root Error ID Reg, and Root error producer/consumer index.
150 */
151 spin_lock_init(&rpc->e_lock); 255 spin_lock_init(&rpc->e_lock);
152 256
153 rpc->rpd = dev; 257 rpc->rpd = dev;
154 INIT_WORK(&rpc->dpc_handler, aer_isr); 258 INIT_WORK(&rpc->dpc_handler, aer_isr);
155 rpc->prod_idx = rpc->cons_idx = 0;
156 mutex_init(&rpc->rpc_mutex); 259 mutex_init(&rpc->rpc_mutex);
157 init_waitqueue_head(&rpc->wait_release); 260 init_waitqueue_head(&rpc->wait_release);
158 261
@@ -167,7 +270,7 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev)
167 * @dev: pointer to the pcie_dev data structure 270 * @dev: pointer to the pcie_dev data structure
168 * 271 *
169 * Invoked when PCI Express bus unloads or AER probe fails. 272 * Invoked when PCI Express bus unloads or AER probe fails.
170 **/ 273 */
171static void aer_remove(struct pcie_device *dev) 274static void aer_remove(struct pcie_device *dev)
172{ 275{
173 struct aer_rpc *rpc = get_service_data(dev); 276 struct aer_rpc *rpc = get_service_data(dev);
@@ -179,7 +282,8 @@ static void aer_remove(struct pcie_device *dev)
179 282
180 wait_event(rpc->wait_release, rpc->prod_idx == rpc->cons_idx); 283 wait_event(rpc->wait_release, rpc->prod_idx == rpc->cons_idx);
181 284
182 aer_delete_rootport(rpc); 285 aer_disable_rootport(rpc);
286 kfree(rpc);
183 set_service_data(dev, NULL); 287 set_service_data(dev, NULL);
184 } 288 }
185} 289}
@@ -190,7 +294,7 @@ static void aer_remove(struct pcie_device *dev)
190 * @id: pointer to the service id data structure 294 * @id: pointer to the service id data structure
191 * 295 *
192 * Invoked when PCI Express bus loads AER service driver. 296 * Invoked when PCI Express bus loads AER service driver.
193 **/ 297 */
194static int __devinit aer_probe(struct pcie_device *dev) 298static int __devinit aer_probe(struct pcie_device *dev)
195{ 299{
196 int status; 300 int status;
@@ -230,47 +334,30 @@ static int __devinit aer_probe(struct pcie_device *dev)
230 * @dev: pointer to Root Port's pci_dev data structure 334 * @dev: pointer to Root Port's pci_dev data structure
231 * 335 *
232 * Invoked by Port Bus driver when performing link reset at Root Port. 336 * Invoked by Port Bus driver when performing link reset at Root Port.
233 **/ 337 */
234static pci_ers_result_t aer_root_reset(struct pci_dev *dev) 338static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
235{ 339{
236 u16 p2p_ctrl; 340 u32 reg32;
237 u32 status;
238 int pos; 341 int pos;
239 342
240 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 343 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
241 344
242 /* Disable Root's interrupt in response to error messages */ 345 /* Disable Root's interrupt in response to error messages */
243 pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, 0); 346 pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
244 347 reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK;
245 /* Assert Secondary Bus Reset */ 348 pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32);
246 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl);
247 p2p_ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
248 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
249
250 /*
251 * we should send hot reset message for 2ms to allow it time to
252 * propogate to all downstream ports
253 */
254 msleep(2);
255
256 /* De-assert Secondary Bus Reset */
257 p2p_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
258 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
259 349
260 /* 350 aer_do_secondary_bus_reset(dev);
261 * System software must wait for at least 100ms from the end
262 * of a reset of one or more device before it is permitted
263 * to issue Configuration Requests to those devices.
264 */
265 msleep(200);
266 dev_printk(KERN_DEBUG, &dev->dev, "Root Port link has been reset\n"); 351 dev_printk(KERN_DEBUG, &dev->dev, "Root Port link has been reset\n");
267 352
353 /* Clear Root Error Status */
354 pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &reg32);
355 pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, reg32);
356
268 /* Enable Root Port's interrupt in response to error messages */ 357 /* Enable Root Port's interrupt in response to error messages */
269 pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &status); 358 pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, &reg32);
270 pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, status); 359 reg32 |= ROOT_PORT_INTR_ON_MESG_MASK;
271 pci_write_config_dword(dev, 360 pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32);
272 pos + PCI_ERR_ROOT_COMMAND,
273 ROOT_PORT_INTR_ON_MESG_MASK);
274 361
275 return PCI_ERS_RESULT_RECOVERED; 362 return PCI_ERS_RESULT_RECOVERED;
276} 363}
@@ -281,7 +368,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
281 * @error: error severity being notified by port bus 368 * @error: error severity being notified by port bus
282 * 369 *
283 * Invoked by Port Bus driver during error recovery. 370 * Invoked by Port Bus driver during error recovery.
284 **/ 371 */
285static pci_ers_result_t aer_error_detected(struct pci_dev *dev, 372static pci_ers_result_t aer_error_detected(struct pci_dev *dev,
286 enum pci_channel_state error) 373 enum pci_channel_state error)
287{ 374{
@@ -294,7 +381,7 @@ static pci_ers_result_t aer_error_detected(struct pci_dev *dev,
294 * @dev: pointer to Root Port's pci_dev data structure 381 * @dev: pointer to Root Port's pci_dev data structure
295 * 382 *
296 * Invoked by Port Bus driver during nonfatal recovery. 383 * Invoked by Port Bus driver during nonfatal recovery.
297 **/ 384 */
298static void aer_error_resume(struct pci_dev *dev) 385static void aer_error_resume(struct pci_dev *dev)
299{ 386{
300 int pos; 387 int pos;
@@ -321,7 +408,7 @@ static void aer_error_resume(struct pci_dev *dev)
321 * aer_service_init - register AER root service driver 408 * aer_service_init - register AER root service driver
322 * 409 *
323 * Invoked when AER root service driver is loaded. 410 * Invoked when AER root service driver is loaded.
324 **/ 411 */
325static int __init aer_service_init(void) 412static int __init aer_service_init(void)
326{ 413{
327 if (pcie_aer_disable) 414 if (pcie_aer_disable)
@@ -335,7 +422,7 @@ static int __init aer_service_init(void)
335 * aer_service_exit - unregister AER root service driver 422 * aer_service_exit - unregister AER root service driver
336 * 423 *
337 * Invoked when AER root service driver is unloaded. 424 * Invoked when AER root service driver is unloaded.
338 **/ 425 */
339static void __exit aer_service_exit(void) 426static void __exit aer_service_exit(void)
340{ 427{
341 pcie_port_service_unregister(&aerdriver); 428 pcie_port_service_unregister(&aerdriver);
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index bd833ea3ba49..7aaae2d2bd67 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -17,9 +17,6 @@
17#define AER_FATAL 1 17#define AER_FATAL 1
18#define AER_CORRECTABLE 2 18#define AER_CORRECTABLE 2
19 19
20/* Root Error Status Register Bits */
21#define ROOT_ERR_STATUS_MASKS 0x0f
22
23#define SYSTEM_ERROR_INTR_ON_MESG_MASK (PCI_EXP_RTCTL_SECEE| \ 20#define SYSTEM_ERROR_INTR_ON_MESG_MASK (PCI_EXP_RTCTL_SECEE| \
24 PCI_EXP_RTCTL_SENFEE| \ 21 PCI_EXP_RTCTL_SENFEE| \
25 PCI_EXP_RTCTL_SEFEE) 22 PCI_EXP_RTCTL_SEFEE)
@@ -117,8 +114,7 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
117} 114}
118 115
119extern struct bus_type pcie_port_bus_type; 116extern struct bus_type pcie_port_bus_type;
120extern void aer_enable_rootport(struct aer_rpc *rpc); 117extern void aer_do_secondary_bus_reset(struct pci_dev *dev);
121extern void aer_delete_rootport(struct aer_rpc *rpc);
122extern int aer_init(struct pcie_device *dev); 118extern int aer_init(struct pcie_device *dev);
123extern void aer_isr(struct work_struct *work); 119extern void aer_isr(struct work_struct *work);
124extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); 120extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index aceb04b67b60..df2d686fe3dd 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -47,13 +47,12 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev)
47 if (!pos) 47 if (!pos)
48 return -EIO; 48 return -EIO;
49 49
50 pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, &reg16); 50 pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
51 reg16 = reg16 | 51 reg16 |= (PCI_EXP_DEVCTL_CERE |
52 PCI_EXP_DEVCTL_CERE |
53 PCI_EXP_DEVCTL_NFERE | 52 PCI_EXP_DEVCTL_NFERE |
54 PCI_EXP_DEVCTL_FERE | 53 PCI_EXP_DEVCTL_FERE |
55 PCI_EXP_DEVCTL_URRE; 54 PCI_EXP_DEVCTL_URRE);
56 pci_write_config_word(dev, pos+PCI_EXP_DEVCTL, reg16); 55 pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
57 56
58 return 0; 57 return 0;
59} 58}
@@ -71,12 +70,12 @@ int pci_disable_pcie_error_reporting(struct pci_dev *dev)
71 if (!pos) 70 if (!pos)
72 return -EIO; 71 return -EIO;
73 72
74 pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, &reg16); 73 pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
75 reg16 = reg16 & ~(PCI_EXP_DEVCTL_CERE | 74 reg16 &= ~(PCI_EXP_DEVCTL_CERE |
76 PCI_EXP_DEVCTL_NFERE | 75 PCI_EXP_DEVCTL_NFERE |
77 PCI_EXP_DEVCTL_FERE | 76 PCI_EXP_DEVCTL_FERE |
78 PCI_EXP_DEVCTL_URRE); 77 PCI_EXP_DEVCTL_URRE);
79 pci_write_config_word(dev, pos+PCI_EXP_DEVCTL, reg16); 78 pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
80 79
81 return 0; 80 return 0;
82} 81}
@@ -99,99 +98,46 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
99} 98}
100EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); 99EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);
101 100
102static int set_device_error_reporting(struct pci_dev *dev, void *data)
103{
104 bool enable = *((bool *)data);
105
106 if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) ||
107 (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) ||
108 (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) {
109 if (enable)
110 pci_enable_pcie_error_reporting(dev);
111 else
112 pci_disable_pcie_error_reporting(dev);
113 }
114
115 if (enable)
116 pcie_set_ecrc_checking(dev);
117
118 return 0;
119}
120
121/** 101/**
122 * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports. 102 * add_error_device - list device to be handled
123 * @dev: pointer to root port's pci_dev data structure 103 * @e_info: pointer to error info
124 * @enable: true = enable error reporting, false = disable error reporting. 104 * @dev: pointer to pci_dev to be added
125 */ 105 */
126static void set_downstream_devices_error_reporting(struct pci_dev *dev,
127 bool enable)
128{
129 set_device_error_reporting(dev, &enable);
130
131 if (!dev->subordinate)
132 return;
133 pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable);
134}
135
136static inline int compare_device_id(struct pci_dev *dev,
137 struct aer_err_info *e_info)
138{
139 if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) {
140 /*
141 * Device ID match
142 */
143 return 1;
144 }
145
146 return 0;
147}
148
149static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev) 106static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev)
150{ 107{
151 if (e_info->error_dev_num < AER_MAX_MULTI_ERR_DEVICES) { 108 if (e_info->error_dev_num < AER_MAX_MULTI_ERR_DEVICES) {
152 e_info->dev[e_info->error_dev_num] = dev; 109 e_info->dev[e_info->error_dev_num] = dev;
153 e_info->error_dev_num++; 110 e_info->error_dev_num++;
154 return 1; 111 return 0;
155 } 112 }
156 113 return -ENOSPC;
157 return 0;
158} 114}
159 115
160
161#define PCI_BUS(x) (((x) >> 8) & 0xff) 116#define PCI_BUS(x) (((x) >> 8) & 0xff)
162 117
163static int find_device_iter(struct pci_dev *dev, void *data) 118/**
119 * is_error_source - check whether the device is source of reported error
120 * @dev: pointer to pci_dev to be checked
121 * @e_info: pointer to reported error info
122 */
123static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)
164{ 124{
165 int pos; 125 int pos;
166 u32 status; 126 u32 status, mask;
167 u32 mask;
168 u16 reg16; 127 u16 reg16;
169 int result;
170 struct aer_err_info *e_info = (struct aer_err_info *)data;
171 128
172 /* 129 /*
173 * When bus id is equal to 0, it might be a bad id 130 * When bus id is equal to 0, it might be a bad id
174 * reported by root port. 131 * reported by root port.
175 */ 132 */
176 if (!nosourceid && (PCI_BUS(e_info->id) != 0)) { 133 if (!nosourceid && (PCI_BUS(e_info->id) != 0)) {
177 result = compare_device_id(dev, e_info); 134 /* Device ID match? */
178 if (result) 135 if (e_info->id == ((dev->bus->number << 8) | dev->devfn))
179 add_error_device(e_info, dev); 136 return true;
180 137
181 /* 138 /* Continue id comparing if there is no multiple error */
182 * If there is no multiple error, we stop
183 * or continue based on the id comparing.
184 */
185 if (!e_info->multi_error_valid) 139 if (!e_info->multi_error_valid)
186 return result; 140 return false;
187
188 /*
189 * If there are multiple errors and id does match,
190 * We need continue to search other devices under
191 * the root port. Return 0 means that.
192 */
193 if (result)
194 return 0;
195 } 141 }
196 142
197 /* 143 /*
@@ -200,71 +146,94 @@ static int find_device_iter(struct pci_dev *dev, void *data)
200 * 2) bus id is equal to 0. Some ports might lose the bus 146 * 2) bus id is equal to 0. Some ports might lose the bus
201 * id of error source id; 147 * id of error source id;
202 * 3) There are multiple errors and prior id comparing fails; 148 * 3) There are multiple errors and prior id comparing fails;
203 * We check AER status registers to find the initial reporter. 149 * We check AER status registers to find possible reporter.
204 */ 150 */
205 if (atomic_read(&dev->enable_cnt) == 0) 151 if (atomic_read(&dev->enable_cnt) == 0)
206 return 0; 152 return false;
207 pos = pci_pcie_cap(dev); 153 pos = pci_pcie_cap(dev);
208 if (!pos) 154 if (!pos)
209 return 0; 155 return false;
156
210 /* Check if AER is enabled */ 157 /* Check if AER is enabled */
211 pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, &reg16); 158 pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
212 if (!(reg16 & ( 159 if (!(reg16 & (
213 PCI_EXP_DEVCTL_CERE | 160 PCI_EXP_DEVCTL_CERE |
214 PCI_EXP_DEVCTL_NFERE | 161 PCI_EXP_DEVCTL_NFERE |
215 PCI_EXP_DEVCTL_FERE | 162 PCI_EXP_DEVCTL_FERE |
216 PCI_EXP_DEVCTL_URRE))) 163 PCI_EXP_DEVCTL_URRE)))
217 return 0; 164 return false;
218 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 165 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
219 if (!pos) 166 if (!pos)
220 return 0; 167 return false;
221 168
222 status = 0; 169 /* Check if error is recorded */
223 mask = 0;
224 if (e_info->severity == AER_CORRECTABLE) { 170 if (e_info->severity == AER_CORRECTABLE) {
225 pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status); 171 pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status);
226 pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &mask); 172 pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &mask);
227 if (status & ~mask) {
228 add_error_device(e_info, dev);
229 goto added;
230 }
231 } else { 173 } else {
232 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); 174 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
233 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &mask); 175 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &mask);
234 if (status & ~mask) {
235 add_error_device(e_info, dev);
236 goto added;
237 }
238 } 176 }
177 if (status & ~mask)
178 return true;
239 179
240 return 0; 180 return false;
181}
241 182
242added: 183static int find_device_iter(struct pci_dev *dev, void *data)
243 if (e_info->multi_error_valid) 184{
244 return 0; 185 struct aer_err_info *e_info = (struct aer_err_info *)data;
245 else 186
246 return 1; 187 if (is_error_source(dev, e_info)) {
188 /* List this device */
189 if (add_error_device(e_info, dev)) {
190 /* We cannot handle more... Stop iteration */
191 /* TODO: Should print error message here? */
192 return 1;
193 }
194
195 /* If there is only a single error, stop iteration */
196 if (!e_info->multi_error_valid)
197 return 1;
198 }
199 return 0;
247} 200}
248 201
249/** 202/**
250 * find_source_device - search through device hierarchy for source device 203 * find_source_device - search through device hierarchy for source device
251 * @parent: pointer to Root Port pci_dev data structure 204 * @parent: pointer to Root Port pci_dev data structure
252 * @err_info: including detailed error information such like id 205 * @e_info: including detailed error information such like id
253 * 206 *
254 * Invoked when error is detected at the Root Port. 207 * Return true if found.
208 *
209 * Invoked by DPC when error is detected at the Root Port.
210 * Caller of this function must set id, severity, and multi_error_valid of
211 * struct aer_err_info pointed by @e_info properly. This function must fill
212 * e_info->error_dev_num and e_info->dev[], based on the given information.
255 */ 213 */
256static void find_source_device(struct pci_dev *parent, 214static bool find_source_device(struct pci_dev *parent,
257 struct aer_err_info *e_info) 215 struct aer_err_info *e_info)
258{ 216{
259 struct pci_dev *dev = parent; 217 struct pci_dev *dev = parent;
260 int result; 218 int result;
261 219
220 /* Must reset in this function */
221 e_info->error_dev_num = 0;
222
262 /* Is Root Port an agent that sends error message? */ 223 /* Is Root Port an agent that sends error message? */
263 result = find_device_iter(dev, e_info); 224 result = find_device_iter(dev, e_info);
264 if (result) 225 if (result)
265 return; 226 return true;
266 227
267 pci_walk_bus(parent->subordinate, find_device_iter, e_info); 228 pci_walk_bus(parent->subordinate, find_device_iter, e_info);
229
230 if (!e_info->error_dev_num) {
231 dev_printk(KERN_DEBUG, &parent->dev,
232 "can't find device of ID%04x\n",
233 e_info->id);
234 return false;
235 }
236 return true;
268} 237}
269 238
270static int report_error_detected(struct pci_dev *dev, void *data) 239static int report_error_detected(struct pci_dev *dev, void *data)
@@ -403,43 +372,77 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
403 return result_data.result; 372 return result_data.result;
404} 373}
405 374
406struct find_aer_service_data { 375/**
407 struct pcie_port_service_driver *aer_driver; 376 * aer_do_secondary_bus_reset - perform secondary bus reset
408 int is_downstream; 377 * @dev: pointer to bridge's pci_dev data structure
409}; 378 *
410 379 * Invoked when performing link reset at Root Port or Downstream Port.
411static int find_aer_service_iter(struct device *device, void *data) 380 */
381void aer_do_secondary_bus_reset(struct pci_dev *dev)
412{ 382{
413 struct device_driver *driver; 383 u16 p2p_ctrl;
414 struct pcie_port_service_driver *service_driver; 384
415 struct find_aer_service_data *result; 385 /* Assert Secondary Bus Reset */
386 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl);
387 p2p_ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
388 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
389
390 /*
391 * we should send hot reset message for 2ms to allow it time to
392 * propagate to all downstream ports
393 */
394 msleep(2);
395
396 /* De-assert Secondary Bus Reset */
397 p2p_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
398 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
399
400 /*
401 * System software must wait for at least 100ms from the end
402 * of a reset of one or more device before it is permitted
403 * to issue Configuration Requests to those devices.
404 */
405 msleep(200);
406}
416 407
417 result = (struct find_aer_service_data *) data; 408/**
409 * default_downstream_reset_link - default reset function for Downstream Port
410 * @dev: pointer to downstream port's pci_dev data structure
411 *
412 * Invoked when performing link reset at Downstream Port w/ no aer driver.
413 */
414static pci_ers_result_t default_downstream_reset_link(struct pci_dev *dev)
415{
416 aer_do_secondary_bus_reset(dev);
417 dev_printk(KERN_DEBUG, &dev->dev,
418 "Downstream Port link has been reset\n");
419 return PCI_ERS_RESULT_RECOVERED;
420}
418 421
419 if (device->bus == &pcie_port_bus_type) { 422static int find_aer_service_iter(struct device *device, void *data)
420 struct pcie_device *pcie = to_pcie_device(device); 423{
424 struct pcie_port_service_driver *service_driver, **drv;
421 425
422 if (pcie->port->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) 426 drv = (struct pcie_port_service_driver **) data;
423 result->is_downstream = 1;
424 427
425 driver = device->driver; 428 if (device->bus == &pcie_port_bus_type && device->driver) {
426 if (driver) { 429 service_driver = to_service_driver(device->driver);
427 service_driver = to_service_driver(driver); 430 if (service_driver->service == PCIE_PORT_SERVICE_AER) {
428 if (service_driver->service == PCIE_PORT_SERVICE_AER) { 431 *drv = service_driver;
429 result->aer_driver = service_driver; 432 return 1;
430 return 1;
431 }
432 } 433 }
433 } 434 }
434 435
435 return 0; 436 return 0;
436} 437}
437 438
438static void find_aer_service(struct pci_dev *dev, 439static struct pcie_port_service_driver *find_aer_service(struct pci_dev *dev)
439 struct find_aer_service_data *data)
440{ 440{
441 int retval; 441 struct pcie_port_service_driver *drv = NULL;
442 retval = device_for_each_child(&dev->dev, data, find_aer_service_iter); 442
443 device_for_each_child(&dev->dev, &drv, find_aer_service_iter);
444
445 return drv;
443} 446}
444 447
445static pci_ers_result_t reset_link(struct pcie_device *aerdev, 448static pci_ers_result_t reset_link(struct pcie_device *aerdev,
@@ -447,38 +450,34 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev,
447{ 450{
448 struct pci_dev *udev; 451 struct pci_dev *udev;
449 pci_ers_result_t status; 452 pci_ers_result_t status;
450 struct find_aer_service_data data; 453 struct pcie_port_service_driver *driver;
451 454
452 if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) 455 if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) {
456 /* Reset this port for all subordinates */
453 udev = dev; 457 udev = dev;
454 else 458 } else {
459 /* Reset the upstream component (likely downstream port) */
455 udev = dev->bus->self; 460 udev = dev->bus->self;
461 }
456 462
457 data.is_downstream = 0; 463 /* Use the aer driver of the component firstly */
458 data.aer_driver = NULL; 464 driver = find_aer_service(udev);
459 find_aer_service(udev, &data);
460 465
461 /* 466 if (driver && driver->reset_link) {
462 * Use the aer driver of the error agent firstly. 467 status = driver->reset_link(udev);
463 * If it hasn't the aer driver, use the root port's 468 } else if (udev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) {
464 */ 469 status = default_downstream_reset_link(udev);
465 if (!data.aer_driver || !data.aer_driver->reset_link) { 470 } else {
466 if (data.is_downstream && 471 dev_printk(KERN_DEBUG, &dev->dev,
467 aerdev->device.driver && 472 "no link-reset support at upstream device %s\n",
468 to_service_driver(aerdev->device.driver)->reset_link) { 473 pci_name(udev));
469 data.aer_driver = 474 return PCI_ERS_RESULT_DISCONNECT;
470 to_service_driver(aerdev->device.driver);
471 } else {
472 dev_printk(KERN_DEBUG, &dev->dev, "no link-reset "
473 "support\n");
474 return PCI_ERS_RESULT_DISCONNECT;
475 }
476 } 475 }
477 476
478 status = data.aer_driver->reset_link(udev);
479 if (status != PCI_ERS_RESULT_RECOVERED) { 477 if (status != PCI_ERS_RESULT_RECOVERED) {
480 dev_printk(KERN_DEBUG, &dev->dev, "link reset at upstream " 478 dev_printk(KERN_DEBUG, &dev->dev,
481 "device %s failed\n", pci_name(udev)); 479 "link reset at upstream device %s failed\n",
480 pci_name(udev));
482 return PCI_ERS_RESULT_DISCONNECT; 481 return PCI_ERS_RESULT_DISCONNECT;
483 } 482 }
484 483
@@ -495,8 +494,7 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev,
495 * error detected message to all downstream drivers within a hierarchy in 494 * error detected message to all downstream drivers within a hierarchy in
496 * question and return the returned code. 495 * question and return the returned code.
497 */ 496 */
498static pci_ers_result_t do_recovery(struct pcie_device *aerdev, 497static void do_recovery(struct pcie_device *aerdev, struct pci_dev *dev,
499 struct pci_dev *dev,
500 int severity) 498 int severity)
501{ 499{
502 pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED; 500 pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED;
@@ -514,10 +512,8 @@ static pci_ers_result_t do_recovery(struct pcie_device *aerdev,
514 512
515 if (severity == AER_FATAL) { 513 if (severity == AER_FATAL) {
516 result = reset_link(aerdev, dev); 514 result = reset_link(aerdev, dev);
517 if (result != PCI_ERS_RESULT_RECOVERED) { 515 if (result != PCI_ERS_RESULT_RECOVERED)
518 /* TODO: Should panic here? */ 516 goto failed;
519 return result;
520 }
521 } 517 }
522 518
523 if (status == PCI_ERS_RESULT_CAN_RECOVER) 519 if (status == PCI_ERS_RESULT_CAN_RECOVER)
@@ -538,13 +534,22 @@ static pci_ers_result_t do_recovery(struct pcie_device *aerdev,
538 report_slot_reset); 534 report_slot_reset);
539 } 535 }
540 536
541 if (status == PCI_ERS_RESULT_RECOVERED) 537 if (status != PCI_ERS_RESULT_RECOVERED)
542 broadcast_error_message(dev, 538 goto failed;
539
540 broadcast_error_message(dev,
543 state, 541 state,
544 "resume", 542 "resume",
545 report_resume); 543 report_resume);
546 544
547 return status; 545 dev_printk(KERN_DEBUG, &dev->dev,
546 "AER driver successfully recovered\n");
547 return;
548
549failed:
550 /* TODO: Should kernel panic here? */
551 dev_printk(KERN_DEBUG, &dev->dev,
552 "AER driver didn't recover\n");
548} 553}
549 554
550/** 555/**
@@ -559,7 +564,6 @@ static void handle_error_source(struct pcie_device *aerdev,
559 struct pci_dev *dev, 564 struct pci_dev *dev,
560 struct aer_err_info *info) 565 struct aer_err_info *info)
561{ 566{
562 pci_ers_result_t status = 0;
563 int pos; 567 int pos;
564 568
565 if (info->severity == AER_CORRECTABLE) { 569 if (info->severity == AER_CORRECTABLE) {
@@ -571,114 +575,8 @@ static void handle_error_source(struct pcie_device *aerdev,
571 if (pos) 575 if (pos)
572 pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, 576 pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
573 info->status); 577 info->status);
574 } else { 578 } else
575 status = do_recovery(aerdev, dev, info->severity); 579 do_recovery(aerdev, dev, info->severity);
576 if (status == PCI_ERS_RESULT_RECOVERED) {
577 dev_printk(KERN_DEBUG, &dev->dev, "AER driver "
578 "successfully recovered\n");
579 } else {
580 /* TODO: Should kernel panic here? */
581 dev_printk(KERN_DEBUG, &dev->dev, "AER driver didn't "
582 "recover\n");
583 }
584 }
585}
586
587/**
588 * aer_enable_rootport - enable Root Port's interrupts when receiving messages
589 * @rpc: pointer to a Root Port data structure
590 *
591 * Invoked when PCIe bus loads AER service driver.
592 */
593void aer_enable_rootport(struct aer_rpc *rpc)
594{
595 struct pci_dev *pdev = rpc->rpd->port;
596 int pos, aer_pos;
597 u16 reg16;
598 u32 reg32;
599
600 pos = pci_pcie_cap(pdev);
601 /* Clear PCIe Capability's Device Status */
602 pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, &reg16);
603 pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16);
604
605 /* Disable system error generation in response to error messages */
606 pci_read_config_word(pdev, pos + PCI_EXP_RTCTL, &reg16);
607 reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK);
608 pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16);
609
610 aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
611 /* Clear error status */
612 pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32);
613 pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32);
614 pci_read_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, &reg32);
615 pci_write_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, reg32);
616 pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, &reg32);
617 pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32);
618
619 /*
620 * Enable error reporting for the root port device and downstream port
621 * devices.
622 */
623 set_downstream_devices_error_reporting(pdev, true);
624
625 /* Enable Root Port's interrupt in response to error messages */
626 pci_write_config_dword(pdev,
627 aer_pos + PCI_ERR_ROOT_COMMAND,
628 ROOT_PORT_INTR_ON_MESG_MASK);
629}
630
631/**
632 * disable_root_aer - disable Root Port's interrupts when receiving messages
633 * @rpc: pointer to a Root Port data structure
634 *
635 * Invoked when PCIe bus unloads AER service driver.
636 */
637static void disable_root_aer(struct aer_rpc *rpc)
638{
639 struct pci_dev *pdev = rpc->rpd->port;
640 u32 reg32;
641 int pos;
642
643 /*
644 * Disable error reporting for the root port device and downstream port
645 * devices.
646 */
647 set_downstream_devices_error_reporting(pdev, false);
648
649 pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
650 /* Disable Root's interrupt in response to error messages */
651 pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0);
652
653 /* Clear Root's error status reg */
654 pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, &reg32);
655 pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, reg32);
656}
657
658/**
659 * get_e_source - retrieve an error source
660 * @rpc: pointer to the root port which holds an error
661 *
662 * Invoked by DPC handler to consume an error.
663 */
664static struct aer_err_source *get_e_source(struct aer_rpc *rpc)
665{
666 struct aer_err_source *e_source;
667 unsigned long flags;
668
669 /* Lock access to Root error producer/consumer index */
670 spin_lock_irqsave(&rpc->e_lock, flags);
671 if (rpc->prod_idx == rpc->cons_idx) {
672 spin_unlock_irqrestore(&rpc->e_lock, flags);
673 return NULL;
674 }
675 e_source = &rpc->e_sources[rpc->cons_idx];
676 rpc->cons_idx++;
677 if (rpc->cons_idx == AER_ERROR_SOURCES_MAX)
678 rpc->cons_idx = 0;
679 spin_unlock_irqrestore(&rpc->e_lock, flags);
680
681 return e_source;
682} 580}
683 581
684/** 582/**
@@ -687,11 +585,14 @@ static struct aer_err_source *get_e_source(struct aer_rpc *rpc)
687 * @info: pointer to structure to store the error record 585 * @info: pointer to structure to store the error record
688 * 586 *
689 * Return 1 on success, 0 on error. 587 * Return 1 on success, 0 on error.
588 *
589 * Note that @info is reused among all error devices. Clear fields properly.
690 */ 590 */
691static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) 591static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
692{ 592{
693 int pos, temp; 593 int pos, temp;
694 594
595 /* Must reset in this function */
695 info->status = 0; 596 info->status = 0;
696 info->tlp_header_valid = 0; 597 info->tlp_header_valid = 0;
697 598
@@ -744,12 +645,6 @@ static inline void aer_process_err_devices(struct pcie_device *p_device,
744{ 645{
745 int i; 646 int i;
746 647
747 if (!e_info->dev[0]) {
748 dev_printk(KERN_DEBUG, &p_device->port->dev,
749 "can't find device of ID%04x\n",
750 e_info->id);
751 }
752
753 /* Report all before handle them, not to lost records by reset etc. */ 648 /* Report all before handle them, not to lost records by reset etc. */
754 for (i = 0; i < e_info->error_dev_num && e_info->dev[i]; i++) { 649 for (i = 0; i < e_info->error_dev_num && e_info->dev[i]; i++) {
755 if (get_device_error_info(e_info->dev[i], e_info)) 650 if (get_device_error_info(e_info->dev[i], e_info))
@@ -770,11 +665,10 @@ static void aer_isr_one_error(struct pcie_device *p_device,
770 struct aer_err_source *e_src) 665 struct aer_err_source *e_src)
771{ 666{
772 struct aer_err_info *e_info; 667 struct aer_err_info *e_info;
773 int i;
774 668
775 /* struct aer_err_info might be big, so we allocate it with slab */ 669 /* struct aer_err_info might be big, so we allocate it with slab */
776 e_info = kmalloc(sizeof(struct aer_err_info), GFP_KERNEL); 670 e_info = kmalloc(sizeof(struct aer_err_info), GFP_KERNEL);
777 if (e_info == NULL) { 671 if (!e_info) {
778 dev_printk(KERN_DEBUG, &p_device->port->dev, 672 dev_printk(KERN_DEBUG, &p_device->port->dev,
779 "Can't allocate mem when processing AER errors\n"); 673 "Can't allocate mem when processing AER errors\n");
780 return; 674 return;
@@ -784,37 +678,72 @@ static void aer_isr_one_error(struct pcie_device *p_device,
784 * There is a possibility that both correctable error and 678 * There is a possibility that both correctable error and
785 * uncorrectable error being logged. Report correctable error first. 679 * uncorrectable error being logged. Report correctable error first.
786 */ 680 */
787 for (i = 1; i & ROOT_ERR_STATUS_MASKS ; i <<= 2) { 681 if (e_src->status & PCI_ERR_ROOT_COR_RCV) {
788 if (i > 4) 682 e_info->id = ERR_COR_ID(e_src->id);
789 break; 683 e_info->severity = AER_CORRECTABLE;
790 if (!(e_src->status & i)) 684
791 continue; 685 if (e_src->status & PCI_ERR_ROOT_MULTI_COR_RCV)
792
793 memset(e_info, 0, sizeof(struct aer_err_info));
794
795 /* Init comprehensive error information */
796 if (i & PCI_ERR_ROOT_COR_RCV) {
797 e_info->id = ERR_COR_ID(e_src->id);
798 e_info->severity = AER_CORRECTABLE;
799 } else {
800 e_info->id = ERR_UNCOR_ID(e_src->id);
801 e_info->severity = ((e_src->status >> 6) & 1);
802 }
803 if (e_src->status &
804 (PCI_ERR_ROOT_MULTI_COR_RCV |
805 PCI_ERR_ROOT_MULTI_UNCOR_RCV))
806 e_info->multi_error_valid = 1; 686 e_info->multi_error_valid = 1;
687 else
688 e_info->multi_error_valid = 0;
689
690 aer_print_port_info(p_device->port, e_info);
691
692 if (find_source_device(p_device->port, e_info))
693 aer_process_err_devices(p_device, e_info);
694 }
695
696 if (e_src->status & PCI_ERR_ROOT_UNCOR_RCV) {
697 e_info->id = ERR_UNCOR_ID(e_src->id);
698
699 if (e_src->status & PCI_ERR_ROOT_FATAL_RCV)
700 e_info->severity = AER_FATAL;
701 else
702 e_info->severity = AER_NONFATAL;
703
704 if (e_src->status & PCI_ERR_ROOT_MULTI_UNCOR_RCV)
705 e_info->multi_error_valid = 1;
706 else
707 e_info->multi_error_valid = 0;
807 708
808 aer_print_port_info(p_device->port, e_info); 709 aer_print_port_info(p_device->port, e_info);
809 710
810 find_source_device(p_device->port, e_info); 711 if (find_source_device(p_device->port, e_info))
811 aer_process_err_devices(p_device, e_info); 712 aer_process_err_devices(p_device, e_info);
812 } 713 }
813 714
814 kfree(e_info); 715 kfree(e_info);
815} 716}
816 717
817/** 718/**
719 * get_e_source - retrieve an error source
720 * @rpc: pointer to the root port which holds an error
721 * @e_src: pointer to store retrieved error source
722 *
723 * Return 1 if an error source is retrieved, otherwise 0.
724 *
725 * Invoked by DPC handler to consume an error.
726 */
727static int get_e_source(struct aer_rpc *rpc, struct aer_err_source *e_src)
728{
729 unsigned long flags;
730 int ret = 0;
731
732 /* Lock access to Root error producer/consumer index */
733 spin_lock_irqsave(&rpc->e_lock, flags);
734 if (rpc->prod_idx != rpc->cons_idx) {
735 *e_src = rpc->e_sources[rpc->cons_idx];
736 rpc->cons_idx++;
737 if (rpc->cons_idx == AER_ERROR_SOURCES_MAX)
738 rpc->cons_idx = 0;
739 ret = 1;
740 }
741 spin_unlock_irqrestore(&rpc->e_lock, flags);
742
743 return ret;
744}
745
746/**
818 * aer_isr - consume errors detected by root port 747 * aer_isr - consume errors detected by root port
819 * @work: definition of this work item 748 * @work: definition of this work item
820 * 749 *
@@ -824,34 +753,17 @@ void aer_isr(struct work_struct *work)
824{ 753{
825 struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler); 754 struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler);
826 struct pcie_device *p_device = rpc->rpd; 755 struct pcie_device *p_device = rpc->rpd;
827 struct aer_err_source *e_src; 756 struct aer_err_source e_src;
828 757
829 mutex_lock(&rpc->rpc_mutex); 758 mutex_lock(&rpc->rpc_mutex);
830 e_src = get_e_source(rpc); 759 while (get_e_source(rpc, &e_src))
831 while (e_src) { 760 aer_isr_one_error(p_device, &e_src);
832 aer_isr_one_error(p_device, e_src);
833 e_src = get_e_source(rpc);
834 }
835 mutex_unlock(&rpc->rpc_mutex); 761 mutex_unlock(&rpc->rpc_mutex);
836 762
837 wake_up(&rpc->wait_release); 763 wake_up(&rpc->wait_release);
838} 764}
839 765
840/** 766/**
841 * aer_delete_rootport - disable root port aer and delete service data
842 * @rpc: pointer to a root port device being deleted
843 *
844 * Invoked when AER service unloaded on a specific Root Port
845 */
846void aer_delete_rootport(struct aer_rpc *rpc)
847{
848 /* Disable root port AER itself */
849 disable_root_aer(rpc);
850
851 kfree(rpc);
852}
853
854/**
855 * aer_init - provide AER initialization 767 * aer_init - provide AER initialization
856 * @dev: pointer to AER pcie device 768 * @dev: pointer to AER pcie device
857 * 769 *
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 27c0e6eb7136..b7512cf08c58 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2127,6 +2127,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9602, quirk_disable_msi);
2127DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 0x9602, quirk_disable_msi); 2127DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 0x9602, quirk_disable_msi);
2128DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AI, 0x9602, quirk_disable_msi); 2128DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AI, 0x9602, quirk_disable_msi);
2129DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); 2129DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi);
2130DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x5a3f, quirk_disable_msi);
2130 2131
2131/* Go through the list of Hypertransport capabilities and 2132/* Go through the list of Hypertransport capabilities and
2132 * return 1 if a HT MSI capability is found and enabled */ 2133 * return 1 if a HT MSI capability is found and enabled */
@@ -2218,15 +2219,16 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS,
2218DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, 2219DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE,
2219 ht_enable_msi_mapping); 2220 ht_enable_msi_mapping);
2220 2221
2221/* The P5N32-SLI Premium motherboard from Asus has a problem with msi 2222/* The P5N32-SLI motherboards from Asus have a problem with msi
2222 * for the MCP55 NIC. It is not yet determined whether the msi problem 2223 * for the MCP55 NIC. It is not yet determined whether the msi problem
2223 * also affects other devices. As for now, turn off msi for this device. 2224 * also affects other devices. As for now, turn off msi for this device.
2224 */ 2225 */
2225static void __devinit nvenet_msi_disable(struct pci_dev *dev) 2226static void __devinit nvenet_msi_disable(struct pci_dev *dev)
2226{ 2227{
2227 if (dmi_name_in_vendors("P5N32-SLI PREMIUM")) { 2228 if (dmi_name_in_vendors("P5N32-SLI PREMIUM") ||
2229 dmi_name_in_vendors("P5N32-E SLI")) {
2228 dev_info(&dev->dev, 2230 dev_info(&dev->dev,
2229 "Disabling msi for MCP55 NIC on P5N32-SLI Premium\n"); 2231 "Disabling msi for MCP55 NIC on P5N32-SLI\n");
2230 dev->no_msi = 1; 2232 dev->no_msi = 1;
2231 } 2233 }
2232} 2234}
@@ -2552,6 +2554,19 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov);
2552 2554
2553#endif /* CONFIG_PCI_IOV */ 2555#endif /* CONFIG_PCI_IOV */
2554 2556
2557/* Allow manual resource allocation for PCI hotplug bridges
2558 * via pci=hpmemsize=nnM and pci=hpiosize=nnM parameters. For
2559 * some PCI-PCI hotplug bridges, like PLX 6254 (former HINT HB6),
2560 * kernel fails to allocate resources when hotplug device is
2561 * inserted and PCI bus is rescanned.
2562 */
2563static void __devinit quirk_hotplug_bridge(struct pci_dev *dev)
2564{
2565 dev->is_hotplug_bridge = 1;
2566}
2567
2568DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HINT, 0x0020, quirk_hotplug_bridge);
2569
2555/* 2570/*
2556 * This is a quirk for the Ricoh MMC controller found as a part of 2571 * This is a quirk for the Ricoh MMC controller found as a part of
2557 * some mulifunction chips. 2572 * some mulifunction chips.
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index 659eaa0fc48f..e0189cf7c558 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -97,6 +97,50 @@ static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf)
97 return bus_speed_read(slot->bus->cur_bus_speed, buf); 97 return bus_speed_read(slot->bus->cur_bus_speed, buf);
98} 98}
99 99
100static void remove_sysfs_files(struct pci_slot *slot)
101{
102 char func[10];
103 struct list_head *tmp;
104
105 list_for_each(tmp, &slot->bus->devices) {
106 struct pci_dev *dev = pci_dev_b(tmp);
107 if (PCI_SLOT(dev->devfn) != slot->number)
108 continue;
109 sysfs_remove_link(&dev->dev.kobj, "slot");
110
111 snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn));
112 sysfs_remove_link(&slot->kobj, func);
113 }
114}
115
116static int create_sysfs_files(struct pci_slot *slot)
117{
118 int result;
119 char func[10];
120 struct list_head *tmp;
121
122 list_for_each(tmp, &slot->bus->devices) {
123 struct pci_dev *dev = pci_dev_b(tmp);
124 if (PCI_SLOT(dev->devfn) != slot->number)
125 continue;
126
127 result = sysfs_create_link(&dev->dev.kobj, &slot->kobj, "slot");
128 if (result)
129 goto fail;
130
131 snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn));
132 result = sysfs_create_link(&slot->kobj, &dev->dev.kobj, func);
133 if (result)
134 goto fail;
135 }
136
137 return 0;
138
139fail:
140 remove_sysfs_files(slot);
141 return result;
142}
143
100static void pci_slot_release(struct kobject *kobj) 144static void pci_slot_release(struct kobject *kobj)
101{ 145{
102 struct pci_dev *dev; 146 struct pci_dev *dev;
@@ -109,6 +153,8 @@ static void pci_slot_release(struct kobject *kobj)
109 if (PCI_SLOT(dev->devfn) == slot->number) 153 if (PCI_SLOT(dev->devfn) == slot->number)
110 dev->slot = NULL; 154 dev->slot = NULL;
111 155
156 remove_sysfs_files(slot);
157
112 list_del(&slot->list); 158 list_del(&slot->list);
113 159
114 kfree(slot); 160 kfree(slot);
@@ -300,6 +346,8 @@ placeholder:
300 INIT_LIST_HEAD(&slot->list); 346 INIT_LIST_HEAD(&slot->list);
301 list_add(&slot->list, &parent->slots); 347 list_add(&slot->list, &parent->slots);
302 348
349 create_sysfs_files(slot);
350
303 list_for_each_entry(dev, &parent->devices, bus_list) 351 list_for_each_entry(dev, &parent->devices, bus_list)
304 if (PCI_SLOT(dev->devfn) == slot_nr) 352 if (PCI_SLOT(dev->devfn) == slot_nr)
305 dev->slot = slot; 353 dev->slot = slot;