mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	[PATCH] Fix PCI ROM mapping
This fixes a problem with pci_map_rom() which doesn't properly update the ROM BAR value with the address thas allocated for it by the PCI code. This problem, among other, breaks boot on Mac laptops. It'ss a new version based on Linus latest one with better error checking. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
		
							parent
							
								
									319e76a1ae
								
							
						
					
					
						commit
						8085ce084c
					
				
					 1 changed files with 17 additions and 7 deletions
				
			
		| 
						 | 
					@ -21,13 +21,21 @@
 | 
				
			||||||
 * between the ROM and other resources, so enabling it may disable access
 | 
					 * between the ROM and other resources, so enabling it may disable access
 | 
				
			||||||
 * to MMIO registers or other card memory.
 | 
					 * to MMIO registers or other card memory.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void pci_enable_rom(struct pci_dev *pdev)
 | 
					static int pci_enable_rom(struct pci_dev *pdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct resource *res = pdev->resource + PCI_ROM_RESOURCE;
 | 
				
			||||||
 | 
						struct pci_bus_region region;
 | 
				
			||||||
	u32 rom_addr;
 | 
						u32 rom_addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!res->flags)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pcibios_resource_to_bus(pdev, ®ion, res);
 | 
				
			||||||
	pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
 | 
						pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
 | 
				
			||||||
	rom_addr |= PCI_ROM_ADDRESS_ENABLE;
 | 
						rom_addr &= ~PCI_ROM_ADDRESS_MASK;
 | 
				
			||||||
 | 
						rom_addr |= region.start | PCI_ROM_ADDRESS_ENABLE;
 | 
				
			||||||
	pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
 | 
						pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -71,19 +79,21 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (res->flags & IORESOURCE_ROM_COPY) {
 | 
							if (res->flags & IORESOURCE_ROM_COPY) {
 | 
				
			||||||
			*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
 | 
								*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
 | 
				
			||||||
			return (void __iomem *)pci_resource_start(pdev, PCI_ROM_RESOURCE);
 | 
								return (void __iomem *)pci_resource_start(pdev,
 | 
				
			||||||
 | 
												     PCI_ROM_RESOURCE);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			/* assign the ROM an address if it doesn't have one */
 | 
								/* assign the ROM an address if it doesn't have one */
 | 
				
			||||||
			if (res->parent == NULL)
 | 
								if (res->parent == NULL &&
 | 
				
			||||||
				pci_assign_resource(pdev, PCI_ROM_RESOURCE);
 | 
								    pci_assign_resource(pdev,PCI_ROM_RESOURCE))
 | 
				
			||||||
 | 
									return NULL;
 | 
				
			||||||
			start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
 | 
								start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
 | 
				
			||||||
			*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
 | 
								*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
 | 
				
			||||||
			if (*size == 0)
 | 
								if (*size == 0)
 | 
				
			||||||
				return NULL;
 | 
									return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Enable ROM space decodes */
 | 
								/* Enable ROM space decodes */
 | 
				
			||||||
			pci_enable_rom(pdev);
 | 
								if (pci_enable_rom(pdev))
 | 
				
			||||||
 | 
									return NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue