]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'pci/alexander-msi' into next
authorBjorn Helgaas <bhelgaas@google.com>
Tue, 25 Jun 2013 17:29:49 +0000 (11:29 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 25 Jun 2013 17:29:49 +0000 (11:29 -0600)
* pci/alexander-msi:
  x86/MSI: Conserve interrupt resources when using multiple-MSIs

33 files changed:
Documentation/i2c/busses/i2c-piix4
arch/ia64/sn/kernel/io_init.c
arch/m68k/platform/coldfire/pci.c
arch/powerpc/kernel/pci_of_scan.c
arch/sparc/kernel/pci.c
arch/unicore32/kernel/pci.c
arch/x86/pci/acpi.c
drivers/acpi/apei/ghes.c
drivers/acpi/pci_root.c
drivers/ata/ahci.c
drivers/char/agp/alpha-agp.c
drivers/char/agp/parisc-agp.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-piix4.c
drivers/pci/bus.c
drivers/pci/ioapic.c
drivers/pci/iov.c
drivers/pci/pci-acpi.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pcie/aer/aerdrv.h
drivers/pci/pcie/aer/aerdrv_acpi.c
drivers/pci/pcie/aer/aerdrv_core.c
drivers/pci/pcie/aspm.c
drivers/pci/pcie/pme.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/scsi/megaraid.c
include/acpi/acpi_bus.h
include/linux/aer.h
include/linux/pci.h
include/linux/pci_ids.h
include/uapi/linux/pci_regs.h

index 1e6634f54c5019b45b6d663b6fd7cd7db9b23530..a370b2047cf3025b5a0c318af15c670a76bc41e3 100644 (file)
@@ -13,7 +13,7 @@ Supported adapters:
   * AMD SP5100 (SB700 derivative found on some server mainboards)
     Datasheet: Publicly available at the AMD website
     http://support.amd.com/us/Embedded_TechDocs/44413.pdf
-  * AMD Hudson-2
+  * AMD Hudson-2, CZ
     Datasheet: Not publicly available
   * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
     Datasheet: Publicly available at the SMSC website http://www.smsc.com
index 238e2c511d94e735fb823cb612d30a7333a28510..e2c7733e18a7cc443575011702944152550ef7d6 100644 (file)
@@ -326,16 +326,7 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
        bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller,
                                &resources);
        if (bus == NULL)
-               goto error_return; /* error, or bus already scanned */
-
-       bus->sysdata = controller;
-
-       return;
-
-error_return:
-
-       kfree(controller);
-       return;
+               kfree(controller);
 }
 
 /*
index 8572246db84d3fe35d9075a5157e42a3e0eb1e2e..b33f97a13e6d11650db6f5a183511356884ae51e 100644 (file)
@@ -320,7 +320,6 @@ static int __init mcf_pci_init(void)
        pci_bus_size_bridges(rootbus);
        pci_bus_assign_resources(rootbus);
        pci_enable_bridges(rootbus);
-       pci_bus_add_devices(rootbus);
        return 0;
 }
 
index 2a67e9baa59f80200f4a25b5a75471c04f04c776..6b0ba5854d9960aff03bbd01b810543c9e369588 100644 (file)
@@ -128,7 +128,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
        const char *type;
        struct pci_slot *slot;
 
-       dev = alloc_pci_dev();
+       dev = pci_alloc_dev(bus);
        if (!dev)
                return NULL;
        type = of_get_property(node, "device_type", NULL);
@@ -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);
 
-       dev->bus = bus;
        dev->dev.of_node = of_node_get(node);
        dev->dev.parent = bus->bridge;
        dev->dev.bus = &pci_bus_type;
@@ -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("    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->dma_mask = 0xffffffff;
 
index baf4366e2d6afe937db5fe792c3183d56da4c580..b16f624398af34e7b97187292e277c3a86c4e3a8 100644 (file)
@@ -254,7 +254,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
        const char *type;
        u32 class;
 
-       dev = alloc_pci_dev();
+       dev = pci_alloc_dev(bus);
        if (!dev)
                return NULL;
 
@@ -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",
                       devfn, type);
 
-       dev->bus = bus;
        dev->sysdata = node;
        dev->dev.parent = bus->bridge;
        dev->dev.bus = &pci_bus_type;
@@ -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)
                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->dma_mask = 0xffffffff;
 
index ef69c0c828253991c7b633a22822acc04d333633..374a055a8e6bb5886ead0595dabaa5627cf5868a 100644 (file)
@@ -277,11 +277,6 @@ static int __init pci_common_init(void)
                pci_bus_assign_resources(puv3_bus);
        }
 
-       /*
-        * Tell drivers about devices found.
-        */
-       pci_bus_add_devices(puv3_bus);
-
        return 0;
 }
 subsys_initcall(pci_common_init);
index 3e724256dbee6b0bb4d2e4156522a08e3bd480e4..d641897a1f4e5d53a5f14ec3e25b7517fe3d8b9f 100644 (file)
@@ -324,14 +324,11 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
        res->start = start;
        res->end = end;
        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,
                           "host bridge window %pR (ignored)\n", res);
