@@ -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
*
@@ -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
@@ -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);
@@ -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 {