cregit-Linux how code gets into the kernel

Release 4.14 arch/x86/pci/mmconfig_64.c

Directory: arch/x86/pci
// SPDX-License-Identifier: GPL-2.0
/*
 * mmconfig.c - Low-level direct PCI config space access via MMCONFIG
 *
 * This is an 64bit optimized version that always keeps the full mmconfig
 * space mapped. This allows lockless config space operation.
 */

#include <linux/pci.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/bitmap.h>
#include <linux/rcupdate.h>
#include <asm/e820/api.h>
#include <asm/pci_x86.h>


#define PREFIX "PCI: "


static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) { struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus); if (cfg && cfg->virt) return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12)); return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Björn Helgaas2439.34%555.56%
Greg Kroah-Hartman2337.70%111.11%
Andi Kleen1321.31%222.22%
Al Viro11.64%111.11%
Total61100.00%9100.00%


static int pci_mmcfg_read(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 *value) { char __iomem *addr; /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) { err: *value = -1; return -EINVAL; } rcu_read_lock(); addr = pci_dev_base(seg, bus, devfn); if (!addr) { rcu_read_unlock(); goto err; } switch (len) { case 1: *value = mmio_config_readb(addr + reg); break; case 2: *value = mmio_config_readw(addr + reg); break; case 4: *value = mmio_config_readl(addr + reg); break; } rcu_read_unlock(); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Andi Kleen11374.34%337.50%
Ivan Kokshaysky2113.82%112.50%
Jiang Liu117.24%112.50%
Dean Gaudet31.97%112.50%
Björn Helgaas31.97%112.50%
Al Viro10.66%112.50%
Total152100.00%8100.00%


static int pci_mmcfg_write(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 value) { char __iomem *addr; /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; rcu_read_lock(); addr = pci_dev_base(seg, bus, devfn); if (!addr) { rcu_read_unlock(); return -EINVAL; } switch (len) { case 1: mmio_config_writeb(addr + reg, value); break; case 2: mmio_config_writew(addr + reg, value); break; case 4: mmio_config_writel(addr + reg, value); break; } rcu_read_unlock(); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Andi Kleen9568.35%228.57%
Ivan Kokshaysky2014.39%114.29%
Jiang Liu117.91%114.29%
Dean Gaudet96.47%114.29%
Björn Helgaas32.16%114.29%
Al Viro10.72%114.29%
Total139100.00%7100.00%

const struct pci_raw_ops pci_mmcfg = { .read = pci_mmcfg_read, .write = pci_mmcfg_write, };
static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg) { void __iomem *addr; u64 start, size; int num_buses; start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus); num_buses = cfg->end_bus - cfg->start_bus + 1; size = PCI_MMCFG_BUS_OFFSET(num_buses); addr = ioremap_nocache(start, size); if (addr) addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus); return addr; }

Contributors

PersonTokensPropCommitsCommitProp
Hirofumi Ogawa3845.78%120.00%
Björn Helgaas2428.92%360.00%
Yinghai Lu2125.30%120.00%
Total83100.00%5100.00%


int __init pci_mmcfg_arch_init(void) { struct pci_mmcfg_region *cfg; list_for_each_entry(cfg, &pci_mmcfg_list, list) if (pci_mmcfg_arch_map(cfg)) { pci_mmcfg_arch_free(); return 0; } raw_pci_ext_ops = &pci_mmcfg; return 1; }

Contributors

PersonTokensPropCommitsCommitProp
Andi Kleen1534.09%225.00%
Björn Helgaas1431.82%225.00%
Olivier Galibert818.18%112.50%
Jiang Liu36.82%112.50%
Yinghai Lu36.82%112.50%
Matthew Wilcox12.27%112.50%
Total44100.00%8100.00%


void __init pci_mmcfg_arch_free(void) { struct pci_mmcfg_region *cfg; list_for_each_entry(cfg, &pci_mmcfg_list, list) pci_mmcfg_arch_unmap(cfg); }

Contributors

PersonTokensPropCommitsCommitProp
Björn Helgaas1350.00%250.00%
Yinghai Lu726.92%125.00%
Jiang Liu623.08%125.00%
Total26100.00%4100.00%


int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg) { cfg->virt = mcfg_ioremap(cfg); if (!cfg->virt) { pr_err(PREFIX "can't map MMCONFIG at %pR\n", &cfg->res); return -ENOMEM; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jiang Liu4393.48%250.00%
Björn Helgaas24.35%125.00%
Yinghai Lu12.17%125.00%
Total46100.00%4100.00%


void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg) { if (cfg && cfg->virt) { iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus)); cfg->virt = NULL; } }

Contributors

PersonTokensPropCommitsCommitProp
Yinghai Lu1742.50%233.33%
Jiang Liu1332.50%116.67%
Björn Helgaas1025.00%350.00%
Total40100.00%6100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Andi Kleen26341.42%412.90%
Björn Helgaas9715.28%825.81%
Jiang Liu9014.17%39.68%
Yinghai Lu497.72%26.45%
Ivan Kokshaysky416.46%13.23%
Hirofumi Ogawa385.98%13.23%
Greg Kroah-Hartman274.25%39.68%
Dean Gaudet121.89%13.23%
Olivier Galibert81.26%13.23%
Al Viro30.47%13.23%
Arjan van de Ven20.31%13.23%
Jan Beulich10.16%13.23%
Ingo Molnar10.16%13.23%
Jaswinder Singh Rajput10.16%13.23%
Alexey Y. Starikovskiy10.16%13.23%
Matthew Wilcox10.16%13.23%
Total635100.00%31100.00%
Directory: arch/x86/pci
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.