0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/efi.h>
0010 #include <linux/pci.h>
0011
0012 #include <asm/efi.h>
0013
0014 #include "efistub.h"
0015
0016 void efi_pci_disable_bridge_busmaster(void)
0017 {
0018 efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
0019 unsigned long pci_handle_size = 0;
0020 efi_handle_t *pci_handle = NULL;
0021 efi_handle_t handle;
0022 efi_status_t status;
0023 u16 class, command;
0024 int i;
0025
0026 status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL, &pci_proto,
0027 NULL, &pci_handle_size, NULL);
0028
0029 if (status != EFI_BUFFER_TOO_SMALL) {
0030 if (status != EFI_SUCCESS && status != EFI_NOT_FOUND)
0031 efi_err("Failed to locate PCI I/O handles'\n");
0032 return;
0033 }
0034
0035 status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, pci_handle_size,
0036 (void **)&pci_handle);
0037 if (status != EFI_SUCCESS) {
0038 efi_err("Failed to allocate memory for 'pci_handle'\n");
0039 return;
0040 }
0041
0042 status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL, &pci_proto,
0043 NULL, &pci_handle_size, pci_handle);
0044 if (status != EFI_SUCCESS) {
0045 efi_err("Failed to locate PCI I/O handles'\n");
0046 goto free_handle;
0047 }
0048
0049 for_each_efi_handle(handle, pci_handle, pci_handle_size, i) {
0050 efi_pci_io_protocol_t *pci;
0051 unsigned long segment_nr, bus_nr, device_nr, func_nr;
0052
0053 status = efi_bs_call(handle_protocol, handle, &pci_proto,
0054 (void **)&pci);
0055 if (status != EFI_SUCCESS)
0056 continue;
0057
0058
0059
0060
0061
0062 status = efi_call_proto(pci, get_location, &segment_nr, &bus_nr,
0063 &device_nr, &func_nr);
0064 if (status != EFI_SUCCESS || bus_nr == 0)
0065 continue;
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,
0077 PCI_CLASS_DEVICE, 1, &class);
0078 if (status != EFI_SUCCESS || class == PCI_CLASS_DISPLAY_VGA)
0079 continue;
0080
0081
0082 efi_bs_call(disconnect_controller, handle, NULL, NULL);
0083 }
0084
0085 for_each_efi_handle(handle, pci_handle, pci_handle_size, i) {
0086 efi_pci_io_protocol_t *pci;
0087
0088 status = efi_bs_call(handle_protocol, handle, &pci_proto,
0089 (void **)&pci);
0090 if (status != EFI_SUCCESS || !pci)
0091 continue;
0092
0093 status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,
0094 PCI_CLASS_DEVICE, 1, &class);
0095
0096 if (status != EFI_SUCCESS || class != PCI_CLASS_BRIDGE_PCI)
0097 continue;
0098
0099
0100 status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16,
0101 PCI_COMMAND, 1, &command);
0102 if (status != EFI_SUCCESS || !(command & PCI_COMMAND_MASTER))
0103 continue;
0104
0105 command &= ~PCI_COMMAND_MASTER;
0106 status = efi_call_proto(pci, pci.write, EfiPciIoWidthUint16,
0107 PCI_COMMAND, 1, &command);
0108 if (status != EFI_SUCCESS)
0109 efi_err("Failed to disable PCI busmastering\n");
0110 }
0111
0112 free_handle:
0113 efi_bs_call(free_pool, pci_handle);
0114 }