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

[Xen-devel] [PATCH 2/9] dom0 PCI: add new general functions



Centralize capability related functions into several new functions and put PCI 
resource definitions into an enum.

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

diff -r 6301e7e967c0 -r 5020cef2bc39 drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c   Sat Sep 27 01:23:54 2008 -0400
+++ b/drivers/pci/pci-sysfs.c   Sat Sep 27 01:25:05 2008 -0400
@@ -85,11 +85,11 @@
        struct pci_dev * pci_dev = to_pci_dev(dev);
        char * str = buf;
        int i;
-       int max = 7;
+       int max;
        resource_size_t start, end;

-       if (pci_dev->subordinate)
-               max = DEVICE_COUNT_RESOURCE;
+       max = pci_dev->subordinate ? DEVICE_COUNT_RESOURCE :
+                               PCI_BRIDGE_RESOURCES;

        for (i = 0; i < max; i++) {
                struct resource *res =  &pci_dev->resource[i];
diff -r 6301e7e967c0 -r 5020cef2bc39 drivers/pci/pci.c
--- a/drivers/pci/pci.c Sat Sep 27 01:23:54 2008 -0400
+++ b/drivers/pci/pci.c Sat Sep 27 01:25:05 2008 -0400
@@ -256,25 +256,10 @@
 void
 pci_restore_bars(struct pci_dev *dev)
 {
-       int i, numres;
+       int i;

-       switch (dev->hdr_type) {
-       case PCI_HEADER_TYPE_NORMAL:
-               numres = 6;
-               break;
-       case PCI_HEADER_TYPE_BRIDGE:
-               numres = 2;
-               break;
-       case PCI_HEADER_TYPE_CARDBUS:
-               numres = 1;
-               break;
-       default:
-               /* Should never get here, but just in case... */
-               return;
-       }
-
-       for (i = 0; i < numres; i ++)
-               pci_update_resource(dev, &dev->resource[i], i);
+       for (i = 0; i < PCI_BRIDGE_RESOURCES; i++)
+               pci_update_resource(dev, i);
 }

 int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t);
@@ -927,6 +912,48 @@
 }
 #endif

+/**
+ * pci_resource_alignment - get a PCI BAR resource alignment
+ * @dev: the PCI device
+ * @resno: the resource number
+ *
+ * Returns alignment size on success, or 0 on error.
+ */
+int pci_resource_alignment(struct pci_dev *dev, int resno)
+{
+       struct resource *res = dev->resource + resno;
+
+       if (resno <= PCI_ROM_RESOURCE)
+               return res->end - res->start + 1;
+       else if (resno <= PCI_BRIDGE_RES_END)
+               return res->start;
+
+       dev_err(&dev->dev, "alignment: invalid resource #%d\n", resno);
+       return 0;
+}
+
+/**
+ * pci_resource_bar - get position of the BAR associated with a resource
+ * @dev: the PCI device
+ * @resno: the resource number
+ * @type: the BAR type to be filled in
+ *
+ * Returns BAR position in config space, or 0 if the BAR is invalid.
+ */
+int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
+{
+       if (resno < PCI_ROM_RESOURCE) {
+               *type = pci_bar_unknown;
+               return PCI_BASE_ADDRESS_0 + 4 * resno;
+       } else if (resno == PCI_ROM_RESOURCE) {
+               *type = pci_bar_rom;
+               return dev->rom_base_reg;
+       }
+
+       dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno);
+       return 0;
+}
+
 static int __devinit pci_init(void)
 {
        struct pci_dev *dev = NULL;
diff -r 6301e7e967c0 -r 5020cef2bc39 drivers/pci/pci.h
--- a/drivers/pci/pci.h Sat Sep 27 01:23:54 2008 -0400
+++ b/drivers/pci/pci.h Sat Sep 27 01:25:05 2008 -0400
@@ -117,5 +117,8 @@
                                struct resource *res, unsigned int reg);
 extern struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
                                struct pci_dev *bridge, int busnr);
+extern int pci_resource_alignment(struct pci_dev *dev, int resno);
+extern int pci_resource_bar(struct pci_dev *dev, int resno,
+                           enum pci_bar_type *type);

 #endif /* DRIVERS_PCI_H */
