* [PATCH -v5 1/6] PCI,pciehp: avoid add a device already exist before suspend during resume
2013-08-05 8:54 [PATCH -v5 0/6] Use PCI Serial Number to identify device change Yijing Wang
@ 2013-08-05 8:54 ` Yijing Wang
2013-08-05 8:54 ` [PATCH -v5 2/6] PCI: introduce PCIe Device Serial Number Capability support Yijing Wang
` (5 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Yijing Wang @ 2013-08-05 8:54 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Rafael, Oliver Neukum, Gu Zheng, Paul Bolle,
Hanjun Guo, jiang.liu, Yijing Wang
Currently, pciehp_resume() try to hot add device if the slot adapter
status return true. But if there are already some devices exist,
namely list_empty(bus->devices) return false. We should not add the device
again, because the device add action will fail. Also print some uncomfortable
messages like this:
pciehp 0000:00:1c.1:pcie04: Device 0000:03:00.0 already exists at 0000:03:00, cannot hot-add
pciehp 0000:00:1c.1:pcie04: Cannot add device at 0000:03:00
Tested-by: Paul Bolle <pebolle@tiscali.nl>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Paul Bolle <pebolle@tiscali.nl>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Oliver Neukum <oneukum@suse.de>
Cc: Gu Zheng <guz.fnst@cn.fujitsu.com>
Cc: linux-pci@vger.kernel.org
---
drivers/pci/hotplug/pciehp_core.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 7d72c5e..7fe9dbd 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -300,6 +300,7 @@ static int pciehp_resume (struct pcie_device *dev)
{
struct controller *ctrl;
struct slot *slot;
+ struct pci_bus *pbus = dev->port->subordinate;
u8 status;
ctrl = get_service_data(dev);
@@ -311,10 +312,13 @@ static int pciehp_resume (struct pcie_device *dev)
/* Check if slot is occupied */
pciehp_get_adapter_status(slot, &status);
- if (status)
- pciehp_enable_slot(slot);
- else
+ if (status) {
+ if (list_empty(&pbus->devices))
+ pciehp_enable_slot(slot);
+ } else if (!list_empty(&pbus->devices)) {
pciehp_disable_slot(slot);
+ }
+
return 0;
}
#endif /* PM */
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH -v5 2/6] PCI: introduce PCIe Device Serial Number Capability support
2013-08-05 8:54 [PATCH -v5 0/6] Use PCI Serial Number to identify device change Yijing Wang
2013-08-05 8:54 ` [PATCH -v5 1/6] PCI,pciehp: avoid add a device already exist before suspend during resume Yijing Wang
@ 2013-08-05 8:54 ` Yijing Wang
2013-08-05 8:54 ` [PATCH -v5 3/6] PCI: Introduce Vital Product Data Serial Number capability support Yijing Wang
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Yijing Wang @ 2013-08-05 8:54 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Rafael, Oliver Neukum, Gu Zheng, Paul Bolle,
Hanjun Guo, jiang.liu, Yijing Wang
Introduce PCIe Ext Capability Device Serial Number support,
so we can use the unique device serial number to identify
the physical device. During system suspend, if the PCIe
device was removed and reinserted a new same device, during
system resume there is no good way to identify it, maybe
Device Serial Number is a good choice if device support.
Reviewed-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Paul Bolle <pebolle@tiscali.nl>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Oliver Neukum <oneukum@suse.de>
Cc: Gu Zheng <guz.fnst@cn.fujitsu.com>
Cc: linux-pci@vger.kernel.org
---
drivers/pci/pci.c | 29 +++++++++++++++++++++++++++++
drivers/pci/pci.h | 2 +-
drivers/pci/probe.c | 2 ++
include/linux/pci.h | 1 +
4 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 84a3c09..cfc0f7f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2048,6 +2048,35 @@ void pci_free_cap_save_buffers(struct pci_dev *dev)
}
/**
+ * pci_device_serial_number - get device serial number
+ * @dev: the PCI device
+ *
+ * return the device serial number if device support,
+ * otherwise return 0.
+ */
+static u64 pci_device_serial_number(struct pci_dev *dev)
+{
+ int pos;
+ u32 lo, hi;
+
+ if (!pci_is_pcie(dev))
+ return 0;
+
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DSN);
+ if (!pos)
+ return 0;
+
+ pci_read_config_dword(dev, pos + 4, &lo);
+ pci_read_config_dword(dev, pos + 8, &hi);
+ return ((u64)hi << 32) | lo;
+}
+
+void pci_dsn_init(struct pci_dev *dev)
+{
+ dev->sn = pci_device_serial_number(dev);
+}
+
+/**
* pci_configure_ari - enable or disable ARI forwarding
* @dev: the PCI device
*
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 816c297..2b2a9cc 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -207,7 +207,7 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,
void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
struct list_head *realloc_head,
struct list_head *fail_head);
-
+void pci_dsn_init(struct pci_dev *dev);
/**
* pci_ari_enabled - query ARI forwarding status
* @bus: the PCI bus
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 83172bc..0c5da76 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1325,6 +1325,8 @@ static void pci_init_capabilities(struct pci_dev *dev)
/* Vital Product Data */
pci_vpd_pci22_init(dev);
+ pci_dsn_init(dev);
+
/* Alternative Routing-ID Forwarding */
pci_configure_ari(dev);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 0fd1f15..4354eaf 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -342,6 +342,7 @@ struct pci_dev {
struct list_head msi_list;
struct kset *msi_kset;
#endif
+ u64 sn; /* device serial number, 0 if not support */
struct pci_vpd *vpd;
#ifdef CONFIG_PCI_ATS
union {
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH -v5 3/6] PCI: Introduce Vital Product Data Serial Number capability support
2013-08-05 8:54 [PATCH -v5 0/6] Use PCI Serial Number to identify device change Yijing Wang
2013-08-05 8:54 ` [PATCH -v5 1/6] PCI,pciehp: avoid add a device already exist before suspend during resume Yijing Wang
2013-08-05 8:54 ` [PATCH -v5 2/6] PCI: introduce PCIe Device Serial Number Capability support Yijing Wang
@ 2013-08-05 8:54 ` Yijing Wang
2013-08-05 8:54 ` [PATCH -v5 4/6] PCI: add pci_serial_number_changed() for device change identification Yijing Wang
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Yijing Wang @ 2013-08-05 8:54 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Rafael, Oliver Neukum, Gu Zheng, Paul Bolle,
Hanjun Guo, jiang.liu, Yijing Wang
Vital Product Data Serial Number is another capability to support
device serial number, some devices may implement this cap. So we
introduce VPD SN support here to enhance the device change
identification.
Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Paul Bolle <pebolle@tiscali.nl>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Oliver Neukum <oneukum@suse.de>
Cc: Gu Zheng <guz.fnst@cn.fujitsu.com>
Cc: linux-pci@vger.kernel.org
---
drivers/pci/access.c | 4 ++-
drivers/pci/pci.h | 4 +++
drivers/pci/vpd.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/pci.h | 1 +
4 files changed, 78 insertions(+), 1 deletions(-)
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 1cc2366..0069981 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -194,7 +194,6 @@ PCI_USER_WRITE_CONFIG(dword, u32)
/* VPD access through PCI 2.2+ VPD capability */
-#define PCI_VPD_PCI22_SIZE (PCI_VPD_ADDR_MASK + 1)
struct pci_vpd_pci22 {
struct pci_vpd base;
@@ -350,6 +349,7 @@ out:
static void pci_vpd_pci22_release(struct pci_dev *dev)
{
+ kfree(dev->vpd->sn);
kfree(container_of(dev->vpd, struct pci_vpd_pci22, base));
}
@@ -377,6 +377,8 @@ int pci_vpd_pci22_init(struct pci_dev *dev)
vpd->cap = cap;
vpd->busy = false;
dev->vpd = &vpd->base;
+
+ pci_vpd_serial_number_init(dev, dev->vpd);
return 0;
}
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 2b2a9cc..eb77124 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -83,6 +83,8 @@ static inline bool pci_is_bridge(struct pci_dev *pci_dev)
return !!(pci_dev->subordinate);
}
+#define PCI_VPD_PCI22_SIZE (PCI_VPD_ADDR_MASK + 1)
+
struct pci_vpd_ops {
ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
@@ -91,6 +93,7 @@ struct pci_vpd_ops {
struct pci_vpd {
unsigned int len;
+ char *sn; /* serial number */
const struct pci_vpd_ops *ops;
struct bin_attribute *attr; /* descriptor for sysfs VPD entry */
};
@@ -208,6 +211,7 @@ void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
struct list_head *realloc_head,
struct list_head *fail_head);
void pci_dsn_init(struct pci_dev *dev);
+struct pci_vpd *pci_vpd_serial_number_init(struct pci_dev *dev, struct pci_vpd *vpd);
/**
* pci_ari_enabled - query ARI forwarding status
* @bus: the PCI bus
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c
index 39b7907..e5a4853 100644
--- a/drivers/pci/vpd.c
+++ b/drivers/pci/vpd.c
@@ -7,6 +7,7 @@
#include <linux/pci.h>
#include <linux/export.h>
+#include "pci.h"
int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt)
{
@@ -60,3 +61,71 @@ int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off,
return -ENOENT;
}
EXPORT_SYMBOL_GPL(pci_vpd_find_info_keyword);
+
+/**
+ * pci_vpd_serial_number_init - initialize the device VPD SN
+ * @dev: the PCI device
+ * @vpd: the VPD used to initialize SN
+ *
+ * Initialize the device VPD Serial Number, if vpd passed as NULL,
+ * allocate a new VPD and initialize its SN.
+ */
+struct pci_vpd *pci_vpd_serial_number_init(struct pci_dev *dev,
+ struct pci_vpd *vpd)
+{
+ char *buf = NULL;
+ struct pci_vpd *old = dev->vpd;
+ struct pci_vpd *new = NULL;
+ int cnt, i, end, j, len;
+
+ /* To detect whether the device is changed, we should
+ * allocate a new VPD to initialize serial number,
+ * because if the device has been changed, the cap
+ * info is stale.
+ */
+ if (!vpd) {
+ dev->vpd = NULL;
+ pci_vpd_pci22_init(dev);
+ if (!dev->vpd)
+ goto fail;
+ }
+
+ new = dev->vpd;
+ buf = kzalloc(PCI_VPD_PCI22_SIZE, GFP_KERNEL);
+ if (!buf)
+ goto fail;
+
+ cnt = pci_read_vpd(dev, 0, PCI_VPD_PCI22_SIZE, buf);
+ if (cnt < 0)
+ goto fail;
+
+ i = pci_vpd_find_tag(buf, 0, PCI_VPD_PCI22_SIZE,
+ PCI_VPD_LRDT_RO_DATA);
+ if (i < 0)
+ goto fail;
+
+ end = i + PCI_VPD_LRDT_TAG_SIZE + pci_vpd_lrdt_size(&buf[i]);
+ i += PCI_VPD_LRDT_TAG_SIZE;
+
+ j = pci_vpd_find_info_keyword(buf, i, end,
+ PCI_VPD_RO_KEYWORD_SN);
+ if (j < 0)
+ goto fail;
+
+ len = pci_vpd_info_field_size(&buf[j]);
+ new->sn = kzalloc(len + 1, GFP_KERNEL);
+ if (!new->sn)
+ goto fail;
+
+ j += PCI_VPD_INFO_FLD_HDR_SIZE;
+ memcpy(new->sn, &buf[j], len);
+ kfree(buf);
+ dev->vpd = old;
+ return new;
+fail:
+ kfree(buf);
+ if (new != old)
+ pci_vpd_release(dev);
+ dev->vpd = old;
+ return NULL;
+}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 4354eaf..5c38b55 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1781,6 +1781,7 @@ bool pci_acs_path_enabled(struct pci_dev *start,
#define PCI_VPD_RO_KEYWORD_PARTNO "PN"
#define PCI_VPD_RO_KEYWORD_MFR_ID "MN"
+#define PCI_VPD_RO_KEYWORD_SN "SN"
#define PCI_VPD_RO_KEYWORD_VENDOR0 "V0"
#define PCI_VPD_RO_KEYWORD_CHKSUM "RV"
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH -v5 4/6] PCI: add pci_serial_number_changed() for device change identification
2013-08-05 8:54 [PATCH -v5 0/6] Use PCI Serial Number to identify device change Yijing Wang
` (2 preceding siblings ...)
2013-08-05 8:54 ` [PATCH -v5 3/6] PCI: Introduce Vital Product Data Serial Number capability support Yijing Wang
@ 2013-08-05 8:54 ` Yijing Wang
2013-08-05 8:54 ` [PATCH -v5 5/6] PCI: add inspection of device change in pci_scan_single_device Yijing Wang
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Yijing Wang @ 2013-08-05 8:54 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Rafael, Oliver Neukum, Gu Zheng, Paul Bolle,
Hanjun Guo, jiang.liu, Yijing Wang
Sometimes OS do not know the physical device swap,
for instance, some device hotplug during system suspend.
Interrupt can not deliver to OS in some platform.
So we can use pci serial number capability to detect this
issue if device supports serial number.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Paul Bolle <pebolle@tiscali.nl>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Oliver Neukum <oneukum@suse.de>
Cc: Gu Zheng <guz.fnst@cn.fujitsu.com>
Cc: linux-pci@vger.kernel.org
---
drivers/pci/access.c | 9 ---------
drivers/pci/pci.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
drivers/pci/pci.h | 8 ++++++++
include/linux/pci.h | 2 ++
4 files changed, 58 insertions(+), 9 deletions(-)
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 0069981..7f8df11 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -194,15 +194,6 @@ PCI_USER_WRITE_CONFIG(dword, u32)
/* VPD access through PCI 2.2+ VPD capability */
-
-struct pci_vpd_pci22 {
- struct pci_vpd base;
- struct mutex lock;
- u16 flag;
- bool busy;
- u8 cap;
-};
-
/*
* Wait for last operation to complete.
* This code has to spin since there is no other notification from the PCI
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index cfc0f7f..a6ac0c8 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2077,6 +2077,54 @@ void pci_dsn_init(struct pci_dev *dev)
}
/**
+ * pci_serial_number_changed - check the device SN is changed
+ * @pdev: the PCI device
+ *
+ * check the device serial number is changed.
+ * if device does not support device serial number,
+ * return false.
+ */
+bool pci_serial_number_changed(struct pci_dev *pdev)
+{
+ struct pci_vpd *vpd;
+ u64 old_dsn, new_dsn;
+ int ret;
+
+ /* first check PCIe DSN */
+ old_dsn = pdev->sn;
+ new_dsn = pci_device_serial_number(pdev);
+
+ if (old_dsn != new_dsn)
+ return true;
+ else if (old_dsn)
+ return false;
+
+ /* PCIe DSN does not support, check VPD SN */
+ vpd = pci_vpd_serial_number_init(pdev, NULL);
+ if (!pdev->vpd && !vpd) {
+ /* VPD SN does not support */
+ return false;
+ } else if (pdev->vpd && pdev->vpd->sn && vpd) {
+ ret = strcmp(pdev->vpd->sn, vpd->sn);
+ kfree(vpd->sn);
+ kfree(container_of(vpd, struct pci_vpd_pci22, base));
+ if (!ret)
+ return false;
+ else
+ return true;
+ } else if ((pdev->vpd && pdev->vpd->sn) || (vpd && vpd->sn)) {
+ if (vpd) {
+ kfree(vpd->sn);
+ kfree(container_of(vpd, struct pci_vpd_pci22, base));
+ }
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(pci_serial_number_changed);
+
+/**
* pci_configure_ari - enable or disable ARI forwarding
* @dev: the PCI device
*
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index eb77124..5d1f261 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -98,6 +98,14 @@ struct pci_vpd {
struct bin_attribute *attr; /* descriptor for sysfs VPD entry */
};
+struct pci_vpd_pci22 {
+ struct pci_vpd base;
+ struct mutex lock;
+ u16 flag;
+ bool busy;
+ u8 cap;
+};
+
int pci_vpd_pci22_init(struct pci_dev *dev);
static inline void pci_vpd_release(struct pci_dev *dev)
{
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5c38b55..9580fa5 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -996,6 +996,8 @@ ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
int pci_vpd_truncate(struct pci_dev *dev, size_t size);
+bool pci_serial_number_changed(struct pci_dev *pdev);
+
/* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx);
void pci_bus_assign_resources(const struct pci_bus *bus);
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH -v5 5/6] PCI: add inspection of device change in pci_scan_single_device
2013-08-05 8:54 [PATCH -v5 0/6] Use PCI Serial Number to identify device change Yijing Wang
` (3 preceding siblings ...)
2013-08-05 8:54 ` [PATCH -v5 4/6] PCI: add pci_serial_number_changed() for device change identification Yijing Wang
@ 2013-08-05 8:54 ` Yijing Wang
2013-08-05 8:54 ` [PATCH -v5 6/6] PCI,pciehp: identify device change during suspend Yijing Wang
2013-08-05 12:01 ` [PATCH -v5 0/6] Use PCI Serial Number to identify device change Paul Bolle
6 siblings, 0 replies; 9+ messages in thread
From: Yijing Wang @ 2013-08-05 8:54 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Rafael, Oliver Neukum, Gu Zheng, Paul Bolle,
Hanjun Guo, jiang.liu, Yijing Wang
Add inspection of device change in pci_scan_single_device.
If device change found, print warning. Because the new device
bind the old device driver, so for safety, we do not remove this
device.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Paul Bolle <pebolle@tiscali.nl>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Oliver Neukum <oneukum@suse.de>
Cc: Gu Zheng <guz.fnst@cn.fujitsu.com>
Cc: linux-pci@vger.kernel.org
---
drivers/pci/probe.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 0c5da76..f2812db 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1389,6 +1389,8 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
dev = pci_get_slot(bus, devfn);
if (dev) {
+ if (pci_serial_number_changed(dev))
+ dev_warn(&dev->dev, "device serial number changed!");
pci_dev_put(dev);
return dev;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH -v5 6/6] PCI,pciehp: identify device change during suspend
2013-08-05 8:54 [PATCH -v5 0/6] Use PCI Serial Number to identify device change Yijing Wang
` (4 preceding siblings ...)
2013-08-05 8:54 ` [PATCH -v5 5/6] PCI: add inspection of device change in pci_scan_single_device Yijing Wang
@ 2013-08-05 8:54 ` Yijing Wang
2013-08-05 12:01 ` [PATCH -v5 0/6] Use PCI Serial Number to identify device change Paul Bolle
6 siblings, 0 replies; 9+ messages in thread
From: Yijing Wang @ 2013-08-05 8:54 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Rafael, Oliver Neukum, Gu Zheng, Paul Bolle,
Hanjun Guo, jiang.liu, Yijing Wang
If device was removed from slot and reinsert a new device during
suspend, pciehp can not identify the physical device change now.
So the old driver .resume() method will be called for the new device,
this is bad. If device support device serial number capability,
we can identify this by DSN. So the reasonable way is first remove
the old device, then enable the new device.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Paul Bolle <pebolle@tiscali.nl>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Oliver Neukum <oneukum@suse.de>
Cc: Gu Zheng <guz.fnst@cn.fujitsu.com>
Cc: linux-pci@vger.kernel.org
---
drivers/pci/hotplug/pciehp_core.c | 29 ++++++++++++++++++++++++++++-
1 files changed, 28 insertions(+), 1 deletions(-)
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 7fe9dbd..7c6e4a6 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -301,6 +301,8 @@ static int pciehp_resume (struct pcie_device *dev)
struct controller *ctrl;
struct slot *slot;
struct pci_bus *pbus = dev->port->subordinate;
+ struct pci_dev *pdev;
+ int ret = 0;
u8 status;
ctrl = get_service_data(dev);
@@ -313,8 +315,33 @@ static int pciehp_resume (struct pcie_device *dev)
/* Check if slot is occupied */
pciehp_get_adapter_status(slot, &status);
if (status) {
- if (list_empty(&pbus->devices))
+ if (list_empty(&pbus->devices)) {
pciehp_enable_slot(slot);
+ return 0;
+ }
+
+ pdev = pci_get_slot(pbus, PCI_DEVFN(0, 0));
+ if (!pdev)
+ return 0;
+ ret = pci_serial_number_changed(pdev);
+ pci_dev_put(pdev);
+ if (ret) {
+ /*
+ * first power off slot, avoid the old driver
+ * .remove() method touch the new hardware
+ */
+ if (POWER_CTRL(ctrl)) {
+ ret = pciehp_power_off_slot(slot);
+ if (ret) {
+ ctrl_err(ctrl,
+ "Issue of Slot Disable command failed\n");
+ return 0;
+ }
+ msleep(1000);
+ pciehp_unconfigure_device(slot);
+ pciehp_enable_slot(slot);
+ }
+ }
} else if (!list_empty(&pbus->devices)) {
pciehp_disable_slot(slot);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH -v5 0/6] Use PCI Serial Number to identify device change
2013-08-05 8:54 [PATCH -v5 0/6] Use PCI Serial Number to identify device change Yijing Wang
` (5 preceding siblings ...)
2013-08-05 8:54 ` [PATCH -v5 6/6] PCI,pciehp: identify device change during suspend Yijing Wang
@ 2013-08-05 12:01 ` Paul Bolle
2013-08-06 1:23 ` Yijing Wang
6 siblings, 1 reply; 9+ messages in thread
From: Paul Bolle @ 2013-08-05 12:01 UTC (permalink / raw)
To: Yijing Wang
Cc: Bjorn Helgaas, linux-pci, Rafael, Oliver Neukum, Gu Zheng,
Hanjun Guo, jiang.liu
On Mon, 2013-08-05 at 16:54 +0800, Yijing Wang wrote:
> v4->v5: update patch 6/6, correct some mistakes in this patch, thank Paul for help
> test this series.
>[...]
> I tested to apply this series to Linus 3.11-rc4 and Bjorn's pci-next branch, and
> result is ok.
And I tested this series on top of v3.10.5 (on x86_64). It applied
cleanly, and it compiled cleanly. No pciehp related errors at resume.
And, more importantly, the severe issues of v4 are gone: a few suspend
and resume cycles showed no obvious problems.
Thanks!
Paul Bolle
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH -v5 0/6] Use PCI Serial Number to identify device change
2013-08-05 12:01 ` [PATCH -v5 0/6] Use PCI Serial Number to identify device change Paul Bolle
@ 2013-08-06 1:23 ` Yijing Wang
0 siblings, 0 replies; 9+ messages in thread
From: Yijing Wang @ 2013-08-06 1:23 UTC (permalink / raw)
To: Paul Bolle
Cc: Bjorn Helgaas, linux-pci, Rafael, Oliver Neukum, Gu Zheng,
Hanjun Guo, jiang.liu
On 2013/8/5 20:01, Paul Bolle wrote:
> On Mon, 2013-08-05 at 16:54 +0800, Yijing Wang wrote:
>> v4->v5: update patch 6/6, correct some mistakes in this patch, thank Paul for help
>> test this series.
>> [...]
>> I tested to apply this series to Linus 3.11-rc4 and Bjorn's pci-next branch, and
>> result is ok.
>
> And I tested this series on top of v3.10.5 (on x86_64). It applied
> cleanly, and it compiled cleanly. No pciehp related errors at resume.
> And, more importantly, the severe issues of v4 are gone: a few suspend
> and resume cycles showed no obvious problems.
>
Hi Paul,
Thanks for your test very much!
Thanks!
Yijing.
>
--
Thanks!
Yijing
^ permalink raw reply [flat|nested] 9+ messages in thread