linux/arch/x86/pci/acpi.c
<<
>>
Prefs
   1#include <linux/pci.h>
   2#include <linux/acpi.h>
   3#include <linux/init.h>
   4#include <linux/irq.h>
   5#include <linux/dmi.h>
   6#include <linux/slab.h>
   7#include <asm/numa.h>
   8#include <asm/pci_x86.h>
   9
  10struct pci_root_info {
  11        struct acpi_device *bridge;
  12        char name[16];
  13        unsigned int res_num;
  14        struct resource *res;
  15        resource_size_t *res_offset;
  16        struct pci_sysdata sd;
  17#ifdef  CONFIG_PCI_MMCONFIG
  18        bool mcfg_added;
  19        u16 segment;
  20        u8 start_bus;
  21        u8 end_bus;
  22#endif
  23};
  24
  25static bool pci_use_crs = true;
  26static bool pci_ignore_seg = false;
  27
  28static int __init set_use_crs(const struct dmi_system_id *id)
  29{
  30        pci_use_crs = true;
  31        return 0;
  32}
  33
  34static int __init set_nouse_crs(const struct dmi_system_id *id)
  35{
  36        pci_use_crs = false;
  37        return 0;
  38}
  39
  40static int __init set_ignore_seg(const struct dmi_system_id *id)
  41{
  42        printk(KERN_INFO "PCI: %s detected: ignoring ACPI _SEG\n", id->ident);
  43        pci_ignore_seg = true;
  44        return 0;
  45}
  46
  47static const struct dmi_system_id pci_crs_quirks[] __initconst = {
  48        /* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */
  49        {
  50                .callback = set_use_crs,
  51                .ident = "IBM System x3800",
  52                .matches = {
  53                        DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
  54                        DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
  55                },
  56        },
  57        /* https://bugzilla.kernel.org/show_bug.cgi?id=16007 */
  58        /* 2006 AMD HT/VIA system with two host bridges */
  59        {
  60                .callback = set_use_crs,
  61                .ident = "ASRock ALiveSATA2-GLAN",
  62                .matches = {
  63                        DMI_MATCH(DMI_PRODUCT_NAME, "ALiveSATA2-GLAN"),
  64                },
  65        },
  66        /* https://bugzilla.kernel.org/show_bug.cgi?id=30552 */
  67        /* 2006 AMD HT/VIA system with two host bridges */
  68        {
  69                .callback = set_use_crs,
  70                .ident = "ASUS M2V-MX SE",
  71                .matches = {
  72                        DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
  73                        DMI_MATCH(DMI_BOARD_NAME, "M2V-MX SE"),
  74                        DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
  75                },
  76        },
  77        /* https://bugzilla.kernel.org/show_bug.cgi?id=42619 */
  78        {
  79                .callback = set_use_crs,
  80                .ident = "MSI MS-7253",
  81                .matches = {
  82                        DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
  83                        DMI_MATCH(DMI_BOARD_NAME, "MS-7253"),
  84                        DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
  85                },
  86        },
  87
  88        /* Now for the blacklist.. */
  89
  90        /* https://bugzilla.redhat.com/show_bug.cgi?id=769657 */
  91        {
  92                .callback = set_nouse_crs,
  93                .ident = "Dell Studio 1557",
  94                .matches = {
  95                        DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."),
  96                        DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1557"),
  97                        DMI_MATCH(DMI_BIOS_VERSION, "A09"),
  98                },
  99        },
 100        /* https://bugzilla.redhat.com/show_bug.cgi?id=769657 */
 101        {
 102                .callback = set_nouse_crs,
 103                .ident = "Thinkpad SL510",
 104                .matches = {
 105                        DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
 106                        DMI_MATCH(DMI_BOARD_NAME, "2847DFG"),
 107                        DMI_MATCH(DMI_BIOS_VERSION, "6JET85WW (1.43 )"),
 108                },
 109        },
 110
 111        /* https://bugzilla.kernel.org/show_bug.cgi?id=15362 */
 112        {
 113                .callback = set_ignore_seg,
 114                .ident = "HP xw9300",
 115                .matches = {
 116                        DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 117                        DMI_MATCH(DMI_PRODUCT_NAME, "HP xw9300 Workstation"),
 118                },
 119        },
 120        {}
 121};
 122
 123void __init pci_acpi_crs_quirks(void)
 124{
 125        int year;
 126
 127        if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008)
 128                pci_use_crs = false;
 129
 130        dmi_check_system(pci_crs_quirks);
 131
 132        /*
 133         * If the user specifies "pci=use_crs" or "pci=nocrs" explicitly, that
 134         * takes precedence over anything we figured out above.
 135         */
 136        if (pci_probe & PCI_ROOT_NO_CRS)
 137                pci_use_crs = false;
 138        else if (pci_probe & PCI_USE__CRS)
 139                pci_use_crs = true;
 140
 141        printk(KERN_INFO "PCI: %s host bridge windows from ACPI; "
 142               "if necessary, use \"pci=%s\" and report a bug\n",
 143               pci_use_crs ? "Using" : "Ignoring",
 144               pci_use_crs ? "nocrs" : "use_crs");
 145}
 146
 147#ifdef  CONFIG_PCI_MMCONFIG
 148static int check_segment(u16 seg, struct device *dev, char *estr)
 149{
 150        if (seg) {
 151                dev_err(dev,
 152                        "%s can't access PCI configuration "
 153                        "space under this host bridge.\n",
 154                        estr);
 155                return -EIO;
 156        }
 157
 158        /*
 159         * Failure in adding MMCFG information is not fatal,
 160         * just can't access extended configuration space of
 161         * devices under this host bridge.
 162         */
 163        dev_warn(dev,
 164                 "%s can't access extended PCI configuration "
 165                 "space under this bridge.\n",
 166                 estr);
 167
 168        return 0;
 169}
 170
 171static int setup_mcfg_map(struct pci_root_info *info, u16 seg, u8 start,
 172                          u8 end, phys_addr_t addr)
 173{
 174        int result;
 175        struct device *dev = &info->bridge->dev;
 176
 177        info->start_bus = start;
 178        info->end_bus = end;
 179        info->mcfg_added = false;
 180
 181        /* return success if MMCFG is not in use */
 182        if (raw_pci_ext_ops && raw_pci_ext_ops != &pci_mmcfg)
 183                return 0;
 184
 185        if (!(pci_probe & PCI_PROBE_MMCONF))
 186                return check_segment(seg, dev, "MMCONFIG is disabled,");
 187
 188        result = pci_mmconfig_insert(dev, seg, start, end, addr);
 189        if (result == 0) {
 190                /* enable MMCFG if it hasn't been enabled yet */
 191                if (raw_pci_ext_ops == NULL)
 192                        raw_pci_ext_ops = &pci_mmcfg;
 193                info->mcfg_added = true;
 194        } else if (result != -EEXIST)
 195                return check_segment(seg, dev,
 196                         "fail to add MMCONFIG information,");
 197
 198        return 0;
 199}
 200
 201static void teardown_mcfg_map(struct pci_root_info *info)
 202{
 203        if (info->mcfg_added) {
 204                pci_mmconfig_delete(info->segment, info->start_bus,
 205                                    info->end_bus);
 206                info->mcfg_added = false;
 207        }
 208}
 209#else
 210static int setup_mcfg_map(struct pci_root_info *info,
 211                                    u16 seg, u8 start, u8 end,
 212                                    phys_addr_t addr)
 213{
 214        return 0;
 215}
 216static void teardown_mcfg_map(struct pci_root_info *info)
 217{
 218}
 219#endif
 220
 221static acpi_status resource_to_addr(struct acpi_resource *resource,
 222                                    struct acpi_resource_address64 *addr)
 223{
 224        acpi_status status;
 225        struct acpi_resource_memory24 *memory24;
 226        struct acpi_resource_memory32 *memory32;
 227        struct acpi_resource_fixed_memory32 *fixed_memory32;
 228
 229        memset(addr, 0, sizeof(*addr));
 230        switch (resource->type) {
 231        case ACPI_RESOURCE_TYPE_MEMORY24:
 232                memory24 = &resource->data.memory24;
 233                addr->resource_type = ACPI_MEMORY_RANGE;
 234                addr->minimum = memory24->minimum;
 235                addr->address_length = memory24->address_length;
 236                addr->maximum = addr->minimum + addr->address_length - 1;
 237                return AE_OK;
 238        case ACPI_RESOURCE_TYPE_MEMORY32:
 239                memory32 = &resource->data.memory32;
 240                addr->resource_type = ACPI_MEMORY_RANGE;
 241                addr->minimum = memory32->minimum;
 242                addr->address_length = memory32->address_length;
 243                addr->maximum = addr->minimum + addr->address_length - 1;
 244                return AE_OK;
 245        case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 246                fixed_memory32 = &resource->data.fixed_memory32;
 247                addr->resource_type = ACPI_MEMORY_RANGE;
 248                addr->minimum = fixed_memory32->address;
 249                addr->address_length = fixed_memory32->address_length;
 250                addr->maximum = addr->minimum + addr->address_length - 1;
 251                return AE_OK;
 252        case ACPI_RESOURCE_TYPE_ADDRESS16:
 253        case ACPI_RESOURCE_TYPE_ADDRESS32:
 254        case ACPI_RESOURCE_TYPE_ADDRESS64:
 255                status = acpi_resource_to_address64(resource, addr);
 256                if (ACPI_SUCCESS(status) &&
 257                    (addr->resource_type == ACPI_MEMORY_RANGE ||
 258                    addr->resource_type == ACPI_IO_RANGE) &&
 259                    addr->address_length > 0) {
 260                        return AE_OK;
 261                }
 262                break;
 263        }
 264        return AE_ERROR;
 265}
 266
 267static acpi_status count_resource(struct acpi_resource *acpi_res, void *data)
 268{
 269        struct pci_root_info *info = data;
 270        struct acpi_resource_address64 addr;
 271        acpi_status status;
 272
 273        status = resource_to_addr(acpi_res, &addr);
 274        if (ACPI_SUCCESS(status))
 275                info->res_num++;
 276        return AE_OK;
 277}
 278
 279static acpi_status setup_resource(struct acpi_resource *acpi_res, void *data)
 280{
 281        struct pci_root_info *info = data;
 282        struct resource *res;
 283        struct acpi_resource_address64 addr;
 284        acpi_status status;
 285        unsigned long flags;
 286        u64 start, orig_end, end;
 287
 288        status = resource_to_addr(acpi_res, &addr);
 289        if (!ACPI_SUCCESS(status))
 290                return AE_OK;
 291
 292        if (addr.resource_type == ACPI_MEMORY_RANGE) {
 293                flags = IORESOURCE_MEM;
 294                if (addr.info.mem.caching == ACPI_PREFETCHABLE_MEMORY)
 295                        flags |= IORESOURCE_PREFETCH;
 296        } else if (addr.resource_type == ACPI_IO_RANGE) {
 297                flags = IORESOURCE_IO;
 298        } else
 299                return AE_OK;
 300
 301        start = addr.minimum + addr.translation_offset;
 302        orig_end = end = addr.maximum + addr.translation_offset;
 303
 304        /* Exclude non-addressable range or non-addressable portion of range */
 305        end = min(end, (u64)iomem_resource.end);
 306        if (end <= start) {
 307                dev_info(&info->bridge->dev,
 308                        "host bridge window [%#llx-%#llx] "
 309                        "(ignored, not CPU addressable)\n", start, orig_end);
 310                return AE_OK;
 311        } else if (orig_end != end) {
 312                dev_info(&info->bridge->dev,
 313                        "host bridge window [%#llx-%#llx] "
 314                        "([%#llx-%#llx] ignored, not CPU addressable)\n", 
 315                        start, orig_end, end + 1, orig_end);
 316        }
 317
 318        res = &info->res[info->res_num];
 319        res->name = info->name;
 320        res->flags = flags;
 321        res->start = start;
 322        res->end = end;
 323        info->res_offset[info->res_num] = addr.translation_offset;
 324        info->res_num++;
 325
 326        if (!pci_use_crs)
 327                dev_printk(KERN_DEBUG, &info->bridge->dev,
 328                           "host bridge window %pR (ignored)\n", res);
 329
 330        return AE_OK;
 331}
 332
 333static void coalesce_windows(struct pci_root_info *info, unsigned long type)
 334{
 335        int i, j;
 336        struct resource *res1, *res2;
 337
 338        for (i = 0; i < info->res_num; i++) {
 339                res1 = &info->res[i];
 340                if (!(res1->flags & type))
 341                        continue;
 342
 343                for (j = i + 1; j < info->res_num; j++) {
 344                        res2 = &info->res[j];
 345                        if (!(res2->flags & type))
 346                                continue;
 347
 348                        /*
 349                         * I don't like throwing away windows because then
 350                         * our resources no longer match the ACPI _CRS, but
 351                         * the kernel resource tree doesn't allow overlaps.
 352                         */
 353                        if (resource_overlaps(res1, res2)) {
 354                                res2->start = min(res1->start, res2->start);
 355                                res2->end = max(res1->end, res2->end);
 356                                dev_info(&info->bridge->dev,
 357                                         "host bridge window expanded to %pR; %pR ignored\n",
 358                                         res2, res1);
 359                                res1->flags = 0;
 360                        }
 361                }
 362        }
 363}
 364
 365static void add_resources(struct pci_root_info *info,
 366                          struct list_head *resources)
 367{
 368        int i;
 369        struct resource *res, *root, *conflict;
 370
 371        coalesce_windows(info, IORESOURCE_MEM);
 372        coalesce_windows(info, IORESOURCE_IO);
 373
 374        for (i = 0; i < info->res_num; i++) {
 375                res = &info->res[i];
 376
 377                if (res->flags & IORESOURCE_MEM)
 378                        root = &iomem_resource;
 379                else if (res->flags & IORESOURCE_IO)
 380                        root = &ioport_resource;
 381                else
 382                        continue;
 383
 384                conflict = insert_resource_conflict(root, res);
 385                if (conflict)
 386                        dev_info(&info->bridge->dev,
 387                                 "ignoring host bridge window %pR (conflicts with %s %pR)\n",
 388                                 res, conflict->name, conflict);
 389                else
 390                        pci_add_resource_offset(resources, res,
 391                                        info->res_offset[i]);
 392        }
 393}
 394
 395static void free_pci_root_info_res(struct pci_root_info *info)
 396{
 397        kfree(info->res);
 398        info->res = NULL;
 399        kfree(info->res_offset);
 400        info->res_offset = NULL;
 401        info->res_num = 0;
 402}
 403
 404static void __release_pci_root_info(struct pci_root_info *info)
 405{
 406        int i;
 407        struct resource *res;
 408
 409        for (i = 0; i < info->res_num; i++) {
 410                res = &info->res[i];
 411
 412                if (!res->parent)
 413                        continue;
 414
 415                if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
 416                        continue;
 417
 418                release_resource(res);
 419        }
 420
 421        free_pci_root_info_res(info);
 422
 423        teardown_mcfg_map(info);
 424
 425        kfree(info);
 426}
 427
 428static void release_pci_root_info(struct pci_host_bridge *bridge)
 429{
 430        struct pci_root_info *info = bridge->release_data;
 431
 432        __release_pci_root_info(info);
 433}
 434
 435static void probe_pci_root_info(struct pci_root_info *info,
 436                                struct acpi_device *device,
 437                                int busnum, int domain)
 438{
 439        size_t size;
 440
 441        sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum);
 442        info->bridge = device;
 443
 444        info->res_num = 0;
 445        acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
 446                                info);
 447        if (!info->res_num)
 448                return;
 449
 450        size = sizeof(*info->res) * info->res_num;
 451        info->res = kzalloc_node(size, GFP_KERNEL, info->sd.node);
 452        if (!info->res) {
 453                info->res_num = 0;
 454                return;
 455        }
 456
 457        size = sizeof(*info->res_offset) * info->res_num;
 458        info->res_num = 0;
 459        info->res_offset = kzalloc_node(size, GFP_KERNEL, info->sd.node);
 460        if (!info->res_offset) {
 461                kfree(info->res);
 462                info->res = NULL;
 463                return;
 464        }
 465
 466        acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
 467                                info);
 468}
 469
 470struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 471{
 472        struct acpi_device *device = root->device;
 473        struct pci_root_info *info;
 474        int domain = root->segment;
 475        int busnum = root->secondary.start;
 476        LIST_HEAD(resources);
 477        struct pci_bus *bus;
 478        struct pci_sysdata *sd;
 479        int node;
 480
 481        if (pci_ignore_seg)
 482                domain = 0;
 483
 484        if (domain && !pci_domains_supported) {
 485                printk(KERN_WARNING "pci_bus %04x:%02x: "
 486                       "ignored (multiple domains not supported)\n",
 487                       domain, busnum);
 488                return NULL;
 489        }
 490
 491        node = acpi_get_node(device->handle);
 492        if (node == NUMA_NO_NODE) {
 493                node = x86_pci_root_bus_node(busnum);
 494                if (node != 0 && node != NUMA_NO_NODE)
 495                        dev_info(&device->dev, FW_BUG "no _PXM; falling back to node %d from hardware (may be inconsistent with ACPI node numbers)\n",
 496                                node);
 497        }
 498
 499        if (node != NUMA_NO_NODE && !node_online(node))
 500                node = NUMA_NO_NODE;
 501
 502        info = kzalloc_node(sizeof(*info), GFP_KERNEL, node);
 503        if (!info) {
 504                printk(KERN_WARNING "pci_bus %04x:%02x: "
 505                       "ignored (out of memory)\n", domain, busnum);
 506                return NULL;
 507        }
 508
 509        sd = &info->sd;
 510        sd->domain = domain;
 511        sd->node = node;
 512        sd->companion = device;
 513
 514        bus = pci_find_bus(domain, busnum);
 515        if (bus) {
 516                /*
 517                 * If the desired bus has been scanned already, replace
 518                 * its bus->sysdata.
 519                 */
 520                memcpy(bus->sysdata, sd, sizeof(*sd));
 521                kfree(info);
 522        } else {
 523                probe_pci_root_info(info, device, busnum, domain);
 524
 525                /* insert busn res at first */
 526                pci_add_resource(&resources,  &root->secondary);
 527                /*
 528                 * _CRS with no apertures is normal, so only fall back to
 529                 * defaults or native bridge info if we're ignoring _CRS.
 530                 */
 531                if (pci_use_crs)
 532                        add_resources(info, &resources);
 533                else {
 534                        free_pci_root_info_res(info);
 535                        x86_pci_root_bus_resources(busnum, &resources);
 536                }
 537
 538                if (!setup_mcfg_map(info, domain, (u8)root->secondary.start,
 539                                    (u8)root->secondary.end, root->mcfg_addr))
 540                        bus = pci_create_root_bus(NULL, busnum, &pci_root_ops,
 541                                                  sd, &resources);
 542
 543                if (bus) {
 544                        pci_scan_child_bus(bus);
 545                        pci_set_host_bridge_release(
 546                                to_pci_host_bridge(bus->bridge),
 547                                release_pci_root_info, info);
 548                } else {
 549                        pci_free_resource_list(&resources);
 550                        __release_pci_root_info(info);
 551                }
 552        }
 553
 554        /* After the PCI-E bus has been walked and all devices discovered,
 555         * configure any settings of the fabric that might be necessary.
 556         */
 557        if (bus) {
 558                struct pci_bus *child;
 559                list_for_each_entry(child, &bus->children, node)
 560                        pcie_bus_configure_settings(child);
 561        }
 562
 563        if (bus && node != NUMA_NO_NODE)
 564                dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node);
 565
 566        return bus;
 567}
 568
 569int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
 570{
 571        struct pci_sysdata *sd = bridge->bus->sysdata;
 572
 573        ACPI_COMPANION_SET(&bridge->dev, sd->companion);
 574        return 0;
 575}
 576
 577int __init pci_acpi_init(void)
 578{
 579        struct pci_dev *dev = NULL;
 580
 581        if (acpi_noirq)
 582                return -ENODEV;
 583
 584        printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
 585        acpi_irq_penalty_init();
 586        pcibios_enable_irq = acpi_pci_irq_enable;
 587        pcibios_disable_irq = acpi_pci_irq_disable;
 588        x86_init.pci.init_irq = x86_init_noop;
 589
 590        if (pci_routeirq) {
 591                /*
 592                 * PCI IRQ routing is set up by pci_enable_device(), but we
 593                 * also do it here in case there are still broken drivers that
 594                 * don't use pci_enable_device().
 595                 */
 596                printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");
 597                for_each_pci_dev(dev)
 598                        acpi_pci_irq_enable(dev);
 599        }
 600
 601        return 0;
 602}
 603