diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 15:14:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 15:14:47 -0500 |
commit | 193c0d682525987db59ac3a24531a77e4947aa95 (patch) | |
tree | 7b58346171c4d07e2c2ee6c3c469c325495149a4 /arch/x86/boot/compressed/eboot.c | |
parent | 8b0cab14951fbf8126795ab301835a8f8126a988 (diff) | |
parent | 1cb73f8c479e66541fefd3f7fa547b1fa56cdc54 (diff) |
Merge tag 'for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI update from Bjorn Helgaas:
"Host bridge hotplug:
- Untangle _PRT from struct pci_bus (Bjorn Helgaas)
- Request _OSC control before scanning root bus (Taku Izumi)
- Assign resources when adding host bridge (Yinghai Lu)
- Remove root bus when removing host bridge (Yinghai Lu)
- Remove _PRT during hot remove (Yinghai Lu)
SRIOV
- Add sysfs knobs to control numVFs (Don Dutile)
Power management
- Notify devices when power resource turned on (Huang Ying)
Bug fixes
- Work around broken _SEG on HP xw9300 (Bjorn Helgaas)
- Keep runtime PM enabled for unbound PCI devices (Huang Ying)
- Fix Optimus dual-GPU runtime D3 suspend issue (Dave Airlie)
- Fix xen frontend shutdown issue (David Vrabel)
- Work around PLX PCI 9050 BAR alignment erratum (Ian Abbott)
Miscellaneous
- Add GPL license for drivers/pci/ioapic (Andrew Cooks)
- Add standard PCI-X, PCIe ASPM register #defines (Bjorn Helgaas)
- NumaChip remote PCI support (Daniel Blueman)
- Fix PCIe Link Capabilities Supported Link Speed definition (Jingoo
Han)
- Convert dev_printk() to dev_info(), etc (Joe Perches)
- Add support for non PCI BAR ROM data (Matthew Garrett)
- Add x86 support for host bridge translation offset (Mike Yoknis)
- Report success only when every driver supports AER (Vijay
Pandarathil)"
Fix up trivial conflicts.
* tag 'for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (48 commits)
PCI: Use phys_addr_t for physical ROM address
x86/PCI: Add NumaChip remote PCI support
ath9k: Use standard #defines for PCIe Capability ASPM fields
iwlwifi: Use standard #defines for PCIe Capability ASPM fields
iwlwifi: collapse wrapper for pcie_capability_read_word()
iwlegacy: Use standard #defines for PCIe Capability ASPM fields
iwlegacy: collapse wrapper for pcie_capability_read_word()
cxgb3: Use standard #defines for PCIe Capability ASPM fields
PCI: Add standard PCIe Capability Link ASPM field names
PCI/portdrv: Use PCI Express Capability accessors
PCI: Use standard PCIe Capability Link register field names
x86: Use PCI setup data
PCI: Add support for non-BAR ROMs
PCI: Add pcibios_add_device
EFI: Stash ROMs if they're not in the PCI BAR
PCI: Add and use standard PCI-X Capability register names
PCI/PM: Keep runtime PM enabled for unbound PCI devices
xen-pcifront: Handle backend CLOSED without CLOSING
PCI: SRIOV control and status via sysfs (documentation)
PCI/AER: Report success only when every device has AER-aware driver
...
Diffstat (limited to 'arch/x86/boot/compressed/eboot.c')
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index e87b0cac14b5..b1942e222768 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * ----------------------------------------------------------------------- */ | 8 | * ----------------------------------------------------------------------- */ |
9 | 9 | ||
10 | #include <linux/efi.h> | 10 | #include <linux/efi.h> |
11 | #include <linux/pci.h> | ||
11 | #include <asm/efi.h> | 12 | #include <asm/efi.h> |
12 | #include <asm/setup.h> | 13 | #include <asm/setup.h> |
13 | #include <asm/desc.h> | 14 | #include <asm/desc.h> |
@@ -245,6 +246,121 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size) | |||
245 | *size = len; | 246 | *size = len; |
246 | } | 247 | } |
247 | 248 | ||
249 | static efi_status_t setup_efi_pci(struct boot_params *params) | ||
250 | { | ||
251 | efi_pci_io_protocol *pci; | ||
252 | efi_status_t status; | ||
253 | void **pci_handle; | ||
254 | efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; | ||
255 | unsigned long nr_pci, size = 0; | ||
256 | int i; | ||
257 | struct setup_data *data; | ||
258 | |||
259 | data = (struct setup_data *)params->hdr.setup_data; | ||
260 | |||
261 | while (data && data->next) | ||
262 | data = (struct setup_data *)data->next; | ||
263 | |||
264 | status = efi_call_phys5(sys_table->boottime->locate_handle, | ||
265 | EFI_LOCATE_BY_PROTOCOL, &pci_proto, | ||
266 | NULL, &size, pci_handle); | ||
267 | |||
268 | if (status == EFI_BUFFER_TOO_SMALL) { | ||
269 | status = efi_call_phys3(sys_table->boottime->allocate_pool, | ||
270 | EFI_LOADER_DATA, size, &pci_handle); | ||
271 | |||
272 | if (status != EFI_SUCCESS) | ||
273 | return status; | ||
274 | |||
275 | status = efi_call_phys5(sys_table->boottime->locate_handle, | ||
276 | EFI_LOCATE_BY_PROTOCOL, &pci_proto, | ||
277 | NULL, &size, pci_handle); | ||
278 | } | ||
279 | |||
280 | if (status != EFI_SUCCESS) | ||
281 | goto free_handle; | ||
282 | |||
283 | nr_pci = size / sizeof(void *); | ||
284 | for (i = 0; i < nr_pci; i++) { | ||
285 | void *h = pci_handle[i]; | ||
286 | uint64_t attributes; | ||
287 | struct pci_setup_rom *rom; | ||
288 | |||
289 | status = efi_call_phys3(sys_table->boottime->handle_protocol, | ||
290 | h, &pci_proto, &pci); | ||
291 | |||
292 | if (status != EFI_SUCCESS) | ||
293 | continue; | ||
294 | |||
295 | if (!pci) | ||
296 | continue; | ||
297 | |||
298 | status = efi_call_phys4(pci->attributes, pci, | ||
299 | EfiPciIoAttributeOperationGet, 0, | ||
300 | &attributes); | ||
301 | |||
302 | if (status != EFI_SUCCESS) | ||
303 | continue; | ||
304 | |||
305 | if (!attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM) | ||
306 | continue; | ||
307 | |||
308 | if (!pci->romimage || !pci->romsize) | ||
309 | continue; | ||
310 | |||
311 | size = pci->romsize + sizeof(*rom); | ||
312 | |||
313 | status = efi_call_phys3(sys_table->boottime->allocate_pool, | ||
314 | EFI_LOADER_DATA, size, &rom); | ||
315 | |||
316 | if (status != EFI_SUCCESS) | ||
317 | continue; | ||
318 | |||
319 | rom->data.type = SETUP_PCI; | ||
320 | rom->data.len = size - sizeof(struct setup_data); | ||
321 | rom->data.next = 0; | ||
322 | rom->pcilen = pci->romsize; | ||
323 | |||
324 | status = efi_call_phys5(pci->pci.read, pci, | ||
325 | EfiPciIoWidthUint16, PCI_VENDOR_ID, | ||
326 | 1, &(rom->vendor)); | ||
327 | |||
328 | if (status != EFI_SUCCESS) | ||
329 | goto free_struct; | ||
330 | |||
331 | status = efi_call_phys5(pci->pci.read, pci, | ||
332 | EfiPciIoWidthUint16, PCI_DEVICE_ID, | ||
333 | 1, &(rom->devid)); | ||
334 | |||
335 | if (status != EFI_SUCCESS) | ||
336 | goto free_struct; | ||
337 | |||
338 | status = efi_call_phys5(pci->get_location, pci, | ||
339 | &(rom->segment), &(rom->bus), | ||
340 | &(rom->device), &(rom->function)); | ||
341 | |||
342 | if (status != EFI_SUCCESS) | ||
343 | goto free_struct; | ||
344 | |||
345 | memcpy(rom->romdata, pci->romimage, pci->romsize); | ||
346 | |||
347 | if (data) | ||
348 | data->next = (uint64_t)rom; | ||
349 | else | ||
350 | params->hdr.setup_data = (uint64_t)rom; | ||
351 | |||
352 | data = (struct setup_data *)rom; | ||
353 | |||
354 | continue; | ||
355 | free_struct: | ||
356 | efi_call_phys1(sys_table->boottime->free_pool, rom); | ||
357 | } | ||
358 | |||
359 | free_handle: | ||
360 | efi_call_phys1(sys_table->boottime->free_pool, pci_handle); | ||
361 | return status; | ||
362 | } | ||
363 | |||
248 | /* | 364 | /* |
249 | * See if we have Graphics Output Protocol | 365 | * See if we have Graphics Output Protocol |
250 | */ | 366 | */ |
@@ -1028,6 +1144,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, | |||
1028 | 1144 | ||
1029 | setup_graphics(boot_params); | 1145 | setup_graphics(boot_params); |
1030 | 1146 | ||
1147 | setup_efi_pci(boot_params); | ||
1148 | |||
1031 | status = efi_call_phys3(sys_table->boottime->allocate_pool, | 1149 | status = efi_call_phys3(sys_table->boottime->allocate_pool, |
1032 | EFI_LOADER_DATA, sizeof(*gdt), | 1150 | EFI_LOADER_DATA, sizeof(*gdt), |
1033 | (void **)&gdt); | 1151 | (void **)&gdt); |