diff options
author | Yinghai Lu <yinghai@kernel.org> | 2012-02-16 00:40:31 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2012-02-24 17:37:26 -0500 |
commit | 2069ecfbe14ebd71a6f98e8a00724e9adf4fe4ee (patch) | |
tree | 5a0328d6e545a6488e85face05b0a4d78676bedf /drivers/pci | |
parent | 8474ecd9231434d71a39cd1ba118629e1b036137 (diff) |
PCI: Move "pci reassigndev resource alignment" out of quirks.c
This isn't really a quirk; calling it directly from pci_add_device makes
more sense.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci.c | 62 | ||||
-rw-r--r-- | drivers/pci/pci.h | 5 | ||||
-rw-r--r-- | drivers/pci/probe.c | 3 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 63 | ||||
-rw-r--r-- | drivers/pci/setup-res.c | 4 |
5 files changed, 66 insertions, 71 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e9f9dc183cfc..b832f0fece97 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -3694,6 +3694,68 @@ int pci_is_reassigndev(struct pci_dev *dev) | |||
3694 | return (pci_specified_resource_alignment(dev) != 0); | 3694 | return (pci_specified_resource_alignment(dev) != 0); |
3695 | } | 3695 | } |
3696 | 3696 | ||
3697 | /* | ||
3698 | * This function disables memory decoding and releases memory resources | ||
3699 | * of the device specified by kernel's boot parameter 'pci=resource_alignment='. | ||
3700 | * It also rounds up size to specified alignment. | ||
3701 | * Later on, the kernel will assign page-aligned memory resource back | ||
3702 | * to the device. | ||
3703 | */ | ||
3704 | void pci_reassigndev_resource_alignment(struct pci_dev *dev) | ||
3705 | { | ||
3706 | int i; | ||
3707 | struct resource *r; | ||
3708 | resource_size_t align, size; | ||
3709 | u16 command; | ||
3710 | |||
3711 | if (!pci_is_reassigndev(dev)) | ||
3712 | return; | ||
3713 | |||
3714 | if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL && | ||
3715 | (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) { | ||
3716 | dev_warn(&dev->dev, | ||
3717 | "Can't reassign resources to host bridge.\n"); | ||
3718 | return; | ||
3719 | } | ||
3720 | |||
3721 | dev_info(&dev->dev, | ||
3722 | "Disabling memory decoding and releasing memory resources.\n"); | ||
3723 | pci_read_config_word(dev, PCI_COMMAND, &command); | ||
3724 | command &= ~PCI_COMMAND_MEMORY; | ||
3725 | pci_write_config_word(dev, PCI_COMMAND, command); | ||
3726 | |||
3727 | align = pci_specified_resource_alignment(dev); | ||
3728 | for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) { | ||
3729 | r = &dev->resource[i]; | ||
3730 | if (!(r->flags & IORESOURCE_MEM)) | ||
3731 | continue; | ||
3732 | size = resource_size(r); | ||
3733 | if (size < align) { | ||
3734 | size = align; | ||
3735 | dev_info(&dev->dev, | ||
3736 | "Rounding up size of resource #%d to %#llx.\n", | ||
3737 | i, (unsigned long long)size); | ||
3738 | } | ||
3739 | r->end = size - 1; | ||
3740 | r->start = 0; | ||
3741 | } | ||
3742 | /* Need to disable bridge's resource window, | ||
3743 | * to enable the kernel to reassign new resource | ||
3744 | * window later on. | ||
3745 | */ | ||
3746 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && | ||
3747 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
3748 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { | ||
3749 | r = &dev->resource[i]; | ||
3750 | if (!(r->flags & IORESOURCE_MEM)) | ||
3751 | continue; | ||
3752 | r->end = resource_size(r) - 1; | ||
3753 | r->start = 0; | ||
3754 | } | ||
3755 | pci_disable_bridge_window(dev); | ||
3756 | } | ||
3757 | } | ||
3758 | |||
3697 | ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) | 3759 | ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) |
3698 | { | 3760 | { |
3699 | if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) | 3761 | if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 1fc63b39f83f..e4943479b234 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -228,11 +228,8 @@ static inline int pci_ari_enabled(struct pci_bus *bus) | |||
228 | return bus->self && bus->self->ari_enabled; | 228 | return bus->self && bus->self->ari_enabled; |
229 | } | 229 | } |
230 | 230 | ||
231 | #ifdef CONFIG_PCI_QUIRKS | 231 | void pci_reassigndev_resource_alignment(struct pci_dev *dev); |
232 | extern int pci_is_reassigndev(struct pci_dev *dev); | ||
233 | resource_size_t pci_specified_resource_alignment(struct pci_dev *dev); | ||
234 | extern void pci_disable_bridge_window(struct pci_dev *dev); | 232 | extern void pci_disable_bridge_window(struct pci_dev *dev); |
235 | #endif | ||
236 | 233 | ||
237 | /* Single Root I/O Virtualization */ | 234 | /* Single Root I/O Virtualization */ |
238 | struct pci_sriov { | 235 | struct pci_sriov { |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 36c22032ea14..944e05a66b97 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1325,6 +1325,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | |||
1325 | /* Fix up broken headers */ | 1325 | /* Fix up broken headers */ |
1326 | pci_fixup_device(pci_fixup_header, dev); | 1326 | pci_fixup_device(pci_fixup_header, dev); |
1327 | 1327 | ||
1328 | /* moved out from quirk header fixup code */ | ||
1329 | pci_reassigndev_resource_alignment(dev); | ||
1330 | |||
1328 | /* Clear the state_saved flag. */ | 1331 | /* Clear the state_saved flag. */ |
1329 | dev->state_saved = false; | 1332 | dev->state_saved = false; |
1330 | 1333 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e198589d0990..f8f81d4f29ff 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -32,69 +32,6 @@ | |||
32 | #include "pci.h" | 32 | #include "pci.h" |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * This quirk function disables memory decoding and releases memory resources | ||
36 | * of the device specified by kernel's boot parameter 'pci=resource_alignment='. | ||
37 | * It also rounds up size to specified alignment. | ||
38 | * Later on, the kernel will assign page-aligned memory resource back | ||
39 | * to the device. | ||
40 | */ | ||
41 | static void __devinit quirk_resource_alignment(struct pci_dev *dev) | ||
42 | { | ||
43 | int i; | ||
44 | struct resource *r; | ||
45 | resource_size_t align, size; | ||
46 | u16 command; | ||
47 | |||
48 | if (!pci_is_reassigndev(dev)) | ||
49 | return; | ||
50 | |||
51 | if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL && | ||
52 | (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) { | ||
53 | dev_warn(&dev->dev, | ||
54 | "Can't reassign resources to host bridge.\n"); | ||
55 | return; | ||
56 | } | ||
57 | |||
58 | dev_info(&dev->dev, | ||
59 | "Disabling memory decoding and releasing memory resources.\n"); | ||
60 | pci_read_config_word(dev, PCI_COMMAND, &command); | ||
61 | command &= ~PCI_COMMAND_MEMORY; | ||
62 | pci_write_config_word(dev, PCI_COMMAND, command); | ||
63 | |||
64 | align = pci_specified_resource_alignment(dev); | ||
65 | for (i=0; i < PCI_BRIDGE_RESOURCES; i++) { | ||
66 | r = &dev->resource[i]; | ||
67 | if (!(r->flags & IORESOURCE_MEM)) | ||
68 | continue; | ||
69 | size = resource_size(r); | ||
70 | if (size < align) { | ||
71 | size = align; | ||
72 | dev_info(&dev->dev, | ||
73 | "Rounding up size of resource #%d to %#llx.\n", | ||
74 | i, (unsigned long long)size); | ||
75 | } | ||
76 | r->end = size - 1; | ||
77 | r->start = 0; | ||
78 | } | ||
79 | /* Need to disable bridge's resource window, | ||
80 | * to enable the kernel to reassign new resource | ||
81 | * window later on. | ||
82 | */ | ||
83 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && | ||
84 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
85 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { | ||
86 | r = &dev->resource[i]; | ||
87 | if (!(r->flags & IORESOURCE_MEM)) | ||
88 | continue; | ||
89 | r->end = resource_size(r) - 1; | ||
90 | r->start = 0; | ||
91 | } | ||
92 | pci_disable_bridge_window(dev); | ||
93 | } | ||
94 | } | ||
95 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment); | ||
96 | |||
97 | /* | ||
98 | * Decoding should be disabled for a PCI device during BAR sizing to avoid | 35 | * Decoding should be disabled for a PCI device during BAR sizing to avoid |
99 | * conflict. But doing so may cause problems on host bridge and perhaps other | 36 | * conflict. But doing so may cause problems on host bridge and perhaps other |
100 | * key system devices. For devices that need to have mmio decoding always-on, | 37 | * key system devices. For devices that need to have mmio decoding always-on, |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index f968185aa192..eea85dafc763 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -114,7 +114,6 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
114 | } | 114 | } |
115 | EXPORT_SYMBOL(pci_claim_resource); | 115 | EXPORT_SYMBOL(pci_claim_resource); |
116 | 116 | ||
117 | #ifdef CONFIG_PCI_QUIRKS | ||
118 | void pci_disable_bridge_window(struct pci_dev *dev) | 117 | void pci_disable_bridge_window(struct pci_dev *dev) |
119 | { | 118 | { |
120 | dev_info(&dev->dev, "disabling bridge mem windows\n"); | 119 | dev_info(&dev->dev, "disabling bridge mem windows\n"); |
@@ -127,9 +126,6 @@ void pci_disable_bridge_window(struct pci_dev *dev) | |||
127 | pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0); | 126 | pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0); |
128 | pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff); | 127 | pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff); |
129 | } | 128 | } |
130 | #endif /* CONFIG_PCI_QUIRKS */ | ||
131 | |||
132 | |||
133 | 129 | ||
134 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | 130 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, |
135 | int resno, resource_size_t size, resource_size_t align) | 131 | int resno, resource_size_t size, resource_size_t align) |