Commit 862f0012 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pci-v3.11-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci

Pull PCI changes from Bjorn Helgaas:
 "PCI device hotplug
    - Add pci_alloc_dev() interface (Gu Zheng)
    - Add pci_bus_get()/put() for reference counting (Jiang Liu)
    - Fix SR-IOV reference count issues (Jiang Liu)
    - Remove unused acpi_pci_roots list (Jiang Liu)

  MSI
    - Conserve interrupt resources on x86 (Alexander Gordeev)

  AER
    - Force fatal severity when component has been reset (Betty Dall)
    - Reset link below Root Port as well as Downstream Port (Betty Dall)
    - Fix "Firmware first" flag setting (Bjorn Helgaas)
    - Don't parse HEST for non-PCIe devices (Bjorn Helgaas)

  ASPM
    - Warn when we can't disable ASPM as driver requests (Bjorn Helgaas)

  Miscellaneous
    - Add CircuitCo PCI IDs (Darren Hart)
    - Add AMD CZ SATA and SMBus PCI IDs (Shane Huang)
    - Work around Ivytown NTB BAR size issue (Jon Mason)
    - Detect invalid initial BAR values (Kevin Hao)
    - Add pcibios_release_device() (Sebastian Ott)
    - Fix powerpc & sparc PCI_UNKNOWN power state usage (Bjorn Helgaas)"

* tag 'pci-v3.11-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (51 commits)
  MAINTAINERS: Add ACPI folks for ACPI-related things under drivers/pci
  PCI: Add CircuitCo vendor ID and subsystem ID
  PCI: Use pdev->pm_cap instead of pci_find_capability(..,PCI_CAP_ID_PM)
  PCI: Return early on allocation failures to unindent mainline code
  PCI: Simplify IOV implementation and fix reference count races
  PCI: Drop redundant setting of bus->is_added in virtfn_add_bus()
  unicore32/PCI: Remove redundant call of pci_bus_add_devices()
  m68k/PCI: Remove redundant call of pci_bus_add_devices()
  PCI / ACPI / PM: Use correct power state strings in messages
  PCI: Fix comment typo for pcie_pme_remove()
  PCI: Rename pci_release_bus_bridge_dev() to pci_release_host_bridge_dev()
  PCI: Fix refcount issue in pci_create_root_bus() error recovery path
  ia64/PCI: Clean up pci_scan_root_bus() usage
  PCI/AER: Reset link for devices below Root Port or Downstream Port
  ACPI / APEI: Force fatal AER severity when component has been reset
  PCI/AER: Remove "extern" from function declarations
  PCI/AER: Move AER severity defines to aer.h
  PCI/AER: Set dev->__aer_firmware_first only for matching devices
  PCI/AER: Factor out HEST device type matching
  PCI/AER: Don't parse HEST table for non-PCIe devices
  ...
