Skip to contentSkip to conversation

2.4.18 early printk, PCI segment, multi-IOMMU support

PATCH New Bjorn Helgaas 1 participant 1 message Jul 22, 2002

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 2.4.18 early printk, PCI segment, multi-IOMMU support

The attached patches are for 2.4.18-ia64-020719. They add support for early printk on a UART, multiple PCI segments, PCI root bridge translation offsets, and multiple HP ZX1 IOMMUs.

Tested on HP ZX1 and i2000.

10_early_printk.diff
Early printk for MMIO UARTs. UART address from HCDP or specified in config.

20_iosapic_gsi.diff
Remove gsi_to_vector(), which had a hard-coded limit on the range of GSIs.

30_sci.diff
Add acpi_irq_to_vector() to handle both legacy ISA and new GSI interrupt numbers. Add support for SCI on GSI interrupt.

40_pcibios_segment.diff
Add struct pci_controller for IA64 sysdata. Stash the PCI segment there and add support in config accessors. The HP ZX1 "fake dev" stuff that used to be stored in sysdata is pushed down a level (I hope to get rid of this completely soon).

50_iosapic_segment.diff
Add segment support for PCI interrupts.

60_pci_tra.diff
Add support for PCI root bridges with non-zero translation offsets.

70_enable_device.diff
Add a platform vector for pci_enable_device(). ZX1 needs this to associate a device with the correct IOMMU.

80_multi_ioc.diff
Support multiple ZX1 IOMMUs, discovered via ACPI (not "fake dev" stuff).

Signature · 3 lines
Bjorn Helgaas - bjorn_helgaas at hp.com
Linux Systems Operation R&D
Hewlett-Packard Company
Documentation/Configure.help +22 -5
diff -u -r -X /home/helgaas/exclude linux-2.4.18-ia64-020719/Documentation/Configure.help 10_early_printk/Documentation/Configure.help
@@ -23866,12 +23866,29 @@
   and restore instructions.  It's useful for tracking down spinlock
   problems, but slow!  If you're unsure, select N.
 
-Early printk support (requires VGA!)
+Early printk support
 CONFIG_IA64_EARLY_PRINTK
-  Selecting this option uses the VGA screen for printk() output before
-  the consoles are initialised.  It is useful for debugging problems
-  early in the boot process, but only if you have a VGA screen
-  attached.  If you're unsure, select N.
+  Selecting this option uses a UART or VGA screen (or both) for
+  printk() output before the consoles are initialised.  It is useful
+  for debugging problems early in the boot process, but only if you
+  have a serial terminal or a VGA screen attached.  If you're unsure,
+  select N.
+
+Early printk on serial port
+CONFIG_IA64_EARLY_PRINTK_UART
+  Select this option to use a serial port for early printk() output.
+  You must either select CONFIG_SERIAL_HCDP (to locate the UART
+  using the EFI HCDP table) or set the UART address explicitly
+  with CONFIG_IA64_EARLY_PRINTK_UART_BASE.
+
+UART base address
+CONFIG_IA64_EARLY_PRINTK_UART_BASE
+  The physical MMIO address of the UART to use for early printk().
+  This overrides any UART located using the EFI HCDP table.
+
+Early printk on VGA
+CONFIG_IA64_EARLY_PRINTK_VGA
+  Select this option to use VGA for early printk() output.
 
 Print possible IA64 hazards to console
 CONFIG_IA64_PRINT_HAZARDS
arch/ia64/config.in +8 -1
diff -u -r -X /home/helgaas/exclude linux-2.4.18-ia64-020719/arch/ia64/config.in 10_early_printk/arch/ia64/config.in
@@ -294,7 +294,14 @@
    bool '  Disable VHPT' CONFIG_DISABLE_VHPT
    bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
 
-   bool '  Early printk support (requires VGA!)' CONFIG_IA64_EARLY_PRINTK
+   bool '  Early printk support' CONFIG_IA64_EARLY_PRINTK
+   if [ "$CONFIG_IA64_EARLY_PRINTK" != "n" ]; then
+      bool '    Early printk on MMIO serial port' CONFIG_IA64_EARLY_PRINTK_UART
+      if [ "$CONFIG_IA64_EARLY_PRINTK_UART" != "n" ]; then
+         hex '      UART MMIO base address' CONFIG_IA64_EARLY_PRINTK_UART_BASE 0
+      fi
+      bool '    Early printk on VGA' CONFIG_IA64_EARLY_PRINTK_VGA
+   fi
    bool '  Debug memory allocations' CONFIG_DEBUG_SLAB
    bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
    bool '  Turn on compare-and-exchange bug checking (slow!)' CONFIG_IA64_DEBUG_CMPXCHG
drivers/char/hcdp_serial.c +38 -0
diff -u -r -X /home/helgaas/exclude linux-2.4.18-ia64-020719/drivers/char/hcdp_serial.c 10_early_printk/drivers/char/hcdp_serial.c
@@ -219,3 +219,41 @@
 	printk("Leaving setup_serial_hcdp()\n");
 #endif
 }
+
+#ifdef CONFIG_IA64_EARLY_PRINTK_UART
+unsigned long hcdp_early_uart(void)
+{
+	efi_system_table_t *systab;
+	efi_config_table_t *config_tables;
+	hcdp_t *hcdp = 0;
+	hcdp_dev_t *dev;
+	int i;
+
+	systab = (efi_system_table_t *) ia64_boot_param->efi_systab;
+	if (!systab)
+		return 0;
+	systab = __va(systab);
+
+	config_tables = (efi_config_table_t *) systab->tables;
+	if (!config_tables)
+		return 0;
+	config_tables = __va(config_tables);
+
+	for (i = 0; i < systab->nr_tables; i++) {
+		if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
+			hcdp = (hcdp_t *) config_tables[i].table;
+			break;
+		}
+	}
+	if (!hcdp)
+		return 0;
+	hcdp = __va(hcdp);
+
+	for (i = 0, dev = hcdp->hcdp_dev; i < hcdp->num_entries; i++, dev++) {
+		if (dev->type == HCDP_DEV_CONSOLE)
+			return (u64) dev->base_addr.addrhi << 32
+				| dev->base_addr.addrlo;
+	}
+	return 0;
+}
+#endif
kernel/printk.c +53 -2

73 lines not on this page · raw message

arch/ia64/kernel/ia64_ksyms.c +0 -1
diff -u -r 10_early_printk/arch/ia64/kernel/ia64_ksyms.c 20_iosapic_gsi/arch/ia64/kernel/ia64_ksyms.c
@@ -28,7 +28,6 @@
 
 #include <linux/irq.h>
 EXPORT_SYMBOL(isa_irq_to_vector_map);
-EXPORT_SYMBOL(gsi_to_vector_map);
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(disable_irq_nosync);
arch/ia64/kernel/iosapic.c +0 -1
diff -u -r 10_early_printk/arch/ia64/kernel/iosapic.c 20_iosapic_gsi/arch/ia64/kernel/iosapic.c
@@ -421,7 +421,6 @@
 	irq_desc_t *idesc;
 	struct hw_interrupt_type *irq_type;
 
-	gsi_to_vector(global_vector) = vector;
 	iosapic_irq[vector].pin	= pin;
 	iosapic_irq[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW;
 	iosapic_irq[vector].dmode    = delivery;
arch/ia64/kernel/irq_ia64.c +0 -5
diff -u -r 10_early_printk/arch/ia64/kernel/irq_ia64.c 20_iosapic_gsi/arch/ia64/kernel/irq_ia64.c
@@ -54,11 +54,6 @@
 	0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21
 };
 
-/*
- * GSI to IA-64 vector translation table.
- */
-__u8 gsi_to_vector_map[255];
-
 int
 ia64_alloc_irq (void)
 {
drivers/acpi/osl.c +2 -2
diff -u -r 10_early_printk/drivers/acpi/osl.c 20_iosapic_gsi/drivers/acpi/osl.c
@@ -235,7 +235,7 @@
 acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context)
 {
 #ifdef CONFIG_IA64
-	irq = gsi_to_vector(irq);
+	irq = isa_irq_to_vector(irq);
 #endif /* CONFIG_IA64 */
 	acpi_irq_irq = irq;
 	acpi_irq_handler = handler;
@@ -253,7 +253,7 @@
 {
 	if (acpi_irq_handler) {
 #ifdef CONFIG_IA64
-		irq = gsi_to_vector(irq);
+		irq = isa_irq_to_vector(irq);
 #endif /* CONFIG_IA64 */
 		free_irq(irq, acpi_irq);
 		acpi_irq_handler = NULL;
include/asm-ia64/hw_irq.h +0 -2
diff -u -r 10_early_printk/include/asm-ia64/hw_irq.h 20_iosapic_gsi/include/asm-ia64/hw_irq.h
@@ -67,8 +67,6 @@
 
 extern __u8 isa_irq_to_vector_map[16];
 #define isa_irq_to_vector(x)	isa_irq_to_vector_map[(x)]
-extern __u8 gsi_to_vector_map[255];
-#define gsi_to_vector(x)	gsi_to_vector_map[(x)]
 
 extern unsigned long ipi_base_addr;
 
arch/ia64/kernel/acpi.c +53 -2

92 lines not on this page · raw message

arch/ia64/kernel/iosapic.c +2 -2
diff -u -r -X /home/helgaas/exclude 20_iosapic_gsi/arch/ia64/kernel/iosapic.c 30_sci/arch/ia64/kernel/iosapic.c
@@ -124,8 +124,8 @@
  * Translate IOSAPIC irq number to the corresponding IA-64 interrupt vector.  If no
  * entry exists, return -1.
  */
-static int
-iosapic_irq_to_vector (int irq)
+int
+iosapic_irq_to_vector (unsigned int irq)
 {
 	int vector;
 
drivers/acpi/osl.c +12 -9
diff -u -r -X /home/helgaas/exclude 20_iosapic_gsi/drivers/acpi/osl.c 30_sci/drivers/acpi/osl.c
@@ -33,6 +33,7 @@
 #include <linux/interrupt.h>
 #include <linux/kmod.h>
 #include <linux/delay.h>
+#include <linux/acpi.h>
 #include <asm/io.h>
 #include "acpi.h"
 
@@ -41,11 +42,6 @@
 u64 efi_mem_attributes (u64 phys_addr);
 #endif
 
-#ifdef CONFIG_IA64
-#include <asm/hw_irq.h>
-#include <asm/delay.h>
-#endif
-
 
 #define _COMPONENT		ACPI_OS_SERVICES
 ACPI_MODULE_NAME	("osl")
@@ -235,8 +231,15 @@
 acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context)
 {
 #ifdef CONFIG_IA64
-	irq = isa_irq_to_vector(irq);
-#endif /* CONFIG_IA64 */
+	int vector;
+
+	vector = acpi_irq_to_vector(irq);
+	if (vector < 0) {
+		printk(KERN_ERR PREFIX "SCI (IRQ%d) not registered\n", irq);
+		return AE_OK;
+	}
+	irq = vector;
+#endif
 	acpi_irq_irq = irq;
 	acpi_irq_handler = handler;
 	acpi_irq_context = context;
@@ -253,8 +256,8 @@
 {
 	if (acpi_irq_handler) {
 #ifdef CONFIG_IA64
-		irq = isa_irq_to_vector(irq);
-#endif /* CONFIG_IA64 */
+		irq = acpi_irq_to_vector(irq);
+#endif
 		free_irq(irq, acpi_irq);
 		acpi_irq_handler = NULL;
 	}
include/asm-ia64/iosapic.h +1 -0
diff -u -r -X /home/helgaas/exclude 20_iosapic_gsi/include/asm-ia64/iosapic.h 30_sci/include/asm-ia64/iosapic.h
@@ -53,6 +53,7 @@
 
 extern void __init iosapic_init (unsigned long address, unsigned int base_irq,
                                  int pcat_compat);
+extern int iosapic_irq_to_vector (unsigned int irq);
 extern int iosapic_register_irq (u32 global_vector, unsigned long polarity,
                                  unsigned long edge_triggered, u32 base_irq,
                                  char *iosapic_address);
include/linux/acpi.h +1 -0
diff -u -r -X /home/helgaas/exclude 20_iosapic_gsi/include/linux/acpi.h 30_sci/include/linux/acpi.h
@@ -377,6 +377,7 @@
 #ifdef CONFIG_ACPI
 
 int acpi_init(void);
+int acpi_irq_to_vector(u32 irq);
 
 #endif /*CONFIG_ACPI*/
 
arch/ia64/hp/zx1/hpzx1_misc.c +20 -3
diff -u -r 30_sci/arch/ia64/hp/zx1/hpzx1_misc.c 40_pcibios_segment/arch/ia64/hp/zx1/hpzx1_misc.c
@@ -30,13 +30,16 @@
 	int sizing;			// in middle of BAR sizing operation?
 };
 
+#define PCI_FAKE_DEV(dev)	((struct fake_pci_dev *) \
+					PCI_CONTROLLER(dev)->platform_data)
+
 static struct pci_ops *orig_pci_ops;
 
 #define HP_CFG_RD(sz, bits, name) \
 static int hp_cfg_read##sz (struct pci_dev *dev, int where, u##bits *value) \
 { \
 	struct fake_pci_dev *fake_dev; \
-	if (!(fake_dev = (struct fake_pci_dev *) dev->sysdata)) \
+	if (!(fake_dev = PCI_FAKE_DEV(dev))) \
 		return orig_pci_ops->name(dev, where, value); \
 	\
 	if (where == PCI_BASE_ADDRESS_0) { \
@@ -60,7 +63,7 @@
 { \
 	struct fake_pci_dev *fake_dev; \
 	\
-	if (!(fake_dev = (struct fake_pci_dev *) dev->sysdata)) \
+	if (!(fake_dev = PCI_FAKE_DEV(dev))) \
 		return orig_pci_ops->name(dev, where, value); \
 	\
 	if (where == PCI_BASE_ADDRESS_0) { \
@@ -91,16 +94,26 @@
 static void
 hpzx1_fake_pci_dev(char *name, unsigned int busnum, unsigned long addr, unsigned int size)
 {
+	struct pci_controller *controller;
 	struct fake_pci_dev *fake;
 	int slot;
 	struct pci_dev *dev;
 	struct pci_bus *b, *bus = NULL;
 	u8 hdr;
 
+	controller = kmalloc(sizeof(*controller), GFP_KERNEL);
+	if (!controller) {
+		printk(KERN_ERR PFX "No memory for %s (0x%p) sysdata\n", name,
+			(void *) addr);
+		return;
+	}
+	memset(controller, 0, sizeof(*controller));
+
         fake = kmalloc(sizeof(*fake), GFP_KERNEL);
 	if (!fake) {
 		printk(KERN_ERR PFX "No memory for %s (0x%p) sysdata\n", name,
 			(void *) addr);
+		kfree(controller);
 		return;
 	}
 
@@ -109,6 +122,7 @@
 	fake->csr_size = size;
 	fake->mapped_csrs = (unsigned long) ioremap(addr, size);
 	fake->sizing = 0;
+	controller->platform_data = fake;
 
 	pci_for_each_bus(b)
 		if (busnum == b->number) {
@@ -120,6 +134,7 @@
 		printk(KERN_ERR PFX "No host bus 0x%02x for %s (0x%p)\n",
 			busnum, name, (void *) addr);
 		kfree(fake);
+		kfree(controller);
 		return;
 	}
 
@@ -131,6 +146,7 @@
 		printk(KERN_ERR PFX "No space for %s (0x%p) on bus 0x%02x\n",
 			name, (void *) addr, busnum);
 		kfree(fake);
+		kfree(controller);
 		return;
 	}
 
@@ -139,6 +155,7 @@
 		printk(KERN_ERR PFX "No memory for %s (0x%p)\n", name,
 			(void *) addr);
 		kfree(fake);
+		kfree(controller);
 		return;
 	}
 
@@ -146,7 +163,7 @@
 
 	memset(dev, 0, sizeof(*dev));
 	dev->bus = bus;
-	dev->sysdata = fake;
+	dev->sysdata = controller;
 	dev->devfn = PCI_DEVFN(slot, 0);
 	pci_read_config_word(dev, PCI_VENDOR_ID, &dev->vendor);
 	pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
arch/ia64/kernel/pci.c +72 -28

183 lines not on this page · raw message

drivers/acpi/pci_root.c +2 -3
diff -u -r 30_sci/drivers/acpi/pci_root.c 40_pcibios_segment/drivers/acpi/pci_root.c
@@ -103,8 +103,6 @@
 	switch (status) {
 	case AE_OK:
 		root->id.segment = (u16) value;
-		printk("_SEG exists! Unsupported. Abort.\n");
-		BUG();
 		break;
 	case AE_NOT_FOUND:
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
@@ -162,7 +160,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", 
include/asm-ia64/pci.h +11 -1
diff -u -r 30_sci/include/asm-ia64/pci.h 40_pcibios_segment/include/asm-ia64/pci.h
@@ -20,7 +20,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);
 extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
 extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
 
@@ -81,5 +81,15 @@
 #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;
+	int segment;
+
+	void *platform_data;
+};
+
+#define PCI_CONTROLLER(dev) ((struct pci_controller *) dev->sysdata)
+#define PCI_SEGMENT(dev)    (PCI_CONTROLLER(dev)->segment)
 
 #endif /* _ASM_IA64_PCI_H */
arch/ia64/kernel/acpi.c +1 -0
diff -u -r -X /home/helgaas/exclude 40_pcibios_segment/arch/ia64/kernel/acpi.c 80_multi_ioc/arch/ia64/kernel/acpi.c
@@ -712,6 +712,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;
arch/ia64/kernel/iosapic.c +9 -5
diff -u -r -X /home/helgaas/exclude 40_pcibios_segment/arch/ia64/kernel/iosapic.c 80_multi_ioc/arch/ia64/kernel/iosapic.c
@@ -25,12 +25,13 @@
  * 02/04/02	P. Diefenbaugh	Cleaned up ACPI PCI IRQ routing.
  * 02/04/18	J.I. Lee	bug fix in iosapic_init_pci_irq
  * 02/04/30	J.I. Lee	bug fix in find_iosapic to fix ACPI PCI IRQ to IOSAPIC mapping error
+ * 02/07/11	B. Helgaas	Support PCI segments
  */
 /*
  * Here is what the interrupt logic between a PCI device and the CPU looks like:
  *
  * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC, INTD).  The
- *     device is uniquely identified by its bus--, and slot-number (the function
+ *     device is uniquely identified by its segment--, bus--, and slot-number (the function
  *     number does not matter here because all functions share the same interrupt
  *     lines).
  *
@@ -140,12 +141,13 @@
  * return -1.
  */
 int
-pci_pin_to_vector (int bus, int slot, int pci_pin)
+pci_pin_to_vector (int segment, int bus, int slot, int pci_pin)
 {
 	struct pci_vector_struct *r;
 
 	for (r = pci_irq.route; r < pci_irq.route + pci_irq.num_routes; ++r)
-		if (r->bus == bus && (r->pci_id >> 16) == slot && r->pin == pci_pin)
+		if (r->segment == segment && r->bus == bus &&
+		    (r->pci_id >> 16) == slot && r->pin == pci_pin)
 			return iosapic_irq_to_vector(r->irq);
 	return -1;
 }
@@ -689,6 +691,7 @@
 iosapic_pci_fixup (int phase)
 {
 	struct	pci_dev	*dev;
+	int segment;
 	unsigned char pin;
 	int vector;
 	struct hw_interrupt_type *irq_type;
@@ -706,7 +709,8 @@
 		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 		if (pin) {
 			pin--;          /* interrupt pins are numbered starting from 1 */
-			vector = pci_pin_to_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
+			segment = PCI_SEGMENT(dev);
+			vector = pci_pin_to_vector(segment, dev->bus->number, PCI_SLOT(dev->devfn), pin);
 			if (vector < 0 && dev->bus->parent) {
 				/* go back to the bridge */
 				struct pci_dev *bridge = dev->bus->self;
@@ -716,7 +720,7 @@
 					do {
 						/* do the bridge swizzle... */
 						pin = (pin + PCI_SLOT(dev->devfn)) % 4;
-						vector = pci_pin_to_vector(bridge->bus->number,
+						vector = pci_pin_to_vector(segment, bridge->bus->number,
 									   PCI_SLOT(bridge->devfn),
 									   pin);
 					} while (vector < 0 && (bridge = bridge->bus->self));
include/asm-ia64/system.h +1 -0
diff -u -r -X /home/helgaas/exclude 40_pcibios_segment/include/asm-ia64/system.h 80_multi_ioc/include/asm-ia64/system.h
@@ -29,6 +29,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) */
arch/ia64/kernel/acpi.c +67 -0

73 lines not on this page · raw message

arch/ia64/kernel/pci.c +31 -1
diff -u -r 50_iosapic_segment/arch/ia64/kernel/pci.c 60_pci_tra/arch/ia64/kernel/pci.c
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
+#include <linux/acpi.h>
 
 #include <asm/machvec.h>
 #include <asm/page.h>
@@ -214,6 +215,7 @@
 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);
 
@@ -222,6 +224,10 @@
 		return NULL;
 
 	controller->acpi_handle = handle;
+
+	acpi_get_addr_space(handle, ACPI_MEMORY_RANGE, &base, &size, &offset);
+	controller->mem_offset = offset;
+
 	return scan_root_bus(bus, pci_root_ops, controller);
 }
 
@@ -266,6 +272,27 @@
 	return;
 }
 
+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 after each bus is probed, but before its children
  *  are examined.
@@ -273,7 +300,10 @@
 void __init
 pcibios_fixup_bus (struct pci_bus *b)
 {
-	return;
+	struct list_head *ln;
+
+	for (ln = b->devices.next; ln != &b->devices; ln = ln->next)
+		pcibios_fixup_device_resources(pci_dev_b(ln), b);
 }
 
 void __init
arch/ia64/kernel/setup.c +2 -0
diff -u -r 50_iosapic_segment/arch/ia64/kernel/setup.c 60_pci_tra/arch/ia64/kernel/setup.c
@@ -29,6 +29,7 @@
 #include <linux/string.h>
 #include <linux/threads.h>
 #include <linux/console.h>
+#include <linux/ioport.h>
 
 #include <asm/ia32.h>
 #include <asm/page.h>
@@ -295,6 +296,7 @@
 
 	efi_init();
 
+	iomem_resource.end = ~0UL;	/* FIXME probably belongs elsewhere */
 	find_memory();
 
 #if 0
include/asm-ia64/pci.h +2 -0
diff -u -r 50_iosapic_segment/include/asm-ia64/pci.h 60_pci_tra/include/asm-ia64/pci.h
@@ -86,6 +86,8 @@
 	void *acpi_handle;
 	int segment;
 
+	u64 mem_offset;
+
 	void *platform_data;
 };
 
include/linux/acpi.h +2 -0
diff -u -r 50_iosapic_segment/include/linux/acpi.h 60_pci_tra/include/linux/acpi.h
@@ -378,6 +378,8 @@
 
 int acpi_init(void);
 int acpi_irq_to_vector(u32 irq);
+acpi_status acpi_get_addr_space(acpi_handle, u8 type, u64 *base, u64 *length, u64 *tra);
+
 
 #endif /*CONFIG_ACPI*/
 
arch/ia64/kernel/pci.c +2 -0
diff -u -r 60_pci_tra/arch/ia64/kernel/pci.c 70_enable_device/arch/ia64/kernel/pci.c
@@ -349,6 +349,8 @@
 	if (!dev)
 		return -EINVAL;
 
+ 	platform_pci_enable_device(dev);
+
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	old_cmd = cmd;
 	for (idx=0; idx<6; idx++) {
include/asm-ia64/machvec.h +8 -1
diff -u -r 60_pci_tra/include/asm-ia64/machvec.h 70_enable_device/include/asm-ia64/machvec.h
@@ -24,6 +24,7 @@
 typedef void ia64_mv_cpu_init_t(void);
 typedef void ia64_mv_irq_init_t (void);
 typedef void ia64_mv_pci_fixup_t (int);
+typedef void ia64_mv_pci_enable_device_t (struct pci_dev *);
 typedef unsigned long ia64_mv_map_nr_t (unsigned long);
 typedef void ia64_mv_mca_init_t (void);
 typedef void ia64_mv_mca_handler_t (void);
@@ -91,7 +92,8 @@
 #  define platform_cmci_handler	ia64_mv.cmci_handler
 #  define platform_log_print	ia64_mv.log_print
 #  define platform_pci_fixup	ia64_mv.pci_fixup
-#  define platform_send_ipi	ia64_mv.send_ipi
+#  define platform_pci_enable_device	ia64_mv.pci_enable_device
+#  define platform_send_ipi		ia64_mv.send_ipi
 #  define platform_global_tlb_purge	ia64_mv.global_tlb_purge
 #  define platform_pci_dma_init		ia64_mv.dma_init
 #  define platform_pci_alloc_consistent	ia64_mv.alloc_consistent
@@ -121,6 +123,7 @@
 	ia64_mv_cpu_init_t *cpu_init;
 	ia64_mv_irq_init_t *irq_init;
 	ia64_mv_pci_fixup_t *pci_fixup;
+	ia64_mv_pci_enable_device_t *pci_enable_device;
 	ia64_mv_map_nr_t *map_nr;
 	ia64_mv_mca_init_t *mca_init;
 	ia64_mv_mca_handler_t *mca_handler;
@@ -157,6 +160,7 @@
 	platform_cpu_init,			\
 	platform_irq_init,			\
 	platform_pci_fixup,			\
+	platform_pci_enable_device,		\
 	platform_map_nr,			\
 	platform_mca_init,			\
 	platform_mca_handler,			\
@@ -235,6 +239,9 @@
 #endif
 #ifndef platform_pci_fixup
 # define platform_pci_fixup	((ia64_mv_pci_fixup_t *) machvec_noop)
+#endif
+#ifndef platform_pci_enable_device
+# define platform_pci_enable_device	((ia64_mv_pci_enable_device_t *) machvec_noop)
 #endif
 #ifndef platform_send_ipi
 # define platform_send_ipi	ia64_send_ipi	/* default to architected version */
arch/ia64/hp/common/sba_iommu.c +304 -306

829 lines not on this page · raw message

arch/ia64/hp/zx1/hpzx1_misc.c +2 -70

90 lines not on this page · raw message

arch/ia64/kernel/acpi.c +63 -0

69 lines not on this page · raw message

include/asm-ia64/machvec_hpzx1.h +2 -0
diff -u -r 70_enable_device/include/asm-ia64/machvec_hpzx1.h 80_multi_ioc/include/asm-ia64/machvec_hpzx1.h
@@ -3,6 +3,7 @@
 
 extern ia64_mv_setup_t dig_setup;
 extern ia64_mv_pci_fixup_t hpzx1_pci_fixup;
+extern ia64_mv_pci_enable_device_t sba_enable_device;
 extern ia64_mv_map_nr_t map_nr_dense;
 extern ia64_mv_pci_alloc_consistent sba_alloc_consistent;
 extern ia64_mv_pci_free_consistent sba_free_consistent;
@@ -23,6 +24,7 @@
 #define platform_name			"hpzx1"
 #define platform_setup			dig_setup
 #define platform_pci_fixup		hpzx1_pci_fixup
+#define platform_pci_enable_device	sba_enable_device
 #define platform_map_nr			map_nr_dense
 #define platform_pci_dma_init		((ia64_mv_pci_dma_init *) machvec_noop)
 #define platform_pci_alloc_consistent	sba_alloc_consistent
include/asm-ia64/pci.h +1 -0
diff -u -r 70_enable_device/include/asm-ia64/pci.h 80_multi_ioc/include/asm-ia64/pci.h
@@ -84,6 +84,7 @@
 
 struct pci_controller {
 	void *acpi_handle;
+	void *iommu;
 	int segment;
 
 	u64 mem_offset;
include/linux/acpi.h +2 -0
diff -u -r 70_enable_device/include/linux/acpi.h 80_multi_ioc/include/linux/acpi.h
@@ -36,6 +36,7 @@
  * isn't the right answer either.  Please just ignore it for now.
  */
 #include "../../drivers/acpi/include/acpi.h"
+#include "../../drivers/acpi/acpi_drivers.h"
 #include <asm/acpi.h>
 
 
@@ -378,6 +379,7 @@
 
 int acpi_init(void);
 int acpi_irq_to_vector(u32 irq);
+acpi_status acpi_hp_csr_space (acpi_handle, u64 *base, u64 *length);
 acpi_status acpi_get_addr_space(acpi_handle, u8 type, u64 *base, u64 *length, u64 *tra);
 
 
include/linux/pci_ids.h +2 -0
diff -u -r 70_enable_device/include/linux/pci_ids.h 80_multi_ioc/include/linux/pci_ids.h
@@ -505,6 +505,8 @@
 #define PCI_DEVICE_ID_HP_DIVA1		0x1049
 #define PCI_DEVICE_ID_HP_DIVA2		0x104A
 #define PCI_DEVICE_ID_HP_SP2_0		0x104B
+#define PCI_DEVICE_ID_HP_REO_SBA	0x10f0
+#define PCI_DEVICE_ID_HP_REO_IOC	0x10f1
 #define PCI_DEVICE_ID_HP_ZX1_SBA	0x1229
 #define PCI_DEVICE_ID_HP_ZX1_IOC	0x122a
 #define PCI_DEVICE_ID_HP_ZX1_LBA	0x122e