diff -Nru a/Documentation/mmio_barrier.txt b/Documentation/mmio_barrier.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/mmio_barrier.txt Thu Aug 29 22:23:25 2002 @@ -0,0 +1,15 @@ +On some platforms, so-called memory-mapped I/O is weakly ordered. For +example, the following might occur: + +CPU A writes 0x1 to Device #1 +CPU B writes 0x2 to Device #1 +Device #1 sees 0x2 +Device #1 sees 0x1 + +On such platforms, driver writers are responsible for ensuring that I/O +writes to memory-mapped addresses on their device arrive in the order +intended. The mmiob() macro is provided for this purpose. A typical use +of this macro might be immediately prior to the exit of a critical +section of code proteced by spinlocks. This would ensure that subsequent +writes to I/O space arrived only after all prior writes (much like a +typical memory barrier op, mb(), only with respect to I/O). diff -Nru a/Makefile b/Makefile --- a/Makefile Thu Aug 29 22:23:24 2002 +++ b/Makefile Thu Aug 29 22:23:24 2002 @@ -232,7 +232,7 @@ CPPFLAGS := -D__KERNEL__ -I$(objtree)/include -CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ +CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -g -O2 \ -fomit-frame-pointer -fno-strict-aliasing -fno-common AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS) diff -Nru a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c --- a/arch/i386/mm/fault.c Thu Aug 29 22:23:24 2002 +++ b/arch/i386/mm/fault.c Thu Aug 29 22:23:24 2002 @@ -28,8 +28,6 @@ extern void die(const char *,struct pt_regs *,long); -extern int console_loglevel; - /* * Ugly, ugly, but the goto's result in better assembly.. */ diff -Nru a/arch/ia64/Makefile b/arch/ia64/Makefile --- a/arch/ia64/Makefile Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/Makefile Thu Aug 29 22:23:24 2002 @@ -96,7 +96,8 @@ vmlinux: arch/$(ARCH)/vmlinux.lds.s -CPPFLAGS_arch/ia64/vmlinux.lds.s := -traditional +arch/$(ARCH)/vmlinux.lds.s: arch/$(ARCH)/vmlinux.lds.S + $(CPP) $(CPPFLAGS) $(CPPFLAGS_$@) -D__ASSEMBLY__ -P -C -U$(ARCH) $< -o $@ compressed: vmlinux $(OBJCOPY) $(OBJCOPYFLAGS) vmlinux vmlinux-tmp diff -Nru a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c --- a/arch/ia64/hp/common/sba_iommu.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/hp/common/sba_iommu.c Thu Aug 29 22:23:24 2002 @@ -30,11 +30,11 @@ #include #include #include +#include #include /* ia64_get_itc() */ #include #include /* PAGE_OFFSET */ -#include #define DRIVER_NAME "SBA" diff -Nru a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c --- a/arch/ia64/hp/sim/simeth.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/hp/sim/simeth.c Thu Aug 29 22:23:24 2002 @@ -213,7 +213,7 @@ memcpy(dev->dev_addr, mac_addr, sizeof(mac_addr)); - dev->irq = ia64_alloc_irq(); + dev->irq = ia64_alloc_vector(); /* * attach the interrupt in the simulator, this does enable interrupts diff -Nru a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c --- a/arch/ia64/hp/sim/simserial.c Thu Aug 29 22:23:25 2002 +++ b/arch/ia64/hp/sim/simserial.c Thu Aug 29 22:23:25 2002 @@ -1076,7 +1076,7 @@ if (state->type == PORT_UNKNOWN) continue; if (!state->irq) { - state->irq = ia64_alloc_irq(); + state->irq = ia64_alloc_vector(); ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); } diff -Nru a/arch/ia64/hp/zx1/hpzx1_misc.c b/arch/ia64/hp/zx1/hpzx1_misc.c --- a/arch/ia64/hp/zx1/hpzx1_misc.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/hp/zx1/hpzx1_misc.c Thu Aug 29 22:23:24 2002 @@ -12,9 +12,9 @@ #include #include #include +#include #include -#include #include extern acpi_status acpi_evaluate_integer (acpi_handle, acpi_string, acpi_object_list *, diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c --- a/arch/ia64/ia32/sys_ia32.c Thu Aug 29 22:23:25 2002 +++ b/arch/ia64/ia32/sys_ia32.c Thu Aug 29 22:23:25 2002 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c --- a/arch/ia64/kernel/acpi.c Thu Aug 29 22:23:25 2002 +++ b/arch/ia64/kernel/acpi.c Thu Aug 29 22:23:25 2002 @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include @@ -47,9 +47,9 @@ #define PREFIX "ACPI: " -asm (".weak iosapic_register_irq"); -asm (".weak iosapic_register_legacy_irq"); -asm (".weak iosapic_register_platform_irq"); +asm (".weak iosapic_register_intr"); +asm (".weak iosapic_override_isa_irq"); +asm (".weak iosapic_register_platform_intr"); asm (".weak iosapic_init"); asm (".weak iosapic_version"); @@ -173,10 +173,10 @@ #ifdef CONFIG_ACPI_BOOT -#define ACPI_MAX_PLATFORM_IRQS 256 +#define ACPI_MAX_PLATFORM_INTERRUPTS 256 /* Array to record platform interrupt vectors for generic interrupt routing. */ -int platform_irq_list[ACPI_MAX_PLATFORM_IRQS] = { [0 ... ACPI_MAX_PLATFORM_IRQS - 1] = -1 }; +int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = { [0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1 }; enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC; @@ -189,9 +189,9 @@ { int vector = -1; - if (int_type < ACPI_MAX_PLATFORM_IRQS) { + if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) { /* correctable platform error interrupt */ - vector = platform_irq_list[int_type]; + vector = platform_intr_list[int_type]; } else printk("acpi_request_vector(): invalid interrupt type\n"); return vector; @@ -210,6 +210,7 @@ static int total_cpus __initdata; static int available_cpus __initdata; struct acpi_table_madt * acpi_madt __initdata; +static u8 has_8259; static int __init @@ -284,7 +285,7 @@ static int __init -acpi_find_iosapic (int global_vector, u32 *irq_base, char **iosapic_address) +acpi_find_iosapic (unsigned int gsi, u32 *gsi_base, char **iosapic_address) { struct acpi_table_iosapic *iosapic; int ver; @@ -292,7 +293,7 @@ char *p; char *end; - if (!irq_base || !iosapic_address) + if (!gsi_base || !iosapic_address) return -ENODEV; p = (char *) (acpi_madt + 1); @@ -302,13 +303,13 @@ if (*p == ACPI_MADT_IOSAPIC) { iosapic = (struct acpi_table_iosapic *) p; - *irq_base = iosapic->global_irq_base; + *gsi_base = iosapic->global_irq_base; *iosapic_address = ioremap(iosapic->address, 0); ver = iosapic_version(*iosapic_address); max_pin = (ver >> 16) & 0xff; - if ((global_vector - *irq_base) <= max_pin) + if ((gsi - *gsi_base) <= max_pin) return 0; /* Found it! */ } p += p[1]; @@ -347,7 +348,7 @@ { struct acpi_table_plat_int_src *plintsrc; int vector; - u32 irq_base; + u32 gsi_base; char *iosapic_address; plintsrc = (struct acpi_table_plat_int_src *) header; @@ -356,31 +357,31 @@ acpi_table_print_madt_entry(header); - if (!iosapic_register_platform_irq) { - printk(KERN_WARNING PREFIX "No ACPI platform IRQ support\n"); + if (!iosapic_register_platform_intr) { + printk(KERN_WARNING PREFIX "No ACPI platform interrupt support\n"); return -ENODEV; } - if (acpi_find_iosapic(plintsrc->global_irq, &irq_base, &iosapic_address)) { + if (acpi_find_iosapic(plintsrc->global_irq, &gsi_base, &iosapic_address)) { printk(KERN_WARNING PREFIX "IOSAPIC not found\n"); return -ENODEV; } /* - * Get vector assignment for this IRQ, set attributes, and program the - * IOSAPIC routing table. + * Get vector assignment for this interrupt, set attributes, + * and program the IOSAPIC routing table. */ - vector = iosapic_register_platform_irq(plintsrc->type, - plintsrc->global_irq, - plintsrc->iosapic_vector, - plintsrc->eid, - plintsrc->id, - (plintsrc->flags.polarity == 1) ? 1 : 0, - (plintsrc->flags.trigger == 1) ? 1 : 0, - irq_base, - iosapic_address); + vector = iosapic_register_platform_intr(plintsrc->type, + plintsrc->global_irq, + plintsrc->iosapic_vector, + plintsrc->eid, + plintsrc->id, + (plintsrc->flags.polarity == 1) ? 1 : 0, + (plintsrc->flags.trigger == 1) ? 1 : 0, + gsi_base, + iosapic_address); - platform_irq_list[plintsrc->type] = vector; + platform_intr_list[plintsrc->type] = vector; return 0; } @@ -397,12 +398,12 @@ acpi_table_print_madt_entry(header); /* Ignore if the platform doesn't support overrides */ - if (!iosapic_register_legacy_irq) + if (!iosapic_override_isa_irq) return 0; - iosapic_register_legacy_irq(p->bus_irq, p->global_irq, - (p->flags.polarity == 1) ? 1 : 0, - (p->flags.trigger == 1) ? 1 : 0); + iosapic_override_isa_irq(p->bus_irq, p->global_irq, + (p->flags.polarity == 1) ? 1 : 0, + (p->flags.trigger == 1) ? 1 : 0); return 0; } @@ -431,6 +432,9 @@ acpi_madt = (struct acpi_table_madt *) __va(phys_addr); + /* remember the value for reference after free_initmem() */ + has_8259 = acpi_madt->flags.pcat_compat; + /* Get base address of IPI Message Block */ if (acpi_madt->lapic_address) @@ -440,11 +444,14 @@ return 0; } + static int __init acpi_parse_fadt (unsigned long phys_addr, unsigned long size) { struct acpi_table_header *fadt_header; fadt_descriptor_rev2 *fadt; + u32 sci_irq, gsi_base; + char *iosapic_address; if (!phys_addr || !size) return -EINVAL; @@ -458,9 +465,20 @@ if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER)) acpi_kbd_controller_present = 0; + if (!iosapic_register_intr) + return 0; /* just ignore the rest */ + + sci_irq = fadt->sci_int; + + if (has_8259 && sci_irq < 16) + return 0; /* legacy, no setup required */ + + if (!acpi_find_iosapic(sci_irq, &gsi_base, &iosapic_address)) + iosapic_register_intr(sci_irq, 0, 0, gsi_base, iosapic_address); return 0; } + unsigned long __init acpi_find_rsdp (void) { @@ -482,12 +500,12 @@ acpi_parse_spcr (unsigned long phys_addr, unsigned long size) { acpi_ser_t *spcr; - unsigned long global_int; + unsigned int gsi; if (!phys_addr || !size) return -EINVAL; - if (!iosapic_register_irq) + if (!iosapic_register_intr) return -ENODEV; /* @@ -500,6 +518,7 @@ */ spcr = (acpi_ser_t *) __va(phys_addr); + setup_serial_acpi(spcr); if (spcr->length < sizeof(acpi_ser_t)) @@ -509,22 +528,22 @@ if ((spcr->base_addr.space_id != ACPI_SERIAL_PCICONF_SPACE) && (spcr->int_type == ACPI_SERIAL_INT_SAPIC)) { - u32 irq_base; + u32 gsi_base; char *iosapic_address; int vector; /* We have a UART in memory space with an SAPIC interrupt */ - global_int = ((spcr->global_int[3] << 24) | - (spcr->global_int[2] << 16) | - (spcr->global_int[1] << 8) | - (spcr->global_int[0]) ); - - /* Which iosapic does this IRQ belong to? */ - - if (!acpi_find_iosapic(global_int, &irq_base, &iosapic_address)) - vector = iosapic_register_irq(global_int, 1, 1, - irq_base, iosapic_address); + gsi = ( (spcr->global_int[3] << 24) | + (spcr->global_int[2] << 16) | + (spcr->global_int[1] << 8) | + (spcr->global_int[0]) ); + + /* Which iosapic does this interrupt belong to? */ + + if (!acpi_find_iosapic(gsi, &gsi_base, &iosapic_address)) + vector = iosapic_register_intr(gsi, 1, 1, + gsi_base, iosapic_address); } return 0; } @@ -583,7 +602,12 @@ printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); skip_madt: - /* FADT says whether a legacy keyboard controller is present. */ + /* + * FADT says whether a legacy keyboard controller is present. + * The FADT also contains an SCI_INT line, by which the system + * gets interrupts such as power and sleep buttons. If it's not + * on a Legacy interrupt, it needs to be setup. + */ if (acpi_table_parse(ACPI_FACP, acpi_parse_fadt) < 1) printk(KERN_ERR PREFIX "Can't find FADT\n"); @@ -631,7 +655,7 @@ *count = 0; if (acpi_prt.count < 0) { - printk(KERN_ERR PREFIX "No PCI IRQ routing entries\n"); + printk(KERN_ERR PREFIX "No PCI interrupt routing entries\n"); return -ENODEV; } @@ -667,6 +691,15 @@ *type = ACPI_IRQ_MODEL_IOSAPIC; return 0; +} + +int +acpi_irq_to_vector (u32 irq) +{ + if (has_8259 && irq < 16) + return isa_irq_to_vector(irq); + + return gsi_to_vector(irq); } #endif /* CONFIG_ACPI_BOOT */ diff -Nru a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c --- a/arch/ia64/kernel/efi.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/kernel/efi.c Thu Aug 29 22:23:24 2002 @@ -24,8 +24,8 @@ #include #include #include +#include -#include #include #include #include diff -Nru a/arch/ia64/kernel/efivars.c b/arch/ia64/kernel/efivars.c --- a/arch/ia64/kernel/efivars.c Thu Aug 29 22:23:25 2002 +++ b/arch/ia64/kernel/efivars.c Thu Aug 29 22:23:25 2002 @@ -65,8 +65,8 @@ #include #include #include +#include -#include #include MODULE_AUTHOR("Matt Domsch "); diff -Nru a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S --- a/arch/ia64/kernel/entry.S Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/kernel/entry.S Thu Aug 29 22:23:24 2002 @@ -1229,11 +1229,11 @@ data8 ia64_ni_syscall // 1235 data8 ia64_ni_syscall data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall - data8 ia64_ni_syscall // 1240 - data8 ia64_ni_syscall - data8 ia64_ni_syscall + data8 sys_io_setup + data8 sys_io_destroy + data8 sys_io_getevents // 1240 + data8 sys_io_submit + data8 sys_io_cancel data8 ia64_ni_syscall data8 ia64_ni_syscall data8 ia64_ni_syscall // 1245 diff -Nru a/arch/ia64/kernel/fw-emu.c b/arch/ia64/kernel/fw-emu.c --- a/arch/ia64/kernel/fw-emu.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/kernel/fw-emu.c Thu Aug 29 22:23:24 2002 @@ -13,7 +13,7 @@ # include #endif -#include +#include #include #include #include diff -Nru a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c --- a/arch/ia64/kernel/ia64_ksyms.c Thu Aug 29 22:23:25 2002 +++ b/arch/ia64/kernel/ia64_ksyms.c Thu Aug 29 22:23:25 2002 @@ -58,7 +58,7 @@ #include # ifndef CONFIG_NUMA -EXPORT_SYMBOL(cpu_info); +EXPORT_SYMBOL(cpu_info__per_cpu); # endif EXPORT_SYMBOL(kernel_thread); diff -Nru a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c --- a/arch/ia64/kernel/iosapic.c Thu Aug 29 22:23:25 2002 +++ b/arch/ia64/kernel/iosapic.c Thu Aug 29 22:23:25 2002 @@ -26,9 +26,12 @@ * 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/29 T. Kochi Allocate interrupt vectors dynamically + * 02/08/04 T. Kochi Cleaned up terminology (irq, global system interrupt, vector, + * etc.) */ /* - * Here is what the interrupt logic between a PCI device and the CPU looks like: + * Here is what the interrupt logic between a PCI device and the kernel 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 @@ -37,19 +40,28 @@ * * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC controller. * Multiple interrupt lines may have to share the same IOSAPIC pin (if they're level - * triggered and use the same polarity). Each interrupt line has a unique IOSAPIC - * irq number which can be calculated as the sum of the controller's base irq number - * and the IOSAPIC pin number to which the line connects. + * triggered and use the same polarity). Each interrupt line has a unique Global + * System Interrupt (GSI) number which can be calculated as the sum of the controller's + * base GSI number and the IOSAPIC pin number to which the line connects. * - * (3) The IOSAPIC uses an internal table to map the IOSAPIC pin into the IA-64 interrupt - * vector. This interrupt vector is then sent to the CPU. + * (3) The IOSAPIC uses an internal routing table entries (RTEs) to map the IOSAPIC pin + * into the IA-64 interrupt vector. This interrupt vector is then sent to the CPU. * - * In other words, there are two levels of indirections involved: + * (4) The kernel recognizes an interrupt as an IRQ. The IRQ interface is used as + * architecture-independent interrupt handling mechanism in Linux. As an + * IRQ is a number, we have to have IA-64 interrupt vector number <-> IRQ number + * mapping. On smaller systems, we use one-to-one mapping between IA-64 vector and + * IRQ. A platform can implemnent platform_irq_to_vector(irq) and + * platform_local_vector_to_irq(vector) APIs to differentiate the mapping. + * Please see also include/asm-ia64/hw_irq.h for those APIs. * - * pci pin -> iosapic irq -> IA-64 vector + * To sum up, there are three levels of mappings involved: * - * Note: outside this module, IA-64 vectors are called "irqs". This is because that's - * the traditional name Linux uses for interrupt vectors. + * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ + * + * Note: The term "IRQ" is loosely used everywhere in Linux kernel to describe interrupts. + * Now we use "IRQ" only for Linux IRQ's. ISA IRQ (isa_irq) is the only exception in this + * source code. */ #include @@ -72,49 +84,55 @@ #include -#undef DEBUG_IRQ_ROUTING +#undef DEBUG_INTERRUPT_ROUTING #undef OVERRIDE_DEBUG +#ifdef DEBUG_INTERRUPT_ROUTING +#define DBG(fmt...) printk(fmt) +#else +#define DBG(fmt...) +#endif + static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED; -/* PCI pin to IOSAPIC irq routing information. This info typically comes from ACPI. */ +/* PCI pin to GSI routing information. This info typically comes from ACPI. */ static struct { int num_routes; struct pci_vector_struct *route; } pci_irq; -/* This tables maps IA-64 vectors to the IOSAPIC pin that generates this vector. */ +/* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */ -static struct iosapic_irq { - char *addr; /* base address of IOSAPIC */ - unsigned int base_irq; /* first irq assigned to this IOSAPIC */ - char pin; /* IOSAPIC pin (-1 => not an IOSAPIC irq) */ - unsigned char dmode : 3; /* delivery mode (see iosapic.h) */ - unsigned char polarity : 1; /* interrupt polarity (see iosapic.h) */ - unsigned char trigger : 1; /* trigger mode (see iosapic.h) */ -} iosapic_irq[IA64_NUM_VECTORS]; +static struct iosapic_intr_info { + char *addr; /* base address of IOSAPIC */ + unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ + char rte_index; /* IOSAPIC RTE index (-1 => not an IOSAPIC interrupt) */ + unsigned char dmode : 3; /* delivery mode (see iosapic.h) */ + unsigned char polarity: 1; /* interrupt polarity (see iosapic.h) */ + unsigned char trigger : 1; /* trigger mode (see iosapic.h) */ +} iosapic_intr_info[IA64_NUM_VECTORS]; static struct iosapic { - char *addr; /* base address of IOSAPIC */ - unsigned int base_irq; /* first irq assigned to this IOSAPIC */ - unsigned short max_pin; /* max input pin supported in this IOSAPIC */ + char *addr; /* base address of IOSAPIC */ + unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ + unsigned short num_rte; /* number of RTE in this IOSAPIC */ unsigned char pcat_compat; /* 8259 compatibility flag */ -} iosapic_lists[256] __initdata; +} iosapic_lists[256] __devinitdata; static int num_iosapic = 0; /* - * Find an IOSAPIC associated with an IRQ + * Find an IOSAPIC associated with a GSI */ -static inline int __init -find_iosapic (unsigned int irq) +static inline int __devinit +find_iosapic (unsigned int gsi) { int i; for (i = 0; i < num_iosapic; i++) { - if ((unsigned) (irq - iosapic_lists[i].base_irq) <= iosapic_lists[i].max_pin) + if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) return i; } @@ -122,60 +140,51 @@ } /* - * Translate IOSAPIC irq number to the corresponding IA-64 interrupt vector. If no + * Translate GSI number to the corresponding IA-64 interrupt vector. If no * entry exists, return -1. */ -static int -iosapic_irq_to_vector (int irq) +int +gsi_to_vector (unsigned int gsi) { int vector; for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) - if (iosapic_irq[vector].base_irq + iosapic_irq[vector].pin == irq) + if (iosapic_intr_info[vector].gsi_base + iosapic_intr_info[vector].rte_index == gsi) return vector; return -1; } -/* - * Map PCI pin to the corresponding IA-64 interrupt vector. If no such mapping exists, - * return -1. - */ -int -pci_pin_to_vector (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) - return iosapic_irq_to_vector(r->irq); - return -1; -} - static void -set_rte (unsigned int vector, unsigned long dest) +set_rte (unsigned int vector, unsigned int dest) { unsigned long pol, trigger, dmode; u32 low32, high32; char *addr; - int pin; + int rte_index; char redir; -#ifdef DEBUG_IRQ_ROUTING - printk(KERN_DEBUG "set_rte: routing vector 0x%02x to 0x%lx\n", vector, dest); -#endif + DBG(KERN_DEBUG "%s: routing vector %d to %x\n", __FUNCTION__, vector, dest); - pin = iosapic_irq[vector].pin; - if (pin < 0) + rte_index = iosapic_intr_info[vector].rte_index; + if (rte_index < 0) return; /* not an IOSAPIC interrupt */ - addr = iosapic_irq[vector].addr; - pol = iosapic_irq[vector].polarity; - trigger = iosapic_irq[vector].trigger; - dmode = iosapic_irq[vector].dmode; + addr = iosapic_intr_info[vector].addr; + pol = iosapic_intr_info[vector].polarity; + trigger = iosapic_intr_info[vector].trigger; + dmode = iosapic_intr_info[vector].dmode; redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0; #ifdef CONFIG_SMP - set_irq_affinity_info(vector, (int)(dest & 0xffff), redir); + { + unsigned int irq; + + for (irq = 0; irq < NR_IRQS; ++irq) + if (irq_to_vector(irq) == vector) { + set_irq_affinity_info(irq, (int)(dest & 0xffff), redir); + break; + } + } #endif low32 = ((pol << IOSAPIC_POLARITY_SHIFT) | @@ -186,9 +195,9 @@ /* dest contains both id and eid */ high32 = (dest << IOSAPIC_DEST_SHIFT); - writel(IOSAPIC_RTE_HIGH(pin), addr + IOSAPIC_REG_SELECT); + writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT); writel(high32, addr + IOSAPIC_WINDOW); - writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT); + writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); writel(low32, addr + IOSAPIC_WINDOW); } @@ -204,18 +213,18 @@ unsigned long flags; char *addr; u32 low32; - int pin; + int rte_index; ia64_vector vec = irq_to_vector(irq); - addr = iosapic_irq[vec].addr; - pin = iosapic_irq[vec].pin; + addr = iosapic_intr_info[vec].addr; + rte_index = iosapic_intr_info[vec].rte_index; - if (pin < 0) + if (rte_index < 0) return; /* not an IOSAPIC interrupt! */ spin_lock_irqsave(&iosapic_lock, flags); { - writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT); + writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); low32 = readl(addr + IOSAPIC_WINDOW); low32 |= (1 << IOSAPIC_MASK_SHIFT); /* set only the mask bit */ @@ -230,17 +239,17 @@ unsigned long flags; char *addr; u32 low32; - int pin; + int rte_index; ia64_vector vec = irq_to_vector(irq); - addr = iosapic_irq[vec].addr; - pin = iosapic_irq[vec].pin; - if (pin < 0) + addr = iosapic_intr_info[vec].addr; + rte_index = iosapic_intr_info[vec].rte_index; + if (rte_index < 0) return; /* not an IOSAPIC interrupt! */ spin_lock_irqsave(&iosapic_lock, flags); { - writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT); + writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); low32 = readl(addr + IOSAPIC_WINDOW); low32 &= ~(1 << IOSAPIC_MASK_SHIFT); /* clear only the mask bit */ @@ -256,24 +265,28 @@ #ifdef CONFIG_SMP unsigned long flags; u32 high32, low32; - int dest, pin; + int dest, rte_index; char *addr; - int redir = (irq & (1<<31)) ? 1 : 0; + int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0; + ia64_vector vec; + + irq &= (~IA64_IRQ_REDIRECTED); + vec = irq_to_vector(irq); mask &= cpu_online_map; - if (!mask || irq >= IA64_NUM_VECTORS) + if (!mask || vec >= IA64_NUM_VECTORS) return; dest = cpu_physical_id(ffz(~mask)); - pin = iosapic_irq[irq].pin; - addr = iosapic_irq[irq].addr; + rte_index = iosapic_intr_info[vec].rte_index; + addr = iosapic_intr_info[vec].addr; - if (pin < 0) + if (rte_index < 0) return; /* not an IOSAPIC interrupt */ - set_irq_affinity_info(irq,dest,redir); + set_irq_affinity_info(irq, dest, redir); /* dest contains both id and eid */ high32 = dest << IOSAPIC_DEST_SHIFT; @@ -281,7 +294,7 @@ spin_lock_irqsave(&iosapic_lock, flags); { /* get current delivery mode by reading the low32 */ - writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT); + writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); low32 = readl(addr + IOSAPIC_WINDOW); low32 &= ~(7 << IOSAPIC_DELIVERY_SHIFT); @@ -292,9 +305,9 @@ /* change delivery mode to fixed */ low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); - writel(IOSAPIC_RTE_HIGH(pin), addr + IOSAPIC_REG_SELECT); + writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT); writel(high32, addr + IOSAPIC_WINDOW); - writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT); + writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); writel(low32, addr + IOSAPIC_WINDOW); } spin_unlock_irqrestore(&iosapic_lock, flags); @@ -317,7 +330,7 @@ { ia64_vector vec = irq_to_vector(irq); - writel(vec, iosapic_irq[vec].addr + IOSAPIC_EOI); + writel(vec, iosapic_intr_info[vec].addr + IOSAPIC_EOI); } #define iosapic_shutdown_level_irq mask_irq @@ -388,7 +401,7 @@ * { * unsigned int version : 8; * unsigned int reserved1 : 8; - * unsigned int pins : 8; + * unsigned int max_redir : 8; * unsigned int reserved2 : 8; * } */ @@ -405,70 +418,72 @@ { int new_vector; - if (iosapic_irq[vector].pin >= 0 || iosapic_irq[vector].addr - || iosapic_irq[vector].base_irq || iosapic_irq[vector].dmode - || iosapic_irq[vector].polarity || iosapic_irq[vector].trigger) + if (iosapic_intr_info[vector].rte_index >= 0 || iosapic_intr_info[vector].addr + || iosapic_intr_info[vector].gsi_base || iosapic_intr_info[vector].dmode + || iosapic_intr_info[vector].polarity || iosapic_intr_info[vector].trigger) { - new_vector = ia64_alloc_irq(); - printk("Reassigning vector 0x%x to 0x%x\n", vector, new_vector); - memcpy (&iosapic_irq[new_vector], &iosapic_irq[vector], - sizeof(struct iosapic_irq)); - memset (&iosapic_irq[vector], 0, sizeof(struct iosapic_irq)); - iosapic_irq[vector].pin = -1; + new_vector = ia64_alloc_vector(); + printk("Reassigning vector %d to %d\n", vector, new_vector); + memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], + sizeof(struct iosapic_intr_info)); + memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); + iosapic_intr_info[vector].rte_index = -1; } } static void -register_irq (u32 global_vector, int vector, int pin, unsigned char delivery, - unsigned long polarity, unsigned long edge_triggered, - u32 base_irq, char *iosapic_address) +register_intr (unsigned int gsi, int vector, unsigned char delivery, + unsigned long polarity, unsigned long edge_triggered, + unsigned int gsi_base, char *iosapic_address) { irq_desc_t *idesc; struct hw_interrupt_type *irq_type; + int rte_index; - 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; + rte_index = gsi - gsi_base; + iosapic_intr_info[vector].rte_index = rte_index; + iosapic_intr_info[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW; + iosapic_intr_info[vector].dmode = delivery; /* - * In override, it does not provide addr/base_irq. global_vector is enough to - * locate iosapic addr, base_irq and pin by examining base_irq and max_pin of - * registered iosapics (tbd) + * In override, it may not provide addr/gsi_base. GSI is enough to + * locate iosapic addr, gsi_base and rte_index by examining + * gsi_base and num_rte of registered iosapics (tbd) */ #ifndef OVERRIDE_DEBUG if (iosapic_address) { - iosapic_irq[vector].addr = iosapic_address; - iosapic_irq[vector].base_irq = base_irq; + iosapic_intr_info[vector].addr = iosapic_address; + iosapic_intr_info[vector].gsi_base = gsi_base; } #else if (iosapic_address) { - if (iosapic_irq[vector].addr && (iosapic_irq[vector].addr != iosapic_address)) - printk("WARN: register_irq: diff IOSAPIC ADDRESS for gv %x, v %x\n", - global_vector, vector); - iosapic_irq[vector].addr = iosapic_address; - if (iosapic_irq[vector].base_irq && (iosapic_irq[vector].base_irq != base_irq)) { - printk("WARN: register_irq: diff BASE IRQ %x for gv %x, v %x\n", - base_irq, global_vector, vector); + if (iosapic_intr_info[vector].addr && (iosapic_intr_info[vector].addr != iosapic_address)) + printk("WARN: register_intr: diff IOSAPIC ADDRESS for GSI 0x%x, vector %d\n", + gsi, vector); + iosapic_intr_info[vector].addr = iosapic_address; + if (iosapic_intr_info[vector].gsi_base && (iosapic_intr_info[vector].gsi_base != gsi_base)) { + printk("WARN: register_intr: diff GSI base 0x%x for GSI 0x%x, vector %d\n", + gsi_base, gsi, vector); } - iosapic_irq[vector].base_irq = base_irq; - } else if (!iosapic_irq[vector].addr) - printk("WARN: register_irq: invalid override for gv %x, v %x\n", - global_vector, vector); + iosapic_intr_info[vector].gsi_base = gsi_base; + } else if (!iosapic_intr_info[vector].addr) + printk("WARN: register_intr: invalid override for GSI 0x%x, vector %d\n", + gsi, vector); #endif if (edge_triggered) { - iosapic_irq[vector].trigger = IOSAPIC_EDGE; + iosapic_intr_info[vector].trigger = IOSAPIC_EDGE; irq_type = &irq_type_iosapic_edge; } else { - iosapic_irq[vector].trigger = IOSAPIC_LEVEL; + iosapic_intr_info[vector].trigger = IOSAPIC_LEVEL; irq_type = &irq_type_iosapic_level; } idesc = irq_desc(vector); if (idesc->handler != irq_type) { if (idesc->handler != &no_irq_type) - printk("register_irq(): changing vector 0x%02x from " - "%s to %s\n", vector, idesc->handler->typename, irq_type->typename); + printk("%s: changing vector %d from %s to %s\n", + __FUNCTION__, vector, idesc->handler->typename, + irq_type->typename); idesc->handler = irq_type; } } @@ -479,24 +494,26 @@ * program the IOSAPIC RTE. */ int -iosapic_register_irq (u32 global_vector, unsigned long polarity, unsigned long - edge_triggered, u32 base_irq, char *iosapic_address) +iosapic_register_intr (unsigned int gsi, + unsigned long polarity, unsigned long edge_triggered, + unsigned int gsi_base, char *iosapic_address) { int vector; + unsigned int dest = (ia64_get_lid() >> 16) & 0xffff; - vector = iosapic_irq_to_vector(global_vector); + vector = gsi_to_vector(gsi); if (vector < 0) - vector = ia64_alloc_irq(); + vector = ia64_alloc_vector(); - register_irq (global_vector, vector, global_vector - base_irq, - IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered, - base_irq, iosapic_address); + register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, + polarity, edge_triggered, gsi_base, iosapic_address); - printk("IOSAPIC 0x%x(%s,%s) -> Vector 0x%x\n", global_vector, - (polarity ? "high" : "low"), (edge_triggered ? "edge" : "level"), vector); + printk("GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", + gsi, (polarity ? "high" : "low"), + (edge_triggered ? "edge" : "level"), dest, vector); /* program the IOSAPIC routing table */ - set_rte(vector, (ia64_get_lid() >> 16) & 0xffff); + set_rte(vector, dest); return vector; } @@ -505,12 +522,14 @@ * Note that the irq_base and IOSAPIC address must be set in iosapic_init(). */ int -iosapic_register_platform_irq (u32 int_type, u32 global_vector, - u32 iosapic_vector, u16 eid, u16 id, unsigned long polarity, - unsigned long edge_triggered, u32 base_irq, char *iosapic_address) +iosapic_register_platform_intr (u32 int_type, unsigned int gsi, + int iosapic_vector, u16 eid, u16 id, + unsigned long polarity, unsigned long edge_triggered, + unsigned int gsi_base, char *iosapic_address) { unsigned char delivery; int vector; + unsigned int dest = ((id << 8) | eid) & 0xffff; switch (int_type) { case ACPI_INTERRUPT_PMI: @@ -523,7 +542,7 @@ delivery = IOSAPIC_PMI; break; case ACPI_INTERRUPT_INIT: - vector = ia64_alloc_irq(); + vector = ia64_alloc_vector(); delivery = IOSAPIC_INIT; break; case ACPI_INTERRUPT_CPEI: @@ -535,56 +554,137 @@ return -1; } - register_irq(global_vector, vector, global_vector - base_irq, delivery, polarity, - edge_triggered, base_irq, iosapic_address); + register_intr(gsi, vector, delivery, polarity, + edge_triggered, gsi_base, iosapic_address); - printk("PLATFORM int 0x%x: IOSAPIC 0x%x(%s,%s) -> Vector 0x%x CPU %.02u:%.02u\n", - int_type, global_vector, (polarity ? "high" : "low"), - (edge_triggered ? "edge" : "level"), vector, eid, id); + printk("PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", + int_type, gsi, (polarity ? "high" : "low"), + (edge_triggered ? "edge" : "level"), dest, vector); /* program the IOSAPIC routing table */ - set_rte(vector, ((id << 8) | eid) & 0xffff); + set_rte(vector, dest); return vector; } /* - * ACPI calls this when it finds an entry for a legacy ISA interrupt. - * Note that the irq_base and IOSAPIC address must be set in iosapic_init(). + * ACPI calls this when it finds an entry for a legacy ISA IRQ override. + * Note that the gsi_base and IOSAPIC address must be set in iosapic_init(). */ void -iosapic_register_legacy_irq (unsigned long irq, - unsigned long pin, unsigned long polarity, - unsigned long edge_triggered) -{ - int vector = isa_irq_to_vector(irq); - - register_irq(irq, vector, (int)pin, IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered, - 0, NULL); /* ignored for override */ - -#ifdef DEBUG_IRQ_ROUTING - printk("ISA: IRQ %u -> IOSAPIC irq 0x%02x (%s, %s) -> vector %02x\n", - (unsigned) irq, (unsigned) pin, - polarity ? "high" : "low", edge_triggered ? "edge" : "level", - vector); -#endif +iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, + unsigned long polarity, + unsigned long edge_triggered) +{ + int index, vector; + unsigned int gsi_base; + char *addr; + unsigned int dest = (ia64_get_lid() >> 16) & 0xffff; + + index = find_iosapic(gsi); + + if (index < 0) { + printk("ISA: No corresponding IOSAPIC found : ISA IRQ %u -> GSI 0x%x\n", isa_irq, gsi); + return; + } + + vector = isa_irq_to_vector(isa_irq); + addr = iosapic_lists[index].addr; + gsi_base = iosapic_lists[index].gsi_base; + + register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered, + gsi_base, addr); + + DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n", + isa_irq, gsi, + polarity ? "high" : "low", edge_triggered ? "edge" : "level", + dest, vector); /* program the IOSAPIC routing table */ - set_rte(vector, (ia64_get_lid() >> 16) & 0xffff); + set_rte(vector, dest); +} + +/* + * Map PCI pin to the corresponding GSI. + * If no such mapping exists, return -1. + */ +static int +pci_pin_to_gsi (int bus, int slot, int pci_pin, unsigned int *gsi) +{ + 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) { + *gsi = r->irq; + return 0; + } + + return -1; +} + +/* + * Map PCI pin to the corresponding IA-64 interrupt vector. If no such mapping exists, + * try to allocate a new vector. If it fails, return -1. + */ +static int +pci_pin_to_vector (int bus, int slot, int pci_pin) +{ + int index, vector; + int gsi_base, pcat_compat; + char *addr; + unsigned int gsi; + + if (pci_pin_to_gsi(bus, slot, pci_pin, &gsi) < 0) { + printk("PCI: no interrupt route for %02x:%02x pin %c\n", bus, slot, 'A' + pci_pin); + return -1; + } + + vector = gsi_to_vector(gsi); + + if (vector < 0) { + /* we should allocate a vector for this interrupt line */ + + index = find_iosapic(gsi); + + if (index < 0) { + printk("PCI: GSI 0x%x has no IOSAPIC mapping\n", gsi); + return -1; + } + + addr = iosapic_lists[index].addr; + gsi_base = iosapic_lists[index].gsi_base; + pcat_compat = iosapic_lists[index].pcat_compat; + + if (pcat_compat && (gsi < 16)) + vector = isa_irq_to_vector(gsi); + else { + /* new GSI; allocate a vector for it */ + vector = ia64_alloc_vector(); + } + + register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, + 0, 0, gsi_base, addr); + + DBG("PCI: (%02x:%02x INT%c) -> GSI 0x%x -> vector %d\n", + bus, slot, 'A' + pci_pin, gsi, vector); + } + + return vector; } -void __init -iosapic_init (unsigned long phys_addr, unsigned int base_irq, int pcat_compat) +void __devinit +iosapic_init (unsigned long phys_addr, unsigned int gsi_base, int pcat_compat) { - int irq, max_pin, vector, pin; - unsigned int ver; + int num_rte, vector; + unsigned int isa_irq, ver; char *addr; static int first_time = 1; if (first_time) { first_time = 0; for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) - iosapic_irq[vector].pin = -1; /* mark as unused */ + iosapic_intr_info[vector].rte_index = -1; /* mark as unused */ } if (pcat_compat) { @@ -599,109 +699,148 @@ addr = ioremap(phys_addr, 0); ver = iosapic_version(addr); - max_pin = (ver >> 16) & 0xff; + + /* + * The MAX_REDIR register holds the highest input pin + * number (starting from 0). + * We add 1 so that we can use it for number of pins (= RTEs) + */ + num_rte = ((ver >> 16) & 0xff) + 1; iosapic_lists[num_iosapic].addr = addr; iosapic_lists[num_iosapic].pcat_compat = pcat_compat; - iosapic_lists[num_iosapic].base_irq = base_irq; - iosapic_lists[num_iosapic].max_pin = max_pin; + iosapic_lists[num_iosapic].gsi_base = gsi_base; + iosapic_lists[num_iosapic].num_rte = num_rte; num_iosapic++; - printk("IOSAPIC: version %x.%x, address 0x%lx, IRQs 0x%02x-0x%02x\n", - (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, base_irq, base_irq + max_pin); + printk("IOSAPIC: version %x.%x, address 0x%lx, GSIs 0x%x-0x%x\n", + (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, gsi_base, gsi_base + num_rte - 1); + + if ((gsi_base == 0) && pcat_compat) { + unsigned int dest = (ia64_get_lid() >> 16) & 0xffff; - if ((base_irq == 0) && pcat_compat) { /* * Map the legacy ISA devices into the IOSAPIC data. Some of these may * get reprogrammed later on with data from the ACPI Interrupt Source * Override table. */ - for (irq = 0; irq < 16; ++irq) { - vector = isa_irq_to_vector(irq); - if ((pin = iosapic_irq[vector].pin) == -1) - pin = irq; + for (isa_irq = 0; isa_irq < 16; ++isa_irq) { + vector = isa_irq_to_vector(isa_irq); - register_irq(irq, vector, pin, + register_intr(isa_irq, vector, IOSAPIC_LOWEST_PRIORITY, /* IOSAPIC_POL_HIGH, IOSAPIC_EDGE */ - IOSAPIC_LOWEST_PRIORITY, 1, 1, base_irq, addr); + 1, 1, gsi_base, addr); -#ifdef DEBUG_IRQ_ROUTING - printk("ISA: IRQ %u -> IOSAPIC irq 0x%02x (high, edge) -> vector 0x%02x\n", - irq, iosapic_irq[vector].base_irq + iosapic_irq[vector].pin, - vector); -#endif + DBG("ISA: IRQ %u -> GSI 0x%x (high,edge) -> CPU 0x%04x vector %d\n", + isa_irq, isa_irq, dest, vector); /* program the IOSAPIC routing table: */ - set_rte(vector, (ia64_get_lid() >> 16) & 0xffff); + set_rte(vector, dest); } } } -static void __init -iosapic_init_pci_irq (void) -{ - int i, index, vector, pin; - int base_irq, max_pin, pcat_compat; - unsigned int irq; - char *addr; - - if (acpi_get_prt(&pci_irq.route, &pci_irq.num_routes)) - return; - - for (i = 0; i < pci_irq.num_routes; i++) { - irq = pci_irq.route[i].irq; +/* + * Set allocated interrupt vector to dev->irq and + * program IOSAPIC to deliver interrupts + */ +void +iosapic_fixup_pci_interrupt (struct pci_dev *dev) +{ + unsigned char pci_pin; + int vector; + unsigned int dest; + struct hw_interrupt_type *irq_type; + irq_desc_t *idesc; - index = find_iosapic(irq); - if (index < 0) { - printk("PCI: IRQ %u has no IOSAPIC mapping\n", irq); - continue; + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pci_pin); + if (pci_pin) { + pci_pin--; /* interrupt pins are numberd starting from 1 */ + + vector = pci_pin_to_vector(dev->bus->number, PCI_SLOT(dev->devfn), pci_pin); + + if (vector < 0 && dev->bus->parent) { + /* go back to the bridge */ + struct pci_dev *bridge = dev->bus->self; + + if (bridge) { + /* allow for multiple bridges on an adapter */ + do { + /* do the bridge swizzle... */ + pci_pin = (pci_pin + PCI_SLOT(dev->devfn)) % 4; + vector = pci_pin_to_vector(bridge->bus->number, + PCI_SLOT(bridge->devfn), + pci_pin); + } while (vector < 0 && (bridge = bridge->bus->self)); + } + if (vector >= 0) + printk(KERN_WARNING + "PCI: using PPB (%s INT%c) to get vector %d\n", + dev->slot_name, 'A' + pci_pin, + vector); + else + printk(KERN_WARNING + "PCI: Couldn't map irq for (%s INT%c)\n", + dev->slot_name, 'A' + pci_pin); } - addr = iosapic_lists[index].addr; - base_irq = iosapic_lists[index].base_irq; - max_pin = iosapic_lists[index].max_pin; - pcat_compat = iosapic_lists[index].pcat_compat; - pin = irq - base_irq; - - if ((unsigned) pin > max_pin) - /* the interrupt route is for another controller... */ - continue; + if (vector >= 0) { + dev->irq = vector; - if (pcat_compat && (irq < 16)) - vector = isa_irq_to_vector(irq); - else { - vector = iosapic_irq_to_vector(irq); - if (vector < 0) - /* new iosapic irq: allocate a vector for it */ - vector = ia64_alloc_irq(); - } - - register_irq(irq, vector, pin, IOSAPIC_LOWEST_PRIORITY, 0, 0, base_irq, addr); + irq_type = &irq_type_iosapic_level; + idesc = irq_desc(vector); + if (idesc->handler != irq_type) { + if (idesc->handler != &no_irq_type) + printk("%s: changing vector %d from %s to %s\n", + __FUNCTION__, vector, + idesc->handler->typename, + irq_type->typename); + idesc->handler = irq_type; + } +#ifdef CONFIG_SMP + /* + * For platforms that do not support interrupt redirect + * via the XTP interface, we can round-robin the PCI + * device interrupts to the processors + */ + if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) { + static int cpu_index = 0; + + while (!cpu_online(cpu_index)) + if (++cpu_index >= NR_CPUS) + cpu_index = 0; -#ifdef DEBUG_IRQ_ROUTING - printk("PCI: (B%d,I%d,P%d) -> IOSAPIC irq 0x%02x -> vector 0x%02x\n", - pci_irq.route[i].bus, pci_irq.route[i].pci_id>>16, pci_irq.route[i].pin, - iosapic_irq[vector].base_irq + iosapic_irq[vector].pin, vector); + dest = cpu_physical_id(cpu_index) & 0xffff; + } else { + /* + * Direct the interrupt vector to the current cpu, + * platform redirection will distribute them. + */ + dest = (ia64_get_lid() >> 16) & 0xffff; + } +#else + /* direct the interrupt vector to the running cpu id */ + dest = (ia64_get_lid() >> 16) & 0xffff; #endif - /* - * NOTE: The IOSAPIC RTE will be programmed in iosapic_pci_fixup(). It - * needs to be done there to ensure PCI hotplug works right. - */ + + printk("PCI->APIC IRQ transform: (%s INT%c) -> CPU 0x%04x vector %d\n", + dev->slot_name, 'A' + pci_pin, dest, vector); + set_rte(vector, dest); + } } } + void iosapic_pci_fixup (int phase) { struct pci_dev *dev; - unsigned char pin; - int vector; - struct hw_interrupt_type *irq_type; - irq_desc_t *idesc; if (phase == 0) { - iosapic_init_pci_irq(); + if (acpi_get_prt(&pci_irq.route, &pci_irq.num_routes)) { + printk("%s: acpi_get_prt failed\n", __FILE__); + } return; } @@ -709,76 +848,9 @@ return; pci_for_each_dev(dev) { - 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); - if (vector < 0 && dev->bus->parent) { - /* go back to the bridge */ - struct pci_dev *bridge = dev->bus->self; - - if (bridge) { - /* allow for multiple bridges on an adapter */ - do { - /* do the bridge swizzle... */ - pin = (pin + PCI_SLOT(dev->devfn)) % 4; - vector = pci_pin_to_vector(bridge->bus->number, - PCI_SLOT(bridge->devfn), - pin); - } while (vector < 0 && (bridge = bridge->bus->self)); - } - if (vector >= 0) - printk(KERN_WARNING - "PCI: using PPB(B%d,I%d,P%d) to get vector %02x\n", - dev->bus->number, PCI_SLOT(dev->devfn), - pin, vector); - else - printk(KERN_WARNING - "PCI: Couldn't map irq for (B%d,I%d,P%d)\n", - dev->bus->number, PCI_SLOT(dev->devfn), pin); - } - if (vector >= 0) { - printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> 0x%02x\n", - dev->bus->number, PCI_SLOT(dev->devfn), pin, vector); - dev->irq = vector; - - irq_type = &irq_type_iosapic_level; - idesc = irq_desc(vector); - if (idesc->handler != irq_type) { - if (idesc->handler != &no_irq_type) - printk("iosapic_pci_fixup: changing vector 0x%02x " - "from %s to %s\n", vector, - idesc->handler->typename, - irq_type->typename); - idesc->handler = irq_type; - } -#ifdef CONFIG_SMP - /* - * For platforms that do not support interrupt redirect - * via the XTP interface, we can round-robin the PCI - * device interrupts to the processors - */ - if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) { - static int cpu_index = 0; + /* fixup dev->irq and program IOSAPIC */ + iosapic_fixup_pci_interrupt(dev); - while (!cpu_online(cpu_index)) - if (++cpu_index >= NR_CPUS) - cpu_index = 0; - - set_rte(vector, cpu_physical_id(cpu_index) & 0xffff); - } else { - /* - * Direct the interrupt vector to the current cpu, - * platform redirection will distribute them. - */ - set_rte(vector, (ia64_get_lid() >> 16) & 0xffff); - } -#else - /* direct the interrupt vector to the running cpu id */ - set_rte(vector, (ia64_get_lid() >> 16) & 0xffff); -#endif - } - } /* * Nothing to fixup * Fix out-of-range IRQ numbers diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c --- a/arch/ia64/kernel/irq.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/kernel/irq.c Thu Aug 29 22:23:24 2002 @@ -802,8 +802,7 @@ #define HEX_DIGITS 8 -static unsigned int parse_hex_value (const char *buffer, - unsigned long count, unsigned long *ret) +static int parse_hex_value (const char *buffer, unsigned long count, unsigned long *ret) { unsigned char hexnum [HEX_DIGITS]; unsigned long value; @@ -846,11 +845,11 @@ static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 }; -void set_irq_affinity_info(int irq, int hwid, int redir) +void set_irq_affinity_info (unsigned int irq, int hwid, int redir) { unsigned long mask = 1UL<= 0 && irq < NR_IRQS) { + if (irq < NR_IRQS) { irq_affinity[irq] = mask; irq_redir[irq] = (char) (redir & 0xff); } @@ -861,14 +860,15 @@ { if (count < HEX_DIGITS+3) return -EINVAL; - return sprintf (page, "%s%08lx\n", irq_redir[(long)data] ? "r " : "", - irq_affinity[(long)data]); + return sprintf (page, "%s%08lx\n", irq_redir[(unsigned long)data] ? "r " : "", + irq_affinity[(unsigned long)data]); } static int irq_affinity_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - int irq = (long) data, full_count = count, err; + unsigned int irq = (unsigned long) data; + int full_count = count, err; unsigned long new_value; const char *buf = buffer; int redir; @@ -884,6 +884,8 @@ redir = 0; err = parse_hex_value(buf, count, &new_value); + if (err) + return err; /* * Do not allow disabling IRQs completely - it's a too easy @@ -893,7 +895,7 @@ if (!(new_value & cpu_online_map)) return -EINVAL; - irq_desc(irq)->handler->set_affinity(irq | (redir?(1<<31):0), new_value); + irq_desc(irq)->handler->set_affinity(irq | (redir? IA64_IRQ_REDIRECTED : 0), new_value); return full_count; } @@ -912,7 +914,8 @@ static int prof_cpu_mask_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - unsigned long *mask = (unsigned long *) data, full_count = count, err; + unsigned long *mask = (unsigned long *) data; + int full_count = count, err; unsigned long new_value; err = parse_hex_value(buffer, count, &new_value); @@ -946,7 +949,7 @@ if (entry) { entry->nlink = 1; - entry->data = (void *)(long)irq; + entry->data = (void *)(unsigned long)irq; entry->read_proc = irq_affinity_read_proc; entry->write_proc = irq_affinity_write_proc; } diff -Nru a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c --- a/arch/ia64/kernel/irq_ia64.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/kernel/irq_ia64.c Thu Aug 29 22:23:24 2002 @@ -54,20 +54,15 @@ 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) +ia64_alloc_vector (void) { - static int next_irq = IA64_FIRST_DEVICE_VECTOR; + static int next_vector = IA64_FIRST_DEVICE_VECTOR; - if (next_irq > IA64_LAST_DEVICE_VECTOR) + if (next_vector > IA64_LAST_DEVICE_VECTOR) /* XXX could look for sharable vectors instead of panic'ing... */ - panic("ia64_alloc_irq: out of interrupt vectors!"); - return next_irq++; + panic("ia64_alloc_vector: out of interrupt vectors!"); + return next_vector++; } extern unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs); diff -Nru a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c --- a/arch/ia64/kernel/palinfo.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/kernel/palinfo.c Thu Aug 29 22:23:24 2002 @@ -21,10 +21,10 @@ #include #include #include +#include #include #include -#include #include #include #ifdef CONFIG_SMP diff -Nru a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c --- a/arch/ia64/kernel/process.c Thu Aug 29 22:23:25 2002 +++ b/arch/ia64/kernel/process.c Thu Aug 29 22:23:25 2002 @@ -19,9 +19,9 @@ #include #include #include +#include #include -#include #include #include #include diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c --- a/arch/ia64/kernel/setup.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/kernel/setup.c Thu Aug 29 22:23:24 2002 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,6 @@ #include #include #include -#include #include #include @@ -58,9 +58,8 @@ unsigned long __per_cpu_offset[NR_CPUS]; #endif -DECLARE_PER_CPU(struct cpuinfo_ia64, cpu_info); - -unsigned long ia64_phys_stacked_size_p8; +DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info); +DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); unsigned long ia64_cycles_per_usec; struct ia64_boot_param *ia64_boot_param; struct screen_info screen_info; @@ -564,11 +563,11 @@ my_cpu_data = (void *) get_free_page(GFP_KERNEL); memcpy(my_cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start); __per_cpu_offset[cpu] = (char *) my_cpu_data - __per_cpu_start; - my_cpu_info = my_cpu_data + ((char *) &cpu_info - __per_cpu_start); + my_cpu_info = my_cpu_data + ((char *) &__get_cpu_var(cpu_info) - __per_cpu_start); #else my_cpu_data = __phys_per_cpu_start; #endif - my_cpu_info = my_cpu_data + ((char *) &cpu_info - __per_cpu_start); + my_cpu_info = my_cpu_data + ((char *) &__get_cpu_var(cpu_info) - __per_cpu_start); /* * We can't pass "local_cpu_data" to identify_cpu() because we haven't called @@ -652,6 +651,6 @@ num_phys_stacked = 96; } /* size of physical stacked register partition plus 8 bytes: */ - ia64_phys_stacked_size_p8 = num_phys_stacked*8 + 8; + __get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8; platform_cpu_init(); } diff -Nru a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c --- a/arch/ia64/kernel/smp.c Thu Aug 29 22:23:25 2002 +++ b/arch/ia64/kernel/smp.c Thu Aug 29 22:23:25 2002 @@ -32,12 +32,12 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -72,7 +72,7 @@ #define IPI_CPU_STOP 1 /* This needs to be cacheline aligned because it is written to by *other* CPUs. */ -static DECLARE_PER_CPU(__u64, ipi_operation) ____cacheline_aligned; +static DEFINE_PER_CPU(__u64, ipi_operation) ____cacheline_aligned; static void stop_this_cpu (void) diff -Nru a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c --- a/arch/ia64/kernel/smpboot.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/kernel/smpboot.c Thu Aug 29 22:23:24 2002 @@ -27,13 +27,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include diff -Nru a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c --- a/arch/ia64/kernel/time.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/kernel/time.c Thu Aug 29 22:23:24 2002 @@ -15,9 +15,9 @@ #include #include #include +#include #include -#include #include #include #include diff -Nru a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c --- a/arch/ia64/kernel/traps.c Thu Aug 29 22:23:25 2002 +++ b/arch/ia64/kernel/traps.c Thu Aug 29 22:23:25 2002 @@ -135,8 +135,6 @@ siginfo_t siginfo; int sig, code; - die_if_kernel("bad break", regs, break_num); - /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri); siginfo.si_imm = break_num; @@ -144,7 +142,8 @@ siginfo.si_isr = 0; switch (break_num) { - case 0: /* unknown error */ + case 0: /* unknown error (used by GCC for __builtin_abort()) */ + die_if_kernel("bad break", regs, break_num); sig = SIGILL; code = ILL_ILLOPC; break; diff -Nru a/arch/ia64/lib/memcpy.S b/arch/ia64/lib/memcpy.S --- a/arch/ia64/lib/memcpy.S Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/lib/memcpy.S Thu Aug 29 22:23:24 2002 @@ -13,8 +13,6 @@ * Stephane Eranian * David Mosberger-Tang */ -#include - #include GLOBAL_ENTRY(bcopy) diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c --- a/arch/ia64/mm/init.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/mm/init.c Thu Aug 29 22:23:24 2002 @@ -14,11 +14,11 @@ #include #include #include +#include #include #include #include -#include #include #include #include diff -Nru a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c --- a/arch/ia64/mm/tlb.c Thu Aug 29 22:23:25 2002 +++ b/arch/ia64/mm/tlb.c Thu Aug 29 22:23:25 2002 @@ -41,7 +41,7 @@ .max_ctx = ~0U }; -u8 ia64_need_tlb_flush __per_cpu_data; +DEFINE_PER_CPU(u8, ia64_need_tlb_flush); /* * Acquire the ia64_ctx.lock before calling this function! diff -Nru a/arch/ia64/sn/fakeprom/fpmem.c b/arch/ia64/sn/fakeprom/fpmem.c --- a/arch/ia64/sn/fakeprom/fpmem.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/sn/fakeprom/fpmem.c Thu Aug 29 22:23:24 2002 @@ -18,7 +18,7 @@ */ #include -#include +#include #include "fpmem.h" /* diff -Nru a/arch/ia64/sn/fakeprom/fw-emu.c b/arch/ia64/sn/fakeprom/fw-emu.c --- a/arch/ia64/sn/fakeprom/fw-emu.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/sn/fakeprom/fw-emu.c Thu Aug 29 22:23:24 2002 @@ -36,7 +36,7 @@ * http://oss.sgi.com/projects/GenInfo/NoticeExplan */ #include -#include +#include #include #include #include diff -Nru a/arch/ia64/sn/io/efi-rtc.c b/arch/ia64/sn/io/efi-rtc.c --- a/arch/ia64/sn/io/efi-rtc.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/sn/io/efi-rtc.c Thu Aug 29 22:23:24 2002 @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include /* diff -Nru a/arch/ia64/sn/io/sn1/pcibr.c b/arch/ia64/sn/io/sn1/pcibr.c --- a/arch/ia64/sn/io/sn1/pcibr.c Thu Aug 29 22:23:25 2002 +++ b/arch/ia64/sn/io/sn1/pcibr.c Thu Aug 29 22:23:25 2002 @@ -7485,7 +7485,7 @@ #ifdef LITTLE_ENDIAN /* - * on sn-ia we need to twiddle the the addresses going out + * on sn-ia we need to twiddle the addresses going out * the pci bus because we use the unswizzled synergy space * (the alternative is to use the swizzled synergy space * and byte swap the data) diff -Nru a/arch/ia64/sn/kernel/llsc4.c b/arch/ia64/sn/kernel/llsc4.c --- a/arch/ia64/sn/kernel/llsc4.c Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/sn/kernel/llsc4.c Thu Aug 29 22:23:24 2002 @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff -Nru a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S --- a/arch/ia64/vmlinux.lds.S Thu Aug 29 22:23:24 2002 +++ b/arch/ia64/vmlinux.lds.S Thu Aug 29 22:23:24 2002 @@ -7,7 +7,7 @@ OUTPUT_FORMAT("elf64-ia64-little") OUTPUT_ARCH(ia64) ENTRY(phys_start) -jiffies = jiffies_64; +jiffies = jiffies_64; SECTIONS { /* Sections to be discarded */ diff -Nru a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c --- a/arch/parisc/kernel/traps.c Thu Aug 29 22:23:25 2002 +++ b/arch/parisc/kernel/traps.c Thu Aug 29 22:23:25 2002 @@ -43,7 +43,6 @@ static inline void console_verbose(void) { - extern int console_loglevel; console_loglevel = 15; } diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c --- a/drivers/acpi/bus.c Thu Aug 29 22:23:25 2002 +++ b/drivers/acpi/bus.c Thu Aug 29 22:23:25 2002 @@ -2167,6 +2167,6 @@ return 1; } -subsys_initcall(acpi_init); +arch_initcall(acpi_init); /* XXX fix me: should be subsys_initcall */ __setup("acpi=", acpi_setup); diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c --- a/drivers/acpi/osl.c Thu Aug 29 22:23:25 2002 +++ b/drivers/acpi/osl.c Thu Aug 29 22:23:25 2002 @@ -38,15 +38,10 @@ #include "acpi.h" #ifdef CONFIG_ACPI_EFI -#include +#include u64 efi_mem_attributes (u64 phys_addr); #endif -#ifdef CONFIG_IA64 -#include -#include -#endif - #define _COMPONENT ACPI_OS_SERVICES ACPI_MODULE_NAME ("osl") @@ -80,6 +75,7 @@ * it while walking the namespace (bus 0 and root bridges w/ _BBNs). */ #ifdef CONFIG_ACPI_PCI + pcibios_config_init(); if (!pci_config_read || !pci_config_write) { printk(KERN_ERR PREFIX "Access to PCI configuration space unavailable\n"); return AE_NULL_ENTRY; @@ -176,10 +172,10 @@ acpi_os_map_memory(ACPI_PHYSICAL_ADDRESS phys, ACPI_SIZE size, void **virt) { #ifdef CONFIG_ACPI_EFI - if (!(EFI_MEMORY_WB & efi_mem_attributes(phys))) { - *virt = ioremap(phys, size); - } else { + if (EFI_MEMORY_WB & efi_mem_attributes(phys)) { *virt = phys_to_virt(phys); + } else { + *virt = ioremap(phys, size); } #else if (phys > ULONG_MAX) { @@ -235,7 +231,14 @@ acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context) { #ifdef CONFIG_IA64 - irq = gsi_to_vector(irq); + int vector; + + vector = acpi_irq_to_vector(irq); + if (vector < 0) { + printk(KERN_ERR PREFIX "SCI (IRQ%d) not registerd\n", irq); + return AE_OK; + } + irq = vector; #endif acpi_irq_irq = irq; acpi_irq_handler = handler; @@ -253,7 +256,7 @@ { if (acpi_irq_handler) { #ifdef CONFIG_IA64 - irq = gsi_to_vector(irq); + irq = acpi_irq_to_vector(irq); #endif free_irq(irq, acpi_irq); acpi_irq_handler = NULL; @@ -351,8 +354,7 @@ if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) { virt_addr = phys_to_virt(phys_addr); - } - else { + } else { iomem = 1; virt_addr = ioremap(phys_addr, width); } @@ -397,8 +399,7 @@ if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) { virt_addr = phys_to_virt(phys_addr); - } - else { + } else { iomem = 1; virt_addr = ioremap(phys_addr, width); } diff -Nru a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c --- a/drivers/acpi/pci_irq.c Thu Aug 29 22:23:24 2002 +++ b/drivers/acpi/pci_irq.c Thu Aug 29 22:23:24 2002 @@ -33,7 +33,9 @@ #include #include #include +#ifdef CONFIG_X86_IO_APIC #include +#endif #include "acpi_bus.h" #include "acpi_drivers.h" diff -Nru a/drivers/char/agp/agp.c b/drivers/char/agp/agp.c --- a/drivers/char/agp/agp.c Thu Aug 29 22:23:24 2002 +++ b/drivers/char/agp/agp.c Thu Aug 29 22:23:24 2002 @@ -25,6 +25,7 @@ * TODO: * - Allocate more than order 0 pages to avoid too much linear map splitting. */ + #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #include "agp.h" MODULE_AUTHOR("Jeff Hartmann "); @@ -134,6 +136,9 @@ { int i; + pr_debug("agp_free_memory(curr=%p): type=%u, page_count=%Zu\n", + curr, curr->type, curr->page_count); + if ((agp_bridge.type == NOT_SUPPORTED) || (curr == NULL)) return; @@ -146,7 +151,6 @@ } if (curr->page_count != 0) { for (i = 0; i < curr->page_count; i++) { - curr->memory[i] &= ~(0x00000fff); agp_bridge.agp_destroy_page(phys_to_virt(curr->memory[i])); } } @@ -164,6 +168,8 @@ agp_memory *new; int i; + pr_debug("agp_allocate_memory(count=%Zu, type=%u)\n", page_count, type); + if (agp_bridge.type == NOT_SUPPORTED) return NULL; @@ -199,12 +205,13 @@ agp_free_memory(new); return NULL; } - new->memory[i] = agp_bridge.mask_memory(virt_to_phys(addr), type); + new->memory[i] = virt_to_phys(addr); new->page_count++; } flush_agp_mappings(); + pr_debug("agp_allocate_memory: new=%p\n", new); return new; } @@ -648,7 +655,7 @@ } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) - agp_bridge.gatt_table[j] = mem->memory[i]; + agp_bridge.gatt_table[j] = agp_bridge.mask_memory(mem->memory[i], mem->type); agp_bridge.tlb_flush(mem); return 0; @@ -966,6 +973,17 @@ }, #endif /* CONFIG_AGP_INTEL */ + +#ifdef CONFIG_AGP_I460 + { + .device_id = PCI_DEVICE_ID_INTEL_460GX, + .vendor_id = PCI_VENDOR_ID_INTEL, + .chipset = INTEL_460GX, + .vendor_name = "Intel", + .chipset_name = "460GX", + .chipset_setup = intel_i460_setup + }, +#endif #ifdef CONFIG_AGP_SIS { diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h --- a/drivers/char/agp/agp.h Thu Aug 29 22:23:24 2002 +++ b/drivers/char/agp/agp.h Thu Aug 29 22:23:24 2002 @@ -82,7 +82,7 @@ flush_agp_cache(); } #else -static void global_cache_flush(void) +static void __attribute__((unused)) global_cache_flush(void) { flush_agp_cache(); } diff -Nru a/drivers/char/agp/amd-agp.c b/drivers/char/agp/amd-agp.c --- a/drivers/char/agp/amd-agp.c Thu Aug 29 22:23:25 2002 +++ b/drivers/char/agp/amd-agp.c Thu Aug 29 22:23:25 2002 @@ -330,7 +330,7 @@ for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr; cur_gatt = GET_GATT(addr); - cur_gatt[GET_GATT_OFF(addr)] = mem->memory[i]; + cur_gatt[GET_GATT_OFF(addr)] = agp_bridge.mask_memory(mem->memory[i], mem->type); } agp_bridge.tlb_flush(mem); return 0; diff -Nru a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c --- a/drivers/char/agp/hp-agp.c Thu Aug 29 22:23:25 2002 +++ b/drivers/char/agp/hp-agp.c Thu Aug 29 22:23:25 2002 @@ -43,8 +43,7 @@ #define HP_ZX1_SBA_IOMMU_COOKIE 0x0000badbadc0ffeeUL #define HP_ZX1_PDIR_VALID_BIT 0x8000000000000000UL -#define HP_ZX1_IOVA_TO_PDIR(va) ((va - hp_private.iova_base) >> \ - hp_private.io_tlb_shift) +#define HP_ZX1_IOVA_TO_PDIR(va) ((va - hp_private.iova_base) >> hp_private.io_tlb_shift) static struct aper_size_info_fixed hp_zx1_sizes[] = { @@ -357,12 +356,7 @@ return HP_ZX1_PDIR_VALID_BIT | addr; } -static unsigned long hp_zx1_unmask_memory(unsigned long addr) -{ - return addr & ~(HP_ZX1_PDIR_VALID_BIT); -} - -int __init hp_zx1_setup (struct pci_dev *pdev) +int __init hp_zx1_setup (struct pci_dev *pdev __attribute__((unused))) { agp_bridge.masks = hp_zx1_masks; agp_bridge.num_of_masks = 1; @@ -374,7 +368,6 @@ agp_bridge.cleanup = hp_zx1_cleanup; agp_bridge.tlb_flush = hp_zx1_tlbflush; agp_bridge.mask_memory = hp_zx1_mask_memory; - agp_bridge.unmask_memory = hp_zx1_unmask_memory; agp_bridge.agp_enable = agp_generic_agp_enable; agp_bridge.cache_flush = global_cache_flush; agp_bridge.create_gatt_table = hp_zx1_create_gatt_table; @@ -388,7 +381,4 @@ agp_bridge.cant_use_aperture = 1; return hp_zx1_ioc_init(); - - (void) pdev; /* unused */ } - diff -Nru a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c --- a/drivers/char/agp/i460-agp.c Thu Aug 29 22:23:25 2002 +++ b/drivers/char/agp/i460-agp.c Thu Aug 29 22:23:25 2002 @@ -4,6 +4,9 @@ * Copyright (C) 1999 Precision Insight, Inc. * Copyright (C) 1999 Xi Graphics, Inc. * + * 460GX support by Chris Ahna + * Clean up & simplification by David Mosberger-Tang + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation @@ -17,55 +20,105 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * TODO: + * TODO: * - Allocate more than order 0 pages to avoid too much linear map splitting. */ +/* + * For documentation on the i460 AGP interface, see Chapter 7 (AGP Subsystem) of + * the "Intel 460GTX Chipset Software Developer's Manual": + * http://developer.intel.com/design/itanium/downloads/24870401s.htm + */ +#include +#include #include #include #include #include -#include "agp.h" -/* BIOS configures the chipset so that one of two apbase registers are used */ -static u8 intel_i460_dynamic_apbase = 0x10; +#include "agp.h" -/* 460 supports multiple GART page sizes, so GART pageshift is dynamic */ -static u8 intel_i460_pageshift = 12; -static u32 intel_i460_pagesize; - -/* Keep track of which is larger, chipset or kernel page size. */ -static u32 intel_i460_cpk = 1; - -/* Structure for tracking partial use of 4MB GART pages */ -static u32 **i460_pg_detail = NULL; -static u32 *i460_pg_count = NULL; +/* + * The i460 can operate with large (4MB) pages, but there is no sane way to support this + * within the current kernel/DRM environment, so we disable the relevant code for now. + * See also comments in ia64_alloc_page()... + */ +#define I460_LARGE_IO_PAGES 0 -#define I460_CPAGES_PER_KPAGE (PAGE_SIZE >> intel_i460_pageshift) -#define I460_KPAGES_PER_CPAGE ((1 << intel_i460_pageshift) >> PAGE_SHIFT) +#if I460_LARGE_IO_PAGES +# define I460_IO_PAGE_SHIFT i460.io_page_shift +#else +# define I460_IO_PAGE_SHIFT 12 +#endif +#define I460_IOPAGES_PER_KPAGE (PAGE_SIZE >> I460_IO_PAGE_SHIFT) +#define I460_KPAGES_PER_IOPAGE (1 << (I460_IO_PAGE_SHIFT - PAGE_SHIFT)) #define I460_SRAM_IO_DISABLE (1 << 4) #define I460_BAPBASE_ENABLE (1 << 3) #define I460_AGPSIZ_MASK 0x7 #define I460_4M_PS (1 << 1) -#define log2(x) ffz(~(x)) +/* Control bits for Out-Of-GART coherency and Burst Write Combining */ +#define I460_GXBCTL_OOG (1UL << 0) +#define I460_GXBCTL_BWC (1UL << 2) + +/* + * gatt_table entries are 32-bits wide on the i460; the generic code ought to declare the + * gatt_table and gatt_table_real pointers a "void *"... + */ +#define RD_GATT(index) readl((u32 *) i460.gatt + (index)) +#define WR_GATT(index, val) writel((val), (u32 *) i460.gatt + (index)) +/* + * The 460 spec says we have to read the last location written to make sure that all + * writes have taken effect + */ +#define WR_FLUSH_GATT(index) RD_GATT(index) + +#define log2(x) ffz(~(x)) + +static struct { + void *gatt; /* ioremap'd GATT area */ + + /* i460 supports multiple GART page sizes, so GART pageshift is dynamic: */ + u8 io_page_shift; + + /* BIOS configures chipset to one of 2 possible apbase values: */ + u8 dynamic_apbase; -static inline void intel_i460_read_back (volatile u32 *entry) + /* structure for tracking partial use of 4MB GART pages: */ + struct lp_desc { + unsigned long *alloced_map; /* bitmap of kernel-pages in use */ + int refcount; /* number of kernel pages using the large page */ + u64 paddr; /* physical address of large page */ + } *lp_desc; +} i460; + +static const struct aper_size_info_8 i460_sizes[3] = { /* - * The 460 spec says we have to read the last location written to - * make sure that all writes have taken effect + * The 32GB aperture is only available with a 4M GART page size. Due to the + * dynamic GART page size, we can't figure out page_order or num_entries until + * runtime. */ - *entry; -} + {32768, 0, 0, 4}, + {1024, 0, 0, 2}, + {256, 0, 0, 1} +}; -static int intel_i460_fetch_size(void) +static struct gatt_mask i460_masks[] = +{ + { + .mask = INTEL_I460_GATT_VALID | INTEL_I460_GATT_COHERENT, + .type = 0 + } +}; + +static int i460_fetch_size (void) { int i; u8 temp; @@ -73,8 +126,15 @@ /* Determine the GART page size */ pci_read_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL, &temp); - intel_i460_pageshift = (temp & I460_4M_PS) ? 22 : 12; - intel_i460_pagesize = 1UL << intel_i460_pageshift; + i460.io_page_shift = (temp & I460_4M_PS) ? 22 : 12; + pr_debug("i460_fetch_size: io_page_shift=%d\n", i460.io_page_shift); + + if (i460.io_page_shift != I460_IO_PAGE_SHIFT) { + printk(KERN_ERR PFX + "I/O (GART) page-size %ZuKB doesn't match expected size %ZuKB\n", + 1UL << (i460.io_page_shift - 10), 1UL << (I460_IO_PAGE_SHIFT)); + return 0; + } values = A_SIZE_8(agp_bridge.aperture_sizes); @@ -88,16 +148,16 @@ } /* Make sure we don't try to create an 2 ^ 23 entry GATT */ - if ((intel_i460_pageshift == 0) && ((temp & I460_AGPSIZ_MASK) == 4)) { + if ((i460.io_page_shift == 0) && ((temp & I460_AGPSIZ_MASK) == 4)) { printk(KERN_ERR PFX "We can't have a 32GB aperture with 4KB GART pages\n"); return 0; } /* Determine the proper APBASE register */ if (temp & I460_BAPBASE_ENABLE) - intel_i460_dynamic_apbase = INTEL_I460_BAPBASE; + i460.dynamic_apbase = INTEL_I460_BAPBASE; else - intel_i460_dynamic_apbase = INTEL_I460_APBASE; + i460.dynamic_apbase = INTEL_I460_APBASE; for (i = 0; i < agp_bridge.num_aperture_sizes; i++) { /* @@ -105,7 +165,7 @@ * the define aperture sizes. Take care not to shift off the end of * values[i].size. */ - values[i].num_entries = (values[i].size << 8) >> (intel_i460_pageshift - 12); + values[i].num_entries = (values[i].size << 8) >> (I460_IO_PAGE_SHIFT - 12); values[i].page_order = log2((sizeof(u32)*values[i].num_entries) >> PAGE_SHIFT); } @@ -122,7 +182,7 @@ } /* There isn't anything to do here since 460 has no GART TLB. */ -static void intel_i460_tlb_flush(agp_memory * mem) +static void i460_tlb_flush (agp_memory * mem) { return; } @@ -131,7 +191,7 @@ * This utility function is needed to prevent corruption of the control bits * which are stored along with the aperture size in 460's AGPSIZ register */ -static void intel_i460_write_agpsiz(u8 size_value) +static void i460_write_agpsiz (u8 size_value) { u8 temp; @@ -140,47 +200,39 @@ ((temp & ~I460_AGPSIZ_MASK) | size_value)); } -static void intel_i460_cleanup(void) +static void i460_cleanup (void) { struct aper_size_info_8 *previous_size; previous_size = A_SIZE_8(agp_bridge.previous_size); - intel_i460_write_agpsiz(previous_size->size_value); + i460_write_agpsiz(previous_size->size_value); - if (intel_i460_cpk == 0) { - vfree(i460_pg_detail); - vfree(i460_pg_count); - } + if (I460_IO_PAGE_SHIFT > PAGE_SHIFT) + kfree(i460.lp_desc); } - -/* Control bits for Out-Of-GART coherency and Burst Write Combining */ -#define I460_GXBCTL_OOG (1UL << 0) -#define I460_GXBCTL_BWC (1UL << 2) - -static int intel_i460_configure(void) +static int i460_configure (void) { union { u32 small[2]; u64 large; } temp; + size_t size; u8 scratch; - int i; - struct aper_size_info_8 *current_size; temp.large = 0; current_size = A_SIZE_8(agp_bridge.current_size); - intel_i460_write_agpsiz(current_size->size_value); + i460_write_agpsiz(current_size->size_value); /* * Do the necessary rigmarole to read all eight bytes of APBASE. * This has to be done since the AGP aperture can be above 4GB on * 460 based systems. */ - pci_read_config_dword(agp_bridge.dev, intel_i460_dynamic_apbase, &(temp.small[0])); - pci_read_config_dword(agp_bridge.dev, intel_i460_dynamic_apbase + 4, &(temp.small[1])); + pci_read_config_dword(agp_bridge.dev, i460.dynamic_apbase, &(temp.small[0])); + pci_read_config_dword(agp_bridge.dev, i460.dynamic_apbase + 4, &(temp.small[1])); /* Clear BAR control bits */ agp_bridge.gart_bus_addr = temp.large & ~((1UL << 3) - 1); @@ -190,406 +242,349 @@ (scratch & 0x02) | I460_GXBCTL_OOG | I460_GXBCTL_BWC); /* - * Initialize partial allocation trackers if a GART page is bigger than - * a kernel page. + * Initialize partial allocation trackers if a GART page is bigger than a kernel + * page. */ - if (I460_CPAGES_PER_KPAGE >= 1) { - intel_i460_cpk = 1; - } else { - intel_i460_cpk = 0; - - i460_pg_detail = vmalloc(sizeof(*i460_pg_detail) * current_size->num_entries); - i460_pg_count = vmalloc(sizeof(*i460_pg_count) * current_size->num_entries); - - for (i = 0; i < current_size->num_entries; i++) { - i460_pg_count[i] = 0; - i460_pg_detail[i] = NULL; - } + if (I460_IO_PAGE_SHIFT > PAGE_SHIFT) { + size = current_size->num_entries * sizeof(i460.lp_desc[0]); + i460.lp_desc = kmalloc(size, GFP_KERNEL); + if (!i460.lp_desc) + return -ENOMEM; + memset(i460.lp_desc, 0, size); } return 0; } -static int intel_i460_create_gatt_table(void) +static int i460_create_gatt_table (void) { - char *table; - int i; - int page_order; - int num_entries; + int page_order, num_entries, i; void *temp; /* - * Load up the fixed address of the GART SRAMS which hold our - * GATT table. + * Load up the fixed address of the GART SRAMS which hold our GATT table. */ - table = (char *) __va(INTEL_I460_ATTBASE); - temp = agp_bridge.current_size; page_order = A_SIZE_8(temp)->page_order; num_entries = A_SIZE_8(temp)->num_entries; - agp_bridge.gatt_table_real = (u32 *) table; - agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table), - (PAGE_SIZE * (1 << page_order))); - agp_bridge.gatt_bus_addr = virt_to_phys(agp_bridge.gatt_table_real); - - for (i = 0; i < num_entries; i++) { - agp_bridge.gatt_table[i] = 0; - } + i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order); - intel_i460_read_back(agp_bridge.gatt_table + i - 1); + /* These are no good, the should be removed from the agp_bridge strucure... */ + agp_bridge.gatt_table_real = NULL; + agp_bridge.gatt_table = NULL; + agp_bridge.gatt_bus_addr = 0; + + for (i = 0; i < num_entries; ++i) + WR_GATT(i, 0); + WR_FLUSH_GATT(i - 1); return 0; } -static int intel_i460_free_gatt_table(void) +static int i460_free_gatt_table (void) { - int num_entries; - int i; + int num_entries, i; void *temp; temp = agp_bridge.current_size; num_entries = A_SIZE_8(temp)->num_entries; - for (i = 0; i < num_entries; i++) { - agp_bridge.gatt_table[i] = 0; - } - - intel_i460_read_back(agp_bridge.gatt_table + i - 1); + for (i = 0; i < num_entries; ++i) + WR_GATT(i, 0); + WR_FLUSH_GATT(num_entries - 1); - iounmap(agp_bridge.gatt_table); + iounmap(i460.gatt); return 0; } -/* These functions are called when PAGE_SIZE exceeds the GART page size */ +/* + * The following functions are called when the I/O (GART) page size is smaller than + * PAGE_SIZE. + */ -static int intel_i460_insert_memory_cpk(agp_memory * mem, off_t pg_start, int type) +static int i460_insert_memory_small_io_page (agp_memory *mem, off_t pg_start, int type) { + unsigned long paddr, io_pg_start, io_page_size; int i, j, k, num_entries; void *temp; - unsigned long paddr; - /* - * The rest of the kernel will compute page offsets in terms of - * PAGE_SIZE. - */ - pg_start = I460_CPAGES_PER_KPAGE * pg_start; + pr_debug("i460_insert_memory_small_io_page(mem=%p, pg_start=%ld, type=%d, paddr0=0x%lx)\n", + mem, pg_start, type, mem->memory[0]); + + io_pg_start = I460_IOPAGES_PER_KPAGE * pg_start; temp = agp_bridge.current_size; num_entries = A_SIZE_8(temp)->num_entries; - if ((pg_start + I460_CPAGES_PER_KPAGE * mem->page_count) > num_entries) { + if ((io_pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count) > num_entries) { printk(KERN_ERR PFX "Looks like we're out of AGP memory\n"); return -EINVAL; } - j = pg_start; - while (j < (pg_start + I460_CPAGES_PER_KPAGE * mem->page_count)) { - if (!PGE_EMPTY(agp_bridge.gatt_table[j])) { + j = io_pg_start; + while (j < (io_pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count)) { + if (!PGE_EMPTY(RD_GATT(j))) { + pr_debug("i460_insert_memory_small_io_page: GATT[%d]=0x%x is busy\n", + j, RD_GATT(j)); return -EBUSY; } j++; } -#if 0 - /* not necessary since 460 GART is operated in coherent mode... */ - if (mem->is_flushed == FALSE) { - CACHE_FLUSH(); - mem->is_flushed = TRUE; - } -#endif - - for (i = 0, j = pg_start; i < mem->page_count; i++) { + io_page_size = 1UL << I460_IO_PAGE_SHIFT; + for (i = 0, j = io_pg_start; i < mem->page_count; i++) { paddr = mem->memory[i]; - for (k = 0; k < I460_CPAGES_PER_KPAGE; k++, j++, paddr += intel_i460_pagesize) - agp_bridge.gatt_table[j] = (u32) agp_bridge.mask_memory(paddr, mem->type); + for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size) + WR_GATT(j, agp_bridge.mask_memory(paddr, mem->type)); } - - intel_i460_read_back(agp_bridge.gatt_table + j - 1); + WR_FLUSH_GATT(j - 1); return 0; } -static int intel_i460_remove_memory_cpk(agp_memory * mem, off_t pg_start, int type) +static int i460_remove_memory_small_io_page(agp_memory * mem, off_t pg_start, int type) { int i; - pg_start = I460_CPAGES_PER_KPAGE * pg_start; + pr_debug("i460_remove_memory_small_io_page(mem=%p, pg_start=%ld, type=%d)\n", + mem, pg_start, type); - for (i = pg_start; i < (pg_start + I460_CPAGES_PER_KPAGE * mem->page_count); i++) - agp_bridge.gatt_table[i] = 0; + pg_start = I460_IOPAGES_PER_KPAGE * pg_start; - intel_i460_read_back(agp_bridge.gatt_table + i - 1); + for (i = pg_start; i < (pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count); i++) + WR_GATT(i, 0); + WR_FLUSH_GATT(i - 1); return 0; } +#if I460_LARGE_IO_PAGES + /* - * These functions are called when the GART page size exceeds PAGE_SIZE. + * These functions are called when the I/O (GART) page size exceeds PAGE_SIZE. * - * This situation is interesting since AGP memory allocations that are - * smaller than a single GART page are possible. The structures i460_pg_count - * and i460_pg_detail track partial allocation of the large GART pages to - * work around this issue. + * This situation is interesting since AGP memory allocations that are smaller than a + * single GART page are possible. The i460.lp_desc array tracks partial allocation of the + * large GART pages to work around this issue. * - * i460_pg_count[pg_num] tracks the number of kernel pages in use within - * GART page pg_num. i460_pg_detail[pg_num] is an array containing a - * psuedo-GART entry for each of the aforementioned kernel pages. The whole - * of i460_pg_detail is equivalent to a giant GATT with page size equal to - * that of the kernel. + * i460.lp_desc[pg_num].refcount tracks the number of kernel pages in use within GART page + * pg_num. i460.lp_desc[pg_num].paddr is the physical address of the large page and + * i460.lp_desc[pg_num].alloced_map is a bitmap of kernel pages that are in use (allocated). */ -static void *intel_i460_alloc_large_page(int pg_num) +static int i460_alloc_large_page (struct lp_desc *lp) { - int i; - void *bp, *bp_end; - struct page *page; - - i460_pg_detail[pg_num] = (void *) vmalloc(sizeof(u32) * I460_KPAGES_PER_CPAGE); - if (i460_pg_detail[pg_num] == NULL) { - printk(KERN_ERR PFX "Out of memory, we're in trouble...\n"); - return NULL; - } - - for (i = 0; i < I460_KPAGES_PER_CPAGE; i++) - i460_pg_detail[pg_num][i] = 0; + unsigned long order = I460_IO_PAGE_SHIFT - PAGE_SHIFT; + size_t map_size; + void *lpage; - bp = (void *) __get_free_pages(GFP_KERNEL, intel_i460_pageshift - PAGE_SHIFT); - if (bp == NULL) { + lpage = (void *) __get_free_pages(GFP_KERNEL, order); + if (!lpage) { printk(KERN_ERR PFX "Couldn't alloc 4M GART page...\n"); - return NULL; + return -ENOMEM; } - bp_end = bp + ((PAGE_SIZE * (1 << (intel_i460_pageshift - PAGE_SHIFT))) - 1); - - for (page = virt_to_page(bp); page <= virt_to_page(bp_end); page++) { - atomic_inc(&agp_bridge.current_memory_agp); + map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8; + lp->alloced_map = kmalloc(map_size, GFP_KERNEL); + if (!lp->alloced_map) { + free_pages((unsigned long) lpage, order); + printk(KERN_ERR PFX "Out of memory, we're in trouble...\n"); + return -ENOMEM; } - return bp; + memset(lp->alloced_map, 0, map_size); + + lp->paddr = virt_to_phys(lpage); + lp->refcount = 0; + atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge.current_memory_agp); + return 0; } -static void intel_i460_free_large_page(int pg_num, unsigned long addr) +static void i460_free_large_page (struct lp_desc *lp) { - struct page *page; - void *bp, *bp_end; - - bp = (void *) __va(addr); - bp_end = bp + (PAGE_SIZE * (1 << (intel_i460_pageshift - PAGE_SHIFT))); + kfree(lp->alloced_map); + lp->alloced_map = NULL; - vfree(i460_pg_detail[pg_num]); - i460_pg_detail[pg_num] = NULL; - - for (page = virt_to_page(bp); page < virt_to_page(bp_end); page++) { - atomic_dec(&agp_bridge.current_memory_agp); - } - - free_pages((unsigned long) bp, intel_i460_pageshift - PAGE_SHIFT); + free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); + atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge.current_memory_agp); } -static int intel_i460_insert_memory_kpc(agp_memory * mem, off_t pg_start, int type) +static int i460_insert_memory_large_io_page (agp_memory * mem, off_t pg_start, int type) { - int i, pg, start_pg, end_pg, start_offset, end_offset, idx; - int num_entries; + int i, start_offset, end_offset, idx, pg, num_entries; + struct lp_desc *start, *end, *lp; void *temp; - unsigned long paddr; temp = agp_bridge.current_size; num_entries = A_SIZE_8(temp)->num_entries; /* Figure out what pg_start means in terms of our large GART pages */ - start_pg = pg_start / I460_KPAGES_PER_CPAGE; - start_offset = pg_start % I460_KPAGES_PER_CPAGE; - end_pg = (pg_start + mem->page_count - 1) / I460_KPAGES_PER_CPAGE; - end_offset = (pg_start + mem->page_count - 1) % I460_KPAGES_PER_CPAGE; + start = &i460.lp_desc[pg_start / I460_KPAGES_PER_IOPAGE]; + end = &i460.lp_desc[(pg_start + mem->page_count - 1) / I460_KPAGES_PER_IOPAGE]; + start_offset = pg_start % I460_KPAGES_PER_IOPAGE; + end_offset = (pg_start + mem->page_count - 1) % I460_KPAGES_PER_IOPAGE; - if (end_pg > num_entries) { + if (end > i460.lp_desc + num_entries) { printk(KERN_ERR PFX "Looks like we're out of AGP memory\n"); return -EINVAL; } /* Check if the requested region of the aperture is free */ - for (pg = start_pg; pg <= end_pg; pg++) { - /* Allocate new GART pages if necessary */ - if (i460_pg_detail[pg] == NULL) { - temp = intel_i460_alloc_large_page(pg); - if (temp == NULL) - return -ENOMEM; - agp_bridge.gatt_table[pg] = agp_bridge.mask_memory((unsigned long) temp, - 0); - intel_i460_read_back(agp_bridge.gatt_table + pg); - } + for (lp = start; lp <= end; ++lp) { + if (!lp->alloced_map) + continue; /* OK, the entire large page is available... */ - for (idx = ((pg == start_pg) ? start_offset : 0); - idx < ((pg == end_pg) ? (end_offset + 1) : I460_KPAGES_PER_CPAGE); + for (idx = ((lp == start) ? start_offset : 0); + idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE); idx++) { - if (i460_pg_detail[pg][idx] != 0) + if (test_bit(idx, lp->alloced_map)) return -EBUSY; } } -#if 0 - /* not necessary since 460 GART is operated in coherent mode... */ - if (mem->is_flushed == FALSE) { - CACHE_FLUSH(); - mem->is_flushed = TRUE; - } -#endif + for (lp = start, i = 0; lp <= end; ++lp) { + if (!lp->alloced_map) { + /* Allocate new GART pages... */ + if (i460_alloc_large_page(lp) < 0) + return -ENOMEM; + pg = lp - i460.lp_desc; + WR_GATT(pg, agp_bridge.mask_memory(lp->paddr, 0)); + WR_FLUSH_GATT(pg); + } - for (pg = start_pg, i = 0; pg <= end_pg; pg++) { - paddr = agp_bridge.unmask_memory(agp_bridge.gatt_table[pg]); - for (idx = ((pg == start_pg) ? start_offset : 0); - idx < ((pg == end_pg) ? (end_offset + 1) : I460_KPAGES_PER_CPAGE); + for (idx = ((lp == start) ? start_offset : 0); + idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE); idx++, i++) { - mem->memory[i] = paddr + (idx * PAGE_SIZE); - i460_pg_detail[pg][idx] = agp_bridge.mask_memory(mem->memory[i], - mem->type); - i460_pg_count[pg]++; + mem->memory[i] = lp->paddr + idx*PAGE_SIZE; + __set_bit(idx, lp->alloced_map); + ++lp->refcount; } } - return 0; } -static int intel_i460_remove_memory_kpc(agp_memory * mem, off_t pg_start, int type) +static int i460_remove_memory_large_io_page (agp_memory * mem, off_t pg_start, int type) { - int i, pg, start_pg, end_pg, start_offset, end_offset, idx; - int num_entries; + int i, pg, start_offset, end_offset, idx, num_entries; + struct lp_desc *start, *end, *lp; void *temp; - unsigned long paddr; temp = agp_bridge.current_size; num_entries = A_SIZE_8(temp)->num_entries; /* Figure out what pg_start means in terms of our large GART pages */ - start_pg = pg_start / I460_KPAGES_PER_CPAGE; - start_offset = pg_start % I460_KPAGES_PER_CPAGE; - end_pg = (pg_start + mem->page_count - 1) / I460_KPAGES_PER_CPAGE; - end_offset = (pg_start + mem->page_count - 1) % I460_KPAGES_PER_CPAGE; - - for (i = 0, pg = start_pg; pg <= end_pg; pg++) { - for (idx = ((pg == start_pg) ? start_offset : 0); - idx < ((pg == end_pg) ? (end_offset + 1) : I460_KPAGES_PER_CPAGE); - idx++, i++) + start = &i460.lp_desc[pg_start / I460_KPAGES_PER_IOPAGE]; + end = &i460.lp_desc[(pg_start + mem->page_count - 1) / I460_KPAGES_PER_IOPAGE]; + start_offset = pg_start % I460_KPAGES_PER_IOPAGE; + end_offset = (pg_start + mem->page_count - 1) % I460_KPAGES_PER_IOPAGE; + + for (i = 0, lp = start; lp <= end; ++lp) { + for (idx = ((lp == start) ? start_offset : 0); + idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE); + idx++, i++) { mem->memory[i] = 0; - i460_pg_detail[pg][idx] = 0; - i460_pg_count[pg]--; + __clear_bit(idx, lp->alloced_map); + --lp->refcount; } /* Free GART pages if they are unused */ - if (i460_pg_count[pg] == 0) { - paddr = agp_bridge.unmask_memory(agp_bridge.gatt_table[pg]); - agp_bridge.gatt_table[pg] = agp_bridge.scratch_page; - intel_i460_read_back(agp_bridge.gatt_table + pg); - intel_i460_free_large_page(pg, paddr); + if (lp->refcount == 0) { + pg = lp - i460.lp_desc; + WR_GATT(pg, 0); + WR_FLUSH_GATT(pg); + i460_free_large_page(lp); } } return 0; } -/* Dummy routines to call the approriate {cpk,kpc} function */ +/* Wrapper routines to call the approriate {small_io_page,large_io_page} function */ -static int intel_i460_insert_memory(agp_memory * mem, off_t pg_start, int type) +static int i460_insert_memory (agp_memory * mem, off_t pg_start, int type) { - if (intel_i460_cpk) - return intel_i460_insert_memory_cpk(mem, pg_start, type); + if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) + return i460_insert_memory_small_io_page(mem, pg_start, type); else - return intel_i460_insert_memory_kpc(mem, pg_start, type); + return i460_insert_memory_large_io_page(mem, pg_start, type); } -static int intel_i460_remove_memory(agp_memory * mem, off_t pg_start, int type) +static int i460_remove_memory (agp_memory * mem, off_t pg_start, int type) { - if (intel_i460_cpk) - return intel_i460_remove_memory_cpk(mem, pg_start, type); + if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) + return i460_remove_memory_small_io_page(mem, pg_start, type); else - return intel_i460_remove_memory_kpc(mem, pg_start, type); + return i460_remove_memory_large_io_page(mem, pg_start, type); } /* - * If the kernel page size is smaller that the chipset page size, we don't - * want to allocate memory until we know where it is to be bound in the - * aperture (a multi-kernel-page alloc might fit inside of an already - * allocated GART page). Consequently, don't allocate or free anything - * if i460_cpk (meaning chipset pages per kernel page) isn't set. + * If the I/O (GART) page size is bigger than the kernel page size, we don't want to + * allocate memory until we know where it is to be bound in the aperture (a + * multi-kernel-page alloc might fit inside of an already allocated GART page). * - * Let's just hope nobody counts on the allocated AGP memory being there - * before bind time (I don't think current drivers do)... + * Let's just hope nobody counts on the allocated AGP memory being there before bind time + * (I don't think current drivers do)... */ -static void * intel_i460_alloc_page(void) +static void *i460_alloc_page (void) { - if (intel_i460_cpk) - return agp_generic_alloc_page(); + void *page; - /* Returning NULL would cause problems */ - /* AK: really dubious code. */ - return (void *)~0UL; + if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) + page = agp_generic_alloc_page(); + else + /* Returning NULL would cause problems */ + /* AK: really dubious code. */ + page = (void *)~0UL; + return page; } -static void intel_i460_destroy_page(void *page) +static void i460_destroy_page (void *page) { - if (intel_i460_cpk) + if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) agp_generic_destroy_page(page); } -static struct gatt_mask intel_i460_masks[] = -{ - { - .mask = INTEL_I460_GATT_VALID | INTEL_I460_GATT_COHERENT, - .type = 0 - } -}; +#endif /* I460_LARGE_IO_PAGES */ -static unsigned long intel_i460_mask_memory(unsigned long addr, int type) +static unsigned long i460_mask_memory (unsigned long addr, int type) { /* Make sure the returned address is a valid GATT entry */ return (agp_bridge.masks[0].mask - | (((addr & ~((1 << intel_i460_pageshift) - 1)) & 0xffffff000) >> 12)); + | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12)); } -static unsigned long intel_i460_unmask_memory(unsigned long addr) -{ - /* Turn a GATT entry into a physical address */ - return ((addr & 0xffffff) << 12); -} - -static struct aper_size_info_8 intel_i460_sizes[3] = -{ - /* - * The 32GB aperture is only available with a 4M GART page size. - * Due to the dynamic GART page size, we can't figure out page_order - * or num_entries until runtime. - */ - {32768, 0, 0, 4}, - {1024, 0, 0, 2}, - {256, 0, 0, 1} -}; - int __init intel_i460_setup (struct pci_dev *pdev __attribute__((unused))) { - agp_bridge.masks = intel_i460_masks; - agp_bridge.aperture_sizes = (void *) intel_i460_sizes; + agp_bridge.num_of_masks = 1; + agp_bridge.masks = i460_masks; + agp_bridge.aperture_sizes = (void *) i460_sizes; agp_bridge.size_type = U8_APER_SIZE; agp_bridge.num_aperture_sizes = 3; agp_bridge.dev_private_data = NULL; agp_bridge.needs_scratch_page = FALSE; - agp_bridge.configure = intel_i460_configure; - agp_bridge.fetch_size = intel_i460_fetch_size; - agp_bridge.cleanup = intel_i460_cleanup; - agp_bridge.tlb_flush = intel_i460_tlb_flush; - agp_bridge.mask_memory = intel_i460_mask_memory; - agp_bridge.unmask_memory = intel_i460_unmask_memory; + agp_bridge.configure = i460_configure; + agp_bridge.fetch_size = i460_fetch_size; + agp_bridge.cleanup = i460_cleanup; + agp_bridge.tlb_flush = i460_tlb_flush; + agp_bridge.mask_memory = i460_mask_memory; agp_bridge.agp_enable = agp_generic_agp_enable; agp_bridge.cache_flush = global_cache_flush; - agp_bridge.create_gatt_table = intel_i460_create_gatt_table; - agp_bridge.free_gatt_table = intel_i460_free_gatt_table; - agp_bridge.insert_memory = intel_i460_insert_memory; - agp_bridge.remove_memory = intel_i460_remove_memory; + agp_bridge.create_gatt_table = i460_create_gatt_table; + agp_bridge.free_gatt_table = i460_free_gatt_table; +#if I460_LARGE_IO_PAGES + agp_bridge.insert_memory = i460_insert_memory; + agp_bridge.remove_memory = i460_remove_memory; + agp_bridge.agp_alloc_page = i460_alloc_page; + agp_bridge.agp_destroy_page = i460_destroy_page; +#else + agp_bridge.insert_memory = i460_insert_memory_small_io_page; + agp_bridge.remove_memory = i460_remove_memory_small_io_page; + agp_bridge.agp_alloc_page = agp_generic_alloc_page; + agp_bridge.agp_destroy_page = agp_generic_destroy_page; +#endif agp_bridge.alloc_by_type = agp_generic_alloc_by_type; agp_bridge.free_by_type = agp_generic_free_by_type; - agp_bridge.agp_alloc_page = intel_i460_alloc_page; - agp_bridge.agp_destroy_page = intel_i460_destroy_page; agp_bridge.suspend = agp_generic_suspend; agp_bridge.resume = agp_generic_resume; agp_bridge.cant_use_aperture = 1; return 0; } - diff -Nru a/drivers/char/agp/i810-agp.c b/drivers/char/agp/i810-agp.c --- a/drivers/char/agp/i810-agp.c Thu Aug 29 22:23:25 2002 +++ b/drivers/char/agp/i810-agp.c Thu Aug 29 22:23:25 2002 @@ -179,7 +179,8 @@ CACHE_FLUSH(); for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { OUTREG32(intel_i810_private.registers, - I810_PTE_BASE + (j * 4), mem->memory[i]); + I810_PTE_BASE + (j * 4), agp_bridge.mask_memory(mem->memory[i], + mem->type)); } CACHE_FLUSH(); @@ -246,11 +247,11 @@ agp_free_memory(new); return NULL; } - new->memory[0] = agp_bridge.mask_memory(virt_to_phys(addr), type); + new->memory[0] = virt_to_phys(addr); new->page_count = 1; new->num_scratch_pages = 1; new->type = AGP_PHYS_MEMORY; - new->physical = virt_to_phys((void *) new->memory[0]); + new->physical = virt_to_phys(addr); return new; } @@ -483,7 +484,8 @@ CACHE_FLUSH(); for (i = 0, j = pg_start; i < mem->page_count; i++, j++) - OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),mem->memory[i]); + OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4), + agp_bridge.mask_memory(mem->memory[i], mem->type)); CACHE_FLUSH(); @@ -543,7 +545,7 @@ return(NULL); } - nw->memory[0] = agp_bridge.mask_memory(virt_to_phys(addr),type); + nw->memory[0] = virt_to_phys(addr); nw->page_count = 1; nw->num_scratch_pages = 1; nw->type = AGP_PHYS_MEMORY; diff -Nru a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c --- a/drivers/char/agp/sworks-agp.c Thu Aug 29 22:23:24 2002 +++ b/drivers/char/agp/sworks-agp.c Thu Aug 29 22:23:24 2002 @@ -405,7 +405,7 @@ for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr; cur_gatt = SVRWRKS_GET_GATT(addr); - cur_gatt[GET_GATT_OFF(addr)] = mem->memory[i]; + cur_gatt[GET_GATT_OFF(addr)] = agp_bridge.mask_memory(mem->memory[i], mem->type); } agp_bridge.tlb_flush(mem); return 0; diff -Nru a/drivers/char/drm/ati_pcigart.h b/drivers/char/drm/ati_pcigart.h --- a/drivers/char/drm/ati_pcigart.h Thu Aug 29 22:23:24 2002 +++ b/drivers/char/drm/ati_pcigart.h Thu Aug 29 22:23:24 2002 @@ -30,14 +30,20 @@ #define __NO_VERSION__ #include "drmP.h" -#if PAGE_SIZE == 8192 +#if PAGE_SIZE == 65536 +# define ATI_PCIGART_TABLE_ORDER 0 +# define ATI_PCIGART_TABLE_PAGES (1 << 0) +#elif PAGE_SIZE == 16384 +# define ATI_PCIGART_TABLE_ORDER 1 +# define ATI_PCIGART_TABLE_PAGES (1 << 1) +#elif PAGE_SIZE == 8192 # define ATI_PCIGART_TABLE_ORDER 2 # define ATI_PCIGART_TABLE_PAGES (1 << 2) #elif PAGE_SIZE == 4096 # define ATI_PCIGART_TABLE_ORDER 3 # define ATI_PCIGART_TABLE_PAGES (1 << 3) #else -# error - PAGE_SIZE not 8K or 4K +# error - PAGE_SIZE not 64K, 16K, 8K or 4K #endif # define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */ diff -Nru a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h --- a/drivers/char/drm/drmP.h Thu Aug 29 22:23:25 2002 +++ b/drivers/char/drm/drmP.h Thu Aug 29 22:23:25 2002 @@ -201,19 +201,17 @@ /* Macros to make printk easier */ #define DRM_ERROR(fmt, arg...) \ - printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg) + printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __FUNCTION__ , ##arg) #define DRM_MEM_ERROR(area, fmt, arg...) \ - printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ ":%s] *ERROR* " fmt , \ + printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __FUNCTION__ , \ DRM(mem_stats)[area].name , ##arg) #define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg) #if DRM_DEBUG_CODE -#define DRM_DEBUG(fmt, arg...) \ - do { \ - if ( DRM(flags) & DRM_FLAG_DEBUG ) \ - printk(KERN_DEBUG \ - "[" DRM_NAME ":" __FUNCTION__ "] " fmt , \ - ##arg); \ +#define DRM_DEBUG(fmt, arg...) \ + do { \ + if ( DRM(flags) & DRM_FLAG_DEBUG ) \ + printk(KERN_DEBUG "[" DRM_NAME ":%s] " fmt, __FUNCTION__, ##arg); \ } while (0) #else #define DRM_DEBUG(fmt, arg...) do { } while (0) @@ -230,16 +228,16 @@ if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; } /* Mapping helper macros */ -#define DRM_IOREMAP(map) \ - (map)->handle = DRM(ioremap)( (map)->offset, (map)->size ) +#define DRM_IOREMAP(map, dev) \ + (map)->handle = DRM(ioremap)( (map)->offset, (map)->size, (dev) ) -#define DRM_IOREMAP_NOCACHE(map) \ - (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size) +#define DRM_IOREMAP_NOCACHE(map, dev) \ + (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size, (dev)) -#define DRM_IOREMAPFREE(map) \ - do { \ - if ( (map)->handle && (map)->size ) \ - DRM(ioremapfree)( (map)->handle, (map)->size ); \ +#define DRM_IOREMAPFREE(map, dev) \ + do { \ + if ( (map)->handle && (map)->size ) \ + DRM(ioremapfree)( (map)->handle, (map)->size, (dev) ); \ } while (0) #define DRM_FIND_MAP(_map, _o) \ @@ -677,9 +675,10 @@ extern unsigned long DRM(alloc_pages)(int order, int area); extern void DRM(free_pages)(unsigned long address, int order, int area); -extern void *DRM(ioremap)(unsigned long offset, unsigned long size); -extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size); -extern void DRM(ioremapfree)(void *pt, unsigned long size); +extern void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev); +extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, + drm_device_t *dev); +extern void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev); #if __REALLY_HAVE_AGP extern agp_memory *DRM(alloc_agp)(int pages, u32 type); diff -Nru a/drivers/char/drm/drm_bufs.h b/drivers/char/drm/drm_bufs.h --- a/drivers/char/drm/drm_bufs.h Thu Aug 29 22:23:24 2002 +++ b/drivers/char/drm/drm_bufs.h Thu Aug 29 22:23:24 2002 @@ -107,7 +107,7 @@ switch ( map->type ) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: -#if !defined(__sparc__) && !defined(__alpha__) +#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) if ( map->offset + map->size < map->offset || map->offset < virt_to_phys(high_memory) ) { DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); @@ -124,7 +124,7 @@ MTRR_TYPE_WRCOMB, 1 ); } #endif - map->handle = DRM(ioremap)( map->offset, map->size ); + map->handle = DRM(ioremap)( map->offset, map->size, dev ); break; case _DRM_SHM: @@ -245,7 +245,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - DRM(ioremapfree)(map->handle, map->size); + DRM(ioremapfree)(map->handle, map->size, dev); break; case _DRM_SHM: vfree(map->handle); diff -Nru a/drivers/char/drm/drm_drv.h b/drivers/char/drm/drm_drv.h --- a/drivers/char/drm/drm_drv.h Thu Aug 29 22:23:24 2002 +++ b/drivers/char/drm/drm_drv.h Thu Aug 29 22:23:24 2002 @@ -439,7 +439,7 @@ DRM_DEBUG( "mtrr_del=%d\n", retcode ); } #endif - DRM(ioremapfree)( map->handle, map->size ); + DRM(ioremapfree)( map->handle, map->size, dev ); break; case _DRM_SHM: vfree(map->handle); diff -Nru a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h --- a/drivers/char/drm/drm_memory.h Thu Aug 29 22:23:24 2002 +++ b/drivers/char/drm/drm_memory.h Thu Aug 29 22:23:24 2002 @@ -33,6 +33,10 @@ #include #include "drmP.h" #include +#include + +#include +#include typedef struct drm_mem_stats { const char *name; @@ -291,17 +295,108 @@ } } -void *DRM(ioremap)(unsigned long offset, unsigned long size) +#if __REALLY_HAVE_AGP + +/* + * Find the drm_map that covers the range [offset, offset+size). + */ +static inline drm_map_t * +DRM(lookup_map)(unsigned long offset, unsigned long size, drm_device_t *dev) +{ + struct list_head *list; + drm_map_list_t *r_list; + drm_map_t *map; + + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *) list; + map = r_list->map; + if (!map) + continue; + if (map->offset <= offset && (offset + size) <= (map->offset + map->size)) + return map; + } + return NULL; +} + +static inline void * +DRM(agp_remap) (unsigned long offset, unsigned long size, drm_device_t *dev) { + unsigned long *phys_addr_map, i, num_pages = PAGE_ALIGN(size) / PAGE_SIZE; + struct page **page_map, **page_map_ptr; + struct drm_agp_mem *agpmem; + struct vm_struct *area; + + + size = PAGE_ALIGN(size); + + for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) + if (agpmem->bound <= offset + && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= (offset + size)) + break; + if (!agpmem) + return NULL; + + /* + * OK, we're mapping AGP space on a chipset/platform on which memory accesses by + * the CPU do not get remapped by the GART. We fix this by using the kernel's + * page-table instead (that's probably faster anyhow...). + */ + area = get_vm_area(size, VM_AGP_REMAP); + if (!area) + return NULL; + + flush_cache_all(); + + /* note: use vmalloc() because num_pages could be large... */ + page_map = vmalloc(num_pages * sizeof(struct page *)); + if (!page_map) + return NULL; + + phys_addr_map = agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE; + for (i = 0; i < num_pages; ++i) + page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT); + page_map_ptr = page_map; + if (map_vm_area(area, PAGE_AGP, &page_map_ptr) < 0) { + vunmap(area->addr); + vfree(page_map); + return NULL; + } + vfree(page_map); + + flush_tlb_kernel_range(area->addr, area->addr + size); + return area->addr; +} + +#else /* !__REALLY_HAVE_AGP */ + +static inline void * +DRM(agp_remap) (unsigned long offset, unsigned long size, drm_device_t *dev) { return NULL; } + +#endif /* !__REALLY_HAVE_AGP */ + +void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev) +{ + int remap_aperture = 0; void *pt; if (!size) { - DRM_MEM_ERROR(DRM_MEM_MAPPINGS, - "Mapping 0 bytes at 0x%08lx\n", offset); + DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Mapping 0 bytes at 0x%08lx\n", offset); return NULL; } - if (!(pt = ioremap(offset, size))) { +#if __REALLY_HAVE_AGP + if (dev->agp->cant_use_aperture) { + drm_map_t *map = DRM(lookup_map)(offset, size, dev); + + if (map && map->type == _DRM_AGP) + remap_aperture = 1; + } +#endif + if (remap_aperture) + pt = DRM(agp_remap)(offset, size, dev); + else + pt = ioremap(offset, size); + if (!pt) { spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; spin_unlock(&DRM(mem_lock)); @@ -314,8 +409,9 @@ return pt; } -void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) +void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev) { + int remap_aperture = 0; void *pt; if (!size) { @@ -324,7 +420,19 @@ return NULL; } - if (!(pt = ioremap_nocache(offset, size))) { +#if __REALLY_HAVE_AGP + if (dev->agp->cant_use_aperture) { + drm_map_t *map = DRM(lookup_map)(offset, size, dev); + + if (map && map->type == _DRM_AGP) + remap_aperture = 1; + } +#endif + if (remap_aperture) + pt = DRM(agp_remap)(offset, size, dev); + else + pt = ioremap_nocache(offset, size); + if (!pt) { spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; spin_unlock(&DRM(mem_lock)); @@ -337,7 +445,7 @@ return pt; } -void DRM(ioremapfree)(void *pt, unsigned long size) +void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev) { int alloc_count; int free_count; @@ -345,8 +453,14 @@ if (!pt) DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Attempt to free NULL pointer\n"); - else - iounmap(pt); + else { +#if __REALLY_HAVE_AGP + if (dev->agp->cant_use_aperture && (vgetflags(pt) & VM_AGP_REMAP)) + vunmap(pt); + else +#endif + iounmap(pt); + } spin_lock(&DRM(mem_lock)); DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size; diff -Nru a/drivers/char/drm/drm_vm.h b/drivers/char/drm/drm_vm.h --- a/drivers/char/drm/drm_vm.h Thu Aug 29 22:23:25 2002 +++ b/drivers/char/drm/drm_vm.h Thu Aug 29 22:23:25 2002 @@ -108,12 +108,12 @@ * Get the page, inc the use count, and return it */ offset = (baddr - agpmem->bound) >> PAGE_SHIFT; - agpmem->memory->memory[offset] &= dev->agp->page_mask; page = virt_to_page(__va(agpmem->memory->memory[offset])); get_page(page); - DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx\n", - baddr, __va(agpmem->memory->memory[offset]), offset); + DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n", + baddr, __va(agpmem->memory->memory[offset]), offset, + atomic_read(&page->count)); return page; } @@ -207,7 +207,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - DRM(ioremapfree)(map->handle, map->size); + DRM(ioremapfree)(map->handle, map->size, dev); break; case _DRM_SHM: vfree(map->handle); @@ -421,15 +421,16 @@ switch (map->type) { case _DRM_AGP: -#if defined(__alpha__) +#if __REALLY_HAVE_AGP + if (dev->agp->cant_use_aperture) { /* - * On Alpha we can't talk to bus dma address from the - * CPU, so for memory of type DRM_AGP, we'll deal with - * sorting out the real physical pages and mappings - * in nopage() + * On some platforms we can't talk to bus dma address from the CPU, so for + * memory of type DRM_AGP, we'll deal with sorting out the real physical + * pages and mappings in nopage() */ vma->vm_ops = &DRM(vm_ops); break; + } #endif /* fall through to _DRM_FRAME_BUFFER... */ case _DRM_FRAME_BUFFER: @@ -440,15 +441,15 @@ pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT; } -#elif defined(__ia64__) - if (map->type != _DRM_AGP) - vma->vm_page_prot = - pgprot_writecombine(vma->vm_page_prot); #elif defined(__powerpc__) pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED; #endif vma->vm_flags |= VM_IO; /* not in core dump */ } +#if defined(__ia64__) + if (map->type != _DRM_AGP) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); +#endif offset = DRIVER_GET_REG_OFS(); #ifdef __sparc__ if (io_remap_page_range(DRM_RPR_ARG(vma) vma->vm_start, diff -Nru a/drivers/char/drm/gamma_dma.c b/drivers/char/drm/gamma_dma.c --- a/drivers/char/drm/gamma_dma.c Thu Aug 29 22:23:25 2002 +++ b/drivers/char/drm/gamma_dma.c Thu Aug 29 22:23:25 2002 @@ -638,7 +638,7 @@ } else { DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->buffers, dev ); buf = dma->buflist[GLINT_DRI_BUF_COUNT]; pgt = buf->address; @@ -668,7 +668,7 @@ if ( dev->dev_private ) { drm_gamma_private_t *dev_priv = dev->dev_private; - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); DRM(free)( dev->dev_private, sizeof(drm_gamma_private_t), DRM_MEM_DRIVER ); diff -Nru a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c --- a/drivers/char/drm/i810_dma.c Thu Aug 29 22:23:24 2002 +++ b/drivers/char/drm/i810_dma.c Thu Aug 29 22:23:24 2002 @@ -309,7 +309,7 @@ if(dev_priv->ring.virtual_start) { DRM(ioremapfree)((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size); + dev_priv->ring.Size, dev); } if(dev_priv->hw_status_page != 0UL) { i810_free_page(dev, dev_priv->hw_status_page); @@ -323,7 +323,7 @@ for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev); } } return 0; @@ -395,7 +395,7 @@ *buf_priv->in_use = I810_BUF_FREE; buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, - buf->total); + buf->total, dev); } return 0; } @@ -448,7 +448,7 @@ dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + init->ring_start, - init->ring_size); + init->ring_size, dev); if (dev_priv->ring.virtual_start == NULL) { dev->dev_private = (void *) dev_priv; diff -Nru a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c --- a/drivers/char/drm/i830_dma.c Thu Aug 29 22:23:24 2002 +++ b/drivers/char/drm/i830_dma.c Thu Aug 29 22:23:24 2002 @@ -340,7 +340,7 @@ if(dev_priv->ring.virtual_start) { DRM(ioremapfree)((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size); + dev_priv->ring.Size, dev); } if(dev_priv->hw_status_page != 0UL) { i830_free_page(dev, dev_priv->hw_status_page); @@ -354,7 +354,7 @@ for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i830_buf_priv_t *buf_priv = buf->dev_private; - DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev); } } return 0; @@ -426,7 +426,7 @@ *buf_priv->in_use = I830_BUF_FREE; buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, - buf->total); + buf->total, dev); } return 0; } @@ -483,7 +483,7 @@ dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + init->ring_start, - init->ring_size); + init->ring_size, dev); if (dev_priv->ring.virtual_start == NULL) { dev->dev_private = (void *) dev_priv; diff -Nru a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c --- a/drivers/char/drm/mga_dma.c Thu Aug 29 22:23:24 2002 +++ b/drivers/char/drm/mga_dma.c Thu Aug 29 22:23:24 2002 @@ -545,9 +545,9 @@ (drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle + init->sarea_priv_offset); - DRM_IOREMAP( dev_priv->warp ); - DRM_IOREMAP( dev_priv->primary ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->warp, dev ); + DRM_IOREMAP( dev_priv->primary, dev ); + DRM_IOREMAP( dev_priv->buffers, dev ); if(!dev_priv->warp->handle || !dev_priv->primary->handle || @@ -633,9 +633,9 @@ if ( dev->dev_private ) { drm_mga_private_t *dev_priv = dev->dev_private; - DRM_IOREMAPFREE( dev_priv->warp ); - DRM_IOREMAPFREE( dev_priv->primary ); - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->warp, dev ); + DRM_IOREMAPFREE( dev_priv->primary, dev ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); if ( dev_priv->head != NULL ) { mga_freelist_cleanup( dev ); diff -Nru a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h --- a/drivers/char/drm/mga_drv.h Thu Aug 29 22:23:25 2002 +++ b/drivers/char/drm/mga_drv.h Thu Aug 29 22:23:25 2002 @@ -235,7 +235,7 @@ if ( MGA_VERBOSE ) { \ DRM_INFO( "BEGIN_DMA( %d ) in %s\n", \ (n), __func__ ); \ - DRM_INFO( " space=0x%x req=0x%x\n", \ + DRM_INFO( " space=0x%x req=0x%Zx\n", \ dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \ } \ prim = dev_priv->prim.start; \ @@ -285,7 +285,7 @@ #define DMA_WRITE( offset, val ) \ do { \ if ( MGA_VERBOSE ) { \ - DRM_INFO( " DMA_WRITE( 0x%08x ) at 0x%04x\n", \ + DRM_INFO( " DMA_WRITE( 0x%08x ) at 0x%04Zx\n", \ (u32)(val), write + (offset) * sizeof(u32) ); \ } \ *(volatile u32 *)(prim + write + (offset) * sizeof(u32)) = val; \ diff -Nru a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c --- a/drivers/char/drm/r128_cce.c Thu Aug 29 22:23:24 2002 +++ b/drivers/char/drm/r128_cce.c Thu Aug 29 22:23:24 2002 @@ -350,8 +350,8 @@ R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, entry->busaddr[page_ofs]); - DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n", - entry->busaddr[page_ofs], + DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n", + (unsigned long) entry->busaddr[page_ofs], entry->handle + tmp_ofs ); } @@ -540,9 +540,9 @@ init->sarea_priv_offset); if ( !dev_priv->is_pci ) { - DRM_IOREMAP( dev_priv->cce_ring ); - DRM_IOREMAP( dev_priv->ring_rptr ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->cce_ring, dev ); + DRM_IOREMAP( dev_priv->ring_rptr, dev ); + DRM_IOREMAP( dev_priv->buffers, dev ); if(!dev_priv->cce_ring->handle || !dev_priv->ring_rptr->handle || !dev_priv->buffers->handle) { @@ -618,9 +618,9 @@ #if __REALLY_HAVE_SG if ( !dev_priv->is_pci ) { #endif - DRM_IOREMAPFREE( dev_priv->cce_ring ); - DRM_IOREMAPFREE( dev_priv->ring_rptr ); - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->cce_ring, dev ); + DRM_IOREMAPFREE( dev_priv->ring_rptr, dev ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); #if __REALLY_HAVE_SG } else { if (!DRM(ati_pcigart_cleanup)( dev, diff -Nru a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c --- a/drivers/char/drm/radeon_cp.c Thu Aug 29 22:23:24 2002 +++ b/drivers/char/drm/radeon_cp.c Thu Aug 29 22:23:24 2002 @@ -904,8 +904,8 @@ RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); - DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n", - entry->busaddr[page_ofs], + DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n", + (unsigned long) entry->busaddr[page_ofs], entry->handle + tmp_ofs ); } @@ -1139,9 +1139,9 @@ init->sarea_priv_offset); if ( !dev_priv->is_pci ) { - DRM_IOREMAP( dev_priv->cp_ring ); - DRM_IOREMAP( dev_priv->ring_rptr ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->cp_ring, dev ); + DRM_IOREMAP( dev_priv->ring_rptr, dev ); + DRM_IOREMAP( dev_priv->buffers, dev ); if(!dev_priv->cp_ring->handle || !dev_priv->ring_rptr->handle || !dev_priv->buffers->handle) { @@ -1260,9 +1260,9 @@ drm_radeon_private_t *dev_priv = dev->dev_private; if ( !dev_priv->is_pci ) { - DRM_IOREMAPFREE( dev_priv->cp_ring ); - DRM_IOREMAPFREE( dev_priv->ring_rptr ); - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->cp_ring, dev ); + DRM_IOREMAPFREE( dev_priv->ring_rptr, dev ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); } else { #if __REALLY_HAVE_SG if (!DRM(ati_pcigart_cleanup)( dev, diff -Nru a/drivers/char/efirtc.c b/drivers/char/efirtc.c --- a/drivers/char/efirtc.c Thu Aug 29 22:23:25 2002 +++ b/drivers/char/efirtc.c Thu Aug 29 22:23:25 2002 @@ -35,8 +35,8 @@ #include #include #include +#include -#include #include #include diff -Nru a/drivers/char/mem.c b/drivers/char/mem.c --- a/drivers/char/mem.c Thu Aug 29 22:23:25 2002 +++ b/drivers/char/mem.c Thu Aug 29 22:23:25 2002 @@ -511,10 +511,12 @@ case 0: file->f_pos = offset; ret = file->f_pos; + force_successful_syscall_return(); break; case 1: file->f_pos += offset; ret = file->f_pos; + force_successful_syscall_return(); break; default: ret = -EINVAL; diff -Nru a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile --- a/drivers/media/radio/Makefile Thu Aug 29 22:23:25 2002 +++ b/drivers/media/radio/Makefile Thu Aug 29 22:23:25 2002 @@ -5,6 +5,8 @@ # All of the (potential) objects that export symbols. # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. +obj-y := dummy.o + export-objs := miropcm20-rds-core.o miropcm20-objs := miropcm20-rds-core.o miropcm20-radio.o diff -Nru a/drivers/media/radio/dummy.c b/drivers/media/radio/dummy.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/media/radio/dummy.c Thu Aug 29 22:23:25 2002 @@ -0,0 +1 @@ +/* just so the linker knows what kind of object files it's deadling with... */ diff -Nru a/drivers/media/video/Makefile b/drivers/media/video/Makefile --- a/drivers/media/video/Makefile Thu Aug 29 22:23:24 2002 +++ b/drivers/media/video/Makefile Thu Aug 29 22:23:24 2002 @@ -5,7 +5,8 @@ # All of the (potential) objects that export symbols. # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. -export-objs := videodev.o bttv-if.o cpia.o video-buf.o +obj-y := dummy.o + bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ bttv-risc.o bttv-vbi.o diff -Nru a/drivers/media/video/dummy.c b/drivers/media/video/dummy.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/media/video/dummy.c Thu Aug 29 22:23:25 2002 @@ -0,0 +1 @@ +/* just so the linker knows what kind of object files it's deadling with... */ diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c --- a/drivers/message/fusion/mptscsih.c Thu Aug 29 22:23:24 2002 +++ b/drivers/message/fusion/mptscsih.c Thu Aug 29 22:23:24 2002 @@ -99,6 +99,8 @@ MODULE_PARM(mptscsih, "s"); #endif +static spinlock_t detect_lock = SPIN_LOCK_UNLOCKED; + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ typedef struct _BIG_SENSE_BUF { @@ -1156,8 +1158,7 @@ #endif sh = scsi_register(tpnt, sizeof(MPT_SCSI_HOST)); if (sh != NULL) { - save_flags(flags); - cli(); + spin_lock_irqsave(&detect_lock, flags); sh->io_port = 0; sh->n_io_port = 0; sh->irq = 0; @@ -1221,7 +1222,7 @@ */ scsi_set_pci_device(sh, this->pcidev); - restore_flags(flags); + spin_unlock_irqrestore(&detect_lock, flags); hd = (MPT_SCSI_HOST *) sh->hostdata; hd->ioc = this; diff -Nru a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c --- a/drivers/net/tulip/media.c Thu Aug 29 22:23:24 2002 +++ b/drivers/net/tulip/media.c Thu Aug 29 22:23:24 2002 @@ -278,6 +278,10 @@ for (i = 0; i < init_length; i++) outl(init_sequence[i], ioaddr + CSR12); } + + (void) inl(ioaddr + CSR6); /* flush CSR12 writes */ + udelay(500); /* Give MII time to recover */ + tmp_info = get_u16(&misc_info[1]); if (tmp_info) tp->advertising[phy_num] = tmp_info | 1; diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c --- a/drivers/scsi/megaraid.c Thu Aug 29 22:23:24 2002 +++ b/drivers/scsi/megaraid.c Thu Aug 29 22:23:24 2002 @@ -2047,7 +2047,7 @@ return; mbox = (mega_mailbox *) pScb->mboxData; - printk ("%u cmd:%x id:%x #scts:%x lba:%x addr:%x logdrv:%x #sg:%x\n", + printk ("%lu cmd:%x id:%x #scts:%x lba:%x addr:%x logdrv:%x #sg:%x\n", pScb->SCpnt->pid, mbox->cmd, mbox->cmdid, mbox->numsectors, mbox->lba, mbox->xferaddr, mbox->logdrv, mbox->numsgelements); @@ -3356,9 +3356,13 @@ mbox[0] = IS_BIOS_ENABLED; mbox[2] = GET_BIOS; - mboxpnt->xferaddr = virt_to_bus ((void *) megacfg->mega_buffer); + mboxpnt->xferaddr = pci_map_single(megacfg->dev, + (void *) megacfg->mega_buffer, (2 * 1024L), + PCI_DMA_FROMDEVICE); ret = megaIssueCmd (megacfg, mbox, NULL, 0); + + pci_unmap_single(megacfg->dev, mboxpnt->xferaddr, 2 * 1024L, PCI_DMA_FROMDEVICE); return (*(char *) megacfg->mega_buffer); } diff -Nru a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c --- a/drivers/scsi/scsi_ioctl.c Thu Aug 29 22:23:25 2002 +++ b/drivers/scsi/scsi_ioctl.c Thu Aug 29 22:23:25 2002 @@ -196,6 +196,9 @@ unsigned int needed, buf_needed; int timeout, retries, result; int data_direction, gfp_mask = GFP_KERNEL; +#if __GNUC__ < 3 + int foo; +#endif if (!sic) return -EINVAL; @@ -209,11 +212,21 @@ if (verify_area(VERIFY_READ, sic, sizeof(Scsi_Ioctl_Command))) return -EFAULT; +#if __GNUC__ < 3 + foo = __get_user(inlen, &sic->inlen); + if (foo) + return -EFAULT; + + foo = __get_user(outlen, &sic->outlen); + if (foo) + return -EFAULT; +#else if(__get_user(inlen, &sic->inlen)) return -EFAULT; if(__get_user(outlen, &sic->outlen)) return -EFAULT; +#endif /* * We do not transfer more than MAX_BUF with this interface. diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c --- a/drivers/scsi/sym53c8xx_2/sym_glue.c Thu Aug 29 22:23:25 2002 +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c Thu Aug 29 22:23:25 2002 @@ -295,11 +295,7 @@ #ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING typedef u_long bus_addr_t; #else -#if SYM_CONF_DMA_ADDRESSING_MODE > 0 -typedef dma64_addr_t bus_addr_t; -#else typedef dma_addr_t bus_addr_t; -#endif #endif /* diff -Nru a/drivers/scsi/sym53c8xx_2/sym_malloc.c b/drivers/scsi/sym53c8xx_2/sym_malloc.c --- a/drivers/scsi/sym53c8xx_2/sym_malloc.c Thu Aug 29 22:23:25 2002 +++ b/drivers/scsi/sym53c8xx_2/sym_malloc.c Thu Aug 29 22:23:25 2002 @@ -143,12 +143,14 @@ a = (m_addr_t) ptr; while (1) { -#ifdef SYM_MEM_FREE_UNUSED if (s == SYM_MEM_CLUSTER_SIZE) { +#ifdef SYM_MEM_FREE_UNUSED M_FREE_MEM_CLUSTER(a); - break; - } +#else + ((m_link_p) a)->next = h[i].next; + h[i].next = (m_link_p) a; #endif + } b = a ^ s; q = &h[i]; while (q->next && q->next != (m_link_p) b) { diff -Nru a/drivers/serial/8250.c b/drivers/serial/8250.c --- a/drivers/serial/8250.c Thu Aug 29 22:23:24 2002 +++ b/drivers/serial/8250.c Thu Aug 29 22:23:24 2002 @@ -1909,6 +1909,17 @@ return 0; } +int __init early_register_port (struct uart_port *port) +{ + if (port->line >= ARRAY_SIZE(serial8250_ports)) + return -ENODEV; + + serial8250_isa_init_ports(); /* force ISA defaults */ + serial8250_ports[port->line].port = *port; + serial8250_ports[port->line].port.ops = &serial8250_pops; + return 0; +} + /** * unregister_serial - remove a 16x50 serial port at runtime * @line: serial line number diff -Nru a/drivers/serial/8250_acpi.c b/drivers/serial/8250_acpi.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/serial/8250_acpi.c Thu Aug 29 22:23:25 2002 @@ -0,0 +1,179 @@ +/* + * linux/drivers/char/acpi_serial.c + * + * Copyright (C) 2000, 20002 Hewlett-Packard Co. + * Khalid Aziz + * + * Detect and initialize the headless console serial port defined in SPCR table and debug + * serial port defined in DBGP table. + * + * 2002/08/29 davidm Adjust it to new 2.5 serial driver infrastructure. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#undef SERIAL_DEBUG_ACPI + +/* + * Query ACPI tables for a debug and a headless console serial port. If found, add them to + * rs_table[]. A pointer to either SPCR or DBGP table is passed as parameter. This + * function should be called before serial_console_init() is called to make sure the SPCR + * serial console will be available for use. IA-64 kernel calls this function from within + * acpi.c when it encounters SPCR or DBGP tables as it parses the ACPI 2.0 tables during + * bootup. + */ +void __init +setup_serial_acpi (void *tablep) +{ + acpi_ser_t *acpi_ser_p; + struct uart_port port; + unsigned long iobase; + int gsi; + extern int early_register_port (struct uart_port *); /* XXX fix me */ + +#ifdef SERIAL_DEBUG_ACPI + printk("Entering setup_serial_acpi()\n"); +#endif + + /* Now get the table */ + if (!tablep) + return; + + memset(&port, 0, sizeof(port)); + + acpi_ser_p = (acpi_ser_t *) tablep; + + /* + * Perform a sanity check on the table. Table should have a signature of "SPCR" or + * "DBGP" and it should be atleast 52 bytes long. + */ + if (strncmp(acpi_ser_p->signature, ACPI_SPCRT_SIGNATURE, ACPI_SIG_LEN) != 0 && + strncmp(acpi_ser_p->signature, ACPI_DBGPT_SIGNATURE, ACPI_SIG_LEN) != 0) + return; + if (acpi_ser_p->length < 52) + return; + + iobase = (((u64) acpi_ser_p->base_addr.addrh) << 32) | acpi_ser_p->base_addr.addrl; + gsi = ( (acpi_ser_p->global_int[3] << 24) | (acpi_ser_p->global_int[2] << 16) + | (acpi_ser_p->global_int[1] << 8) | (acpi_ser_p->global_int[0] << 0)); + +#ifdef SERIAL_DEBUG_ACPI + printk("setup_serial_acpi(): table pointer = 0x%p\n", acpi_ser_p); + printk(" sig = '%c%c%c%c'\n", acpi_ser_p->signature[0], + acpi_ser_p->signature[1], acpi_ser_p->signature[2], acpi_ser_p->signature[3]); + printk(" length = %d\n", acpi_ser_p->length); + printk(" Rev = %d\n", acpi_ser_p->rev); + printk(" Interface type = %d\n", acpi_ser_p->intfc_type); + printk(" Base address = 0x%lX\n", iobase); + printk(" IRQ = %d\n", acpi_ser_p->irq); + printk(" Global System Int = %d\n", gsi); + printk(" Baud rate = "); + switch (acpi_ser_p->baud) { + case ACPI_SERIAL_BAUD_9600: + printk("9600\n"); + break; + + case ACPI_SERIAL_BAUD_19200: + printk("19200\n"); + break; + + case ACPI_SERIAL_BAUD_57600: + printk("57600\n"); + break; + + case ACPI_SERIAL_BAUD_115200: + printk("115200\n"); + break; + + default: + printk("Huh (%d)\n", acpi_ser_p->baud); + break; + } + if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_PCICONF_SPACE) { + printk(" PCI serial port:\n"); + printk(" Bus %d, Device %d, Vendor ID 0x%x, Dev ID 0x%x\n", + acpi_ser_p->pci_bus, acpi_ser_p->pci_dev, + acpi_ser_p->pci_vendor_id, acpi_ser_p->pci_dev_id); + } +#endif + /* + * Now build a serial_req structure to update the entry in rs_table for the + * headless console port. + */ + switch (acpi_ser_p->intfc_type) { + case ACPI_SERIAL_INTFC_16550: + port.type = PORT_16550; + port.uartclk = BASE_BAUD * 16; + break; + + case ACPI_SERIAL_INTFC_16450: + port.type = PORT_16450; + port.uartclk = BASE_BAUD * 16; + break; + + default: + port.type = PORT_UNKNOWN; + break; + } + if (strncmp(acpi_ser_p->signature, ACPI_SPCRT_SIGNATURE, ACPI_SIG_LEN) == 0) + port.line = ACPI_SERIAL_CONSOLE_PORT; + else if (strncmp(acpi_ser_p->signature, ACPI_DBGPT_SIGNATURE, ACPI_SIG_LEN) == 0) + port.line = ACPI_SERIAL_DEBUG_PORT; + /* + * Check if this is an I/O mapped address or a memory mapped address + */ + if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_MEM_SPACE) { + port.iobase = 0; + port.mapbase = iobase; + port.membase = ioremap(iobase, 64); + port.iotype = SERIAL_IO_MEM; + } else if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_IO_SPACE) { + port.iobase = iobase; + port.mapbase = 0; + port.membase = NULL; + port.iotype = SERIAL_IO_PORT; + } else if (acpi_ser_p->base_addr.space_id == ACPI_SERIAL_PCICONF_SPACE) { + printk("WARNING: No support for PCI serial console\n"); + return; + } + + /* + * If the table does not have IRQ information, use 0 for IRQ. This will force + * rs_init() to probe for IRQ. + */ + if (acpi_ser_p->length < 53) + port.irq = 0; + else { + port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_AUTO_IRQ; + if (acpi_ser_p->int_type & (ACPI_SERIAL_INT_APIC | ACPI_SERIAL_INT_SAPIC)) + port.irq = gsi; + else if (acpi_ser_p->int_type & ACPI_SERIAL_INT_PCAT) + port.irq = acpi_ser_p->irq; + else + /* + * IRQ type not being set would mean UART will run in polling + * mode. Do not probe for IRQ in that case. + */ + port.flags &= UPF_AUTO_IRQ; + } + port.fifosize = 0; + port.hub6 = 0; + port.regshift = 0; + if (early_register_port(&port) < 0) { + printk("early_register_port() for ACPI serial console port failed\n"); + return; + } + +#ifdef SERIAL_DEBUG_ACPI + printk("Leaving setup_serial_acpi()\n"); +#endif +} diff -Nru a/drivers/serial/8250_hcdp.c b/drivers/serial/8250_hcdp.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/serial/8250_hcdp.c Thu Aug 29 22:23:25 2002 @@ -0,0 +1,242 @@ +/* + * linux/drivers/char/hcdp_serial.c + * + * Copyright (C) 2002 Hewlett-Packard Co. + * Khalid Aziz + * + * Parse the EFI HCDP table to locate serial console and debug ports and initialize them. + * + * 2002/08/29 davidm Adjust it to new 2.5 serial driver infrastructure (untested). + */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define SERIAL_DEBUG_HCDP + +/* + * Parse the HCDP table to find descriptions for headless console and debug serial ports + * and add them to rs_table[]. A pointer to HCDP table is passed as parameter. This + * function should be called before serial_console_init() is called to make sure the HCDP + * serial console will be available for use. IA-64 kernel calls this function from + * setup_arch() after the EFI and ACPI tables have been parsed. + */ +void __init +setup_serial_hcdp (void *tablep) +{ + hcdp_dev_t *hcdp_dev; + struct uart_port port; + unsigned long iobase; + hcdp_t hcdp; + int gsi, i = 0, nr; +#if 0 + static int shift_once = 1; +#endif + extern int early_register_port (struct uart_port *); /* XXX fix me */ + +#ifdef SERIAL_DEBUG_HCDP + printk("Entering setup_serial_hcdp()\n"); +#endif + + /* Verify we have a valid table pointer */ + if (!tablep) + return; + + memset(&port, 0, sizeof(port)); + + /* + * Don't trust firmware to give us a table starting at an aligned address. Make a + * local copy of the HCDP table with aligned structures. + */ + memcpy(&hcdp, tablep, sizeof(hcdp)); + + /* + * Perform a sanity check on the table. Table should have a signature of "HCDP" + * and it should be atleast 82 bytes long to have any useful information. + */ + if ((strncmp(hcdp.signature, HCDP_SIGNATURE, HCDP_SIG_LEN) != 0)) + return; + if (hcdp.len < 82) + return; + +#ifdef SERIAL_DEBUG_HCDP + printk("setup_serial_hcdp(): table pointer = 0x%p\n", tablep); + printk(" sig = '%c%c%c%c'\n", + hcdp.signature[0], hcdp.signature[1], hcdp.signature[2], hcdp.signature[3]); + printk(" length = %d\n", hcdp.len); + printk(" Rev = %d\n", hcdp.rev); + printk(" OEM ID = %c%c%c%c%c%c\n", + hcdp.oemid[0], hcdp.oemid[1], hcdp.oemid[2], + hcdp.oemid[3], hcdp.oemid[4], hcdp.oemid[5]); + printk(" Number of entries = %d\n", hcdp.num_entries); +#endif + + /* + * Parse each device entry + */ + for (nr = 0; nr < hcdp.num_entries; nr++) { + hcdp_dev = hcdp.hcdp_dev + nr; + /* + * We will parse only the primary console device which is the first entry + * for these devices. We will ignore rest of the entries for the same type + * device that has already been parsed and initialized + */ + if (hcdp_dev->type != HCDP_DEV_CONSOLE) + continue; + + iobase = ((u64) hcdp_dev->base_addr.addrhi << 32) | hcdp_dev->base_addr.addrlo; + gsi = hcdp_dev->global_int; +#ifdef SERIAL_DEBUG_HCDP + printk(" type = %s\n", + ((hcdp_dev->type == HCDP_DEV_CONSOLE) + ? "Headless Console" : ((hcdp_dev->type == HCDP_DEV_DEBUG) + ? "Debug port" : "Huh????"))); + printk(" Base address space = %s\n", + ((hcdp_dev->base_addr.space_id == ACPI_MEM_SPACE) + ? "Memory Space" : ((hcdp_dev->base_addr.space_id == ACPI_IO_SPACE) + ? "I/O space" : "PCI space"))); + printk(" Base address = 0x%lx\n", iobase); + printk(" Global System Int = %d\n", gsi); + printk(" Baud rate = %lu\n", (unsigned long) hcdp_dev->baud); + printk(" Bits = %d\n", hcdp_dev->bits); + printk(" Clock rate = %d\n", hcdp_dev->clock_rate); + if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE) { + printk(" PCI serial port:\n"); + printk(" Bus %d, Device %d, Vendor ID 0x%x, Dev ID 0x%x\n", + hcdp_dev->pci_bus, hcdp_dev->pci_dev, + hcdp_dev->pci_vendor_id, hcdp_dev->pci_dev_id); + } +#endif + /* + * Now fill in a port structure to update the 8250 port table.. + */ + if (hcdp_dev->clock_rate) + port.uartclk = hcdp_dev->clock_rate; + else + port.uartclk = DEFAULT_UARTCLK; + /* + * Check if this is an I/O mapped address or a memory mapped address + */ + if (hcdp_dev->base_addr.space_id == ACPI_MEM_SPACE) { + port.iobase = 0; + port.mapbase = iobase; + port.membase = ioremap(iobase, 64); + port.iotype = SERIAL_IO_MEM; + } else if (hcdp_dev->base_addr.space_id == ACPI_IO_SPACE) { + port.iobase = iobase; + port.mapbase = 0; + port.membase = NULL; + port.iotype = SERIAL_IO_PORT; + } else if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE) { + printk("WARNING: No support for PCI serial console\n"); + return; + } + +#if 0 + /* + * Check if HCDP defines a port already in rs_table + */ + for (i = 0; i < serial_nr_ports; i++) { + if ((rs_table[i].port == serial_req.port) && + (rs_table[i].iomem_base==serial_req.iomem_base)) + break; + } + if (i == serial_nr_ports) { + /* + * We have reserved a slot for HCDP defined console port at + * HCDP_SERIAL_CONSOLE_PORT in rs_table which is not 0. This means + * using this slot would put the console at a device other than + * ttyS0. Users expect to see the console at ttyS0. Now that we + * have determined HCDP does describe a serial console and it is + * not one of the compiled in ports, let us move the entries in + * rs_table up by a slot towards HCDP_SERIAL_CONSOLE_PORT to make + * room for the HCDP console at ttyS0. We may go through this loop + * more than once if early_serial_setup() fails. Make sure we + * shift the entries in rs_table only once. + */ + if (shift_once) { + int j; + + for (j = HCDP_SERIAL_CONSOLE_PORT; j > 0; j--) + memcpy(rs_table+j, rs_table+j-1, + sizeof(struct serial_state)); + shift_once = 0; + } + serial_req.line = 0; + } else + serial_req.line = i; +#else + port.line = i++; /* XXX fix me */ +#endif + + port.irq = gsi; + port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; + if (gsi) + port.flags |= ASYNC_AUTO_IRQ; + + port.fifosize = 0; + port.hub6 = 0; + port.regshift = 0; + if (early_register_port(&port) < 0) { + printk("setup_serial_hcdp(): early_register_port() for HCDP serial " + "console port failed. Will try any additional consoles in HCDP.\n"); + continue; + } else if (hcdp_dev->type == HCDP_DEV_CONSOLE) + break; +#ifdef SERIAL_DEBUG_HCDP + printk("\n"); +#endif + } + +#ifdef SERIAL_DEBUG_HCDP + 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 /* CONFIG_IA64_EARLY_PRINTK_UART */ diff -Nru a/drivers/serial/Config.in b/drivers/serial/Config.in --- a/drivers/serial/Config.in Thu Aug 29 22:23:24 2002 +++ b/drivers/serial/Config.in Thu Aug 29 22:23:24 2002 @@ -11,6 +11,10 @@ dep_tristate '8250/16550 and compatible serial support (EXPERIMENTAL)' CONFIG_SERIAL_8250 $CONFIG_EXPERIMENTAL dep_bool ' Console on 8250/16550 and compatible serial port (EXPERIMENTAL)' CONFIG_SERIAL_8250_CONSOLE $CONFIG_SERIAL_8250 $CONFIG_EXPERIMENTAL dep_tristate ' 8250/16550 PCMCIA device support' CONFIG_SERIAL_8250_CS $CONFIG_PCMCIA $CONFIG_SERIAL_8250 +if [ "$CONFIG_IA64" = "y" ]; then + dep_tristate ' 8250/16550 device discovery support via ACPI SPCR/DBGP tables' CONFIG_SERIAL_8250_ACPI + dep_tristate ' 8250/16550 device discovery support via EFI HCDP table' CONFIG_SERIAL_8250_HCDP +fi dep_mbool 'Extended 8250/16550 serial driver options' CONFIG_SERIAL_8250_EXTENDED $CONFIG_SERIAL_8250 dep_bool ' Support more than 4 serial ports' CONFIG_SERIAL_8250_MANY_PORTS $CONFIG_SERIAL_8250_EXTENDED diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile --- a/drivers/serial/Makefile Thu Aug 29 22:23:25 2002 +++ b/drivers/serial/Makefile Thu Aug 29 22:23:25 2002 @@ -9,6 +9,8 @@ serial-8250-y := serial-8250-$(CONFIG_PCI) += 8250_pci.o serial-8250-$(CONFIG_ISAPNP) += 8250_pnp.o +obj-$(CONFIG_SERIAL_8250_ACPI) += 8250_acpi.o +obj-$(CONFIG_SERIAL_8250_HCDP) += 8250_hcdp.o obj-$(CONFIG_SERIAL_CORE) += core.o obj-$(CONFIG_SERIAL_21285) += 21285.o obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y) diff -Nru a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c --- a/drivers/video/radeonfb.c Thu Aug 29 22:23:25 2002 +++ b/drivers/video/radeonfb.c Thu Aug 29 22:23:25 2002 @@ -233,8 +233,8 @@ u32 mmio_base_phys; u32 fb_base_phys; - u32 mmio_base; - u32 fb_base; + void *mmio_base; + void *fb_base; struct pci_dev *pdev; @@ -727,8 +727,7 @@ } /* map the regions */ - rinfo->mmio_base = (u32) ioremap (rinfo->mmio_base_phys, - RADEON_REGSIZE); + rinfo->mmio_base = ioremap (rinfo->mmio_base_phys, RADEON_REGSIZE); if (!rinfo->mmio_base) { printk ("radeonfb: cannot map MMIO\n"); release_mem_region (rinfo->mmio_base_phys, @@ -858,8 +857,7 @@ } } - rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys, - rinfo->video_ram); + rinfo->fb_base = ioremap (rinfo->fb_base_phys, rinfo->video_ram); if (!rinfo->fb_base) { printk ("radeonfb: cannot map FB\n"); iounmap ((void*)rinfo->mmio_base); diff -Nru a/fs/fcntl.c b/fs/fcntl.c --- a/fs/fcntl.c Thu Aug 29 22:23:24 2002 +++ b/fs/fcntl.c Thu Aug 29 22:23:24 2002 @@ -303,6 +303,7 @@ * to fix this will be in libc. */ err = filp->f_owner.pid; + force_successful_syscall_return(); break; case F_SETOWN: lock_kernel(); diff -Nru a/fs/partitions/efi.h b/fs/partitions/efi.h --- a/fs/partitions/efi.h Thu Aug 29 22:23:24 2002 +++ b/fs/partitions/efi.h Thu Aug 29 22:23:24 2002 @@ -33,11 +33,7 @@ #include #include #include -/* - * Yes, specifying asm-ia64 is ugly, but this lets it build on - * other platforms too, until efi.h moves to include/linux. - */ -#include +#include #define MSDOS_MBR_SIGNATURE 0xaa55 #define EFI_PMBR_OSTYPE_EFI 0xEF diff -Nru a/fs/proc/base.c b/fs/proc/base.c --- a/fs/proc/base.c Thu Aug 29 22:23:24 2002 +++ b/fs/proc/base.c Thu Aug 29 22:23:24 2002 @@ -508,7 +508,24 @@ } #endif +static loff_t mem_lseek(struct file * file, loff_t offset, int orig) +{ + switch (orig) { + case 0: + file->f_pos = offset; + break; + case 1: + file->f_pos += offset; + break; + default: + return -EINVAL; + } + force_successful_syscall_return(); + return file->f_pos; +} + static struct file_operations proc_mem_operations = { + llseek: mem_lseek, read: mem_read, write: mem_write, open: mem_open, diff -Nru a/include/asm-alpha/agp.h b/include/asm-alpha/agp.h --- a/include/asm-alpha/agp.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-alpha/agp.h Thu Aug 29 22:23:24 2002 @@ -8,4 +8,11 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() +/* + * Page-protection value to be used for AGP memory mapped into kernel space. For + * platforms which use coherent AGP DMA, this can be PAGE_KERNEL. For others, it needs to + * be an uncached mapping (such as write-combining). + */ +#define PAGE_AGP PAGE_KERNEL_NOCACHE /* XXX fix me */ + #endif diff -Nru a/include/asm-i386/agp.h b/include/asm-i386/agp.h --- a/include/asm-i386/agp.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-i386/agp.h Thu Aug 29 22:23:24 2002 @@ -20,4 +20,11 @@ worth it. Would need a page for it. */ #define flush_agp_cache() asm volatile("wbinvd":::"memory") +/* + * Page-protection value to be used for AGP memory mapped into kernel space. For + * platforms which use coherent AGP DMA, this can be PAGE_KERNEL. For others, it needs to + * be an uncached mapping (such as write-combining). + */ +#define PAGE_AGP PAGE_KERNEL_NOCACHE + #endif diff -Nru a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h --- a/include/asm-i386/hw_irq.h Thu Aug 29 22:23:25 2002 +++ b/include/asm-i386/hw_irq.h Thu Aug 29 22:23:25 2002 @@ -107,4 +107,6 @@ static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {} #endif +extern irq_desc_t irq_desc [NR_IRQS]; + #endif /* _ASM_HW_IRQ_H */ diff -Nru a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h --- a/include/asm-i386/ptrace.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-i386/ptrace.h Thu Aug 29 22:23:24 2002 @@ -58,6 +58,7 @@ #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) #define instruction_pointer(regs) ((regs)->eip) extern void show_regs(struct pt_regs *); +#define force_successful_syscall_return() do { } while (0) #endif #endif diff -Nru a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h --- a/include/asm-ia64/acpi.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-ia64/acpi.h Thu Aug 29 22:23:24 2002 @@ -100,7 +100,8 @@ int acpi_boot_init (char *cdline); 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_get_interrupt_model (int *type); +int acpi_irq_to_vector (u32 irq); #ifdef CONFIG_DISCONTIGMEM #define NODE_ARRAY_INDEX(x) ((x) / 8) /* 8 bits/char */ diff -Nru a/include/asm-ia64/agp.h b/include/asm-ia64/agp.h --- a/include/asm-ia64/agp.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-ia64/agp.h Thu Aug 29 22:23:24 2002 @@ -18,4 +18,7 @@ #define flush_agp_mappings() /* nothing */ #define flush_agp_cache() mb() +/* Page-protection value to be used for AGP memory mapped into kernel space. */ +#define PAGE_AGP PAGE_KERNEL + #endif /* _ASM_IA64_AGP_H */ diff -Nru a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h --- a/include/asm-ia64/atomic.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-ia64/atomic.h Thu Aug 29 22:23:24 2002 @@ -9,8 +9,8 @@ * "int" types were carefully placed so as to ensure proper operation * of the macros. * - * Copyright (C) 1998, 1999 Hewlett-Packard Co - * Copyright (C) 1998, 1999 David Mosberger-Tang + * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co + * David Mosberger-Tang */ #include diff -Nru a/include/asm-ia64/efi.h b/include/asm-ia64/efi.h --- a/include/asm-ia64/efi.h Thu Aug 29 22:23:25 2002 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,284 +0,0 @@ -#ifndef _ASM_IA64_EFI_H -#define _ASM_IA64_EFI_H - -/* - * Extensible Firmware Interface - * Based on 'Extensible Firmware Interface Specification' version 0.9, April 30, 1999 - * - * Copyright (C) 1999 VA Linux Systems - * Copyright (C) 1999 Walt Drummond - * Copyright (C) 1999, 2002 Hewlett-Packard Co. - * David Mosberger-Tang - * Stephane Eranian - */ -#include -#include -#include -#include -#include - -#include -#include - -#define EFI_SUCCESS 0 -#define EFI_LOAD_ERROR (1L | (1L << 63)) -#define EFI_INVALID_PARAMETER (2L | (1L << 63)) -#define EFI_UNSUPPORTED (3L | (1L << 63)) -#define EFI_BAD_BUFFER_SIZE (4L | (1L << 63)) -#define EFI_BUFFER_TOO_SMALL (5L | (1L << 63)) -#define EFI_NOT_FOUND (14L | (1L << 63)) - -typedef unsigned long efi_status_t; -typedef u8 efi_bool_t; -typedef u16 efi_char16_t; /* UNICODE character */ - - -typedef struct { - u8 b[16]; -} efi_guid_t; - -#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \ -((efi_guid_t) \ -{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ - (b) & 0xff, ((b) >> 8) & 0xff, \ - (c) & 0xff, ((c) >> 8) & 0xff, \ - (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}) - -/* - * Generic EFI table header - */ -typedef struct { - u64 signature; - u32 revision; - u32 headersize; - u32 crc32; - u32 reserved; -} efi_table_hdr_t; - -/* - * Memory map descriptor: - */ - -/* Memory types: */ -#define EFI_RESERVED_TYPE 0 -#define EFI_LOADER_CODE 1 -#define EFI_LOADER_DATA 2 -#define EFI_BOOT_SERVICES_CODE 3 -#define EFI_BOOT_SERVICES_DATA 4 -#define EFI_RUNTIME_SERVICES_CODE 5 -#define EFI_RUNTIME_SERVICES_DATA 6 -#define EFI_CONVENTIONAL_MEMORY 7 -#define EFI_UNUSABLE_MEMORY 8 -#define EFI_ACPI_RECLAIM_MEMORY 9 -#define EFI_ACPI_MEMORY_NVS 10 -#define EFI_MEMORY_MAPPED_IO 11 -#define EFI_MEMORY_MAPPED_IO_PORT_SPACE 12 -#define EFI_PAL_CODE 13 -#define EFI_MAX_MEMORY_TYPE 14 - -/* Attribute values: */ -#define EFI_MEMORY_UC 0x0000000000000001 /* uncached */ -#define EFI_MEMORY_WC 0x0000000000000002 /* write-coalescing */ -#define EFI_MEMORY_WT 0x0000000000000004 /* write-through */ -#define EFI_MEMORY_WB 0x0000000000000008 /* write-back */ -#define EFI_MEMORY_WP 0x0000000000001000 /* write-protect */ -#define EFI_MEMORY_RP 0x0000000000002000 /* read-protect */ -#define EFI_MEMORY_XP 0x0000000000004000 /* execute-protect */ -#define EFI_MEMORY_RUNTIME 0x8000000000000000 /* range requires runtime mapping */ -#define EFI_MEMORY_DESCRIPTOR_VERSION 1 - -#define EFI_PAGE_SHIFT 12 - -typedef struct { - u32 type; - u32 pad; - u64 phys_addr; - u64 virt_addr; - u64 num_pages; - u64 attribute; -} efi_memory_desc_t; - -typedef int efi_freemem_callback_t (u64 start, u64 end, void *arg); - -/* - * Types and defines for Time Services - */ -#define EFI_TIME_ADJUST_DAYLIGHT 0x1 -#define EFI_TIME_IN_DAYLIGHT 0x2 -#define EFI_UNSPECIFIED_TIMEZONE 0x07ff - -typedef struct { - u16 year; - u8 month; - u8 day; - u8 hour; - u8 minute; - u8 second; - u8 pad1; - u32 nanosecond; - s16 timezone; - u8 daylight; - u8 pad2; -} efi_time_t; - -typedef struct { - u32 resolution; - u32 accuracy; - u8 sets_to_zero; -} efi_time_cap_t; - -/* - * Types and defines for EFI ResetSystem - */ -#define EFI_RESET_COLD 0 -#define EFI_RESET_WARM 1 - -/* - * EFI Runtime Services table - */ -#define EFI_RUNTIME_SERVICES_SIGNATURE 0x5652453544e5552 -#define EFI_RUNTIME_SERVICES_REVISION 0x00010000 - -typedef struct { - efi_table_hdr_t hdr; - u64 get_time; - u64 set_time; - u64 get_wakeup_time; - u64 set_wakeup_time; - u64 set_virtual_address_map; - u64 convert_pointer; - u64 get_variable; - u64 get_next_variable; - u64 set_variable; - u64 get_next_high_mono_count; - u64 reset_system; -} efi_runtime_services_t; - -typedef efi_status_t efi_get_time_t (efi_time_t *tm, efi_time_cap_t *tc); -typedef efi_status_t efi_set_time_t (efi_time_t *tm); -typedef efi_status_t efi_get_wakeup_time_t (efi_bool_t *enabled, efi_bool_t *pending, - efi_time_t *tm); -typedef efi_status_t efi_set_wakeup_time_t (efi_bool_t enabled, efi_time_t *tm); -typedef efi_status_t efi_get_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 *attr, - unsigned long *data_size, void *data); -typedef efi_status_t efi_get_next_variable_t (unsigned long *name_size, efi_char16_t *name, - efi_guid_t *vendor); -typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 attr, - unsigned long data_size, void *data); -typedef efi_status_t efi_get_next_high_mono_count_t (u64 *count); -typedef void efi_reset_system_t (int reset_type, efi_status_t status, - unsigned long data_size, efi_char16_t *data); - -/* - * EFI Configuration Table and GUID definitions - */ -#define NULL_GUID \ - EFI_GUID( 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ) - -#define MPS_TABLE_GUID \ - EFI_GUID( 0xeb9d2d2f, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d ) - -#define ACPI_TABLE_GUID \ - EFI_GUID( 0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d ) - -#define ACPI_20_TABLE_GUID \ - EFI_GUID( 0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 ) - -#define SMBIOS_TABLE_GUID \ - EFI_GUID( 0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d ) - -#define SAL_SYSTEM_TABLE_GUID \ - EFI_GUID( 0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d ) - -#define HCDP_TABLE_GUID \ - EFI_GUID( 0xf951938d, 0x620b, 0x42ef, 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 ) - -typedef struct { - efi_guid_t guid; - u64 table; -} efi_config_table_t; - -#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249 -#define EFI_SYSTEM_TABLE_REVISION ((1 << 16) | 00) - -typedef struct { - efi_table_hdr_t hdr; - u64 fw_vendor; /* physical addr of CHAR16 vendor string */ - u32 fw_revision; - u64 con_in_handle; - u64 con_in; - u64 con_out_handle; - u64 con_out; - u64 stderr_handle; - u64 stderr; - u64 runtime; - u64 boottime; - u64 nr_tables; - u64 tables; -} efi_system_table_t; - -/* - * All runtime access to EFI goes through this structure: - */ -extern struct efi { - efi_system_table_t *systab; /* EFI system table */ - void *mps; /* MPS table */ - void *acpi; /* ACPI table (IA64 ext 0.71) */ - void *acpi20; /* ACPI table (ACPI 2.0) */ - void *smbios; /* SM BIOS table */ - void *sal_systab; /* SAL system table */ - void *boot_info; /* boot info table */ - void *hcdp; /* HCDP table */ - efi_get_time_t *get_time; - efi_set_time_t *set_time; - efi_get_wakeup_time_t *get_wakeup_time; - efi_set_wakeup_time_t *set_wakeup_time; - efi_get_variable_t *get_variable; - efi_get_next_variable_t *get_next_variable; - efi_set_variable_t *set_variable; - efi_get_next_high_mono_count_t *get_next_high_mono_count; - efi_reset_system_t *reset_system; -} efi; - -static inline int -efi_guidcmp (efi_guid_t left, efi_guid_t right) -{ - return memcmp(&left, &right, sizeof (efi_guid_t)); -} - -static inline char * -efi_guid_unparse(efi_guid_t *guid, char *out) -{ - sprintf(out, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - guid->b[3], guid->b[2], guid->b[1], guid->b[0], - guid->b[5], guid->b[4], guid->b[7], guid->b[6], - guid->b[8], guid->b[9], guid->b[10], guid->b[11], - guid->b[12], guid->b[13], guid->b[14], guid->b[15]); - return out; -} - -extern void efi_init (void); -extern void efi_map_pal_code (void); -extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg); -extern void efi_gettimeofday (struct timeval *tv); -extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if possible */ -extern u64 efi_get_iobase (void); -extern u32 efi_mem_type (unsigned long phys_addr); -extern u64 efi_mem_attributes (unsigned long phys_addr); - -/* - * Variable Attributes - */ -#define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 -#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 -#define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 - - -/* - * efi_dir is allocated in arch/ia64/kernel/efi.c. - */ -#ifdef CONFIG_PROC_FS -extern struct proc_dir_entry *efi_dir; -#endif - -#endif /* _ASM_IA64_EFI_H */ diff -Nru a/include/asm-ia64/fpu.h b/include/asm-ia64/fpu.h --- a/include/asm-ia64/fpu.h Thu Aug 29 22:23:25 2002 +++ b/include/asm-ia64/fpu.h Thu Aug 29 22:23:25 2002 @@ -2,8 +2,8 @@ #define _ASM_IA64_FPU_H /* - * Copyright (C) 1998, 1999 Hewlett-Packard Co - * Copyright (C) 1998, 1999 David Mosberger-Tang + * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co + * David Mosberger-Tang */ #include diff -Nru a/include/asm-ia64/hardirq.h b/include/asm-ia64/hardirq.h --- a/include/asm-ia64/hardirq.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-ia64/hardirq.h Thu Aug 29 22:23:24 2002 @@ -92,12 +92,12 @@ # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET #endif -#define irq_exit() \ -do { \ - preempt_count() -= IRQ_EXIT_OFFSET; \ - if (!in_interrupt() && softirq_pending(smp_processor_id())) \ - do_softirq(); \ - preempt_enable_no_resched(); \ +#define irq_exit() \ +do { \ + preempt_count() -= IRQ_EXIT_OFFSET; \ + if (!in_interrupt() && local_softirq_pending()) \ + do_softirq(); \ + preempt_enable_no_resched(); \ } while (0) #ifdef CONFIG_SMP diff -Nru a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h --- a/include/asm-ia64/hw_irq.h Thu Aug 29 22:23:25 2002 +++ b/include/asm-ia64/hw_irq.h Thu Aug 29 22:23:25 2002 @@ -53,6 +53,10 @@ #define IA64_IPI_RESCHEDULE 0xfd /* SMP reschedule */ #define IA64_IPI_VECTOR 0xfe /* inter-processor interrupt vector */ +/* Used for encoding redirected irqs */ + +#define IA64_IRQ_REDIRECTED (1 << 31) + /* IA64 inter-cpu interrupt related definitions */ #define IA64_IPI_DEFAULT_BASE_ADDR 0xfee00000 @@ -68,14 +72,12 @@ 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; extern struct hw_interrupt_type irq_type_ia64_lsapic; /* CPU-internal interrupt controller */ -extern int ia64_alloc_irq (void); /* allocate a free irq */ +extern int ia64_alloc_vector (void); /* allocate a free vector */ extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); diff -Nru a/include/asm-ia64/ide.h b/include/asm-ia64/ide.h --- a/include/asm-ia64/ide.h Thu Aug 29 22:23:25 2002 +++ b/include/asm-ia64/ide.h Thu Aug 29 22:23:25 2002 @@ -85,10 +85,24 @@ for(index = 0; index < MAX_HWIFS; index++) { ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL); hw.irq = ide_default_irq(ide_default_io_base(index)); - ide_register_hw(&hw); + ide_register_hw(&hw, NULL); } #endif } + +#define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id)) +#define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id)) +#define ide_check_region(from,extent) check_region((from), (extent)) +#define ide_request_region(from,extent,name) request_region((from), (extent), (name)) +#define ide_release_region(from,extent) release_region((from), (extent)) + +/* + * The following are not needed for the non-m68k ports + */ +#define ide_ack_intr(hwif) (1) +#define ide_fix_driveid(id) do {} while (0) +#define ide_release_lock(lock) do {} while (0) +#define ide_get_lock(lock, hdlr, data) do {} while (0) #endif /* __KERNEL__ */ diff -Nru a/include/asm-ia64/io.h b/include/asm-ia64/io.h --- a/include/asm-ia64/io.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-ia64/io.h Thu Aug 29 22:23:24 2002 @@ -13,7 +13,7 @@ * over and over again with slight variations and possibly making a * mistake somewhere. * - * Copyright (C) 1998-2001 Hewlett-Packard Co + * Copyright (C) 1998-2002 Hewlett-Packard Co * David Mosberger-Tang * Copyright (C) 1999 Asit Mallick * Copyright (C) 1999 Don Dugger @@ -277,9 +277,9 @@ } /* - * Unfortunately, some platforms are broken and do not follow the - * IA-64 architecture specification regarding legacy I/O support. - * Thus, we have to make these operations platform dependent... + * Unfortunately, some platforms are broken and do not follow the IA-64 architecture + * specification regarding legacy I/O support. Thus, we have to make these operations + * platform dependent... */ #define __inb platform_inb #define __inw platform_inw @@ -289,19 +289,19 @@ #define __outl platform_outl #define __mmiob platform_mmiob -#define inb __inb -#define inw __inw -#define inl __inl -#define insb __insb -#define insw __insw -#define insl __insl -#define outb __outb -#define outw __outw -#define outl __outl -#define outsb __outsb -#define outsw __outsw -#define outsl __outsl -#define mmiob __mmiob +#define inb(p) __inb(p) +#define inw(p) __inw(p) +#define inl(p) __inl(p) +#define insb(p,d,c) __insb(p,d,c) +#define insw(p,d,c) __insw(p,d,c) +#define insl(p,d,c) __insl(p,d,c) +#define outb(v,p) __outb(v,p) +#define outw(v,p) __outw(v,p) +#define outl(v,p) __outl(v,p) +#define outsb(p,s,c) __outsb(p,s,c) +#define outsw(p,s,c) __outsw(p,s,c) +#define outsl(p,s,c) __outsl(p,s,c) +#define mmiob() __mmiob() /* * The address passed to these functions are ioremap()ped already. diff -Nru a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h --- a/include/asm-ia64/iosapic.h Thu Aug 29 22:23:25 2002 +++ b/include/asm-ia64/iosapic.h Thu Aug 29 22:23:25 2002 @@ -51,17 +51,24 @@ #ifndef __ASSEMBLY__ -extern void __init iosapic_init (unsigned long address, unsigned int base_irq, - int pcat_compat); -extern int iosapic_register_irq (u32 global_vector, unsigned long polarity, - unsigned long edge_triggered, u32 base_irq, - char *iosapic_address); -extern void iosapic_register_legacy_irq (unsigned long irq, unsigned long pin, - unsigned long polarity, unsigned long trigger); -extern int iosapic_register_platform_irq (u32 int_type, u32 global_vector, u32 iosapic_vector, - u16 eid, u16 id, unsigned long polarity, - unsigned long edge_triggered, u32 base_irq, - char *iosapic_address); +extern void __devinit iosapic_init (unsigned long address, + unsigned int gsi_base, + int pcat_compat); +extern int gsi_to_vector (unsigned int gsi); +extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity, + unsigned long edge_triggered, + u32 gsi_base, char *iosapic_address); +extern void iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, + unsigned long polarity, + unsigned long edge_triggered); +extern int iosapic_register_platform_intr (u32 int_type, + unsigned int gsi, + int pmi_vector, + u16 eid, u16 id, + unsigned long polarity, + unsigned long edge_triggered, + unsigned int gsi_base, + char *iosapic_address); extern unsigned int iosapic_version (char *addr); extern void iosapic_pci_fixup (int); diff -Nru a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h --- a/include/asm-ia64/irq.h Thu Aug 29 22:23:25 2002 +++ b/include/asm-ia64/irq.h Thu Aug 29 22:23:25 2002 @@ -27,6 +27,6 @@ extern void disable_irq (unsigned int); extern void disable_irq_nosync (unsigned int); extern void enable_irq (unsigned int); -extern void set_irq_affinity_info (int irq, int dest, int redir); +extern void set_irq_affinity_info (unsigned int irq, int dest, int redir); #endif /* _ASM_IA64_IRQ_H */ diff -Nru a/include/asm-ia64/kmap_types.h b/include/asm-ia64/kmap_types.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-ia64/kmap_types.h Thu Aug 29 22:23:25 2002 @@ -0,0 +1,29 @@ +#ifndef _ASM_IA64_KMAP_TYPES_H +#define _ASM_IA64_KMAP_TYPES_H + +#include + +#if CONFIG_DEBUG_HIGHMEM +# define D(n) __KM_FENCE_##n , +#else +# define D(n) +#endif + +enum km_type { +D(0) KM_BOUNCE_READ, +D(1) KM_SKB_SUNRPC_DATA, +D(2) KM_SKB_DATA_SOFTIRQ, +D(3) KM_USER0, +D(4) KM_USER1, +D(5) KM_BIO_SRC_IRQ, +D(6) KM_BIO_DST_IRQ, +D(7) KM_PTE0, +D(8) KM_PTE1, +D(9) KM_IRQ0, +D(10) KM_IRQ1, +D(11) KM_TYPE_NR +}; + +#undef D + +#endif /* _ASM_IA64_KMAP_TYPES_H */ diff -Nru a/include/asm-ia64/mc146818rtc.h b/include/asm-ia64/mc146818rtc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-ia64/mc146818rtc.h Thu Aug 29 22:23:25 2002 @@ -0,0 +1,10 @@ +#ifndef _ASM_IA64_MC146818RTC_H +#define _ASM_IA64_MC146818RTC_H + +/* + * Machine dependent access functions for RTC registers. + */ + +/* empty include file to satisfy the include in genrtc.c */ + +#endif /* _ASM_IA64_MC146818RTC_H */ diff -Nru a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h --- a/include/asm-ia64/mmu_context.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-ia64/mmu_context.h Thu Aug 29 22:23:24 2002 @@ -36,7 +36,7 @@ }; extern struct ia64_ctx ia64_ctx; -extern u8 ia64_need_tlb_flush __per_cpu_data; +DECLARE_PER_CPU(u8, ia64_need_tlb_flush); extern void wrap_mmu_context (struct mm_struct *mm); @@ -56,9 +56,9 @@ { extern void __flush_tlb_all (void); - if (unlikely(ia64_need_tlb_flush)) { + if (unlikely(__get_cpu_var(ia64_need_tlb_flush))) { __flush_tlb_all(); - ia64_need_tlb_flush = 0; + __get_cpu_var(ia64_need_tlb_flush) = 0; } } diff -Nru a/include/asm-ia64/percpu.h b/include/asm-ia64/percpu.h --- a/include/asm-ia64/percpu.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-ia64/percpu.h Thu Aug 29 22:23:24 2002 @@ -1,6 +1,9 @@ #ifndef _ASM_IA64_PERCPU_H #define _ASM_IA64_PERCPU_H +#include +#include + /* * Copyright (C) 2002 Hewlett-Packard Co * David Mosberger-Tang @@ -8,7 +11,7 @@ #ifdef __ASSEMBLY__ -#define THIS_CPU(var) (var##__per_cpu) /* use this to mark accesses to per-CPU variables... */ +#define THIS_CPU(var) (var##__per_cpu) /* use this to mark accesses to per-CPU variables... */ #else /* !__ASSEMBLY__ */ @@ -22,8 +25,12 @@ #endif #define DECLARE_PER_CPU(type, name) extern __typeof__(type) name##__per_cpu -#define per_cpu(var, cpu) (*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset[cpu])) #define __get_cpu_var(var) (var##__per_cpu) +#ifdef CONFIG_SMP +# define per_cpu(var, cpu) (*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset[cpu])) +#else +# define per_cpu(var, cpu) __get_cpu_var(var) +#endif #endif /* !__ASSEMBLY__ */ diff -Nru a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h --- a/include/asm-ia64/processor.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-ia64/processor.h Thu Aug 29 22:23:24 2002 @@ -15,9 +15,6 @@ #include -#include -#include - #include #include #include @@ -81,8 +78,10 @@ #ifndef __ASSEMBLY__ -#include #include +#include +#include +#include #include #include diff -Nru a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h --- a/include/asm-ia64/sal.h Thu Aug 29 22:23:25 2002 +++ b/include/asm-ia64/sal.h Thu Aug 29 22:23:25 2002 @@ -24,9 +24,9 @@ */ #include +#include #include -#include #include #include @@ -535,7 +535,7 @@ u64 reg_data_pairs[1]; /* array of address/data register pairs is num_mem_regs + num_io_regs elements long. Each array element consists of a u64 address followed - by a u64 data value. The oem_data array immediately follows the the + by a u64 data value. The oem_data array immediately follows the reg_data_pairs array */ u8 oem_data[1]; /* Variable length data */ } sal_log_pci_comp_err_info_t; diff -Nru a/include/asm-ia64/sn/alenlist.h b/include/asm-ia64/sn/alenlist.h --- a/include/asm-ia64/sn/alenlist.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-ia64/sn/alenlist.h Thu Aug 29 22:23:24 2002 @@ -15,7 +15,7 @@ /* * An Address/Length List is used when setting up for an I/O DMA operation. - * A driver creates an Address/Length List that describes to the the DMA + * A driver creates an Address/Length List that describes to the DMA * interface where in memory the DMA should go. The bus interface sets up * mapping registers, if required, and returns a suitable list of "physical * addresses" or "I/O address" to the driver. The driver then uses these diff -Nru a/include/asm-ia64/system.h b/include/asm-ia64/system.h --- a/include/asm-ia64/system.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-ia64/system.h Thu Aug 29 22:23:24 2002 @@ -13,7 +13,6 @@ * Copyright (C) 1999 Don Dugger */ #include -#include #include #include @@ -26,6 +25,7 @@ #ifndef __ASSEMBLY__ +#include #include #include @@ -368,8 +368,8 @@ extern void ia64_load_extra (struct task_struct *task); #if defined(CONFIG_SMP) && defined(CONFIG_PERFMON) - extern int __per_cpu_data pfm_syst_wide; -# define PERFMON_IS_SYSWIDE() (this_cpu(pfm_syst_wide) != 0) + DECLARE_PER_CPU(int, pfm_syst_wide); +# define PERFMON_IS_SYSWIDE() (get_cpu_var(pfm_syst_wide) != 0) #else # define PERFMON_IS_SYSWIDE() (0) #endif diff -Nru a/include/asm-ia64/types.h b/include/asm-ia64/types.h --- a/include/asm-ia64/types.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-ia64/types.h Thu Aug 29 22:23:24 2002 @@ -2,14 +2,13 @@ #define _ASM_IA64_TYPES_H /* - * This file is never included by application software unless - * explicitly requested (e.g., via linux/types.h) in which case the - * application is Linux specific so (user-) name space pollution is - * not a major issue. However, for interoperability, libraries still + * This file is never included by application software unless explicitly requested (e.g., + * via linux/types.h) in which case the application is Linux specific so (user-) name + * space pollution is not a major issue. However, for interoperability, libraries still * need to be careful to avoid a name clashes. * - * Copyright (C) 1998-2000 Hewlett-Packard Co - * Copyright (C) 1998-2000 David Mosberger-Tang + * Copyright (C) 1998-2000, 2002 Hewlett-Packard Co + * David Mosberger-Tang */ #ifdef __ASSEMBLY__ @@ -18,9 +17,6 @@ #else # define __IA64_UL(x) ((unsigned long)(x)) # define __IA64_UL_CONST(x) x##UL -#endif - -#ifndef __ASSEMBLY__ typedef unsigned int umode_t; diff -Nru a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h --- a/include/asm-ia64/unistd.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-ia64/unistd.h Thu Aug 29 22:23:24 2002 @@ -223,10 +223,15 @@ #define __NR_sched_setaffinity 1231 #define __NR_sched_getaffinity 1232 #define __NR_security 1233 -#define __NR_get_large_pages 1234 -#define __NR_free_large_pages 1235 -#define __NR_share_large_pages 1236 -#define __NR_unshare_large_pages 1237 +#define __NR_alloc_hugepages 1234 +#define __NR_free_hugepages 1235 +/* 1236 currently unused */ +/* 1237 currently unused */ +#define __NR_io_setup 1238 +#define __NR_io_destroy 1239 +#define __NR_io_getevents 1240 +#define __NR_io_submit 1241 +#define __NR_io_cancel 1242 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER) diff -Nru a/include/asm-sparc64/agp.h b/include/asm-sparc64/agp.h --- a/include/asm-sparc64/agp.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-sparc64/agp.h Thu Aug 29 22:23:24 2002 @@ -8,4 +8,11 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() +/* + * Page-protection value to be used for AGP memory mapped into kernel space. For + * platforms which use coherent AGP DMA, this can be PAGE_KERNEL. For others, it needs to + * be an uncached mapping (such as write-combining). + */ +#define PAGE_AGP PAGE_KERNEL_NOCACHE + #endif diff -Nru a/include/asm-x86_64/agp.h b/include/asm-x86_64/agp.h --- a/include/asm-x86_64/agp.h Thu Aug 29 22:23:24 2002 +++ b/include/asm-x86_64/agp.h Thu Aug 29 22:23:24 2002 @@ -20,4 +20,11 @@ worth it. Would need a page for it. */ #define flush_agp_cache() asm volatile("wbinvd":::"memory") +/* + * Page-protection value to be used for AGP memory mapped into kernel space. For + * platforms which use coherent AGP DMA, this can be PAGE_KERNEL. For others, it needs to + * be an uncached mapping (such as write-combining). + */ +#define PAGE_AGP PAGE_KERNEL_NOCACHE + #endif diff -Nru a/include/linux/acpi_serial.h b/include/linux/acpi_serial.h --- a/include/linux/acpi_serial.h Thu Aug 29 22:23:25 2002 +++ b/include/linux/acpi_serial.h Thu Aug 29 22:23:25 2002 @@ -9,6 +9,8 @@ * */ +#include + extern void setup_serial_acpi(void *); #define ACPI_SIG_LEN 4 diff -Nru a/include/linux/efi.h b/include/linux/efi.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/efi.h Thu Aug 29 22:23:25 2002 @@ -0,0 +1,284 @@ +#ifndef _LINUX_EFI_H +#define _LINUX_EFI_H + +/* + * Extensible Firmware Interface + * Based on 'Extensible Firmware Interface Specification' version 0.9, April 30, 1999 + * + * Copyright (C) 1999 VA Linux Systems + * Copyright (C) 1999 Walt Drummond + * Copyright (C) 1999, 2002 Hewlett-Packard Co. + * David Mosberger-Tang + * Stephane Eranian + */ +#include +#include +#include +#include +#include + +#include +#include + +#define EFI_SUCCESS 0 +#define EFI_LOAD_ERROR (1L | (1L << 63)) +#define EFI_INVALID_PARAMETER (2L | (1L << 63)) +#define EFI_UNSUPPORTED (3L | (1L << 63)) +#define EFI_BAD_BUFFER_SIZE (4L | (1L << 63)) +#define EFI_BUFFER_TOO_SMALL (5L | (1L << 63)) +#define EFI_NOT_FOUND (14L | (1L << 63)) + +typedef unsigned long efi_status_t; +typedef u8 efi_bool_t; +typedef u16 efi_char16_t; /* UNICODE character */ + + +typedef struct { + u8 b[16]; +} efi_guid_t; + +#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \ +((efi_guid_t) \ +{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ + (b) & 0xff, ((b) >> 8) & 0xff, \ + (c) & 0xff, ((c) >> 8) & 0xff, \ + (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}) + +/* + * Generic EFI table header + */ +typedef struct { + u64 signature; + u32 revision; + u32 headersize; + u32 crc32; + u32 reserved; +} efi_table_hdr_t; + +/* + * Memory map descriptor: + */ + +/* Memory types: */ +#define EFI_RESERVED_TYPE 0 +#define EFI_LOADER_CODE 1 +#define EFI_LOADER_DATA 2 +#define EFI_BOOT_SERVICES_CODE 3 +#define EFI_BOOT_SERVICES_DATA 4 +#define EFI_RUNTIME_SERVICES_CODE 5 +#define EFI_RUNTIME_SERVICES_DATA 6 +#define EFI_CONVENTIONAL_MEMORY 7 +#define EFI_UNUSABLE_MEMORY 8 +#define EFI_ACPI_RECLAIM_MEMORY 9 +#define EFI_ACPI_MEMORY_NVS 10 +#define EFI_MEMORY_MAPPED_IO 11 +#define EFI_MEMORY_MAPPED_IO_PORT_SPACE 12 +#define EFI_PAL_CODE 13 +#define EFI_MAX_MEMORY_TYPE 14 + +/* Attribute values: */ +#define EFI_MEMORY_UC 0x0000000000000001 /* uncached */ +#define EFI_MEMORY_WC 0x0000000000000002 /* write-coalescing */ +#define EFI_MEMORY_WT 0x0000000000000004 /* write-through */ +#define EFI_MEMORY_WB 0x0000000000000008 /* write-back */ +#define EFI_MEMORY_WP 0x0000000000001000 /* write-protect */ +#define EFI_MEMORY_RP 0x0000000000002000 /* read-protect */ +#define EFI_MEMORY_XP 0x0000000000004000 /* execute-protect */ +#define EFI_MEMORY_RUNTIME 0x8000000000000000 /* range requires runtime mapping */ +#define EFI_MEMORY_DESCRIPTOR_VERSION 1 + +#define EFI_PAGE_SHIFT 12 + +typedef struct { + u32 type; + u32 pad; + u64 phys_addr; + u64 virt_addr; + u64 num_pages; + u64 attribute; +} efi_memory_desc_t; + +typedef int efi_freemem_callback_t (u64 start, u64 end, void *arg); + +/* + * Types and defines for Time Services + */ +#define EFI_TIME_ADJUST_DAYLIGHT 0x1 +#define EFI_TIME_IN_DAYLIGHT 0x2 +#define EFI_UNSPECIFIED_TIMEZONE 0x07ff + +typedef struct { + u16 year; + u8 month; + u8 day; + u8 hour; + u8 minute; + u8 second; + u8 pad1; + u32 nanosecond; + s16 timezone; + u8 daylight; + u8 pad2; +} efi_time_t; + +typedef struct { + u32 resolution; + u32 accuracy; + u8 sets_to_zero; +} efi_time_cap_t; + +/* + * Types and defines for EFI ResetSystem + */ +#define EFI_RESET_COLD 0 +#define EFI_RESET_WARM 1 + +/* + * EFI Runtime Services table + */ +#define EFI_RUNTIME_SERVICES_SIGNATURE 0x5652453544e5552 +#define EFI_RUNTIME_SERVICES_REVISION 0x00010000 + +typedef struct { + efi_table_hdr_t hdr; + u64 get_time; + u64 set_time; + u64 get_wakeup_time; + u64 set_wakeup_time; + u64 set_virtual_address_map; + u64 convert_pointer; + u64 get_variable; + u64 get_next_variable; + u64 set_variable; + u64 get_next_high_mono_count; + u64 reset_system; +} efi_runtime_services_t; + +typedef efi_status_t efi_get_time_t (efi_time_t *tm, efi_time_cap_t *tc); +typedef efi_status_t efi_set_time_t (efi_time_t *tm); +typedef efi_status_t efi_get_wakeup_time_t (efi_bool_t *enabled, efi_bool_t *pending, + efi_time_t *tm); +typedef efi_status_t efi_set_wakeup_time_t (efi_bool_t enabled, efi_time_t *tm); +typedef efi_status_t efi_get_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 *attr, + unsigned long *data_size, void *data); +typedef efi_status_t efi_get_next_variable_t (unsigned long *name_size, efi_char16_t *name, + efi_guid_t *vendor); +typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 attr, + unsigned long data_size, void *data); +typedef efi_status_t efi_get_next_high_mono_count_t (u64 *count); +typedef void efi_reset_system_t (int reset_type, efi_status_t status, + unsigned long data_size, efi_char16_t *data); + +/* + * EFI Configuration Table and GUID definitions + */ +#define NULL_GUID \ + EFI_GUID( 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ) + +#define MPS_TABLE_GUID \ + EFI_GUID( 0xeb9d2d2f, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d ) + +#define ACPI_TABLE_GUID \ + EFI_GUID( 0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d ) + +#define ACPI_20_TABLE_GUID \ + EFI_GUID( 0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 ) + +#define SMBIOS_TABLE_GUID \ + EFI_GUID( 0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d ) + +#define SAL_SYSTEM_TABLE_GUID \ + EFI_GUID( 0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d ) + +#define HCDP_TABLE_GUID \ + EFI_GUID( 0xf951938d, 0x620b, 0x42ef, 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 ) + +typedef struct { + efi_guid_t guid; + u64 table; +} efi_config_table_t; + +#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249 +#define EFI_SYSTEM_TABLE_REVISION ((1 << 16) | 00) + +typedef struct { + efi_table_hdr_t hdr; + u64 fw_vendor; /* physical addr of CHAR16 vendor string */ + u32 fw_revision; + u64 con_in_handle; + u64 con_in; + u64 con_out_handle; + u64 con_out; + u64 stderr_handle; + u64 stderr; + u64 runtime; + u64 boottime; + u64 nr_tables; + u64 tables; +} efi_system_table_t; + +/* + * All runtime access to EFI goes through this structure: + */ +extern struct efi { + efi_system_table_t *systab; /* EFI system table */ + void *mps; /* MPS table */ + void *acpi; /* ACPI table (IA64 ext 0.71) */ + void *acpi20; /* ACPI table (ACPI 2.0) */ + void *smbios; /* SM BIOS table */ + void *sal_systab; /* SAL system table */ + void *boot_info; /* boot info table */ + void *hcdp; /* HCDP table */ + efi_get_time_t *get_time; + efi_set_time_t *set_time; + efi_get_wakeup_time_t *get_wakeup_time; + efi_set_wakeup_time_t *set_wakeup_time; + efi_get_variable_t *get_variable; + efi_get_next_variable_t *get_next_variable; + efi_set_variable_t *set_variable; + efi_get_next_high_mono_count_t *get_next_high_mono_count; + efi_reset_system_t *reset_system; +} efi; + +static inline int +efi_guidcmp (efi_guid_t left, efi_guid_t right) +{ + return memcmp(&left, &right, sizeof (efi_guid_t)); +} + +static inline char * +efi_guid_unparse(efi_guid_t *guid, char *out) +{ + sprintf(out, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + guid->b[3], guid->b[2], guid->b[1], guid->b[0], + guid->b[5], guid->b[4], guid->b[7], guid->b[6], + guid->b[8], guid->b[9], guid->b[10], guid->b[11], + guid->b[12], guid->b[13], guid->b[14], guid->b[15]); + return out; +} + +extern void efi_init (void); +extern void efi_map_pal_code (void); +extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg); +extern void efi_gettimeofday (struct timeval *tv); +extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if possible */ +extern u64 efi_get_iobase (void); +extern u32 efi_mem_type (unsigned long phys_addr); +extern u64 efi_mem_attributes (unsigned long phys_addr); + +/* + * Variable Attributes + */ +#define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 + + +/* + * efi_dir is allocated in arch/ia64/kernel/efi.c. + */ +#ifdef CONFIG_PROC_FS +extern struct proc_dir_entry *efi_dir; +#endif + +#endif /* _LINUX_EFI_H */ diff -Nru a/include/linux/hcdp_serial.h b/include/linux/hcdp_serial.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/hcdp_serial.h Thu Aug 29 22:23:25 2002 @@ -0,0 +1,83 @@ +/* + * linux/include/linux/hcdp_serial.h + * + * Copyright (C) 2002 Hewlett-Packard Co. + * Khalid Aziz + * + * Definitions for HCDP defined serial ports (Serial console and debug + * ports) + */ +#ifndef _LINUX_HCDP_SERIAL_H +#define _LINUX_HCDP_SERIAL_H + +/* ACPI table signatures */ +#define HCDP_SIG_LEN 4 +#define HCDP_SIGNATURE "HCDP" + +/* Space ID as defined in ACPI generic address structure */ +#define ACPI_MEM_SPACE 0 +#define ACPI_IO_SPACE 1 +#define ACPI_PCICONF_SPACE 2 + +/* + * Maximum number of HCDP devices we want to read in + */ +#define MAX_HCDP_DEVICES 6 + +/* + * Default UART clock rate if clock rate is 0 in HCDP table. + */ +#define DEFAULT_UARTCLK 115200 + +/* + * ACPI Generic Address Structure + */ +typedef struct { + u8 space_id; + u8 bit_width; + u8 bit_offset; + u8 resv; + u32 addrlo; + u32 addrhi; +} acpi_gen_addr; + +/* HCDP Device descriptor entry types */ +#define HCDP_DEV_CONSOLE 0 +#define HCDP_DEV_DEBUG 1 + +/* HCDP Device descriptor type */ +typedef struct { + u8 type; + u8 bits; + u8 parity; + u8 stop_bits; + u8 pci_seg; + u8 pci_bus; + u8 pci_dev; + u8 pci_func; + u64 baud; + acpi_gen_addr base_addr; + u16 pci_dev_id; + u16 pci_vendor_id; + u32 global_int; + u32 clock_rate; + u8 pci_prog_intfc; + u8 resv; +} hcdp_dev_t; + +/* HCDP Table format */ +typedef struct { + u8 signature[4]; + u32 len; + u8 rev; + u8 chksum; + u8 oemid[6]; + u8 oem_tabid[8]; + u32 oem_rev; + u8 creator_id[4]; + u32 creator_rev; + u32 num_entries; + hcdp_dev_t hcdp_dev[MAX_HCDP_DEVICES]; +} hcdp_t; + +#endif /* _LINUX_HCDP_SERIAL_H */ diff -Nru a/include/linux/highmem.h b/include/linux/highmem.h --- a/include/linux/highmem.h Thu Aug 29 22:23:24 2002 +++ b/include/linux/highmem.h Thu Aug 29 22:23:24 2002 @@ -3,6 +3,8 @@ #include #include +#include + #include #ifdef CONFIG_HIGHMEM diff -Nru a/include/linux/irq.h b/include/linux/irq.h --- a/include/linux/irq.h Thu Aug 29 22:23:24 2002 +++ b/include/linux/irq.h Thu Aug 29 22:23:24 2002 @@ -56,15 +56,13 @@ * * Pad this out to 32 bytes for cache and indexing reasons. */ -typedef struct { +typedef struct irq_desc { unsigned int status; /* IRQ status */ hw_irq_controller *handler; struct irqaction *action; /* IRQ action list */ unsigned int depth; /* nested irq disables */ spinlock_t lock; } ____cacheline_aligned irq_desc_t; - -extern irq_desc_t irq_desc [NR_IRQS]; #include /* the arch dependent stuff */ diff -Nru a/include/linux/irq_cpustat.h b/include/linux/irq_cpustat.h --- a/include/linux/irq_cpustat.h Thu Aug 29 22:23:24 2002 +++ b/include/linux/irq_cpustat.h Thu Aug 29 22:23:24 2002 @@ -24,7 +24,7 @@ #define __IRQ_STAT(cpu, member) (irq_stat[cpu].member) #else #define __IRQ_STAT(cpu, member) ((void)(cpu), irq_stat[0].member) -#endif +#endif #endif /* arch independent irq_stat fields */ @@ -33,5 +33,10 @@ #define ksoftirqd_task(cpu) __IRQ_STAT((cpu), __ksoftirqd_task) /* arch dependent irq_stat fields */ #define nmi_count(cpu) __IRQ_STAT((cpu), __nmi_count) /* i386, ia64 */ + +#define local_softirq_pending() softirq_pending(smp_processor_id()) +#define local_syscall_count() syscall_count(smp_processor_id()) +#define local_ksoftirqd_task() ksoftirqd_task(smp_processor_id()) +#define local_nmi_count() nmi_count(smp_processor_id()) #endif /* __irq_cpustat_h */ diff -Nru a/include/linux/kernel.h b/include/linux/kernel.h --- a/include/linux/kernel.h Thu Aug 29 22:23:24 2002 +++ b/include/linux/kernel.h Thu Aug 29 22:23:24 2002 @@ -38,6 +38,13 @@ #define KERN_INFO "<6>" /* informational */ #define KERN_DEBUG "<7>" /* debug-level messages */ +extern int console_printk[]; + +#define console_loglevel (console_printk[0]) +#define default_message_loglevel (console_printk[1]) +#define minimum_console_loglevel (console_printk[2]) +#define default_console_loglevel (console_printk[3]) + struct completion; extern struct notifier_block *panic_notifier_list; @@ -73,8 +80,6 @@ asmlinkage int printk(const char * fmt, ...) __attribute__ ((format (printf, 1, 2))); - -extern int console_loglevel; static inline void console_silent(void) { diff -Nru a/include/linux/mm.h b/include/linux/mm.h --- a/include/linux/mm.h Thu Aug 29 22:23:24 2002 +++ b/include/linux/mm.h Thu Aug 29 22:23:24 2002 @@ -182,6 +182,36 @@ }; /* + * inlines for acquisition and release of PG_chainlock + */ +static inline void pte_chain_lock(struct page *page) +{ + /* + * Assuming the lock is uncontended, this never enters + * the body of the outer loop. If it is contended, then + * within the inner loop a non-atomic test is used to + * busywait with less bus contention for a good time to + * attempt to acquire the lock bit. + */ + preempt_disable(); +#ifdef CONFIG_SMP + while (test_and_set_bit(PG_chainlock, &page->flags)) { + while (test_bit(PG_chainlock, &page->flags)) + cpu_relax(); + } +#endif +} + +static inline void pte_chain_unlock(struct page *page) +{ +#ifdef CONFIG_SMP + smp_mb__before_clear_bit(); + clear_bit(PG_chainlock, &page->flags); +#endif + preempt_enable(); +} + +/* * Methods to modify the page usage count. * * What counts for a page usage: diff -Nru a/include/linux/mmzone.h b/include/linux/mmzone.h --- a/include/linux/mmzone.h Thu Aug 29 22:23:24 2002 +++ b/include/linux/mmzone.h Thu Aug 29 22:23:24 2002 @@ -88,7 +88,8 @@ * rarely used fields: */ char *name; - unsigned long size; + unsigned long totalsize; /* total size, including holes */ + unsigned long memsize; /* amount of memory (excluding holes) */ } zone_t; #define ZONE_DMA 0 diff -Nru a/include/linux/page-flags.h b/include/linux/page-flags.h --- a/include/linux/page-flags.h Thu Aug 29 22:23:24 2002 +++ b/include/linux/page-flags.h Thu Aug 29 22:23:24 2002 @@ -42,6 +42,10 @@ * address space... */ +#include + +struct page; + /* * Don't use the *_dontuse flags. Use the macros. Otherwise you'll break * locked- and dirty-page accounting. The top eight bits of page->flags are @@ -228,36 +232,6 @@ #define TestSetPageDirect(page) test_and_set_bit(PG_direct, &(page)->flags) #define ClearPageDirect(page) clear_bit(PG_direct, &(page)->flags) #define TestClearPageDirect(page) test_and_clear_bit(PG_direct, &(page)->flags) - -/* - * inlines for acquisition and release of PG_chainlock - */ -static inline void pte_chain_lock(struct page *page) -{ - /* - * Assuming the lock is uncontended, this never enters - * the body of the outer loop. If it is contended, then - * within the inner loop a non-atomic test is used to - * busywait with less bus contention for a good time to - * attempt to acquire the lock bit. - */ - preempt_disable(); -#ifdef CONFIG_SMP - while (test_and_set_bit(PG_chainlock, &page->flags)) { - while (test_bit(PG_chainlock, &page->flags)) - cpu_relax(); - } -#endif -} - -static inline void pte_chain_unlock(struct page *page) -{ -#ifdef CONFIG_SMP - smp_mb__before_clear_bit(); - clear_bit(PG_chainlock, &page->flags); -#endif - preempt_enable(); -} /* * The PageSwapCache predicate doesn't use a PG_flag at this time, diff -Nru a/include/linux/percpu.h b/include/linux/percpu.h --- a/include/linux/percpu.h Thu Aug 29 22:23:24 2002 +++ b/include/linux/percpu.h Thu Aug 29 22:23:24 2002 @@ -1,8 +1,7 @@ #ifndef __LINUX_PERCPU_H #define __LINUX_PERCPU_H -#include /* For preempt_disable() */ +#include /* For preempt_disable() */ #include - #define get_cpu_var(var) ({ preempt_disable(); __get_cpu_var(var); }) #define put_cpu_var(var) preempt_enable() diff -Nru a/include/linux/ptrace.h b/include/linux/ptrace.h --- a/include/linux/ptrace.h Thu Aug 29 22:23:24 2002 +++ b/include/linux/ptrace.h Thu Aug 29 22:23:24 2002 @@ -4,6 +4,7 @@ /* structs and defines to help the user use the ptrace system call. */ #include +#include /* has the defines to get at the registers. */ diff -Nru a/include/linux/sched.h b/include/linux/sched.h --- a/include/linux/sched.h Thu Aug 29 22:23:24 2002 +++ b/include/linux/sched.h Thu Aug 29 22:23:24 2002 @@ -441,14 +441,14 @@ #ifndef INIT_THREAD_SIZE # define INIT_THREAD_SIZE 2048*sizeof(long) -#endif - union thread_union { struct thread_info thread_info; unsigned long stack[INIT_THREAD_SIZE/sizeof(long)]; }; extern union thread_union init_thread_union; +#endif + extern struct task_struct init_task; extern struct mm_struct init_mm; diff -Nru a/include/linux/serial.h b/include/linux/serial.h --- a/include/linux/serial.h Thu Aug 29 22:23:24 2002 +++ b/include/linux/serial.h Thu Aug 29 22:23:24 2002 @@ -184,9 +184,12 @@ #ifdef CONFIG_ACPI /* tty ports reserved for the ACPI serial console port and debug port */ -#define ACPI_SERIAL_CONSOLE_PORT 4 +#define ACPI_SERIAL_CONSOLE_PORT 0 #define ACPI_SERIAL_DEBUG_PORT 5 #endif + +/* tty port reserved for the HCDP serial console port */ +#define HCDP_SERIAL_CONSOLE_PORT 4 #endif /* __KERNEL__ */ #endif /* _LINUX_SERIAL_H */ diff -Nru a/include/linux/smp.h b/include/linux/smp.h --- a/include/linux/smp.h Thu Aug 29 22:23:25 2002 +++ b/include/linux/smp.h Thu Aug 29 22:23:25 2002 @@ -57,10 +57,6 @@ */ extern int smp_threads_ready; -extern volatile unsigned long smp_msg_data; -extern volatile int smp_src_cpu; -extern volatile int smp_msg_id; - #define MSG_ALL_BUT_SELF 0x8000 /* Assume <32768 CPU's */ #define MSG_ALL 0x8001 @@ -97,7 +93,6 @@ #define cpu_online(cpu) ({ cpu; 1; }) #define num_online_cpus() 1 #define num_booting_cpus() 1 - struct notifier_block; /* Need to know about CPUs going up/down? */ diff -Nru a/include/linux/vmalloc.h b/include/linux/vmalloc.h --- a/include/linux/vmalloc.h Thu Aug 29 22:23:25 2002 +++ b/include/linux/vmalloc.h Thu Aug 29 22:23:25 2002 @@ -7,6 +7,7 @@ #define VM_IOREMAP 0x00000001 /* ioremap() and friends */ #define VM_ALLOC 0x00000002 /* vmalloc() */ #define VM_MAP 0x00000004 /* vmap()ed pages */ +#define VM_AGP_REMAP 0x00000008 /* remapped AGP-memory */ struct vm_struct { void *addr; @@ -37,6 +38,9 @@ extern int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages); extern void unmap_vm_area(struct vm_struct *area); + +/* Get the flags associated with the area starting at ADDR. */ +extern unsigned long vgetflags (void *addr); /* * Internals. Dont't use.. diff -Nru a/kernel/exec_domain.c b/kernel/exec_domain.c --- a/kernel/exec_domain.c Thu Aug 29 22:23:25 2002 +++ b/kernel/exec_domain.c Thu Aug 29 22:23:25 2002 @@ -196,8 +196,10 @@ put_exec_domain(oep); +#if 0 printk(KERN_DEBUG "[%s:%d]: set personality to %lx\n", current->comm, current->pid, personality); +#endif return 0; } diff -Nru a/kernel/fork.c b/kernel/fork.c --- a/kernel/fork.c Thu Aug 29 22:23:24 2002 +++ b/kernel/fork.c Thu Aug 29 22:23:24 2002 @@ -52,6 +52,7 @@ rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED; /* outer */ +#if 0 /* * A per-CPU task cache - this relies on the fact that * the very last portion of sys_exit() is executed with @@ -75,6 +76,7 @@ task_cache[cpu] = current; } } +#endif /* Protects next_safe and last_pid. */ void add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait) @@ -127,7 +129,11 @@ init_task.rlim[RLIMIT_NPROC].rlim_max = max_threads/2; } -static struct task_struct *dup_task_struct(struct task_struct *orig) +#if 1 +extern struct task_struct *dup_task_struct (struct task_struct *orig); +#else + +struct task_struct *dup_task_struct(struct task_struct *orig) { struct task_struct *tsk; struct thread_info *ti; @@ -150,6 +156,8 @@ return tsk; } + +#endif spinlock_t lastpid_lock = SPIN_LOCK_UNLOCKED; diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c --- a/kernel/ksyms.c Thu Aug 29 22:23:24 2002 +++ b/kernel/ksyms.c Thu Aug 29 22:23:24 2002 @@ -108,6 +108,7 @@ EXPORT_SYMBOL(kmalloc); EXPORT_SYMBOL(kfree); EXPORT_SYMBOL(vfree); +EXPORT_SYMBOL(vgetflags); EXPORT_SYMBOL(__vmalloc); EXPORT_SYMBOL(vmalloc); EXPORT_SYMBOL(vmalloc_32); @@ -391,7 +392,9 @@ EXPORT_SYMBOL(del_timer); EXPORT_SYMBOL(request_irq); EXPORT_SYMBOL(free_irq); +#if !defined(CONFIG_IA64) EXPORT_SYMBOL(irq_stat); +#endif /* waitqueue handling */ EXPORT_SYMBOL(add_wait_queue); @@ -601,7 +604,9 @@ /* init task, for moving kthread roots - ought to export a function ?? */ EXPORT_SYMBOL(init_task); +#ifndef CONFIG_IA64 EXPORT_SYMBOL(init_thread_union); +#endif EXPORT_SYMBOL(tasklist_lock); EXPORT_SYMBOL(pidhash); diff -Nru a/kernel/printk.c b/kernel/printk.c --- a/kernel/printk.c Thu Aug 29 22:23:25 2002 +++ b/kernel/printk.c Thu Aug 29 22:23:25 2002 @@ -16,6 +16,7 @@ * 01Mar01 Andrew Morton */ +#include #include #include #include @@ -55,11 +56,12 @@ DECLARE_WAIT_QUEUE_HEAD(log_wait); -/* Keep together for sysctl support */ -int console_loglevel = DEFAULT_CONSOLE_LOGLEVEL; -int default_message_loglevel = DEFAULT_MESSAGE_LOGLEVEL; -int minimum_console_loglevel = MINIMUM_CONSOLE_LOGLEVEL; -int default_console_loglevel = DEFAULT_CONSOLE_LOGLEVEL; +int console_printk[4] = { + DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel */ + DEFAULT_MESSAGE_LOGLEVEL, /* default_message_loglevel */ + MINIMUM_CONSOLE_LOGLEVEL, /* minimum_console_loglevel */ + DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ +}; int oops_in_progress; @@ -341,6 +343,12 @@ __call_console_drivers(start, end); } } +#ifdef CONFIG_IA64_EARLY_PRINTK + if (!console_drivers) { + static void early_printk (const char *str, size_t len); + early_printk(&LOG_BUF(start), end - start); + } +#endif } /* @@ -707,3 +715,109 @@ tty->driver.write(tty, 0, msg, strlen(msg)); return; } + +#ifdef CONFIG_IA64_EARLY_PRINTK + +# ifdef CONFIG_IA64_EARLY_PRINTK_VGA + +#include + +#define VGABASE ((char *)0xc0000000000b8000) +#define VGALINES 24 +#define VGACOLS 80 + +static int current_ypos = VGALINES, current_xpos = 0; + +static void +early_printk_vga (const char *str, size_t len) +{ + char c; + int i, k, j; + + while (len-- > 0) { + c = *str++; + if (current_ypos >= VGALINES) { + /* scroll 1 line up */ + for (k = 1, j = 0; k < VGALINES; k++, j++) { + for (i = 0; i < VGACOLS; i++) { + writew(readw(VGABASE + 2*(VGACOLS*k + i)), + VGABASE + 2*(VGACOLS*j + i)); + } + } + for (i = 0; i < VGACOLS; i++) { + writew(0x720, VGABASE + 2*(VGACOLS*j + i)); + } + current_ypos = VGALINES-1; + } + if (c == '\n') { + current_xpos = 0; + current_ypos++; + } else if (c != '\r') { + writew(((0x7 << 8) | (unsigned short) c), + VGABASE + 2*(VGACOLS*current_ypos + current_xpos++)); + if (current_xpos >= VGACOLS) { + current_xpos = 0; + current_ypos++; + } + } + } +} + +# endif /* CONFIG_IA64_EARLY_PRINTK_VGA */ + +# ifdef CONFIG_IA64_EARLY_PRINTK_UART + +#include +#include + +static void early_printk_uart(const char *str, size_t len) +{ + static char *uart = NULL; + unsigned long uart_base; + char c; + + if (!uart) { + uart_base = 0; +# ifdef CONFIG_SERIAL_8250_HCDP + { + extern unsigned long hcdp_early_uart(void); + uart_base = hcdp_early_uart(); + } +# endif +# if CONFIG_IA64_EARLY_PRINTK_UART_BASE + if (!uart_base) + uart_base = CONFIG_IA64_EARLY_PRINTK_UART_BASE; +# endif + if (!uart_base) + return; + + uart = ioremap(uart_base, 64); + if (!uart) + return; + } + + while (len-- > 0) { + c = *str++; + while ((readb(uart + UART_LSR) & UART_LSR_TEMT) == 0) + cpu_relax(); /* spin */ + + writeb(c, uart + UART_TX); + + if (c == '\n') + writeb('\r', uart + UART_TX); + } +} + +# endif /* CONFIG_IA64_EARLY_PRINTK_UART */ + +void early_printk(const char *str, size_t len) +{ +#ifdef CONFIG_IA64_EARLY_PRINTK_UART + early_printk_uart(str, len); +#endif +#ifdef CONFIG_IA64_EARLY_PRINTK_VGA + early_printk_vga(str, len); +#endif +} + +#endif /* CONFIG_IA64_EARLY_PRINTK */ diff -Nru a/kernel/softirq.c b/kernel/softirq.c --- a/kernel/softirq.c Thu Aug 29 22:23:24 2002 +++ b/kernel/softirq.c Thu Aug 29 22:23:24 2002 @@ -38,7 +38,10 @@ - Bottom halves: globally serialized, grr... */ +/* No separate irq_stat for ia64, it is part of PSA */ +#if !defined(CONFIG_IA64) irq_cpustat_t irq_stat[NR_CPUS]; +#endif /* CONFIG_IA64 */ static struct softirq_action softirq_vec[32] __cacheline_aligned_in_smp; @@ -69,7 +72,7 @@ local_irq_save(flags); cpu = smp_processor_id(); - pending = softirq_pending(cpu); + pending = local_softirq_pending(); if (pending) { struct softirq_action *h; @@ -78,7 +81,7 @@ local_bh_disable(); restart: /* Reset the pending bitmask before enabling irqs */ - softirq_pending(cpu) = 0; + local_softirq_pending() = 0; local_irq_enable(); @@ -93,7 +96,7 @@ local_irq_disable(); - pending = softirq_pending(cpu); + pending = local_softirq_pending(); if (pending & mask) { mask &= ~pending; goto restart; @@ -101,7 +104,7 @@ __local_bh_enable(); if (pending) - wakeup_softirqd(cpu); + wakeup_softirqd(smp_processor_id()); } local_irq_restore(flags); @@ -371,15 +374,15 @@ __set_current_state(TASK_INTERRUPTIBLE); mb(); - ksoftirqd_task(cpu) = current; + local_ksoftirqd_task() = current; for (;;) { - if (!softirq_pending(cpu)) + if (!local_softirq_pending()) schedule(); __set_current_state(TASK_RUNNING); - while (softirq_pending(cpu)) { + while (local_softirq_pending()) { do_softirq(); cond_resched(); } diff -Nru a/kernel/timer.c b/kernel/timer.c --- a/kernel/timer.c Thu Aug 29 22:23:24 2002 +++ b/kernel/timer.c Thu Aug 29 22:23:24 2002 @@ -886,7 +886,7 @@ if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 || t.tv_sec < 0) return -EINVAL; - +#if !defined(__ia64__) if (t.tv_sec == 0 && t.tv_nsec <= 2000000L && current->policy != SCHED_NORMAL) { @@ -899,6 +899,7 @@ udelay((t.tv_nsec + 999) / 1000); return 0; } +#endif expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec); diff -Nru a/mm/bootmem.c b/mm/bootmem.c --- a/mm/bootmem.c Thu Aug 29 22:23:24 2002 +++ b/mm/bootmem.c Thu Aug 29 22:23:24 2002 @@ -143,6 +143,7 @@ static void * __init __alloc_bootmem_core (bootmem_data_t *bdata, unsigned long size, unsigned long align, unsigned long goal) { + static unsigned long last_success; unsigned long i, start = 0; void *ret; unsigned long offset, remaining_size; @@ -168,6 +169,9 @@ if (goal && (goal >= bdata->node_boot_start) && ((goal >> PAGE_SHIFT) < bdata->node_low_pfn)) { preferred = goal - bdata->node_boot_start; + + if (last_success >= preferred) + preferred = last_success; } else preferred = 0; @@ -179,6 +183,8 @@ restart_scan: for (i = preferred; i < eidx; i += incr) { unsigned long j; + i = find_next_zero_bit((char *)bdata->node_bootmem_map, eidx, i); + i = (i + incr - 1) & -incr; if (test_bit(i, bdata->node_bootmem_map)) continue; for (j = i + 1; j < i + areasize; ++j) { @@ -197,6 +203,7 @@ } return NULL; found: + last_success = start << PAGE_SHIFT; if (start >= eidx) BUG(); @@ -256,21 +263,21 @@ map = bdata->node_bootmem_map; for (i = 0; i < idx; ) { unsigned long v = ~map[i / BITS_PER_LONG]; - if (v) { + if (v) { unsigned long m; - for (m = 1; m && i < idx; m<<=1, page++, i++) { + for (m = 1; m && i < idx; m<<=1, page++, i++) { if (v & m) { - count++; - ClearPageReserved(page); - set_page_count(page, 1); - __free_page(page); - } - } + count++; + ClearPageReserved(page); + set_page_count(page, 1); + __free_page(page); + } + } } else { i+=BITS_PER_LONG; - page+=BITS_PER_LONG; - } - } + page+=BITS_PER_LONG; + } + } total += count; /* diff -Nru a/mm/memory.c b/mm/memory.c --- a/mm/memory.c Thu Aug 29 22:23:25 2002 +++ b/mm/memory.c Thu Aug 29 22:23:25 2002 @@ -110,7 +110,7 @@ pmd = pmd_offset(dir, 0); pgd_clear(dir); for (j = 0; j < PTRS_PER_PMD ; j++) { - prefetchw(pmd+j+(PREFETCH_STRIDE/16)); + prefetchw(pmd + j + PREFETCH_STRIDE/sizeof(*pmd)); free_one_pmd(tlb, pmd+j); } pmd_free_tlb(tlb, pmd); diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c --- a/mm/page_alloc.c Thu Aug 29 22:23:24 2002 +++ b/mm/page_alloc.c Thu Aug 29 22:23:24 2002 @@ -48,7 +48,7 @@ */ static inline int bad_range(zone_t *zone, struct page *page) { - if (page - mem_map >= zone->zone_start_mapnr + zone->size) + if (page - mem_map >= zone->zone_start_mapnr + zone->totalsize) return 1; if (page - mem_map < zone->zone_start_mapnr) return 1; @@ -497,7 +497,7 @@ zone_t *zone; for (zone = *zonep++; zone; zone = *zonep++) { - unsigned long size = zone->size; + unsigned long size = zone->memsize; unsigned long high = zone->pages_high; if (size > high) sum += size - high; @@ -637,7 +637,7 @@ zone_t *zone = &pgdat->node_zones[type]; unsigned long nr, flags, order, total = 0; - if (!zone->size) + if (!zone->memsize) continue; spin_lock_irqsave(&zone->lock, flags); @@ -684,7 +684,7 @@ */ case ZONE_HIGHMEM: zone = pgdat->node_zones + ZONE_HIGHMEM; - if (zone->size) { + if (zone->memsize) { #ifndef CONFIG_HIGHMEM BUG(); #endif @@ -692,11 +692,11 @@ } case ZONE_NORMAL: zone = pgdat->node_zones + ZONE_NORMAL; - if (zone->size) + if (zone->memsize) zonelist->zones[j++] = zone; case ZONE_DMA: zone = pgdat->node_zones + ZONE_DMA; - if (zone->size) + if (zone->memsize) zonelist->zones[j++] = zone; } zonelist->zones[j++] = NULL; @@ -807,7 +807,8 @@ realsize -= zholes_size[j]; printk("zone(%lu): %lu pages.\n", j, size); - zone->size = size; + zone->totalsize = size; + zone->memsize = realsize; zone->name = zone_names[j]; zone->lock = SPIN_LOCK_UNLOCKED; zone->zone_pgdat = pgdat; diff -Nru a/mm/vmalloc.c b/mm/vmalloc.c --- a/mm/vmalloc.c Thu Aug 29 22:23:25 2002 +++ b/mm/vmalloc.c Thu Aug 29 22:23:25 2002 @@ -512,3 +512,20 @@ read_unlock(&vmlist_lock); return buf - buf_start; } + +unsigned long vgetflags (void * addr) +{ + struct vm_struct *tmp; + unsigned long flags = 0; + + read_lock(&vmlist_lock); + for (tmp = vmlist ; tmp ; tmp = tmp->next) { + if (tmp->addr == addr) { + flags = tmp->flags; + break; + } + + } + read_unlock(&vmlist_lock); + return flags; +} diff -Nru a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c --- a/sound/oss/cs4281/cs4281m.c Thu Aug 29 22:23:25 2002 +++ b/sound/oss/cs4281/cs4281m.c Thu Aug 29 22:23:25 2002 @@ -1942,8 +1942,8 @@ len -= x; } CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO - "cs4281: clear_advance(): memset %d at 0x%.8x for %d size \n", - (unsigned)c, (unsigned)((char *) buf) + bptr, len)); + "cs4281: clear_advance(): memset %d at %p for %d size \n", + (unsigned)c, ((char *) buf) + bptr, len)); memset(((char *) buf) + bptr, c, len); } @@ -1978,9 +1978,8 @@ wake_up(&s->dma_adc.wait); } CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO - "cs4281: cs4281_update_ptr(): s=0x%.8x hwptr=%d total_bytes=%d count=%d \n", - (unsigned)s, s->dma_adc.hwptr, - s->dma_adc.total_bytes, s->dma_adc.count)); + "cs4281: cs4281_update_ptr(): s=%p hwptr=%d total_bytes=%d count=%d \n", + s, s->dma_adc.hwptr, s->dma_adc.total_bytes, s->dma_adc.count)); } // update DAC pointer // @@ -2012,11 +2011,10 @@ // Continue to play silence until the _release. // CS_DBGOUT(CS_WAVE_WRITE, 6, printk(KERN_INFO - "cs4281: cs4281_update_ptr(): memset %d at 0x%.8x for %d size \n", + "cs4281: cs4281_update_ptr(): memset %d at %p for %d size \n", (unsigned)(s->prop_dac.fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0, - (unsigned)s->dma_dac.rawbuf, - s->dma_dac.dmasize)); + s->dma_dac.rawbuf, s->dma_dac.dmasize)); memset(s->dma_dac.rawbuf, (s->prop_dac. fmt & (AFMT_U8 | AFMT_U16_LE)) ? @@ -2047,9 +2045,8 @@ } } CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO - "cs4281: cs4281_update_ptr(): s=0x%.8x hwptr=%d total_bytes=%d count=%d \n", - (unsigned) s, s->dma_dac.hwptr, - s->dma_dac.total_bytes, s->dma_dac.count)); + "cs4281: cs4281_update_ptr(): s=%p hwptr=%d total_bytes=%d count=%d \n", + s, s->dma_dac.hwptr, s->dma_dac.total_bytes, s->dma_dac.count)); } } @@ -2180,8 +2177,7 @@ VALIDATE_STATE(s); CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO - "cs4281: mixer_ioctl(): s=0x%.8x cmd=0x%.8x\n", - (unsigned) s, cmd)); + "cs4281: mixer_ioctl(): s=%p cmd=0x%.8x\n", s, cmd)); #if CSDEBUG cs_printioctl(cmd); #endif @@ -2746,9 +2742,8 @@ CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO "cs4281: CopySamples()+ ")); CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO - " dst=0x%x src=0x%x count=%d iChannels=%d fmt=0x%x\n", - (unsigned) dst, (unsigned) src, (unsigned) count, - (unsigned) iChannels, (unsigned) fmt)); + " dst=%p src=%p count=%d iChannels=%d fmt=0x%x\n", + dst, src, (unsigned) count, (unsigned) iChannels, (unsigned) fmt)); // Gershwin does format conversion in hardware so normally // we don't do any host based coversion. The data formatter @@ -2828,9 +2823,9 @@ void *src = hwsrc; //default to the standard destination buffer addr CS_DBGOUT(CS_FUNCTION, 6, printk(KERN_INFO - "cs_copy_to_user()+ fmt=0x%x fmt_o=0x%x cnt=%d dest=0x%.8x\n", + "cs_copy_to_user()+ fmt=0x%x fmt_o=0x%x cnt=%d dest=%p\n", s->prop_adc.fmt, s->prop_adc.fmt_original, - (unsigned) cnt, (unsigned) dest)); + (unsigned) cnt, dest)); if (cnt > s->dma_adc.dmasize) { cnt = s->dma_adc.dmasize; @@ -2875,7 +2870,7 @@ unsigned copied = 0; CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2, - printk(KERN_INFO "cs4281: cs4281_read()+ %d \n", count)); + printk(KERN_INFO "cs4281: cs4281_read()+ %Zu \n", count)); VALIDATE_STATE(s); if (ppos != &file->f_pos) @@ -2898,7 +2893,7 @@ // while (count > 0) { CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO - "_read() count>0 count=%d .count=%d .swptr=%d .hwptr=%d \n", + "_read() count>0 count=%Zu .count=%d .swptr=%d .hwptr=%d \n", count, s->dma_adc.count, s->dma_adc.swptr, s->dma_adc.hwptr)); spin_lock_irqsave(&s->lock, flags); @@ -2955,11 +2950,10 @@ // the "cnt" is the number of bytes to read. CS_DBGOUT(CS_WAVE_READ, 2, printk(KERN_INFO - "_read() copy_to cnt=%d count=%d ", cnt, count)); + "_read() copy_to cnt=%d count=%Zu ", cnt, count)); CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO - " .dmasize=%d .count=%d buffer=0x%.8x ret=%d\n", - s->dma_adc.dmasize, s->dma_adc.count, - (unsigned) buffer, ret)); + " .dmasize=%d .count=%d buffer=%p ret=%Zd\n", + s->dma_adc.dmasize, s->dma_adc.count, buffer, ret)); if (cs_copy_to_user (s, buffer, s->dma_adc.rawbuf + swptr, cnt, &copied)) @@ -2975,7 +2969,7 @@ start_adc(s); } CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2, - printk(KERN_INFO "cs4281: cs4281_read()- %d\n", ret)); + printk(KERN_INFO "cs4281: cs4281_read()- %Zd\n", ret)); return ret; } @@ -2991,7 +2985,7 @@ int cnt; CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2, - printk(KERN_INFO "cs4281: cs4281_write()+ count=%d\n", + printk(KERN_INFO "cs4281: cs4281_write()+ count=%Zu\n", count)); VALIDATE_STATE(s); @@ -3047,7 +3041,7 @@ start_dac(s); } CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2, - printk(KERN_INFO "cs4281: cs4281_write()- %d\n", ret)); + printk(KERN_INFO "cs4281: cs4281_write()- %Zd\n", ret)); return ret; } @@ -3168,8 +3162,7 @@ int val, mapped, ret; CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO - "cs4281: cs4281_ioctl(): file=0x%.8x cmd=0x%.8x\n", - (unsigned) file, cmd)); + "cs4281: cs4281_ioctl(): file=%p cmd=0x%.8x\n", file, cmd)); #if CSDEBUG cs_printioctl(cmd); #endif @@ -3205,7 +3198,7 @@ "cs4281: cs4281_ioctl(): DSP_RESET\n")); if (file->f_mode & FMODE_WRITE) { stop_dac(s); - synchronize_irq(); + synchronize_irq(s->irq); s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = s->dma_dac.blocks = s->dma_dac.wakeup = 0; @@ -3213,7 +3206,7 @@ } if (file->f_mode & FMODE_READ) { stop_adc(s); - synchronize_irq(); + synchronize_irq(s->irq); s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = s->dma_adc.blocks = s->dma_dac.wakeup = 0; @@ -3599,8 +3592,8 @@ (struct cs4281_state *) file->private_data; CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 2, printk(KERN_INFO - "cs4281: cs4281_release(): inode=0x%.8x file=0x%.8x f_mode=%d\n", - (unsigned) inode, (unsigned) file, file->f_mode)); + "cs4281: cs4281_release(): inode=%p file=%p f_mode=%d\n", + inode, file, file->f_mode)); VALIDATE_STATE(s); @@ -3634,8 +3627,8 @@ struct list_head *entry; CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO - "cs4281: cs4281_open(): inode=0x%.8x file=0x%.8x f_mode=0x%x\n", - (unsigned) inode, (unsigned) file, file->f_mode)); + "cs4281: cs4281_open(): inode=%p file=%p f_mode=0x%x\n", + inode, file, file->f_mode)); list_for_each(entry, &cs4281_devs) { @@ -4344,10 +4337,8 @@ CS_DBGOUT(CS_INIT, 2, printk(KERN_INFO - "cs4281: probe() BA0=0x%.8x BA1=0x%.8x pBA0=0x%.8x pBA1=0x%.8x \n", - (unsigned) temp1, (unsigned) temp2, - (unsigned) s->pBA0, (unsigned) s->pBA1)); - + "cs4281: probe() BA0=0x%.8x BA1=0x%.8x pBA0=%p pBA1=%p \n", + (unsigned) temp1, (unsigned) temp2, s->pBA0, s->pBA1)); CS_DBGOUT(CS_INIT, 2, printk(KERN_INFO "cs4281: probe() pBA0phys=0x%.8x pBA1phys=0x%.8x\n", @@ -4394,15 +4385,13 @@ if (pmdev) { CS_DBGOUT(CS_INIT | CS_PM, 4, printk(KERN_INFO - "cs4281: probe() pm_register() succeeded (0x%x).\n", - (unsigned)pmdev)); + "cs4281: probe() pm_register() succeeded (%p).\n", pmdev)); pmdev->data = s; } else { CS_DBGOUT(CS_INIT | CS_PM | CS_ERROR, 0, printk(KERN_INFO - "cs4281: probe() pm_register() failed (0x%x).\n", - (unsigned)pmdev)); + "cs4281: probe() pm_register() failed (%p).\n", pmdev)); s->pm.flags |= CS4281_PM_NOT_REGISTERED; } #endif @@ -4452,7 +4441,7 @@ { struct cs4281_state *s = pci_get_drvdata(pci_dev); // stop DMA controller - synchronize_irq(); + synchronize_irq(s->irq); free_irq(s->irq, s); unregister_sound_dsp(s->dev_audio); unregister_sound_mixer(s->dev_mixer); diff -Nru a/sound/oss/cs4281/cs4281pm-24.c b/sound/oss/cs4281/cs4281pm-24.c --- a/sound/oss/cs4281/cs4281pm-24.c Thu Aug 29 22:23:25 2002 +++ b/sound/oss/cs4281/cs4281pm-24.c Thu Aug 29 22:23:25 2002 @@ -38,16 +38,16 @@ #define CS4281_SUSPEND_TBL cs4281_suspend_tbl #define CS4281_RESUME_TBL cs4281_resume_tbl */ -#define CS4281_SUSPEND_TBL cs4281_null -#define CS4281_RESUME_TBL cs4281_null +#define CS4281_SUSPEND_TBL (int (*) (struct pci_dev *, u32)) cs4281_null +#define CS4281_RESUME_TBL (int (*) (struct pci_dev *)) cs4281_null int cs4281_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) { struct cs4281_state *state; CS_DBGOUT(CS_PM, 2, printk(KERN_INFO - "cs4281: cs4281_pm_callback dev=0x%x rqst=0x%x state=%d\n", - (unsigned)dev,(unsigned)rqst,(unsigned)data)); + "cs4281: cs4281_pm_callback dev=%p rqst=0x%x state=%p\n", + dev,(unsigned)rqst,data)); state = (struct cs4281_state *) dev->data; if (state) { switch(rqst) { @@ -78,7 +78,7 @@ } #else /* CS4281_PM */ -#define CS4281_SUSPEND_TBL cs4281_null -#define CS4281_RESUME_TBL cs4281_null +#define CS4281_SUSPEND_TBL (int (*) (struct pci_dev *, u32)) cs4281_null +#define CS4281_RESUME_TBL (int (*) (struct pci_dev *)) cs4281_null #endif /* CS4281_PM */