aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci.c43
-rw-r--r--drivers/pci/pci.h3
-rw-r--r--drivers/pci/probe.c4
3 files changed, 48 insertions, 2 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index b821a62958fd..e8ccf6c0f08a 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3998,6 +3998,49 @@ int pcie_set_mps(struct pci_dev *dev, int mps)
3998} 3998}
3999 3999
4000/** 4000/**
4001 * pcie_get_minimum_link - determine minimum link settings of a PCI device
4002 * @dev: PCI device to query
4003 * @speed: storage for minimum speed
4004 * @width: storage for minimum width
4005 *
4006 * This function will walk up the PCI device chain and determine the minimum
4007 * link width and speed of the device.
4008 */
4009int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
4010 enum pcie_link_width *width)
4011{
4012 int ret;
4013
4014 *speed = PCI_SPEED_UNKNOWN;
4015 *width = PCIE_LNK_WIDTH_UNKNOWN;
4016
4017 while (dev) {
4018 u16 lnksta;
4019 enum pci_bus_speed next_speed;
4020 enum pcie_link_width next_width;
4021
4022 ret = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
4023 if (ret)
4024 return ret;
4025
4026 next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS];
4027 next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >>
4028 PCI_EXP_LNKSTA_NLW_SHIFT;
4029
4030 if (next_speed < *speed)
4031 *speed = next_speed;
4032
4033 if (next_width < *width)
4034 *width = next_width;
4035
4036 dev = dev->bus->self;
4037 }
4038
4039 return 0;
4040}
4041EXPORT_SYMBOL(pcie_get_minimum_link);
4042
4043/**
4001 * pci_select_bars - Make BAR mask from the type of resource 4044 * pci_select_bars - Make BAR mask from the type of resource
4002 * @dev: the PCI device for which BAR mask is made 4045 * @dev: the PCI device for which BAR mask is made
4003 * @flags: resource type mask to be selected 4046 * @flags: resource type mask to be selected
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 816c297f170c..8a00c063d7bc 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -6,6 +6,9 @@
6#define PCI_CFG_SPACE_SIZE 256 6#define PCI_CFG_SPACE_SIZE 256
7#define PCI_CFG_SPACE_EXP_SIZE 4096 7#define PCI_CFG_SPACE_EXP_SIZE 4096
8 8
9extern const unsigned char pcix_bus_speed[];
10extern const unsigned char pcie_link_speed[];
11
9/* Functions internal to the PCI core code */ 12/* Functions internal to the PCI core code */
10 13
11int pci_create_sysfs_dev_files(struct pci_dev *pdev); 14int pci_create_sysfs_dev_files(struct pci_dev *pdev);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index eeb50bd62402..4f9cc93c3b59 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -518,7 +518,7 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
518 return bridge; 518 return bridge;
519} 519}
520 520
521static unsigned char pcix_bus_speed[] = { 521const unsigned char pcix_bus_speed[] = {
522 PCI_SPEED_UNKNOWN, /* 0 */ 522 PCI_SPEED_UNKNOWN, /* 0 */
523 PCI_SPEED_66MHz_PCIX, /* 1 */ 523 PCI_SPEED_66MHz_PCIX, /* 1 */
524 PCI_SPEED_100MHz_PCIX, /* 2 */ 524 PCI_SPEED_100MHz_PCIX, /* 2 */
@@ -537,7 +537,7 @@ static unsigned char pcix_bus_speed[] = {
537 PCI_SPEED_133MHz_PCIX_533 /* F */ 537 PCI_SPEED_133MHz_PCIX_533 /* F */
538}; 538};
539 539
540static unsigned char pcie_link_speed[] = { 540const unsigned char pcie_link_speed[] = {
541 PCI_SPEED_UNKNOWN, /* 0 */ 541 PCI_SPEED_UNKNOWN, /* 0 */
542 PCIE_SPEED_2_5GT, /* 1 */ 542 PCIE_SPEED_2_5GT, /* 1 */
543 PCIE_SPEED_5_0GT, /* 2 */ 543 PCIE_SPEED_5_0GT, /* 2 */