diff -r 6301e7e967c0 -r 5020cef2bc39 drivers/pci/probe.c
--- a/drivers/pci/probe.c       Sat Sep 27 01:23:54 2008 -0400
+++ b/drivers/pci/probe.c       Sat Sep 27 01:25:05 2008 -0400
@@ -412,7 +412,7 @@
        child->self = bridge;
        child->bridge = get_device(&bridge->dev);
        /* Set up default resource pointers and names.. */
-       for (i = 0; i < 4; i++) {
+       for (i = 0; i < PCI_BRIDGE_RES_NUM; i++) {
                child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i];
                child->resource[i]->name = child->name;
        }
diff -r 6301e7e967c0 -r 5020cef2bc39 drivers/pci/proc.c
--- a/drivers/pci/proc.c        Sat Sep 27 01:23:54 2008 -0400
+++ b/drivers/pci/proc.c        Sat Sep 27 01:25:05 2008 -0400
@@ -348,15 +348,16 @@
                        dev->vendor,
                        dev->device,
                        dev->irq);
-       /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve 
compatibility */
-       for (i=0; i<7; i++) {
+
+       /* only print standard and ROM resources to preserve compatibility */
+       for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
                resource_size_t start, end;
                pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
                seq_printf(m, "\t%16llx",
                        (unsigned long long)(start |
                        (dev->resource[i].flags & PCI_REGION_FLAG_MASK)));
        }
