aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/Kconfig2
-rw-r--r--drivers/pci/pci.c3
-rw-r--r--drivers/pci/quirks.c16
-rw-r--r--drivers/pci/search.c24
4 files changed, 36 insertions, 9 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index f1dd81a1d592..3cfb0a3575e6 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -19,7 +19,7 @@ config PCI_MSI
19 19
20config PCI_MULTITHREAD_PROBE 20config PCI_MULTITHREAD_PROBE
21 bool "PCI Multi-threaded probe (EXPERIMENTAL)" 21 bool "PCI Multi-threaded probe (EXPERIMENTAL)"
22 depends on PCI && EXPERIMENTAL 22 depends on PCI && EXPERIMENTAL && BROKEN
23 help 23 help
24 Say Y here if you want the PCI core to spawn a new thread for 24 Say Y here if you want the PCI core to spawn a new thread for
25 every PCI device that is probed. This can cause a huge 25 every PCI device that is probed. This can cause a huge
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6bfb942428e4..206c834d263a 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -254,7 +254,8 @@ static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
254 if ((cap & mask) == ht_cap) 254 if ((cap & mask) == ht_cap)
255 return pos; 255 return pos;
256 256
257 pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos, 257 pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn,
258 pos + PCI_CAP_LIST_NEXT,
258 PCI_CAP_ID_HT, &ttl); 259 PCI_CAP_ID_HT, &ttl);
259 } 260 }
260 261
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 8f0322d6f3bf..0a70943f8bb6 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -955,7 +955,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_ho
955 * becomes necessary to do this tweak in two steps -- I've chosen the Host 955 * becomes necessary to do this tweak in two steps -- I've chosen the Host
956 * bridge as trigger. 956 * bridge as trigger.
957 */ 957 */
958static int __initdata asus_hides_smbus; 958static int asus_hides_smbus;
959 959
960static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) 960static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
961{ 961{
@@ -1117,10 +1117,11 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_h
1117static void quirk_sis_96x_smbus(struct pci_dev *dev) 1117static void quirk_sis_96x_smbus(struct pci_dev *dev)
1118{ 1118{
1119 u8 val = 0; 1119 u8 val = 0;
1120 printk(KERN_INFO "Enabling SiS 96x SMBus.\n");
1121 pci_read_config_byte(dev, 0x77, &val);
1122 pci_write_config_byte(dev, 0x77, val & ~0x10);
1123 pci_read_config_byte(dev, 0x77, &val); 1120 pci_read_config_byte(dev, 0x77, &val);
1121 if (val & 0x10) {
1122 printk(KERN_INFO "Enabling SiS 96x SMBus.\n");
1123 pci_write_config_byte(dev, 0x77, val & ~0x10);
1124 }
1124} 1125}
1125 1126
1126/* 1127/*
@@ -1152,11 +1153,12 @@ static void quirk_sis_503(struct pci_dev *dev)
1152 printk(KERN_WARNING "Uncovering SIS%x that hid as a SIS503 (compatible=%d)\n", devid, sis_96x_compatible); 1153 printk(KERN_WARNING "Uncovering SIS%x that hid as a SIS503 (compatible=%d)\n", devid, sis_96x_compatible);
1153 1154
1154 /* 1155 /*
1155 * Ok, it now shows up as a 96x.. The 96x quirks are after 1156 * Ok, it now shows up as a 96x.. run the 96x quirk by
1156 * the 503 quirk in the quirk table, so they'll automatically 1157 * hand in case it has already been processed.
1157 * run and enable things like the SMBus device 1158 * (depends on link order, which is apparently not guaranteed)
1158 */ 1159 */
1159 dev->device = devid; 1160 dev->device = devid;
1161 quirk_sis_96x_smbus(dev);
1160} 1162}
1161 1163
1162static void __init quirk_sis_96x_compatible(struct pci_dev *dev) 1164static void __init quirk_sis_96x_compatible(struct pci_dev *dev)
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 45f2b20ef513..fab381ed853c 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -193,6 +193,18 @@ static struct pci_dev * pci_find_subsys(unsigned int vendor,
193 struct pci_dev *dev; 193 struct pci_dev *dev;
194 194
195 WARN_ON(in_interrupt()); 195 WARN_ON(in_interrupt());
196
197 /*
198 * pci_find_subsys() can be called on the ide_setup() path, super-early
199 * in boot. But the down_read() will enable local interrupts, which
200 * can cause some machines to crash. So here we detect and flag that
201 * situation and bail out early.
202 */
203 if (unlikely(list_empty(&pci_devices))) {
204 printk(KERN_INFO "pci_find_subsys() called while pci_devices "
205 "is still empty\n");
206 return NULL;
207 }
196 down_read(&pci_bus_sem); 208 down_read(&pci_bus_sem);
197 n = from ? from->global_list.next : pci_devices.next; 209 n = from ? from->global_list.next : pci_devices.next;
198 210
@@ -259,6 +271,18 @@ pci_get_subsys(unsigned int vendor, unsigned int device,
259 struct pci_dev *dev; 271 struct pci_dev *dev;
260 272
261 WARN_ON(in_interrupt()); 273 WARN_ON(in_interrupt());
274
275 /*
276 * pci_get_subsys() can potentially be called by drivers super-early
277 * in boot. But the down_read() will enable local interrupts, which
278 * can cause some machines to crash. So here we detect and flag that
279 * situation and bail out early.
280 */
281 if (unlikely(list_empty(&pci_devices))) {
282 printk(KERN_NOTICE "pci_get_subsys() called while pci_devices "
283 "is still empty\n");
284 return NULL;
285 }
262 down_read(&pci_bus_sem); 286 down_read(&pci_bus_sem);
263 n = from ? from->global_list.next : pci_devices.next; 287 n = from ? from->global_list.next : pci_devices.next;
264 288