diff options
Diffstat (limited to 'drivers/pci/pci.c')
| -rw-r--r-- | drivers/pci/pci.c | 81 | 
1 files changed, 15 insertions, 66 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 005b92e6585e..b14dd064006c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -423,36 +423,10 @@ found:  	return 1;  } -static u8 __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn, -				  u8 pos, int cap, int *ttl) -{ -	u8 id; -	u16 ent; - -	pci_bus_read_config_byte(bus, devfn, pos, &pos); - -	while ((*ttl)--) { -		if (pos < 0x40) -			break; -		pos &= ~3; -		pci_bus_read_config_word(bus, devfn, pos, &ent); - -		id = ent & 0xff; -		if (id == 0xff) -			break; -		if (id == cap) -			return pos; -		pos = (ent >> 8); -	} -	return 0; -} -  static u8 __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn,  			      u8 pos, int cap)  { -	int ttl = PCI_FIND_CAP_TTL; - -	return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl); +	return PCI_FIND_NEXT_CAP(pci_bus_read_config, pos, cap, bus, devfn);  }  u8 pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap) @@ -553,42 +527,11 @@ EXPORT_SYMBOL(pci_bus_find_capability);   */  u16 pci_find_next_ext_capability(struct pci_dev *dev, u16 start, int cap)  { -	u32 header; -	int ttl; -	u16 pos = PCI_CFG_SPACE_SIZE; - -	/* minimum 8 bytes per capability */ -	ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; -  	if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)  		return 0; -	if (start) -		pos = start; - -	if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) -		return 0; - -	/* -	 * If we have no capabilities, this is indicated by cap ID, -	 * cap version and next pointer all being 0. -	 */ -	if (header == 0) -		return 0; - -	while (ttl-- > 0) { -		if (PCI_EXT_CAP_ID(header) == cap && pos != start) -			return pos; - -		pos = PCI_EXT_CAP_NEXT(header); -		if (pos < PCI_CFG_SPACE_SIZE) -			break; - -		if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) -			break; -	} - -	return 0; +	return PCI_FIND_NEXT_EXT_CAP(pci_bus_read_config, start, cap, +				     dev->bus, dev->devfn);  }  EXPORT_SYMBOL_GPL(pci_find_next_ext_capability); @@ -648,7 +591,7 @@ EXPORT_SYMBOL_GPL(pci_get_dsn);  static u8 __pci_find_next_ht_cap(struct pci_dev *dev, u8 pos, int ht_cap)  { -	int rc, ttl = PCI_FIND_CAP_TTL; +	int rc;  	u8 cap, mask;  	if (ht_cap == HT_CAPTYPE_SLAVE || ht_cap == HT_CAPTYPE_HOST) @@ -656,8 +599,8 @@ static u8 __pci_find_next_ht_cap(struct pci_dev *dev, u8 pos, int ht_cap)  	else  		mask = HT_5BIT_CAP_MASK; -	pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos, -				      PCI_CAP_ID_HT, &ttl); +	pos = PCI_FIND_NEXT_CAP(pci_bus_read_config, pos, +				PCI_CAP_ID_HT, dev->bus, dev->devfn);  	while (pos) {  		rc = pci_read_config_byte(dev, pos + 3, &cap);  		if (rc != PCIBIOS_SUCCESSFUL) @@ -666,9 +609,10 @@ static u8 __pci_find_next_ht_cap(struct pci_dev *dev, u8 pos, int ht_cap)  		if ((cap & mask) == ht_cap)  			return pos; -		pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, -					      pos + PCI_CAP_LIST_NEXT, -					      PCI_CAP_ID_HT, &ttl); +		pos = PCI_FIND_NEXT_CAP(pci_bus_read_config, +					pos + PCI_CAP_LIST_NEXT, +					PCI_CAP_ID_HT, dev->bus, +					dev->devfn);  	}  	return 0; @@ -1374,6 +1318,11 @@ int pci_power_up(struct pci_dev *dev)  		return -EIO;  	} +	if (pci_dev_is_disconnected(dev)) { +		dev->current_state = PCI_D3cold; +		return -EIO; +	} +  	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);  	if (PCI_POSSIBLE_ERROR(pmcsr)) {  		pci_err(dev, "Unable to change power state from %s to D0, device inaccessible\n",  | 
