diff options
Diffstat (limited to 'drivers/pci/access.c')
| -rw-r--r-- | drivers/pci/access.c | 36 | 
1 files changed, 19 insertions, 17 deletions
diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 46935695cfb9..0d9f6b21babb 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -42,7 +42,10 @@ int noinline pci_bus_read_config_##size \  	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\  	pci_lock_config(flags);						\  	res = bus->ops->read(bus, devfn, pos, len, &data);		\ -	*value = (type)data;						\ +	if (res)							\ +		PCI_SET_ERROR_RESPONSE(value);				\ +	else								\ +		*value = (type)data;					\  	pci_unlock_config(flags);					\  	return res;							\  } @@ -80,10 +83,8 @@ int pci_generic_config_read(struct pci_bus *bus, unsigned int devfn,  	void __iomem *addr;  	addr = bus->ops->map_bus(bus, devfn, where); -	if (!addr) { -		*val = ~0; +	if (!addr)  		return PCIBIOS_DEVICE_NOT_FOUND; -	}  	if (size == 1)  		*val = readb(addr); @@ -122,10 +123,8 @@ int pci_generic_config_read32(struct pci_bus *bus, unsigned int devfn,  	void __iomem *addr;  	addr = bus->ops->map_bus(bus, devfn, where & ~0x3); -	if (!addr) { -		*val = ~0; +	if (!addr)  		return PCIBIOS_DEVICE_NOT_FOUND; -	}  	*val = readl(addr); @@ -228,7 +227,10 @@ int pci_user_read_config_##size						\  	ret = dev->bus->ops->read(dev->bus, dev->devfn,			\  					pos, sizeof(type), &data);	\  	raw_spin_unlock_irq(&pci_lock);				\ -	*val = (type)data;						\ +	if (ret)							\ +		PCI_SET_ERROR_RESPONSE(val);				\ +	else								\ +		*val = (type)data;					\  	return pcibios_err_to_errno(ret);				\  }									\  EXPORT_SYMBOL_GPL(pci_user_read_config_##size); @@ -410,9 +412,9 @@ int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val)  	if (pcie_capability_reg_implemented(dev, pos)) {  		ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val);  		/* -		 * Reset *val to 0 if pci_read_config_word() fails, it may -		 * have been written as 0xFFFF if hardware error happens -		 * during pci_read_config_word(). +		 * Reset *val to 0 if pci_read_config_word() fails; it may +		 * have been written as 0xFFFF (PCI_ERROR_RESPONSE) if the +		 * config read failed on PCI.  		 */  		if (ret)  			*val = 0; @@ -445,9 +447,9 @@ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val)  	if (pcie_capability_reg_implemented(dev, pos)) {  		ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val);  		/* -		 * Reset *val to 0 if pci_read_config_dword() fails, it may -		 * have been written as 0xFFFFFFFF if hardware error happens -		 * during pci_read_config_dword(). +		 * Reset *val to 0 if pci_read_config_dword() fails; it may +		 * have been written as 0xFFFFFFFF (PCI_ERROR_RESPONSE) if +		 * the config read failed on PCI.  		 */  		if (ret)  			*val = 0; @@ -523,7 +525,7 @@ EXPORT_SYMBOL(pcie_capability_clear_and_set_dword);  int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)  {  	if (pci_dev_is_disconnected(dev)) { -		*val = ~0; +		PCI_SET_ERROR_RESPONSE(val);  		return PCIBIOS_DEVICE_NOT_FOUND;  	}  	return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val); @@ -533,7 +535,7 @@ EXPORT_SYMBOL(pci_read_config_byte);  int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val)  {  	if (pci_dev_is_disconnected(dev)) { -		*val = ~0; +		PCI_SET_ERROR_RESPONSE(val);  		return PCIBIOS_DEVICE_NOT_FOUND;  	}  	return pci_bus_read_config_word(dev->bus, dev->devfn, where, val); @@ -544,7 +546,7 @@ int pci_read_config_dword(const struct pci_dev *dev, int where,  					u32 *val)  {  	if (pci_dev_is_disconnected(dev)) { -		*val = ~0; +		PCI_SET_ERROR_RESPONSE(val);  		return PCIBIOS_DEVICE_NOT_FOUND;  	}  	return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);  |