mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	PCI: cpcihp: Iterate over all devices in slot, not functions 0-7
Iterate through devices in a slot by using the upstream bridge's "bus->devices" list instead of assuming they are functions 0-7. It's possible there are several slots on the same pci_bus, so restrict it to only devices matching this slot's device number. ARI (which allows functions 0-255) is a PCIe-only feature, and this is a PCI hotplug driver, so we shouldn't find anything other than functions 0-7, but it's better to iterate the same way as other hotplug drivers. [bhelgaas: changelog, check PCI_SLOT, fix cpci_unconfigure_slot()] Signed-off-by: Yijing Wang <wangyijing@huawei.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
		
							parent
							
								
									ba518e3c17
								
							
						
					
					
						commit
						05b1250048
					
				| @ -252,8 +252,8 @@ int cpci_led_off(struct slot* slot) | |||||||
| 
 | 
 | ||||||
| int __ref cpci_configure_slot(struct slot *slot) | int __ref cpci_configure_slot(struct slot *slot) | ||||||
| { | { | ||||||
|  | 	struct pci_dev *dev; | ||||||
| 	struct pci_bus *parent; | 	struct pci_bus *parent; | ||||||
| 	int fn; |  | ||||||
| 
 | 
 | ||||||
| 	dbg("%s - enter", __func__); | 	dbg("%s - enter", __func__); | ||||||
| 
 | 
 | ||||||
| @ -282,18 +282,13 @@ int __ref cpci_configure_slot(struct slot *slot) | |||||||
| 	} | 	} | ||||||
| 	parent = slot->dev->bus; | 	parent = slot->dev->bus; | ||||||
| 
 | 
 | ||||||
| 	for (fn = 0; fn < 8; fn++) { | 	list_for_each_entry(dev, &parent->devices, bus_list) | ||||||
| 		struct pci_dev *dev; | 		if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn)) | ||||||
| 
 |  | ||||||
| 		dev = pci_get_slot(parent, |  | ||||||
| 				   PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); |  | ||||||
| 		if (!dev) |  | ||||||
| 			continue; | 			continue; | ||||||
| 		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || | 		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || | ||||||
| 		    (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) | 		    (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) | ||||||
| 			pci_hp_add_bridge(dev); | 			pci_hp_add_bridge(dev); | ||||||
| 		pci_dev_put(dev); | 
 | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	pci_assign_unassigned_bridge_resources(parent->self); | 	pci_assign_unassigned_bridge_resources(parent->self); | ||||||
| 
 | 
 | ||||||
| @ -305,8 +300,7 @@ int __ref cpci_configure_slot(struct slot *slot) | |||||||
| 
 | 
 | ||||||
| int cpci_unconfigure_slot(struct slot* slot) | int cpci_unconfigure_slot(struct slot* slot) | ||||||
| { | { | ||||||
| 	int i; | 	struct pci_dev *dev, *temp; | ||||||
| 	struct pci_dev *dev; |  | ||||||
| 
 | 
 | ||||||
| 	dbg("%s - enter", __func__); | 	dbg("%s - enter", __func__); | ||||||
| 	if (!slot->dev) { | 	if (!slot->dev) { | ||||||
| @ -314,13 +308,12 @@ int cpci_unconfigure_slot(struct slot* slot) | |||||||
| 		return -ENODEV; | 		return -ENODEV; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < 8; i++) { | 	list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) { | ||||||
| 		dev = pci_get_slot(slot->bus, | 		if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn)) | ||||||
| 				    PCI_DEVFN(PCI_SLOT(slot->devfn), i)); | 			continue; | ||||||
| 		if (dev) { | 		pci_dev_get(dev); | ||||||
| 			pci_stop_and_remove_bus_device(dev); | 		pci_stop_and_remove_bus_device(dev); | ||||||
| 			pci_dev_put(dev); | 		pci_dev_put(dev); | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	pci_dev_put(slot->dev); | 	pci_dev_put(slot->dev); | ||||||
| 	slot->dev = NULL; | 	slot->dev = NULL; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Yijing Wang
						Yijing Wang