-               return AE_OK;
-       }
-
-       info->res_num++;
 
        return AE_OK;
 }
index d668a8ae602bb4533b793911408cf138c047a4ce..ab315515908eb921caa1f0768d5c79aceb6293a2 100644 (file)
@@ -449,9 +449,19 @@ static void ghes_do_proc(struct ghes *ghes,
                            pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) {
                                unsigned int devfn;
                                int aer_severity;
+
                                devfn = PCI_DEVFN(pcie_err->device_id.device,
                                                  pcie_err->device_id.function);
                                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,
                                                  pcie_err->device_id.bus,
                                                  devfn, aer_severity);
index 1dd6f6c8587442ab1fcbdf7d7bd78d98ef551a9b..122b4dc7b0faed4653189e2f01e987f12c2208b0 100644 (file)
@@ -65,10 +65,6 @@ static struct acpi_scan_handler pci_root_handler = {
        .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);
 
 /**
@@ -100,13 +96,12 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
 {
        struct resource *res = data;
        struct acpi_resource_address64 address;
+       acpi_status status;
 
-       if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
-           resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
-           resource->type != ACPI_RESOURCE_TYPE_ADDRESS64)
+       status = acpi_resource_to_address64(resource, &address);
+       if (ACPI_FAILURE(status))
                return AE_OK;
 
-       acpi_resource_to_address64(resource, &address);
        if ((address.address_length > 0) &&
            (address.resource_type == ACPI_BUS_NUMBER_RANGE)) {
                res->start = address.minimum;
@@ -382,23 +377,24 @@ static int acpi_pci_root_add(struct acpi_device *device,
        int result;
        struct acpi_pci_root *root;
        u32 flags, base_flags;
+       acpi_handle handle = device->handle;
 
        root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
        if (!root)
                return -ENOMEM;
 
        segment = 0;
-       status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
+       status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL,
                                       &segment);
        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;
                goto end;
        }
 
        /* Check _CRS first, then _BBN.  If no _BBN, default to zero. */
        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)) {
                /*
                 * 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,
                 * can do is assume [_BBN-0xFF] or [0-0xFF].
                 */
                root->secondary.end = 0xFF;
-               printk(KERN_WARNING FW_BUG PREFIX
-                      "no secondary bus range in _CRS\n");
-               status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN,
+               dev_warn(&device->dev,
+                        FW_BUG "no secondary bus range in _CRS\n");
+               status = acpi_evaluate_integer(handle, METHOD_NAME__BBN,
                                               NULL, &bus);
                if (ACPI_SUCCESS(status))
                        root->secondary.start = bus;
                else if (status == AE_NOT_FOUND)
                        root->secondary.start = 0;
                else {
-                       printk(KERN_ERR PREFIX "can't evaluate _BBN\n");
+                       dev_err(&device->dev, "can't evaluate _BBN\n");
                        result = -ENODEV;
                        goto end;
                }
        }
 
-       INIT_LIST_HEAD(&root->node);
        root->device = device;
        root->segment = segment & 0xFFFF;
        strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
        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),
               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
@@ -446,10 +441,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
         * 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
         * --------------------
@@ -459,11 +450,11 @@ static int acpi_pci_root_add(struct acpi_device *device,
         */
        root->bus = pci_acpi_scan_root(root);
        if (!root->bus) {
-               printk(KERN_ERR PREFIX
-                           "Bus %04x:%02x not present in PCI namespace\n",
-                           root->segment, (unsigned int)root->secondary.start);
+               dev_err(&device->dev,
+                       "Bus %04x:%02x not present in PCI namespace\n",
+                       root->segment, (unsigned int)root->secondary.start);
                result = -ENODEV;
-               goto out_del_root;
+               goto end;
        }
 
        /* Indicate support for various _OSC capabilities. */
@@ -502,7 +493,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
                dev_info(&device->dev,
                        "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);
                if (ACPI_SUCCESS(status)) {
                        dev_info(&device->dev,
@@ -519,8 +510,8 @@ static int acpi_pci_root_add(struct acpi_device *device,
                                "ACPI _OSC request failed (%s), "
                                "returned control mask: 0x%02x\n",
                                acpi_format_exception(status), flags);
-                       pr_info("ACPI _OSC control for PCIe not granted, "
-                               "disabling ASPM\n");
+                       dev_info(&device->dev,
+                                "ACPI _OSC control for PCIe not granted, disabling ASPM\n");
                        pcie_no_aspm();
                }
        } else {
@@ -536,20 +527,14 @@ static int acpi_pci_root_add(struct acpi_device *device,
        if (system_state != SYSTEM_BOOTING) {
                pcibios_resource_survey_bus(root->bus);
                pci_assign_unassigned_bus_resources(root->bus);
-       }
 
-       /* need to after hot-added ioapic is registered */
-       if (system_state != SYSTEM_BOOTING)
+               /* need to after hot-added ioapic is registered */
                pci_enable_bridges(root->bus);
+       }
 
        pci_bus_add_devices(root->bus);
        return 1;
 
-out_del_root:
-       mutex_lock(&acpi_pci_root_lock);
-       list_del(&root->node);
-       mutex_unlock(&acpi_pci_root_lock);
-
 end:
        kfree(root);
        return result;
@@ -566,9 +551,6 @@ static void acpi_pci_root_remove(struct acpi_device *device)
 
        pci_remove_root_bus(root->bus);
 
-       mutex_lock(&acpi_pci_root_lock);
-       list_del(&root->node);
-       mutex_unlock(&acpi_pci_root_lock);
        kfree(root);
 }
 
@@ -588,12 +570,13 @@ static void handle_root_bridge_insertion(acpi_handle handle)
        struct acpi_device *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;
        }
 
        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)
@@ -622,7 +605,6 @@ static void handle_root_bridge_removal(struct acpi_device *device)
 static void _handle_hotplug_event_root(struct work_struct *work)
 {
        struct acpi_pci_root *root;
-       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER };
        struct acpi_hp_work *hp_work;
        acpi_handle handle;
        u32 type;
@@ -634,13 +616,12 @@ static void _handle_hotplug_event_root(struct work_struct *work)
        acpi_scan_lock_acquire();
 
        root = acpi_pci_find_root(handle);
-       acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 
        switch (type) {
        case ACPI_NOTIFY_BUS_CHECK:
                /* bus enumerate */
-               printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__,
-                                (char *)buffer.pointer);
+               acpi_handle_printk(KERN_DEBUG, handle,
+                                  "Bus check notify on %s\n", __func__);
                if (!root)
                        handle_root_bridge_insertion(handle);
 
@@ -648,28 +629,28 @@ static void _handle_hotplug_event_root(struct work_struct *work)
 
        case ACPI_NOTIFY_DEVICE_CHECK:
                /* device check */
-               printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__,
-                                (char *)buffer.pointer);
+               acpi_handle_printk(KERN_DEBUG, handle,
+                                  "Device check notify on %s\n", __func__);
                if (!root)
                        handle_root_bridge_insertion(handle);
                break;
 
        case ACPI_NOTIFY_EJECT_REQUEST:
                /* request device eject */
-               printk(KERN_DEBUG "%s: Device eject notify on %s\n", __func__,
-                                (char *)buffer.pointer);
+               acpi_handle_printk(KERN_DEBUG, handle,
+                                  "Device eject notify on %s\n", __func__);
                if (root)
                        handle_root_bridge_removal(root->device);
                break;
        default:
-               printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n",
-                                type, (char *)buffer.pointer);
+               acpi_handle_warn(handle,
+                                "notify_handler: unknown event type 0x%x\n",
+                                type);
                break;
        }
 
        acpi_scan_lock_release();
        kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
-       kfree(buffer.pointer);
 }
 
 static void handle_hotplug_event_root(acpi_handle handle, u32 type,
@@ -683,9 +664,6 @@ static acpi_status __init
 find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
        acpi_status status;
-       char objname[64];
-       struct acpi_buffer buffer = { .length = sizeof(objname),
-                                     .pointer = objname };
        int *count = (int *)context;
 
        if (!acpi_is_root_bridge(handle))
@@ -693,16 +671,15 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
 
        (*count)++;
 
-       acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
-
        status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
                                        handle_hotplug_event_root, NULL);
        if (ACPI_FAILURE(status))
-               printk(KERN_DEBUG "acpi root: %s notify handler is not installed, exit status: %u\n",
-                                 objname, (unsigned int)status);
+               acpi_handle_printk(KERN_DEBUG, handle,
+                       "notify handler is not installed, exit status: %u\n",
+                        (unsigned int)status);
        else
-               printk(KERN_DEBUG "acpi root: %s notify handler is installed\n",
-                                objname);
+               acpi_handle_printk(KERN_DEBUG, handle,
+                                  "notify handler is installed\n");
 
        return AE_OK;
 }
