aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/rom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/rom.c')
-rw-r--r--drivers/pci/rom.c55
1 files changed, 35 insertions, 20 deletions
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index ab886b7ee327..b41ac7756a4b 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -100,6 +100,27 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
100 return min((size_t)(image - rom), size); 100 return min((size_t)(image - rom), size);
101} 101}
102 102
103static loff_t pci_find_rom(struct pci_dev *pdev, size_t *size)
104{
105 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
106 loff_t start;
107
108 /* assign the ROM an address if it doesn't have one */
109 if (res->parent == NULL && pci_assign_resource(pdev, PCI_ROM_RESOURCE))
110 return 0;
111 start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
112 *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
113
114 if (*size == 0)
115 return 0;
116
117 /* Enable ROM space decodes */
118 if (pci_enable_rom(pdev))
119 return 0;
120
121 return start;
122}
123
103/** 124/**
104 * pci_map_rom - map a PCI ROM to kernel space 125 * pci_map_rom - map a PCI ROM to kernel space
105 * @pdev: pointer to pci device struct 126 * @pdev: pointer to pci device struct
@@ -114,21 +135,15 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
114void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) 135void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
115{ 136{
116 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; 137 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
117 loff_t start; 138 loff_t start = 0;
118 void __iomem *rom; 139 void __iomem *rom;
119 140
120 /* 141 /*
121 * Some devices may provide ROMs via a source other than the BAR
122 */
123 if (pdev->rom && pdev->romlen) {
124 *size = pdev->romlen;
125 return phys_to_virt(pdev->rom);
126 /*
127 * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy 142 * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
128 * memory map if the VGA enable bit of the Bridge Control register is 143 * memory map if the VGA enable bit of the Bridge Control register is
129 * set for embedded VGA. 144 * set for embedded VGA.
130 */ 145 */
131 } else if (res->flags & IORESOURCE_ROM_SHADOW) { 146 if (res->flags & IORESOURCE_ROM_SHADOW) {
132 /* primary video rom always starts here */ 147 /* primary video rom always starts here */
133 start = (loff_t)0xC0000; 148 start = (loff_t)0xC0000;
134 *size = 0x20000; /* cover C000:0 through E000:0 */ 149 *size = 0x20000; /* cover C000:0 through E000:0 */
@@ -139,21 +154,21 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
139 return (void __iomem *)(unsigned long) 154 return (void __iomem *)(unsigned long)
140 pci_resource_start(pdev, PCI_ROM_RESOURCE); 155 pci_resource_start(pdev, PCI_ROM_RESOURCE);
141 } else { 156 } else {
142 /* assign the ROM an address if it doesn't have one */ 157 start = pci_find_rom(pdev, size);
143 if (res->parent == NULL &&
144 pci_assign_resource(pdev,PCI_ROM_RESOURCE))
145 return NULL;
146 start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
147 *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
148 if (*size == 0)
149 return NULL;
150
151 /* Enable ROM space decodes */
152 if (pci_enable_rom(pdev))
153 return NULL;
154 } 158 }
155 } 159 }
156 160
161 /*
162 * Some devices may provide ROMs via a source other than the BAR
163 */
164 if (!start && pdev->rom && pdev->romlen) {
165 *size = pdev->romlen;
166 return phys_to_virt(pdev->rom);
167 }
168
169 if (!start)
170 return NULL;
171
157 rom = ioremap(start, *size); 172 rom = ioremap(start, *size);
158 if (!rom) { 173 if (!rom) {
159 /* restore enable if ioremap fails */ 174 /* restore enable if ioremap fails */