[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 1/9] dom0 PCI: export some functions and macros



Export some functions and move some macros from c file to header file.

Signed-off-by: Yu Zhao <yu.zhao@xxxxxxxxx>

diff -r cc6fc966c613 -r 6301e7e967c0 drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c   Fri Sep 26 14:07:10 2008 +0100
+++ b/drivers/pci/pci-sysfs.c   Sat Sep 27 01:23:54 2008 -0400
@@ -513,7 +513,7 @@
                .mode = S_IRUGO | S_IWUSR,
                .owner = THIS_MODULE,
        },
-       .size = 256,
+       .size = PCI_CFG_SPACE_SIZE,
        .read = pci_read_config,
        .write = pci_write_config,
 };
@@ -524,7 +524,7 @@
                .mode = S_IRUGO | S_IWUSR,
                .owner = THIS_MODULE,
        },
-       .size = 4096,
+       .size = PCI_CFG_SPACE_EXP_SIZE,
        .read = pci_read_config,
        .write = pci_write_config,
 };
@@ -534,7 +534,7 @@
        if (!sysfs_initialized)
                return -EACCES;

-       if (pdev->cfg_size < 4096)
+       if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
                sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
        else
                sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
@@ -574,7 +574,7 @@
        if (!sysfs_initialized)
                return;

-       if (pdev->cfg_size < 4096)
+       if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
                sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
        else
                sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
diff -r cc6fc966c613 -r 6301e7e967c0 drivers/pci/pci.c
--- a/drivers/pci/pci.c Fri Sep 26 14:07:10 2008 +0100
+++ b/drivers/pci/pci.c Sat Sep 27 01:23:54 2008 -0400
@@ -185,7 +185,7 @@
        int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */
        int pos = 0x100;

-       if (dev->cfg_size <= 256)
+       if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
                return 0;

        if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
diff -r cc6fc966c613 -r 6301e7e967c0 drivers/pci/pci.h
--- a/drivers/pci/pci.h Fri Sep 26 14:07:10 2008 +0100
+++ b/drivers/pci/pci.h Sat Sep 27 01:23:54 2008 -0400
@@ -1,3 +1,9 @@
+#ifndef DRIVERS_PCI_H
+#define DRIVERS_PCI_H
+
+#define PCI_CFG_SPACE_SIZE     256
+#define PCI_CFG_SPACE_EXP_SIZE 4096
+
 /* Functions internal to the PCI core code */

 extern int pci_uevent(struct device *dev, char **envp, int num_envp,
@@ -99,3 +105,17 @@
        return NULL;
 }

+enum pci_bar_type {
+       pci_bar_unknown,        /* Standard PCI BAR probe */
+       pci_bar_io,             /* An io port BAR */
+       pci_bar_mem32,          /* A 32-bit memory BAR */
+       pci_bar_mem64,          /* A 64-bit memory BAR */
+       pci_bar_rom,            /* A ROM BAR */
+};
+
+extern int pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
+                               struct resource *res, unsigned int reg);
+extern struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
+                               struct pci_dev *bridge, int busnr);
+
+#endif /* DRIVERS_PCI_H */
diff -r cc6fc966c613 -r 6301e7e967c0 drivers/pci/probe.c
--- a/drivers/pci/probe.c       Fri Sep 26 14:07:10 2008 +0100
+++ b/drivers/pci/probe.c       Sat Sep 27 01:23:54 2008 -0400
@@ -13,8 +13,6 @@

 #define CARDBUS_LATENCY_TIMER  176     /* secondary latency timer */
 #define CARDBUS_RESERVE_BUSNR  3
-#define PCI_CFG_SPACE_SIZE     256
-#define PCI_CFG_SPACE_EXP_SIZE 4096

 /* Ugh.  Need to stop exporting this to modules. */
 LIST_HEAD(pci_root_buses);
@@ -123,12 +121,9 @@
        return IORESOURCE_MEM;
 }

-/*
- * Find the extent of a PCI decode..
- */
-static u32 pci_size(u32 base, u32 maxbase, u32 mask)
+static u64 pci_size(u32 base, u32 maxbase, u32 mask)
 {
-       u32 size = mask & maxbase;      /* Find the significant bits */
+       u64 size = mask & maxbase;      /* Find the significant bits */
        if (!size)
                return 0;

@@ -144,91 +139,140 @@
        return size;
 }

