diff options
Diffstat (limited to 'arch/ia64')
29 files changed, 165 insertions, 83 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index de1bff659969..616c96e73483 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -520,8 +520,10 @@ config PCI here unless you are using a simulator without PCI support. config PCI_DOMAINS - bool - default PCI + def_bool PCI + +config PCI_SYSCALL + def_bool PCI source "drivers/pci/pcie/Kconfig" @@ -580,8 +582,8 @@ menu "Instrumentation Support" source "arch/ia64/oprofile/Kconfig" config KPROBES - bool "Kprobes (EXPERIMENTAL)" - depends on KALLSYMS && EXPERIMENTAL && MODULES + bool "Kprobes" + depends on KALLSYMS && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index c1dca226b479..cd4adf52f174 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -34,6 +34,7 @@ #include <linux/efi.h> #include <linux/nodemask.h> #include <linux/bitops.h> /* hweight64() */ +#include <linux/crash_dump.h> #include <asm/delay.h> /* ia64_get_itc() */ #include <asm/io.h> @@ -43,6 +44,8 @@ #include <asm/acpi-ext.h> +extern int swiotlb_late_init_with_default_size (size_t size); + #define PFX "IOC: " /* @@ -2026,11 +2029,24 @@ sba_init(void) if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb")) return 0; +#if defined(CONFIG_IA64_GENERIC) && defined(CONFIG_CRASH_DUMP) + /* If we are booting a kdump kernel, the sba_iommu will + * cause devices that were not shutdown properly to MCA + * as soon as they are turned back on. Our only option for + * a successful kdump kernel boot is to use the swiotlb. + */ + if (elfcorehdr_addr < ELFCORE_ADDR_MAX) { + if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0) + panic("Unable to initialize software I/O TLB:" + " Try machvec=dig boot option"); + machvec_init("dig"); + return 0; + } +#endif + acpi_bus_register_driver(&acpi_sba_ioc_driver); if (!ioc_list) { #ifdef CONFIG_IA64_GENERIC - extern int swiotlb_late_init_with_default_size (size_t size); - /* * If we didn't find something sba_iommu can claim, we * need to setup the swiotlb and switch to the dig machvec. diff --git a/arch/ia64/hp/sim/boot/fw-emu.c b/arch/ia64/hp/sim/boot/fw-emu.c index 300acd913d9c..1189d035d316 100644 --- a/arch/ia64/hp/sim/boot/fw-emu.c +++ b/arch/ia64/hp/sim/boot/fw-emu.c @@ -329,11 +329,6 @@ sys_fw_init (const char *args, int arglen) strcpy(sal_systab->product_id, "HP-simulator"); #endif -#ifdef CONFIG_IA64_SDV - strcpy(sal_systab->oem_id, "Intel"); - strcpy(sal_systab->product_id, "SDV"); -#endif - /* fill in an entry point: */ sal_ed->type = SAL_DESC_ENTRY_POINT; sal_ed->pal_proc = __pa(pal_desc[0]); diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 324ea7565e2c..ef252df50e1e 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -36,10 +36,6 @@ #include <asm/hw_irq.h> #include <asm/uaccess.h> -#ifdef CONFIG_KDB -# include <linux/kdb.h> -#endif - #undef SIMSERIAL_DEBUG /* define this to get some debug information */ #define KEYBOARD_INTR 3 /* must match with simulator! */ diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c index c05bda662364..6f4d3d06f0ed 100644 --- a/arch/ia64/ia32/binfmt_elf32.c +++ b/arch/ia64/ia32/binfmt_elf32.c @@ -261,7 +261,7 @@ elf32_set_personality (void) } static unsigned long -elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type) +elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused) { unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK; diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S index 99b665e2b1d5..06efd1f9b800 100644 --- a/arch/ia64/ia32/ia32_entry.S +++ b/arch/ia64/ia32/ia32_entry.S @@ -304,7 +304,7 @@ ia32_syscall_table: data8 sys_ni_syscall /* init_module */ data8 sys_ni_syscall /* delete_module */ data8 sys_ni_syscall /* get_kernel_syms */ /* 130 */ - data8 sys_quotactl + data8 sys32_quotactl data8 sys_getpgid data8 sys_fchdir data8 sys_ni_syscall /* sys_bdflush */ diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 75ec3478d8a2..73ca86d03810 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -28,6 +28,7 @@ #include <linux/time.h> #include <linux/efi.h> #include <linux/kexec.h> +#include <linux/mm.h> #include <asm/io.h> #include <asm/kregs.h> diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 8589e84a27c6..3f926c2dc708 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -247,6 +247,9 @@ ENTRY(fsys_gettimeofday) .time_redo: .pred.rel.mutex p8,p9,p10 ld4.acq r28 = [r29] // xtime_lock.sequence. Must come first for locking purposes + ;; + and r28 = ~1,r28 // Make sequence even to force retry if odd + ;; (p8) mov r2 = ar.itc // CPU_TIMER. 36 clocks latency!!! add r22 = IA64_TIME_INTERPOLATOR_LAST_COUNTER_OFFSET,r20 (p9) ld8 r2 = [r30] // readq(ti->address). Could also have latency issues.. @@ -284,7 +287,6 @@ EX(.fail_efault, probe.w.fault r31, 3) // This takes 5 cycles and we have spare (p15) ld8 r17 = [r19],-IA64_TIMESPEC_TV_NSEC_OFFSET (p7) cmp.ne p7,p0 = r25,r3 // if cmpxchg not successful redo // simulate tbit.nz.or p7,p0 = r28,0 - and r28 = ~1,r28 // Make sequence even to force retry if odd getf.sig r2 = f8 mf add r8 = r8,r18 // Add time interpolator offset diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S index 3274850cf272..74b1ccce4e84 100644 --- a/arch/ia64/kernel/gate.S +++ b/arch/ia64/kernel/gate.S @@ -30,6 +30,7 @@ .previous #define BRL_COND_FSYS_BUBBLE_DOWN(pr) \ [1:](pr)brl.cond.sptk 0; \ + ;; \ .xdata4 ".data.patch.brl_fsys_bubble_down", 1b-. GLOBAL_ENTRY(__kernel_syscall_via_break) diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 1ead5ea6c5ce..4b5daa3cc0fe 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -57,6 +57,9 @@ * * 2006-09-15 Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> * Add printing support for MCA/INIT. + * + * 2007-04-27 Russ Anderson <rja@sgi.com> + * Support multiple cpus going through OS_MCA in the same event. */ #include <linux/types.h> #include <linux/init.h> @@ -96,7 +99,6 @@ #endif /* Used by mca_asm.S */ -u32 ia64_mca_serialize; DEFINE_PER_CPU(u64, ia64_mca_data); /* == __per_cpu_mca[smp_processor_id()] */ DEFINE_PER_CPU(u64, ia64_mca_per_cpu_pte); /* PTE to map per-CPU area */ DEFINE_PER_CPU(u64, ia64_mca_pal_pte); /* PTE to map PAL code */ @@ -963,11 +965,12 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, goto no_mod; } + if (r13 != sos->prev_IA64_KR_CURRENT) { + msg = "inconsistent previous current and r13"; + goto no_mod; + } + if (!mca_recover_range(ms->pmsa_iip)) { - if (r13 != sos->prev_IA64_KR_CURRENT) { - msg = "inconsistent previous current and r13"; - goto no_mod; - } if ((r12 - r13) >= KERNEL_STACK_SIZE) { msg = "inconsistent r12 and r13"; goto no_mod; @@ -1187,6 +1190,13 @@ all_in: * further MCA logging is enabled by clearing logs. * Monarch also has the duty of sending wakeup-IPIs to pull the * slave processors out of rendezvous spinloop. + * + * If multiple processors call into OS_MCA, the first will become + * the monarch. Subsequent cpus will be recorded in the mca_cpu + * bitmask. After the first monarch has processed its MCA, it + * will wake up the next cpu in the mca_cpu bitmask and then go + * into the rendezvous loop. When all processors have serviced + * their MCA, the last monarch frees up the rest of the processors. */ void ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, @@ -1196,16 +1206,32 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, struct task_struct *previous_current; struct ia64_mca_notify_die nd = { .sos = sos, .monarch_cpu = &monarch_cpu }; + static atomic_t mca_count; + static cpumask_t mca_cpu; + if (atomic_add_return(1, &mca_count) == 1) { + monarch_cpu = cpu; + sos->monarch = 1; + } else { + cpu_set(cpu, mca_cpu); + sos->monarch = 0; + } mprintk(KERN_INFO "Entered OS MCA handler. PSP=%lx cpu=%d " "monarch=%ld\n", sos->proc_state_param, cpu, sos->monarch); previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); - monarch_cpu = cpu; + if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); - ia64_wait_for_slaves(cpu, "MCA"); + if (sos->monarch) { + ia64_wait_for_slaves(cpu, "MCA"); + } else { + ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA; + while (cpu_isset(cpu, mca_cpu)) + cpu_relax(); /* spin until monarch wakes us */ + ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; + } /* Wakeup all the processors which are spinning in the rendezvous loop. * They will leave SAL, then spin in the OS with interrupts disabled @@ -1244,6 +1270,26 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); + + if (atomic_dec_return(&mca_count) > 0) { + int i; + + /* wake up the next monarch cpu, + * and put this cpu in the rendez loop. + */ + ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA; + for_each_online_cpu(i) { + if (cpu_isset(i, mca_cpu)) { + monarch_cpu = i; + cpu_clear(i, mca_cpu); /* wake next cpu */ + while (monarch_cpu != -1) + cpu_relax(); /* spin until last cpu leaves */ + ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; + set_curr_task(cpu, previous_current); + return; + } + } + } set_curr_task(cpu, previous_current); monarch_cpu = -1; } diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index 8c9c26aa6ae0..0f5965fcdf85 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S @@ -133,14 +133,6 @@ ia64_do_tlb_purge: //StartMain//////////////////////////////////////////////////////////////////// ia64_os_mca_dispatch: - // Serialize all MCA processing - mov r3=1;; - LOAD_PHYSICAL(p0,r2,ia64_mca_serialize);; -ia64_os_mca_spin: - xchg4 r4=[r2],r3;; - cmp.ne p6,p0=r4,r0 -(p6) br ia64_os_mca_spin - mov r3=IA64_MCA_CPU_MCA_STACK_OFFSET // use the MCA stack LOAD_PHYSICAL(p0,r2,1f) // return address mov r19=1 // All MCA events are treated as monarch (for now) @@ -291,10 +283,6 @@ END(ia64_os_mca_virtual_begin) mov b0=r12 // SAL_CHECK return address - // release lock - LOAD_PHYSICAL(p0,r3,ia64_mca_serialize);; - st4.rel [r3]=r0 - br b0 //EndMain////////////////////////////////////////////////////////////////////// diff --git a/arch/ia64/kernel/mca_drv_asm.S b/arch/ia64/kernel/mca_drv_asm.S index f2d4900751ba..3bccb06c8d21 100644 --- a/arch/ia64/kernel/mca_drv_asm.S +++ b/arch/ia64/kernel/mca_drv_asm.S @@ -40,7 +40,11 @@ GLOBAL_ENTRY(mca_handler_bhhook) mov b6=loc1 ;; mov loc1=rp - ssm psr.i | psr.ic + ssm psr.ic + ;; + srlz.i + ;; + ssm psr.i br.call.sptk.many rp=b6 // does not return ... ;; mov ar.pfs=loc0 diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index af73b8dfde28..fa40cba43350 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -513,7 +513,8 @@ copy_thread (int nr, unsigned long clone_flags, static void do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg) { - unsigned long mask, sp, nat_bits = 0, ip, ar_rnat, urbs_end, cfm; + unsigned long mask, sp, nat_bits = 0, ar_rnat, urbs_end, cfm; + unsigned long uninitialized_var(ip); /* GCC be quiet */ elf_greg_t *dst = arg; struct pt_regs *pt; char nat; diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index eaa6a24bc0b6..4d9864cc92c9 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -390,10 +390,6 @@ early_console_setup (char *cmdline) if (!efi_setup_pcdp_console(cmdline)) earlycons++; #endif -#ifdef CONFIG_SERIAL_8250_CONSOLE - if (!early_serial_console_init(cmdline)) - earlycons++; -#endif return (earlycons) ? 0 : -1; } @@ -805,7 +801,6 @@ static void __cpuinit get_max_cacheline_size (void) { unsigned long line_size, max = 1; - unsigned int cache_size = 0; u64 l, levels, unique_caches; pal_cache_config_info_t cci; s64 status; @@ -835,8 +830,6 @@ get_max_cacheline_size (void) line_size = 1 << cci.pcci_line_size; if (line_size > max) max = line_size; - if (cache_size < cci.pcci_cache_size) - cache_size = cci.pcci_cache_size; if (!cci.pcci_unified) { status = ia64_pal_cache_config_info(l, /* cache_type (instruction)= */ 1, @@ -853,9 +846,6 @@ get_max_cacheline_size (void) ia64_i_cache_stride_shift = cci.pcci_stride; } out: -#ifdef CONFIG_SMP - max_cache_size = max(max_cache_size, cache_size); -#endif if (max > ia64_max_cacheline_size) ia64_max_cacheline_size = max; } diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index a06667c7acc0..3486fe7d6e65 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -18,7 +18,6 @@ #include <linux/time.h> #include <linux/interrupt.h> #include <linux/efi.h> -#include <linux/profile.h> #include <linux/timex.h> #include <asm/machvec.h> diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 15ad85da15a9..3aeaf15e468b 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -69,6 +69,7 @@ die (const char *str, struct pt_regs *regs, long err) bust_spinlocks(0); die.lock_owner = -1; + add_taint(TAINT_DIE); spin_unlock_irq(&die.lock); if (panic_on_oops) diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c index b0b08b5f3eca..c1bdb5131814 100644 --- a/arch/ia64/kernel/unwind.c +++ b/arch/ia64/kernel/unwind.c @@ -1856,11 +1856,19 @@ find_save_locs (struct unw_frame_info *info) return 0; } +static int +unw_valid(const struct unw_frame_info *info, unsigned long* p) +{ + unsigned long loc = (unsigned long)p; + return (loc >= info->regstk.limit && loc < info->regstk.top) || + (loc >= info->memstk.top && loc < info->memstk.limit); +} + int unw_unwind (struct unw_frame_info *info) { unsigned long prev_ip, prev_sp, prev_bsp; - unsigned long ip, pr, num_regs, rp_loc, pfs_loc; + unsigned long ip, pr, num_regs; STAT(unsigned long start, flags;) int retval; @@ -1871,8 +1879,7 @@ unw_unwind (struct unw_frame_info *info) prev_bsp = info->bsp; /* validate the return IP pointer */ - rp_loc = (unsigned long) info->rp_loc; - if ((rp_loc < info->regstk.limit) || (rp_loc > info->regstk.top)) { + if (!unw_valid(info, info->rp_loc)) { /* FIXME: should really be level 0 but it occurs too often. KAO */ UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n", __FUNCTION__, info->ip); @@ -1888,8 +1895,7 @@ unw_unwind (struct unw_frame_info *info) } /* validate the previous stack frame pointer */ - pfs_loc = (unsigned long) info->pfs_loc; - if ((pfs_loc < info->regstk.limit) || (pfs_loc > info->regstk.top)) { + if (!unw_valid(info, info->pfs_loc)) { UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; diff --git a/arch/ia64/lib/checksum.c b/arch/ia64/lib/checksum.c index 4411d9baeb21..9fc955026f86 100644 --- a/arch/ia64/lib/checksum.c +++ b/arch/ia64/lib/checksum.c @@ -60,6 +60,7 @@ csum_tcpudp_nofold (__be32 saddr, __be32 daddr, unsigned short len, result = (result & 0xffffffff) + (result >> 32); return (__force __wsum)result; } +EXPORT_SYMBOL(csum_tcpudp_nofold); extern unsigned long do_csum (const unsigned char *, long); diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index 1346b7f05397..d22861c5b04c 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c @@ -15,6 +15,7 @@ #include <linux/pagemap.h> #include <linux/slab.h> #include <linux/sysctl.h> +#include <linux/log2.h> #include <asm/mman.h> #include <asm/pgalloc.h> #include <asm/tlb.h> @@ -182,7 +183,7 @@ static int __init hugetlb_setup_sz(char *str) tr_pages = 0x15557000UL; size = memparse(str, &str); - if (*str || (size & (size-1)) || !(tr_pages & size) || + if (*str || !is_power_of_2(size) || !(tr_pages & size) || size <= PAGE_SIZE || size >= (1UL << PAGE_SHIFT << MAX_ORDER)) { printk(KERN_WARNING "Invalid huge page size specified\n"); diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index fa4e6d4810f3..1682fc639038 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -175,7 +175,7 @@ EXPORT_SYMBOL(flush_tlb_range); void __devinit ia64_tlb_init (void) { - ia64_ptce_info_t ptce_info; + ia64_ptce_info_t uninitialized_var(ptce_info); /* GCC be quiet */ unsigned long tr_pgbits; long status; diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 73696b4a2eed..07d0e92742c8 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -591,6 +591,9 @@ int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { + unsigned long size = vma->vm_end - vma->vm_start; + pgprot_t prot; + /* * I/O space cannot be accessed via normal processor loads and * stores on this platform. @@ -604,15 +607,24 @@ pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, */ return -EINVAL; + if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) + return -EINVAL; + + prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size, + vma->vm_page_prot); + /* - * Leave vm_pgoff as-is, the PCI space address is the physical - * address on this platform. + * If the user requested WC, the kernel uses UC or WC for this region, + * and the chipset supports WC, we can use WC. Otherwise, we have to + * use the same attribute the kernel uses. */ - if (write_combine && efi_range_is_wc(vma->vm_start, - vma->vm_end - vma->vm_start)) + if (write_combine && + ((pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_UC || + (pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_WC) && + efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start)) vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); else - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_page_prot = prot; if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot)) diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c index c6216f454ffb..3c7178f5dce8 100644 --- a/arch/ia64/sn/kernel/io_acpi_init.c +++ b/arch/ia64/sn/kernel/io_acpi_init.c @@ -418,7 +418,7 @@ sn_acpi_slot_fixup(struct pci_dev *dev) void __iomem *addr; struct pcidev_info *pcidev_info = NULL; struct sn_irq_info *sn_irq_info = NULL; - size_t size; + size_t image_size, size; if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) { panic("%s: Failure obtaining pcidev_info for %s\n", @@ -428,17 +428,16 @@ sn_acpi_slot_fixup(struct pci_dev *dev) if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) { /* * A valid ROM image exists and has been shadowed by the - * PROM. Setup the pci_dev ROM resource to point to - * the shadowed copy. + * PROM. Setup the pci_dev ROM resource with the address + * of the shadowed copy, and the actual length of the ROM image. */ - size = dev->resource[PCI_ROM_RESOURCE].end - - dev->resource[PCI_ROM_RESOURCE].start; - addr = - ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE], - size); + size = pci_resource_len(dev, PCI_ROM_RESOURCE); + addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE], + size); + image_size = pci_get_rom_size(addr, size); dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr; dev->resource[PCI_ROM_RESOURCE].end = - (unsigned long) addr + size; + (unsigned long) addr + image_size - 1; dev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_BIOS_COPY; } sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info); diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 6b10e5d28488..906b93674b76 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -259,9 +259,23 @@ sn_io_slot_fixup(struct pci_dev *dev) insert_resource(&ioport_resource, &dev->resource[idx]); else insert_resource(&iomem_resource, &dev->resource[idx]); - /* If ROM, mark as shadowed in PROM */ - if (idx == PCI_ROM_RESOURCE) - dev->resource[idx].flags |= IORESOURCE_ROM_BIOS_COPY; + /* + * If ROM, set the actual ROM image size, and mark as + * shadowed in PROM. + */ + if (idx == PCI_ROM_RESOURCE) { + size_t image_size; + void __iomem *rom; + + rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE), + size + 1); + image_size = pci_get_rom_size(rom, size + 1); + dev->resource[PCI_ROM_RESOURCE].end = + dev->resource[PCI_ROM_RESOURCE].start + + image_size - 1; + dev->resource[PCI_ROM_RESOURCE].flags |= + IORESOURCE_ROM_BIOS_COPY; + } } /* Create a pci_window in the pci_controller struct for * each device resource. diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 6da9854751cd..df8d5bed6119 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -750,9 +750,10 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg) goto error; } else if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) { + int cpuobj_index = 0; + memset(p, 0, a.sz); for (i = 0; i < nobj; i++) { - int cpuobj_index = 0; if (!SN_HWPERF_IS_NODE(objs + i)) continue; node = sn_hwperf_obj_to_cnode(objs + i); diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index 493380b2c05f..5a289e4de838 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -369,7 +369,7 @@ static void tio_corelet_reset(nasid_t nasid, int corelet) static int is_fpga_tio(int nasid, int *bt) { - u16 ioboard_type; + u16 uninitialized_var(ioboard_type); /* GCC be quiet */ s64 rc; rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard_type); diff --git a/arch/ia64/sn/kernel/xp_nofault.S b/arch/ia64/sn/kernel/xp_nofault.S index b772543053c9..54e8973b6e99 100644 --- a/arch/ia64/sn/kernel/xp_nofault.S +++ b/arch/ia64/sn/kernel/xp_nofault.S @@ -21,7 +21,8 @@ xp_nofault_PIOR: mov r8=r0 // Stage a success return value ld8.acq r9=[r32];; // PIO Read the specified register - adds r9=1,r9 // Add to force a consume + adds r9=1,r9;; // Add to force consumption + or r9=r9,r9;; // Or to force consumption br.ret.sptk.many b0;; // Return success .global xp_error_PIOR diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 04a8256017eb..42485ad50ceb 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -15,6 +15,7 @@ #include <asm/sn/pcibus_provider_defs.h> #include <asm/sn/pcidev.h> #include <asm/sn/sn_sal.h> +#include <asm/sn/pic.h> #include <asm/sn/sn2/sn_hwperf.h> #include "xtalk/xwidgetdev.h" #include "xtalk/hubdev.h" @@ -79,7 +80,7 @@ static int sal_pcibr_error_interrupt(struct pcibus_info *soft) u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus) { s64 rc; - u16 ioboard; + u16 uninitialized_var(ioboard); /* GCC be quiet */ nasid_t nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base); rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard); @@ -130,9 +131,9 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont } memcpy(soft, prom_bussoft, sizeof(struct pcibus_info)); - soft->pbi_buscommon.bs_base = - (((u64) soft->pbi_buscommon. - bs_base << 4) >> 4) | __IA64_UNCACHED_OFFSET; + soft->pbi_buscommon.bs_base = (unsigned long) + ioremap(REGION_OFFSET(soft->pbi_buscommon.bs_base), + sizeof(struct pic)); spin_lock_init(&soft->pbi_lock); diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index b9bedbd6e1d6..d798dd4d0dc4 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -610,7 +610,9 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont return NULL; memcpy(tioca_common, prom_bussoft, sizeof(struct tioca_common)); - tioca_common->ca_common.bs_base |= __IA64_UNCACHED_OFFSET; + tioca_common->ca_common.bs_base = (unsigned long) + ioremap(REGION_OFFSET(tioca_common->ca_common.bs_base), + sizeof(struct tioca_common)); /* init kernel-private area */ diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index f4c0b961a939..84b72b27e27f 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c @@ -1002,7 +1002,9 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont return NULL; memcpy(tioce_common, prom_bussoft, sizeof(struct tioce_common)); - tioce_common->ce_pcibus.bs_base |= __IA64_UNCACHED_OFFSET; + tioce_common->ce_pcibus.bs_base = (unsigned long) + ioremap(REGION_OFFSET(tioce_common->ce_pcibus.bs_base), + sizeof(struct tioce_common)); tioce_kern = tioce_kern_init(tioce_common); if (tioce_kern == NULL) { |