diff options
Diffstat (limited to 'arch/i386/pci')
-rw-r--r-- | arch/i386/pci/common.c | 60 | ||||
-rw-r--r-- | arch/i386/pci/early.c | 7 | ||||
-rw-r--r-- | arch/i386/pci/fixup.c | 62 | ||||
-rw-r--r-- | arch/i386/pci/i386.c | 73 | ||||
-rw-r--r-- | arch/i386/pci/irq.c | 14 | ||||
-rw-r--r-- | arch/i386/pci/mmconfig.c | 35 | ||||
-rw-r--r-- | arch/i386/pci/pcbios.c | 11 | ||||
-rw-r--r-- | arch/i386/pci/pci.h | 8 |
8 files changed, 147 insertions, 123 deletions
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 68bce194e688..53ca6e897984 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 | static 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")) { |
@@ -288,7 +343,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
288 | 343 | ||
289 | void pcibios_disable_device (struct pci_dev *dev) | 344 | void pcibios_disable_device (struct pci_dev *dev) |
290 | { | 345 | { |
291 | pcibios_disable_resources(dev); | ||
292 | if (pcibios_disable_irq) | 346 | if (pcibios_disable_irq) |
293 | pcibios_disable_irq(dev); | 347 | pcibios_disable_irq(dev); |
294 | } | 348 | } |
diff --git a/arch/i386/pci/early.c b/arch/i386/pci/early.c index 713d6c866cae..42df4b6606df 100644 --- a/arch/i386/pci/early.c +++ b/arch/i386/pci/early.c | |||
@@ -45,6 +45,13 @@ void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, | |||
45 | outl(val, 0xcfc); | 45 | outl(val, 0xcfc); |
46 | } | 46 | } |
47 | 47 | ||
48 | void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val) | ||
49 | { | ||
50 | PDprintk("%x writing to %x: %x\n", slot, offset, val); | ||
51 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | ||
52 | outb(val, 0xcfc); | ||
53 | } | ||
54 | |||
48 | int early_pci_allowed(void) | 55 | int early_pci_allowed(void) |
49 | { | 56 | { |
50 | return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) == | 57 | return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) == |
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index b60d7e8689ed..cde1170b01a1 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c | |||
@@ -74,52 +74,6 @@ static void __devinit pci_fixup_ncr53c810(struct pci_dev *d) | |||
74 | } | 74 | } |
75 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, pci_fixup_ncr53c810); | 75 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, pci_fixup_ncr53c810); |
76 | 76 | ||
77 | static void __devinit pci_fixup_ide_bases(struct pci_dev *d) | ||
78 | { | ||
79 | int i; | ||
80 | |||
81 | /* | ||
82 | * PCI IDE controllers use non-standard I/O port decoding, respect it. | ||
83 | */ | ||
84 | if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) | ||
85 | return; | ||
86 | DBG("PCI: IDE base address fixup for %s\n", pci_name(d)); | ||
87 | for(i=0; i<4; i++) { | ||
88 | struct resource *r = &d->resource[i]; | ||
89 | if ((r->start & ~0x80) == 0x374) { | ||
90 | r->start |= 2; | ||
91 | r->end = r->start; | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); | ||
96 | |||
97 | static void __devinit pci_fixup_ide_trash(struct pci_dev *d) | ||
98 | { | ||
99 | int i; | ||
100 | |||
101 | /* | ||
102 | * Runs the fixup only for the first IDE controller | ||
103 | * (Shai Fultheim - shai@ftcon.com) | ||
104 | */ | ||
105 | static int called = 0; | ||
106 | if (called) | ||
107 | return; | ||
108 | called = 1; | ||
109 | |||
110 | /* | ||
111 | * There exist PCI IDE controllers which have utter garbage | ||
112 | * in first four base registers. Ignore that. | ||
113 | */ | ||
114 | DBG("PCI: IDE base address trash cleared for %s\n", pci_name(d)); | ||
115 | for(i=0; i<4; i++) | ||
116 | d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0; | ||
117 | } | ||
118 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, pci_fixup_ide_trash); | ||
119 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_fixup_ide_trash); | ||
120 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11, pci_fixup_ide_trash); | ||
121 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_9, pci_fixup_ide_trash); | ||
122 | |||
123 | static void __devinit pci_fixup_latency(struct pci_dev *d) | 77 | static void __devinit pci_fixup_latency(struct pci_dev *d) |
124 | { | 78 | { |
125 | /* | 79 | /* |
@@ -348,8 +302,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_r | |||
348 | * From information provided by "Jon Smirl" <jonsmirl@gmail.com> | 302 | * From information provided by "Jon Smirl" <jonsmirl@gmail.com> |
349 | * | 303 | * |
350 | * The standard boot ROM sequence for an x86 machine uses the BIOS | 304 | * 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 | 305 | * 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. | 306 | * card will have it's BIOS copied to C0000 in system RAM. |
353 | * IORESOURCE_ROM_SHADOW is used to associate the boot video | 307 | * IORESOURCE_ROM_SHADOW is used to associate the boot video |
354 | * card with this copy. On laptops this copy has to be used since | 308 | * 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. | 309 | * the main ROM may be compressed or combined with another image. |
@@ -371,7 +325,17 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) | |||
371 | bus = pdev->bus; | 325 | bus = pdev->bus; |
372 | while (bus) { | 326 | while (bus) { |
373 | bridge = bus->self; | 327 | bridge = bus->self; |
374 | if (bridge) { | 328 | |
329 | /* | ||
330 | * From information provided by | ||
331 | * "David Miller" <davem@davemloft.net> | ||
332 | * The bridge control register is valid for PCI header | ||
333 | * type BRIDGE, or CARDBUS. Host to PCI controllers use | ||
334 | * PCI header type NORMAL. | ||
335 | */ | ||
336 | if (bridge | ||
337 | &&((bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE) | ||
338 | ||(bridge->hdr_type == PCI_HEADER_TYPE_CARDBUS))) { | ||
375 | pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, | 339 | pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, |
376 | &config); | 340 | &config); |
377 | if (!(config & PCI_BRIDGE_CTL_VGA)) | 341 | if (!(config & PCI_BRIDGE_CTL_VGA)) |
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index 10154a2cac68..43005f044424 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c | |||
@@ -104,16 +104,24 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
104 | /* Depth-First Search on bus tree */ | 104 | /* Depth-First Search on bus tree */ |
105 | list_for_each_entry(bus, bus_list, node) { | 105 | list_for_each_entry(bus, bus_list, node) { |
106 | if ((dev = bus->self)) { | 106 | if ((dev = bus->self)) { |
107 | for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { | 107 | for (idx = PCI_BRIDGE_RESOURCES; |
108 | idx < PCI_NUM_RESOURCES; idx++) { | ||
108 | r = &dev->resource[idx]; | 109 | r = &dev->resource[idx]; |
109 | if (!r->flags) | 110 | if (!r->flags) |
110 | continue; | 111 | continue; |
111 | pr = pci_find_parent_resource(dev, r); | 112 | pr = pci_find_parent_resource(dev, r); |
112 | if (!r->start || !pr || request_resource(pr, r) < 0) { | 113 | if (!r->start || !pr || |
113 | printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); | 114 | request_resource(pr, r) < 0) { |
114 | /* Something is wrong with the region. | 115 | printk(KERN_ERR "PCI: Cannot allocate " |
115 | Invalidate the resource to prevent child | 116 | "resource region %d " |
116 | resource allocations in this range. */ | 117 | "of bridge %s\n", |
118 | idx, pci_name(dev)); | ||
119 | /* | ||
120 | * Something is wrong with the region. | ||
121 | * Invalidate the resource to prevent | ||
122 | * child resource allocations in this | ||
123 | * range. | ||
124 | */ | ||
117 | r->flags = 0; | 125 | r->flags = 0; |
118 | } | 126 | } |
119 | } | 127 | } |
@@ -131,7 +139,7 @@ static void __init pcibios_allocate_resources(int pass) | |||
131 | 139 | ||
132 | for_each_pci_dev(dev) { | 140 | for_each_pci_dev(dev) { |
133 | pci_read_config_word(dev, PCI_COMMAND, &command); | 141 | pci_read_config_word(dev, PCI_COMMAND, &command); |
134 | for(idx = 0; idx < 6; idx++) { | 142 | for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { |
135 | r = &dev->resource[idx]; | 143 | r = &dev->resource[idx]; |
136 | if (r->parent) /* Already allocated */ | 144 | if (r->parent) /* Already allocated */ |
137 | continue; | 145 | continue; |
@@ -142,11 +150,15 @@ static void __init pcibios_allocate_resources(int pass) | |||
142 | else | 150 | else |
143 | disabled = !(command & PCI_COMMAND_MEMORY); | 151 | disabled = !(command & PCI_COMMAND_MEMORY); |
144 | if (pass == disabled) { | 152 | if (pass == disabled) { |
145 | DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n", | 153 | DBG("PCI: Resource %08lx-%08lx " |
154 | "(f=%lx, d=%d, p=%d)\n", | ||
146 | r->start, r->end, r->flags, disabled, pass); | 155 | r->start, r->end, r->flags, disabled, pass); |
147 | pr = pci_find_parent_resource(dev, r); | 156 | pr = pci_find_parent_resource(dev, r); |
148 | if (!pr || request_resource(pr, r) < 0) { | 157 | if (!pr || request_resource(pr, r) < 0) { |
149 | printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev)); | 158 | printk(KERN_ERR "PCI: Cannot allocate " |
159 | "resource region %d " | ||
160 | "of device %s\n", | ||
161 | idx, pci_name(dev)); | ||
150 | /* We'll assign a new address later */ | 162 | /* We'll assign a new address later */ |
151 | r->end -= r->start; | 163 | r->end -= r->start; |
152 | r->start = 0; | 164 | r->start = 0; |
@@ -156,12 +168,16 @@ static void __init pcibios_allocate_resources(int pass) | |||
156 | if (!pass) { | 168 | if (!pass) { |
157 | r = &dev->resource[PCI_ROM_RESOURCE]; | 169 | r = &dev->resource[PCI_ROM_RESOURCE]; |
158 | if (r->flags & IORESOURCE_ROM_ENABLE) { | 170 | if (r->flags & IORESOURCE_ROM_ENABLE) { |
159 | /* Turn the ROM off, leave the resource region, but keep it unregistered. */ | 171 | /* Turn the ROM off, leave the resource region, |
172 | * but keep it unregistered. */ | ||
160 | u32 reg; | 173 | u32 reg; |
161 | DBG("PCI: Switching off ROM of %s\n", pci_name(dev)); | 174 | DBG("PCI: Switching off ROM of %s\n", |
175 | pci_name(dev)); | ||
162 | r->flags &= ~IORESOURCE_ROM_ENABLE; | 176 | r->flags &= ~IORESOURCE_ROM_ENABLE; |
163 | pci_read_config_dword(dev, dev->rom_base_reg, ®); | 177 | pci_read_config_dword(dev, |
164 | pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE); | 178 | dev->rom_base_reg, ®); |
179 | pci_write_config_dword(dev, dev->rom_base_reg, | ||
180 | reg & ~PCI_ROM_ADDRESS_ENABLE); | ||
165 | } | 181 | } |
166 | } | 182 | } |
167 | } | 183 | } |
@@ -173,9 +189,11 @@ static int __init pcibios_assign_resources(void) | |||
173 | struct resource *r, *pr; | 189 | struct resource *r, *pr; |
174 | 190 | ||
175 | if (!(pci_probe & PCI_ASSIGN_ROMS)) { | 191 | if (!(pci_probe & PCI_ASSIGN_ROMS)) { |
176 | /* Try to use BIOS settings for ROMs, otherwise let | 192 | /* |
177 | pci_assign_unassigned_resources() allocate the new | 193 | * Try to use BIOS settings for ROMs, otherwise let |
178 | addresses. */ | 194 | * pci_assign_unassigned_resources() allocate the new |
195 | * addresses. | ||
196 | */ | ||
179 | for_each_pci_dev(dev) { | 197 | for_each_pci_dev(dev) { |
180 | r = &dev->resource[PCI_ROM_RESOURCE]; | 198 | r = &dev->resource[PCI_ROM_RESOURCE]; |
181 | if (!r->flags || !r->start) | 199 | if (!r->flags || !r->start) |
@@ -215,9 +233,9 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) | |||
215 | 233 | ||
216 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | 234 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
217 | old_cmd = cmd; | 235 | old_cmd = cmd; |
218 | for(idx = 0; idx < PCI_NUM_RESOURCES; idx++) { | 236 | for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { |
219 | /* Only set up the requested stuff */ | 237 | /* Only set up the requested stuff */ |
220 | if (!(mask & (1<<idx))) | 238 | if (!(mask & (1 << idx))) |
221 | continue; | 239 | continue; |
222 | 240 | ||
223 | r = &dev->resource[idx]; | 241 | r = &dev->resource[idx]; |
@@ -227,7 +245,9 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) | |||
227 | (!(r->flags & IORESOURCE_ROM_ENABLE))) | 245 | (!(r->flags & IORESOURCE_ROM_ENABLE))) |
228 | continue; | 246 | continue; |
229 | if (!r->start && r->end) { | 247 | if (!r->start && r->end) { |
230 | printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev)); | 248 | printk(KERN_ERR "PCI: Device %s not available " |
249 | "because of resource collisions\n", | ||
250 | pci_name(dev)); | ||
231 | return -EINVAL; | 251 | return -EINVAL; |
232 | } | 252 | } |
233 | if (r->flags & IORESOURCE_IO) | 253 | if (r->flags & IORESOURCE_IO) |
@@ -236,21 +256,13 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) | |||
236 | cmd |= PCI_COMMAND_MEMORY; | 256 | cmd |= PCI_COMMAND_MEMORY; |
237 | } | 257 | } |
238 | if (cmd != old_cmd) { | 258 | if (cmd != old_cmd) { |
239 | printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); | 259 | printk("PCI: Enabling device %s (%04x -> %04x)\n", |
260 | pci_name(dev), old_cmd, cmd); | ||
240 | pci_write_config_word(dev, PCI_COMMAND, cmd); | 261 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
241 | } | 262 | } |
242 | return 0; | 263 | return 0; |
243 | } | 264 | } |
244 | 265 | ||
245 | void pcibios_disable_resources(struct pci_dev *dev) | ||
246 | { | ||
247 | u16 cmd; | ||
248 | |||
249 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
250 | cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY); | ||
251 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
252 | } | ||
253 | |||
254 | /* | 266 | /* |
255 | * If we set up a device for bus mastering, we need to check the latency | 267 | * If we set up a device for bus mastering, we need to check the latency |
256 | * timer as certain crappy BIOSes forget to set it properly. | 268 | * timer as certain crappy BIOSes forget to set it properly. |
@@ -267,7 +279,8 @@ void pcibios_set_master(struct pci_dev *dev) | |||
267 | lat = pcibios_max_latency; | 279 | lat = pcibios_max_latency; |
268 | else | 280 | else |
269 | return; | 281 | return; |
270 | printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); | 282 | printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", |
283 | pci_name(dev), lat); | ||
271 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); | 284 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); |
272 | } | 285 | } |
273 | 286 | ||
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index dbc4aae91959..f2cb942f8281 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -255,13 +255,13 @@ static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i | |||
255 | */ | 255 | */ |
256 | static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | 256 | static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) |
257 | { | 257 | { |
258 | static const unsigned int pirqmap[4] = { 3, 2, 5, 1 }; | 258 | static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; |
259 | return read_config_nybble(router, 0x55, pirqmap[pirq-1]); | 259 | return read_config_nybble(router, 0x55, pirqmap[pirq-1]); |
260 | } | 260 | } |
261 | 261 | ||
262 | static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | 262 | static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
263 | { | 263 | { |
264 | static const unsigned int pirqmap[4] = { 3, 2, 5, 1 }; | 264 | static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; |
265 | write_config_nybble(router, 0x55, pirqmap[pirq-1], irq); | 265 | write_config_nybble(router, 0x55, pirqmap[pirq-1], irq); |
266 | return 1; | 266 | return 1; |
267 | } | 267 | } |
@@ -543,6 +543,12 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route | |||
543 | case PCI_DEVICE_ID_INTEL_ICH8_2: | 543 | case PCI_DEVICE_ID_INTEL_ICH8_2: |
544 | case PCI_DEVICE_ID_INTEL_ICH8_3: | 544 | case PCI_DEVICE_ID_INTEL_ICH8_3: |
545 | case PCI_DEVICE_ID_INTEL_ICH8_4: | 545 | case PCI_DEVICE_ID_INTEL_ICH8_4: |
546 | case PCI_DEVICE_ID_INTEL_ICH9_0: | ||
547 | case PCI_DEVICE_ID_INTEL_ICH9_1: | ||
548 | case PCI_DEVICE_ID_INTEL_ICH9_2: | ||
549 | case PCI_DEVICE_ID_INTEL_ICH9_3: | ||
550 | case PCI_DEVICE_ID_INTEL_ICH9_4: | ||
551 | case PCI_DEVICE_ID_INTEL_ICH9_5: | ||
546 | r->name = "PIIX/ICH"; | 552 | r->name = "PIIX/ICH"; |
547 | r->get = pirq_piix_get; | 553 | r->get = pirq_piix_get; |
548 | r->set = pirq_piix_set; | 554 | r->set = pirq_piix_set; |
@@ -758,7 +764,7 @@ static void __init pirq_find_router(struct irq_router *r) | |||
758 | DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for %04x:%04x\n", | 764 | DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for %04x:%04x\n", |
759 | rt->rtr_vendor, rt->rtr_device); | 765 | rt->rtr_vendor, rt->rtr_device); |
760 | 766 | ||
761 | pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn); | 767 | pirq_router_dev = pci_get_bus_and_slot(rt->rtr_bus, rt->rtr_devfn); |
762 | if (!pirq_router_dev) { | 768 | if (!pirq_router_dev) { |
763 | DBG(KERN_DEBUG "PCI: Interrupt router not found at " | 769 | DBG(KERN_DEBUG "PCI: Interrupt router not found at " |
764 | "%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); | 770 | "%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); |
@@ -778,6 +784,8 @@ static void __init pirq_find_router(struct irq_router *r) | |||
778 | pirq_router_dev->vendor, | 784 | pirq_router_dev->vendor, |
779 | pirq_router_dev->device, | 785 | pirq_router_dev->device, |
780 | pci_name(pirq_router_dev)); | 786 | pci_name(pirq_router_dev)); |
787 | |||
788 | /* The device remains referenced for the kernel lifetime */ | ||
781 | } | 789 | } |
782 | 790 | ||
783 | static struct irq_info *pirq_get_info(struct pci_dev *dev) | 791 | static struct irq_info *pirq_get_info(struct pci_dev *dev) |
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index d0c3da3aa2aa..c6b6d9bbc453 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -154,38 +154,6 @@ static struct pci_raw_ops pci_mmcfg = { | |||
154 | .write = pci_mmcfg_write, | 154 | .write = pci_mmcfg_write, |
155 | }; | 155 | }; |
156 | 156 | ||
157 | |||
158 | static __init void pci_mmcfg_insert_resources(void) | ||
159 | { | ||
160 | #define PCI_MMCFG_RESOURCE_NAME_LEN 19 | ||
161 | int i; | ||
162 | struct resource *res; | ||
163 | char *names; | ||
164 | unsigned num_buses; | ||
165 | |||
166 | res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res), | ||
167 | pci_mmcfg_config_num, GFP_KERNEL); | ||
168 | |||
169 | if (!res) { | ||
170 | printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n"); | ||
171 | return; | ||
172 | } | ||
173 | |||
174 | names = (void *)&res[pci_mmcfg_config_num]; | ||
175 | for (i = 0; i < pci_mmcfg_config_num; i++, res++) { | ||
176 | num_buses = pci_mmcfg_config[i].end_bus_number - | ||
177 | pci_mmcfg_config[i].start_bus_number + 1; | ||
178 | res->name = names; | ||
179 | snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u", | ||
180 | pci_mmcfg_config[i].pci_segment_group_number); | ||
181 | res->start = pci_mmcfg_config[i].base_address; | ||
182 | res->end = res->start + (num_buses << 20) - 1; | ||
183 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
184 | insert_resource(&iomem_resource, res); | ||
185 | names += PCI_MMCFG_RESOURCE_NAME_LEN; | ||
186 | } | ||
187 | } | ||
188 | |||
189 | /* K8 systems have some devices (typically in the builtin northbridge) | 157 | /* K8 systems have some devices (typically in the builtin northbridge) |
190 | that are only accessible using type1 | 158 | that are only accessible using type1 |
191 | Normally this can be expressed in the MCFG by not listing them | 159 | Normally this can be expressed in the MCFG by not listing them |
@@ -222,8 +190,6 @@ static __init void unreachable_devices(void) | |||
222 | } | 190 | } |
223 | } | 191 | } |
224 | 192 | ||
225 | |||
226 | |||
227 | void __init pci_mmcfg_init(int type) | 193 | void __init pci_mmcfg_init(int type) |
228 | { | 194 | { |
229 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | 195 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) |
@@ -251,5 +217,4 @@ void __init pci_mmcfg_init(int type) | |||
251 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | 217 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; |
252 | 218 | ||
253 | unreachable_devices(); | 219 | unreachable_devices(); |
254 | pci_mmcfg_insert_resources(); | ||
255 | } | 220 | } |
diff --git a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c index ed1512a175ab..5f5193401bea 100644 --- a/arch/i386/pci/pcbios.c +++ b/arch/i386/pci/pcbios.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/uaccess.h> | ||
8 | #include "pci.h" | 9 | #include "pci.h" |
9 | #include "pci-functions.h" | 10 | #include "pci-functions.h" |
10 | 11 | ||
@@ -314,6 +315,10 @@ static struct pci_raw_ops * __devinit pci_find_bios(void) | |||
314 | for (check = (union bios32 *) __va(0xe0000); | 315 | for (check = (union bios32 *) __va(0xe0000); |
315 | check <= (union bios32 *) __va(0xffff0); | 316 | check <= (union bios32 *) __va(0xffff0); |
316 | ++check) { | 317 | ++check) { |
318 | long sig; | ||
319 | if (probe_kernel_address(&check->fields.signature, sig)) | ||
320 | continue; | ||
321 | |||
317 | if (check->fields.signature != BIOS32_SIGNATURE) | 322 | if (check->fields.signature != BIOS32_SIGNATURE) |
318 | continue; | 323 | continue; |
319 | length = check->fields.length * 16; | 324 | length = check->fields.length * 16; |
@@ -331,11 +336,13 @@ static struct pci_raw_ops * __devinit pci_find_bios(void) | |||
331 | } | 336 | } |
332 | DBG("PCI: BIOS32 Service Directory structure at 0x%p\n", check); | 337 | DBG("PCI: BIOS32 Service Directory structure at 0x%p\n", check); |
333 | if (check->fields.entry >= 0x100000) { | 338 | if (check->fields.entry >= 0x100000) { |
334 | printk("PCI: BIOS32 entry (0x%p) in high memory, cannot use.\n", check); | 339 | printk("PCI: BIOS32 entry (0x%p) in high memory, " |
340 | "cannot use.\n", check); | ||
335 | return NULL; | 341 | return NULL; |
336 | } else { | 342 | } else { |
337 | unsigned long bios32_entry = check->fields.entry; | 343 | unsigned long bios32_entry = check->fields.entry; |
338 | DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n", bios32_entry); | 344 | DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n", |
345 | bios32_entry); | ||
339 | bios32_indirect.address = bios32_entry + PAGE_OFFSET; | 346 | bios32_indirect.address = bios32_entry + PAGE_OFFSET; |
340 | if (check_pcibios()) | 347 | if (check_pcibios()) |
341 | return &pci_bios_access; | 348 | return &pci_bios_access; |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index 1814f74569c6..a0a25180b61a 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -30,13 +30,19 @@ | |||
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; |
36 | 43 | ||
37 | void pcibios_resource_survey(void); | 44 | void pcibios_resource_survey(void); |
38 | int pcibios_enable_resources(struct pci_dev *, int); | 45 | int pcibios_enable_resources(struct pci_dev *, int); |
39 | void pcibios_disable_resources(struct pci_dev *); | ||
40 | 46 | ||
41 | /* pci-pc.c */ | 47 | /* pci-pc.c */ |
42 | 48 | ||