index 251e57d38942cdec01790d5fa02cb2c7aed87535..98496600a15a3a66c59978a92bb4ac7478d36ff0 100644 (file)
@@ -310,6 +310,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 
        /* AMD */
        { 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 */
        { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
          PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
index dd84af4d4f7e1cfdd0c74e576269d1744e1cfdef..199b8e99f7d7886d5d5e59b4fff5bf43337e523d 100644 (file)
@@ -174,7 +174,7 @@ alpha_core_agp_setup(void)
        /*
         * Build a fake pci_dev struct
         */
-       pdev = alloc_pci_dev();
+       pdev = pci_alloc_dev(NULL);
        if (!pdev)
                return -ENOMEM;
        pdev->vendor = 0xffff;
index 94821ab01c6d6ae1803201c27217c69a30357329..bf5d2477cb77c296dac3a63b3aea2e8a2ec5ce0a 100644 (file)
@@ -333,7 +333,7 @@ parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa)
        struct agp_bridge_data *bridge;
        int error = 0;
 
-       fake_bridge_dev = alloc_pci_dev();
+       fake_bridge_dev = pci_alloc_dev(NULL);
        if (!fake_bridge_dev) {
                error = -ENOMEM;
                goto fail;
index 631736e2e7ed94297a0f871615d6d5b6c9e6acd3..4faf02b3657d6f834c7b8d9860a8640da8580b4a 100644 (file)
@@ -150,6 +150,7 @@ config I2C_PIIX4
            ATI SB700/SP5100
            ATI SB800
            AMD Hudson-2
+           AMD CZ
            Serverworks OSB4
            Serverworks CSB5
            Serverworks CSB6
index 39ab78c1a02cc3a4f056a0294432ef01fbbfd165..d05ad590af29b5163e0920a8d7868a31d8ec0529 100644 (file)
@@ -22,7 +22,7 @@
        Intel PIIX4, 440MX
        Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
        ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800
-       AMD Hudson-2
+       AMD Hudson-2, CZ
        SMSC Victory66
 
    Note: we assume there can only be one device, with one or more
@@ -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_SBX00_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_ID_SERVERWORKS_OSB4) },
        { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
index 32e66a6f12d98084f77f493ed1d202084ad3329e..b1ff02ab4f131fbda7edd9971342b9ae91bf4149 100644 (file)
@@ -283,6 +283,21 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
 }
 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_GPL(pci_bus_add_device);
 EXPORT_SYMBOL(pci_bus_add_devices);
index 3c6bbdd059a459614ab2710f377d3f9796ccd3aa..1b90579b233ae8c2d7db5efe00cc022c42fbb73a 100644 (file)
@@ -113,17 +113,6 @@ static struct pci_driver ioapic_driver = {
        .remove         = ioapic_remove,
 };
 
-static int __init ioapic_init(void)
-{
-       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_pci_driver(ioapic_driver);
 
 MODULE_LICENSE("GPL");
index c93071d428f5d6d6cb038d5cb614e4117c5fd8aa..de8ffacf9c9b27cd1f758065e5b3f8158bab89b9 100644 (file)
@@ -47,51 +47,43 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
                return NULL;
 
        pci_bus_insert_busn_res(child, busnr, busnr);
-       bus->is_added = 1;
 
        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 (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);
+       if (physbus != virtbus && list_empty(&virtbus->devices))
+               pci_remove_bus(virtbus);
 }
 
 static int virtfn_add(struct pci_dev *dev, int id, int reset)
 {
        int i;
-       int rc;
+       int rc = -ENOMEM;
        u64 size;
        char buf[VIRTFN_ID_LEN];
        struct pci_dev *virtfn;
        struct resource *res;
        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)
-               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->vendor = dev->vendor;
        pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device);
        pci_setup_device(virtfn);
        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++) {
                res = dev->resource + PCI_IOV_RESOURCES + i;
@@ -113,9 +105,6 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
        pci_device_add(virtfn, virtfn->bus);
        mutex_unlock(&iov->dev->sriov->lock);
 
-       virtfn->physfn = pci_dev_get(dev);
-       virtfn->is_virtfn = 1;
-
        rc = pci_bus_add_device(virtfn);
        sprintf(buf, "virtfn%u", id);
        rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
@@ -135,7 +124,9 @@ failed1:
        pci_dev_put(dev);
        mutex_lock(&iov->dev->sriov->lock);
        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);
 
        return rc;
@@ -144,20 +135,15 @@ failed1:
 static void virtfn_remove(struct pci_dev *dev, int id, int reset)
 {
        char buf[VIRTFN_ID_LEN];
-       struct pci_bus *bus;
        struct pci_dev *virtfn;
        struct pci_sriov *iov = dev->sriov;
 
-       bus = pci_find_bus(pci_domain_nr(dev->bus), virtfn_bus(dev, id));
-       if (!bus)
-               return;
-
-       virtfn = pci_get_slot(bus, virtfn_devfn(dev, id));
+       virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus),
+                                            virtfn_bus(dev, id),
+                                            virtfn_devfn(dev, id));
        if (!virtfn)
                return;
 
-       pci_dev_put(virtfn);
-
        if (reset) {
                device_release_driver(&virtfn->dev);
                __pci_reset_function(virtfn);
@@ -175,9 +161,11 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset)
 
        mutex_lock(&iov->dev->sriov->lock);
        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);
 
+       /* balance pci_get_domain_bus_and_slot() */
+       pci_dev_put(virtfn);
        pci_dev_put(dev);
 }
 
@@ -334,13 +322,14 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
                if (!pdev)
                        return -ENODEV;
 
-               pci_dev_put(pdev);
-
-               if (!pdev->is_physfn)
+               if (!pdev->is_physfn) {
+                       pci_dev_put(pdev);
                        return -ENODEV;
+               }
 
                rc = sysfs_create_link(&dev->dev.kobj,
                                        &pdev->dev.kobj, "dep_link");
+               pci_dev_put(pdev);
                if (rc)
                        return rc;
        }
index e4b1fb2c0f5d83029e0a62ffa4aaef36f4559da3..dbdc5f7e2b294fad4adfe3ae676e258c5af6abbe 100644 (file)
@@ -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_D1] = ACPI_STATE_D1,
                [PCI_D2] = ACPI_STATE_D2,