parents f991fae5 a0f75f9d
...@@ -13,7 +13,7 @@ Supported adapters: ...@@ -13,7 +13,7 @@ Supported adapters:
* AMD SP5100 (SB700 derivative found on some server mainboards) * AMD SP5100 (SB700 derivative found on some server mainboards)
Datasheet: Publicly available at the AMD website Datasheet: Publicly available at the AMD website
http://support.amd.com/us/Embedded_TechDocs/44413.pdf http://support.amd.com/us/Embedded_TechDocs/44413.pdf
* AMD Hudson-2 * AMD Hudson-2, CZ
Datasheet: Not publicly available Datasheet: Not publicly available
* Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
Datasheet: Publicly available at the SMSC website http://www.smsc.com Datasheet: Publicly available at the SMSC website http://www.smsc.com
......
...@@ -244,6 +244,9 @@ F: include/linux/acpi.h ...@@ -244,6 +244,9 @@ F: include/linux/acpi.h
F: include/acpi/ F: include/acpi/
F: Documentation/acpi F: Documentation/acpi
F: Documentation/ABI/testing/sysfs-bus-acpi F: Documentation/ABI/testing/sysfs-bus-acpi
F: drivers/pci/*acpi*
F: drivers/pci/*/*acpi*
F: drivers/pci/*/*/*acpi*
ACPI FAN DRIVER ACPI FAN DRIVER
M: Zhang Rui <rui.zhang@intel.com> M: Zhang Rui <rui.zhang@intel.com>
......
...@@ -268,17 +268,10 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) ...@@ -268,17 +268,10 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller, bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller,
&resources); &resources);
if (bus == NULL) if (bus == NULL) {
goto error_return; /* error, or bus already scanned */
bus->sysdata = controller;
return;
error_return:
kfree(res); kfree(res);
kfree(controller); kfree(controller);
return; }
} }
/* /*
......
...@@ -320,7 +320,6 @@ static int __init mcf_pci_init(void) ...@@ -320,7 +320,6 @@ static int __init mcf_pci_init(void)
pci_bus_size_bridges(rootbus); pci_bus_size_bridges(rootbus);
pci_bus_assign_resources(rootbus); pci_bus_assign_resources(rootbus);
pci_enable_bridges(rootbus); pci_enable_bridges(rootbus);
pci_bus_add_devices(rootbus);
return 0; return 0;
} }
......
...@@ -128,7 +128,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, ...@@ -128,7 +128,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
const char *type; const char *type;
struct pci_slot *slot; struct pci_slot *slot;
dev = alloc_pci_dev(); dev = pci_alloc_dev(bus);
if (!dev) if (!dev)
return NULL; return NULL;
type = of_get_property(node, "device_type", NULL); type = of_get_property(node, "device_type", NULL);
...@@ -137,7 +137,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, ...@@ -137,7 +137,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
pr_debug(" create device, devfn: %x, type: %s\n", devfn, type); pr_debug(" create device, devfn: %x, type: %s\n", devfn, type);
dev->bus = bus;
dev->dev.of_node = of_node_get(node); dev->dev.of_node = of_node_get(node);
dev->dev.parent = bus->bridge; dev->dev.parent = bus->bridge;
dev->dev.bus = &pci_bus_type; dev->dev.bus = &pci_bus_type;
...@@ -165,7 +164,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, ...@@ -165,7 +164,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
pr_debug(" class: 0x%x\n", dev->class); pr_debug(" class: 0x%x\n", dev->class);
pr_debug(" revision: 0x%x\n", dev->revision); pr_debug(" revision: 0x%x\n", dev->revision);
dev->current_state = 4; /* unknown power state */ dev->current_state = PCI_UNKNOWN; /* unknown power state */
dev->error_state = pci_channel_io_normal; dev->error_state = pci_channel_io_normal;
dev->dma_mask = 0xffffffff; dev->dma_mask = 0xffffffff;
......
...@@ -254,7 +254,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, ...@@ -254,7 +254,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
const char *type; const char *type;
u32 class; u32 class;
dev = alloc_pci_dev(); dev = pci_alloc_dev(bus);
if (!dev) if (!dev)
return NULL; return NULL;
...@@ -281,7 +281,6 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, ...@@ -281,7 +281,6 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
printk(" create device, devfn: %x, type: %s\n", printk(" create device, devfn: %x, type: %s\n",
devfn, type); devfn, type);
dev->bus = bus;
dev->sysdata = node; dev->sysdata = node;
dev->dev.parent = bus->bridge; dev->dev.parent = bus->bridge;
dev->dev.bus = &pci_bus_type; dev->dev.bus = &pci_bus_type;
...@@ -327,7 +326,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, ...@@ -327,7 +326,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)
pci_set_master(dev); pci_set_master(dev);
dev->current_state = 4; /* unknown power state */ dev->current_state = PCI_UNKNOWN; /* unknown power state */
dev->error_state = pci_channel_io_normal; dev->error_state = pci_channel_io_normal;
dev->dma_mask = 0xffffffff; dev->dma_mask = 0xffffffff;
......
...@@ -277,11 +277,6 @@ static int __init pci_common_init(void) ...@@ -277,11 +277,6 @@ static int __init pci_common_init(void)
pci_bus_assign_resources(puv3_bus); pci_bus_assign_resources(puv3_bus);
} }
/*
* Tell drivers about devices found.
*/
pci_bus_add_devices(puv3_bus);
return 0; return 0;
} }
subsys_initcall(pci_common_init); subsys_initcall(pci_common_init);
......
...@@ -324,14 +324,11 @@ setup_resource(struct acpi_resource *acpi_res, void *data) ...@@ -324,14 +324,11 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
res->start = start; res->start = start;
res->end = end; res->end = end;
info->res_offset[info->res_num] = addr.translation_offset; info->res_offset[info->res_num] = addr.translation_offset;
info->res_num++;
if (!pci_use_crs) { if (!pci_use_crs)
dev_printk(KERN_DEBUG, &info->bridge->dev, dev_printk(KERN_DEBUG, &info->bridge->dev,
"host bridge window %pR (ignored)\n", res); "host bridge window %pR (ignored)\n", res);
return AE_OK;
}
info->res_num++;
return AE_OK; return AE_OK;
} }
......
...@@ -449,9 +449,19 @@ static void ghes_do_proc(struct ghes *ghes, ...@@ -449,9 +449,19 @@ static void ghes_do_proc(struct ghes *ghes,
pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) { pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) {
unsigned int devfn; unsigned int devfn;
int aer_severity; int aer_severity;
devfn = PCI_DEVFN(pcie_err->device_id.device, devfn = PCI_DEVFN(pcie_err->device_id.device,
pcie_err->device_id.function); pcie_err->device_id.function);
aer_severity = cper_severity_to_aer(sev); aer_severity = cper_severity_to_aer(sev);
/*
* If firmware reset the component to contain
* the error, we must reinitialize it before
* use, so treat it as a fatal AER error.
*/
if (gdata->flags & CPER_SEC_RESET)
aer_severity = AER_FATAL;
aer_recover_queue(pcie_err->device_id.segment, aer_recover_queue(pcie_err->device_id.segment,
pcie_err->device_id.bus, pcie_err->device_id.bus,
devfn, aer_severity, devfn, aer_severity,
......
...@@ -65,10 +65,6 @@ static struct acpi_scan_handler pci_root_handler = { ...@@ -65,10 +65,6 @@ static struct acpi_scan_handler pci_root_handler = {
.detach = acpi_pci_root_remove, .detach = acpi_pci_root_remove,
}; };
/* Lock to protect both acpi_pci_roots lists */
static DEFINE_MUTEX(acpi_pci_root_lock);
static LIST_HEAD(acpi_pci_roots);
static DEFINE_MUTEX(osc_lock); static DEFINE_MUTEX(osc_lock);
/** /**
...@@ -100,13 +96,12 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) ...@@ -100,13 +96,12 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
{ {
struct resource *res = data; struct resource *res = data;
struct acpi_resource_address64 address; struct acpi_resource_address64 address;
acpi_status status;
if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && status = acpi_resource_to_address64(resource, &address);
resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 && if (ACPI_FAILURE(status))
resource->type != ACPI_RESOURCE_TYPE_ADDRESS64)
return AE_OK; return AE_OK;
acpi_resource_to_address64(resource, &address);
if ((address.address_length > 0) && if ((address.address_length > 0) &&
(address.resource_type == ACPI_BUS_NUMBER_RANGE)) { (address.resource_type == ACPI_BUS_NUMBER_RANGE)) {
res->start = address.minimum; res->start = address.minimum;
...@@ -382,23 +377,24 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -382,23 +377,24 @@ static int acpi_pci_root_add(struct acpi_device *device,
int result; int result;
struct acpi_pci_root *root; struct acpi_pci_root *root;
u32 flags, base_flags; u32 flags, base_flags;
acpi_handle handle = device->handle;
root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
if (!root) if (!root)
return -ENOMEM; return -ENOMEM;
segment = 0; segment = 0;
status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL,
&segment); &segment);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); dev_err(&device->dev, "can't evaluate _SEG\n");
result = -ENODEV; result = -ENODEV;
goto end; goto end;
} }
/* Check _CRS first, then _BBN. If no _BBN, default to zero. */ /* Check _CRS first, then _BBN. If no _BBN, default to zero. */
root->secondary.flags = IORESOURCE_BUS; root->secondary.flags = IORESOURCE_BUS;
status = try_get_root_bridge_busnr(device->handle, &root->secondary); status = try_get_root_bridge_busnr(handle, &root->secondary);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
/* /*
* We need both the start and end of the downstream bus range * We need both the start and end of the downstream bus range
...@@ -407,33 +403,32 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -407,33 +403,32 @@ static int acpi_pci_root_add(struct acpi_device *device,
* can do is assume [_BBN-0xFF] or [0-0xFF]. * can do is assume [_BBN-0xFF] or [0-0xFF].
*/ */
root->secondary.end = 0xFF; root->secondary.end = 0xFF;
printk(KERN_WARNING FW_BUG PREFIX dev_warn(&device->dev,
"no secondary bus range in _CRS\n"); FW_BUG "no secondary bus range in _CRS\n");
status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, status = acpi_evaluate_integer(handle, METHOD_NAME__BBN,
NULL, &bus); NULL, &bus);
if (ACPI_SUCCESS(status)) if (ACPI_SUCCESS(status))
root->secondary.start = bus; root->secondary.start = bus;
else if (status == AE_NOT_FOUND) else if (status == AE_NOT_FOUND)
root->secondary.start = 0; root->secondary.start = 0;
else { else {
printk(KERN_ERR PREFIX "can't evaluate _BBN\n"); dev_err(&device->dev, "can't evaluate _BBN\n");
result = -ENODEV; result = -ENODEV;
goto end; goto end;
} }
} }
INIT_LIST_HEAD(&root->node);
root->device = device; root->device = device;
root->segment = segment & 0xFFFF; root->segment = segment & 0xFFFF;
strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
device->driver_data = root; device->driver_data = root;
printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n", pr_info(PREFIX "%s [%s] (domain %04x %pR)\n",
acpi_device_name(device), acpi_device_bid(device), acpi_device_name(device), acpi_device_bid(device),
root->segment, &root->secondary); root->segment, &root->secondary);
root->mcfg_addr = acpi_pci_root_get_mcfg_addr(device->handle); root->mcfg_addr = acpi_pci_root_get_mcfg_addr(handle);
/* /*
* All supported architectures that use ACPI have support for * All supported architectures that use ACPI have support for
...@@ -446,10 +441,6 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -446,10 +441,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
* TBD: Need PCI interface for enumeration/configuration of roots. * TBD: Need PCI interface for enumeration/configuration of roots.
*/ */
mutex_lock(&acpi_pci_root_lock);
list_add_tail(&root->node, &acpi_pci_roots);
mutex_unlock(&acpi_pci_root_lock);
/* /*
* Scan the Root Bridge * Scan the Root Bridge
* -------------------- * --------------------
...@@ -459,11 +450,11 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -459,11 +450,11 @@ static int acpi_pci_root_add(struct acpi_device *device,
*/ */
root->bus = pci_acpi_scan_root(root); root->bus = pci_acpi_scan_root(root);
if (!root->bus) { if (!root->bus) {
printk(KERN_ERR PREFIX dev_err(&device->dev,
"Bus %04x:%02x not present in PCI namespace\n", "Bus %04x:%02x not present in PCI namespace\n",
root->segment, (unsigned int)root->secondary.start); root->segment, (unsigned int)root->secondary.start);
result = -ENODEV; result = -ENODEV;
goto out_del_root; goto end;
} }
/* Indicate support for various _OSC capabilities. */ /* Indicate support for various _OSC capabilities. */
...@@ -502,7 +493,7 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -502,7 +493,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
dev_info(&device->dev, dev_info(&device->dev,
"Requesting ACPI _OSC control (0x%02x)\n", flags); "Requesting ACPI _OSC control (0x%02x)\n", flags);
status = acpi_pci_osc_control_set(device->handle, &flags, status = acpi_pci_osc_control_set(handle, &flags,
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
dev_info(&device->dev, dev_info(&device->dev,
...@@ -519,8 +510,8 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -519,8 +510,8 @@ static int acpi_pci_root_add(struct acpi_device *device,
"ACPI _OSC request failed (%s), " "ACPI _OSC request failed (%s), "
"returned control mask: 0x%02x\n", "returned control mask: 0x%02x\n",
acpi_format_exception(status), flags); acpi_format_exception(status), flags);
pr_info("ACPI _OSC control for PCIe not granted, " dev_info(&device->dev,
"disabling ASPM\n"); "ACPI _OSC control for PCIe not granted, disabling ASPM\n");
pcie_no_aspm(); pcie_no_aspm();
} }
} else { } else {
...@@ -536,20 +527,14 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -536,20 +527,14 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (system_state != SYSTEM_BOOTING) { if (system_state != SYSTEM_BOOTING) {
pcibios_resource_survey_bus(root->bus); pcibios_resource_survey_bus(root->bus);
pci_assign_unassigned_bus_resources(root->bus); pci_assign_unassigned_bus_resources(root->bus);
}
/* need to after hot-added ioapic is registered */ /* need to after hot-added ioapic is registered */
if (system_state != SYSTEM_BOOTING)
pci_enable_bridges(root->bus); pci_enable_bridges(root->bus);
}
pci_bus_add_devices(root->bus); pci_bus_add_devices(root->bus);
return 1; return 1;
out_del_root:
mutex_lock(&acpi_pci_root_lock);
list_del(&root->node);
mutex_unlock(&acpi_pci_root_lock);
end: end:
kfree(root); kfree(root);
return result; return result;
...@@ -566,9 +551,6 @@ static void acpi_pci_root_remove(struct acpi_device *device) ...@@ -566,9 +551,6 @@ static void acpi_pci_root_remove(struct acpi_device *device)
pci_remove_root_bus(root->bus); pci_remove_root_bus(root->bus);
mutex_lock(&acpi_pci_root_lock);
list_del(&root->node);
mutex_unlock(&acpi_pci_root_lock);
kfree(root); kfree(root);
} }
...@@ -588,12 +570,13 @@ static void handle_root_bridge_insertion(acpi_handle handle) ...@@ -588,12 +570,13 @@ static void handle_root_bridge_insertion(acpi_handle handle)
struct acpi_device *device; struct acpi_device *device;
if (!acpi_bus_get_device(handle, &device)) { if (!acpi_bus_get_device(handle, &device)) {
printk(KERN_DEBUG "acpi device exists...\n"); dev_printk(KERN_DEBUG, &device->dev,
"acpi device already exists; ignoring notify\n");
return; return;
} }
if (acpi_bus_scan(handle)) if (acpi_bus_scan(handle))
printk(KERN_ERR "cannot add bridge to acpi list\n"); acpi_handle_err(handle, "cannot add bridge to acpi list\n");
} }
static void handle_root_bridge_removal(struct acpi_device *device) static void handle_root_bridge_removal(struct acpi_device *device)
...@@ -622,7 +605,6 @@ static void handle_root_bridge_removal(struct acpi_device *device) ...@@ -622,7 +605,6 @@ static void handle_root_bridge_removal(struct acpi_device *device)
static void _handle_hotplug_event_root(struct work_struct *work) static void _handle_hotplug_event_root(struct work_struct *work)
{ {
struct acpi_pci_root *root; struct acpi_pci_root *root;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER };
struct acpi_hp_work *hp_work; struct acpi_hp_work *hp_work;
acpi_handle handle; acpi_handle handle;
u32 type; u32 type;
...@@ -634,13 +616,12 @@ static void _handle_hotplug_event_root(struct work_struct *work) ...@@ -634,13 +616,12 @@ static void _handle_hotplug_event_root(struct work_struct *work)
acpi_scan_lock_acquire(); acpi_scan_lock_acquire();
root = acpi_pci_find_root(handle); root = acpi_pci_find_root(handle);
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
switch (type) { switch (type) {
case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_BUS_CHECK:
/* bus enumerate */ /* bus enumerate */
printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__, acpi_handle_printk(KERN_DEBUG, handle,
(char *)buffer.pointer); "Bus check notify on %s\n", __func__);
if (root) if (root)
acpiphp_check_host_bridge(handle); acpiphp_check_host_bridge(handle);
else else
...@@ -650,28 +631,28 @@ static void _handle_hotplug_event_root(struct work_struct *work) ...@@ -650,28 +631,28 @@ static void _handle_hotplug_event_root(struct work_struct *work)
case ACPI_NOTIFY_DEVICE_CHECK: case ACPI_NOTIFY_DEVICE_CHECK:
/* device check */ /* device check */
printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__, acpi_handle_printk(KERN_DEBUG, handle,
(char *)buffer.pointer); "Device check notify on %s\n", __func__);
if (!root) if (!root)
handle_root_bridge_insertion(handle); handle_root_bridge_insertion(handle);
break; break;
case ACPI_NOTIFY_EJECT_REQUEST: case ACPI_NOTIFY_EJECT_REQUEST:
/* request device eject */ /* request device eject */
printk(KERN_DEBUG "%s: Device eject notify on %s\n", __func__, acpi_handle_printk(KERN_DEBUG, handle,
(char *)buffer.pointer); "Device eject notify on %s\n", __func__);
if (root) if (root)
handle_root_bridge_removal(root->device); handle_root_bridge_removal(root->device);
break; break;
default: default:
printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n", acpi_handle_warn(handle,
type, (char *)buffer.pointer); "notify_handler: unknown event type 0x%x\n",
type);
break; break;
} }
acpi_scan_lock_release(); acpi_scan_lock_release();
kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
kfree(buffer.pointer);
} }
static void handle_hotplug_event_root(acpi_handle handle, u32 type, static void handle_hotplug_event_root(acpi_handle handle, u32 type,
...@@ -685,9 +666,6 @@ static acpi_status __init ...@@ -685,9 +666,6 @@ static acpi_status __init
find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
{ {
acpi_status status; acpi_status status;
char objname[64];
struct acpi_buffer buffer = { .length = sizeof(objname),
.pointer = objname };
int *count = (int *)context; int *count = (int *)context;
if (!acpi_is_root_bridge(handle)) if (!acpi_is_root_bridge(handle))
...@@ -695,16 +673,15 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) ...@@ -695,16 +673,15 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
(*count)++; (*count)++;
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
handle_hotplug_event_root, NULL); handle_hotplug_event_root, NULL);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
printk(KERN_DEBUG "acpi root: %s notify handler is not installed, exit status: %u\n", acpi_handle_printk(KERN_DEBUG, handle,
objname, (unsigned int)status); "notify handler is not installed, exit status: %u\n",
(unsigned int)status);
else else
printk(KERN_DEBUG "acpi root: %s notify handler is installed\n", acpi_handle_printk(KERN_DEBUG, handle,
objname); "notify handler is installed\n");
return AE_OK; return AE_OK;
} }
......
...@@ -310,6 +310,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { ...@@ -310,6 +310,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
/* AMD */ /* AMD */
{ PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */ { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
{ PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */
/* AMD is using RAID class only for ahci controllers */ /* AMD is using RAID class only for ahci controllers */
{ PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci }, PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
......
...@@ -174,7 +174,7 @@ alpha_core_agp_setup(void) ...@@ -174,7 +174,7 @@ alpha_core_agp_setup(void)
/* /*
* Build a fake pci_dev struct * Build a fake pci_dev struct
*/ */
pdev = alloc_pci_dev(); pdev = pci_alloc_dev(NULL);
if (!pdev) if (!pdev)
return -ENOMEM; return -ENOMEM;
pdev->vendor = 0xffff; pdev->vendor = 0xffff;
......
...@@ -333,7 +333,7 @@ parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa) ...@@ -333,7 +333,7 @@ parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa)
struct agp_bridge_data *bridge; struct agp_bridge_data *bridge;
int error = 0; int error = 0;
fake_bridge_dev = alloc_pci_dev(); fake_bridge_dev = pci_alloc_dev(NULL);
if (!fake_bridge_dev) { if (!fake_bridge_dev) {
error = -ENOMEM; error = -ENOMEM;
goto fail; goto fail;
......
...@@ -150,6 +150,7 @@ config I2C_PIIX4 ...@@ -150,6 +150,7 @@ config I2C_PIIX4
ATI SB700/SP5100 ATI SB700/SP5100
ATI SB800 ATI SB800
AMD Hudson-2 AMD Hudson-2
AMD CZ
Serverworks OSB4 Serverworks OSB4
Serverworks CSB5 Serverworks CSB5
Serverworks CSB6 Serverworks CSB6
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
Intel PIIX4, 440MX Intel PIIX4, 440MX
Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100 Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800 ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800
AMD Hudson-2 AMD Hudson-2, CZ
SMSC Victory66 SMSC Victory66
Note: we assume there can only be one device, with one or more Note: we assume there can only be one device, with one or more
...@@ -522,6 +522,7 @@ static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = { ...@@ -522,6 +522,7 @@ static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x790b) },
{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_OSB4) }, PCI_DEVICE_ID_SERVERWORKS_OSB4) },
{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
......
...@@ -51,26 +51,27 @@ static void irq_remapping_disable_io_apic(void) ...@@ -51,26 +51,27 @@ static void irq_remapping_disable_io_apic(void)
static int do_setup_msi_irqs(struct pci_dev *dev, int nvec) static int do_setup_msi_irqs(struct pci_dev *dev, int nvec)
{ {
int node, ret, sub_handle, index = 0; int node, ret, sub_handle, nvec_pow2, index = 0;
unsigned int irq; unsigned int irq;
struct msi_desc *msidesc; struct msi_desc *msidesc;
nvec = __roundup_pow_of_two(nvec);
WARN_ON(!list_is_singular(&dev->msi_list)); WARN_ON(!list_is_singular(&dev->msi_list));
msidesc = list_entry(dev->msi_list.next, struct msi_desc, list); msidesc = list_entry(dev->msi_list.next, struct msi_desc, list);
WARN_ON(msidesc->irq); WARN_ON(msidesc->irq);
WARN_ON(msidesc->msi_attrib.multiple); WARN_ON(msidesc->msi_attrib.multiple);
WARN_ON(msidesc->nvec_used);
node = dev_to_node(&dev->dev); node = dev_to_node(&dev->dev);
irq = __create_irqs(get_nr_irqs_gsi(), nvec, node); irq = __create_irqs(get_nr_irqs_gsi(), nvec, node);
if (irq == 0) if (irq == 0)
return -ENOSPC; return -ENOSPC;
msidesc->msi_attrib.multiple = ilog2(nvec); nvec_pow2 = __roundup_pow_of_two(nvec);
msidesc->nvec_used = nvec;
msidesc->msi_attrib.multiple = ilog2(nvec_pow2);
for (sub_handle = 0; sub_handle < nvec; sub_handle++) { for (sub_handle = 0; sub_handle < nvec; sub_handle++) {
if (!sub_handle) { if (!sub_handle) {
index = msi_alloc_remapped_irq(dev, irq, nvec); index = msi_alloc_remapped_irq(dev, irq, nvec_pow2);
if (index < 0) { if (index < 0) {
ret = index; ret = index;
goto error; goto error;
...@@ -95,6 +96,7 @@ static int do_setup_msi_irqs(struct pci_dev *dev, int nvec) ...@@ -95,6 +96,7 @@ static int do_setup_msi_irqs(struct pci_dev *dev, int nvec)
* IRQs from tearing down again in default_teardown_msi_irqs() * IRQs from tearing down again in default_teardown_msi_irqs()
*/ */
msidesc->irq = 0; msidesc->irq = 0;
msidesc->nvec_used = 0;
msidesc->msi_attrib.multiple = 0; msidesc->msi_attrib.multiple = 0;
return ret; return ret;
......
...@@ -283,6 +283,21 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), ...@@ -283,6 +283,21 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
} }
EXPORT_SYMBOL_GPL(pci_walk_bus); EXPORT_SYMBOL_GPL(pci_walk_bus);
struct pci_bus *pci_bus_get(struct pci_bus *bus)
{
if (bus)
get_device(&bus->dev);
return bus;
}
EXPORT_SYMBOL(pci_bus_get);
void pci_bus_put(struct pci_bus *bus)
{
if (bus)
put_device(&bus->dev);
}
EXPORT_SYMBOL(pci_bus_put);
EXPORT_SYMBOL(pci_bus_alloc_resource); EXPORT_SYMBOL(pci_bus_alloc_resource);
EXPORT_SYMBOL_GPL(pci_bus_add_device); EXPORT_SYMBOL_GPL(pci_bus_add_device);
EXPORT_SYMBOL(pci_bus_add_devices); EXPORT_SYMBOL(pci_bus_add_devices);
......
...@@ -113,17 +113,6 @@ static struct pci_driver ioapic_driver = { ...@@ -113,17 +113,6 @@ static struct pci_driver ioapic_driver = {
.remove = ioapic_remove, .remove = ioapic_remove,
}; };
static int __init ioapic_init(void) module_pci_driver(ioapic_driver);
{
return pci_register_driver(&ioapic_driver);
}
static void __exit ioapic_exit(void)
{
pci_unregister_driver(&ioapic_driver);
}
module_init(ioapic_init);
module_exit(ioapic_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -47,51 +47,43 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) ...@@ -47,51 +47,43 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
return NULL; return NULL;
pci_bus_insert_busn_res(child, busnr, busnr); pci_bus_insert_busn_res(child, busnr, busnr);
bus->is_added = 1;
return child; return child;
} }
static void virtfn_remove_bus(struct pci_bus *bus, int busnr) static void virtfn_remove_bus(struct pci_bus *physbus, struct pci_bus *virtbus)
{ {
struct pci_bus *child; if (physbus != virtbus && list_empty(&virtbus->devices))
pci_remove_bus(virtbus);
if (bus->number == busnr)
return;
child = pci_find_bus(pci_domain_nr(bus), busnr);
BUG_ON(!child);
if (list_empty(&child->devices))
pci_remove_bus(child);
} }
static int virtfn_add(struct pci_dev *dev, int id, int reset) static int virtfn_add(struct pci_dev *dev, int id, int reset)
{ {
int i; int i;
int rc; int rc = -ENOMEM;
u64 size; u64 size;
char buf[VIRTFN_ID_LEN]; char buf[VIRTFN_ID_LEN];
struct pci_dev *virtfn; struct pci_dev *virtfn;
struct resource *res; struct resource *res;
struct pci_sriov *iov = dev->sriov; struct pci_sriov *iov = dev->sriov;
struct pci_bus *bus;
virtfn = alloc_pci_dev(); mutex_lock(&iov->dev->sriov->lock);
bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
if (!bus)
goto failed;
virtfn = pci_alloc_dev(bus);
if (!virtfn) if (!virtfn)
return -ENOMEM; goto failed0;
mutex_lock(&iov->dev->sriov->lock);
virtfn->bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
if (!virtfn->bus) {
kfree(virtfn);
mutex_unlock(&iov->dev->sriov->lock);
return -ENOMEM;
}
virtfn->devfn = virtfn_devfn(dev, id); virtfn->devfn = virtfn_devfn(dev, id);
virtfn->vendor = dev->vendor; virtfn->vendor = dev->vendor;
pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device); pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device);
pci_setup_device(virtfn); pci_setup_device(virtfn);
virtfn->dev.parent = dev->dev.parent; virtfn->dev.parent = dev->dev.parent;
virtfn->physfn = pci_dev_get(dev);
virtfn->is_virtfn = 1;
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
res = dev->resource + PCI_IOV_RESOURCES + i; res = dev->resource + PCI_IOV_RESOURCES + i;
...@@ -113,9 +105,6 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset) ...@@ -113,9 +105,6 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
pci_device_add(virtfn, virtfn->bus); pci_device_add(virtfn, virtfn->bus);
mutex_unlock(&iov->dev->sriov->lock); mutex_unlock(&iov->dev->sriov->lock);
virtfn->physfn = pci_dev_get(dev);
virtfn->is_virtfn = 1;
rc = pci_bus_add_device(virtfn); rc = pci_bus_add_device(virtfn);
sprintf(buf, "virtfn%u", id); sprintf(buf, "virtfn%u", id);
rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf); rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
...@@ -135,7 +124,9 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset) ...@@ -135,7 +124,9 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
pci_dev_put(dev); pci_dev_put(dev);
mutex_lock(&iov->dev->sriov->lock); mutex_lock(&iov->dev->sriov->lock);
pci_stop_and_remove_bus_device(virtfn); pci_stop_and_remove_bus_device(virtfn);
virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); failed0:
virtfn_remove_bus(dev->bus, bus);
failed:
mutex_unlock(&iov->dev->sriov->lock); mutex_unlock(&iov->dev->sriov->lock);
return rc; return rc;
...@@ -144,20 +135,15 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset) ...@@ -144,20 +135,15 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
static void virtfn_remove(struct pci_dev *dev, int id, int reset) static void virtfn_remove(struct pci_dev *dev, int id, int reset)
{ {
char buf[VIRTFN_ID_LEN]; char buf[VIRTFN_ID_LEN];
struct pci_bus *bus;
struct pci_dev *virtfn; struct pci_dev *virtfn;
struct pci_sriov *iov = dev->sriov; struct pci_sriov *iov = dev->sriov;
bus = pci_find_bus(pci_domain_nr(dev->bus), virtfn_bus(dev, id)); virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus),
if (!bus) virtfn_bus(dev, id),
return; virtfn_devfn(dev, id));
virtfn = pci_get_slot(bus, virtfn_devfn(dev, id));
if (!virtfn) if (!virtfn)
return; return;
pci_dev_put(virtfn);
if (reset) { if (reset) {
device_release_driver(&virtfn->dev); device_release_driver(&virtfn->dev);
__pci_reset_function(virtfn); __pci_reset_function(virtfn);
...@@ -175,9 +161,11 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset) ...@@ -175,9 +161,11 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset)
mutex_lock(&iov->dev->sriov->lock); mutex_lock(&iov->dev->sriov->lock);
pci_stop_and_remove_bus_device(virtfn); pci_stop_and_remove_bus_device(virtfn);
virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); virtfn_remove_bus(dev->bus, virtfn->bus);
mutex_unlock(&iov->dev->sriov->lock); mutex_unlock(&iov->dev->sriov->lock);
/* balance pci_get_domain_bus_and_slot() */
pci_dev_put(virtfn);
pci_dev_put(dev); pci_dev_put(dev);
} }
...@@ -334,13 +322,14 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) ...@@ -334,13 +322,14 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
if (!pdev) if (!pdev)
return -ENODEV; return -ENODEV;
if (!pdev->is_physfn) {
pci_dev_put(pdev); pci_dev_put(pdev);
if (!pdev->is_physfn)
return -ENODEV; return -ENODEV;
}
rc = sysfs_create_link(&dev->dev.kobj, rc = sysfs_create_link(&dev->dev.kobj,
&pdev->dev.kobj, "dep_link"); &pdev->dev.kobj, "dep_link");
pci_dev_put(pdev);
if (rc) if (rc)
return rc; return rc;
} }
......
...@@ -81,6 +81,9 @@ void default_teardown_msi_irqs(struct pci_dev *dev) ...@@ -81,6 +81,9 @@ void default_teardown_msi_irqs(struct pci_dev *dev)
int i, nvec; int i, nvec;
if (entry->irq == 0) if (entry->irq == 0)
continue; continue;
if (entry->nvec_used)
nvec = entry->nvec_used;
else
nvec = 1 << entry->msi_attrib.multiple; nvec = 1 << entry->msi_attrib.multiple;
for (i = 0; i < nvec; i++) for (i = 0; i < nvec; i++)
arch_teardown_msi_irq(entry->irq + i); arch_teardown_msi_irq(entry->irq + i);
...@@ -336,6 +339,9 @@ static void free_msi_irqs(struct pci_dev *dev) ...@@ -336,6 +339,9 @@ static void free_msi_irqs(struct pci_dev *dev)
int i, nvec; int i, nvec;
if (!entry->irq) if (!entry->irq)
continue; continue;
if (entry->nvec_used)
nvec = entry->nvec_used;
else
nvec = 1 << entry->msi_attrib.multiple; nvec = 1 << entry->msi_attrib.multiple;
#ifdef CONFIG_GENERIC_HARDIRQS #ifdef CONFIG_GENERIC_HARDIRQS
for (i = 0; i < nvec; i++) for (i = 0; i < nvec; i++)
......
...@@ -186,8 +186,8 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) ...@@ -186,8 +186,8 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
[PCI_D0] = ACPI_STATE_D0, [PCI_D0] = ACPI_STATE_D0,
[PCI_D1] = ACPI_STATE_D1, [PCI_D1] = ACPI_STATE_D1,
[PCI_D2] = ACPI_STATE_D2, [PCI_D2] = ACPI_STATE_D2,
[PCI_D3hot] = ACPI_STATE_D3, [PCI_D3hot] = ACPI_STATE_D3_COLD,
[PCI_D3cold] = ACPI_STATE_D3 [PCI_D3cold] = ACPI_STATE_D3_COLD,
}; };
int error = -EINVAL; int error = -EINVAL;
...@@ -211,7 +211,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) ...@@ -211,7 +211,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
if (!error) if (!error)
dev_info(&dev->dev, "power state changed by ACPI to %s\n", dev_info(&dev->dev, "power state changed by ACPI to %s\n",
pci_power_name(state)); acpi_power_state_string(state_conv[state]));
return error; return error;
} }
...@@ -376,12 +376,12 @@ static int __init acpi_pci_init(void) ...@@ -376,12 +376,12 @@ static int __init acpi_pci_init(void)
int ret; int ret;
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) { if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) {
printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n"); pr_info("ACPI FADT declares the system doesn't support MSI, so disable it\n");
pci_no_msi(); pci_no_msi();
} }
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); pr_info("ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
pcie_no_aspm(); pcie_no_aspm();
} }
......
...@@ -66,7 +66,7 @@ static ssize_t broken_parity_status_store(struct device *dev, ...@@ -66,7 +66,7 @@ static ssize_t broken_parity_status_store(struct device *dev,
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
unsigned long val; unsigned long val;
if (strict_strtoul(buf, 0, &val) < 0) if (kstrtoul(buf, 0, &val) < 0)
return -EINVAL; return -EINVAL;
pdev->broken_parity_status = !!val; pdev->broken_parity_status = !!val;
...@@ -188,7 +188,7 @@ static ssize_t is_enabled_store(struct device *dev, ...@@ -188,7 +188,7 @@ static ssize_t is_enabled_store(struct device *dev,
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
unsigned long val; unsigned long val;
ssize_t result = strict_strtoul(buf, 0, &val); ssize_t result = kstrtoul(buf, 0, &val);
if (result < 0) if (result < 0)
return result; return result;
...@@ -259,7 +259,7 @@ msi_bus_store(struct device *dev, struct device_attribute *attr, ...@@ -259,7 +259,7 @@ msi_bus_store(struct device *dev, struct device_attribute *attr,
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
unsigned long val; unsigned long val;
if (strict_strtoul(buf, 0, &val) < 0) if (kstrtoul(buf, 0, &val) < 0)
return -EINVAL; return -EINVAL;
/* bad things may happen if the no_msi flag is changed /* bad things may happen if the no_msi flag is changed
...@@ -291,7 +291,7 @@ static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf, ...@@ -291,7 +291,7 @@ static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf,
unsigned long val; unsigned long val;
struct pci_bus *b = NULL; struct pci_bus *b = NULL;
if (strict_strtoul(buf, 0, &val) < 0) if (kstrtoul(buf, 0, &val) < 0)
return -EINVAL; return -EINVAL;
if (val) { if (val) {
...@@ -315,7 +315,7 @@ dev_rescan_store(struct device *dev, struct device_attribute *attr, ...@@ -315,7 +315,7 @@ dev_rescan_store(struct device *dev, struct device_attribute *attr,
unsigned long val; unsigned long val;
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
if (strict_strtoul(buf, 0, &val) < 0) if (kstrtoul(buf, 0, &val) < 0)
return -EINVAL; return -EINVAL;
if (val) { if (val) {
...@@ -325,6 +325,8 @@ dev_rescan_store(struct device *dev, struct device_attribute *attr, ...@@ -325,6 +325,8 @@ dev_rescan_store(struct device *dev, struct device_attribute *attr,
} }
return count; return count;
} }
struct device_attribute dev_rescan_attr = __ATTR(rescan, (S_IWUSR|S_IWGRP),
NULL, dev_rescan_store);
static void remove_callback(struct device *dev) static void remove_callback(struct device *dev)
{ {
...@@ -342,7 +344,7 @@ remove_store(struct device *dev, struct device_attribute *dummy, ...@@ -342,7 +344,7 @@ remove_store(struct device *dev, struct device_attribute *dummy,
int ret = 0; int ret = 0;
unsigned long val; unsigned long val;
if (strict_strtoul(buf, 0, &val) < 0) if (kstrtoul(buf, 0, &val) < 0)
return -EINVAL; return -EINVAL;
/* An attribute cannot be unregistered by one of its own methods, /* An attribute cannot be unregistered by one of its own methods,
...@@ -354,6 +356,8 @@ remove_store(struct device *dev, struct device_attribute *dummy, ...@@ -354,6 +356,8 @@ remove_store(struct device *dev, struct device_attribute *dummy,
count = ret; count = ret;
return count; return count;
} }
struct device_attribute dev_remove_attr = __ATTR(remove, (S_IWUSR|S_IWGRP),
NULL, remove_store);
static ssize_t static ssize_t
dev_bus_rescan_store(struct device *dev, struct device_attribute *attr, dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
...@@ -362,7 +366,7 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr, ...@@ -362,7 +366,7 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
unsigned long val; unsigned long val;
struct pci_bus *bus = to_pci_bus(dev); struct pci_bus *bus = to_pci_bus(dev);
if (strict_strtoul(buf, 0, &val) < 0) if (kstrtoul(buf, 0, &val) < 0)
return -EINVAL; return -EINVAL;
if (val) { if (val) {
...@@ -384,7 +388,7 @@ static ssize_t d3cold_allowed_store(struct device *dev, ...@@ -384,7 +388,7 @@ static ssize_t d3cold_allowed_store(struct device *dev,
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
unsigned long val; unsigned long val;
if (strict_strtoul(buf, 0, &val) < 0) if (kstrtoul(buf, 0, &val) < 0)
return -EINVAL; return -EINVAL;
pdev->d3cold_allowed = !!val; pdev->d3cold_allowed = !!val;
...@@ -504,8 +508,6 @@ struct device_attribute pci_dev_attrs[] = { ...@@ -504,8 +508,6 @@ struct device_attribute pci_dev_attrs[] = {
__ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
broken_parity_status_show,broken_parity_status_store), broken_parity_status_show,broken_parity_status_store),
__ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store), __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
__ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store),
__ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store),
#if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI) #if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI)
__ATTR(d3cold_allowed, 0644, d3cold_allowed_show, d3cold_allowed_store), __ATTR(d3cold_allowed, 0644, d3cold_allowed_show, d3cold_allowed_store),
#endif #endif
...@@ -1236,7 +1238,7 @@ static ssize_t reset_store(struct device *dev, ...@@ -1236,7 +1238,7 @@ static ssize_t reset_store(struct device *dev,
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
unsigned long val; unsigned long val;
ssize_t result = strict_strtoul(buf, 0, &val); ssize_t result = kstrtoul(buf, 0, &val);
if (result < 0) if (result < 0)
return result; return result;
...@@ -1463,6 +1465,29 @@ static umode_t pci_dev_attrs_are_visible(struct kobject *kobj, ...@@ -1463,6 +1465,29 @@ static umode_t pci_dev_attrs_are_visible(struct kobject *kobj,
return a->mode; return a->mode;
} }
static struct attribute *pci_dev_hp_attrs[] = {
&dev_remove_attr.attr,
&dev_rescan_attr.attr,
NULL,
};
static umode_t pci_dev_hp_attrs_are_visible(struct kobject *kobj,
struct attribute *a, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct pci_dev *pdev = to_pci_dev(dev);
if (pdev->is_virtfn)
return 0;
return a->mode;
}
static struct attribute_group pci_dev_hp_attr_group = {
.attrs = pci_dev_hp_attrs,
.is_visible = pci_dev_hp_attrs_are_visible,
};
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
static struct attribute *sriov_dev_attrs[] = { static struct attribute *sriov_dev_attrs[] = {
&sriov_totalvfs_attr.attr, &sriov_totalvfs_attr.attr,
...@@ -1494,6 +1519,7 @@ static struct attribute_group pci_dev_attr_group = { ...@@ -1494,6 +1519,7 @@ static struct attribute_group pci_dev_attr_group = {
static const struct attribute_group *pci_dev_attr_groups[] = { static const struct attribute_group *pci_dev_attr_groups[] = {
&pci_dev_attr_group, &pci_dev_attr_group,
&pci_dev_hp_attr_group,
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
&sriov_dev_attr_group, &sriov_dev_attr_group,
#endif #endif
......
...@@ -805,7 +805,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) ...@@ -805,7 +805,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
{ {
pci_power_t ret; pci_power_t ret;
if (!pci_find_capability(dev, PCI_CAP_ID_PM)) if (!dev->pm_cap)
return PCI_D0; return PCI_D0;
ret = platform_pci_choose_state(dev); ret = platform_pci_choose_state(dev);
...@@ -2431,7 +2431,7 @@ bool pci_acs_path_enabled(struct pci_dev *start, ...@@ -2431,7 +2431,7 @@ bool pci_acs_path_enabled(struct pci_dev *start,
/** /**
* pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
* @dev: the PCI device * @dev: the PCI device
* @pin: the INTx pin (1=INTA, 2=INTB, 3=INTD, 4=INTD) * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTC, 4=INTD)
* *
* Perform INTx swizzling for a device behind one level of bridge. This is * Perform INTx swizzling for a device behind one level of bridge. This is
* required by section 9.1 of the PCI-to-PCI bridge specification for devices * required by section 9.1 of the PCI-to-PCI bridge specification for devices
......
...@@ -13,10 +13,6 @@ ...@@ -13,10 +13,6 @@
#include <linux/aer.h> #include <linux/aer.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#define AER_NONFATAL 0
#define AER_FATAL 1
#define AER_CORRECTABLE 2
#define SYSTEM_ERROR_INTR_ON_MESG_MASK (PCI_EXP_RTCTL_SECEE| \ #define SYSTEM_ERROR_INTR_ON_MESG_MASK (PCI_EXP_RTCTL_SECEE| \
PCI_EXP_RTCTL_SENFEE| \ PCI_EXP_RTCTL_SENFEE| \
PCI_EXP_RTCTL_SEFEE) PCI_EXP_RTCTL_SEFEE)
......
...@@ -29,6 +29,22 @@ static inline int hest_match_pci(struct acpi_hest_aer_common *p, ...@@ -29,6 +29,22 @@ static inline int hest_match_pci(struct acpi_hest_aer_common *p,
p->function == PCI_FUNC(pci->devfn)); p->function == PCI_FUNC(pci->devfn));
} }
static inline bool hest_match_type(struct acpi_hest_header *hest_hdr,
struct pci_dev *dev)
{
u16 hest_type = hest_hdr->type;
u8 pcie_type = pci_pcie_type(dev);
if ((hest_type == ACPI_HEST_TYPE_AER_ROOT_PORT &&
pcie_type == PCI_EXP_TYPE_ROOT_PORT) ||
(hest_type == ACPI_HEST_TYPE_AER_ENDPOINT &&
pcie_type == PCI_EXP_TYPE_ENDPOINT) ||
(hest_type == ACPI_HEST_TYPE_AER_BRIDGE &&
(dev->class >> 16) == PCI_BASE_CLASS_BRIDGE))
return true;
return false;
}
struct aer_hest_parse_info { struct aer_hest_parse_info {
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
int firmware_first; int firmware_first;
...@@ -38,33 +54,15 @@ static int aer_hest_parse(struct acpi_hest_header *hest_hdr, void *data) ...@@ -38,33 +54,15 @@ static int aer_hest_parse(struct acpi_hest_header *hest_hdr, void *data)
{ {
struct aer_hest_parse_info *info = data; struct aer_hest_parse_info *info = data;
struct acpi_hest_aer_common *p; struct acpi_hest_aer_common *p;
u8 pcie_type = 0; int ff;
u8 bridge = 0;
int ff = 0;
switch (hest_hdr->type) {
case ACPI_HEST_TYPE_AER_ROOT_PORT:
pcie_type = PCI_EXP_TYPE_ROOT_PORT;
break;
case ACPI_HEST_TYPE_AER_ENDPOINT:
pcie_type = PCI_EXP_TYPE_ENDPOINT;
break;
case ACPI_HEST_TYPE_AER_BRIDGE:
if ((info->pci_dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
bridge = 1;
break;
default:
return 0;
}
p = (struct acpi_hest_aer_common *)(hest_hdr + 1); p = (struct acpi_hest_aer_common *)(hest_hdr + 1);
if (p->flags & ACPI_HEST_GLOBAL) {
if ((pci_is_pcie(info->pci_dev) &&
pci_pcie_type(info->pci_dev) == pcie_type) || bridge)
ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
if (p->flags & ACPI_HEST_GLOBAL) {
if (hest_match_type(hest_hdr, info->pci_dev))
info->firmware_first = ff;
} else } else
if (hest_match_pci(p, info->pci_dev)) if (hest_match_pci(p, info->pci_dev))
ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
info->firmware_first = ff; info->firmware_first = ff;
return 0; return 0;
...@@ -89,6 +87,9 @@ static void aer_set_firmware_first(struct pci_dev *pci_dev) ...@@ -89,6 +87,9 @@ static void aer_set_firmware_first(struct pci_dev *pci_dev)
int pcie_aer_get_firmware_first(struct pci_dev *dev) int pcie_aer_get_firmware_first(struct pci_dev *dev)
{ {
if (!pci_is_pcie(dev))
return 0;
if (!dev->__aer_firmware_first_valid) if (!dev->__aer_firmware_first_valid)
aer_set_firmware_first(dev); aer_set_firmware_first(dev);
return dev->__aer_firmware_first; return dev->__aer_firmware_first;
......
...@@ -400,16 +400,16 @@ void aer_do_secondary_bus_reset(struct pci_dev *dev) ...@@ -400,16 +400,16 @@ void aer_do_secondary_bus_reset(struct pci_dev *dev)
} }
/** /**
* default_downstream_reset_link - default reset function for Downstream Port * default_reset_link - default reset function
* @dev: pointer to downstream port's pci_dev data structure * @dev: pointer to pci_dev data structure
* *
* Invoked when performing link reset at Downstream Port w/ no aer driver. * Invoked when performing link reset on a Downstream Port or a
* Root Port with no aer driver.
*/ */
static pci_ers_result_t default_downstream_reset_link(struct pci_dev *dev) static pci_ers_result_t default_reset_link(struct pci_dev *dev)
{ {
aer_do_secondary_bus_reset(dev); aer_do_secondary_bus_reset(dev);
dev_printk(KERN_DEBUG, &dev->dev, dev_printk(KERN_DEBUG, &dev->dev, "downstream link has been reset\n");
"Downstream Port link has been reset\n");
return PCI_ERS_RESULT_RECOVERED; return PCI_ERS_RESULT_RECOVERED;
} }
...@@ -458,8 +458,9 @@ static pci_ers_result_t reset_link(struct pci_dev *dev) ...@@ -458,8 +458,9 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
if (driver && driver->reset_link) { if (driver && driver->reset_link) {
status = driver->reset_link(udev); status = driver->reset_link(udev);
} else if (pci_pcie_type(udev) == PCI_EXP_TYPE_DOWNSTREAM) { } else if (pci_pcie_type(udev) == PCI_EXP_TYPE_DOWNSTREAM ||
status = default_downstream_reset_link(udev); pci_pcie_type(udev) == PCI_EXP_TYPE_ROOT_PORT) {
status = default_reset_link(udev);
} else { } else {
dev_printk(KERN_DEBUG, &dev->dev, dev_printk(KERN_DEBUG, &dev->dev,
"no link-reset support at upstream device %s\n", "no link-reset support at upstream device %s\n",
......
...@@ -714,19 +714,12 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev) ...@@ -714,19 +714,12 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
up_read(&pci_bus_sem); up_read(&pci_bus_sem);
} }
/*
* pci_disable_link_state - disable pci device's link state, so the link will
* never enter specific states
*/
static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem, static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem,
bool force) bool force)
{ {
struct pci_dev *parent = pdev->bus->self; struct pci_dev *parent = pdev->bus->self;
struct pcie_link_state *link; struct pcie_link_state *link;
if (aspm_disabled && !force)
return;
if (!pci_is_pcie(pdev)) if (!pci_is_pcie(pdev))
return; return;
...@@ -736,6 +729,19 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem, ...@@ -736,6 +729,19 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem,
if (!parent || !parent->link_state) if (!parent || !parent->link_state)
return; return;
/*
* A driver requested that ASPM be disabled on this device, but
* if we don't have permission to manage ASPM (e.g., on ACPI
* systems we have to observe the FADT ACPI_FADT_NO_ASPM bit and
* the _OSC method), we can't honor that request. Windows has
* a similar mechanism using "PciASPMOptOut", which is also
* ignored in this situation.
*/
if (aspm_disabled && !force) {
dev_warn(&pdev->dev, "can't disable ASPM; OS doesn't have ASPM control\n");
return;
}
if (sem) if (sem)
down_read(&pci_bus_sem); down_read(&pci_bus_sem);
mutex_lock(&aspm_lock); mutex_lock(&aspm_lock);
...@@ -761,6 +767,15 @@ void pci_disable_link_state_locked(struct pci_dev *pdev, int state) ...@@ -761,6 +767,15 @@ void pci_disable_link_state_locked(struct pci_dev *pdev, int state)
} }
EXPORT_SYMBOL(pci_disable_link_state_locked); EXPORT_SYMBOL(pci_disable_link_state_locked);
/**
* pci_disable_link_state - Disable device's link state, so the link will
* never enter specific states. Note that if the BIOS didn't grant ASPM
* control to the OS, this does nothing because we can't touch the LNKCTL
* register.
*
* @pdev: PCI device
* @state: ASPM link state to disable
*/
void pci_disable_link_state(struct pci_dev *pdev, int state) void pci_disable_link_state(struct pci_dev *pdev, int state)
{ {
__pci_disable_link_state(pdev, state, true, false); __pci_disable_link_state(pdev, state, true, false);
......
...@@ -408,7 +408,7 @@ static int pcie_pme_resume(struct pcie_device *srv) ...@@ -408,7 +408,7 @@ static int pcie_pme_resume(struct pcie_device *srv)
/** /**
* pcie_pme_remove - Prepare PCIe PME service device for removal. * pcie_pme_remove - Prepare PCIe PME service device for removal.
* @srv - PCIe service device to resume. * @srv - PCIe service device to remove.
*/ */
static void pcie_pme_remove(struct pcie_device *srv) static void pcie_pme_remove(struct pcie_device *srv)
{ {
......
...@@ -170,7 +170,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, ...@@ -170,7 +170,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
{ {
u32 l, sz, mask; u32 l, sz, mask;
u16 orig_cmd; u16 orig_cmd;
struct pci_bus_region region; struct pci_bus_region region, inverted_region;
bool bar_too_big = false, bar_disabled = false; bool bar_too_big = false, bar_disabled = false;
mask = type ? PCI_ROM_ADDRESS_MASK : ~0; mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
...@@ -250,12 +250,10 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, ...@@ -250,12 +250,10 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
pci_write_config_dword(dev, pos + 4, 0); pci_write_config_dword(dev, pos + 4, 0);
region.start = 0; region.start = 0;
region.end = sz64; region.end = sz64;
pcibios_bus_to_resource(dev, res, &region);
bar_disabled = true; bar_disabled = true;
} else { } else {
region.start = l64; region.start = l64;
region.end = l64 + sz64; region.end = l64 + sz64;
pcibios_bus_to_resource(dev, res, &region);
} }
} else { } else {
sz = pci_size(l, sz, mask); sz = pci_size(l, sz, mask);
...@@ -265,7 +263,28 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, ...@@ -265,7 +263,28 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
region.start = l; region.start = l;
region.end = l + sz; region.end = l + sz;
}
pcibios_bus_to_resource(dev, res, &region); pcibios_bus_to_resource(dev, res, &region);
pcibios_resource_to_bus(dev, &inverted_region, res);
/*
* If "A" is a BAR value (a bus address), "bus_to_resource(A)" is
* the corresponding resource address (the physical address used by
* the CPU. Converting that resource address back to a bus address
* should yield the original BAR value:
*
* resource_to_bus(bus_to_resource(A)) == A
*
* If it doesn't, CPU accesses to "bus_to_resource(A)" will not
* be claimed by the device.
*/
if (inverted_region.start != region.start) {
dev_info(&dev->dev, "reg 0x%x: initial BAR value %pa invalid; forcing reassignment\n",
pos, &region.start);
res->flags |= IORESOURCE_UNSET;
res->end -= res->start;
res->start = 0;
} }
goto out; goto out;
...@@ -278,9 +297,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, ...@@ -278,9 +297,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
pci_write_config_word(dev, PCI_COMMAND, orig_cmd); pci_write_config_word(dev, PCI_COMMAND, orig_cmd);
if (bar_too_big) if (bar_too_big)
dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", pos); dev_err(&dev->dev, "reg 0x%x: can't handle 64-bit BAR\n", pos);
if (res->flags && !bar_disabled) if (res->flags && !bar_disabled)
dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res);
return (res->flags & IORESOURCE_MEM_64) ? 1 : 0; return (res->flags & IORESOURCE_MEM_64) ? 1 : 0;
} }
...@@ -451,12 +470,14 @@ void pci_read_bridge_bases(struct pci_bus *child) ...@@ -451,12 +470,14 @@ void pci_read_bridge_bases(struct pci_bus *child)
} }
} }
static struct pci_bus * pci_alloc_bus(void) static struct pci_bus *pci_alloc_bus(void)
{ {
struct pci_bus *b; struct pci_bus *b;
b = kzalloc(sizeof(*b), GFP_KERNEL); b = kzalloc(sizeof(*b), GFP_KERNEL);
if (b) { if (!b)
return NULL;
INIT_LIST_HEAD(&b->node); INIT_LIST_HEAD(&b->node);
INIT_LIST_HEAD(&b->children); INIT_LIST_HEAD(&b->children);
INIT_LIST_HEAD(&b->devices); INIT_LIST_HEAD(&b->devices);
...@@ -464,20 +485,31 @@ static struct pci_bus * pci_alloc_bus(void) ...@@ -464,20 +485,31 @@ static struct pci_bus * pci_alloc_bus(void)
INIT_LIST_HEAD(&b->resources); INIT_LIST_HEAD(&b->resources);
b->max_bus_speed = PCI_SPEED_UNKNOWN; b->max_bus_speed = PCI_SPEED_UNKNOWN;
b->cur_bus_speed = PCI_SPEED_UNKNOWN; b->cur_bus_speed = PCI_SPEED_UNKNOWN;
}
return b; return b;
} }
static void pci_release_host_bridge_dev(struct device *dev)
{
struct pci_host_bridge *bridge = to_pci_host_bridge(dev);
if (bridge->release_fn)
bridge->release_fn(bridge);
pci_free_resource_list(&bridge->windows);
kfree(bridge);
}
static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b) static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
{ {
struct pci_host_bridge *bridge; struct pci_host_bridge *bridge;
bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
if (bridge) { if (!bridge)
return NULL;
INIT_LIST_HEAD(&bridge->windows); INIT_LIST_HEAD(&bridge->windows);
bridge->bus = b; bridge->bus = b;
}
return bridge; return bridge;
} }
...@@ -1133,6 +1165,7 @@ static void pci_release_dev(struct device *dev) ...@@ -1133,6 +1165,7 @@ static void pci_release_dev(struct device *dev)
pci_release_capabilities(pci_dev); pci_release_capabilities(pci_dev);
pci_release_of_node(pci_dev); pci_release_of_node(pci_dev);
pcibios_release_device(pci_dev); pcibios_release_device(pci_dev);
pci_bus_put(pci_dev->bus);
kfree(pci_dev); kfree(pci_dev);
} }
...@@ -1189,19 +1222,7 @@ int pci_cfg_space_size(struct pci_dev *dev) ...@@ -1189,19 +1222,7 @@ int pci_cfg_space_size(struct pci_dev *dev)
return PCI_CFG_SPACE_SIZE; return PCI_CFG_SPACE_SIZE;
} }
static void pci_release_bus_bridge_dev(struct device *dev) struct pci_dev *pci_alloc_dev(struct pci_bus *bus)
{
struct pci_host_bridge *bridge = to_pci_host_bridge(dev);
if (bridge->release_fn)
bridge->release_fn(bridge);
pci_free_resource_list(&bridge->windows);
kfree(bridge);
}
struct pci_dev *alloc_pci_dev(void)
{ {
struct pci_dev *dev; struct pci_dev *dev;
...@@ -1211,9 +1232,16 @@ struct pci_dev *alloc_pci_dev(void) ...@@ -1211,9 +1232,16 @@ struct pci_dev *alloc_pci_dev(void)
INIT_LIST_HEAD(&dev->bus_list); INIT_LIST_HEAD(&dev->bus_list);
dev->dev.type = &pci_dev_type; dev->dev.type = &pci_dev_type;
dev->bus = pci_bus_get(bus);
return dev; return dev;
} }
EXPORT_SYMBOL(pci_alloc_dev);
struct pci_dev *alloc_pci_dev(void)
{
return pci_alloc_dev(NULL);
}
EXPORT_SYMBOL(alloc_pci_dev); EXPORT_SYMBOL(alloc_pci_dev);
bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l, bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
...@@ -1264,11 +1292,10 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) ...@@ -1264,11 +1292,10 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000)) if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000))
return NULL; return NULL;
dev = alloc_pci_dev(); dev = pci_alloc_dev(bus);
if (!dev) if (!dev)
return NULL; return NULL;
dev->bus = bus;
dev->devfn = devfn; dev->devfn = devfn;
dev->vendor = l & 0xffff; dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff; dev->device = (l >> 16) & 0xffff;
...@@ -1276,6 +1303,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) ...@@ -1276,6 +1303,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
pci_set_of_node(dev); pci_set_of_node(dev);
if (pci_setup_device(dev)) { if (pci_setup_device(dev)) {
pci_bus_put(dev->bus);
kfree(dev); kfree(dev);
return NULL; return NULL;
} }
...@@ -1701,15 +1729,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, ...@@ -1701,15 +1729,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
goto err_out; goto err_out;
bridge->dev.parent = parent; bridge->dev.parent = parent;
bridge->dev.release = pci_release_bus_bridge_dev; bridge->dev.release = pci_release_host_bridge_dev;
dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
error = pcibios_root_bridge_prepare(bridge); error = pcibios_root_bridge_prepare(bridge);
if (error) if (error) {
goto bridge_dev_reg_err; kfree(bridge);
goto err_out;
}
error = device_register(&bridge->dev); error = device_register(&bridge->dev);
if (error) if (error) {
goto bridge_dev_reg_err; put_device(&bridge->dev);
goto err_out;
}
b->bridge = get_device(&bridge->dev); b->bridge = get_device(&bridge->dev);
device_enable_async_suspend(b->bridge); device_enable_async_suspend(b->bridge);
pci_set_bus_of_node(b); pci_set_bus_of_node(b);
...@@ -1765,8 +1797,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, ...@@ -1765,8 +1797,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
class_dev_reg_err: class_dev_reg_err:
put_device(&bridge->dev); put_device(&bridge->dev);
device_unregister(&bridge->dev); device_unregister(&bridge->dev);
bridge_dev_reg_err:
kfree(bridge);
err_out: err_out:
kfree(b); kfree(b);
return NULL; return NULL;
......
...@@ -1022,6 +1022,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk ...@@ -1022,6 +1022,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode);
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x7900, quirk_amd_ide_mode);
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, 0x7900, quirk_amd_ide_mode);
/* /*
* Serverworks CSB5 IDE does not fully support native mode * Serverworks CSB5 IDE does not fully support native mode
...@@ -1832,7 +1834,6 @@ static void quirk_e100_interrupt(struct pci_dev *dev) ...@@ -1832,7 +1834,6 @@ static void quirk_e100_interrupt(struct pci_dev *dev)
u16 command, pmcsr; u16 command, pmcsr;
u8 __iomem *csr; u8 __iomem *csr;
u8 cmd_hi; u8 cmd_hi;
int pm;
switch (dev->device) { switch (dev->device) {
/* PCI IDs taken from drivers/net/e100.c */ /* PCI IDs taken from drivers/net/e100.c */
...@@ -1870,9 +1871,8 @@ static void quirk_e100_interrupt(struct pci_dev *dev) ...@@ -1870,9 +1871,8 @@ static void quirk_e100_interrupt(struct pci_dev *dev)
* Check that the device is in the D0 power state. If it's not, * Check that the device is in the D0 power state. If it's not,
* there is no point to look any further. * there is no point to look any further.
*/ */
pm = pci_find_capability(dev, PCI_CAP_ID_PM); if (dev->pm_cap) {
if (pm) { pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0)
return; return;
} }
...@@ -2865,6 +2865,31 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); ...@@ -2865,6 +2865,31 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata);
/*
* Ivytown NTB BAR sizes are misreported by the hardware due to an erratum. To
* work around this, query the size it should be configured to by the device and
* modify the resource end to correspond to this new size.
*/
static void quirk_intel_ntb(struct pci_dev *dev)
{
int rc;
u8 val;
rc = pci_read_config_byte(dev, 0x00D0, &val);
if (rc)
return;
dev->resource[2].end = dev->resource[2].start + ((u64) 1 << val) - 1;
rc = pci_read_config_byte(dev, 0x00D1, &val);
if (rc)
return;
dev->resource[4].end = dev->resource[4].start + ((u64) 1 << val) - 1;
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e08, quirk_intel_ntb);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e0d, quirk_intel_ntb);
static ktime_t fixup_debug_start(struct pci_dev *dev, static ktime_t fixup_debug_start(struct pci_dev *dev,
void (*fn)(struct pci_dev *dev)) void (*fn)(struct pci_dev *dev))
{ {
......
...@@ -2026,7 +2026,7 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor) ...@@ -2026,7 +2026,7 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor)
static inline int static inline int
make_local_pdev(adapter_t *adapter, struct pci_dev **pdev) make_local_pdev(adapter_t *adapter, struct pci_dev **pdev)
{ {
*pdev = alloc_pci_dev(); *pdev = pci_alloc_dev(NULL);
if( *pdev == NULL ) return -1; if( *pdev == NULL ) return -1;
......
...@@ -434,7 +434,6 @@ int register_acpi_bus_type(struct acpi_bus_type *); ...@@ -434,7 +434,6 @@ int register_acpi_bus_type(struct acpi_bus_type *);
int unregister_acpi_bus_type(struct acpi_bus_type *); int unregister_acpi_bus_type(struct acpi_bus_type *);
struct acpi_pci_root { struct acpi_pci_root {
struct list_head node;
struct acpi_device * device; struct acpi_device * device;
struct pci_bus *bus; struct pci_bus *bus;
u16 segment; u16 segment;
......
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
#ifndef _AER_H_ #ifndef _AER_H_
#define _AER_H_ #define _AER_H_
#define AER_NONFATAL 0
#define AER_FATAL 1
#define AER_CORRECTABLE 2
struct aer_header_log_regs { struct aer_header_log_regs {
unsigned int dw0; unsigned int dw0;
unsigned int dw1; unsigned int dw1;
...@@ -31,9 +35,9 @@ struct aer_capability_regs { ...@@ -31,9 +35,9 @@ struct aer_capability_regs {
#if defined(CONFIG_PCIEAER) #if defined(CONFIG_PCIEAER)
/* pci-e port driver needs this function to enable aer */ /* pci-e port driver needs this function to enable aer */
extern int pci_enable_pcie_error_reporting(struct pci_dev *dev); int pci_enable_pcie_error_reporting(struct pci_dev *dev);
extern int pci_disable_pcie_error_reporting(struct pci_dev *dev); int pci_disable_pcie_error_reporting(struct pci_dev *dev);
extern int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
#else #else
static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev) static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{ {
...@@ -49,10 +53,10 @@ static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) ...@@ -49,10 +53,10 @@ static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
} }
#endif #endif
extern void cper_print_aer(struct pci_dev *dev, void cper_print_aer(struct pci_dev *dev, int cper_severity,
int cper_severity, struct aer_capability_regs *aer); struct aer_capability_regs *aer);
extern int cper_severity_to_aer(int cper_severity); int cper_severity_to_aer(int cper_severity);
extern void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
int severity, int severity,
struct aer_capability_regs *aer_regs); struct aer_capability_regs *aer_regs);
#endif //_AER_H_ #endif //_AER_H_
......
...@@ -35,6 +35,7 @@ struct msi_desc { ...@@ -35,6 +35,7 @@ struct msi_desc {
u32 masked; /* mask bits */ u32 masked; /* mask bits */
unsigned int irq; unsigned int irq;
unsigned int nvec_used; /* number of messages */
struct list_head list; struct list_head list;
union { union {
......
...@@ -364,7 +364,8 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev) ...@@ -364,7 +364,8 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
return dev; return dev;
} }
struct pci_dev *alloc_pci_dev(void); struct pci_dev *pci_alloc_dev(struct pci_bus *bus);
struct pci_dev * __deprecated alloc_pci_dev(void);
#define to_pci_dev(n) container_of(n, struct pci_dev, dev) #define to_pci_dev(n) container_of(n, struct pci_dev, dev)
#define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)
...@@ -1018,6 +1019,8 @@ int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *); ...@@ -1018,6 +1019,8 @@ int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *);
void pci_release_selected_regions(struct pci_dev *, int); void pci_release_selected_regions(struct pci_dev *, int);
/* drivers/pci/bus.c */ /* drivers/pci/bus.c */
struct pci_bus *pci_bus_get(struct pci_bus *bus);
void pci_bus_put(struct pci_bus *bus);
void pci_add_resource(struct list_head *resources, struct resource *res); void pci_add_resource(struct list_head *resources, struct resource *res);
void pci_add_resource_offset(struct list_head *resources, struct resource *res, void pci_add_resource_offset(struct list_head *resources, struct resource *res,
resource_size_t offset); resource_size_t offset);
......
...@@ -556,7 +556,6 @@ ...@@ -556,7 +556,6 @@
#define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450 #define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450
#define PCI_DEVICE_ID_AMD_8131_APIC 0x7451 #define PCI_DEVICE_ID_AMD_8131_APIC 0x7451
#define PCI_DEVICE_ID_AMD_8132_BRIDGE 0x7458 #define PCI_DEVICE_ID_AMD_8132_BRIDGE 0x7458
#define PCI_DEVICE_ID_AMD_HUDSON2_SMBUS 0x780b
#define PCI_DEVICE_ID_AMD_CS5535_IDE 0x208F #define PCI_DEVICE_ID_AMD_CS5535_IDE 0x208F
#define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090 #define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090
#define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091 #define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091
...@@ -568,8 +567,9 @@ ...@@ -568,8 +567,9 @@
#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A #define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A
#define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081 #define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081
#define PCI_DEVICE_ID_AMD_LX_AES 0x2082 #define PCI_DEVICE_ID_AMD_LX_AES 0x2082
#define PCI_DEVICE_ID_AMD_HUDSON2_IDE 0x780c
#define PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE 0x7800 #define PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE 0x7800
#define PCI_DEVICE_ID_AMD_HUDSON2_SMBUS 0x780b
#define PCI_DEVICE_ID_AMD_HUDSON2_IDE 0x780c
#define PCI_VENDOR_ID_TRIDENT 0x1023 #define PCI_VENDOR_ID_TRIDENT 0x1023
#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
...@@ -2476,6 +2476,9 @@ ...@@ -2476,6 +2476,9 @@
#define PCI_VENDOR_ID_ASMEDIA 0x1b21 #define PCI_VENDOR_ID_ASMEDIA 0x1b21
#define PCI_VENDOR_ID_CIRCUITCO 0x1cc8
#define PCI_SUBSYSTEM_ID_CIRCUITCO_MINNOWBOARD 0x0001
#define PCI_VENDOR_ID_TEKRAM 0x1de1 #define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
......
...@@ -468,7 +468,7 @@ ...@@ -468,7 +468,7 @@
#define PCI_EXP_LNKCAP_ASPMS 0x00000c00 /* ASPM Support */ #define PCI_EXP_LNKCAP_ASPMS 0x00000c00 /* ASPM Support */
#define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */ #define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */
#define PCI_EXP_LNKCAP_L1EL 0x00038000 /* L1 Exit Latency */ #define PCI_EXP_LNKCAP_L1EL 0x00038000 /* L1 Exit Latency */
#define PCI_EXP_LNKCAP_CLKPM 0x00040000 /* L1 Clock Power Management */ #define PCI_EXP_LNKCAP_CLKPM 0x00040000 /* Clock Power Management */
#define PCI_EXP_LNKCAP_SDERC 0x00080000 /* Surprise Down Error Reporting Capable */ #define PCI_EXP_LNKCAP_SDERC 0x00080000 /* Surprise Down Error Reporting Capable */
#define PCI_EXP_LNKCAP_DLLLARC 0x00100000 /* Data Link Layer Link Active Reporting Capable */ #define PCI_EXP_LNKCAP_DLLLARC 0x00100000 /* Data Link Layer Link Active Reporting Capable */
#define PCI_EXP_LNKCAP_LBNC 0x00200000 /* Link Bandwidth Notification Capability */ #define PCI_EXP_LNKCAP_LBNC 0x00200000 /* Link Bandwidth Notification Capability */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment