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 1/9] dom0 PCI: export some functions and macros

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 1/9] dom0 PCI: export some functions and macros
From: "Zhao, Yu" <yu.zhao@xxxxxxxxx>
Date: Sat, 27 Sep 2008 16:59:00 +0800
Accept-language: en-US
Acceptlanguage: en-US
Cc: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>
Delivery-date: Sat, 27 Sep 2008 02:01:43 -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: Ackgf0gNlMUHy7d1RN28/KWYFTADgg==
Thread-topic: [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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH 1/9] dom0 PCI: export some functions and macros, Zhao, Yu <=