diff options
Diffstat (limited to 'drivers/pci/controller/vmd.c')
| -rw-r--r-- | drivers/pci/controller/vmd.c | 25 | 
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index 4575e0c6dc4b..a35d3f3996d7 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c @@ -31,6 +31,9 @@  #define PCI_REG_VMLOCK		0x70  #define MB2_SHADOW_EN(vmlock)	(vmlock & 0x2) +#define MB2_SHADOW_OFFSET	0x2000 +#define MB2_SHADOW_SIZE		16 +  enum vmd_features {  	/*  	 * Device may contain registers which hint the physical location of the @@ -94,6 +97,7 @@ struct vmd_dev {  	struct resource		resources[3];  	struct irq_domain	*irq_domain;  	struct pci_bus		*bus; +	u8			busn_start;  	struct dma_map_ops	dma_ops;  	struct dma_domain	dma_domain; @@ -440,7 +444,8 @@ static char __iomem *vmd_cfg_addr(struct vmd_dev *vmd, struct pci_bus *bus,  				  unsigned int devfn, int reg, int len)  {  	char __iomem *addr = vmd->cfgbar + -			     (bus->number << 20) + (devfn << 12) + reg; +			     ((bus->number - vmd->busn_start) << 20) + +			     (devfn << 12) + reg;  	if ((addr - vmd->cfgbar) + len >=  	    resource_size(&vmd->dev->resource[VMD_CFGBAR])) @@ -563,7 +568,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)  	unsigned long flags;  	LIST_HEAD(resources);  	resource_size_t offset[2] = {0}; -	resource_size_t membar2_offset = 0x2000, busn_start = 0; +	resource_size_t membar2_offset = 0x2000;  	struct pci_bus *child;  	/* @@ -576,7 +581,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)  		u32 vmlock;  		int ret; -		membar2_offset = 0x2018; +		membar2_offset = MB2_SHADOW_OFFSET + MB2_SHADOW_SIZE;  		ret = pci_read_config_dword(vmd->dev, PCI_REG_VMLOCK, &vmlock);  		if (ret || vmlock == ~0)  			return -ENODEV; @@ -588,9 +593,9 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)  			if (!membar2)  				return -ENOMEM;  			offset[0] = vmd->dev->resource[VMD_MEMBAR1].start - -						readq(membar2 + 0x2008); +					readq(membar2 + MB2_SHADOW_OFFSET);  			offset[1] = vmd->dev->resource[VMD_MEMBAR2].start - -						readq(membar2 + 0x2010); +					readq(membar2 + MB2_SHADOW_OFFSET + 8);  			pci_iounmap(vmd->dev, membar2);  		}  	} @@ -606,14 +611,14 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)  		pci_read_config_dword(vmd->dev, PCI_REG_VMCONFIG, &vmconfig);  		if (BUS_RESTRICT_CAP(vmcap) &&  		    (BUS_RESTRICT_CFG(vmconfig) == 0x1)) -			busn_start = 128; +			vmd->busn_start = 128;  	}  	res = &vmd->dev->resource[VMD_CFGBAR];  	vmd->resources[0] = (struct resource) {  		.name  = "VMD CFGBAR", -		.start = busn_start, -		.end   = busn_start + (resource_size(res) >> 20) - 1, +		.start = vmd->busn_start, +		.end   = vmd->busn_start + (resource_size(res) >> 20) - 1,  		.flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED,  	}; @@ -681,8 +686,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)  	pci_add_resource_offset(&resources, &vmd->resources[1], offset[0]);  	pci_add_resource_offset(&resources, &vmd->resources[2], offset[1]); -	vmd->bus = pci_create_root_bus(&vmd->dev->dev, busn_start, &vmd_ops, -				       sd, &resources); +	vmd->bus = pci_create_root_bus(&vmd->dev->dev, vmd->busn_start, +				       &vmd_ops, sd, &resources);  	if (!vmd->bus) {  		pci_free_resource_list(&resources);  		irq_domain_remove(vmd->irq_domain);  |