diff options
| -rw-r--r-- | arch/x86/pci/acpi.c | 44 | ||||
| -rw-r--r-- | drivers/pci/pci.c | 6 | ||||
| -rw-r--r-- | drivers/pci/pcie/aer/aerdrv.c | 10 | ||||
| -rw-r--r-- | drivers/pci/probe.c | 23 |
4 files changed, 53 insertions, 30 deletions
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index c7b1ebfb7da7..44f83ce02470 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
| @@ -66,14 +66,44 @@ resource_to_addr(struct acpi_resource *resource, | |||
| 66 | struct acpi_resource_address64 *addr) | 66 | struct acpi_resource_address64 *addr) |
| 67 | { | 67 | { |
| 68 | acpi_status status; | 68 | acpi_status status; |
| 69 | 69 | struct acpi_resource_memory24 *memory24; | |
| 70 | status = acpi_resource_to_address64(resource, addr); | 70 | struct acpi_resource_memory32 *memory32; |
| 71 | if (ACPI_SUCCESS(status) && | 71 | struct acpi_resource_fixed_memory32 *fixed_memory32; |
| 72 | (addr->resource_type == ACPI_MEMORY_RANGE || | 72 | |
| 73 | addr->resource_type == ACPI_IO_RANGE) && | 73 | memset(addr, 0, sizeof(*addr)); |
| 74 | addr->address_length > 0 && | 74 | switch (resource->type) { |
| 75 | addr->producer_consumer == ACPI_PRODUCER) { | 75 | case ACPI_RESOURCE_TYPE_MEMORY24: |
| 76 | memory24 = &resource->data.memory24; | ||
| 77 | addr->resource_type = ACPI_MEMORY_RANGE; | ||
| 78 | addr->minimum = memory24->minimum; | ||
| 79 | addr->address_length = memory24->address_length; | ||
| 80 | addr->maximum = addr->minimum + addr->address_length - 1; | ||
| 81 | return AE_OK; | ||
| 82 | case ACPI_RESOURCE_TYPE_MEMORY32: | ||
| 83 | memory32 = &resource->data.memory32; | ||
| 84 | addr->resource_type = ACPI_MEMORY_RANGE; | ||
| 85 | addr->minimum = memory32->minimum; | ||
| 86 | addr->address_length = memory32->address_length; | ||
| 87 | addr->maximum = addr->minimum + addr->address_length - 1; | ||
| 76 | return AE_OK; | 88 | return AE_OK; |
| 89 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | ||
| 90 | fixed_memory32 = &resource->data.fixed_memory32; | ||
| 91 | addr->resource_type = ACPI_MEMORY_RANGE; | ||
| 92 | addr->minimum = fixed_memory32->address; | ||
| 93 | addr->address_length = fixed_memory32->address_length; | ||
| 94 | addr->maximum = addr->minimum + addr->address_length - 1; | ||
| 95 | return AE_OK; | ||
| 96 | case ACPI_RESOURCE_TYPE_ADDRESS16: | ||
| 97 | case ACPI_RESOURCE_TYPE_ADDRESS32: | ||
| 98 | case ACPI_RESOURCE_TYPE_ADDRESS64: | ||
| 99 | status = acpi_resource_to_address64(resource, addr); | ||
| 100 | if (ACPI_SUCCESS(status) && | ||
| 101 | (addr->resource_type == ACPI_MEMORY_RANGE || | ||
| 102 | addr->resource_type == ACPI_IO_RANGE) && | ||
| 103 | addr->address_length > 0) { | ||
| 104 | return AE_OK; | ||
| 105 | } | ||
| 106 | break; | ||
| 77 | } | 107 | } |
| 78 | return AE_ERROR; | 108 | return AE_ERROR; |
| 79 | } | 109 | } |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5ea587e59e48..37499127c801 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -679,7 +679,7 @@ static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state) | |||
| 679 | */ | 679 | */ |
| 680 | int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state) | 680 | int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state) |
| 681 | { | 681 | { |
| 682 | return state > PCI_D0 ? | 682 | return state >= PCI_D0 ? |
| 683 | pci_platform_power_transition(dev, state) : -EINVAL; | 683 | pci_platform_power_transition(dev, state) : -EINVAL; |
| 684 | } | 684 | } |
| 685 | EXPORT_SYMBOL_GPL(__pci_complete_power_transition); | 685 | EXPORT_SYMBOL_GPL(__pci_complete_power_transition); |
| @@ -716,10 +716,6 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
| 716 | */ | 716 | */ |
| 717 | return 0; | 717 | return 0; |
| 718 | 718 | ||
| 719 | /* Check if we're already there */ | ||
| 720 | if (dev->current_state == state) | ||
| 721 | return 0; | ||
| 722 | |||
| 723 | __pci_start_power_transition(dev, state); | 719 | __pci_start_power_transition(dev, state); |
| 724 | 720 | ||
| 725 | /* This device is quirked not to be put into D3, so | 721 | /* This device is quirked not to be put into D3, so |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index aa495ad9bbd4..7a711ee314b7 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
| @@ -244,11 +244,17 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) | |||
| 244 | 244 | ||
| 245 | /* Assert Secondary Bus Reset */ | 245 | /* Assert Secondary Bus Reset */ |
| 246 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl); | 246 | pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl); |
| 247 | p2p_ctrl |= PCI_CB_BRIDGE_CTL_CB_RESET; | 247 | p2p_ctrl |= PCI_BRIDGE_CTL_BUS_RESET; |
| 248 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); | 248 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); |
| 249 | 249 | ||
| 250 | /* | ||
| 251 | * we should send hot reset message for 2ms to allow it time to | ||
| 252 | * propogate to all downstream ports | ||
| 253 | */ | ||
| 254 | msleep(2); | ||
| 255 | |||
| 250 | /* De-assert Secondary Bus Reset */ | 256 | /* De-assert Secondary Bus Reset */ |
| 251 | p2p_ctrl &= ~PCI_CB_BRIDGE_CTL_CB_RESET; | 257 | p2p_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; |
| 252 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); | 258 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); |
| 253 | 259 | ||
| 254 | /* | 260 | /* |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 882bd8d29fe3..c82548afcd5c 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
| @@ -174,19 +174,14 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 174 | pci_read_config_dword(dev, pos, &sz); | 174 | pci_read_config_dword(dev, pos, &sz); |
| 175 | pci_write_config_dword(dev, pos, l); | 175 | pci_write_config_dword(dev, pos, l); |
| 176 | 176 | ||
| 177 | if (!sz) | ||
| 178 | goto fail; /* BAR not implemented */ | ||
| 179 | |||
| 180 | /* | 177 | /* |
| 181 | * All bits set in sz means the device isn't working properly. | 178 | * All bits set in sz means the device isn't working properly. |
| 182 | * If it's a memory BAR or a ROM, bit 0 must be clear; if it's | 179 | * If the BAR isn't implemented, all bits must be 0. If it's a |
| 183 | * an io BAR, bit 1 must be clear. | 180 | * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit |
| 181 | * 1 must be clear. | ||
| 184 | */ | 182 | */ |
| 185 | if (sz == 0xffffffff) { | 183 | if (!sz || sz == 0xffffffff) |
| 186 | dev_err(&dev->dev, "reg %x: invalid size %#x; broken device?\n", | ||
| 187 | pos, sz); | ||
| 188 | goto fail; | 184 | goto fail; |
| 189 | } | ||
| 190 | 185 | ||
| 191 | /* | 186 | /* |
| 192 | * I don't know how l can have all bits set. Copied from old code. | 187 | * I don't know how l can have all bits set. Copied from old code. |
| @@ -249,17 +244,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 249 | pos, res); | 244 | pos, res); |
| 250 | } | 245 | } |
| 251 | } else { | 246 | } else { |
| 252 | u32 size = pci_size(l, sz, mask); | 247 | sz = pci_size(l, sz, mask); |
| 253 | 248 | ||
| 254 | if (!size) { | 249 | if (!sz) |
| 255 | dev_err(&dev->dev, "reg %x: invalid size " | ||
| 256 | "(l %#x sz %#x mask %#x); broken device?", | ||
| 257 | pos, l, sz, mask); | ||
| 258 | goto fail; | 250 | goto fail; |
| 259 | } | ||
| 260 | 251 | ||
| 261 | res->start = l; | 252 | res->start = l; |
| 262 | res->end = l + size; | 253 | res->end = l + sz; |
| 263 | 254 | ||
| 264 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); | 255 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); |
| 265 | } | 256 | } |
