diff options
Diffstat (limited to 'arch/x86/pci/mmconfig_32.c')
| -rw-r--r-- | arch/x86/pci/mmconfig_32.c | 30 | 
1 files changed, 27 insertions, 3 deletions
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index 5372e86834c..db63ac23e3d 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c @@ -11,6 +11,7 @@  #include <linux/pci.h>  #include <linux/init.h> +#include <linux/rcupdate.h>  #include <asm/e820.h>  #include <asm/pci_x86.h>  #include <acpi/acpi.h> @@ -60,9 +61,12 @@ err:		*value = -1;  		return -EINVAL;  	} +	rcu_read_lock();  	base = get_base_addr(seg, bus, devfn); -	if (!base) +	if (!base) { +		rcu_read_unlock();  		goto err; +	}  	raw_spin_lock_irqsave(&pci_config_lock, flags); @@ -80,6 +84,7 @@ err:		*value = -1;  		break;  	}  	raw_spin_unlock_irqrestore(&pci_config_lock, flags); +	rcu_read_unlock();  	return 0;  } @@ -93,9 +98,12 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,  	if ((bus > 255) || (devfn > 255) || (reg > 4095))  		return -EINVAL; +	rcu_read_lock();  	base = get_base_addr(seg, bus, devfn); -	if (!base) +	if (!base) { +		rcu_read_unlock();  		return -EINVAL; +	}  	raw_spin_lock_irqsave(&pci_config_lock, flags); @@ -113,11 +121,12 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,  		break;  	}  	raw_spin_unlock_irqrestore(&pci_config_lock, flags); +	rcu_read_unlock();  	return 0;  } -static const struct pci_raw_ops pci_mmcfg = { +const struct pci_raw_ops pci_mmcfg = {  	.read =		pci_mmcfg_read,  	.write =	pci_mmcfg_write,  }; @@ -132,3 +141,18 @@ int __init pci_mmcfg_arch_init(void)  void __init pci_mmcfg_arch_free(void)  {  } + +int __devinit pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg) +{ +	return 0; +} + +void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg) +{ +	unsigned long flags; + +	/* Invalidate the cached mmcfg map entry. */ +	raw_spin_lock_irqsave(&pci_config_lock, flags); +	mmcfg_last_accessed_device = 0; +	raw_spin_unlock_irqrestore(&pci_config_lock, flags); +}  |