fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / i386 / pci / pcbios.c
index 50fc1f3..5f51934 100644 (file)
@@ -4,6 +4,8 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
 #include "pci.h"
 #include "pci-functions.h"
 
@@ -172,7 +174,8 @@ static int __devinit pci_bios_find_device (unsigned short vendor, unsigned short
        return (int) (ret & 0xff00) >> 8;
 }
 
-static int pci_bios_read (int seg, int bus, int devfn, int reg, int len, u32 *value)
+static int pci_bios_read(unsigned int seg, unsigned int bus,
+                        unsigned int devfn, int reg, int len, u32 *value)
 {
        unsigned long result = 0;
        unsigned long flags;
@@ -227,7 +230,8 @@ static int pci_bios_read (int seg, int bus, int devfn, int reg, int len, u32 *va
        return (int)((result & 0xff00) >> 8);
 }
 
-static int pci_bios_write (int seg, int bus, int devfn, int reg, int len, u32 value)
+static int pci_bios_write(unsigned int seg, unsigned int bus,
+                         unsigned int devfn, int reg, int len, u32 value)
 {
        unsigned long result = 0;
        unsigned long flags;
@@ -311,6 +315,10 @@ static struct pci_raw_ops * __devinit pci_find_bios(void)
        for (check = (union bios32 *) __va(0xe0000);
             check <= (union bios32 *) __va(0xffff0);
             ++check) {
+               long sig;
+               if (probe_kernel_address(&check->fields.signature, sig))
+                       continue;
+
                if (check->fields.signature != BIOS32_SIGNATURE)
                        continue;
                length = check->fields.length * 16;
@@ -328,11 +336,13 @@ static struct pci_raw_ops * __devinit pci_find_bios(void)
                }
                DBG("PCI: BIOS32 Service Directory structure at 0x%p\n", check);
                if (check->fields.entry >= 0x100000) {
-                       printk("PCI: BIOS32 entry (0x%p) in high memory, cannot use.\n", check);
+                       printk("PCI: BIOS32 entry (0x%p) in high memory, "
+                                       "cannot use.\n", check);
                        return NULL;
                } else {
                        unsigned long bios32_entry = check->fields.entry;
-                       DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);
+                       DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n",
+                                       bios32_entry);
                        bios32_indirect.address = bios32_entry + PAGE_OFFSET;
                        if (check_pcibios())
                                return &pci_bios_access;
@@ -368,8 +378,7 @@ void __devinit pcibios_sort(void)
                        list_for_each(ln, &pci_devices) {
                                d = pci_dev_g(ln);
                                if (d->bus->number == bus && d->devfn == devfn) {
-                                       list_del(&d->global_list);
-                                       list_add_tail(&d->global_list, &sorted_devices);
+                                       list_move_tail(&d->global_list, &sorted_devices);
                                        if (d == dev)
                                                found = 1;
                                        break;
@@ -385,10 +394,9 @@ void __devinit pcibios_sort(void)
                        }
                }
                if (!found) {
-                       printk(KERN_WARNING "PCI: Device %02x:%02x not found by BIOS\n",
-                               dev->bus->number, dev->devfn);
-                       list_del(&dev->global_list);
-                       list_add_tail(&dev->global_list, &sorted_devices);
+                       printk(KERN_WARNING "PCI: Device %s not found by BIOS\n",
+                               pci_name(dev));
+                       list_move_tail(&dev->global_list, &sorted_devices);
                }
        }
        list_splice(&sorted_devices, &pci_devices);
@@ -454,7 +462,7 @@ struct irq_routing_table * __devinit pcibios_get_irq_routing_table(void)
        free_page(page);
        return rt;
 }
-
+EXPORT_SYMBOL(pcibios_get_irq_routing_table);
 
 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
 {
@@ -471,15 +479,14 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
                  "S" (&pci_indirect));
        return !(ret & 0xff00);
 }
+EXPORT_SYMBOL(pcibios_set_irq_routing);
 
-static int __init pci_pcbios_init(void)
+void __init pci_pcbios_init(void)
 {
        if ((pci_probe & PCI_PROBE_BIOS) 
                && ((raw_pci_ops = pci_find_bios()))) {
                pci_probe |= PCI_BIOS_SORT;
                pci_bios_present = 1;
        }
-       return 0;
 }
 
-arch_initcall(pci_pcbios_init);