diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/Kconfig | 2 | ||||
-rw-r--r-- | drivers/pci/pci.c | 3 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 16 | ||||
-rw-r--r-- | drivers/pci/search.c | 24 |
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 | ||
20 | config PCI_MULTITHREAD_PROBE | 20 | config 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 | */ |
958 | static int __initdata asus_hides_smbus; | 958 | static int asus_hides_smbus; |
959 | 959 | ||
960 | static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) | 960 | static 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 | |||
1117 | static void quirk_sis_96x_smbus(struct pci_dev *dev) | 1117 | static 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 | ||
1162 | static void __init quirk_sis_96x_compatible(struct pci_dev *dev) | 1164 | static 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 | ||