.flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
 };
 
+/* does this oprom support the given pci device, or any of the devices
+ * that the driver supports?
+ */
+static bool match_id(struct pci_dev *pdev, unsigned short vendor, unsigned short device)
+{
+       struct pci_driver *drv = pdev->driver;
+       const struct pci_device_id *id;
+
+       if (pdev->vendor == vendor && pdev->device == device)
+               return true;
+
+       for (id = drv ? drv->id_table : NULL; id && id->vendor; id++)
+               if (id->vendor == vendor && id->device == device)
+                       break;
+
+       return id && id->vendor;
+}
+
+static bool probe_list(struct pci_dev *pdev, unsigned short vendor,
+                      const unsigned char *rom_list)
+{
+       unsigned short device;
+
+       do {
+               if (probe_kernel_address(rom_list, device) != 0)
+                       device = 0;
+
+               if (device && match_id(pdev, vendor, device))
+                       break;
+
+               rom_list += 2;
+       } while (device);
+
+       return !!device;
+}
+
+static struct resource *find_oprom(struct pci_dev *pdev)
+{
+       struct resource *oprom = NULL;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(adapter_rom_resources); i++) {
+               struct resource *res = &adapter_rom_resources[i];
+               unsigned short offset, vendor, device, list, rev;
+               const unsigned char *rom;
+
+               if (res->end == 0)
+                       break;
+
+               rom = isa_bus_to_virt(res->start);
+               if (probe_kernel_address(rom + 0x18, offset) != 0)
+                       continue;
+
+               if (probe_kernel_address(rom + offset + 0x4, vendor) != 0)
+                       continue;
+
+               if (probe_kernel_address(rom + offset + 0x6, device) != 0)
+                       continue;
+
+               if (match_id(pdev, vendor, device)) {
+                       oprom = res;
+                       break;
+               }
+
+               if (probe_kernel_address(rom + offset + 0x8, list) == 0 &&
+                   probe_kernel_address(rom + offset + 0xc, rev) == 0 &&
+                   rev >= 3 && list &&
+                   probe_list(pdev, vendor, rom + offset + list)) {
+                       oprom = res;
+                       break;
+               }
+       }
+
+       return oprom;
+}
+
+void *pci_map_biosrom(struct pci_dev *pdev)
+{
+       struct resource *oprom = find_oprom(pdev);
+
+       if (!oprom)
+               return NULL;
+
+       return ioremap(oprom->start, resource_size(oprom));
+}
+EXPORT_SYMBOL(pci_map_biosrom);
+
+void pci_unmap_biosrom(void __iomem *image)
+{
+       iounmap(image);
+}
+EXPORT_SYMBOL(pci_unmap_biosrom);
+
+size_t pci_biosrom_size(struct pci_dev *pdev)
+{
+       struct resource *oprom = find_oprom(pdev);
+
+       return oprom ? resource_size(oprom) : 0;
+}
+EXPORT_SYMBOL(pci_biosrom_size);
+
 #define ROMSIGNATURE 0xaa55
 
 static int __init romsignature(const unsigned char *rom)