aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2012-01-27 13:55:10 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2012-02-14 11:44:59 -0500
commitefdc87dab1cdf25ba631181ac0ead3fb2023dd10 (patch)
treef55b7d0b2e9bbfd9dd280c85166aef423bf68d75 /drivers
parentac205b7bb72fa4227d2e79979bbe2b4687cdf44d (diff)
PCI: Separate pci_bus_read_dev_vendor_id from pci_scan_device
We can reuse it for pciehp probing. -v2: according to Kenji, fix crs timeout checking, and export the function for later use when pciehp is compiled as a module. Suggested-by: Matthew Wilcox <matthew@wil.cx> Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/probe.c48
2 files changed, 33 insertions, 17 deletions
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 1009a5e88e5..aaf7ff8c517 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -207,6 +207,8 @@ enum pci_bar_type {
207 pci_bar_mem64, /* A 64-bit memory BAR */ 207 pci_bar_mem64, /* A 64-bit memory BAR */
208}; 208};
209 209
210bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
211 int crs_timeout);
210extern int pci_setup_device(struct pci_dev *dev); 212extern int pci_setup_device(struct pci_dev *dev);
211extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, 213extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
212 struct resource *res, unsigned int reg); 214 struct resource *res, unsigned int reg);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index aad7d0ff6b0..9f2ff8c5dc2 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1118,40 +1118,54 @@ struct pci_dev *alloc_pci_dev(void)
1118} 1118}
1119EXPORT_SYMBOL(alloc_pci_dev); 1119EXPORT_SYMBOL(alloc_pci_dev);
1120 1120
1121/* 1121bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
1122 * Read the config data for a PCI device, sanity-check it 1122 int crs_timeout)
1123 * and fill in the dev structure...
1124 */
1125static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
1126{ 1123{
1127 struct pci_dev *dev;
1128 u32 l;
1129 int delay = 1; 1124 int delay = 1;
1130 1125
1131 if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l)) 1126 if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l))
1132 return NULL; 1127 return false;
1133 1128
1134 /* some broken boards return 0 or ~0 if a slot is empty: */ 1129 /* some broken boards return 0 or ~0 if a slot is empty: */
1135 if (l == 0xffffffff || l == 0x00000000 || 1130 if (*l == 0xffffffff || *l == 0x00000000 ||
1136 l == 0x0000ffff || l == 0xffff0000) 1131 *l == 0x0000ffff || *l == 0xffff0000)
1137 return NULL; 1132 return false;
1138 1133
1139 /* Configuration request Retry Status */ 1134 /* Configuration request Retry Status */
1140 while (l == 0xffff0001) { 1135 while (*l == 0xffff0001) {
1136 if (!crs_timeout)
1137 return false;
1138
1141 msleep(delay); 1139 msleep(delay);
1142 delay *= 2; 1140 delay *= 2;
1143 if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l)) 1141 if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l))
1144 return NULL; 1142 return false;
1145 /* Card hasn't responded in 60 seconds? Must be stuck. */ 1143 /* Card hasn't responded in 60 seconds? Must be stuck. */
1146 if (delay > 60 * 1000) { 1144 if (delay > crs_timeout) {
1147 printk(KERN_WARNING "pci %04x:%02x:%02x.%d: not " 1145 printk(KERN_WARNING "pci %04x:%02x:%02x.%d: not "
1148 "responding\n", pci_domain_nr(bus), 1146 "responding\n", pci_domain_nr(bus),
1149 bus->number, PCI_SLOT(devfn), 1147 bus->number, PCI_SLOT(devfn),
1150 PCI_FUNC(devfn)); 1148 PCI_FUNC(devfn));
1151 return NULL; 1149 return false;
1152 } 1150 }
1153 } 1151 }
1154 1152
1153 return true;
1154}
1155EXPORT_SYMBOL(pci_bus_read_dev_vendor_id);
1156
1157/*
1158 * Read the config data for a PCI device, sanity-check it
1159 * and fill in the dev structure...
1160 */
1161static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
1162{
1163 struct pci_dev *dev;
1164 u32 l;
1165
1166 if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000))
1167 return NULL;
1168
1155 dev = alloc_pci_dev(); 1169 dev = alloc_pci_dev();
1156 if (!dev) 1170 if (!dev)
1157 return NULL; 1171 return NULL;