PCI: call final fixups hot-added devices
Final fixups are currently applied only at boot-time by pci_apply_final_quirks(), which is an fs_initcall(). Hot-added devices don't get these fixups, so they may not be completely initialized. This patch makes us run final fixups for hot-added devices in pci_bus_add_device() just before the new device becomes eligible for driver binding. This patch keeps the fs_initcall() for devices present at boot because we do resource assignment between pci_bus_add_device and the fs_initcall(), and we don't want to break any fixups that depend on that assignment. This is a design issue that may be addressed in the future -- any resource assignment should be done *before* device_add(). [bhelgaas: changelog] Signed-off-by: Myron Stowe <myron.stowe@redhat.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
		
							parent
							
								
									3274c8eb26
								
							
						
					
					
						commit
						735bff10c1
					
				| @ -164,6 +164,10 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||||||
| int pci_bus_add_device(struct pci_dev *dev) | int pci_bus_add_device(struct pci_dev *dev) | ||||||
| { | { | ||||||
| 	int retval; | 	int retval; | ||||||
|  | 	extern bool pci_fixup_final_inited; | ||||||
|  | 
 | ||||||
|  | 	if (pci_fixup_final_inited) | ||||||
|  | 		pci_fixup_device(pci_fixup_final, dev); | ||||||
| 	retval = device_add(&dev->dev); | 	retval = device_add(&dev->dev); | ||||||
| 	if (retval) | 	if (retval) | ||||||
| 		return retval; | 		return retval; | ||||||
|  | |||||||
| @ -3028,6 +3028,22 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | |||||||
| } | } | ||||||
| EXPORT_SYMBOL(pci_fixup_device); | EXPORT_SYMBOL(pci_fixup_device); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * The global variable 'pci_fixup_final_inited' is being used as a interim | ||||||
|  |  * solution for calling the final quirks only during hot-plug events (not | ||||||
|  |  * during boot processing). | ||||||
|  |  * | ||||||
|  |  * When the boot path's PCI device setup sequencing is addressed, we can | ||||||
|  |  * remove the instance, and usages of, 'pci_fixup_final_inited' along with | ||||||
|  |  * removing 'fs_initcall_sync(pci_apply_final_quirks);' and end up with a | ||||||
|  |  * single, uniform, solution that satisfies both the boot path and the | ||||||
|  |  * various hot-plug event paths. | ||||||
|  |  * | ||||||
|  |  * ToDo: Remove 'pci_fixup_final_inited' | ||||||
|  |  */ | ||||||
|  | bool pci_fixup_final_inited; | ||||||
|  | 
 | ||||||
| static int __init pci_apply_final_quirks(void) | static int __init pci_apply_final_quirks(void) | ||||||
| { | { | ||||||
| 	struct pci_dev *dev = NULL; | 	struct pci_dev *dev = NULL; | ||||||
| @ -3058,6 +3074,8 @@ static int __init pci_apply_final_quirks(void) | |||||||
| 			pci_cache_line_size = pci_dfl_cache_line_size; | 			pci_cache_line_size = pci_dfl_cache_line_size; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	pci_fixup_final_inited = 1; | ||||||
|  | 
 | ||||||
| 	if (!pci_cache_line_size) { | 	if (!pci_cache_line_size) { | ||||||
| 		printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n", | 		printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n", | ||||||
| 		       cls << 2, pci_dfl_cache_line_size << 2); | 		       cls << 2, pci_dfl_cache_line_size << 2); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user