* [Linux-ia64] [PATCH] 2/4 pci segments
@ 2003-04-03 17:51 Alex Williamson
2003-04-03 20:34 ` David Mosberger
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Alex Williamson @ 2003-04-03 17:51 UTC (permalink / raw)
To: linux-ia64
[-- Attachment #1: Type: text/plain, Size: 209 bytes --]
Patch 2 is an update to the PCI segment support that Bjorn posted
around 2.5.19ish. Also against 2.5.64 + 030307. Thanks,
Alex
--
Alex Williamson HP Linux & Open Source Lab
[-- Attachment #2: patch-02.diff --]
[-- Type: text/plain, Size: 10679 bytes --]
diff -urN linux-2.5.64/arch/ia64/kernel/acpi.c linux-work/arch/ia64/kernel/acpi.c
--- linux-2.5.64/arch/ia64/kernel/acpi.c Tue Apr 1 08:49:07 2003
+++ linux-work/arch/ia64/kernel/acpi.c Tue Apr 1 15:20:36 2003
@@ -109,8 +109,6 @@
return "sn2";
# elif defined (CONFIG_IA64_DIG)
return "dig";
-# elif defined (CONFIG_IA64_HP_ZX1)
- return "hpzx1";
# else
# error Unknown platform. Fix acpi.c.
# endif
@@ -176,6 +174,73 @@
kfree(buf->pointer);
}
+void
+acpi_get_crs_addr (struct acpi_buffer *buf, int type, u64 *base, u64 *size, u64 *tra)
+{
+ int offset = 0;
+ struct acpi_resource_address16 *addr16;
+ struct acpi_resource_address32 *addr32;
+ struct acpi_resource_address64 *addr64;
+
+ for (;;) {
+ struct acpi_resource *res = acpi_get_crs_next(buf, &offset);
+ if (!res)
+ return;
+ switch (res->id) {
+ case ACPI_RSTYPE_ADDRESS16:
+ addr16 = (struct acpi_resource_address16 *) &res->data;
+
+ if (type == addr16->resource_type) {
+ *base = addr16->min_address_range;
+ *size = addr16->address_length;
+ *tra = addr16->address_translation_offset;
+ return;
+ }
+ break;
+ case ACPI_RSTYPE_ADDRESS32:
+ addr32 = (struct acpi_resource_address32 *) &res->data;
+ if (type == addr32->resource_type) {
+ *base = addr32->min_address_range;
+ *size = addr32->address_length;
+ *tra = addr32->address_translation_offset;
+ return;
+ }
+ break;
+ case ACPI_RSTYPE_ADDRESS64:
+ addr64 = (struct acpi_resource_address64 *) &res->data;
+ if (type == addr64->resource_type) {
+ *base = addr64->min_address_range;
+ *size = addr64->address_length;
+ *tra = addr64->address_translation_offset;
+ return;
+ }
+ break;
+ }
+ }
+}
+
+int
+acpi_get_addr_space(void *obj, u8 type, u64 *base, u64 *length, u64 *tra)
+{
+ acpi_status status;
+ struct acpi_buffer buf;
+
+ *base = 0;
+ *length = 0;
+ *tra = 0;
+
+ status = acpi_get_crs((acpi_handle)obj, &buf);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n");
+ return status;
+ }
+
+ acpi_get_crs_addr(&buf, type, base, length, tra);
+
+ acpi_dispose_crs(&buf);
+
+ return AE_OK;
+}
#endif /* CONFIG_ACPI */
#ifdef CONFIG_ACPI_BOOT
@@ -808,6 +873,7 @@
list_for_each(node, &acpi_prt.entries) {
entry = (struct acpi_prt_entry *)node;
+ vector[i].segment = entry->id.segment;
vector[i].bus = entry->id.bus;
vector[i].pci_id = ((u32) entry->id.device << 16) | 0xffff;
vector[i].pin = entry->pin;
diff -urN linux-2.5.64/arch/ia64/pci/pci.c linux-work/arch/ia64/pci/pci.c
--- linux-2.5.64/arch/ia64/pci/pci.c Tue Apr 1 08:49:07 2003
+++ linux-work/arch/ia64/pci/pci.c Tue Apr 1 09:19:53 2003
@@ -49,11 +49,13 @@
/*
* Low-level SAL-based PCI configuration access functions. Note that SAL
* calls are already serialized (via sal_lock), so we don't need another
- * synchronization mechanism here. Not using segment number (yet).
+ * synchronization mechanism here.
*/
-#define PCI_SAL_ADDRESS(bus, dev, fn, reg) \
- ((u64)(bus << 16) | (u64)(dev << 11) | (u64)(fn << 8) | (u64)(reg))
+#define PCI_SAL_ADDRESS(seg, bus, dev, fn, reg) \
+ ((u64)(seg << 24) | (u64)(bus << 16) | \
+ (u64)(dev << 11) | (u64)(fn << 8) | (u64)(reg))
+
static int
__pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
@@ -61,10 +63,10 @@
int result = 0;
u64 data = 0;
- if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+ if (!value || (seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
return -EINVAL;
- result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(bus, dev, fn, reg), len, &data);
+ result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, &data);
*value = (u32) data;
@@ -74,24 +76,24 @@
static int
__pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
{
- if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+ if ((seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
return -EINVAL;
- return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(bus, dev, fn, reg), len, value);
+ return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, value);
}
static int
pci_sal_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
- return __pci_sal_read(0, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ return __pci_sal_read(PCI_SEGMENT(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
where, size, value);
}
static int
pci_sal_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
- return __pci_sal_write(0, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ return __pci_sal_write(PCI_SEGMENT(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn),
where, size, value);
}
@@ -114,24 +116,91 @@
subsys_initcall(pci_acpi_init);
+static void __init
+pcibios_fixup_resource(struct resource *res, u64 offset)
+{
+ res->start += offset;
+ res->end += offset;
+}
+
+void __init
+pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
+{
+ int i;
+
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ if (!dev->resource[i].start)
+ continue;
+ if (dev->resource[i].flags & IORESOURCE_MEM)
+ pcibios_fixup_resource(&dev->resource[i],
+ PCI_CONTROLLER(dev)->mem_offset);
+ }
+}
+
/* Called by ACPI when it finds a new root bus. */
+
+static struct pci_controller *
+alloc_pci_controller(int seg)
+{
+ struct pci_controller *controller;
+
+ controller = kmalloc(sizeof(*controller), GFP_KERNEL);
+ if (!controller)
+ return NULL;
+
+ memset(controller, 0, sizeof(*controller));
+ controller->segment = seg;
+ return controller;
+}
+
struct pci_bus *
-pcibios_scan_root (int bus)
+scan_root_bus(int bus, struct pci_ops *ops, void *sysdata)
{
- struct list_head *list;
- struct pci_bus *pci_bus;
+ struct pci_bus *b;
- list_for_each(list, &pci_root_buses) {
- pci_bus = pci_bus_b(list);
- if (pci_bus->number == bus) {
- /* Already scanned */
- printk("PCI: Bus (%02x) already probed\n", bus);
- return pci_bus;
- }
- }
+ /*
+ * We know this is a new root bus we haven't seen before, so
+ * scan it, even if we've seen the same bus number in a different
+ * segment.
+ */
+ b = kmalloc(sizeof(*b), GFP_KERNEL);
+ if (!b)
+ return NULL;
+
+ memset(b, 0, sizeof(*b));
+ INIT_LIST_HEAD(&b->children);
+ INIT_LIST_HEAD(&b->devices);
+
+ list_add_tail(&b->node, &pci_root_buses);
+
+ b->number = b->secondary = bus;
+ b->resource[0] = &ioport_resource;
+ b->resource[1] = &iomem_resource;
+
+ b->sysdata = sysdata;
+ b->ops = ops;
+ b->subordinate = pci_do_scan_bus(b);
+
+ return b;
+}
+
+struct pci_bus *
+pcibios_scan_root(void *handle, int seg, int bus)
+{
+ struct pci_controller *controller;
+ u64 base, size, offset;
+
+ printk("PCI: Probing PCI hardware on bus (%02x:%02x)\n", seg, bus);
+ controller = alloc_pci_controller(seg);
+ if (!controller)
+ return NULL;
+
+ controller->acpi_handle = handle;
- printk("PCI: Probing PCI hardware on bus (%02x)\n", bus);
- return pci_scan_bus(bus, pci_root_ops, NULL);
+ acpi_get_addr_space(handle, ACPI_MEMORY_RANGE, &base, &size, &offset);
+ controller->mem_offset = offset;
+
+ return scan_root_bus(bus, pci_root_ops, controller);
}
/*
@@ -140,6 +209,11 @@
void __devinit
pcibios_fixup_bus (struct pci_bus *b)
{
+ struct list_head *ln;
+
+ for (ln = b->devices.next; ln != &b->devices; ln = ln->next)
+ pcibios_fixup_device_resources(pci_dev_b(ln), b);
+
return;
}
diff -urN linux-2.5.64/drivers/acpi/pci_root.c linux-work/drivers/acpi/pci_root.c
--- linux-2.5.64/drivers/acpi/pci_root.c Tue Mar 4 20:29:04 2003
+++ linux-work/drivers/acpi/pci_root.c Tue Apr 1 09:19:53 2003
@@ -265,7 +265,8 @@
* PCI namespace does not get created until this call is made (and
* thus the root bridge's pci_dev does not exist).
*/
- root->bus = pcibios_scan_root(root->id.bus);
+ root->bus = pcibios_scan_root(root->handle,
+ root->id.segment, root->id.bus);
if (!root->bus) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Bus %02x:%02x not present in PCI namespace\n",
diff -urN linux-2.5.64/include/asm-ia64/acpi.h linux-work/include/asm-ia64/acpi.h
--- linux-2.5.64/include/asm-ia64/acpi.h Tue Mar 4 20:29:34 2003
+++ linux-work/include/asm-ia64/acpi.h Wed Apr 2 13:20:35 2003
@@ -100,7 +100,9 @@
int acpi_request_vector (u32 int_type);
int acpi_get_prt (struct pci_vector_struct **vectors, int *count);
int acpi_get_interrupt_model (int *type);
+int acpi_register_irq (u32 gsi, u32 polarity, u32 trigger);
int acpi_irq_to_vector (u32 irq);
+int acpi_get_addr_space (void *obj, u8 type, u64 *base, u64 *length,u64 *tra);
#ifdef CONFIG_ACPI_NUMA
#include <asm/numa.h>
diff -urN linux-2.5.64/include/asm-ia64/pci.h linux-work/include/asm-ia64/pci.h
--- linux-2.5.64/include/asm-ia64/pci.h Tue Apr 1 08:49:07 2003
+++ linux-work/include/asm-ia64/pci.h Tue Apr 1 09:19:53 2003
@@ -21,7 +21,7 @@
#define PCIBIOS_MIN_MEM 0x10000000
void pcibios_config_init(void);
-struct pci_bus * pcibios_scan_root(int bus);
+struct pci_bus * pcibios_scan_root(void *acpi_handle, int segment, int bus);
struct pci_dev;
@@ -58,7 +58,6 @@
#define pci_unmap_sg platform_pci_unmap_sg
#define pci_dma_sync_single platform_pci_dma_sync_single
#define pci_dma_sync_sg platform_pci_dma_sync_sg
-#define sg_dma_address platform_pci_dma_address
#define pci_dma_supported platform_pci_dma_supported
/* pci_unmap_{single,page} is not a nop, thus... */
@@ -92,9 +91,21 @@
#define pci_controller_num(PDEV) (0)
#define sg_dma_len(sg) ((sg)->dma_length)
+#define sg_dma_address(sg) ((sg)->dma_address)
#define HAVE_PCI_MMAP
extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine);
+
+struct pci_controller {
+ void *acpi_handle;
+ void *iommu;
+ int segment;
+
+ u64 mem_offset;
+};
+
+#define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata)
+#define PCI_SEGMENT(busdev) (PCI_CONTROLLER(busdev)->segment)
#endif /* _ASM_IA64_PCI_H */
diff -urN linux-2.5.64/include/asm-ia64/system.h linux-work/include/asm-ia64/system.h
--- linux-2.5.64/include/asm-ia64/system.h Tue Apr 1 08:49:07 2003
+++ linux-work/include/asm-ia64/system.h Tue Apr 1 09:19:53 2003
@@ -31,6 +31,7 @@
#include <linux/types.h>
struct pci_vector_struct {
+ __u16 segment; /* PCI Segment number */
__u16 bus; /* PCI Bus number */
__u32 pci_id; /* ACPI split 16 bits device, 16 bits function (see section 6.1.1) */
__u8 pin; /* PCI PIN (0 = A, 1 = B, 2 = C, 3 = D) */
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Linux-ia64] [PATCH] 2/4 pci segments
2003-04-03 17:51 [Linux-ia64] [PATCH] 2/4 pci segments Alex Williamson
@ 2003-04-03 20:34 ` David Mosberger
2003-04-03 20:42 ` Alex Williamson
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: David Mosberger @ 2003-04-03 20:34 UTC (permalink / raw)
To: linux-ia64
>>>>> On Thu, 03 Apr 2003 10:51:38 -0700, Alex Williamson <alex_williamson@hp.com> said:
What's up with this hunk?
return "sn2";
# elif defined (CONFIG_IA64_DIG)
return "dig";
-# elif defined (CONFIG_IA64_HP_ZX1)
- return "hpzx1";
# else
# error Unknown platform. Fix acpi.c.
# endif
--david
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Linux-ia64] [PATCH] 2/4 pci segments
2003-04-03 17:51 [Linux-ia64] [PATCH] 2/4 pci segments Alex Williamson
2003-04-03 20:34 ` David Mosberger
2003-04-03 20:42 ` Alex Williamson
@ 2003-04-03 20:42 ` Alex Williamson
2003-04-03 20:42 ` Alex Williamson
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Alex Williamson @ 2003-04-03 20:42 UTC (permalink / raw)
To: linux-ia64
Removing a dup, this is what it looks like in the 2.5.64 tree:
# if defined (CONFIG_IA64_HP_SIM)
return "hpsim";
# elif defined (CONFIG_IA64_HP_ZX1)
return "hpzx1";
# elif defined (CONFIG_IA64_SGI_SN1)
return "sn1";
# elif defined (CONFIG_IA64_SGI_SN2)
return "sn2";
# elif defined (CONFIG_IA64_DIG)
return "dig";
# elif defined (CONFIG_IA64_HP_ZX1)
return "hpzx1";
Thanks,
Alex
David Mosberger wrote:
>
> >>>>> On Thu, 03 Apr 2003 10:51:38 -0700, Alex Williamson <alex_williamson@hp.com> said:
>
> What's up with this hunk?
>
> return "sn2";
> # elif defined (CONFIG_IA64_DIG)
> return "dig";
> -# elif defined (CONFIG_IA64_HP_ZX1)
> - return "hpzx1";
> # else
> # error Unknown platform. Fix acpi.c.
> # endif
>
> --david
--
Alex Williamson HP Linux & Open Source Lab
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Linux-ia64] [PATCH] 2/4 pci segments
2003-04-03 17:51 [Linux-ia64] [PATCH] 2/4 pci segments Alex Williamson
` (2 preceding siblings ...)
2003-04-03 20:42 ` Alex Williamson
@ 2003-04-03 20:42 ` Alex Williamson
2003-04-03 20:44 ` Matthew Wilcox
2003-04-03 21:30 ` David Mosberger
5 siblings, 0 replies; 7+ messages in thread
From: Alex Williamson @ 2003-04-03 20:42 UTC (permalink / raw)
To: linux-ia64
Removing a dup, this is what it looks like in the 2.5.64 tree:
# if defined (CONFIG_IA64_HP_SIM)
return "hpsim";
# elif defined (CONFIG_IA64_HP_ZX1)
return "hpzx1";
# elif defined (CONFIG_IA64_SGI_SN1)
return "sn1";
# elif defined (CONFIG_IA64_SGI_SN2)
return "sn2";
# elif defined (CONFIG_IA64_DIG)
return "dig";
# elif defined (CONFIG_IA64_HP_ZX1)
return "hpzx1";
Thanks,
Alex
David Mosberger wrote:
>
> >>>>> On Thu, 03 Apr 2003 10:51:38 -0700, Alex Williamson <alex_williamson@hp.com> said:
>
> What's up with this hunk?
>
> return "sn2";
> # elif defined (CONFIG_IA64_DIG)
> return "dig";
> -# elif defined (CONFIG_IA64_HP_ZX1)
> - return "hpzx1";
> # else
> # error Unknown platform. Fix acpi.c.
> # endif
>
> --david
--
Alex Williamson HP Linux & Open Source Lab
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Linux-ia64] [PATCH] 2/4 pci segments
2003-04-03 17:51 [Linux-ia64] [PATCH] 2/4 pci segments Alex Williamson
2003-04-03 20:34 ` David Mosberger
@ 2003-04-03 20:42 ` Alex Williamson
2003-04-03 20:42 ` Alex Williamson
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Alex Williamson @ 2003-04-03 20:42 UTC (permalink / raw)
To: linux-ia64
Removing a dup, this is what it looks like in the 2.5.64 tree:
# if defined (CONFIG_IA64_HP_SIM)
return "hpsim";
# elif defined (CONFIG_IA64_HP_ZX1)
return "hpzx1";
# elif defined (CONFIG_IA64_SGI_SN1)
return "sn1";
# elif defined (CONFIG_IA64_SGI_SN2)
return "sn2";
# elif defined (CONFIG_IA64_DIG)
return "dig";
# elif defined (CONFIG_IA64_HP_ZX1)
return "hpzx1";
Thanks,
Alex
David Mosberger wrote:
>
> >>>>> On Thu, 03 Apr 2003 10:51:38 -0700, Alex Williamson <alex_williamson@hp.com> said:
>
> What's up with this hunk?
>
> return "sn2";
> # elif defined (CONFIG_IA64_DIG)
> return "dig";
> -# elif defined (CONFIG_IA64_HP_ZX1)
> - return "hpzx1";
> # else
> # error Unknown platform. Fix acpi.c.
> # endif
>
> --david
--
Alex Williamson HP Linux & Open Source Lab
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Linux-ia64] [PATCH] 2/4 pci segments
2003-04-03 17:51 [Linux-ia64] [PATCH] 2/4 pci segments Alex Williamson
` (3 preceding siblings ...)
2003-04-03 20:42 ` Alex Williamson
@ 2003-04-03 20:44 ` Matthew Wilcox
2003-04-03 21:30 ` David Mosberger
5 siblings, 0 replies; 7+ messages in thread
From: Matthew Wilcox @ 2003-04-03 20:44 UTC (permalink / raw)
To: linux-ia64
On Thu, Apr 03, 2003 at 12:34:52PM -0800, David Mosberger wrote:
> >>>>> On Thu, 03 Apr 2003 10:51:38 -0700, Alex Williamson <alex_williamson@hp.com> said:
>
> What's up with this hunk?
>
> return "sn2";
> # elif defined (CONFIG_IA64_DIG)
> return "dig";
> -# elif defined (CONFIG_IA64_HP_ZX1)
> - return "hpzx1";
> # else
> # error Unknown platform. Fix acpi.c.
> # endif
it's mentioned twice. merge bug from 2.4.17 or so, iirc.
--
"It's not Hollywood. War is real, war is primarily not about defeat or
victory, it is about death. I've seen thousands and thousands of dead bodies.
Do you think I want to have an academic debate on this subject?" -- Robert Fisk
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Linux-ia64] [PATCH] 2/4 pci segments
2003-04-03 17:51 [Linux-ia64] [PATCH] 2/4 pci segments Alex Williamson
` (4 preceding siblings ...)
2003-04-03 20:44 ` Matthew Wilcox
@ 2003-04-03 21:30 ` David Mosberger
5 siblings, 0 replies; 7+ messages in thread
From: David Mosberger @ 2003-04-03 21:30 UTC (permalink / raw)
To: linux-ia64
>>>>> On Thu, 03 Apr 2003 13:42:33 -0700, Alex Williamson <alex_williamson@hp.com> said:
Alex> Removing a dup
Got it, thanks.
--david
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2003-04-03 21:30 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-04-03 17:51 [Linux-ia64] [PATCH] 2/4 pci segments Alex Williamson
2003-04-03 20:34 ` David Mosberger
2003-04-03 20:42 ` Alex Williamson
2003-04-03 20:42 ` Alex Williamson
2003-04-03 20:42 ` Alex Williamson
2003-04-03 20:44 ` Matthew Wilcox
2003-04-03 21:30 ` David Mosberger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox