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
|