LCOV - code coverage report
Current view: top level - arch/x86/pci - common.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 61 212 28.8 %
Date: 2022-04-01 14:58:12 Functions: 15 25 60.0 %
Branches: 19 130 14.6 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  *      Low-Level PCI Support for PC
       4                 :            :  *
       5                 :            :  *      (c) 1999--2000 Martin Mares <mj@ucw.cz>
       6                 :            :  */
       7                 :            : 
       8                 :            : #include <linux/sched.h>
       9                 :            : #include <linux/pci.h>
      10                 :            : #include <linux/pci-acpi.h>
      11                 :            : #include <linux/ioport.h>
      12                 :            : #include <linux/init.h>
      13                 :            : #include <linux/dmi.h>
      14                 :            : #include <linux/slab.h>
      15                 :            : 
      16                 :            : #include <asm/acpi.h>
      17                 :            : #include <asm/segment.h>
      18                 :            : #include <asm/io.h>
      19                 :            : #include <asm/smp.h>
      20                 :            : #include <asm/pci_x86.h>
      21                 :            : #include <asm/setup.h>
      22                 :            : 
      23                 :            : unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
      24                 :            :                                 PCI_PROBE_MMCONF;
      25                 :            : 
      26                 :            : static int pci_bf_sort;
      27                 :            : int pci_routeirq;
      28                 :            : int noioapicquirk;
      29                 :            : #ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS
      30                 :            : int noioapicreroute = 0;
      31                 :            : #else
      32                 :            : int noioapicreroute = 1;
      33                 :            : #endif
      34                 :            : int pcibios_last_bus = -1;
      35                 :            : unsigned long pirq_table_addr;
      36                 :            : const struct pci_raw_ops *__read_mostly raw_pci_ops;
      37                 :            : const struct pci_raw_ops *__read_mostly raw_pci_ext_ops;
      38                 :            : 
      39                 :       1629 : int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
      40                 :            :                                                 int reg, int len, u32 *val)
      41                 :            : {
      42   [ +  +  +  - ]:       1629 :         if (domain == 0 && reg < 256 && raw_pci_ops)
      43                 :       1626 :                 return raw_pci_ops->read(domain, bus, devfn, reg, len, val);
      44         [ -  + ]:          3 :         if (raw_pci_ext_ops)
      45                 :          0 :                 return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val);
      46                 :            :         return -EINVAL;
      47                 :            : }
      48                 :            : 
      49                 :        672 : int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
      50                 :            :                                                 int reg, int len, u32 val)
      51                 :            : {
      52   [ +  -  +  - ]:        672 :         if (domain == 0 && reg < 256 && raw_pci_ops)
      53                 :        672 :                 return raw_pci_ops->write(domain, bus, devfn, reg, len, val);
      54         [ #  # ]:          0 :         if (raw_pci_ext_ops)
      55                 :          0 :                 return raw_pci_ext_ops->write(domain, bus, devfn, reg, len, val);
      56                 :            :         return -EINVAL;
      57                 :            : }
      58                 :            : 
      59                 :       1497 : static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
      60                 :            : {
      61                 :       1497 :         return raw_pci_read(pci_domain_nr(bus), bus->number,
      62                 :            :                                  devfn, where, size, value);
      63                 :            : }
      64                 :            : 
      65                 :        657 : static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
      66                 :            : {
      67                 :        657 :         return raw_pci_write(pci_domain_nr(bus), bus->number,
      68                 :            :                                   devfn, where, size, value);
      69                 :            : }
      70                 :            : 
      71                 :            : struct pci_ops pci_root_ops = {
      72                 :            :         .read = pci_read,
      73                 :            :         .write = pci_write,
      74                 :            : };
      75                 :            : 
      76                 :            : /*
      77                 :            :  * This interrupt-safe spinlock protects all accesses to PCI configuration
      78                 :            :  * space, except for the mmconfig (ECAM) based operations.
      79                 :            :  */
      80                 :            : DEFINE_RAW_SPINLOCK(pci_config_lock);
      81                 :            : 
      82                 :          0 : static int __init can_skip_ioresource_align(const struct dmi_system_id *d)
      83                 :            : {
      84                 :          0 :         pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
      85                 :          0 :         printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident);
      86                 :          0 :         return 0;
      87                 :            : }
      88                 :            : 
      89                 :            : static const struct dmi_system_id can_skip_pciprobe_dmi_table[] __initconst = {
      90                 :            : /*
      91                 :            :  * Systems where PCI IO resource ISA alignment can be skipped
      92                 :            :  * when the ISA enable bit in the bridge control is not set
      93                 :            :  */
      94                 :            :         {
      95                 :            :                 .callback = can_skip_ioresource_align,
      96                 :            :                 .ident = "IBM System x3800",
      97                 :            :                 .matches = {
      98                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
      99                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
     100                 :            :                 },
     101                 :            :         },
     102                 :            :         {
     103                 :            :                 .callback = can_skip_ioresource_align,
     104                 :            :                 .ident = "IBM System x3850",
     105                 :            :                 .matches = {
     106                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
     107                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "x3850"),
     108                 :            :                 },
     109                 :            :         },
     110                 :            :         {
     111                 :            :                 .callback = can_skip_ioresource_align,
     112                 :            :                 .ident = "IBM System x3950",
     113                 :            :                 .matches = {
     114                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
     115                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "x3950"),
     116                 :            :                 },
     117                 :            :         },
     118                 :            :         {}
     119                 :            : };
     120                 :            : 
     121                 :          3 : void __init dmi_check_skip_isa_align(void)
     122                 :            : {
     123                 :          3 :         dmi_check_system(can_skip_pciprobe_dmi_table);
     124                 :          3 : }
     125                 :            : 
     126                 :         21 : static void pcibios_fixup_device_resources(struct pci_dev *dev)
     127                 :            : {
     128                 :         21 :         struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
     129                 :         21 :         struct resource *bar_r;
     130                 :         21 :         int bar;
     131                 :            : 
     132         [ -  + ]:         21 :         if (pci_probe & PCI_NOASSIGN_BARS) {
     133                 :            :                 /*
     134                 :            :                 * If the BIOS did not assign the BAR, zero out the
     135                 :            :                 * resource so the kernel doesn't attempt to assign
     136                 :            :                 * it later on in pci_assign_unassigned_resources
     137                 :            :                 */
     138         [ #  # ]:          0 :                 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
     139                 :          0 :                         bar_r = &dev->resource[bar];
     140   [ #  #  #  # ]:          0 :                         if (bar_r->start == 0 && bar_r->end != 0) {
     141                 :          0 :                                 bar_r->flags = 0;
     142                 :          0 :                                 bar_r->end = 0;
     143                 :            :                         }
     144                 :            :                 }
     145                 :            :         }
     146                 :            : 
     147         [ -  + ]:         21 :         if (pci_probe & PCI_NOASSIGN_ROMS) {
     148         [ #  # ]:          0 :                 if (rom_r->parent)
     149                 :            :                         return;
     150         [ #  # ]:          0 :                 if (rom_r->start) {
     151                 :            :                         /* we deal with BIOS assigned ROM later */
     152                 :            :                         return;
     153                 :            :                 }
     154                 :          0 :                 rom_r->start = rom_r->end = rom_r->flags = 0;
     155                 :            :         }
     156                 :            : }
     157                 :            : 
     158                 :            : /*
     159                 :            :  *  Called after each bus is probed, but before its children
     160                 :            :  *  are examined.
     161                 :            :  */
     162                 :            : 
     163                 :          3 : void pcibios_fixup_bus(struct pci_bus *b)
     164                 :            : {
     165                 :          3 :         struct pci_dev *dev;
     166                 :            : 
     167                 :          3 :         pci_read_bridge_bases(b);
     168         [ +  + ]:         24 :         list_for_each_entry(dev, &b->devices, bus_list)
     169                 :         21 :                 pcibios_fixup_device_resources(dev);
     170                 :          3 : }
     171                 :            : 
     172                 :          3 : void pcibios_add_bus(struct pci_bus *bus)
     173                 :            : {
     174                 :          3 :         acpi_pci_add_bus(bus);
     175                 :          3 : }
     176                 :            : 
     177                 :          0 : void pcibios_remove_bus(struct pci_bus *bus)
     178                 :            : {
     179                 :          0 :         acpi_pci_remove_bus(bus);
     180                 :          0 : }
     181                 :            : 
     182                 :            : /*
     183                 :            :  * Only use DMI information to set this if nothing was passed
     184                 :            :  * on the kernel command line (which was parsed earlier).
     185                 :            :  */
     186                 :            : 
     187                 :          0 : static int __init set_bf_sort(const struct dmi_system_id *d)
     188                 :            : {
     189         [ #  # ]:          0 :         if (pci_bf_sort == pci_bf_sort_default) {
     190                 :          0 :                 pci_bf_sort = pci_dmi_bf;
     191                 :          0 :                 printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident);
     192                 :            :         }
     193                 :          0 :         return 0;
     194                 :            : }
     195                 :            : 
     196                 :          0 : static void __init read_dmi_type_b1(const struct dmi_header *dm,
     197                 :            :                                     void *private_data)
     198                 :            : {
     199                 :          0 :         u8 *data = (u8 *)dm + 4;
     200                 :            : 
     201         [ #  # ]:          0 :         if (dm->type != 0xB1)
     202                 :            :                 return;
     203         [ #  # ]:          0 :         if ((((*(u32 *)data) >> 9) & 0x03) == 0x01)
     204                 :          0 :                 set_bf_sort((const struct dmi_system_id *)private_data);
     205                 :            : }
     206                 :            : 
     207                 :          0 : static int __init find_sort_method(const struct dmi_system_id *d)
     208                 :            : {
     209                 :          0 :         dmi_walk(read_dmi_type_b1, (void *)d);
     210                 :          0 :         return 0;
     211                 :            : }
     212                 :            : 
     213                 :            : /*
     214                 :            :  * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus)
     215                 :            :  */
     216                 :            : #ifdef __i386__
     217                 :            : static int __init assign_all_busses(const struct dmi_system_id *d)
     218                 :            : {
     219                 :            :         pci_probe |= PCI_ASSIGN_ALL_BUSSES;
     220                 :            :         printk(KERN_INFO "%s detected: enabling PCI bus# renumbering"
     221                 :            :                         " (pci=assign-busses)\n", d->ident);
     222                 :            :         return 0;
     223                 :            : }
     224                 :            : #endif
     225                 :            : 
     226                 :          0 : static int __init set_scan_all(const struct dmi_system_id *d)
     227                 :            : {
     228                 :          0 :         printk(KERN_INFO "PCI: %s detected, enabling pci=pcie_scan_all\n",
     229                 :            :                d->ident);
     230                 :          0 :         pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS);
     231                 :          0 :         return 0;
     232                 :            : }
     233                 :            : 
     234                 :            : static const struct dmi_system_id pciprobe_dmi_table[] __initconst = {
     235                 :            : #ifdef __i386__
     236                 :            : /*
     237                 :            :  * Laptops which need pci=assign-busses to see Cardbus cards
     238                 :            :  */
     239                 :            :         {
     240                 :            :                 .callback = assign_all_busses,
     241                 :            :                 .ident = "Samsung X20 Laptop",
     242                 :            :                 .matches = {
     243                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
     244                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"),
     245                 :            :                 },
     246                 :            :         },
     247                 :            : #endif          /* __i386__ */
     248                 :            :         {
     249                 :            :                 .callback = set_bf_sort,
     250                 :            :                 .ident = "Dell PowerEdge 1950",
     251                 :            :                 .matches = {
     252                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
     253                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"),
     254                 :            :                 },
     255                 :            :         },
     256                 :            :         {
     257                 :            :                 .callback = set_bf_sort,
     258                 :            :                 .ident = "Dell PowerEdge 1955",
     259                 :            :                 .matches = {
     260                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
     261                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"),
     262                 :            :                 },
     263                 :            :         },
     264                 :            :         {
     265                 :            :                 .callback = set_bf_sort,
     266                 :            :                 .ident = "Dell PowerEdge 2900",
     267                 :            :                 .matches = {
     268                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
     269                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"),
     270                 :            :                 },
     271                 :            :         },
     272                 :            :         {
     273                 :            :                 .callback = set_bf_sort,
     274                 :            :                 .ident = "Dell PowerEdge 2950",
     275                 :            :                 .matches = {
     276                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
     277                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"),
     278                 :            :                 },
     279                 :            :         },
     280                 :            :         {
     281                 :            :                 .callback = set_bf_sort,
     282                 :            :                 .ident = "Dell PowerEdge R900",
     283                 :            :                 .matches = {
     284                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
     285                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"),
     286                 :            :                 },
     287                 :            :         },
     288                 :            :         {
     289                 :            :                 .callback = find_sort_method,
     290                 :            :                 .ident = "Dell System",
     291                 :            :                 .matches = {
     292                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
     293                 :            :                 },
     294                 :            :         },
     295                 :            :         {
     296                 :            :                 .callback = set_bf_sort,
     297                 :            :                 .ident = "HP ProLiant BL20p G3",
     298                 :            :                 .matches = {
     299                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     300                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G3"),
     301                 :            :                 },
     302                 :            :         },
     303                 :            :         {
     304                 :            :                 .callback = set_bf_sort,
     305                 :            :                 .ident = "HP ProLiant BL20p G4",
     306                 :            :                 .matches = {
     307                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     308                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G4"),
     309                 :            :                 },
     310                 :            :         },
     311                 :            :         {
     312                 :            :                 .callback = set_bf_sort,
     313                 :            :                 .ident = "HP ProLiant BL30p G1",
     314                 :            :                 .matches = {
     315                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     316                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL30p G1"),
     317                 :            :                 },
     318                 :            :         },
     319                 :            :         {
     320                 :            :                 .callback = set_bf_sort,
     321                 :            :                 .ident = "HP ProLiant BL25p G1",
     322                 :            :                 .matches = {
     323                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     324                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL25p G1"),
     325                 :            :                 },
     326                 :            :         },
     327                 :            :         {
     328                 :            :                 .callback = set_bf_sort,
     329                 :            :                 .ident = "HP ProLiant BL35p G1",
     330                 :            :                 .matches = {
     331                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     332                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL35p G1"),
     333                 :            :                 },
     334                 :            :         },
     335                 :            :         {
     336                 :            :                 .callback = set_bf_sort,
     337                 :            :                 .ident = "HP ProLiant BL45p G1",
     338                 :            :                 .matches = {
     339                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     340                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G1"),
     341                 :            :                 },
     342                 :            :         },
     343                 :            :         {
     344                 :            :                 .callback = set_bf_sort,
     345                 :            :                 .ident = "HP ProLiant BL45p G2",
     346                 :            :                 .matches = {
     347                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     348                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G2"),
     349                 :            :                 },
     350                 :            :         },
     351                 :            :         {
     352                 :            :                 .callback = set_bf_sort,
     353                 :            :                 .ident = "HP ProLiant BL460c G1",
     354                 :            :                 .matches = {
     355                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     356                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL460c G1"),
     357                 :            :                 },
     358                 :            :         },
     359                 :            :         {
     360                 :            :                 .callback = set_bf_sort,
     361                 :            :                 .ident = "HP ProLiant BL465c G1",
     362                 :            :                 .matches = {
     363                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     364                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL465c G1"),
     365                 :            :                 },
     366                 :            :         },
     367                 :            :         {
     368                 :            :                 .callback = set_bf_sort,
     369                 :            :                 .ident = "HP ProLiant BL480c G1",
     370                 :            :                 .matches = {
     371                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     372                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL480c G1"),
     373                 :            :                 },
     374                 :            :         },
     375                 :            :         {
     376                 :            :                 .callback = set_bf_sort,
     377                 :            :                 .ident = "HP ProLiant BL685c G1",
     378                 :            :                 .matches = {
     379                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     380                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"),
     381                 :            :                 },
     382                 :            :         },
     383                 :            :         {
     384                 :            :                 .callback = set_bf_sort,
     385                 :            :                 .ident = "HP ProLiant DL360",
     386                 :            :                 .matches = {
     387                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     388                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL360"),
     389                 :            :                 },
     390                 :            :         },
     391                 :            :         {
     392                 :            :                 .callback = set_bf_sort,
     393                 :            :                 .ident = "HP ProLiant DL380",
     394                 :            :                 .matches = {
     395                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     396                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL380"),
     397                 :            :                 },
     398                 :            :         },
     399                 :            : #ifdef __i386__
     400                 :            :         {
     401                 :            :                 .callback = assign_all_busses,
     402                 :            :                 .ident = "Compaq EVO N800c",
     403                 :            :                 .matches = {
     404                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
     405                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "EVO N800c"),
     406                 :            :                 },
     407                 :            :         },
     408                 :            : #endif
     409                 :            :         {
     410                 :            :                 .callback = set_bf_sort,
     411                 :            :                 .ident = "HP ProLiant DL385 G2",
     412                 :            :                 .matches = {
     413                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     414                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL385 G2"),
     415                 :            :                 },
     416                 :            :         },
     417                 :            :         {
     418                 :            :                 .callback = set_bf_sort,
     419                 :            :                 .ident = "HP ProLiant DL585 G2",
     420                 :            :                 .matches = {
     421                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "HP"),
     422                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
     423                 :            :                 },
     424                 :            :         },
     425                 :            :         {
     426                 :            :                 .callback = set_scan_all,
     427                 :            :                 .ident = "Stratus/NEC ftServer",
     428                 :            :                 .matches = {
     429                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Stratus"),
     430                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "ftServer"),
     431                 :            :                 },
     432                 :            :         },
     433                 :            :         {
     434                 :            :                 .callback = set_scan_all,
     435                 :            :                 .ident = "Stratus/NEC ftServer",
     436                 :            :                 .matches = {
     437                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
     438                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R32"),
     439                 :            :                 },
     440                 :            :         },
     441                 :            :         {
     442                 :            :                 .callback = set_scan_all,
     443                 :            :                 .ident = "Stratus/NEC ftServer",
     444                 :            :                 .matches = {
     445                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "NEC"),
     446                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "Express5800/R31"),
     447                 :            :                 },
     448                 :            :         },
     449                 :            :         {}
     450                 :            : };
     451                 :            : 
     452                 :          3 : void __init dmi_check_pciprobe(void)
     453                 :            : {
     454                 :          3 :         dmi_check_system(pciprobe_dmi_table);
     455                 :          3 : }
     456                 :            : 
     457                 :          0 : void pcibios_scan_root(int busnum)
     458                 :            : {
     459                 :          0 :         struct pci_bus *bus;
     460                 :          0 :         struct pci_sysdata *sd;
     461                 :          0 :         LIST_HEAD(resources);
     462                 :            : 
     463                 :          0 :         sd = kzalloc(sizeof(*sd), GFP_KERNEL);
     464         [ #  # ]:          0 :         if (!sd) {
     465                 :          0 :                 printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum);
     466                 :          0 :                 return;
     467                 :            :         }
     468                 :          0 :         sd->node = x86_pci_root_bus_node(busnum);
     469                 :          0 :         x86_pci_root_bus_resources(busnum, &resources);
     470                 :          0 :         printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
     471                 :          0 :         bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources);
     472         [ #  # ]:          0 :         if (!bus) {
     473                 :          0 :                 pci_free_resource_list(&resources);
     474                 :          0 :                 kfree(sd);
     475                 :          0 :                 return;
     476                 :            :         }
     477                 :          0 :         pci_bus_add_devices(bus);
     478                 :            : }
     479                 :            : 
     480                 :          3 : void __init pcibios_set_cache_line_size(void)
     481                 :            : {
     482                 :          3 :         struct cpuinfo_x86 *c = &boot_cpu_data;
     483                 :            : 
     484                 :            :         /*
     485                 :            :          * Set PCI cacheline size to that of the CPU if the CPU has reported it.
     486                 :            :          * (For older CPUs that don't support cpuid, we se it to 32 bytes
     487                 :            :          * It's also good for 386/486s (which actually have 16)
     488                 :            :          * as quite a few PCI devices do not support smaller values.
     489                 :            :          */
     490         [ +  - ]:          3 :         if (c->x86_clflush_size > 0) {
     491                 :          3 :                 pci_dfl_cache_line_size = c->x86_clflush_size >> 2;
     492                 :          3 :                 printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n",
     493                 :            :                         pci_dfl_cache_line_size << 2);
     494                 :            :         } else {
     495                 :          0 :                 pci_dfl_cache_line_size = 32 >> 2;
     496                 :          0 :                 printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n");
     497                 :            :         }
     498                 :          3 : }
     499                 :            : 
     500                 :          3 : int __init pcibios_init(void)
     501                 :            : {
     502   [ -  +  -  - ]:          3 :         if (!raw_pci_ops && !raw_pci_ext_ops) {
     503                 :          0 :                 printk(KERN_WARNING "PCI: System does not support PCI\n");
     504                 :          0 :                 return 0;
     505                 :            :         }
     506                 :            : 
     507                 :          3 :         pcibios_set_cache_line_size();
     508                 :          3 :         pcibios_resource_survey();
     509                 :            : 
     510         [ -  + ]:          3 :         if (pci_bf_sort >= pci_force_bf)
     511                 :          0 :                 pci_sort_breadthfirst();
     512                 :            :         return 0;
     513                 :            : }
     514                 :            : 
     515                 :          0 : char *__init pcibios_setup(char *str)
     516                 :            : {
     517         [ #  # ]:          0 :         if (!strcmp(str, "off")) {
     518                 :          0 :                 pci_probe = 0;
     519                 :          0 :                 return NULL;
     520         [ #  # ]:          0 :         } else if (!strcmp(str, "bfsort")) {
     521                 :          0 :                 pci_bf_sort = pci_force_bf;
     522                 :          0 :                 return NULL;
     523         [ #  # ]:          0 :         } else if (!strcmp(str, "nobfsort")) {
     524                 :          0 :                 pci_bf_sort = pci_force_nobf;
     525                 :          0 :                 return NULL;
     526                 :            :         }
     527                 :            : #ifdef CONFIG_PCI_BIOS
     528                 :            :         else if (!strcmp(str, "bios")) {
     529                 :            :                 pci_probe = PCI_PROBE_BIOS;
     530                 :            :                 return NULL;
     531                 :            :         } else if (!strcmp(str, "nobios")) {
     532                 :            :                 pci_probe &= ~PCI_PROBE_BIOS;
     533                 :            :                 return NULL;
     534                 :            :         } else if (!strcmp(str, "biosirq")) {
     535                 :            :                 pci_probe |= PCI_BIOS_IRQ_SCAN;
     536                 :            :                 return NULL;
     537                 :            :         } else if (!strncmp(str, "pirqaddr=", 9)) {
     538                 :            :                 pirq_table_addr = simple_strtoul(str+9, NULL, 0);
     539                 :            :                 return NULL;
     540                 :            :         }
     541                 :            : #endif
     542                 :            : #ifdef CONFIG_PCI_DIRECT
     543         [ #  # ]:          0 :         else if (!strcmp(str, "conf1")) {
     544                 :          0 :                 pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
     545                 :          0 :                 return NULL;
     546                 :            :         }
     547         [ #  # ]:          0 :         else if (!strcmp(str, "conf2")) {
     548                 :          0 :                 pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS;
     549                 :          0 :                 return NULL;
     550                 :            :         }
     551                 :            : #endif
     552                 :            : #ifdef CONFIG_PCI_MMCONFIG
     553         [ #  # ]:          0 :         else if (!strcmp(str, "nommconf")) {
     554                 :          0 :                 pci_probe &= ~PCI_PROBE_MMCONF;
     555                 :          0 :                 return NULL;
     556                 :            :         }
     557         [ #  # ]:          0 :         else if (!strcmp(str, "check_enable_amd_mmconf")) {
     558                 :          0 :                 pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF;
     559                 :          0 :                 return NULL;
     560                 :            :         }
     561                 :            : #endif
     562         [ #  # ]:          0 :         else if (!strcmp(str, "noacpi")) {
     563                 :          0 :                 acpi_noirq_set();
     564                 :          0 :                 return NULL;
     565                 :            :         }
     566         [ #  # ]:          0 :         else if (!strcmp(str, "noearly")) {
     567                 :          0 :                 pci_probe |= PCI_PROBE_NOEARLY;
     568                 :          0 :                 return NULL;
     569                 :            :         }
     570         [ #  # ]:          0 :         else if (!strcmp(str, "usepirqmask")) {
     571                 :          0 :                 pci_probe |= PCI_USE_PIRQ_MASK;
     572                 :          0 :                 return NULL;
     573         [ #  # ]:          0 :         } else if (!strncmp(str, "irqmask=", 8)) {
     574                 :          0 :                 pcibios_irq_mask = simple_strtol(str+8, NULL, 0);
     575                 :          0 :                 return NULL;
     576         [ #  # ]:          0 :         } else if (!strncmp(str, "lastbus=", 8)) {
     577                 :          0 :                 pcibios_last_bus = simple_strtol(str+8, NULL, 0);
     578                 :          0 :                 return NULL;
     579         [ #  # ]:          0 :         } else if (!strcmp(str, "rom")) {
     580                 :          0 :                 pci_probe |= PCI_ASSIGN_ROMS;
     581                 :          0 :                 return NULL;
     582         [ #  # ]:          0 :         } else if (!strcmp(str, "norom")) {
     583                 :          0 :                 pci_probe |= PCI_NOASSIGN_ROMS;
     584                 :          0 :                 return NULL;
     585         [ #  # ]:          0 :         } else if (!strcmp(str, "nobar")) {
     586                 :          0 :                 pci_probe |= PCI_NOASSIGN_BARS;
     587                 :          0 :                 return NULL;
     588         [ #  # ]:          0 :         } else if (!strcmp(str, "assign-busses")) {
     589                 :          0 :                 pci_probe |= PCI_ASSIGN_ALL_BUSSES;
     590                 :          0 :                 return NULL;
     591         [ #  # ]:          0 :         } else if (!strcmp(str, "use_crs")) {
     592                 :          0 :                 pci_probe |= PCI_USE__CRS;
     593                 :          0 :                 return NULL;
     594         [ #  # ]:          0 :         } else if (!strcmp(str, "nocrs")) {
     595                 :          0 :                 pci_probe |= PCI_ROOT_NO_CRS;
     596                 :          0 :                 return NULL;
     597                 :            : #ifdef CONFIG_PHYS_ADDR_T_64BIT
     598         [ #  # ]:          0 :         } else if (!strcmp(str, "big_root_window")) {
     599                 :          0 :                 pci_probe |= PCI_BIG_ROOT_WINDOW;
     600                 :          0 :                 return NULL;
     601                 :            : #endif
     602         [ #  # ]:          0 :         } else if (!strcmp(str, "routeirq")) {
     603                 :          0 :                 pci_routeirq = 1;
     604                 :          0 :                 return NULL;
     605         [ #  # ]:          0 :         } else if (!strcmp(str, "skip_isa_align")) {
     606                 :          0 :                 pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
     607                 :          0 :                 return NULL;
     608         [ #  # ]:          0 :         } else if (!strcmp(str, "noioapicquirk")) {
     609                 :          0 :                 noioapicquirk = 1;
     610                 :          0 :                 return NULL;
     611         [ #  # ]:          0 :         } else if (!strcmp(str, "ioapicreroute")) {
     612         [ #  # ]:          0 :                 if (noioapicreroute != -1)
     613                 :          0 :                         noioapicreroute = 0;
     614                 :          0 :                 return NULL;
     615         [ #  # ]:          0 :         } else if (!strcmp(str, "noioapicreroute")) {
     616         [ #  # ]:          0 :                 if (noioapicreroute != -1)
     617                 :          0 :                         noioapicreroute = 1;
     618                 :          0 :                 return NULL;
     619                 :            :         }
     620                 :            :         return str;
     621                 :            : }
     622                 :            : 
     623                 :          0 : unsigned int pcibios_assign_all_busses(void)
     624                 :            : {
     625                 :          0 :         return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
     626                 :            : }
     627                 :            : 
     628                 :            : static void set_dev_domain_options(struct pci_dev *pdev)
     629                 :            : {
     630                 :            :         if (is_vmd(pdev->bus))
     631                 :            :                 pdev->hotplug_user_indicators = 1;
     632                 :            : }
     633                 :            : 
     634                 :         21 : int pcibios_add_device(struct pci_dev *dev)
     635                 :            : {
     636                 :         21 :         struct setup_data *data;
     637                 :         21 :         struct pci_setup_rom *rom;
     638                 :         21 :         u64 pa_data;
     639                 :            : 
     640                 :         21 :         pa_data = boot_params.hdr.setup_data;
     641         [ -  + ]:         21 :         while (pa_data) {
     642                 :          0 :                 data = memremap(pa_data, sizeof(*rom), MEMREMAP_WB);
     643         [ #  # ]:          0 :                 if (!data)
     644                 :            :                         return -ENOMEM;
     645                 :            : 
     646         [ #  # ]:          0 :                 if (data->type == SETUP_PCI) {
     647                 :          0 :                         rom = (struct pci_setup_rom *)data;
     648                 :            : 
     649         [ #  # ]:          0 :                         if ((pci_domain_nr(dev->bus) == rom->segment) &&
     650         [ #  # ]:          0 :                             (dev->bus->number == rom->bus) &&
     651         [ #  # ]:          0 :                             (PCI_SLOT(dev->devfn) == rom->device) &&
     652         [ #  # ]:          0 :                             (PCI_FUNC(dev->devfn) == rom->function) &&
     653         [ #  # ]:          0 :                             (dev->vendor == rom->vendor) &&
     654                 :            :                             (dev->device == rom->devid)) {
     655                 :          0 :                                 dev->rom = pa_data +
     656                 :            :                                       offsetof(struct pci_setup_rom, romdata);
     657                 :          0 :                                 dev->romlen = rom->pcilen;
     658                 :            :                         }
     659                 :            :                 }
     660                 :          0 :                 pa_data = data->next;
     661                 :          0 :                 memunmap(data);
     662                 :            :         }
     663                 :            :         set_dev_domain_options(dev);
     664                 :            :         return 0;
     665                 :            : }
     666                 :            : 
     667                 :         12 : int pcibios_enable_device(struct pci_dev *dev, int mask)
     668                 :            : {
     669                 :         12 :         int err;
     670                 :            : 
     671         [ +  - ]:         12 :         if ((err = pci_enable_resources(dev, mask)) < 0)
     672                 :            :                 return err;
     673                 :            : 
     674         [ +  - ]:         12 :         if (!pci_dev_msi_enabled(dev))
     675                 :         12 :                 return pcibios_enable_irq(dev);
     676                 :            :         return 0;
     677                 :            : }
     678                 :            : 
     679                 :          3 : void pcibios_disable_device (struct pci_dev *dev)
     680                 :            : {
     681   [ -  -  +  -  :          3 :         if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq)
                   +  - ]
     682                 :          3 :                 pcibios_disable_irq(dev);
     683                 :          3 : }
     684                 :            : 
     685                 :            : #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
     686                 :          0 : void pcibios_release_device(struct pci_dev *dev)
     687                 :            : {
     688         [ #  # ]:          0 :         if (atomic_dec_return(&dev->enable_cnt) >= 0)
     689         [ #  # ]:          0 :                 pcibios_disable_device(dev);
     690                 :            : 
     691                 :          0 : }
     692                 :            : #endif
     693                 :            : 
     694                 :          3 : int pci_ext_cfg_avail(void)
     695                 :            : {
     696         [ +  - ]:          3 :         if (raw_pci_ext_ops)
     697                 :            :                 return 1;
     698                 :            :         else
     699                 :          3 :                 return 0;
     700                 :            : }
     701                 :            : 
     702                 :            : #if IS_ENABLED(CONFIG_VMD)
     703                 :            : struct pci_dev *pci_real_dma_dev(struct pci_dev *dev)
     704                 :            : {
     705                 :            :         if (is_vmd(dev->bus))
     706                 :            :                 return to_pci_sysdata(dev->bus)->vmd_dev;
     707                 :            : 
     708                 :            :         return dev;
     709                 :            : }
     710                 :            : #endif

Generated by: LCOV version 1.14