Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rom.c
Go to the documentation of this file.
1 /*
2  * drivers/pci/rom.c
3  *
4  * (C) Copyright 2004 Jon Smirl <[email protected]>
5  * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <[email protected]>
6  *
7  * PCI ROM access routines
8  */
9 #include <linux/kernel.h>
10 #include <linux/export.h>
11 #include <linux/pci.h>
12 #include <linux/slab.h>
13 
14 #include "pci.h"
15 
25 int pci_enable_rom(struct pci_dev *pdev)
26 {
27  struct resource *res = pdev->resource + PCI_ROM_RESOURCE;
28  struct pci_bus_region region;
29  u32 rom_addr;
30 
31  if (!res->flags)
32  return -1;
33 
34  pcibios_resource_to_bus(pdev, &region, res);
35  pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
36  rom_addr &= ~PCI_ROM_ADDRESS_MASK;
37  rom_addr |= region.start | PCI_ROM_ADDRESS_ENABLE;
38  pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
39  return 0;
40 }
41 
49 void pci_disable_rom(struct pci_dev *pdev)
50 {
51  u32 rom_addr;
52  pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
53  rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
54  pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
55 }
56 
68 size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
69 {
70  void __iomem *image;
71  int last_image;
72 
73  image = rom;
74  do {
75  void __iomem *pds;
76  /* Standard PCI ROMs start out with these bytes 55 AA */
77  if (readb(image) != 0x55) {
78  dev_err(&pdev->dev, "Invalid ROM contents\n");
79  break;
80  }
81  if (readb(image + 1) != 0xAA)
82  break;
83  /* get the PCI data structure and check its signature */
84  pds = image + readw(image + 24);
85  if (readb(pds) != 'P')
86  break;
87  if (readb(pds + 1) != 'C')
88  break;
89  if (readb(pds + 2) != 'I')
90  break;
91  if (readb(pds + 3) != 'R')
92  break;
93  last_image = readb(pds + 21) & 0x80;
94  /* this length is reliable */
95  image += readw(pds + 16) * 512;
96  } while (!last_image);
97 
98  /* never return a size larger than the PCI resource window */
99  /* there are known ROMs that get the size wrong */
100  return min((size_t)(image - rom), size);
101 }
102 
114 void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
115 {
116  struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
117  loff_t start;
118  void __iomem *rom;
119 
120  /*
121  * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
122  * memory map if the VGA enable bit of the Bridge Control register is
123  * set for embedded VGA.
124  */
125  if (res->flags & IORESOURCE_ROM_SHADOW) {
126  /* primary video rom always starts here */
127  start = (loff_t)0xC0000;
128  *size = 0x20000; /* cover C000:0 through E000:0 */
129  } else {
130  if (res->flags &
132  *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
133  return (void __iomem *)(unsigned long)
135  } else {
136  /* assign the ROM an address if it doesn't have one */
137  if (res->parent == NULL &&
139  return NULL;
140  start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
141  *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
142  if (*size == 0)
143  return NULL;
144 
145  /* Enable ROM space decodes */
146  if (pci_enable_rom(pdev))
147  return NULL;
148  }
149  }
150 
151  rom = ioremap(start, *size);
152  if (!rom) {
153  /* restore enable if ioremap fails */
154  if (!(res->flags & (IORESOURCE_ROM_ENABLE |
157  pci_disable_rom(pdev);
158  return NULL;
159  }
160 
161  /*
162  * Try to find the true size of the ROM since sometimes the PCI window
163  * size is much larger than the actual size of the ROM.
164  * True size is important if the ROM is going to be copied.
165  */
166  *size = pci_get_rom_size(pdev, rom, *size);
167  return rom;
168 }
169 
177 void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
178 {
179  struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
180 
182  return;
183 
184  iounmap(rom);
185 
186  /* Disable again before continuing, leave enabled if pci=rom */
188  pci_disable_rom(pdev);
189 }
190 
197 void pci_cleanup_rom(struct pci_dev *pdev)
198 {
199  struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
200  if (res->flags & IORESOURCE_ROM_COPY) {
201  kfree((void*)(unsigned long)res->start);
202  res->flags &= ~IORESOURCE_ROM_COPY;
203  res->start = 0;
204  res->end = 0;
205  }
206 }
207