Several device drivers read their Device Serial Number from the PCIe extended config space. Introduce a new helper function, pci_get_dsn(). This function reads the eight bytes of the DSN and returns them as a u64. If the capability does not exist for the device, the function returns 0.
Unified · Split
| @@ -580,6 +580,40 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) · 579 unmodified lines | |||
| 580 | } | 580 | } |
| 581 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); | 581 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); |
| 582 | 582 | ||
| 583 | /** | ||
| 584 | * pci_get_dsn - Read and return the 8-byte Device Serial Number | ||
| 585 | * @dev: PCI device to query | ||
| 586 | * | ||
| 587 | * Looks up the PCI_EXT_CAP_ID_DSN and reads the 8 bytes of the Device Serial | ||
| 588 | * Number. | ||
| 589 | * | ||
| 590 | * Returns the DSN, or zero if the capability does not exist. | ||
| 591 | */ | ||
| 592 | u64 pci_get_dsn(struct pci_dev *dev) | ||
| 593 | { | ||
| 594 | u32 dword; | ||
| 595 | u64 dsn; | ||
| 596 | int pos; | ||
| 597 | |||
| 598 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DSN); | ||
| 599 | if (!pos) | ||
| 600 | return 0; | ||
| 601 | |||
| 602 | /* | ||
| 603 | * The Device Serial Number is two dwords offset 4 bytes from the | ||
| 604 | * capability position. The specification says that the first dword is | ||
| 605 | * the lower half, and the second dword is the upper half. | ||
| 606 | */ | ||
| 607 | pos += 4; | ||
| 608 | pci_read_config_dword(dev, pos, &dword); | ||
| 609 | dsn = (u64)dword; | ||
| 610 | pci_read_config_dword(dev, pos + 4, &dword); | ||
| 611 | dsn |= ((u64)dword) << 32; | ||
| 612 | |||
| 613 | return dsn; | ||
| 614 | } | ||
| 615 | EXPORT_SYMBOL_GPL(pci_get_dsn); | ||
| 616 | |||
| 583 | static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) | 617 | static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) |
| 584 | { | 618 | { |
| 585 | int rc, ttl = PCI_FIND_CAP_TTL; | 619 | int rc, ttl = PCI_FIND_CAP_TTL; |
| @@ -1052,6 +1052,8 @@ int pci_find_ht_capability(struct pci_dev *dev, int ht_cap); · 1051 unmodified lines | |||
| 1052 | int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap); | 1052 | int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap); |
| 1053 | struct pci_bus *pci_find_next_bus(const struct pci_bus *from); | 1053 | struct pci_bus *pci_find_next_bus(const struct pci_bus *from); |
| 1054 | 1054 | ||
| 1055 | u64 pci_get_dsn(struct pci_dev *dev); | ||
| 1056 | |||
| 1055 | struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, | 1057 | struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, |
| 1056 | struct pci_dev *from); | 1058 | struct pci_dev *from); |
| 1057 | struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, | 1059 | struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, |
| @@ -1707,6 +1709,9 @@ static inline int pci_find_next_capability(struct pci_dev *dev, u8 post, · 649 unmodified lines | |||
| 1707 | static inline int pci_find_ext_capability(struct pci_dev *dev, int cap) | 1709 | static inline int pci_find_ext_capability(struct pci_dev *dev, int cap) |
| 1708 | { return 0; } | 1710 | { return 0; } |
| 1709 | 1711 | ||
| 1712 | static inline u64 pci_get_dsn(struct pci_dev *dev) | ||
| 1713 | { return 0; } | ||
| 1714 | |||
| 1710 | /* Power management related routines */ | 1715 | /* Power management related routines */ |
| 1711 | static inline int pci_save_state(struct pci_dev *dev) { return 0; } | 1716 | static inline int pci_save_state(struct pci_dev *dev) { return 0; } |
| 1712 | static inline void pci_restore_state(struct pci_dev *dev) { } | 1717 | static inline void pci_restore_state(struct pci_dev *dev) { } |