diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-18 20:50:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-18 20:50:40 -0400 |
commit | b6aefcce747b3bc54d701d3c329416d0c9616f10 (patch) | |
tree | 18340f3dea5abf9f1c67b2ff0e0e4941a432b46e | |
parent | 65740356ccfa66703e7e0d47fbe372ba5193916b (diff) | |
parent | 7a54f25cef6c763f16c9fd49ae382de162147873 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/pci-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/pci-2.6: (22 commits)
PCI Hotplug: move pci_hotplug.h to include/linux/
change pci hotplug subsystem maintainer to Kristen
PCI: optionally sort device lists breadth-first
cpcihp_generic: prevent loading without "bridge" parameter
pci: Additional search functions
PCI: quirks: switch quirks code offender to use pci_get API
PCI: Update MSI-HOWTO.txt according to pci_msi_supported()
PCI: Improve pci_msi_supported() comments
PCI hotplug: ioremap balanced with iounmap
shpchp: remove unnecessary cmd_busy member from struct controller
shpchp: fix command completion check
pci: Stamp out pci_find_* usage in fakephp
PCI: fix pcie_portdrv_restore_config undefined without CONFIG_PM error
Fix DMA resource allocation in ACPIPnP
PCI: Turn pci_fixup_video into generic for embedded VGA
PCI: add ICH7/8 ACPI/GPIO io resource quirks
PCI: pcie-check-and-return-bus_register-errors fix
PCI: VIA IRQ quirk behaviour change
pciehp: Remove unnecessary check in pciehp_ctrl.c
pciehp - add missing locking
...
44 files changed, 584 insertions, 203 deletions
diff --git a/Documentation/MSI-HOWTO.txt b/Documentation/MSI-HOWTO.txt index c70306abb7b2..5c34910665d1 100644 --- a/Documentation/MSI-HOWTO.txt +++ b/Documentation/MSI-HOWTO.txt | |||
@@ -470,7 +470,68 @@ LOC: 324553 325068 | |||
470 | ERR: 0 | 470 | ERR: 0 |
471 | MIS: 0 | 471 | MIS: 0 |
472 | 472 | ||
473 | 6. FAQ | 473 | 6. MSI quirks |
474 | |||
475 | Several PCI chipsets or devices are known to not support MSI. | ||
476 | The PCI stack provides 3 possible levels of MSI disabling: | ||
477 | * on a single device | ||
478 | * on all devices behind a specific bridge | ||
479 | * globally | ||
480 | |||
481 | 6.1. Disabling MSI on a single device | ||
482 | |||
483 | Under some circumstances, it might be required to disable MSI on a | ||
484 | single device, It may be achived by either not calling pci_enable_msi() | ||
485 | or all, or setting the pci_dev->no_msi flag before (most of the time | ||
486 | in a quirk). | ||
487 | |||
488 | 6.2. Disabling MSI below a bridge | ||
489 | |||
490 | The vast majority of MSI quirks are required by PCI bridges not | ||
491 | being able to route MSI between busses. In this case, MSI have to be | ||
492 | disabled on all devices behind this bridge. It is achieves by setting | ||
493 | the PCI_BUS_FLAGS_NO_MSI flag in the pci_bus->bus_flags of the bridge | ||
494 | subordinate bus. There is no need to set the same flag on bridges that | ||
495 | are below the broken brigde. When pci_enable_msi() is called to enable | ||
496 | MSI on a device, pci_msi_supported() takes care of checking the NO_MSI | ||
497 | flag in all parent busses of the device. | ||
498 | |||
499 | Some bridges actually support dynamic MSI support enabling/disabling | ||
500 | by changing some bits in their PCI configuration space (especially | ||
501 | the Hypertransport chipsets such as the nVidia nForce and Serverworks | ||
502 | HT2000). It may then be required to update the NO_MSI flag on the | ||
503 | corresponding devices in the sysfs hierarchy. To enable MSI support | ||
504 | on device "0000:00:0e", do: | ||
505 | |||
506 | echo 1 > /sys/bus/pci/devices/0000:00:0e/msi_bus | ||
507 | |||
508 | To disable MSI support, echo 0 instead of 1. Note that it should be | ||
509 | used with caution since changing this value might break interrupts. | ||
510 | |||
511 | 6.3. Disabling MSI globally | ||
512 | |||
513 | Some extreme cases may require to disable MSI globally on the system. | ||
514 | For now, the only known case is a Serverworks PCI-X chipsets (MSI are | ||
515 | not supported on several busses that are not all connected to the | ||
516 | chipset in the Linux PCI hierarchy). In the vast majority of other | ||
517 | cases, disabling only behind a specific bridge is enough. | ||
518 | |||
519 | For debugging purpose, the user may also pass pci=nomsi on the kernel | ||
520 | command-line to explicitly disable MSI globally. But, once the appro- | ||
521 | priate quirks are added to the kernel, this option should not be | ||
522 | required anymore. | ||
523 | |||
524 | 6.4. Finding why MSI cannot be enabled on a device | ||
525 | |||
526 | Assuming that MSI are not enabled on a device, you should look at | ||
527 | dmesg to find messages that quirks may output when disabling MSI | ||
528 | on some devices, some bridges or even globally. | ||
529 | Then, lspci -t gives the list of bridges above a device. Reading | ||
530 | /sys/bus/pci/devices/0000:00:0e/msi_bus will tell you whether MSI | ||
531 | are enabled (1) or disabled (0). In 0 is found in a single bridge | ||
532 | msi_bus file above the device, MSI cannot be enabled. | ||
533 | |||
534 | 7. FAQ | ||
474 | 535 | ||
475 | Q1. Are there any limitations on using the MSI? | 536 | Q1. Are there any limitations on using the MSI? |
476 | 537 | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index ff571f9298e0..dd00fd556a60 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1231,6 +1231,11 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1231 | machine check when some devices' config space | 1231 | machine check when some devices' config space |
1232 | is read. But various workarounds are disabled | 1232 | is read. But various workarounds are disabled |
1233 | and some IOMMU drivers will not work. | 1233 | and some IOMMU drivers will not work. |
1234 | bfsort Sort PCI devices into breadth-first order. | ||
1235 | This sorting is done to get a device | ||
1236 | order compatible with older (<= 2.4) kernels. | ||
1237 | nobfsort Don't sort PCI devices into breadth-first order. | ||
1238 | |||
1234 | pcmv= [HW,PCMCIA] BadgePAD 4 | 1239 | pcmv= [HW,PCMCIA] BadgePAD 4 |
1235 | 1240 | ||
1236 | pd. [PARIDE] | 1241 | pd. [PARIDE] |
diff --git a/MAINTAINERS b/MAINTAINERS index 5305dd69095b..9b6b88268d3f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2309,8 +2309,8 @@ T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ | |||
2309 | S: Supported | 2309 | S: Supported |
2310 | 2310 | ||
2311 | PCI HOTPLUG CORE | 2311 | PCI HOTPLUG CORE |
2312 | P: Greg Kroah-Hartman | 2312 | P: Kristen Carlson Accardi |
2313 | M: gregkh@suse.de | 2313 | M: kristen.c.accardi@intel.com |
2314 | S: Supported | 2314 | S: Supported |
2315 | 2315 | ||
2316 | PCI HOTPLUG COMPAQ DRIVER | 2316 | PCI HOTPLUG COMPAQ DRIVER |
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 68bce194e688..6d5ace845e44 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -20,6 +20,7 @@ | |||
20 | unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | | 20 | unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | |
21 | PCI_PROBE_MMCONF; | 21 | PCI_PROBE_MMCONF; |
22 | 22 | ||
23 | int pci_bf_sort; | ||
23 | int pci_routeirq; | 24 | int pci_routeirq; |
24 | int pcibios_last_bus = -1; | 25 | int pcibios_last_bus = -1; |
25 | unsigned long pirq_table_addr; | 26 | unsigned long pirq_table_addr; |
@@ -118,6 +119,20 @@ void __devinit pcibios_fixup_bus(struct pci_bus *b) | |||
118 | } | 119 | } |
119 | 120 | ||
120 | /* | 121 | /* |
122 | * Only use DMI information to set this if nothing was passed | ||
123 | * on the kernel command line (which was parsed earlier). | ||
124 | */ | ||
125 | |||
126 | static int __devinit set_bf_sort(struct dmi_system_id *d) | ||
127 | { | ||
128 | if (pci_bf_sort == pci_bf_sort_default) { | ||
129 | pci_bf_sort = pci_dmi_bf; | ||
130 | printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident); | ||
131 | } | ||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | /* | ||
121 | * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) | 136 | * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) |
122 | */ | 137 | */ |
123 | #ifdef __i386__ | 138 | #ifdef __i386__ |
@@ -130,11 +145,11 @@ static int __devinit assign_all_busses(struct dmi_system_id *d) | |||
130 | } | 145 | } |
131 | #endif | 146 | #endif |
132 | 147 | ||
148 | static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { | ||
149 | #ifdef __i386__ | ||
133 | /* | 150 | /* |
134 | * Laptops which need pci=assign-busses to see Cardbus cards | 151 | * Laptops which need pci=assign-busses to see Cardbus cards |
135 | */ | 152 | */ |
136 | static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { | ||
137 | #ifdef __i386__ | ||
138 | { | 153 | { |
139 | .callback = assign_all_busses, | 154 | .callback = assign_all_busses, |
140 | .ident = "Samsung X20 Laptop", | 155 | .ident = "Samsung X20 Laptop", |
@@ -144,6 +159,38 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { | |||
144 | }, | 159 | }, |
145 | }, | 160 | }, |
146 | #endif /* __i386__ */ | 161 | #endif /* __i386__ */ |
162 | { | ||
163 | .callback = set_bf_sort, | ||
164 | .ident = "Dell PowerEdge 1950", | ||
165 | .matches = { | ||
166 | DMI_MATCH(DMI_SYS_VENDOR, "Dell"), | ||
167 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"), | ||
168 | }, | ||
169 | }, | ||
170 | { | ||
171 | .callback = set_bf_sort, | ||
172 | .ident = "Dell PowerEdge 1955", | ||
173 | .matches = { | ||
174 | DMI_MATCH(DMI_SYS_VENDOR, "Dell"), | ||
175 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"), | ||
176 | }, | ||
177 | }, | ||
178 | { | ||
179 | .callback = set_bf_sort, | ||
180 | .ident = "Dell PowerEdge 2900", | ||
181 | .matches = { | ||
182 | DMI_MATCH(DMI_SYS_VENDOR, "Dell"), | ||
183 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"), | ||
184 | }, | ||
185 | }, | ||
186 | { | ||
187 | .callback = set_bf_sort, | ||
188 | .ident = "Dell PowerEdge 2950", | ||
189 | .matches = { | ||
190 | DMI_MATCH(DMI_SYS_VENDOR, "Dell"), | ||
191 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"), | ||
192 | }, | ||
193 | }, | ||
147 | {} | 194 | {} |
148 | }; | 195 | }; |
149 | 196 | ||
@@ -189,6 +236,8 @@ static int __init pcibios_init(void) | |||
189 | 236 | ||
190 | pcibios_resource_survey(); | 237 | pcibios_resource_survey(); |
191 | 238 | ||
239 | if (pci_bf_sort >= pci_force_bf) | ||
240 | pci_sort_breadthfirst(); | ||
192 | #ifdef CONFIG_PCI_BIOS | 241 | #ifdef CONFIG_PCI_BIOS |
193 | if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) | 242 | if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) |
194 | pcibios_sort(); | 243 | pcibios_sort(); |
@@ -203,6 +252,12 @@ char * __devinit pcibios_setup(char *str) | |||
203 | if (!strcmp(str, "off")) { | 252 | if (!strcmp(str, "off")) { |
204 | pci_probe = 0; | 253 | pci_probe = 0; |
205 | return NULL; | 254 | return NULL; |
255 | } else if (!strcmp(str, "bfsort")) { | ||
256 | pci_bf_sort = pci_force_bf; | ||
257 | return NULL; | ||
258 | } else if (!strcmp(str, "nobfsort")) { | ||
259 | pci_bf_sort = pci_force_nobf; | ||
260 | return NULL; | ||
206 | } | 261 | } |
207 | #ifdef CONFIG_PCI_BIOS | 262 | #ifdef CONFIG_PCI_BIOS |
208 | else if (!strcmp(str, "bios")) { | 263 | else if (!strcmp(str, "bios")) { |
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index b60d7e8689ed..908b410f4c93 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c | |||
@@ -343,51 +343,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC, pcie_ro | |||
343 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_rootport_aspm_quirk ); | 343 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_rootport_aspm_quirk ); |
344 | 344 | ||
345 | /* | 345 | /* |
346 | * Fixup to mark boot BIOS video selected by BIOS before it changes | ||
347 | * | ||
348 | * From information provided by "Jon Smirl" <jonsmirl@gmail.com> | ||
349 | * | ||
350 | * The standard boot ROM sequence for an x86 machine uses the BIOS | ||
351 | * to select an initial video card for boot display. This boot video | ||
352 | * card will have it's BIOS copied to C0000 in system RAM. | ||
353 | * IORESOURCE_ROM_SHADOW is used to associate the boot video | ||
354 | * card with this copy. On laptops this copy has to be used since | ||
355 | * the main ROM may be compressed or combined with another image. | ||
356 | * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW | ||
357 | * is marked here since the boot video device will be the only enabled | ||
358 | * video device at this point. | ||
359 | */ | ||
360 | |||
361 | static void __devinit pci_fixup_video(struct pci_dev *pdev) | ||
362 | { | ||
363 | struct pci_dev *bridge; | ||
364 | struct pci_bus *bus; | ||
365 | u16 config; | ||
366 | |||
367 | if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
368 | return; | ||
369 | |||
370 | /* Is VGA routed to us? */ | ||
371 | bus = pdev->bus; | ||
372 | while (bus) { | ||
373 | bridge = bus->self; | ||
374 | if (bridge) { | ||
375 | pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, | ||
376 | &config); | ||
377 | if (!(config & PCI_BRIDGE_CTL_VGA)) | ||
378 | return; | ||
379 | } | ||
380 | bus = bus->parent; | ||
381 | } | ||
382 | pci_read_config_word(pdev, PCI_COMMAND, &config); | ||
383 | if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { | ||
384 | pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; | ||
385 | printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); | ||
386 | } | ||
387 | } | ||
388 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); | ||
389 | |||
390 | /* | ||
391 | * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A. | 346 | * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A. |
392 | * | 347 | * |
393 | * We pretend to bring them out of full D3 state, and restore the proper | 348 | * We pretend to bring them out of full D3 state, and restore the proper |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index 1814f74569c6..ad065cebd7b9 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -30,6 +30,13 @@ | |||
30 | extern unsigned int pci_probe; | 30 | extern unsigned int pci_probe; |
31 | extern unsigned long pirq_table_addr; | 31 | extern unsigned long pirq_table_addr; |
32 | 32 | ||
33 | enum pci_bf_sort_state { | ||
34 | pci_bf_sort_default, | ||
35 | pci_force_nobf, | ||
36 | pci_force_bf, | ||
37 | pci_dmi_bf, | ||
38 | }; | ||
39 | |||
33 | /* pci-i386.c */ | 40 | /* pci-i386.c */ |
34 | 41 | ||
35 | extern unsigned int pcibios_max_latency; | 42 | extern unsigned int pcibios_max_latency; |
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 51cb9f817c22..270a33cc08f6 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -29,10 +29,10 @@ | |||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <linux/pci_hotplug.h> | ||
32 | #include <acpi/acpi.h> | 33 | #include <acpi/acpi.h> |
33 | #include <acpi/acpi_bus.h> | 34 | #include <acpi/acpi_bus.h> |
34 | #include <acpi/actypes.h> | 35 | #include <acpi/actypes.h> |
35 | #include "pci_hotplug.h" | ||
36 | 36 | ||
37 | #define MY_NAME "acpi_pcihp" | 37 | #define MY_NAME "acpi_pcihp" |
38 | 38 | ||
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 7fff07e877c7..59c5b242d86d 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/acpi.h> | 38 | #include <linux/acpi.h> |
39 | #include <linux/kobject.h> /* for KOBJ_NAME_LEN */ | 39 | #include <linux/kobject.h> /* for KOBJ_NAME_LEN */ |
40 | #include <linux/mutex.h> | 40 | #include <linux/mutex.h> |
41 | #include "pci_hotplug.h" | 41 | #include <linux/pci_hotplug.h> |
42 | 42 | ||
43 | #define dbg(format, arg...) \ | 43 | #define dbg(format, arg...) \ |
44 | do { \ | 44 | do { \ |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index e2fef60c2d06..c57d9d5ce84e 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -37,10 +37,10 @@ | |||
37 | 37 | ||
38 | #include <linux/kernel.h> | 38 | #include <linux/kernel.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/pci_hotplug.h> | ||
40 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
41 | #include <linux/smp.h> | 42 | #include <linux/smp.h> |
42 | #include <linux/smp_lock.h> | 43 | #include <linux/smp_lock.h> |
43 | #include "pci_hotplug.h" | ||
44 | #include "acpiphp.h" | 44 | #include "acpiphp.h" |
45 | 45 | ||
46 | #define MY_NAME "acpiphp" | 46 | #define MY_NAME "acpiphp" |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 83e8e4412de5..c44311ac2fd3 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -45,11 +45,11 @@ | |||
45 | 45 | ||
46 | #include <linux/kernel.h> | 46 | #include <linux/kernel.h> |
47 | #include <linux/pci.h> | 47 | #include <linux/pci.h> |
48 | #include <linux/pci_hotplug.h> | ||
48 | #include <linux/smp_lock.h> | 49 | #include <linux/smp_lock.h> |
49 | #include <linux/mutex.h> | 50 | #include <linux/mutex.h> |
50 | 51 | ||
51 | #include "../pci.h" | 52 | #include "../pci.h" |
52 | #include "pci_hotplug.h" | ||
53 | #include "acpiphp.h" | 53 | #include "acpiphp.h" |
54 | 54 | ||
55 | static LIST_HEAD(bridge_list); | 55 | static LIST_HEAD(bridge_list); |
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index d0a07d9ab30c..bd40aee10e16 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/moduleparam.h> | 35 | #include <linux/moduleparam.h> |
36 | 36 | ||
37 | #include "acpiphp.h" | 37 | #include "acpiphp.h" |
38 | #include "pci_hotplug.h" | ||
39 | 38 | ||
40 | #define DRIVER_VERSION "1.0.1" | 39 | #define DRIVER_VERSION "1.0.1" |
41 | #define DRIVER_AUTHOR "Irene Zubarev <zubarev@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>" | 40 | #define DRIVER_AUTHOR "Irene Zubarev <zubarev@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>" |
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index d06ab4045134..684551559d44 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -29,12 +29,12 @@ | |||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <linux/pci_hotplug.h> | ||
32 | #include <linux/init.h> | 33 | #include <linux/init.h> |
33 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
34 | #include <linux/smp_lock.h> | 35 | #include <linux/smp_lock.h> |
35 | #include <asm/atomic.h> | 36 | #include <asm/atomic.h> |
36 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
37 | #include "pci_hotplug.h" | ||
38 | #include "cpci_hotplug.h" | 38 | #include "cpci_hotplug.h" |
39 | 39 | ||
40 | #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" | 40 | #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" |
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 4afcaffd031c..7b1beaad2752 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -26,9 +26,9 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/pci_hotplug.h> | ||
29 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
30 | #include "../pci.h" | 31 | #include "../pci.h" |
31 | #include "pci_hotplug.h" | ||
32 | #include "cpci_hotplug.h" | 32 | #include "cpci_hotplug.h" |
33 | 33 | ||
34 | #define MY_NAME "cpci_hotplug" | 34 | #define MY_NAME "cpci_hotplug" |
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c index e847f0d6c7fe..f3852a6b74ea 100644 --- a/drivers/pci/hotplug/cpcihp_generic.c +++ b/drivers/pci/hotplug/cpcihp_generic.c | |||
@@ -84,7 +84,7 @@ static int __init validate_parameters(void) | |||
84 | 84 | ||
85 | if(!bridge) { | 85 | if(!bridge) { |
86 | info("not configured, disabling."); | 86 | info("not configured, disabling."); |
87 | return 1; | 87 | return -EINVAL; |
88 | } | 88 | } |
89 | str = bridge; | 89 | str = bridge; |
90 | if(!*str) | 90 | if(!*str) |
@@ -147,7 +147,7 @@ static int __init cpcihp_generic_init(void) | |||
147 | 147 | ||
148 | info(DRIVER_DESC " version: " DRIVER_VERSION); | 148 | info(DRIVER_DESC " version: " DRIVER_VERSION); |
149 | status = validate_parameters(); | 149 | status = validate_parameters(); |
150 | if(status != 0) | 150 | if (status) |
151 | return status; | 151 | return status; |
152 | 152 | ||
153 | r = request_region(port, 1, "#ENUM hotswap signal register"); | 153 | r = request_region(port, 1, "#ENUM hotswap signal register"); |
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index ea040c32f47d..298ad7f3f4f4 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h | |||
@@ -28,7 +28,6 @@ | |||
28 | #ifndef _CPQPHP_H | 28 | #ifndef _CPQPHP_H |
29 | #define _CPQPHP_H | 29 | #define _CPQPHP_H |
30 | 30 | ||
31 | #include "pci_hotplug.h" | ||
32 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
33 | #include <asm/io.h> /* for read? and write? functions */ | 32 | #include <asm/io.h> /* for read? and write? functions */ |
34 | #include <linux/delay.h> /* for delays */ | 33 | #include <linux/delay.h> /* for delays */ |
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 1fc259913b68..5617cfdadc5c 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/workqueue.h> | 38 | #include <linux/workqueue.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/pci_hotplug.h> | ||
40 | #include <linux/init.h> | 41 | #include <linux/init.h> |
41 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
42 | 43 | ||
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 3ec2ad7db49a..79ff6b4de3a6 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/wait.h> | 36 | #include <linux/wait.h> |
37 | #include <linux/smp_lock.h> | 37 | #include <linux/smp_lock.h> |
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/pci_hotplug.h> | ||
39 | #include "cpqphp.h" | 40 | #include "cpqphp.h" |
40 | 41 | ||
41 | static u32 configure_new_device(struct controller* ctrl, struct pci_func *func, | 42 | static u32 configure_new_device(struct controller* ctrl, struct pci_func *func, |
diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c index cf0878917537..298a6cfd8406 100644 --- a/drivers/pci/hotplug/cpqphp_nvram.c +++ b/drivers/pci/hotplug/cpqphp_nvram.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/pci_hotplug.h> | ||
36 | #include <linux/init.h> | 37 | #include <linux/init.h> |
37 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
38 | #include "cpqphp.h" | 39 | #include "cpqphp.h" |
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 0d9688952f4a..fc7c74d72595 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/workqueue.h> | 33 | #include <linux/workqueue.h> |
34 | #include <linux/proc_fs.h> | 34 | #include <linux/proc_fs.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/pci_hotplug.h> | ||
36 | #include "../pci.h" | 37 | #include "../pci.h" |
37 | #include "cpqphp.h" | 38 | #include "cpqphp.h" |
38 | #include "cpqphp_nvram.h" | 39 | #include "cpqphp_nvram.h" |
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index 5bab666cd67e..634f74d919d3 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/proc_fs.h> | 32 | #include <linux/proc_fs.h> |
33 | #include <linux/workqueue.h> | 33 | #include <linux/workqueue.h> |
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include <linux/pci_hotplug.h> | ||
35 | #include <linux/debugfs.h> | 36 | #include <linux/debugfs.h> |
36 | #include "cpqphp.h" | 37 | #include "cpqphp.h" |
37 | 38 | ||
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 05a4f0f90186..e27907c91d92 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -35,10 +35,10 @@ | |||
35 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
38 | #include <linux/pci_hotplug.h> | ||
38 | #include <linux/init.h> | 39 | #include <linux/init.h> |
39 | #include <linux/string.h> | 40 | #include <linux/string.h> |
40 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
41 | #include "pci_hotplug.h" | ||
42 | #include "../pci.h" | 42 | #include "../pci.h" |
43 | 43 | ||
44 | #if !defined(MODULE) | 44 | #if !defined(MODULE) |
@@ -181,7 +181,9 @@ static void pci_rescan_slot(struct pci_dev *temp) | |||
181 | 181 | ||
182 | if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { | 182 | if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { |
183 | temp->hdr_type = hdr_type & 0x7f; | 183 | temp->hdr_type = hdr_type & 0x7f; |
184 | if (!pci_find_slot(bus->number, temp->devfn)) { | 184 | if ((dev = pci_get_slot(bus, temp->devfn)) != NULL) |
185 | pci_dev_put(dev); | ||
186 | else { | ||
185 | dev = pci_scan_single_device(bus, temp->devfn); | 187 | dev = pci_scan_single_device(bus, temp->devfn); |
186 | if (dev) { | 188 | if (dev) { |
187 | dbg("New device on %s function %x:%x\n", | 189 | dbg("New device on %s function %x:%x\n", |
@@ -205,7 +207,9 @@ static void pci_rescan_slot(struct pci_dev *temp) | |||
205 | continue; | 207 | continue; |
206 | temp->hdr_type = hdr_type & 0x7f; | 208 | temp->hdr_type = hdr_type & 0x7f; |
207 | 209 | ||
208 | if (!pci_find_slot(bus->number, temp->devfn)) { | 210 | if ((dev = pci_get_slot(bus, temp->devfn)) != NULL) |
211 | pci_dev_put(dev); | ||
212 | else { | ||
209 | dev = pci_scan_single_device(bus, temp->devfn); | 213 | dev = pci_scan_single_device(bus, temp->devfn); |
210 | if (dev) { | 214 | if (dev) { |
211 | dbg("New device on %s function %x:%x\n", | 215 | dbg("New device on %s function %x:%x\n", |
@@ -305,7 +309,7 @@ static int disable_slot(struct hotplug_slot *slot) | |||
305 | /* search for subfunctions and disable them first */ | 309 | /* search for subfunctions and disable them first */ |
306 | if (!(dslot->dev->devfn & 7)) { | 310 | if (!(dslot->dev->devfn & 7)) { |
307 | for (func = 1; func < 8; func++) { | 311 | for (func = 1; func < 8; func++) { |
308 | dev = pci_find_slot(dslot->dev->bus->number, | 312 | dev = pci_get_slot(dslot->dev->bus, |
309 | dslot->dev->devfn + func); | 313 | dslot->dev->devfn + func); |
310 | if (dev) { | 314 | if (dev) { |
311 | hslot = get_slot_from_dev(dev); | 315 | hslot = get_slot_from_dev(dev); |
@@ -315,6 +319,7 @@ static int disable_slot(struct hotplug_slot *slot) | |||
315 | err("Hotplug slot not found for subfunction of PCI device\n"); | 319 | err("Hotplug slot not found for subfunction of PCI device\n"); |
316 | return -ENODEV; | 320 | return -ENODEV; |
317 | } | 321 | } |
322 | pci_dev_put(dev); | ||
318 | } else | 323 | } else |
319 | dbg("No device in slot found\n"); | 324 | dbg("No device in slot found\n"); |
320 | } | 325 | } |
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h index dba6d8ca9bda..612d96301509 100644 --- a/drivers/pci/hotplug/ibmphp.h +++ b/drivers/pci/hotplug/ibmphp.h | |||
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include "pci_hotplug.h" | 33 | #include <linux/pci_hotplug.h> |
34 | 34 | ||
35 | extern int ibmphp_debug; | 35 | extern int ibmphp_debug; |
36 | 36 | ||
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index e2823ea9c4ed..f5d632e72323 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -21,9 +21,7 @@ | |||
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
23 | * | 23 | * |
24 | * Send feedback to <greg@kroah.com> | 24 | * Send feedback to <kristen.c.accardi@intel.com> |
25 | * | ||
26 | * Filesystem portion based on work done by Pat Mochel on ddfs/driverfs | ||
27 | * | 25 | * |
28 | */ | 26 | */ |
29 | 27 | ||
@@ -32,6 +30,8 @@ | |||
32 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
33 | #include <linux/types.h> | 31 | #include <linux/types.h> |
34 | #include <linux/list.h> | 32 | #include <linux/list.h> |
33 | #include <linux/kobject.h> | ||
34 | #include <linux/sysfs.h> | ||
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/smp_lock.h> | 37 | #include <linux/smp_lock.h> |
@@ -39,11 +39,8 @@ | |||
39 | #include <linux/mount.h> | 39 | #include <linux/mount.h> |
40 | #include <linux/namei.h> | 40 | #include <linux/namei.h> |
41 | #include <linux/pci.h> | 41 | #include <linux/pci.h> |
42 | #include <linux/pci_hotplug.h> | ||
42 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
43 | #include <linux/kobject.h> | ||
44 | #include <linux/sysfs.h> | ||
45 | #include "pci_hotplug.h" | ||
46 | |||
47 | 44 | ||
48 | #define MY_NAME "pci_hotplug" | 45 | #define MY_NAME "pci_hotplug" |
49 | 46 | ||
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index eaea9d36a1bb..4fb12fcda563 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -31,11 +31,11 @@ | |||
31 | 31 | ||
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/pci_hotplug.h> | ||
34 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
35 | #include <linux/sched.h> /* signal_pending() */ | 36 | #include <linux/sched.h> /* signal_pending() */ |
36 | #include <linux/pcieport_if.h> | 37 | #include <linux/pcieport_if.h> |
37 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
38 | #include "pci_hotplug.h" | ||
39 | 39 | ||
40 | #define MY_NAME "pciehp" | 40 | #define MY_NAME "pciehp" |
41 | 41 | ||
@@ -92,6 +92,7 @@ struct php_ctlr_state_s { | |||
92 | struct controller { | 92 | struct controller { |
93 | struct controller *next; | 93 | struct controller *next; |
94 | struct mutex crit_sect; /* critical section mutex */ | 94 | struct mutex crit_sect; /* critical section mutex */ |
95 | struct mutex ctrl_lock; /* controller lock */ | ||
95 | struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ | 96 | struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ |
96 | int num_slots; /* Number of slots on ctlr */ | 97 | int num_slots; /* Number of slots on ctlr */ |
97 | int slot_num_inc; /* 1 or -1 */ | 98 | int slot_num_inc; /* 1 or -1 */ |
@@ -166,10 +167,10 @@ struct controller { | |||
166 | * error Messages | 167 | * error Messages |
167 | */ | 168 | */ |
168 | #define msg_initialization_err "Initialization failure, error=%d\n" | 169 | #define msg_initialization_err "Initialization failure, error=%d\n" |
169 | #define msg_button_on "PCI slot #%d - powering on due to button press.\n" | 170 | #define msg_button_on "PCI slot #%s - powering on due to button press.\n" |
170 | #define msg_button_off "PCI slot #%d - powering off due to button press.\n" | 171 | #define msg_button_off "PCI slot #%s - powering off due to button press.\n" |
171 | #define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n" | 172 | #define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" |
172 | #define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n" | 173 | #define msg_button_ignore "PCI slot #%s - button press ignored. (action in progress...)\n" |
173 | 174 | ||
174 | /* controller functions */ | 175 | /* controller functions */ |
175 | extern int pciehp_event_start_thread (void); | 176 | extern int pciehp_event_start_thread (void); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index c67b7c3f1ddf..f93e81e2d2c7 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -448,7 +448,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
448 | } | 448 | } |
449 | 449 | ||
450 | /* Wait for exclusive access to hardware */ | 450 | /* Wait for exclusive access to hardware */ |
451 | mutex_lock(&ctrl->crit_sect); | 451 | mutex_lock(&ctrl->ctrl_lock); |
452 | 452 | ||
453 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ | 453 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ |
454 | 454 | ||
@@ -456,7 +456,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
456 | rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ | 456 | rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ |
457 | if (rc) { | 457 | if (rc) { |
458 | /* Done with exclusive hardware access */ | 458 | /* Done with exclusive hardware access */ |
459 | mutex_unlock(&ctrl->crit_sect); | 459 | mutex_unlock(&ctrl->ctrl_lock); |
460 | goto err_out_free_ctrl_slot; | 460 | goto err_out_free_ctrl_slot; |
461 | } else | 461 | } else |
462 | /* Wait for the command to complete */ | 462 | /* Wait for the command to complete */ |
@@ -464,7 +464,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
464 | } | 464 | } |
465 | 465 | ||
466 | /* Done with exclusive hardware access */ | 466 | /* Done with exclusive hardware access */ |
467 | mutex_unlock(&ctrl->crit_sect); | 467 | mutex_unlock(&ctrl->ctrl_lock); |
468 | 468 | ||
469 | return 0; | 469 | return 0; |
470 | 470 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 41290a106bd8..372c63e35aa9 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -43,6 +43,11 @@ static int event_finished; | |||
43 | static unsigned long pushbutton_pending; /* = 0 */ | 43 | static unsigned long pushbutton_pending; /* = 0 */ |
44 | static unsigned long surprise_rm_pending; /* = 0 */ | 44 | static unsigned long surprise_rm_pending; /* = 0 */ |
45 | 45 | ||
46 | static inline char *slot_name(struct slot *p_slot) | ||
47 | { | ||
48 | return p_slot->hotplug_slot->name; | ||
49 | } | ||
50 | |||
46 | u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) | 51 | u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) |
47 | { | 52 | { |
48 | struct controller *ctrl = (struct controller *) inst_id; | 53 | struct controller *ctrl = (struct controller *) inst_id; |
@@ -68,7 +73,7 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) | |||
68 | /* | 73 | /* |
69 | * Button pressed - See if need to TAKE ACTION!!! | 74 | * Button pressed - See if need to TAKE ACTION!!! |
70 | */ | 75 | */ |
71 | info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot); | 76 | info("Button pressed on Slot(%s)\n", slot_name(p_slot)); |
72 | taskInfo->event_type = INT_BUTTON_PRESS; | 77 | taskInfo->event_type = INT_BUTTON_PRESS; |
73 | 78 | ||
74 | if ((p_slot->state == BLINKINGON_STATE) | 79 | if ((p_slot->state == BLINKINGON_STATE) |
@@ -78,7 +83,7 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) | |||
78 | * or hot-remove | 83 | * or hot-remove |
79 | */ | 84 | */ |
80 | taskInfo->event_type = INT_BUTTON_CANCEL; | 85 | taskInfo->event_type = INT_BUTTON_CANCEL; |
81 | info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot); | 86 | info("Button cancel on Slot(%s)\n", slot_name(p_slot)); |
82 | } else if ((p_slot->state == POWERON_STATE) | 87 | } else if ((p_slot->state == POWERON_STATE) |
83 | || (p_slot->state == POWEROFF_STATE)) { | 88 | || (p_slot->state == POWEROFF_STATE)) { |
84 | /* Ignore if the slot is on power-on or power-off state; this | 89 | /* Ignore if the slot is on power-on or power-off state; this |
@@ -86,7 +91,7 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) | |||
86 | * hot-remove is undergoing | 91 | * hot-remove is undergoing |
87 | */ | 92 | */ |
88 | taskInfo->event_type = INT_BUTTON_IGNORE; | 93 | taskInfo->event_type = INT_BUTTON_IGNORE; |
89 | info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot); | 94 | info("Button ignore on Slot(%s)\n", slot_name(p_slot)); |
90 | } | 95 | } |
91 | 96 | ||
92 | if (rc) | 97 | if (rc) |
@@ -122,13 +127,13 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id) | |||
122 | /* | 127 | /* |
123 | * Switch opened | 128 | * Switch opened |
124 | */ | 129 | */ |
125 | info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); | 130 | info("Latch open on Slot(%s)\n", slot_name(p_slot)); |
126 | taskInfo->event_type = INT_SWITCH_OPEN; | 131 | taskInfo->event_type = INT_SWITCH_OPEN; |
127 | } else { | 132 | } else { |
128 | /* | 133 | /* |
129 | * Switch closed | 134 | * Switch closed |
130 | */ | 135 | */ |
131 | info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot); | 136 | info("Latch close on Slot(%s)\n", slot_name(p_slot)); |
132 | taskInfo->event_type = INT_SWITCH_CLOSE; | 137 | taskInfo->event_type = INT_SWITCH_CLOSE; |
133 | } | 138 | } |
134 | 139 | ||
@@ -166,13 +171,13 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id) | |||
166 | /* | 171 | /* |
167 | * Card Present | 172 | * Card Present |
168 | */ | 173 | */ |
169 | info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot); | 174 | info("Card present on Slot(%s)\n", slot_name(p_slot)); |
170 | taskInfo->event_type = INT_PRESENCE_ON; | 175 | taskInfo->event_type = INT_PRESENCE_ON; |
171 | } else { | 176 | } else { |
172 | /* | 177 | /* |
173 | * Not Present | 178 | * Not Present |
174 | */ | 179 | */ |
175 | info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot); | 180 | info("Card not present on Slot(%s)\n", slot_name(p_slot)); |
176 | taskInfo->event_type = INT_PRESENCE_OFF; | 181 | taskInfo->event_type = INT_PRESENCE_OFF; |
177 | } | 182 | } |
178 | 183 | ||
@@ -206,13 +211,13 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) | |||
206 | /* | 211 | /* |
207 | * power fault Cleared | 212 | * power fault Cleared |
208 | */ | 213 | */ |
209 | info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); | 214 | info("Power fault cleared on Slot(%s)\n", slot_name(p_slot)); |
210 | taskInfo->event_type = INT_POWER_FAULT_CLEAR; | 215 | taskInfo->event_type = INT_POWER_FAULT_CLEAR; |
211 | } else { | 216 | } else { |
212 | /* | 217 | /* |
213 | * power fault | 218 | * power fault |
214 | */ | 219 | */ |
215 | info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); | 220 | info("Power fault on Slot(%s)\n", slot_name(p_slot)); |
216 | taskInfo->event_type = INT_POWER_FAULT; | 221 | taskInfo->event_type = INT_POWER_FAULT; |
217 | info("power fault bit %x set\n", hp_slot); | 222 | info("power fault bit %x set\n", hp_slot); |
218 | } | 223 | } |
@@ -229,13 +234,13 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) | |||
229 | static void set_slot_off(struct controller *ctrl, struct slot * pslot) | 234 | static void set_slot_off(struct controller *ctrl, struct slot * pslot) |
230 | { | 235 | { |
231 | /* Wait for exclusive access to hardware */ | 236 | /* Wait for exclusive access to hardware */ |
232 | mutex_lock(&ctrl->crit_sect); | 237 | mutex_lock(&ctrl->ctrl_lock); |
233 | 238 | ||
234 | /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ | 239 | /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ |
235 | if (POWER_CTRL(ctrl->ctrlcap)) { | 240 | if (POWER_CTRL(ctrl->ctrlcap)) { |
236 | if (pslot->hpc_ops->power_off_slot(pslot)) { | 241 | if (pslot->hpc_ops->power_off_slot(pslot)) { |
237 | err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); | 242 | err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); |
238 | mutex_unlock(&ctrl->crit_sect); | 243 | mutex_unlock(&ctrl->ctrl_lock); |
239 | return; | 244 | return; |
240 | } | 245 | } |
241 | wait_for_ctrl_irq (ctrl); | 246 | wait_for_ctrl_irq (ctrl); |
@@ -249,14 +254,14 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) | |||
249 | if (ATTN_LED(ctrl->ctrlcap)) { | 254 | if (ATTN_LED(ctrl->ctrlcap)) { |
250 | if (pslot->hpc_ops->set_attention_status(pslot, 1)) { | 255 | if (pslot->hpc_ops->set_attention_status(pslot, 1)) { |
251 | err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); | 256 | err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); |
252 | mutex_unlock(&ctrl->crit_sect); | 257 | mutex_unlock(&ctrl->ctrl_lock); |
253 | return; | 258 | return; |
254 | } | 259 | } |
255 | wait_for_ctrl_irq (ctrl); | 260 | wait_for_ctrl_irq (ctrl); |
256 | } | 261 | } |
257 | 262 | ||
258 | /* Done with exclusive hardware access */ | 263 | /* Done with exclusive hardware access */ |
259 | mutex_unlock(&ctrl->crit_sect); | 264 | mutex_unlock(&ctrl->ctrl_lock); |
260 | } | 265 | } |
261 | 266 | ||
262 | /** | 267 | /** |
@@ -279,13 +284,13 @@ static int board_added(struct slot *p_slot) | |||
279 | ctrl->slot_device_offset, hp_slot); | 284 | ctrl->slot_device_offset, hp_slot); |
280 | 285 | ||
281 | /* Wait for exclusive access to hardware */ | 286 | /* Wait for exclusive access to hardware */ |
282 | mutex_lock(&ctrl->crit_sect); | 287 | mutex_lock(&ctrl->ctrl_lock); |
283 | 288 | ||
284 | if (POWER_CTRL(ctrl->ctrlcap)) { | 289 | if (POWER_CTRL(ctrl->ctrlcap)) { |
285 | /* Power on slot */ | 290 | /* Power on slot */ |
286 | rc = p_slot->hpc_ops->power_on_slot(p_slot); | 291 | rc = p_slot->hpc_ops->power_on_slot(p_slot); |
287 | if (rc) { | 292 | if (rc) { |
288 | mutex_unlock(&ctrl->crit_sect); | 293 | mutex_unlock(&ctrl->ctrl_lock); |
289 | return -1; | 294 | return -1; |
290 | } | 295 | } |
291 | 296 | ||
@@ -301,7 +306,7 @@ static int board_added(struct slot *p_slot) | |||
301 | } | 306 | } |
302 | 307 | ||
303 | /* Done with exclusive hardware access */ | 308 | /* Done with exclusive hardware access */ |
304 | mutex_unlock(&ctrl->crit_sect); | 309 | mutex_unlock(&ctrl->ctrl_lock); |
305 | 310 | ||
306 | /* Wait for ~1 second */ | 311 | /* Wait for ~1 second */ |
307 | wait_for_ctrl_irq (ctrl); | 312 | wait_for_ctrl_irq (ctrl); |
@@ -335,7 +340,7 @@ static int board_added(struct slot *p_slot) | |||
335 | pci_fixup_device(pci_fixup_final, ctrl->pci_dev); | 340 | pci_fixup_device(pci_fixup_final, ctrl->pci_dev); |
336 | if (PWR_LED(ctrl->ctrlcap)) { | 341 | if (PWR_LED(ctrl->ctrlcap)) { |
337 | /* Wait for exclusive access to hardware */ | 342 | /* Wait for exclusive access to hardware */ |
338 | mutex_lock(&ctrl->crit_sect); | 343 | mutex_lock(&ctrl->ctrl_lock); |
339 | 344 | ||
340 | p_slot->hpc_ops->green_led_on(p_slot); | 345 | p_slot->hpc_ops->green_led_on(p_slot); |
341 | 346 | ||
@@ -343,7 +348,7 @@ static int board_added(struct slot *p_slot) | |||
343 | wait_for_ctrl_irq (ctrl); | 348 | wait_for_ctrl_irq (ctrl); |
344 | 349 | ||
345 | /* Done with exclusive hardware access */ | 350 | /* Done with exclusive hardware access */ |
346 | mutex_unlock(&ctrl->crit_sect); | 351 | mutex_unlock(&ctrl->ctrl_lock); |
347 | } | 352 | } |
348 | return 0; | 353 | return 0; |
349 | 354 | ||
@@ -375,14 +380,14 @@ static int remove_board(struct slot *p_slot) | |||
375 | dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); | 380 | dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); |
376 | 381 | ||
377 | /* Wait for exclusive access to hardware */ | 382 | /* Wait for exclusive access to hardware */ |
378 | mutex_lock(&ctrl->crit_sect); | 383 | mutex_lock(&ctrl->ctrl_lock); |
379 | 384 | ||
380 | if (POWER_CTRL(ctrl->ctrlcap)) { | 385 | if (POWER_CTRL(ctrl->ctrlcap)) { |
381 | /* power off slot */ | 386 | /* power off slot */ |
382 | rc = p_slot->hpc_ops->power_off_slot(p_slot); | 387 | rc = p_slot->hpc_ops->power_off_slot(p_slot); |
383 | if (rc) { | 388 | if (rc) { |
384 | err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); | 389 | err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); |
385 | mutex_unlock(&ctrl->crit_sect); | 390 | mutex_unlock(&ctrl->ctrl_lock); |
386 | return rc; | 391 | return rc; |
387 | } | 392 | } |
388 | /* Wait for the command to complete */ | 393 | /* Wait for the command to complete */ |
@@ -398,7 +403,7 @@ static int remove_board(struct slot *p_slot) | |||
398 | } | 403 | } |
399 | 404 | ||
400 | /* Done with exclusive hardware access */ | 405 | /* Done with exclusive hardware access */ |
401 | mutex_unlock(&ctrl->crit_sect); | 406 | mutex_unlock(&ctrl->ctrl_lock); |
402 | 407 | ||
403 | return 0; | 408 | return 0; |
404 | } | 409 | } |
@@ -445,7 +450,7 @@ static void pciehp_pushbutton_thread(unsigned long slot) | |||
445 | 450 | ||
446 | if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { | 451 | if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { |
447 | /* Wait for exclusive access to hardware */ | 452 | /* Wait for exclusive access to hardware */ |
448 | mutex_lock(&p_slot->ctrl->crit_sect); | 453 | mutex_lock(&p_slot->ctrl->ctrl_lock); |
449 | 454 | ||
450 | p_slot->hpc_ops->green_led_off(p_slot); | 455 | p_slot->hpc_ops->green_led_off(p_slot); |
451 | 456 | ||
@@ -453,7 +458,7 @@ static void pciehp_pushbutton_thread(unsigned long slot) | |||
453 | wait_for_ctrl_irq (p_slot->ctrl); | 458 | wait_for_ctrl_irq (p_slot->ctrl); |
454 | 459 | ||
455 | /* Done with exclusive hardware access */ | 460 | /* Done with exclusive hardware access */ |
456 | mutex_unlock(&p_slot->ctrl->crit_sect); | 461 | mutex_unlock(&p_slot->ctrl->ctrl_lock); |
457 | } | 462 | } |
458 | p_slot->state = STATIC_STATE; | 463 | p_slot->state = STATIC_STATE; |
459 | } | 464 | } |
@@ -495,7 +500,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot) | |||
495 | 500 | ||
496 | if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { | 501 | if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { |
497 | /* Wait for exclusive access to hardware */ | 502 | /* Wait for exclusive access to hardware */ |
498 | mutex_lock(&p_slot->ctrl->crit_sect); | 503 | mutex_lock(&p_slot->ctrl->ctrl_lock); |
499 | 504 | ||
500 | p_slot->hpc_ops->green_led_off(p_slot); | 505 | p_slot->hpc_ops->green_led_off(p_slot); |
501 | 506 | ||
@@ -503,7 +508,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot) | |||
503 | wait_for_ctrl_irq (p_slot->ctrl); | 508 | wait_for_ctrl_irq (p_slot->ctrl); |
504 | 509 | ||
505 | /* Done with exclusive hardware access */ | 510 | /* Done with exclusive hardware access */ |
506 | mutex_unlock(&p_slot->ctrl->crit_sect); | 511 | mutex_unlock(&p_slot->ctrl->ctrl_lock); |
507 | } | 512 | } |
508 | p_slot->state = STATIC_STATE; | 513 | p_slot->state = STATIC_STATE; |
509 | } | 514 | } |
@@ -616,7 +621,7 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
616 | switch (p_slot->state) { | 621 | switch (p_slot->state) { |
617 | case BLINKINGOFF_STATE: | 622 | case BLINKINGOFF_STATE: |
618 | /* Wait for exclusive access to hardware */ | 623 | /* Wait for exclusive access to hardware */ |
619 | mutex_lock(&ctrl->crit_sect); | 624 | mutex_lock(&ctrl->ctrl_lock); |
620 | 625 | ||
621 | if (PWR_LED(ctrl->ctrlcap)) { | 626 | if (PWR_LED(ctrl->ctrlcap)) { |
622 | p_slot->hpc_ops->green_led_on(p_slot); | 627 | p_slot->hpc_ops->green_led_on(p_slot); |
@@ -630,11 +635,11 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
630 | wait_for_ctrl_irq (ctrl); | 635 | wait_for_ctrl_irq (ctrl); |
631 | } | 636 | } |
632 | /* Done with exclusive hardware access */ | 637 | /* Done with exclusive hardware access */ |
633 | mutex_unlock(&ctrl->crit_sect); | 638 | mutex_unlock(&ctrl->ctrl_lock); |
634 | break; | 639 | break; |
635 | case BLINKINGON_STATE: | 640 | case BLINKINGON_STATE: |
636 | /* Wait for exclusive access to hardware */ | 641 | /* Wait for exclusive access to hardware */ |
637 | mutex_lock(&ctrl->crit_sect); | 642 | mutex_lock(&ctrl->ctrl_lock); |
638 | 643 | ||
639 | if (PWR_LED(ctrl->ctrlcap)) { | 644 | if (PWR_LED(ctrl->ctrlcap)) { |
640 | p_slot->hpc_ops->green_led_off(p_slot); | 645 | p_slot->hpc_ops->green_led_off(p_slot); |
@@ -647,14 +652,14 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
647 | wait_for_ctrl_irq (ctrl); | 652 | wait_for_ctrl_irq (ctrl); |
648 | } | 653 | } |
649 | /* Done with exclusive hardware access */ | 654 | /* Done with exclusive hardware access */ |
650 | mutex_unlock(&ctrl->crit_sect); | 655 | mutex_unlock(&ctrl->ctrl_lock); |
651 | 656 | ||
652 | break; | 657 | break; |
653 | default: | 658 | default: |
654 | warn("Not a valid state\n"); | 659 | warn("Not a valid state\n"); |
655 | return; | 660 | return; |
656 | } | 661 | } |
657 | info(msg_button_cancel, p_slot->number); | 662 | info(msg_button_cancel, slot_name(p_slot)); |
658 | p_slot->state = STATIC_STATE; | 663 | p_slot->state = STATIC_STATE; |
659 | } | 664 | } |
660 | /* ***********Button Pressed (No action on 1st press...) */ | 665 | /* ***********Button Pressed (No action on 1st press...) */ |
@@ -667,16 +672,16 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
667 | /* slot is on */ | 672 | /* slot is on */ |
668 | dbg("slot is on\n"); | 673 | dbg("slot is on\n"); |
669 | p_slot->state = BLINKINGOFF_STATE; | 674 | p_slot->state = BLINKINGOFF_STATE; |
670 | info(msg_button_off, p_slot->number); | 675 | info(msg_button_off, slot_name(p_slot)); |
671 | } else { | 676 | } else { |
672 | /* slot is off */ | 677 | /* slot is off */ |
673 | dbg("slot is off\n"); | 678 | dbg("slot is off\n"); |
674 | p_slot->state = BLINKINGON_STATE; | 679 | p_slot->state = BLINKINGON_STATE; |
675 | info(msg_button_on, p_slot->number); | 680 | info(msg_button_on, slot_name(p_slot)); |
676 | } | 681 | } |
677 | 682 | ||
678 | /* Wait for exclusive access to hardware */ | 683 | /* Wait for exclusive access to hardware */ |
679 | mutex_lock(&ctrl->crit_sect); | 684 | mutex_lock(&ctrl->ctrl_lock); |
680 | 685 | ||
681 | /* blink green LED and turn off amber */ | 686 | /* blink green LED and turn off amber */ |
682 | if (PWR_LED(ctrl->ctrlcap)) { | 687 | if (PWR_LED(ctrl->ctrlcap)) { |
@@ -693,7 +698,7 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
693 | } | 698 | } |
694 | 699 | ||
695 | /* Done with exclusive hardware access */ | 700 | /* Done with exclusive hardware access */ |
696 | mutex_unlock(&ctrl->crit_sect); | 701 | mutex_unlock(&ctrl->ctrl_lock); |
697 | 702 | ||
698 | init_timer(&p_slot->task_event); | 703 | init_timer(&p_slot->task_event); |
699 | p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ | 704 | p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ |
@@ -708,7 +713,7 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
708 | if (POWER_CTRL(ctrl->ctrlcap)) { | 713 | if (POWER_CTRL(ctrl->ctrlcap)) { |
709 | dbg("power fault\n"); | 714 | dbg("power fault\n"); |
710 | /* Wait for exclusive access to hardware */ | 715 | /* Wait for exclusive access to hardware */ |
711 | mutex_lock(&ctrl->crit_sect); | 716 | mutex_lock(&ctrl->ctrl_lock); |
712 | 717 | ||
713 | if (ATTN_LED(ctrl->ctrlcap)) { | 718 | if (ATTN_LED(ctrl->ctrlcap)) { |
714 | p_slot->hpc_ops->set_attention_status(p_slot, 1); | 719 | p_slot->hpc_ops->set_attention_status(p_slot, 1); |
@@ -721,7 +726,7 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
721 | } | 726 | } |
722 | 727 | ||
723 | /* Done with exclusive hardware access */ | 728 | /* Done with exclusive hardware access */ |
724 | mutex_unlock(&ctrl->crit_sect); | 729 | mutex_unlock(&ctrl->ctrl_lock); |
725 | } | 730 | } |
726 | } | 731 | } |
727 | /***********SURPRISE REMOVAL********************/ | 732 | /***********SURPRISE REMOVAL********************/ |
@@ -760,14 +765,16 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
760 | 765 | ||
761 | rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); | 766 | rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); |
762 | if (rc || !getstatus) { | 767 | if (rc || !getstatus) { |
763 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); | 768 | info("%s: no adapter on slot(%s)\n", __FUNCTION__, |
769 | slot_name(p_slot)); | ||
764 | mutex_unlock(&p_slot->ctrl->crit_sect); | 770 | mutex_unlock(&p_slot->ctrl->crit_sect); |
765 | return -ENODEV; | 771 | return -ENODEV; |
766 | } | 772 | } |
767 | if (MRL_SENS(p_slot->ctrl->ctrlcap)) { | 773 | if (MRL_SENS(p_slot->ctrl->ctrlcap)) { |
768 | rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 774 | rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
769 | if (rc || getstatus) { | 775 | if (rc || getstatus) { |
770 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); | 776 | info("%s: latch open on slot(%s)\n", __FUNCTION__, |
777 | slot_name(p_slot)); | ||
771 | mutex_unlock(&p_slot->ctrl->crit_sect); | 778 | mutex_unlock(&p_slot->ctrl->crit_sect); |
772 | return -ENODEV; | 779 | return -ENODEV; |
773 | } | 780 | } |
@@ -776,12 +783,12 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
776 | if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { | 783 | if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { |
777 | rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 784 | rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
778 | if (rc || getstatus) { | 785 | if (rc || getstatus) { |
779 | info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); | 786 | info("%s: already enabled on slot(%s)\n", __FUNCTION__, |
787 | slot_name(p_slot)); | ||
780 | mutex_unlock(&p_slot->ctrl->crit_sect); | 788 | mutex_unlock(&p_slot->ctrl->crit_sect); |
781 | return -EINVAL; | 789 | return -EINVAL; |
782 | } | 790 | } |
783 | } | 791 | } |
784 | mutex_unlock(&p_slot->ctrl->crit_sect); | ||
785 | 792 | ||
786 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 793 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
787 | 794 | ||
@@ -790,9 +797,9 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
790 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 797 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
791 | } | 798 | } |
792 | 799 | ||
793 | if (p_slot) | 800 | update_slot_info(p_slot); |
794 | update_slot_info(p_slot); | ||
795 | 801 | ||
802 | mutex_unlock(&p_slot->ctrl->crit_sect); | ||
796 | return rc; | 803 | return rc; |
797 | } | 804 | } |
798 | 805 | ||
@@ -811,7 +818,8 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
811 | if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) { | 818 | if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) { |
812 | ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); | 819 | ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); |
813 | if (ret || !getstatus) { | 820 | if (ret || !getstatus) { |
814 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); | 821 | info("%s: no adapter on slot(%s)\n", __FUNCTION__, |
822 | slot_name(p_slot)); | ||
815 | mutex_unlock(&p_slot->ctrl->crit_sect); | 823 | mutex_unlock(&p_slot->ctrl->crit_sect); |
816 | return -ENODEV; | 824 | return -ENODEV; |
817 | } | 825 | } |
@@ -820,7 +828,8 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
820 | if (MRL_SENS(p_slot->ctrl->ctrlcap)) { | 828 | if (MRL_SENS(p_slot->ctrl->ctrlcap)) { |
821 | ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 829 | ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
822 | if (ret || getstatus) { | 830 | if (ret || getstatus) { |
823 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); | 831 | info("%s: latch open on slot(%s)\n", __FUNCTION__, |
832 | slot_name(p_slot)); | ||
824 | mutex_unlock(&p_slot->ctrl->crit_sect); | 833 | mutex_unlock(&p_slot->ctrl->crit_sect); |
825 | return -ENODEV; | 834 | return -ENODEV; |
826 | } | 835 | } |
@@ -829,16 +838,17 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
829 | if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { | 838 | if (POWER_CTRL(p_slot->ctrl->ctrlcap)) { |
830 | ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 839 | ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
831 | if (ret || !getstatus) { | 840 | if (ret || !getstatus) { |
832 | info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); | 841 | info("%s: already disabled slot(%s)\n", __FUNCTION__, |
842 | slot_name(p_slot)); | ||
833 | mutex_unlock(&p_slot->ctrl->crit_sect); | 843 | mutex_unlock(&p_slot->ctrl->crit_sect); |
834 | return -EINVAL; | 844 | return -EINVAL; |
835 | } | 845 | } |
836 | } | 846 | } |
837 | 847 | ||
838 | mutex_unlock(&p_slot->ctrl->crit_sect); | ||
839 | |||
840 | ret = remove_board(p_slot); | 848 | ret = remove_board(p_slot); |
841 | update_slot_info(p_slot); | 849 | update_slot_info(p_slot); |
850 | |||
851 | mutex_unlock(&p_slot->ctrl->crit_sect); | ||
842 | return ret; | 852 | return ret; |
843 | } | 853 | } |
844 | 854 | ||
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 703a64a39fe8..1c551c697c35 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -1402,6 +1402,8 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1402 | pdev->subsystem_vendor, pdev->subsystem_device); | 1402 | pdev->subsystem_vendor, pdev->subsystem_device); |
1403 | 1403 | ||
1404 | mutex_init(&ctrl->crit_sect); | 1404 | mutex_init(&ctrl->crit_sect); |
1405 | mutex_init(&ctrl->ctrl_lock); | ||
1406 | |||
1405 | /* setup wait queue */ | 1407 | /* setup wait queue */ |
1406 | init_waitqueue_head(&ctrl->queue); | 1408 | init_waitqueue_head(&ctrl->queue); |
1407 | 1409 | ||
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c index 2b9e10e38613..50bcd3fe61da 100644 --- a/drivers/pci/hotplug/pcihp_skeleton.c +++ b/drivers/pci/hotplug/pcihp_skeleton.c | |||
@@ -33,8 +33,8 @@ | |||
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/pci_hotplug.h> | ||
36 | #include <linux/init.h> | 37 | #include <linux/init.h> |
37 | #include "pci_hotplug.h" | ||
38 | 38 | ||
39 | #define SLOT_NAME_SIZE 10 | 39 | #define SLOT_NAME_SIZE 10 |
40 | struct slot { | 40 | struct slot { |
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c index db69be85b458..6c5be3ff578c 100644 --- a/drivers/pci/hotplug/rpadlpar_sysfs.c +++ b/drivers/pci/hotplug/rpadlpar_sysfs.c | |||
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | #include <linux/kobject.h> | 15 | #include <linux/kobject.h> |
16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | #include "pci_hotplug.h" | 17 | #include <linux/pci_hotplug.h> |
18 | #include "rpadlpar.h" | 18 | #include "rpadlpar.h" |
19 | 19 | ||
20 | #define DLPAR_KOBJ_NAME "control" | 20 | #define DLPAR_KOBJ_NAME "control" |
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 7288a3eccfb3..141486df235b 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/pci_hotplug.h> | ||
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
30 | #include <linux/smp.h> | 31 | #include <linux/smp.h> |
31 | #include <linux/smp_lock.h> | 32 | #include <linux/smp_lock.h> |
@@ -36,7 +37,6 @@ | |||
36 | #include "../pci.h" /* for pci_add_new_bus */ | 37 | #include "../pci.h" /* for pci_add_new_bus */ |
37 | /* and pci_do_scan_bus */ | 38 | /* and pci_do_scan_bus */ |
38 | #include "rpaphp.h" | 39 | #include "rpaphp.h" |
39 | #include "pci_hotplug.h" | ||
40 | 40 | ||
41 | int debug; | 41 | int debug; |
42 | static struct semaphore rpaphp_sem; | 42 | static struct semaphore rpaphp_sem; |
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index f31d83c2c633..b62ad31a9739 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
16 | #include <linux/pci_hotplug.h> | ||
16 | #include <linux/proc_fs.h> | 17 | #include <linux/proc_fs.h> |
17 | #include <linux/types.h> | 18 | #include <linux/types.h> |
18 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
@@ -29,7 +30,6 @@ | |||
29 | #include <asm/sn/types.h> | 30 | #include <asm/sn/types.h> |
30 | 31 | ||
31 | #include "../pci.h" | 32 | #include "../pci.h" |
32 | #include "pci_hotplug.h" | ||
33 | 33 | ||
34 | MODULE_LICENSE("GPL"); | 34 | MODULE_LICENSE("GPL"); |
35 | MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)"); | 35 | MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)"); |
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index c7103ac5cd06..ea2087c34149 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -31,12 +31,11 @@ | |||
31 | 31 | ||
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
34 | #include <linux/pci_hotplug.h> | ||
34 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
35 | #include <linux/sched.h> /* signal_pending(), struct timer_list */ | 36 | #include <linux/sched.h> /* signal_pending(), struct timer_list */ |
36 | #include <linux/mutex.h> | 37 | #include <linux/mutex.h> |
37 | 38 | ||
38 | #include "pci_hotplug.h" | ||
39 | |||
40 | #if !defined(MODULE) | 39 | #if !defined(MODULE) |
41 | #define MY_NAME "shpchp" | 40 | #define MY_NAME "shpchp" |
42 | #else | 41 | #else |
@@ -103,7 +102,6 @@ struct controller { | |||
103 | u32 cap_offset; | 102 | u32 cap_offset; |
104 | unsigned long mmio_base; | 103 | unsigned long mmio_base; |
105 | unsigned long mmio_size; | 104 | unsigned long mmio_size; |
106 | volatile int cmd_busy; | ||
107 | }; | 105 | }; |
108 | 106 | ||
109 | 107 | ||
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 4d8aee119134..83a5226ba9ed 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -302,21 +302,51 @@ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec) | |||
302 | add_timer(&php_ctlr->int_poll_timer); | 302 | add_timer(&php_ctlr->int_poll_timer); |
303 | } | 303 | } |
304 | 304 | ||
305 | static inline int is_ctrl_busy(struct controller *ctrl) | ||
306 | { | ||
307 | u16 cmd_status = shpc_readw(ctrl, CMD_STATUS); | ||
308 | return cmd_status & 0x1; | ||
309 | } | ||
310 | |||
311 | /* | ||
312 | * Returns 1 if SHPC finishes executing a command within 1 sec, | ||
313 | * otherwise returns 0. | ||
314 | */ | ||
315 | static inline int shpc_poll_ctrl_busy(struct controller *ctrl) | ||
316 | { | ||
317 | int i; | ||
318 | |||
319 | if (!is_ctrl_busy(ctrl)) | ||
320 | return 1; | ||
321 | |||
322 | /* Check every 0.1 sec for a total of 1 sec */ | ||
323 | for (i = 0; i < 10; i++) { | ||
324 | msleep(100); | ||
325 | if (!is_ctrl_busy(ctrl)) | ||
326 | return 1; | ||
327 | } | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
305 | static inline int shpc_wait_cmd(struct controller *ctrl) | 332 | static inline int shpc_wait_cmd(struct controller *ctrl) |
306 | { | 333 | { |
307 | int retval = 0; | 334 | int retval = 0; |
308 | unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000; | 335 | unsigned long timeout = msecs_to_jiffies(1000); |
309 | unsigned long timeout = msecs_to_jiffies(timeout_msec); | 336 | int rc; |
310 | int rc = wait_event_interruptible_timeout(ctrl->queue, | 337 | |
311 | !ctrl->cmd_busy, timeout); | 338 | if (shpchp_poll_mode) |
312 | if (!rc) { | 339 | rc = shpc_poll_ctrl_busy(ctrl); |
340 | else | ||
341 | rc = wait_event_interruptible_timeout(ctrl->queue, | ||
342 | !is_ctrl_busy(ctrl), timeout); | ||
343 | if (!rc && is_ctrl_busy(ctrl)) { | ||
313 | retval = -EIO; | 344 | retval = -EIO; |
314 | err("Command not completed in %d msec\n", timeout_msec); | 345 | err("Command not completed in 1000 msec\n"); |
315 | } else if (rc < 0) { | 346 | } else if (rc < 0) { |
316 | retval = -EINTR; | 347 | retval = -EINTR; |
317 | info("Command was interrupted by a signal\n"); | 348 | info("Command was interrupted by a signal\n"); |
318 | } | 349 | } |
319 | ctrl->cmd_busy = 0; | ||
320 | 350 | ||
321 | return retval; | 351 | return retval; |
322 | } | 352 | } |
@@ -327,26 +357,15 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
327 | u16 cmd_status; | 357 | u16 cmd_status; |
328 | int retval = 0; | 358 | int retval = 0; |
329 | u16 temp_word; | 359 | u16 temp_word; |
330 | int i; | ||
331 | 360 | ||
332 | DBG_ENTER_ROUTINE | 361 | DBG_ENTER_ROUTINE |
333 | 362 | ||
334 | mutex_lock(&slot->ctrl->cmd_lock); | 363 | mutex_lock(&slot->ctrl->cmd_lock); |
335 | 364 | ||
336 | for (i = 0; i < 10; i++) { | 365 | if (!shpc_poll_ctrl_busy(ctrl)) { |
337 | cmd_status = shpc_readw(ctrl, CMD_STATUS); | ||
338 | |||
339 | if (!(cmd_status & 0x1)) | ||
340 | break; | ||
341 | /* Check every 0.1 sec for a total of 1 sec*/ | ||
342 | msleep(100); | ||
343 | } | ||
344 | |||
345 | cmd_status = shpc_readw(ctrl, CMD_STATUS); | ||
346 | |||
347 | if (cmd_status & 0x1) { | ||
348 | /* After 1 sec and and the controller is still busy */ | 366 | /* After 1 sec and and the controller is still busy */ |
349 | err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); | 367 | err("%s : Controller is still busy after 1 sec.\n", |
368 | __FUNCTION__); | ||
350 | retval = -EBUSY; | 369 | retval = -EBUSY; |
351 | goto out; | 370 | goto out; |
352 | } | 371 | } |
@@ -358,7 +377,6 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
358 | /* To make sure the Controller Busy bit is 0 before we send out the | 377 | /* To make sure the Controller Busy bit is 0 before we send out the |
359 | * command. | 378 | * command. |
360 | */ | 379 | */ |
361 | slot->ctrl->cmd_busy = 1; | ||
362 | shpc_writew(ctrl, CMD, temp_word); | 380 | shpc_writew(ctrl, CMD, temp_word); |
363 | 381 | ||
364 | /* | 382 | /* |
@@ -908,7 +926,6 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
908 | serr_int &= ~SERR_INTR_RSVDZ_MASK; | 926 | serr_int &= ~SERR_INTR_RSVDZ_MASK; |
909 | shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); | 927 | shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); |
910 | 928 | ||
911 | ctrl->cmd_busy = 0; | ||
912 | wake_up_interruptible(&ctrl->queue); | 929 | wake_up_interruptible(&ctrl->queue); |
913 | } | 930 | } |
914 | 931 | ||
@@ -1101,7 +1118,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1101 | { | 1118 | { |
1102 | struct php_ctlr_state_s *php_ctlr, *p; | 1119 | struct php_ctlr_state_s *php_ctlr, *p; |
1103 | void *instance_id = ctrl; | 1120 | void *instance_id = ctrl; |
1104 | int rc, num_slots = 0; | 1121 | int rc = -1, num_slots = 0; |
1105 | u8 hp_slot; | 1122 | u8 hp_slot; |
1106 | u32 shpc_base_offset; | 1123 | u32 shpc_base_offset; |
1107 | u32 tempdword, slot_reg, slot_config; | 1124 | u32 tempdword, slot_reg, slot_config; |
@@ -1167,11 +1184,15 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1167 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, | 1184 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, |
1168 | pdev->subsystem_device); | 1185 | pdev->subsystem_device); |
1169 | 1186 | ||
1170 | if (pci_enable_device(pdev)) | 1187 | rc = pci_enable_device(pdev); |
1188 | if (rc) { | ||
1189 | err("%s: pci_enable_device failed\n", __FUNCTION__); | ||
1171 | goto abort_free_ctlr; | 1190 | goto abort_free_ctlr; |
1191 | } | ||
1172 | 1192 | ||
1173 | if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) { | 1193 | if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) { |
1174 | err("%s: cannot reserve MMIO region\n", __FUNCTION__); | 1194 | err("%s: cannot reserve MMIO region\n", __FUNCTION__); |
1195 | rc = -1; | ||
1175 | goto abort_free_ctlr; | 1196 | goto abort_free_ctlr; |
1176 | } | 1197 | } |
1177 | 1198 | ||
@@ -1180,6 +1201,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1180 | err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, | 1201 | err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, |
1181 | ctrl->mmio_size, ctrl->mmio_base); | 1202 | ctrl->mmio_size, ctrl->mmio_base); |
1182 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); | 1203 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); |
1204 | rc = -1; | ||
1183 | goto abort_free_ctlr; | 1205 | goto abort_free_ctlr; |
1184 | } | 1206 | } |
1185 | dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); | 1207 | dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); |
@@ -1282,8 +1304,10 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1282 | */ | 1304 | */ |
1283 | if (atomic_add_return(1, &shpchp_num_controllers) == 1) { | 1305 | if (atomic_add_return(1, &shpchp_num_controllers) == 1) { |
1284 | shpchp_wq = create_singlethread_workqueue("shpchpd"); | 1306 | shpchp_wq = create_singlethread_workqueue("shpchpd"); |
1285 | if (!shpchp_wq) | 1307 | if (!shpchp_wq) { |
1286 | return -ENOMEM; | 1308 | rc = -ENOMEM; |
1309 | goto abort_free_ctlr; | ||
1310 | } | ||
1287 | } | 1311 | } |
1288 | 1312 | ||
1289 | /* | 1313 | /* |
@@ -1313,8 +1337,10 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1313 | 1337 | ||
1314 | /* We end up here for the many possible ways to fail this API. */ | 1338 | /* We end up here for the many possible ways to fail this API. */ |
1315 | abort_free_ctlr: | 1339 | abort_free_ctlr: |
1340 | if (php_ctlr->creg) | ||
1341 | iounmap(php_ctlr->creg); | ||
1316 | kfree(php_ctlr); | 1342 | kfree(php_ctlr); |
1317 | abort: | 1343 | abort: |
1318 | DBG_LEAVE_ROUTINE | 1344 | DBG_LEAVE_ROUTINE |
1319 | return -1; | 1345 | return rc; |
1320 | } | 1346 | } |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index f9fdc54473c4..9fc9a34ef24a 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -627,22 +627,24 @@ static int msix_capability_init(struct pci_dev *dev, | |||
627 | * pci_msi_supported - check whether MSI may be enabled on device | 627 | * pci_msi_supported - check whether MSI may be enabled on device |
628 | * @dev: pointer to the pci_dev data structure of MSI device function | 628 | * @dev: pointer to the pci_dev data structure of MSI device function |
629 | * | 629 | * |
630 | * MSI must be globally enabled and supported by the device and its root | 630 | * Look at global flags, the device itself, and its parent busses |
631 | * bus. But, the root bus is not easy to find since some architectures | 631 | * to return 0 if MSI are supported for the device. |
632 | * have virtual busses on top of the PCI hierarchy (for instance the | ||
633 | * hypertransport bus), while the actual bus where MSI must be supported | ||
634 | * is below. So we test the MSI flag on all parent busses and assume | ||
635 | * that no quirk will ever set the NO_MSI flag on a non-root bus. | ||
636 | **/ | 632 | **/ |
637 | static | 633 | static |
638 | int pci_msi_supported(struct pci_dev * dev) | 634 | int pci_msi_supported(struct pci_dev * dev) |
639 | { | 635 | { |
640 | struct pci_bus *bus; | 636 | struct pci_bus *bus; |
641 | 637 | ||
638 | /* MSI must be globally enabled and supported by the device */ | ||
642 | if (!pci_msi_enable || !dev || dev->no_msi) | 639 | if (!pci_msi_enable || !dev || dev->no_msi) |
643 | return -EINVAL; | 640 | return -EINVAL; |
644 | 641 | ||
645 | /* check MSI flags of all parent busses */ | 642 | /* Any bridge which does NOT route MSI transactions from it's |
643 | * secondary bus to it's primary bus must set NO_MSI flag on | ||
644 | * the secondary pci_bus. | ||
645 | * We expect only arch-specific PCI host bus controller driver | ||
646 | * or quirks for specific PCI bridges to be setting NO_MSI. | ||
647 | */ | ||
646 | for (bus = dev->bus; bus; bus = bus->parent) | 648 | for (bus = dev->bus; bus; bus = bus->parent) |
647 | if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) | 649 | if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) |
648 | return -EINVAL; | 650 | return -EINVAL; |
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 67fcd176babd..3656e0349dd1 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #ifndef _PORTDRV_H_ | 9 | #ifndef _PORTDRV_H_ |
10 | #define _PORTDRV_H_ | 10 | #define _PORTDRV_H_ |
11 | 11 | ||
12 | #include <linux/compiler.h> | ||
13 | |||
12 | #if !defined(PCI_CAP_ID_PME) | 14 | #if !defined(PCI_CAP_ID_PME) |
13 | #define PCI_CAP_ID_PME 1 | 15 | #define PCI_CAP_ID_PME 1 |
14 | #endif | 16 | #endif |
@@ -39,7 +41,7 @@ extern int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state); | |||
39 | extern int pcie_port_device_resume(struct pci_dev *dev); | 41 | extern int pcie_port_device_resume(struct pci_dev *dev); |
40 | #endif | 42 | #endif |
41 | extern void pcie_port_device_remove(struct pci_dev *dev); | 43 | extern void pcie_port_device_remove(struct pci_dev *dev); |
42 | extern int pcie_port_bus_register(void); | 44 | extern int __must_check pcie_port_bus_register(void); |
43 | extern void pcie_port_bus_unregister(void); | 45 | extern void pcie_port_bus_unregister(void); |
44 | 46 | ||
45 | #endif /* _PORTDRV_H_ */ | 47 | #endif /* _PORTDRV_H_ */ |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index bd6615b4d40e..b20a9b81dae2 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -6,7 +6,6 @@ | |||
6 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) | 6 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/compiler.h> | ||
10 | #include <linux/module.h> | 9 | #include <linux/module.h> |
11 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
12 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
@@ -401,7 +400,7 @@ void pcie_port_device_remove(struct pci_dev *dev) | |||
401 | pci_disable_msi(dev); | 400 | pci_disable_msi(dev); |
402 | } | 401 | } |
403 | 402 | ||
404 | int __must_check pcie_port_bus_register(void) | 403 | int pcie_port_bus_register(void) |
405 | { | 404 | { |
406 | return bus_register(&pcie_port_bus_type); | 405 | return bus_register(&pcie_port_bus_type); |
407 | } | 406 | } |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 037690e08f5f..b4da7954611e 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -37,7 +37,6 @@ static int pcie_portdrv_save_config(struct pci_dev *dev) | |||
37 | return pci_save_state(dev); | 37 | return pci_save_state(dev); |
38 | } | 38 | } |
39 | 39 | ||
40 | #ifdef CONFIG_PM | ||
41 | static int pcie_portdrv_restore_config(struct pci_dev *dev) | 40 | static int pcie_portdrv_restore_config(struct pci_dev *dev) |
42 | { | 41 | { |
43 | int retval; | 42 | int retval; |
@@ -50,6 +49,7 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) | |||
50 | return 0; | 49 | return 0; |
51 | } | 50 | } |
52 | 51 | ||
52 | #ifdef CONFIG_PM | ||
53 | static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) | 53 | static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) |
54 | { | 54 | { |
55 | int ret = pcie_port_device_suspend(dev, state); | 55 | int ret = pcie_port_device_suspend(dev, state); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index a3b0a5eb5054..e159d6604494 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1067,3 +1067,95 @@ EXPORT_SYMBOL(pci_scan_bridge); | |||
1067 | EXPORT_SYMBOL(pci_scan_single_device); | 1067 | EXPORT_SYMBOL(pci_scan_single_device); |
1068 | EXPORT_SYMBOL_GPL(pci_scan_child_bus); | 1068 | EXPORT_SYMBOL_GPL(pci_scan_child_bus); |
1069 | #endif | 1069 | #endif |
1070 | |||
1071 | static int __init pci_sort_bf_cmp(const struct pci_dev *a, const struct pci_dev *b) | ||
1072 | { | ||
1073 | if (pci_domain_nr(a->bus) < pci_domain_nr(b->bus)) return -1; | ||
1074 | else if (pci_domain_nr(a->bus) > pci_domain_nr(b->bus)) return 1; | ||
1075 | |||
1076 | if (a->bus->number < b->bus->number) return -1; | ||
1077 | else if (a->bus->number > b->bus->number) return 1; | ||
1078 | |||
1079 | if (a->devfn < b->devfn) return -1; | ||
1080 | else if (a->devfn > b->devfn) return 1; | ||
1081 | |||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | /* | ||
1086 | * Yes, this forcably breaks the klist abstraction temporarily. It | ||
1087 | * just wants to sort the klist, not change reference counts and | ||
1088 | * take/drop locks rapidly in the process. It does all this while | ||
1089 | * holding the lock for the list, so objects can't otherwise be | ||
1090 | * added/removed while we're swizzling. | ||
1091 | */ | ||
1092 | static void __init pci_insertion_sort_klist(struct pci_dev *a, struct list_head *list) | ||
1093 | { | ||
1094 | struct list_head *pos; | ||
1095 | struct klist_node *n; | ||
1096 | struct device *dev; | ||
1097 | struct pci_dev *b; | ||
1098 | |||
1099 | list_for_each(pos, list) { | ||
1100 | n = container_of(pos, struct klist_node, n_node); | ||
1101 | dev = container_of(n, struct device, knode_bus); | ||
1102 | b = to_pci_dev(dev); | ||
1103 | if (pci_sort_bf_cmp(a, b) <= 0) { | ||
1104 | list_move_tail(&a->dev.knode_bus.n_node, &b->dev.knode_bus.n_node); | ||
1105 | return; | ||
1106 | } | ||
1107 | } | ||
1108 | list_move_tail(&a->dev.knode_bus.n_node, list); | ||
1109 | } | ||
1110 | |||
1111 | static void __init pci_sort_breadthfirst_klist(void) | ||
1112 | { | ||
1113 | LIST_HEAD(sorted_devices); | ||
1114 | struct list_head *pos, *tmp; | ||
1115 | struct klist_node *n; | ||
1116 | struct device *dev; | ||
1117 | struct pci_dev *pdev; | ||
1118 | |||
1119 | spin_lock(&pci_bus_type.klist_devices.k_lock); | ||
1120 | list_for_each_safe(pos, tmp, &pci_bus_type.klist_devices.k_list) { | ||
1121 | n = container_of(pos, struct klist_node, n_node); | ||
1122 | dev = container_of(n, struct device, knode_bus); | ||
1123 | pdev = to_pci_dev(dev); | ||
1124 | pci_insertion_sort_klist(pdev, &sorted_devices); | ||
1125 | } | ||
1126 | list_splice(&sorted_devices, &pci_bus_type.klist_devices.k_list); | ||
1127 | spin_unlock(&pci_bus_type.klist_devices.k_lock); | ||
1128 | } | ||
1129 | |||
1130 | static void __init pci_insertion_sort_devices(struct pci_dev *a, struct list_head *list) | ||
1131 | { | ||
1132 | struct pci_dev *b; | ||
1133 | |||
1134 | list_for_each_entry(b, list, global_list) { | ||
1135 | if (pci_sort_bf_cmp(a, b) <= 0) { | ||
1136 | list_move_tail(&a->global_list, &b->global_list); | ||
1137 | return; | ||
1138 | } | ||
1139 | } | ||
1140 | list_move_tail(&a->global_list, list); | ||
1141 | } | ||
1142 | |||
1143 | static void __init pci_sort_breadthfirst_devices(void) | ||
1144 | { | ||
1145 | LIST_HEAD(sorted_devices); | ||
1146 | struct pci_dev *dev, *tmp; | ||
1147 | |||
1148 | down_write(&pci_bus_sem); | ||
1149 | list_for_each_entry_safe(dev, tmp, &pci_devices, global_list) { | ||
1150 | pci_insertion_sort_devices(dev, &sorted_devices); | ||
1151 | } | ||
1152 | list_splice(&sorted_devices, &pci_devices); | ||
1153 | up_write(&pci_bus_sem); | ||
1154 | } | ||
1155 | |||
1156 | void __init pci_sort_breadthfirst(void) | ||
1157 | { | ||
1158 | pci_sort_breadthfirst_devices(); | ||
1159 | pci_sort_breadthfirst_klist(); | ||
1160 | } | ||
1161 | |||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 23b599d6a9d5..e8a7f1b1b2bc 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -453,6 +453,12 @@ static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev) | |||
453 | } | 453 | } |
454 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi ); | 454 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi ); |
455 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); | 455 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi ); |
456 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, quirk_ich6_lpc_acpi ); | ||
457 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, quirk_ich6_lpc_acpi ); | ||
458 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, quirk_ich6_lpc_acpi ); | ||
459 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich6_lpc_acpi ); | ||
460 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich6_lpc_acpi ); | ||
461 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich6_lpc_acpi ); | ||
456 | 462 | ||
457 | /* | 463 | /* |
458 | * VIA ACPI: One IO region pointed to by longword at | 464 | * VIA ACPI: One IO region pointed to by longword at |
@@ -648,11 +654,43 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vi | |||
648 | * Some of the on-chip devices are actually '586 devices' so they are | 654 | * Some of the on-chip devices are actually '586 devices' so they are |
649 | * listed here. | 655 | * listed here. |
650 | */ | 656 | */ |
657 | |||
658 | static int via_irq_fixup_needed = -1; | ||
659 | |||
660 | /* | ||
661 | * As some VIA hardware is available in PCI-card form, we need to restrict | ||
662 | * this quirk to VIA PCI hardware built onto VIA-based motherboards only. | ||
663 | * We try to locate a VIA southbridge before deciding whether the quirk | ||
664 | * should be applied. | ||
665 | */ | ||
666 | static const struct pci_device_id via_irq_fixup_tbl[] = { | ||
667 | { | ||
668 | .vendor = PCI_VENDOR_ID_VIA, | ||
669 | .device = PCI_ANY_ID, | ||
670 | .subvendor = PCI_ANY_ID, | ||
671 | .subdevice = PCI_ANY_ID, | ||
672 | .class = PCI_CLASS_BRIDGE_ISA << 8, | ||
673 | .class_mask = 0xffff00, | ||
674 | }, | ||
675 | { 0, }, | ||
676 | }; | ||
677 | |||
651 | static void quirk_via_irq(struct pci_dev *dev) | 678 | static void quirk_via_irq(struct pci_dev *dev) |
652 | { | 679 | { |
653 | u8 irq, new_irq; | 680 | u8 irq, new_irq; |
654 | 681 | ||
655 | new_irq = dev->irq & 0xf; | 682 | if (via_irq_fixup_needed == -1) |
683 | via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl); | ||
684 | |||
685 | if (!via_irq_fixup_needed) | ||
686 | return; | ||
687 | |||
688 | new_irq = dev->irq; | ||
689 | |||
690 | /* Don't quirk interrupts outside the legacy IRQ range */ | ||
691 | if (!new_irq || new_irq > 15) | ||
692 | return; | ||
693 | |||
656 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); | 694 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); |
657 | if (new_irq != irq) { | 695 | if (new_irq != irq) { |
658 | printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n", | 696 | printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n", |
@@ -661,14 +699,7 @@ static void quirk_via_irq(struct pci_dev *dev) | |||
661 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); | 699 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); |
662 | } | 700 | } |
663 | } | 701 | } |
664 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_via_irq); | 702 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); |
665 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, quirk_via_irq); | ||
666 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irq); | ||
667 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_irq); | ||
668 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, quirk_via_irq); | ||
669 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_irq); | ||
670 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_irq); | ||
671 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irq); | ||
672 | 703 | ||
673 | /* | 704 | /* |
674 | * VIA VT82C598 has its device ID settable and many BIOSes | 705 | * VIA VT82C598 has its device ID settable and many BIOSes |
@@ -1588,6 +1619,51 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev) | |||
1588 | } | 1619 | } |
1589 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); | 1620 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); |
1590 | 1621 | ||
1622 | /* | ||
1623 | * Fixup to mark boot BIOS video selected by BIOS before it changes | ||
1624 | * | ||
1625 | * From information provided by "Jon Smirl" <jonsmirl@gmail.com> | ||
1626 | * | ||
1627 | * The standard boot ROM sequence for an x86 machine uses the BIOS | ||
1628 | * to select an initial video card for boot display. This boot video | ||
1629 | * card will have it's BIOS copied to C0000 in system RAM. | ||
1630 | * IORESOURCE_ROM_SHADOW is used to associate the boot video | ||
1631 | * card with this copy. On laptops this copy has to be used since | ||
1632 | * the main ROM may be compressed or combined with another image. | ||
1633 | * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW | ||
1634 | * is marked here since the boot video device will be the only enabled | ||
1635 | * video device at this point. | ||
1636 | */ | ||
1637 | |||
1638 | static void __devinit fixup_video(struct pci_dev *pdev) | ||
1639 | { | ||
1640 | struct pci_dev *bridge; | ||
1641 | struct pci_bus *bus; | ||
1642 | u16 config; | ||
1643 | |||
1644 | if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
1645 | return; | ||
1646 | |||
1647 | /* Is VGA routed to us? */ | ||
1648 | bus = pdev->bus; | ||
1649 | while (bus) { | ||
1650 | bridge = bus->self; | ||
1651 | if (bridge) { | ||
1652 | pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, | ||
1653 | &config); | ||
1654 | if (!(config & PCI_BRIDGE_CTL_VGA)) | ||
1655 | return; | ||
1656 | } | ||
1657 | bus = bus->parent; | ||
1658 | } | ||
1659 | pci_read_config_word(pdev, PCI_COMMAND, &config); | ||
1660 | if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { | ||
1661 | pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; | ||
1662 | printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); | ||
1663 | } | ||
1664 | } | ||
1665 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_video); | ||
1666 | |||
1591 | 1667 | ||
1592 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) | 1668 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) |
1593 | { | 1669 | { |
@@ -1764,7 +1840,7 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) | |||
1764 | /* check HT MSI cap on this chipset and the root one. | 1840 | /* check HT MSI cap on this chipset and the root one. |
1765 | * a single one having MSI is enough to be sure that MSI are supported. | 1841 | * a single one having MSI is enough to be sure that MSI are supported. |
1766 | */ | 1842 | */ |
1767 | pdev = pci_find_slot(dev->bus->number, 0); | 1843 | pdev = pci_get_slot(dev->bus, 0); |
1768 | if (dev->subordinate && !msi_ht_cap_enabled(dev) | 1844 | if (dev->subordinate && !msi_ht_cap_enabled(dev) |
1769 | && !msi_ht_cap_enabled(pdev)) { | 1845 | && !msi_ht_cap_enabled(pdev)) { |
1770 | printk(KERN_WARNING "PCI: MSI quirk detected. " | 1846 | printk(KERN_WARNING "PCI: MSI quirk detected. " |
@@ -1772,6 +1848,7 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) | |||
1772 | pci_name(dev)); | 1848 | pci_name(dev)); |
1773 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; | 1849 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; |
1774 | } | 1850 | } |
1851 | pci_dev_put(pdev); | ||
1775 | } | 1852 | } |
1776 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | 1853 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, |
1777 | quirk_nvidia_ck804_msi_ht_cap); | 1854 | quirk_nvidia_ck804_msi_ht_cap); |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index f5ee7ce16fa6..43e4a49f2cc4 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -71,7 +71,10 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
71 | void __iomem *image; | 71 | void __iomem *image; |
72 | int last_image; | 72 | int last_image; |
73 | 73 | ||
74 | /* IORESOURCE_ROM_SHADOW only set on x86 */ | 74 | /* |
75 | * IORESOURCE_ROM_SHADOW set if the VGA enable bit of the Bridge Control | ||
76 | * register is set for embedded VGA. | ||
77 | */ | ||
75 | if (res->flags & IORESOURCE_ROM_SHADOW) { | 78 | if (res->flags & IORESOURCE_ROM_SHADOW) { |
76 | /* primary video rom always starts here */ | 79 | /* primary video rom always starts here */ |
77 | start = (loff_t)0xC0000; | 80 | start = (loff_t)0xC0000; |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index d529462d1b53..2f13eba5d5ae 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -140,6 +140,31 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) | |||
140 | } | 140 | } |
141 | 141 | ||
142 | /** | 142 | /** |
143 | * pci_get_bus_and_slot - locate PCI device from a given PCI slot | ||
144 | * @bus: number of PCI bus on which desired PCI device resides | ||
145 | * @devfn: encodes number of PCI slot in which the desired PCI | ||
146 | * device resides and the logical device number within that slot | ||
147 | * in case of multi-function devices. | ||
148 | * | ||
149 | * Given a PCI bus and slot/function number, the desired PCI device | ||
150 | * is located in system global list of PCI devices. If the device | ||
151 | * is found, a pointer to its data structure is returned. If no | ||
152 | * device is found, %NULL is returned. The returned device has its | ||
153 | * reference count bumped by one. | ||
154 | */ | ||
155 | |||
156 | struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) | ||
157 | { | ||
158 | struct pci_dev *dev = NULL; | ||
159 | |||
160 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | ||
161 | if (dev->bus->number == bus && dev->devfn == devfn) | ||
162 | return dev; | ||
163 | } | ||
164 | return NULL; | ||
165 | } | ||
166 | |||
167 | /** | ||
143 | * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id | 168 | * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id |
144 | * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids | 169 | * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids |
145 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids | 170 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids |
@@ -274,6 +299,45 @@ pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) | |||
274 | return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); | 299 | return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); |
275 | } | 300 | } |
276 | 301 | ||
302 | /** | ||
303 | * pci_get_device_reverse - begin or continue searching for a PCI device by vendor/device id | ||
304 | * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids | ||
305 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids | ||
306 | * @from: Previous PCI device found in search, or %NULL for new search. | ||
307 | * | ||
308 | * Iterates through the list of known PCI devices in the reverse order of | ||
309 | * pci_get_device. | ||
310 | * If a PCI device is found with a matching @vendor and @device, the reference | ||
311 | * count to the device is incremented and a pointer to its device structure | ||
312 | * is returned Otherwise, %NULL is returned. A new search is initiated by | ||
313 | * passing %NULL as the @from argument. Otherwise if @from is not %NULL, | ||
314 | * searches continue from next device on the global list. The reference | ||
315 | * count for @from is always decremented if it is not %NULL. | ||
316 | */ | ||
317 | struct pci_dev * | ||
318 | pci_get_device_reverse(unsigned int vendor, unsigned int device, struct pci_dev *from) | ||
319 | { | ||
320 | struct list_head *n; | ||
321 | struct pci_dev *dev; | ||
322 | |||
323 | WARN_ON(in_interrupt()); | ||
324 | down_read(&pci_bus_sem); | ||
325 | n = from ? from->global_list.prev : pci_devices.prev; | ||
326 | |||
327 | while (n && (n != &pci_devices)) { | ||
328 | dev = pci_dev_g(n); | ||
329 | if ((vendor == PCI_ANY_ID || dev->vendor == vendor) && | ||
330 | (device == PCI_ANY_ID || dev->device == device)) | ||
331 | goto exit; | ||
332 | n = n->prev; | ||
333 | } | ||
334 | dev = NULL; | ||
335 | exit: | ||
336 | dev = pci_dev_get(dev); | ||
337 | up_read(&pci_bus_sem); | ||
338 | pci_dev_put(from); | ||
339 | return dev; | ||
340 | } | ||
277 | 341 | ||
278 | /** | 342 | /** |
279 | * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id | 343 | * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id |
@@ -382,12 +446,16 @@ exit: | |||
382 | } | 446 | } |
383 | EXPORT_SYMBOL(pci_dev_present); | 447 | EXPORT_SYMBOL(pci_dev_present); |
384 | 448 | ||
385 | EXPORT_SYMBOL(pci_find_bus); | ||
386 | EXPORT_SYMBOL(pci_find_next_bus); | ||
387 | EXPORT_SYMBOL(pci_find_device); | 449 | EXPORT_SYMBOL(pci_find_device); |
388 | EXPORT_SYMBOL(pci_find_device_reverse); | 450 | EXPORT_SYMBOL(pci_find_device_reverse); |
389 | EXPORT_SYMBOL(pci_find_slot); | 451 | EXPORT_SYMBOL(pci_find_slot); |
452 | /* For boot time work */ | ||
453 | EXPORT_SYMBOL(pci_find_bus); | ||
454 | EXPORT_SYMBOL(pci_find_next_bus); | ||
455 | /* For everyone */ | ||
390 | EXPORT_SYMBOL(pci_get_device); | 456 | EXPORT_SYMBOL(pci_get_device); |
457 | EXPORT_SYMBOL(pci_get_device_reverse); | ||
391 | EXPORT_SYMBOL(pci_get_subsys); | 458 | EXPORT_SYMBOL(pci_get_subsys); |
392 | EXPORT_SYMBOL(pci_get_slot); | 459 | EXPORT_SYMBOL(pci_get_slot); |
460 | EXPORT_SYMBOL(pci_get_bus_and_slot); | ||
393 | EXPORT_SYMBOL(pci_get_class); | 461 | EXPORT_SYMBOL(pci_get_class); |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index dc79b0a0059f..379048fdf05d 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -776,21 +776,32 @@ static void pnpacpi_encode_dma(struct acpi_resource *resource, | |||
776 | struct resource *p) | 776 | struct resource *p) |
777 | { | 777 | { |
778 | /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ | 778 | /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ |
779 | if (p->flags & IORESOURCE_DMA_COMPATIBLE) | 779 | switch (p->flags & IORESOURCE_DMA_SPEED_MASK) { |
780 | resource->data.dma.type = ACPI_COMPATIBILITY; | 780 | case IORESOURCE_DMA_TYPEA: |
781 | else if (p->flags & IORESOURCE_DMA_TYPEA) | 781 | resource->data.dma.type = ACPI_TYPE_A; |
782 | resource->data.dma.type = ACPI_TYPE_A; | 782 | break; |
783 | else if (p->flags & IORESOURCE_DMA_TYPEB) | 783 | case IORESOURCE_DMA_TYPEB: |
784 | resource->data.dma.type = ACPI_TYPE_B; | 784 | resource->data.dma.type = ACPI_TYPE_B; |
785 | else if (p->flags & IORESOURCE_DMA_TYPEF) | 785 | break; |
786 | resource->data.dma.type = ACPI_TYPE_F; | 786 | case IORESOURCE_DMA_TYPEF: |
787 | if (p->flags & IORESOURCE_DMA_8BIT) | 787 | resource->data.dma.type = ACPI_TYPE_F; |
788 | resource->data.dma.transfer = ACPI_TRANSFER_8; | 788 | break; |
789 | else if (p->flags & IORESOURCE_DMA_8AND16BIT) | 789 | default: |
790 | resource->data.dma.transfer = ACPI_TRANSFER_8_16; | 790 | resource->data.dma.type = ACPI_COMPATIBILITY; |
791 | else if (p->flags & IORESOURCE_DMA_16BIT) | 791 | } |
792 | resource->data.dma.transfer = ACPI_TRANSFER_16; | 792 | |
793 | resource->data.dma.bus_master = p->flags & IORESOURCE_DMA_MASTER; | 793 | switch (p->flags & IORESOURCE_DMA_TYPE_MASK) { |
794 | case IORESOURCE_DMA_8BIT: | ||
795 | resource->data.dma.transfer = ACPI_TRANSFER_8; | ||
796 | break; | ||
797 | case IORESOURCE_DMA_8AND16BIT: | ||
798 | resource->data.dma.transfer = ACPI_TRANSFER_8_16; | ||
799 | break; | ||
800 | default: | ||
801 | resource->data.dma.transfer = ACPI_TRANSFER_16; | ||
802 | } | ||
803 | |||
804 | resource->data.dma.bus_master = !!(p->flags & IORESOURCE_DMA_MASTER); | ||
794 | resource->data.dma.channel_count = 1; | 805 | resource->data.dma.channel_count = 1; |
795 | resource->data.dma.channels[0] = p->start; | 806 | resource->data.dma.channels[0] = p->start; |
796 | } | 807 | } |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 5c604f5fad67..4689e2a699c0 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -443,6 +443,7 @@ extern void pci_remove_bus(struct pci_bus *b); | |||
443 | extern void pci_remove_bus_device(struct pci_dev *dev); | 443 | extern void pci_remove_bus_device(struct pci_dev *dev); |
444 | extern void pci_stop_bus_device(struct pci_dev *dev); | 444 | extern void pci_stop_bus_device(struct pci_dev *dev); |
445 | void pci_setup_cardbus(struct pci_bus *bus); | 445 | void pci_setup_cardbus(struct pci_bus *bus); |
446 | extern void pci_sort_breadthfirst(void); | ||
446 | 447 | ||
447 | /* Generic PCI functions exported to card drivers */ | 448 | /* Generic PCI functions exported to card drivers */ |
448 | 449 | ||
@@ -452,13 +453,14 @@ struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); | |||
452 | int pci_find_capability (struct pci_dev *dev, int cap); | 453 | int pci_find_capability (struct pci_dev *dev, int cap); |
453 | int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); | 454 | int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); |
454 | int pci_find_ext_capability (struct pci_dev *dev, int cap); | 455 | int pci_find_ext_capability (struct pci_dev *dev, int cap); |
455 | struct pci_bus * pci_find_next_bus(const struct pci_bus *from); | 456 | struct pci_bus *pci_find_next_bus(const struct pci_bus *from); |
456 | 457 | ||
457 | struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from); | 458 | struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from); |
458 | struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, | 459 | struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, |
459 | unsigned int ss_vendor, unsigned int ss_device, | 460 | unsigned int ss_vendor, unsigned int ss_device, |
460 | struct pci_dev *from); | 461 | struct pci_dev *from); |
461 | struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn); | 462 | struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn); |
463 | struct pci_dev *pci_get_bus_and_slot (unsigned int bus, unsigned int devfn); | ||
462 | struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from); | 464 | struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from); |
463 | int pci_dev_present(const struct pci_device_id *ids); | 465 | int pci_dev_present(const struct pci_device_id *ids); |
464 | 466 | ||
diff --git a/drivers/pci/hotplug/pci_hotplug.h b/include/linux/pci_hotplug.h index 772523dc3860..a675a05c4091 100644 --- a/drivers/pci/hotplug/pci_hotplug.h +++ b/include/linux/pci_hotplug.h | |||
@@ -22,7 +22,7 @@ | |||
22 | * along with this program; if not, write to the Free Software | 22 | * along with this program; if not, write to the Free Software |
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
24 | * | 24 | * |
25 | * Send feedback to <greg@kroah.com> | 25 | * Send feedback to <kristen.c.accardi@intel.com> |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | #ifndef _PCI_HOTPLUG_H | 28 | #ifndef _PCI_HOTPLUG_H |