-               [PCI_D3hot] = ACPI_STATE_D3,
-               [PCI_D3cold] = ACPI_STATE_D3
+               [PCI_D3hot] = ACPI_STATE_D3_COLD,
+               [PCI_D3cold] = ACPI_STATE_D3_COLD,
        };
        int error = -EINVAL;
 
@@ -211,7 +211,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 
        if (!error)
                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;
 }
@@ -376,12 +376,12 @@ static int __init acpi_pci_init(void)
        int ret;
 
        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();
        }
 
        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();
        }
 
index 5b4a9d9cd200dd5a6ee32c3d343bbae0cf2ff8ac..c0dbe1f61362aa058db84ffb971671a6ce35e8cd 100644 (file)
@@ -66,7 +66,7 @@ static ssize_t broken_parity_status_store(struct device *dev,
        struct pci_dev *pdev = to_pci_dev(dev);
        unsigned long val;
 
-       if (strict_strtoul(buf, 0, &val) < 0)
+       if (kstrtoul(buf, 0, &val) < 0)
                return -EINVAL;
 
        pdev->broken_parity_status = !!val;
@@ -188,7 +188,7 @@ static ssize_t is_enabled_store(struct device *dev,
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        unsigned long val;
-       ssize_t result = strict_strtoul(buf, 0, &val);
+       ssize_t result = kstrtoul(buf, 0, &val);
 
        if (result < 0)
                return result;
@@ -259,7 +259,7 @@ msi_bus_store(struct device *dev, struct device_attribute *attr,
        struct pci_dev *pdev = to_pci_dev(dev);
        unsigned long val;
 
-       if (strict_strtoul(buf, 0, &val) < 0)
+       if (kstrtoul(buf, 0, &val) < 0)
                return -EINVAL;
 
        /* 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,
        unsigned long val;
        struct pci_bus *b = NULL;
 
-       if (strict_strtoul(buf, 0, &val) < 0)
+       if (kstrtoul(buf, 0, &val) < 0)
                return -EINVAL;
 
        if (val) {
@@ -315,7 +315,7 @@ dev_rescan_store(struct device *dev, struct device_attribute *attr,
        unsigned long val;
        struct pci_dev *pdev = to_pci_dev(dev);
 
-       if (strict_strtoul(buf, 0, &val) < 0)
+       if (kstrtoul(buf, 0, &val) < 0)
                return -EINVAL;
 
        if (val) {
@@ -325,6 +325,8 @@ dev_rescan_store(struct device *dev, struct device_attribute *attr,
        }
        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)
 {
@@ -342,7 +344,7 @@ remove_store(struct device *dev, struct device_attribute *dummy,
        int ret = 0;
        unsigned long val;
 
-       if (strict_strtoul(buf, 0, &val) < 0)
+       if (kstrtoul(buf, 0, &val) < 0)
                return -EINVAL;
 
        /* An attribute cannot be unregistered by one of its own methods,
@@ -354,6 +356,8 @@ remove_store(struct device *dev, struct device_attribute *dummy,
                count = ret;
        return count;
 }
+struct device_attribute dev_remove_attr = __ATTR(remove, (S_IWUSR|S_IWGRP),
+                                                NULL, remove_store);
 
 static ssize_t
 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;
        struct pci_bus *bus = to_pci_bus(dev);
 
-       if (strict_strtoul(buf, 0, &val) < 0)
+       if (kstrtoul(buf, 0, &val) < 0)
                return -EINVAL;
 
        if (val) {
@@ -384,7 +388,7 @@ static ssize_t d3cold_allowed_store(struct device *dev,
        struct pci_dev *pdev = to_pci_dev(dev);
        unsigned long val;
 
-       if (strict_strtoul(buf, 0, &val) < 0)
+       if (kstrtoul(buf, 0, &val) < 0)
                return -EINVAL;
 
        pdev->d3cold_allowed = !!val;
@@ -504,8 +508,6 @@ struct device_attribute pci_dev_attrs[] = {
        __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
                broken_parity_status_show,broken_parity_status_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)
        __ATTR(d3cold_allowed, 0644, d3cold_allowed_show, d3cold_allowed_store),
 #endif
@@ -1236,7 +1238,7 @@ static ssize_t reset_store(struct device *dev,
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        unsigned long val;
-       ssize_t result = strict_strtoul(buf, 0, &val);
+       ssize_t result = kstrtoul(buf, 0, &val);
 
        if (result < 0)
                return result;
@@ -1463,6 +1465,29 @@ static umode_t pci_dev_attrs_are_visible(struct kobject *kobj,
        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
 static struct attribute *sriov_dev_attrs[] = {
        &sriov_totalvfs_attr.attr,
@@ -1494,6 +1519,7 @@ static struct attribute_group pci_dev_attr_group = {
 
 static const struct attribute_group *pci_dev_attr_groups[] = {
        &pci_dev_attr_group,
+       &pci_dev_hp_attr_group,
 #ifdef CONFIG_PCI_IOV
        &sriov_dev_attr_group,
 #endif
index a899d8bb190d897e014f605eec53b496152a0cea..709791b70ca0548cbb74fc52dcba99f163ed8728 100644 (file)
@@ -1334,6 +1334,16 @@ int __weak pcibios_add_device (struct pci_dev *dev)
        return 0;
 }
 
+/**
+ * pcibios_release_device - provide arch specific hooks when releasing device dev
+ * @dev: the PCI device being released
+ *
+ * Permits the platform to provide architecture specific functionality when
+ * devices are released. This is the default implementation. Architecture
+ * implementations can override this.
+ */
+void __weak pcibios_release_device(struct pci_dev *dev) {}
+
 /**
  * pcibios_disable_device - disable arch specific PCI resources for device dev
  * @dev: the PCI device to disable
@@ -2421,7 +2431,7 @@ bool pci_acs_path_enabled(struct pci_dev *start,
 /**
  * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
  * @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
  * required by section 9.1 of the PCI-to-PCI bridge specification for devices
index d12c77cd6991f75c8b62008dc4ce160d6ffec36f..90ea3e88041f74c25f3339d77cf8d4929784edfb 100644 (file)
 #include <linux/aer.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|   \
                                        PCI_EXP_RTCTL_SENFEE|   \
                                        PCI_EXP_RTCTL_SEFEE)
index 5194a7d41730ab4ab1d60d26b836ce84af839b10..cf611ab2193a618880e94303d9bdbe93cd1fdf7e 100644 (file)
@@ -29,6 +29,22 @@ static inline int hest_match_pci(struct acpi_hest_aer_common *p,
                 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 pci_dev *pci_dev;
        int firmware_first;
@@ -38,34 +54,16 @@ static int aer_hest_parse(struct acpi_hest_header *hest_hdr, void *data)
 {
        struct aer_hest_parse_info *info = data;
        struct acpi_hest_aer_common *p;
-       u8 pcie_type = 0;
-       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;
-       }
+       int ff;
 
        p = (struct acpi_hest_aer_common *)(hest_hdr + 1);
+       ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
        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);
+               if (hest_match_type(hest_hdr, info->pci_dev))
+                       info->firmware_first = ff;
        } else
                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;
 }
@@ -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)
 {
+       if (!pci_is_pcie(dev))
+               return 0;
+
        if (!dev->__aer_firmware_first_valid)
                aer_set_firmware_first(dev);
        return dev->__aer_firmware_first;
index 8ec8b4f485604e384de9bf7eddfe2c97c4cae5d5..d9e776e69fe862a4538fa60b0ebc16903d0232e6 100644 (file)
@@ -400,16 +400,16 @@ void aer_do_secondary_bus_reset(struct pci_dev *dev)
 }
 
 /**
- * default_downstream_reset_link - default reset function for Downstream Port
- * @dev: pointer to downstream port's pci_dev data structure
+ * default_reset_link - default reset function
+ * @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);
-       dev_printk(KERN_DEBUG, &dev->dev,
-               "Downstream Port link has been reset\n");
+       dev_printk(KERN_DEBUG, &dev->dev, "downstream link has been reset\n");
        return PCI_ERS_RESULT_RECOVERED;
 }
 
@@ -458,8 +458,9 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
 
        if (driver && driver->reset_link) {
                status = driver->reset_link(udev);
-       } else if (pci_pcie_type(udev) == PCI_EXP_TYPE_DOWNSTREAM) {
-               status = default_downstream_reset_link(udev);
+       } else if (pci_pcie_type(udev) == PCI_EXP_TYPE_DOWNSTREAM ||
+               pci_pcie_type(udev) == PCI_EXP_TYPE_ROOT_PORT) {
+               status = default_reset_link(udev);
        } else {
                dev_printk(KERN_DEBUG, &dev->dev,
                        "no link-reset support at upstream device %s\n",
index d320df6375a2c807f8a45a8badc247bf16a956bf..403a44374ed5e160cbd0f6a0a865a5ab35de139c 100644 (file)
@@ -714,19 +714,12 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
        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,
                                     bool force)
 {
        struct pci_dev *parent = pdev->bus->self;
        struct pcie_link_state *link;
 
-       if (aspm_disabled && !force)
-               return;
-
        if (!pci_is_pcie(pdev))
                return;
 
@@ -736,6 +729,19 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem,
        if (!parent || !parent->link_state)
                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)
                down_read(&pci_bus_sem);
        mutex_lock(&aspm_lock);
@@ -761,6 +767,15 @@ void pci_disable_link_state_locked(struct pci_dev *pdev, int state)
 }
 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)
 {
        __pci_disable_link_state(pdev, state, true, false);
index 795db1f9d50c695893419b766697850c17511752..e56e594ce112fd2f8f15696d9036054e03aa9f63 100644 (file)
@@ -408,7 +408,7 @@ static int pcie_pme_resume(struct pcie_device *srv)
 
 /**
  * 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)
 {
index 70f10fa3c1b216ab88e04471c171d8404f107770..46ada5c098ebed710f24a7deb426720149b219fd 100644 (file)
@@ -170,7 +170,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 {
        u32 l, sz, mask;
        u16 orig_cmd;
-       struct pci_bus_region region;
+       struct pci_bus_region region, inverted_region;
        bool bar_too_big = false, bar_disabled = false;
 
        mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
@@ -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);
                        region.start = 0;
                        region.end = sz64;
-                       pcibios_bus_to_resource(dev, res, &region);
                        bar_disabled = true;
                } else {
                        region.start = l64;
                        region.end = l64 + sz64;
-                       pcibios_bus_to_resource(dev, res, &region);
                }
        } else {
                sz = pci_size(l, sz, mask);
@@ -265,7 +263,28 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 
                region.start = l;
                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;
@@ -278,9 +297,9 @@ out:
                pci_write_config_word(dev, PCI_COMMAND, orig_cmd);
 
        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)
-               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;
 }
@@ -451,33 +470,46 @@ 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;
 
        b = kzalloc(sizeof(*b), GFP_KERNEL);
-       if (b) {
-               INIT_LIST_HEAD(&b->node);
-               INIT_LIST_HEAD(&b->children);
-               INIT_LIST_HEAD(&b->devices);
-               INIT_LIST_HEAD(&b->slots);
-               INIT_LIST_HEAD(&b->resources);
-               b->max_bus_speed = PCI_SPEED_UNKNOWN;
-               b->cur_bus_speed = PCI_SPEED_UNKNOWN;
-       }
+       if (!b)
+               return NULL;
+
+       INIT_LIST_HEAD(&b->node);
+       INIT_LIST_HEAD(&b->children);
+       INIT_LIST_HEAD(&b->devices);
+       INIT_LIST_HEAD(&b->slots);
+       INIT_LIST_HEAD(&b->resources);
+       b->max_bus_speed = PCI_SPEED_UNKNOWN;
+       b->cur_bus_speed = PCI_SPEED_UNKNOWN;
        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)
 {
        struct pci_host_bridge *bridge;
 
        bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
-       if (bridge) {
-               INIT_LIST_HEAD(&bridge->windows);
-               bridge->bus = b;
-       }
+       if (!bridge)
+               return NULL;
 
+       INIT_LIST_HEAD(&bridge->windows);
+       bridge->bus = b;
        return bridge;
 }
 
@@ -1132,6 +1164,8 @@ static void pci_release_dev(struct device *dev)
        pci_dev = to_pci_dev(dev);
        pci_release_capabilities(pci_dev);
        pci_release_of_node(pci_dev);
+       pcibios_release_device(pci_dev);
+       pci_bus_put(pci_dev->bus);
        kfree(pci_dev);
 }
 
@@ -1188,19 +1222,7 @@ int pci_cfg_space_size(struct pci_dev *dev)
        return PCI_CFG_SPACE_SIZE;
 }
 
-static void pci_release_bus_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);
-}
-
-struct pci_dev *alloc_pci_dev(void)
+struct pci_dev *pci_alloc_dev(struct pci_bus *bus)
 {
        struct pci_dev *dev;
 
@@ -1210,9 +1232,16 @@ struct pci_dev *alloc_pci_dev(void)
 
        INIT_LIST_HEAD(&dev->bus_list);
        dev->dev.type = &pci_dev_type;
+       dev->bus = pci_bus_get(bus);
 
        return dev;
 }
+EXPORT_SYMBOL(pci_alloc_dev);
+
+struct pci_dev *alloc_pci_dev(void)
+{
+       return pci_alloc_dev(NULL);
+}
 EXPORT_SYMBOL(alloc_pci_dev);
 
 bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
@@ -1263,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))
                return NULL;
 
-       dev = alloc_pci_dev();
+       dev = pci_alloc_dev(bus);
        if (!dev)
                return NULL;
 
-       dev->bus = bus;
        dev->devfn = devfn;
        dev->vendor = l & 0xffff;
        dev->device = (l >> 16) & 0xffff;
@@ -1275,6 +1303,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
        pci_set_of_node(dev);
 
        if (pci_setup_device(dev)) {
+               pci_bus_put(dev->bus);
                kfree(dev);
                return NULL;
        }
@@ -1700,15 +1729,19 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
                goto err_out;
 
        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);
        error = pcibios_root_bridge_prepare(bridge);
-       if (error)
-               goto bridge_dev_reg_err;
+       if (error) {
+               kfree(bridge);
+               goto err_out;
+       }
 
        error = device_register(&bridge->dev);
-       if (error)
-               goto bridge_dev_reg_err;
+       if (error) {
+               put_device(&bridge->dev);
+               goto err_out;
+       }
        b->bridge = get_device(&bridge->dev);
        device_enable_async_suspend(b->bridge);
        pci_set_bus_of_node(b);
@@ -1764,8 +1797,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 class_dev_reg_err:
        put_device(&bridge->dev);
        device_unregister(&bridge->dev);
-bridge_dev_reg_err:
-       kfree(bridge);
 err_out:
        kfree(b);
        return NULL;
index 7d68aeebf56b1a53d447bd0e152643d85d06ea44..c3a04026cca8ad8d1660eeb4f30cd202038f8281 100644 (file)
@@ -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_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_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
@@ -2865,6 +2867,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);
 
 
+/*
+ * 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,
                                 void (*fn)(struct pci_dev *dev))
 {
index 846f475f62c160890835f33a234f85c6a175a222..90c95a3385d18bb52f93093da10c8d400514f712 100644 (file)
@@ -2026,7 +2026,7 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor)
 static inline int
 make_local_pdev(adapter_t *adapter, struct pci_dev **pdev)
 {
-       *pdev = alloc_pci_dev();
+       *pdev = pci_alloc_dev(NULL);
 
        if( *pdev == NULL ) return -1;
 
index 98db31d9f9b410908b2056b192bf9813bc8ce4aa..af0f840f77c8c55680afa4a0a1518a19890c7006 100644 (file)
@@ -472,7 +472,6 @@ int register_acpi_bus_type(struct acpi_bus_type *);
 int unregister_acpi_bus_type(struct acpi_bus_type *);
 
 struct acpi_pci_root {
-       struct list_head node;
        struct acpi_device * device;
        struct pci_bus *bus;
        u16 segment;
index ec10e1b24c1cce50d50581d58c5000cf7b9e5565..55bb3dc4b2db954eaf590aa93f550dfc36e82768 100644 (file)
@@ -7,6 +7,10 @@
 #ifndef _AER_H_
 #define _AER_H_
 
+#define AER_NONFATAL                   0
+#define AER_FATAL                      1
+#define AER_CORRECTABLE                        2
+
 struct aer_header_log_regs {
        unsigned int dw0;
        unsigned int dw1;
@@ -31,9 +35,9 @@ struct aer_capability_regs {
 
 #if defined(CONFIG_PCIEAER)
 /* pci-e port driver needs this function to enable aer */
-extern int pci_enable_pcie_error_reporting(struct pci_dev *dev);
-extern int pci_disable_pcie_error_reporting(struct pci_dev *dev);
-extern int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
+int pci_enable_pcie_error_reporting(struct pci_dev *dev);
+int pci_disable_pcie_error_reporting(struct pci_dev *dev);
+int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
 #else
 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)
 }
 #endif
 
-extern void cper_print_aer(const char *prefix, struct pci_dev *dev,
-                          int cper_severity, struct aer_capability_regs *aer);
-extern int cper_severity_to_aer(int cper_severity);
-extern void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
-                             int severity);
+void cper_print_aer(const char *prefix, struct pci_dev *dev, int cper_severity,
+                   struct aer_capability_regs *aer);
+int cper_severity_to_aer(int cper_severity);
+void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
+                      int severity);
 #endif //_AER_H_
 