-       for (i=0; i<7; i++) {
+       for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
                resource_size_t start, end;
                pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
                seq_printf(m, "\t%16llx",
diff -r 6301e7e967c0 -r 5020cef2bc39 drivers/pci/setup-bus.c
--- a/drivers/pci/setup-bus.c   Sat Sep 27 01:23:54 2008 -0400
+++ b/drivers/pci/setup-bus.c   Sat Sep 27 01:25:05 2008 -0400
@@ -25,6 +25,7 @@
 #include <linux/ioport.h>
 #include <linux/cache.h>
 #include <linux/slab.h>
+#include "pci.h"


 #define DEBUG_CONFIG 1
@@ -352,8 +353,7 @@
                        if (r->parent || (r->flags & mask) != type)
                                continue;
                        r_size = r->end - r->start + 1;
-                       /* For bridges size != alignment */
-                       align = (i < PCI_BRIDGE_RESOURCES) ? r_size : r->start;
+                       align = pci_resource_alignment(dev, i);
                        order = __ffs(align) - 20;
                        if (order > 11) {
                                printk(KERN_WARNING "PCI: region %s/%d "
diff -r 6301e7e967c0 -r 5020cef2bc39 drivers/pci/setup-res.c
--- a/drivers/pci/setup-res.c   Sat Sep 27 01:23:54 2008 -0400
+++ b/drivers/pci/setup-res.c   Sat Sep 27 01:25:05 2008 -0400
@@ -27,11 +27,13 @@


 void
-pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
+pci_update_resource(struct pci_dev *dev, int resno)
 {
        struct pci_bus_region region;
        u32 new, check, mask;
        int reg;
+       enum pci_bar_type type;
+       struct resource *res = dev->resource + resno;

        /* Ignore resources for unimplemented BARs and unused resource slots
           for 64 bit BARs. */
@@ -51,17 +53,13 @@
        else
                mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;

-       if (resno < 6) {
-               reg = PCI_BASE_ADDRESS_0 + 4 * resno;
-       } else if (resno == PCI_ROM_RESOURCE) {
+       reg = pci_resource_bar(dev, resno, &type);
+       if (!reg)
+               return;
+       if (type == pci_bar_rom) {
                if (!(res->flags & IORESOURCE_ROM_ENABLE))
                        return;
                new |= PCI_ROM_ADDRESS_ENABLE;
-               reg = dev->rom_base_reg;
-       } else {
-               /* Hmm, non-standard resource. */
-
-               return;         /* kill uninitialised var warning */
        }

        pci_write_config_dword(dev, reg, new);
@@ -126,10 +124,7 @@

        size = res->end - res->start + 1;
        min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
-       /* The bridge resources are special, as their
-          size != alignment. Sizing routines return
-          required alignment in the "start" field. */
-       align = (resno < PCI_BRIDGE_RESOURCES) ? size : res->start;
+       align = pci_resource_alignment(dev, resno);

        /* First, try exact prefetching match.. */
        ret = pci_bus_alloc_resource(bus, res, size, align, min,
@@ -154,7 +149,7 @@
                        resno, (unsigned long long)size,
                        (unsigned long long)res->start, pci_name(dev));
        } else if (resno < PCI_BRIDGE_RESOURCES) {
-               pci_update_resource(dev, res, resno);
+               pci_update_resource(dev, resno);
        }

        return ret;
@@ -192,7 +187,7 @@
                        resno, (unsigned long long)(res->end - res->start + 1),
                        (unsigned long long)res->start, pci_name(dev));
        } else if (resno < PCI_BRIDGE_RESOURCES) {
-               pci_update_resource(dev, res, resno);
+               pci_update_resource(dev, resno);
        }

        return ret;
@@ -223,7 +218,7 @@
                                (unsigned long long)r->end, pci_name(dev));
                        continue;
                }
-               r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start;
+               r_align = pci_resource_alignment(dev, i);
                for (list = head; ; list = list->next) {
                        resource_size_t align = 0;
                        struct resource_list *ln = list->next;
@@ -231,9 +226,7 @@

                        if (ln) {
                                idx = ln->res - &ln->dev->resource[0];
-                               align = (idx < PCI_BRIDGE_RESOURCES) ?
-                                       ln->res->end - ln->res->start + 1 :
-                                       ln->res->start;
+                               align = pci_resource_alignment(ln->dev, idx);
                        }
                        if (r_align > align) {
                                tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
diff -r 6301e7e967c0 -r 5020cef2bc39 include/linux/pci.h
--- a/include/linux/pci.h       Sat Sep 27 01:23:54 2008 -0400
+++ b/include/linux/pci.h       Sat Sep 27 01:25:05 2008 -0400
@@ -65,7 +65,31 @@
 #define PCI_DMA_NONE           3

 #define DEVICE_COUNT_COMPATIBLE        4
-#define DEVICE_COUNT_RESOURCE  12
+
+/*
+ *  For PCI devices, the region numbers are assigned this way:
+ */
+enum {
+       /* #0-5: standard PCI regions */
+       PCI_STD_RESOURCES,
+       PCI_STD_RESOURCES_END = 5,
+
+       /* #6: expansion ROM */
+       PCI_ROM_RESOURCE,
+
+       /* address space assigned to buses behind the bridge */
+#ifndef PCI_BRIDGE_RES_NUM
+#define PCI_BRIDGE_RES_NUM 4
+#endif
+       PCI_BRIDGE_RESOURCES,
+       PCI_BRIDGE_RES_END = PCI_BRIDGE_RESOURCES + PCI_BRIDGE_RES_NUM - 1,
+
+       /* total resources associated with a PCI device */
+       PCI_NUM_RESOURCES,
+
+       /* preserve this for compatibility */
+       DEVICE_COUNT_RESOURCE
+};

 typedef int __bitwise pci_power_t;

@@ -205,18 +229,6 @@
 {
        hlist_del(&cap->next);
 }
-
-/*
- *  For PCI devices, the region numbers are assigned this way:
- *
- *     0-5     standard PCI regions
- *     6       expansion ROM
- *     7-10    bridges: address space assigned to buses behind the bridge
- */
-
-#define PCI_ROM_RESOURCE       6
-#define PCI_BRIDGE_RESOURCES   7
-#define PCI_NUM_RESOURCES      11

 #ifndef PCI_BUS_NUM_RESOURCES
 #define PCI_BUS_NUM_RESOURCES  8
@@ -501,7 +513,7 @@
 void pci_intx(struct pci_dev *dev, int enable);
 int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
-void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
+void pci_update_resource(struct pci_dev *dev, int resno);
 int pci_assign_resource(struct pci_dev *dev, int i);
 int pci_assign_resource_fixed(struct pci_dev *dev, int i);
 void pci_restore_bars(struct pci_dev *dev);

_______________________________________________
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®.