+static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
+{
+       if ((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+               res->flags = bar & ~PCI_BASE_ADDRESS_IO_MASK;
+               return pci_bar_io;
+       }
+
+       res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK;
+
+       if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64)
+               return pci_bar_mem64;
+       return pci_bar_mem32;
+}
+
+/**
+ * pci_read_base - read a PCI BAR
+ * @dev: the PCI device
+ * @type: type of the BAR
+ * @res: resource buffer to be filled in
+ * @pos: BAR position in the config space
+ *
+ * Returns 1 if the BAR is 64-bit, or 0 if 32-bit.
+ */
+int pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
+                       struct resource *res, unsigned int pos)
+{
+       u32 l, sz, mask;
+
+       mask = (type == pci_bar_rom) ? ~PCI_ROM_ADDRESS_ENABLE : ~0;
+
+       res->name = pci_name(dev);
+
+       pci_read_config_dword(dev, pos, &l);
+       pci_write_config_dword(dev, pos, mask);
+       pci_read_config_dword(dev, pos, &sz);
+       pci_write_config_dword(dev, pos, l);
+
+       /*
+        * All bits set in sz means the device isn't working properly.
+        * If the BAR isn't implemented, all bits must be 0.  If it's a
+        * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit
+        * 1 must be clear.
+        */
+       if (!sz || sz == 0xffffffff)
+               goto fail;
+
+       /*
+        * I don't know how l can have all bits set.  Copied from old code.
+        * Maybe it fixes a bug on some ancient platform.
+        */
+       if (l == 0xffffffff)
+               l = 0;
+
+       if (type == pci_bar_rom) {
+               res->flags |= (l & IORESOURCE_ROM_ENABLE);
+               l &= PCI_ROM_ADDRESS_MASK;
+               mask = (u32)PCI_ROM_ADDRESS_MASK;
+       } else {
+               type = decode_bar(res, l);
+               res->flags |= pci_calc_resource_flags(l);
+               if (type == pci_bar_io) {
+                       l &= PCI_BASE_ADDRESS_IO_MASK;
+                       mask = PCI_BASE_ADDRESS_IO_MASK & 0xffff;
+               } else {
+                       l &= PCI_BASE_ADDRESS_MEM_MASK;
+                       mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
+               }
+       }
+
+       if (type == pci_bar_mem64) {
+               u64 l64 = l;
+               u64 sz64 = sz;
+               u64 mask64 = mask | (u64)~0 << 32;
+
+               pci_read_config_dword(dev, pos + 4, &l);
+               pci_write_config_dword(dev, pos + 4, ~0);
+               pci_read_config_dword(dev, pos + 4, &sz);
+               pci_write_config_dword(dev, pos + 4, l);
+
+               l64 |= ((u64)l << 32);
+               sz64 |= ((u64)sz << 32);
+
+               sz64 = pci_size(l64, sz64, mask64);
+
+               if (!sz64)
+                       goto fail;
+
+               if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) {
+                       dev_err(&dev->dev, "can't handle 64-bit BAR\n");
+                       goto fail;
+               } else if ((sizeof(resource_size_t) < 8) && l) {
+                       /* Address above 32-bit boundary; disable the BAR */
+                       pci_write_config_dword(dev, pos, 0);
+                       pci_write_config_dword(dev, pos + 4, 0);
+                       res->start = 0;
+                       res->end = sz64;
+               } else {
+                       res->start = l64;
+                       res->end = l64 + sz64;
+               }
+       } else {
+               sz = pci_size(l, sz, mask);
+
+               if (!sz)
+                       goto fail;
+
+               res->start = l;
+               res->end = l + sz;
+       }
+
+ out:
+       return (type == pci_bar_mem64) ? 1 : 0;
+ fail:
+       res->flags = 0;
+       goto out;
+}
+EXPORT_SYMBOL_GPL(pci_read_base);
+
 static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
 {
-       unsigned int pos, reg, next;
-       u32 l, sz;
-       struct resource *res;
+       unsigned int pos, reg;

-       for(pos=0; pos<howmany; pos = next) {
-               next = pos+1;
-               res = &dev->resource[pos];
-               res->name = pci_name(dev);
+       for (pos = 0; pos < howmany; pos++) {
+               struct resource *res = &dev->resource[pos];
                reg = PCI_BASE_ADDRESS_0 + (pos << 2);
-               pci_read_config_dword(dev, reg, &l);
-               pci_write_config_dword(dev, reg, ~0);
-               pci_read_config_dword(dev, reg, &sz);
-               pci_write_config_dword(dev, reg, l);
-               if (!sz || sz == 0xffffffff)
-                       continue;
-               if (l == 0xffffffff)
-                       l = 0;
-               if ((l & PCI_BASE_ADDRESS_SPACE) == 
PCI_BASE_ADDRESS_SPACE_MEMORY) {
-                       sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK);
-                       if (!sz)
-                               continue;
-                       res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
-                       res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK;
-               } else {
-                       sz = pci_size(l, sz, PCI_BASE_ADDRESS_IO_MASK & 0xffff);
-                       if (!sz)
-                               continue;
-                       res->start = l & PCI_BASE_ADDRESS_IO_MASK;
-                       res->flags |= l & ~PCI_BASE_ADDRESS_IO_MASK;
-               }
-               res->end = res->start + (unsigned long) sz;
-               res->flags |= pci_calc_resource_flags(l);
-               if ((l & (PCI_BASE_ADDRESS_SPACE | 
PCI_BASE_ADDRESS_MEM_TYPE_MASK))
-                   == (PCI_BASE_ADDRESS_SPACE_MEMORY | 
PCI_BASE_ADDRESS_MEM_TYPE_64)) {
-                       u32 szhi, lhi;
-                       pci_read_config_dword(dev, reg+4, &lhi);
-                       pci_write_config_dword(dev, reg+4, ~0);
-                       pci_read_config_dword(dev, reg+4, &szhi);
-                       pci_write_config_dword(dev, reg+4, lhi);
-                       szhi = pci_size(lhi, szhi, 0xffffffff);
-                       next++;
-#if BITS_PER_LONG == 64
-                       res->start |= ((unsigned long) lhi) << 32;
-                       res->end = res->start + sz;
-                       if (szhi) {
-                               /* This BAR needs > 4GB?  Wow. */
-                               res->end |= (unsigned long)szhi<<32;
-                       }
-#else
-                       if (szhi) {
-                               printk(KERN_ERR "PCI: Unable to handle 64-bit 
BAR for device %s\n", pci_name(dev));
-                               res->start = 0;
-                               res->flags = 0;
-                       } else if (lhi) {
-                               /* 64-bit wide address, treat as disabled */
-                               pci_write_config_dword(dev, reg, l & 
~(u32)PCI_BASE_ADDRESS_MEM_MASK);
-                               pci_write_config_dword(dev, reg+4, 0);
-                               res->start = 0;
-                               res->end = sz;
-                       }
-#endif
-               }
+               pos += pci_read_base(dev, pci_bar_unknown, res, reg);
        }
+
        if (rom) {
+               struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
                dev->rom_base_reg = rom;
-               res = &dev->resource[PCI_ROM_RESOURCE];
-               res->name = pci_name(dev);
-               pci_read_config_dword(dev, rom, &l);
-               pci_write_config_dword(dev, rom, ~PCI_ROM_ADDRESS_ENABLE);
-               pci_read_config_dword(dev, rom, &sz);
-               pci_write_config_dword(dev, rom, l);
-               if (l == 0xffffffff)
-                       l = 0;
-               if (sz && sz != 0xffffffff) {
-                       sz = pci_size(l, sz, (u32)PCI_ROM_ADDRESS_MASK);
-                       if (sz) {
-                               res->flags = (l & IORESOURCE_ROM_ENABLE) |
-                                 IORESOURCE_MEM | IORESOURCE_PREFETCH |
-                                 IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
-                               res->start = l & PCI_ROM_ADDRESS_MASK;
-                               res->end = res->start + (unsigned long) sz;
-                       }
-               }
+               res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH |
+                               IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+               pci_read_base(dev, pci_bar_rom, res, rom);
        }
 }

@@ -249,9 +293,6 @@
                for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
                        child->resource[i] = child->parent->resource[i - 3];
        }
-
-       for(i=0; i<3; i++)
-               child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];

        res = child->resource[0];
        pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
@@ -334,7 +375,7 @@
        return b;
 }

-static struct pci_bus * __devinit
+struct pci_bus * __devinit
 pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr)
 {
        struct pci_bus *child;
@@ -347,12 +388,10 @@
        if (!child)
                return NULL;

-       child->self = bridge;
        child->parent = parent;
        child->ops = parent->ops;
        child->sysdata = parent->sysdata;
        child->bus_flags = parent->bus_flags;
-       child->bridge = get_device(&bridge->dev);

        child->class_dev.class = &pcibus_class;
        sprintf(child->class_dev.class_id, "%04x:%02x", pci_domain_nr(child), 
busnr);
@@ -367,6 +406,11 @@
        child->primary = parent->secondary;
        child->subordinate = 0xff;

+       if (!bridge)
+               return child;
+
+       child->self = bridge;
+       child->bridge = get_device(&bridge->dev);
        /* Set up default resource pointers and names.. */
        for (i = 0; i < 4; i++) {
                child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i];

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.