index 3a24e4ff32481898f5009c2a162c9a7f33d0222e..0fd1f1582fa1cdf359b33f3cddeaa60026f492ac 100644 (file)
@@ -364,7 +364,8 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *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 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 *);
 void pci_release_selected_regions(struct pci_dev *, int);
 
 /* 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_offset(struct list_head *resources, struct resource *res,
                             resource_size_t offset);
@@ -1643,6 +1646,7 @@ void pcibios_set_master(struct pci_dev *dev);
 int pcibios_set_pcie_reset_state(struct pci_dev *dev,
                                 enum pcie_reset_state state);
 int pcibios_add_device(struct pci_dev *dev);
+void pcibios_release_device(struct pci_dev *dev);
 
 #ifdef CONFIG_PCI_MMCONFIG
 void __init pci_mmcfg_early_init(void);
index c12916248469f577795d28e96c4f86be747fbf5b..84c0bcc2a147570a228c469df627f9f0bafecfb7 100644 (file)
 #define PCI_DEVICE_ID_AMD_8131_BRIDGE  0x7450
 #define PCI_DEVICE_ID_AMD_8131_APIC    0x7451
 #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_CS5536_ISA    0x2090
 #define PCI_DEVICE_ID_AMD_CS5536_FLASH  0x2091
 #define PCI_DEVICE_ID_AMD_CS5536_IDE    0x209A
 #define PCI_DEVICE_ID_AMD_LX_VIDEO  0x2081
 #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_SMBUS                0x780b
+#define PCI_DEVICE_ID_AMD_HUDSON2_IDE          0x780c
 
 #define PCI_VENDOR_ID_TRIDENT          0x1023
 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX        0x2000
index 864e324da80d73aad07778f38bba7f7be8e4d55d..c3cc01d474b0b545ecfb643782386aaadaf6f1da 100644 (file)
 #define  PCI_EXP_LNKCAP_ASPMS  0x00000c00 /* ASPM Support */
 #define  PCI_EXP_LNKCAP_L0SEL  0x00007000 /* L0s 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_DLLLARC        0x00100000 /* Data Link Layer Link Active Reporting Capable */
 #define  PCI_EXP_LNKCAP_LBNC   0x00200000 /* Link Bandwidth Notification Capability */