]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/pci/pci_rom.c
Merge branch 'patman' of git://git.denx.de/u-boot-x86
[karo-tx-uboot.git] / drivers / pci / pci_rom.c
index 7d25cc9f2f37d8b1a06b9cd67f2a320e013b958e..5729a152e5bb00ed759dfe90bd7750f10b7e20b7 100644 (file)
@@ -66,6 +66,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
        struct pci_rom_header *rom_header;
        struct pci_rom_data *rom_data;
        u16 vendor, device;
+       u16 rom_vendor, rom_device;
        u32 vendev;
        u32 mapped_vendev;
        u32 rom_address;
@@ -80,7 +81,12 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
 #ifdef CONFIG_X86_OPTION_ROM_ADDR
        rom_address = CONFIG_X86_OPTION_ROM_ADDR;
 #else
-       pci_write_config_dword(dev, PCI_ROM_ADDRESS, (u32)PCI_ROM_ADDRESS_MASK);
+
+       if (pciauto_setup_rom(pci_bus_to_hose(PCI_BUS(dev)), dev)) {
+               debug("Cannot find option ROM\n");
+               return -ENOENT;
+       }
+
        pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_address);
        if (rom_address == 0x00000000 || rom_address == 0xffffffff) {
                debug("%s: rom_address=%x\n", __func__, rom_address);
@@ -92,29 +98,31 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
                               rom_address | PCI_ROM_ADDRESS_ENABLE);
 #endif
        debug("Option ROM address %x\n", rom_address);
-       rom_header = (struct pci_rom_header *)rom_address;
+       rom_header = (struct pci_rom_header *)(unsigned long)rom_address;
 
        debug("PCI expansion ROM, signature %#04x, INIT size %#04x, data ptr %#04x\n",
-             le32_to_cpu(rom_header->signature),
-             rom_header->size * 512, le32_to_cpu(rom_header->data));
+             le16_to_cpu(rom_header->signature),
+             rom_header->size * 512, le16_to_cpu(rom_header->data));
 
-       if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
+       if (le16_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
                printf("Incorrect expansion ROM header signature %04x\n",
-                      le32_to_cpu(rom_header->signature));
+                      le16_to_cpu(rom_header->signature));
                return -EINVAL;
        }
 
-       rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data));
+       rom_data = (((void *)rom_header) + le16_to_cpu(rom_header->data));
+       rom_vendor = le16_to_cpu(rom_data->vendor);
+       rom_device = le16_to_cpu(rom_data->device);
 
        debug("PCI ROM image, vendor ID %04x, device ID %04x,\n",
-             rom_data->vendor, rom_data->device);
+             rom_vendor, rom_device);
 
        /* If the device id is mapped, a mismatch is expected */
-       if ((vendor != rom_data->vendor || device != rom_data->device) &&
+       if ((vendor != rom_vendor || device != rom_device) &&
            (vendev == mapped_vendev)) {
                printf("ID mismatch: vendor ID %04x, device ID %04x\n",
-                      rom_data->vendor, rom_data->device);
-               return -EPERM;
+                      rom_vendor, rom_device);
+               /* Continue anyway */
        }
 
        debug("PCI ROM image, Class Code %04x%02x, Code Type %02x\n",
@@ -144,17 +152,23 @@ int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header,
                                                            image_size);
 
                rom_data = (struct pci_rom_data *)((void *)rom_header +
-                               le32_to_cpu(rom_header->data));
+                               le16_to_cpu(rom_header->data));
 
-               image_size = le32_to_cpu(rom_data->ilen) * 512;
-       } while ((rom_data->type != 0) && (rom_data->indicator != 0));
+               image_size = le16_to_cpu(rom_data->ilen) * 512;
+       } while ((rom_data->type != 0) && (rom_data->indicator == 0));
 
        if (rom_data->type != 0)
                return -EACCES;
 
        rom_size = rom_header->size * 512;
 
+#ifdef PCI_VGA_RAM_IMAGE_START
        target = (void *)PCI_VGA_RAM_IMAGE_START;
+#else
+       target = (void *)malloc(rom_size);
+       if (!target)
+               return -ENOMEM;
+#endif
        if (target != rom_header) {
                ulong start = get_timer(0);