WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 2/9] dom0 PCI: add new general functions
From: "Zhao, Yu" <yu.zhao@xxxxxxxxx>
Date: Sat, 27 Sep 2008 16:59:04 +0800
Accept-language: en-US
Acceptlanguage: en-US
Cc: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>
Delivery-date: Sat, 27 Sep 2008 02:00:23 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: Ackgf0sIqrpRP1csSXC+Jw0mYobNTw==
Thread-topic: [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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH 2/9] dom0 PCI: add new general functions, Zhao, Yu <=