aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorSean O. Stalley <sean.stalley@intel.com>2015-04-02 17:10:19 -0400
committerBjorn Helgaas <bhelgaas@google.com>2015-04-09 18:01:39 -0400
commit55db3208f238ee776f1f747734051723d8a3c13e (patch)
treeee168a99ac30c859d8158de29be3b25e4ab8078f /drivers/pci
parent387d37577fdd05e9472c20885464c2a53b3c945f (diff)
PCI: Read capability list as dwords, not bytes
Reading both the capability ID and "next" pointer at the same time lets us parse the list with half the number of config reads. Signed-off-by: Sean O. Stalley <sean.stalley@intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 81f06e8dcc04..3c84cc6bc75a 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -145,19 +145,22 @@ static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
145 u8 pos, int cap, int *ttl) 145 u8 pos, int cap, int *ttl)
146{ 146{
147 u8 id; 147 u8 id;
148 u16 ent;
149
150 pci_bus_read_config_byte(bus, devfn, pos, &pos);
148 151
149 while ((*ttl)--) { 152 while ((*ttl)--) {
150 pci_bus_read_config_byte(bus, devfn, pos, &pos);
151 if (pos < 0x40) 153 if (pos < 0x40)
152 break; 154 break;
153 pos &= ~3; 155 pos &= ~3;
154 pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID, 156 pci_bus_read_config_word(bus, devfn, pos, &ent);
155 &id); 157
158 id = ent & 0xff;
156 if (id == 0xff) 159 if (id == 0xff)
157 break; 160 break;
158 if (id == cap) 161 if (id == cap)
159 return pos; 162 return pos;
160 pos += PCI_CAP_LIST_NEXT; 163 pos = (ent >> 8);
161 } 164 }
162 return 0; 165 return 0;
163} 166}