diff options
| author | Matthew Wilcox <willy@debian.org> | 2003-06-15 07:10:47 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-06-15 07:10:47 -0700 |
| commit | 9ff05b1bdf4cfa7dc41fe7d878a780d35196a87d (patch) | |
| tree | 612687a570b6f879cb292ec5e11d7dff99e389b3 | |
| parent | 20904d2543057fef12c928764922e1d190c2c455 (diff) | |
[PATCH] parisc arch update
This update covers a lot of changes to arch/parisc and parisc-specific
drivers.
- irq_return_t changes
- more work on the module loader (James Bottomley)
- rewrite of led.c by Helge Deller
- many miscellaneous updates
40 files changed, 491 insertions, 369 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 50b3c5a8c8e0..567e32f52ee2 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -103,11 +103,6 @@ config PARISC64 enable this option otherwise. The 64bit kernel is significantly bigger and slower than the 32bit one. -config COMPAT - bool - depends on PARISC64 - default y - config PDC_NARROW bool "32-bit firmware" depends on PARISC64 @@ -145,6 +140,14 @@ config PREEMPT # bool "Preemptible Kernel" default n +config COMPAT + bool + depends on PARISC64 + default y + +config HPUX + bool "Support for HP-UX binaries" + config NR_CPUS int "Maximum number of CPUs (2-32)" depends on SMP @@ -165,6 +168,7 @@ config KCORE_ELF config BINFMT_SOM tristate "Kernel support for SOM binaries" + depends on HPUX help SOM is a binary executable format inherited from HP/UX. Say Y here to be able to load and execute SOM binaries directly. diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 09179d4de120..0360608cb28c 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -57,8 +57,10 @@ head-$(CONFIG_PARISC64) := arch/parisc/kernel/head64.o CFLAGS += $(cflags-y) -core-y += $(addprefix arch/parisc/, kernel/pdc_cons.o kernel/process.o \ - mm/ kernel/ hpux/ math-emu/ kernel/init_task.o ) +kernel-y := mm/ kernel/ math-emu/ kernel/init_task.o +kernel-$(CONFIG_HPUX) += hpux/ + +core-y += $(addprefix arch/parisc/, $(kernel-y)) libs-y += arch/parisc/lib/ `$(CC) -print-libgcc-file-name` drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/ diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index d2a7d8813f45..8eb8daa39ee0 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -4,8 +4,7 @@ head-y := head.o head-$(CONFIG_PARISC64) := head64.o -extra-y := init_task.o pdc_cons.o process.o \ - unaligned.o $(head-y) +extra-y := init_task.o $(head-y) AFLAGS_entry.o := -traditional AFLAGS_pacache.o := -traditional @@ -14,7 +13,7 @@ obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ ptrace.o hardware.o inventory.o drivers.o semaphore.o \ signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \ - processor.o pdc_chassis.o + process.o processor.o pdc_cons.o pdc_chassis.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_PA11) += pci-dma.o diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 4e898b9a43b3..78f20ebdbab8 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -546,7 +546,7 @@ __kernel_thread: LDREG -PT_SZ_ALGN-RP_OFFSET(%r30), %r2 ldo -PT_SZ_ALGN(%r30), %r30 bv %r0(%r2) - ldw TASK_PID(%r28), %r28 + nop /* * Child Returns here diff --git a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c index e0848a833d2e..6cb5cc3dce88 100644 --- a/arch/parisc/kernel/ioctl32.c +++ b/arch/parisc/kernel/ioctl32.c @@ -1785,9 +1785,6 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg) return -EINVAL; } -#ifdef CONFIG_GENRTC -#endif - #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE) /* This really belongs in include/linux/drm.h -DaveM */ #include "../../../drivers/char/drm/drm.h" diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 64646c43b5c3..81e369f23f5e 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -43,8 +43,8 @@ #undef DEBUG_IRQ #undef PARISC_IRQ_CR16_COUNTS -extern void timer_interrupt(int, void *, struct pt_regs *); -extern void ipi_interrupt(int, void *, struct pt_regs *); +extern irqreturn_t timer_interrupt(int, void *, struct pt_regs *); +extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *); #ifdef DEBUG_IRQ #define DBG_IRQ(irq, x) if ((irq) != TIMER_IRQ) printk x @@ -583,7 +583,7 @@ struct irq_region *alloc_irq_region( int count, struct irq_region_ops *ops, /* FIXME: SMP, flags, bottom halves, rest */ int request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), + irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id) diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 936eba6c6b99..cf7d6d0a8ec9 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -27,12 +27,39 @@ #include <linux/string.h> #include <linux/kernel.h> -#if 1 +#if 0 #define DEBUGP printk #else #define DEBUGP(fmt...) #endif +#define CHECK_RELOC(val, bits) \ + if ( ( !((val) & (1<<((bits)-1))) && ((val)>>(bits)) != 0 ) || \ + ( ((val) & (1<<((bits)-1))) && ((val)>>(bits)) != (((__typeof__(val))(~0))>>((bits)+2)))) { \ + printk(KERN_ERR "module %s relocation of symbol %s is out of range (0x%lx in %d bits)\n", \ + me->name, strtab + sym->st_name, (unsigned long)val, bits); \ + return -ENOEXEC; \ + } + +/* three functions to determine where in the module core + * or init pieces the location is */ +static inline int is_init(struct module *me, void *loc) +{ + return (loc >= me->module_init && + loc <= (me->module_init + me->init_size)); +} + +static inline int is_core(struct module *me, void *loc) +{ + return (loc >= me->module_core && + loc <= (me->module_core + me->core_size)); +} + +static inline int is_local(struct module *me, void *loc) +{ + return is_init(me, loc) || is_core(me, loc); +} + #ifndef __LP64__ struct got_entry { @@ -40,8 +67,8 @@ struct got_entry { }; struct fdesc_entry { - Elf32_Addr gp; Elf32_Addr addr; + Elf32_Addr gp; }; struct stub_entry { @@ -54,8 +81,8 @@ struct got_entry { struct fdesc_entry { Elf64_Addr dummy[2]; - Elf64_Addr gp; Elf64_Addr addr; + Elf64_Addr gp; }; struct stub_entry { @@ -167,7 +194,7 @@ static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n) static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n) { - unsigned long cnt = 3; /* 3 for finalize */ + unsigned long cnt = 0; for (; n > 0; n--, rela++) { @@ -211,7 +238,7 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr, CONST char *secstrings, struct module *me) { - unsigned long gots = 0, fdescs = 0, stubs = 0; + unsigned long gots = 0, fdescs = 0, stubs = 0, init_stubs = 0; unsigned int i; for (i = 1; i < hdr->e_shnum; i++) { @@ -228,7 +255,11 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr, */ gots += count_gots(rels, nrels); fdescs += count_fdescs(rels, nrels); - stubs += count_stubs(rels, nrels); + if(strncmp(secstrings + sechdrs[i].sh_name, + ".rela.init", 10) == 0) + init_stubs += count_stubs(rels, nrels); + else + stubs += count_stubs(rels, nrels); } /* align things a bit */ @@ -238,16 +269,26 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr, me->core_size = ALIGN(me->core_size, 16); me->arch.fdesc_offset = me->core_size; - me->core_size += stubs * sizeof(struct fdesc_entry); + me->core_size += fdescs * sizeof(struct fdesc_entry); me->core_size = ALIGN(me->core_size, 16); me->arch.stub_offset = me->core_size; me->core_size += stubs * sizeof(struct stub_entry); + me->init_size = ALIGN(me->init_size, 16); + me->arch.init_stub_offset = me->init_size; + me->init_size += init_stubs * sizeof(struct stub_entry); + + me->arch.got_max = gots; + me->arch.fdesc_max = fdescs; + me->arch.stub_max = stubs; + me->arch.init_stub_max = init_stubs; + return 0; } -static Elf_Addr get_got(struct module *me, unsigned long value, long addend) +#ifdef __LP64__ +static Elf64_Word get_got(struct module *me, unsigned long value, long addend) { unsigned int i; struct got_entry *got; @@ -261,10 +302,14 @@ static Elf_Addr get_got(struct module *me, unsigned long value, long addend) if (got[i].addr == value) return i * sizeof(struct got_entry); + BUG_ON(++me->arch.got_count > me->arch.got_max); + got[i].addr = value; return i * sizeof(struct got_entry); } +#endif /* __LP64__ */ +#ifdef __LP64__ static Elf_Addr get_fdesc(struct module *me, unsigned long value) { struct fdesc_entry *fdesc = me->module_core + me->arch.fdesc_offset; @@ -281,32 +326,46 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value) fdesc++; } + BUG_ON(++me->arch.fdesc_count > me->arch.fdesc_max); + /* Create new one */ fdesc->addr = value; fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset; return (Elf_Addr)fdesc; } +#endif /* __LP64__ */ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, - int millicode) + int millicode, int init_section) { unsigned long i; struct stub_entry *stub; - i = me->arch.stub_count++; - stub = me->module_core + me->arch.stub_offset + - i * sizeof(struct stub_entry); + if(init_section) { + i = me->arch.init_stub_count++; + BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max); + stub = me->module_init + me->arch.init_stub_offset + + i * sizeof(struct stub_entry); + } else { + i = me->arch.stub_count++; + BUG_ON(me->arch.stub_count > me->arch.stub_max); + stub = me->module_core + me->arch.stub_offset + + i * sizeof(struct stub_entry); + } #ifndef __LP64__ /* for 32-bit the stub looks like this: * ldil L'XXX,%r1 * be,n R'XXX(%sr4,%r1) */ + //value = *(unsigned long *)((value + addend) & ~3); /* why? */ + stub->insns[0] = 0x20200000; /* ldil L'XXX,%r1 */ stub->insns[1] = 0xe0202002; /* be,n R'XXX(%sr4,%r1) */ stub->insns[0] |= reassemble_21(lrsel(value, addend)); stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4); + #else /* for 64-bit we have two kinds of stubs: * for normal function calls: @@ -328,7 +387,7 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, stub->insns[2] = 0xe820d000; /* bve (%r1) */ stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */ - stub->insns[0] |= reassemble_21(get_got(me, value, addend)); + stub->insns[0] |= reassemble_14(rrsel(get_got(me, value, addend),0)); } else { @@ -371,6 +430,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, Elf32_Addr val; Elf32_Sword addend; Elf32_Addr dot; + //unsigned long dp = (unsigned long)$global$; register unsigned long dp asm ("r27"); DEBUGP("Applying relocate section %u to %u\n", relsec, @@ -387,7 +447,8 @@ int apply_relocate_add(Elf_Shdr *sechdrs, me->name, strtab + sym->st_name); return -ENOENT; } - dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03; + //dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03; + dot = (Elf32_Addr)loc & ~0x03; val = sym->st_value; addend = rel[i].r_addend; @@ -422,11 +483,13 @@ int apply_relocate_add(Elf_Shdr *sechdrs, break; case R_PARISC_DIR21L: /* left 21 bits of effective address */ - *loc = mask(*loc, 21) | reassemble_21(lrsel(val, addend)); + val = lrsel(val, addend); + *loc = mask(*loc, 21) | reassemble_21(val); break; case R_PARISC_DIR14R: /* right 14 bits of effective address */ - *loc = mask(*loc, 14) | reassemble_14(rrsel(val, addend)); + val = rrsel(val, addend); + *loc = mask(*loc, 14) | reassemble_14(val); break; case R_PARISC_SEGREL32: /* 32-bit segment relative address */ @@ -435,23 +498,27 @@ int apply_relocate_add(Elf_Shdr *sechdrs, break; case R_PARISC_DPREL21L: /* left 21 bit of relative address */ - val -= dp; - *loc = mask(*loc, 21) | reassemble_21(lrsel(val, addend) - dp); + val = lrsel(val - dp, addend); + *loc = mask(*loc, 21) | reassemble_21(val); break; case R_PARISC_DPREL14R: /* right 14 bit of relative address */ - val -= dp; - *loc = mask(*loc, 14) | reassemble_14(rrsel(val, addend) - dp); + val = rrsel(val - dp, addend); + *loc = mask(*loc, 14) | reassemble_14(val); break; case R_PARISC_PCREL17F: /* 17-bit PC relative address */ - val = get_stub(me, val, addend, 0) - dot - 8; - *loc = (*loc&0x1f1ffd) | reassemble_17(val); + val = get_stub(me, val, addend, 0, is_init(me, loc)); + val = (val - dot - 8)/4; + CHECK_RELOC(val, 17) + *loc = (*loc & ~0x1f1ffd) | reassemble_17(val); break; case R_PARISC_PCREL22F: /* 22-bit PC relative address; only defined for pa20 */ - val = get_stub(me, val, addend, 0) - dot - 8; - *loc = (*loc&0x3ff1ffd) | reassemble_22(val); + val = get_stub(me, val, addend, 0, is_init(me, loc)); + val = (val - dot - 8)/4; + CHECK_RELOC(val, 22); + *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val); break; default: @@ -475,6 +542,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr; Elf64_Sym *sym; Elf64_Word *loc; + Elf64_Xword *loc64; Elf64_Addr val; Elf64_Sxword addend; Elf64_Addr dot; @@ -493,14 +561,16 @@ int apply_relocate_add(Elf_Shdr *sechdrs, me->name, strtab + sym->st_name); return -ENOENT; } - dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03; + //dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03; + dot = (Elf64_Addr)loc & ~0x03; + loc64 = (Elf64_Xword *)loc; val = sym->st_value; addend = rel[i].r_addend; -#if 1 +#if 0 #define r(t) ELF64_R_TYPE(rel[i].r_info)==t ? #t : - DEBUGP("Symbol %s loc %p val 0x%Lx addend 0x%Lx: %s\n", + printk("Symbol %s loc %p val 0x%Lx addend 0x%Lx: %s\n", strtab + sym->st_name, loc, val, addend, r(R_PARISC_LTOFF14R) @@ -516,24 +586,56 @@ int apply_relocate_add(Elf_Shdr *sechdrs, switch (ELF64_R_TYPE(rel[i].r_info)) { case R_PARISC_LTOFF21L: /* LT-relative; left 21 bits */ - *loc = mask(*loc, 21) | reassemble_21(get_got(me, val, addend)); + val = get_got(me, val, addend); + DEBUGP("LTOFF21L Symbol %s loc %p val %lx\n", + strtab + sym->st_name, + loc, val); + val = lrsel(val, 0); + *loc = mask(*loc, 21) | reassemble_21(val); break; case R_PARISC_LTOFF14R: /* L(ltoff(val+addend)) */ /* LT-relative; right 14 bits */ - *loc = mask(*loc, 14) | reassemble_14(get_got(me, val, addend)); + val = get_got(me, val, addend); + val = rrsel(val, 0); + DEBUGP("LTOFF14R Symbol %s loc %p val %lx\n", + strtab + sym->st_name, + loc, val); + *loc = mask(*loc, 14) | reassemble_14(val); break; case R_PARISC_PCREL22F: /* PC-relative; 22 bits */ - if (strncmp(strtab + sym->st_name, "$$", 2) == 0) - val = get_stub(me, val, addend, 1) - dot - 8; - else - val = get_stub(me, val, addend, 0) - dot - 8; - *loc = (*loc&0x3ff1ffd) | reassemble_22(val); + DEBUGP("PCREL22F Symbol %s loc %p val %lx\n", + strtab + sym->st_name, + loc, val); + /* can we reach it locally? */ + if(!is_local(me, (void *)val)) { + if (strncmp(strtab + sym->st_name, "$$", 2) + == 0) + val = get_stub(me, val, addend, 1, + is_init(me, loc)); + else + val = get_stub(me, val, addend, 0, + is_init(me, loc)); + } + /* FIXME: local symbols work as long as the + * core and init pieces aren't separated too + * far. If this is ever broken, you will trip + * the check below. The way to fix it would + * be to generate local stubs to go between init + * and core */ + if((Elf64_Sxword)(val - dot - 8) > 0x800000 -1 || + (Elf64_Sxword)(val - dot - 8) < -0x800000) { + printk(KERN_ERR "Module %s, symbol %s is out of range for PCREL22F relocation\n", + me->name, strtab + sym->st_name); + return -ENOEXEC; + } + val = (val - dot - 8)/4; + *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val); break; case R_PARISC_DIR64: /* 64-bit effective address */ - *loc = fsel(val, addend); + *loc64 = val + addend; break; case R_PARISC_SEGREL32: /* 32-bit segment relative address */ @@ -542,7 +644,17 @@ int apply_relocate_add(Elf_Shdr *sechdrs, break; case R_PARISC_FPTR64: /* 64-bit function address */ - *loc = get_fdesc(me, val+addend); + if(is_local(me, (void *)(val + addend))) { + *loc64 = get_fdesc(me, val+addend); + } else { + /* if the symbol is not local to this + * module then val+addend is a pointer + * to the function descriptor */ + DEBUGP("Non local FPTR64 Symbol %s loc %p val %lx\n", + strtab + sym->st_name, + loc, val); + *loc64 = val + addend; + } break; default: @@ -559,13 +671,26 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { -#ifdef __LP64__ - me->init = (void *)get_fdesc(me, (Elf_Addr)me->init); -#ifdef CONFIG_MODULE_UNLOAD - if (me->exit) - me->exit = (void *)get_fdesc(me, (Elf_Addr)me->exit); -#endif +#ifdef DEBUG + struct fdesc_entry *entry; + u32 *addr; + + entry = (struct fdesc_entry *)me->init; + printk("FINALIZE, ->init FPTR is %p, GP %lx ADDR %lx\n", entry, + entry->gp, entry->addr); + addr = (u32 *)entry->addr; + printk("INSNS: %x %x %x %x\n", + addr[0], addr[1], addr[2], addr[3]); + printk("stubs used %ld, stubs max %ld\n" + "init_stubs used %ld, init stubs max %ld\n" + "got entries used %ld, gots max %ld\n" + "fdescs used %ld, fdescs max %ld\n", + me->arch.stub_count, me->arch.stub_max, + me->arch.init_stub_count, me->arch.init_stub_max, + me->arch.got_count, me->arch.got_max, + me->arch.fdesc_count, me->arch.fdesc_max); #endif + return 0; } diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index dc7048b99724..5158dd2e2a04 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -7,22 +7,24 @@ #include <linux/kernel.h> #include <linux/string.h> -EXPORT_SYMBOL_NOVERS(memscan); -EXPORT_SYMBOL_NOVERS(memset); +EXPORT_SYMBOL(memchr); EXPORT_SYMBOL(memcmp); -EXPORT_SYMBOL_NOVERS(memcpy); +EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(memscan); +EXPORT_SYMBOL(memset); EXPORT_SYMBOL(strcat); EXPORT_SYMBOL(strchr); -EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(strcmp); EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strlen); -EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strncat); EXPORT_SYMBOL(strncmp); EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(strpbrk); #include <asm/hardware.h> /* struct parisc_device for asm/pci.h */ #include <linux/pci.h> @@ -39,7 +41,6 @@ EXPORT_SYMBOL(disable_irq); #include <asm/processor.h> EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(boot_cpu_data); -EXPORT_SYMBOL(map_hpux_gateway_page); #ifdef CONFIG_EISA EXPORT_SYMBOL(EISA_bus); #endif @@ -72,12 +73,16 @@ EXPORT_SYMBOL(lclear_user); #ifndef __LP64__ /* Needed so insmod can set dp value */ extern int $global$; -EXPORT_SYMBOL_NOVERS($global$); +EXPORT_SYMBOL($global$); #endif EXPORT_SYMBOL(register_parisc_driver); EXPORT_SYMBOL(unregister_parisc_driver); +EXPORT_SYMBOL(print_pci_hwpath); +EXPORT_SYMBOL(print_pa_hwpath); EXPORT_SYMBOL(pdc_iodc_read); +EXPORT_SYMBOL(pdc_tod_read); +EXPORT_SYMBOL(pdc_tod_set); #include <asm/io.h> EXPORT_SYMBOL(__ioremap); @@ -105,7 +110,12 @@ EXPORT_SYMBOL(outsl); #include <asm/cache.h> EXPORT_SYMBOL(flush_kernel_dcache_range_asm); EXPORT_SYMBOL(flush_kernel_dcache_page); +EXPORT_SYMBOL(flush_data_cache_local); +EXPORT_SYMBOL(flush_kernel_icache_range_asm); +EXPORT_SYMBOL(__flush_dcache_page); EXPORT_SYMBOL(flush_all_caches); +EXPORT_SYMBOL(dcache_stride); +EXPORT_SYMBOL(flush_cache_all_local); #include <asm/unistd.h> extern long sys_open(const char *, int, int); @@ -131,6 +141,7 @@ EXPORT_SYMBOL(csum_partial_copy_from_user); EXPORT_SYMBOL(pdc_add_valid); EXPORT_SYMBOL(pdc_lan_station_id); EXPORT_SYMBOL(pdc_get_initiator); +EXPORT_SYMBOL(pdc_sti_call); extern void $$divI(void); extern void $$divU(void); @@ -156,39 +167,39 @@ extern void $$divI_12(void); extern void $$divI_14(void); extern void $$divI_15(void); -EXPORT_SYMBOL_NOVERS($$divI); -EXPORT_SYMBOL_NOVERS($$divU); -EXPORT_SYMBOL_NOVERS($$remI); -EXPORT_SYMBOL_NOVERS($$remU); -EXPORT_SYMBOL_NOVERS($$mulI); -EXPORT_SYMBOL_NOVERS($$divU_3); -EXPORT_SYMBOL_NOVERS($$divU_5); -EXPORT_SYMBOL_NOVERS($$divU_6); -EXPORT_SYMBOL_NOVERS($$divU_9); -EXPORT_SYMBOL_NOVERS($$divU_10); -EXPORT_SYMBOL_NOVERS($$divU_12); -EXPORT_SYMBOL_NOVERS($$divU_7); -EXPORT_SYMBOL_NOVERS($$divU_14); -EXPORT_SYMBOL_NOVERS($$divU_15); -EXPORT_SYMBOL_NOVERS($$divI_3); -EXPORT_SYMBOL_NOVERS($$divI_5); -EXPORT_SYMBOL_NOVERS($$divI_6); -EXPORT_SYMBOL_NOVERS($$divI_7); -EXPORT_SYMBOL_NOVERS($$divI_9); -EXPORT_SYMBOL_NOVERS($$divI_10); -EXPORT_SYMBOL_NOVERS($$divI_12); -EXPORT_SYMBOL_NOVERS($$divI_14); -EXPORT_SYMBOL_NOVERS($$divI_15); +EXPORT_SYMBOL($$divI); +EXPORT_SYMBOL($$divU); +EXPORT_SYMBOL($$remI); +EXPORT_SYMBOL($$remU); +EXPORT_SYMBOL($$mulI); +EXPORT_SYMBOL($$divU_3); +EXPORT_SYMBOL($$divU_5); +EXPORT_SYMBOL($$divU_6); +EXPORT_SYMBOL($$divU_9); +EXPORT_SYMBOL($$divU_10); +EXPORT_SYMBOL($$divU_12); +EXPORT_SYMBOL($$divU_7); +EXPORT_SYMBOL($$divU_14); +EXPORT_SYMBOL($$divU_15); +EXPORT_SYMBOL($$divI_3); +EXPORT_SYMBOL($$divI_5); +EXPORT_SYMBOL($$divI_6); +EXPORT_SYMBOL($$divI_7); +EXPORT_SYMBOL($$divI_9); +EXPORT_SYMBOL($$divI_10); +EXPORT_SYMBOL($$divI_12); +EXPORT_SYMBOL($$divI_14); +EXPORT_SYMBOL($$divI_15); extern void __ashrdi3(void); extern void __ashldi3(void); extern void __lshrdi3(void); extern void __muldi3(void); -EXPORT_SYMBOL_NOVERS(__ashrdi3); -EXPORT_SYMBOL_NOVERS(__ashldi3); -EXPORT_SYMBOL_NOVERS(__lshrdi3); -EXPORT_SYMBOL_NOVERS(__muldi3); +EXPORT_SYMBOL(__ashrdi3); +EXPORT_SYMBOL(__ashldi3); +EXPORT_SYMBOL(__lshrdi3); +EXPORT_SYMBOL(__muldi3); #ifdef __LP64__ extern void __divdi3(void); @@ -196,16 +207,16 @@ extern void __udivdi3(void); extern void __umoddi3(void); extern void __moddi3(void); -EXPORT_SYMBOL_NOVERS(__divdi3); -EXPORT_SYMBOL_NOVERS(__udivdi3); -EXPORT_SYMBOL_NOVERS(__umoddi3); -EXPORT_SYMBOL_NOVERS(__moddi3); +EXPORT_SYMBOL(__divdi3); +EXPORT_SYMBOL(__udivdi3); +EXPORT_SYMBOL(__umoddi3); +EXPORT_SYMBOL(__moddi3); #endif #ifndef __LP64__ extern void $$dyncall(void); -EXPORT_SYMBOL_NOVERS($$dyncall); +EXPORT_SYMBOL($$dyncall); #endif #include <asm/pgtable.h> -EXPORT_SYMBOL_NOVERS(vmalloc_start); +EXPORT_SYMBOL(vmalloc_start); diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index aafcdecb3625..5561b11fc1f4 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c @@ -24,6 +24,7 @@ #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/major.h> +#include <linux/tty.h> #include <asm/page.h> #include <asm/types.h> #include <asm/system.h> @@ -52,12 +53,24 @@ static int pdc_console_setup(struct console *co, char *options) return 0; } -#if defined(CONFIG_PDC_CONSOLE) || defined(CONFIG_SERIAL_MUX) +#if defined(CONFIG_PDC_CONSOLE) #define PDC_CONSOLE_DEVICE pdc_console_device -static kdev_t pdc_console_device (struct console *c) +static struct tty_driver * pdc_console_device (struct console *c, int *index) +{ + extern struct tty_driver console_driver; + *index = c->index ? c->index-1 : fg_console; + return &console_driver; +} + +#elif defined(CONFIG_SERIAL_MUX) +#warning CONFIG_SERIAL_MUX +#define PDC_CONSOLE_DEVICE pdc_console_device +#warning "FIXME - should be: static struct tty_driver * pdc_console_device (struct console *c, int *index)" +static kdev_t pdc_console_device (struct console *c, int *index) { return mk_kdev(MUX_MAJOR, 0); } + #else #define PDC_CONSOLE_DEVICE NULL #endif diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 073a66456867..9bc568e4e755 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -10,33 +10,23 @@ #define __KERNEL_SYSCALLS__ #include <stdarg.h> +#include <linux/elf.h> #include <linux/errno.h> -#include <linux/sched.h> #include <linux/kernel.h> #include <linux/mm.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> +#include <linux/personality.h> +#include <linux/ptrace.h> +#include <linux/sched.h> #include <linux/stddef.h> #include <linux/unistd.h> -#include <linux/ptrace.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/interrupt.h> -#include <linux/reboot.h> -#include <linux/init.h> #include <linux/version.h> -#include <linux/elf.h> -#include <linux/personality.h> -#include <asm/machdep.h> -#include <asm/offsets.h> -#include <asm/uaccess.h> -#include <asm/pgtable.h> -#include <asm/pgalloc.h> -#include <asm/system.h> #include <asm/io.h> -#include <asm/processor.h> +#include <asm/offsets.h> +#include <asm/pdc.h> #include <asm/pdc_chassis.h> +#include <asm/pgalloc.h> +#include <asm/uaccess.h> int hlt_counter; @@ -224,18 +214,14 @@ int sys_clone(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs) { - struct task_struct *p; int *user_tid = (int *)regs->gr[26]; - p = do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0, user_tid, NULL); - return IS_ERR(p) ? PTR_ERR(p) : p->pid; + return do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0, user_tid, NULL); } int sys_vfork(struct pt_regs *regs) { - struct task_struct *p; - p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL); - return IS_ERR(p) ? PTR_ERR(p) : p->pid; + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL); } int @@ -251,7 +237,9 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, * Make them const so the compiler knows they live in .text */ extern void * const ret_from_kernel_thread; extern void * const child_return; +#ifdef CONFIG_HPUX extern void * const hpux_child_return; +#endif *cregs = *pregs; @@ -295,7 +283,11 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, + (pregs->gr[21] & (INIT_THREAD_SIZE - 1)); cregs->gr[30] = usp; if (p->personality == PER_HPUX) { +#ifdef CONFIG_HPUX cregs->kpc = (unsigned long) &hpux_child_return; +#else + BUG(); +#endif } else { cregs->kpc = (unsigned long) &child_return; } diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index 188af817f0d0..ddccdfe8adbe 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -145,6 +145,7 @@ static int __init processor_probe(struct parisc_device *dev) /* initialize counters */ memset(p, 0, sizeof(struct cpuinfo_parisc)); + p->loops_per_jiffy = loops_per_jiffy; p->dev = dev; /* Save IODC data in case we need it */ p->hpa = dev->hpa; /* save CPU hpa */ p->cpuid = cpuid; /* save CPU id */ @@ -356,8 +357,8 @@ show_cpuinfo (struct seq_file *m, void *v) show_cache_info(m); seq_printf(m, "bogomips\t: %lu.%02lu\n", - loops_per_jiffy / (500000 / HZ), - (loops_per_jiffy / (5000 / HZ)) % 100); + cpu_data[n].loops_per_jiffy / (500000 / HZ), + (cpu_data[n].loops_per_jiffy / (5000 / HZ)) % 100); seq_printf(m, "software id\t: %ld\n\n", boot_cpu_data.pdc.model.sw_id); diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 3dd43f06820c..a0aabd65bfe8 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -309,7 +309,8 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, } #endif -#if CACHE_FLUSHING_IS_NOT_BROKEN +#undef CACHE_FLUSHING_IS_NOT_BROKEN +#ifdef CACHE_FLUSHING_IS_NOT_BROKEN flush_user_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[4]); #else diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 84eea09ef6c6..edf4e669ecfc 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -147,7 +147,7 @@ halt_processor(void) } -void +irqreturn_t ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int this_cpu = smp_processor_id(); @@ -256,7 +256,7 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs) } /* Switch */ } /* while (ops) */ } - return; + return IRQ_HANDLED; } @@ -515,14 +515,14 @@ static struct task_struct *fork_by_hand(void) * don't care about the regs settings since * we'll never reschedule the forked task. */ - return do_fork(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0, NULL, NULL); + return copy_process(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0, NULL, NULL); } /* * Bring one cpu online. */ -static int smp_boot_one_cpu(int cpuid, int cpunum) +static int __init smp_boot_one_cpu(int cpuid, int cpunum) { struct task_struct *idle; long timeout; @@ -537,9 +537,11 @@ static int smp_boot_one_cpu(int cpuid, int cpunum) * Sheesh . . . */ - if ((idle = fork_by_hand()) == 0) + idle = fork_by_hand(); + if (IS_ERR(idle)) panic("SMP: fork failed for CPU:%d", cpuid); + wake_up_forked_process(idle); init_idle(idle, cpunum); unhash_process(idle); idle->thread_info->cpu = cpunum; @@ -613,7 +615,7 @@ alive: void __init smp_boot_cpus(void) { int i, cpu_count = 1; - unsigned long bogosum = loops_per_jiffy; /* Count Monarch */ + unsigned long bogosum = cpu_data[0].loops_per_jiffy; /* Count Monarch */ /* REVISIT - assumes first CPU reported by PAT PDC is BSP */ int bootstrap_processor=cpu_data[0].cpuid; /* CPU ID of BSP */ @@ -650,7 +652,7 @@ void __init smp_boot_cpus(void) if (smp_boot_one_cpu(cpu_data[i].cpuid, cpu_count) < 0) continue; - bogosum += loops_per_jiffy; + bogosum += cpu_data[i].loops_per_jiffy; cpu_count++; /* Count good CPUs only... */ cpu_present_mask |= 1UL << i; diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index 23a0afcf31a6..3194fd85b1ec 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -30,10 +30,7 @@ #include <linux/slab.h> #include <linux/uio.h> #include <linux/nfs_fs.h> -#include <linux/smb_fs.h> -#include <linux/smb_mount.h> #include <linux/ncp_fs.h> -#include <linux/quota.h> #include <linux/sunrpc/svc.h> #include <linux/nfsd/nfsd.h> #include <linux/nfsd/cache.h> @@ -42,11 +39,6 @@ #include <linux/poll.h> #include <linux/personality.h> #include <linux/stat.h> -#include <linux/filter.h> /* for setsockopt() */ -#include <linux/icmpv6.h> /* for setsockopt() */ -#include <linux/netfilter_ipv4/ip_queue.h> /* for setsockopt() */ -#include <linux/netfilter_ipv4/ip_tables.h> /* for setsockopt() */ -#include <linux/netfilter_ipv6/ip6_tables.h> /* for setsockopt() */ #include <linux/highmem.h> #include <linux/highuid.h> #include <linux/mman.h> @@ -62,9 +54,6 @@ #include "sys32.h" -#define A(__x) ((unsigned long)(__x)) - - #undef DEBUG #ifdef DEBUG @@ -73,34 +62,6 @@ #define DBG(x) #endif -/* For this source file, we want overflow handling. */ - -#undef high2lowuid -#undef high2lowgid -#undef low2highuid -#undef low2highgid -#undef SET_UID16 -#undef SET_GID16 -#undef NEW_TO_OLD_UID -#undef NEW_TO_OLD_GID -#undef SET_OLDSTAT_UID -#undef SET_OLDSTAT_GID -#undef SET_STAT_UID -#undef SET_STAT_GID - -#define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) -#define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) -#define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid) -#define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid) -#define SET_UID16(var, uid) var = high2lowuid(uid) -#define SET_GID16(var, gid) var = high2lowgid(gid) -#define NEW_TO_OLD_UID(uid) high2lowuid(uid) -#define NEW_TO_OLD_GID(gid) high2lowgid(gid) -#define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) -#define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) -#define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) -#define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) - /* * count32() counts the number of arguments/envelopes. It is basically * a copy of count() from fs/exec.c, except that it works @@ -145,7 +106,7 @@ static int copy_strings32(int argc, u32 *argv, struct linux_binprm *bprm) if (get_user(str, argv + argc) || !str || - !(len = strnlen_user((char *)A(str), bprm->p))) + !(len = strnlen_user((char *)compat_ptr(str), bprm->p))) return -EFAULT; if (bprm->p < len) @@ -181,7 +142,7 @@ static int copy_strings32(int argc, u32 *argv, struct linux_binprm *bprm) if (new) memset(kaddr+offset+len, 0, PAGE_SIZE-offset-len); } - err = copy_from_user(kaddr + offset, (char *)A(str), bytes_to_copy); + err = copy_from_user(kaddr + offset, (char *)compat_ptr(str), bytes_to_copy); flush_dcache_page(page); kunmap(page); @@ -784,7 +745,7 @@ do_readv_writev32(int type, struct file *file, const struct compat_iovec *vector __get_user(len, &vector->iov_len); __get_user(buf, &vector->iov_base); tot_len += len; - ivp->iov_base = (void *)A(buf); + ivp->iov_base = compat_ptr(buf); ivp->iov_len = (compat_size_t) len; vector++; ivp++; @@ -1215,67 +1176,6 @@ asmlinkage int sys32_nfsservctl(int cmd, void *argp, void *resp) return ret; } -#include <linux/quota.h> - -struct dqblk32 { - __u32 dqb_bhardlimit; - __u32 dqb_bsoftlimit; - __u32 dqb_curblocks; - __u32 dqb_ihardlimit; - __u32 dqb_isoftlimit; - __u32 dqb_curinodes; - compat_time_t dqb_btime; - compat_time_t dqb_itime; -}; - - -asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr) -{ -#if 0 - extern int sys_quotactl(int cmd, const char *special, int id, caddr_t addr); - int cmds = cmd >> SUBCMDSHIFT; - int err; - struct dqblk d; - char *spec; - - switch (cmds) { - case Q_GETQUOTA: - break; - case Q_SETQUOTA: - case Q_SETUSE: - case Q_SETQLIM: - if (copy_from_user (&d, (struct dqblk32 *)addr, - sizeof (struct dqblk32))) - return -EFAULT; - d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime; - d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime; - break; - default: - return sys_quotactl(cmd, special, - id, (caddr_t)addr); - } - spec = getname (special); - err = PTR_ERR(spec); - if (IS_ERR(spec)) return err; - KERNEL_SYSCALL(err, sys_quotactl, cmd, (const char *)spec, id, (caddr_t)&d); - putname (spec); - if (cmds == Q_GETQUOTA) { - __kernel_time_t b = d.dqb_btime, i = d.dqb_itime; - ((struct dqblk32 *)&d)->dqb_itime = i; - ((struct dqblk32 *)&d)->dqb_btime = b; - if (copy_to_user ((struct dqblk32 *)addr, &d, - sizeof (struct dqblk32))) - return -EFAULT; - } - return err; -#endif - /* TODO */ - BUG(); - return -EINVAL; -} - - - extern asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t *offset, size_t count); typedef long __kernel_loff_t32; /* move this to asm/posix_types.h? */ diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index daa166eb06df..29e2ee7e7c12 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -496,7 +496,7 @@ sys_call_table: ENTRY_SAME(delete_module) ENTRY_SAME(ni_syscall) /* 130: get_kernel_syms */ /* time_t inside struct dqblk */ - ENTRY_DIFF(quotactl) /* -- FIXME, doesn't work */ + ENTRY_SAME(quotactl) ENTRY_SAME(getpgid) ENTRY_SAME(fchdir) ENTRY_SAME(bdflush) diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 93aabc61c7d2..926b737674b7 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -76,7 +76,7 @@ parisc_do_profile(struct pt_regs *regs) atomic_inc((atomic_t *)&prof_buffer[pc]); } -void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { long now; long next_tick; @@ -127,6 +127,8 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* check soft power switch status */ if (cpu == 0 && !atomic_read(&power_tasklet.count)) tasklet_schedule(&power_tasklet); + + return IRQ_HANDLED; } /*** converted from ia64 ***/ diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 6174ad652c5b..1761f72f37cf 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -114,6 +114,12 @@ void show_regs(struct pt_regs *regs) printk("%s CPU: %8d CR30: " RFMT " CR31: " RFMT "\n", level, current_thread_info()->cpu, cr30, cr31); printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28); + printk(level); + print_symbol(" IAOQ[0]: %s\n", regs->iaoq[0]); + printk(level); + print_symbol(" IAOQ[1]: %s\n", regs->iaoq[1]); + printk(level); + print_symbol(" RP(r2): %s\n", regs->gr[2]); } diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 93aa656bb8b2..85504e531d35 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -10,6 +10,7 @@ #include <linux/config.h> +#include <linux/module.h> #include <linux/mm.h> #include <linux/bootmem.h> #include <linux/delay.h> @@ -666,6 +667,7 @@ static void __init gateway_init(void) PAGE_SIZE, PAGE_GATEWAY); } +#ifdef CONFIG_HPUX void map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm) { @@ -734,6 +736,8 @@ map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm) pg_table = (pte_t *) __va(pg_table) + start_pte; set_pte(pg_table, __mk_pte(address, PAGE_GATEWAY)); } +EXPORT_SYMBOL(map_hpux_gateway_page); +#endif extern void flush_tlb_all_local(void); diff --git a/arch/parisc/oprofile/init.c b/arch/parisc/oprofile/init.c index 1243435fe176..21ad9bec43c5 100644 --- a/arch/parisc/oprofile/init.c +++ b/arch/parisc/oprofile/init.c @@ -7,10 +7,11 @@ * @author John Levon <levon@movementarian.org> */ +#include <linux/errno.h> +#include <linux/init.h> #include <linux/kernel.h> #include <linux/oprofile.h> -#include <linux/init.h> - + extern void timer_init(struct oprofile_operations ** ops); int __init oprofile_arch_init(struct oprofile_operations ** ops) diff --git a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig index 3a6f314ddaea..ac0860df198b 100644 --- a/drivers/parisc/Kconfig +++ b/drivers/parisc/Kconfig @@ -125,4 +125,27 @@ config CHASSIS_LCD_LED If unsure, say Y. +config HOTPLUG + bool "Support for hot-pluggable devices" + ---help--- + Say Y here if you want to plug devices into your computer while + the system is running, and be able to use them quickly. In many + cases, the devices can likewise be unplugged at any time too. + + One well known example of this is PCMCIA- or PC-cards, credit-card + size devices such as network cards, modems or hard drives which are + plugged into slots found on all modern laptop computers. Another + example, used on modern desktops as well as laptops, is USB. + + Enable HOTPLUG and KMOD, and build a modular kernel. Get agent + software (at <http://linux-hotplug.sourceforge.net/>) and install it. + Then your kernel will automatically call out to a user mode "policy + agent" (/sbin/hotplug) to load modules and set up software needed + to use devices as you hotplug them. + +source "drivers/pcmcia/Kconfig" + +source "drivers/pci/hotplug/Kconfig" + + endmenu diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 38d480f19920..49bac9db320f 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -381,7 +381,7 @@ static struct irq_region_ops dino_irq_ops = { * ilr_loop counter is a kluge to prevent a "stuck" IRQ line from * wedging the CPU. Could be removed or made optional at some point. */ -static void +static irqreturn_t dino_isr(int irq, void *intr_dev, struct pt_regs *regs) { struct dino_device *dino_dev = DINO_DEV(intr_dev); @@ -441,7 +441,9 @@ ilr_again: if (--ilr_loop > 0) goto ilr_again; printk("Dino %lx: stuck interrupt %d\n", dino_dev->hba.base_addr, mask); + return IRQ_NONE; } + return IRQ_HANDLED; } static int dino_choose_irq(struct parisc_device *dev) diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index afd2267104ba..547ef6adffe9 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c @@ -213,7 +213,7 @@ static struct irq_region eisa_irq_region = { .action = action, }; -static void eisa_irq(int _, void *intr_dev, struct pt_regs *regs) +static irqreturn_t eisa_irq(int _, void *intr_dev, struct pt_regs *regs) { extern void do_irq(struct irqaction *a, int i, struct pt_regs *p); int irq = gsc_readb(0xfc01f000); /* EISA supports 16 irqs */ @@ -262,11 +262,13 @@ static void eisa_irq(int _, void *intr_dev, struct pt_regs *regs) eisa_out8(master_mask, 0x21); } spin_unlock_irqrestore(&eisa_irq_lock, flags); + return IRQ_HANDLED; } -static void dummy_irq2_handler(int _, void *dev, struct pt_regs *regs) +static irqreturn_t dummy_irq2_handler(int _, void *dev, struct pt_regs *regs) { printk(KERN_ALERT "eisa: uhh, irq2?\n"); + return IRQ_HANDLED; } static void init_eisa_pic(void) diff --git a/drivers/parisc/eisa_eeprom.c b/drivers/parisc/eisa_eeprom.c index bdd34f5f609f..bda206c1393f 100644 --- a/drivers/parisc/eisa_eeprom.c +++ b/drivers/parisc/eisa_eeprom.c @@ -4,6 +4,7 @@ #include <linux/kernel.h> #include <linux/miscdevice.h> #include <linux/slab.h> +#include <linux/fs.h> #include <asm/io.h> #include <asm/uaccess.h> #include <asm/eisa_eeprom.h> diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index f5a921a6db1b..6f78bdb4180a 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c @@ -79,7 +79,7 @@ EXPORT_SYMBOL(gsc_claim_irq); #define GSC_MASK_IRQ(x) (1<<(GSC_FIX_IRQ(x))) /* Common interrupt demultiplexer used by Asp, Lasi & Wax. */ -void busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs) +irqreturn_t busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs) { unsigned long irq; struct busdevice *busdev = (struct busdevice *) dev; @@ -101,6 +101,7 @@ void busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs) do_irq_mask(irq, busdev->busdev_region, regs); } + return IRQ_HANDLED; } static void diff --git a/drivers/parisc/gsc.h b/drivers/parisc/gsc.h index 865976ea99c1..cd05a1fad17b 100644 --- a/drivers/parisc/gsc.h +++ b/drivers/parisc/gsc.h @@ -43,4 +43,4 @@ int gsc_common_irqsetup(struct parisc_device *parent, struct busdevice *busdev); extern int gsc_alloc_irq(struct gsc_irq *dev); /* dev needs an irq */ extern int gsc_claim_irq(struct gsc_irq *dev, int irq); /* dev needs this irq */ -void busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs); +irqreturn_t busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs); diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index d5ca79f00343..89d1484e9a73 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -605,7 +605,7 @@ iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev) } -static void +static irqreturn_t iosapic_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct vector_info *vi = (struct vector_info *)dev_id; @@ -623,6 +623,8 @@ iosapic_interrupt(int irq, void *dev_id, struct pt_regs * regs) ** I/O SAPIC must always issue EOI. */ IOSAPIC_EOI(vi->vi_eoi_addr, vi->vi_eoi_data); + + return IRQ_HANDLED; } diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index ace3cbd21dbb..69a53774882d 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -3,7 +3,7 @@ * * (c) Copyright 2000 Red Hat Software * (c) Copyright 2000 Helge Deller <hdeller@redhat.com> - * (c) Copyright 2001-2002 Helge Deller <deller@gmx.de> + * (c) Copyright 2001-2003 Helge Deller <deller@gmx.de> * (c) Copyright 2001 Randolph Chung <tausq@debian.org> * * This program is free software; you can redistribute it and/or modify @@ -13,7 +13,7 @@ * * TODO: * - speed-up calculations with inlined assembler - * - interface to write to second row of LCD from /proc + * - interface to write to second row of LCD from /proc (if technically possible) */ #include <linux/config.h> @@ -22,10 +22,11 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/ioport.h> -#include <linux/bitops.h> #include <linux/version.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/inetdevice.h> +#include <linux/in.h> #include <linux/interrupt.h> #include <linux/kernel_stat.h> #include <linux/reboot.h> @@ -59,10 +60,6 @@ static char lcd_text[32]; #endif -#define CALC_ADD(val, comp, add) \ - (val<=(comp/8) ? add/16 : val<=(comp/4) ? add/8 : val<=(comp/2) ? add/4 : add) - - struct lcd_block { unsigned char command; /* stores the command byte */ unsigned char on; /* value for turning LED on */ @@ -341,93 +338,81 @@ static void led_LCD_driver(unsigned char leds) /* ** - ** led_get_net_stats() + ** led_get_net_activity() ** - ** calculate the TX- & RX-troughput on the network interfaces in - ** the system for usage in the LED code - ** + ** calculate if there was TX- or RX-troughput on the network interfaces ** (analog to dev_get_info() from net/core/dev.c) ** */ -static unsigned long led_net_rx_counter, led_net_tx_counter; - -static void led_get_net_stats(int addvalue) +static __inline__ int led_get_net_activity(void) { -#ifdef CONFIG_NET +#ifndef CONFIG_NET + return 0; +#else static unsigned long rx_total_last, tx_total_last; unsigned long rx_total, tx_total; struct net_device *dev; - struct net_device_stats *stats; + int retval; rx_total = tx_total = 0; - /* we are running as a tasklet, so locking dev_base + /* we are running as tasklet, so locking dev_base * for reading should be OK */ read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { - if (dev->get_stats) { - stats = dev->get_stats(dev); - rx_total += stats->rx_packets; - tx_total += stats->tx_packets; - } + for (dev = dev_base; dev; dev = dev->next) { + struct net_device_stats *stats; + struct in_device *in_dev = __in_dev_get(dev); + if (!in_dev || !in_dev->ifa_list) + continue; + if (LOOPBACK(in_dev->ifa_list->ifa_local)) + continue; + if (!dev->get_stats) + continue; + stats = dev->get_stats(dev); + rx_total += stats->rx_packets; + tx_total += stats->tx_packets; } read_unlock(&dev_base_lock); - rx_total -= rx_total_last; - tx_total -= tx_total_last; - - if (rx_total) - led_net_rx_counter += CALC_ADD(rx_total, tx_total, addvalue); - - if (tx_total) - led_net_tx_counter += CALC_ADD(tx_total, rx_total, addvalue); - - rx_total_last += rx_total; - tx_total_last += tx_total; + retval = 0; + + if (rx_total != rx_total_last) { + rx_total_last = rx_total; + retval |= LED_LAN_RCV; + } + + if (tx_total != tx_total_last) { + tx_total_last = tx_total; + retval |= LED_LAN_TX; + } + + return retval; #endif } /* ** - ** led_get_diskio_stats() + ** led_get_diskio_activity() ** - ** calculate the disk-io througput in the system - ** (analog to linux/fs/proc/proc_misc.c) + ** calculate if there was disk-io in the system ** */ -static unsigned long led_diskio_counter; - -static void led_get_diskio_stats(int addvalue) +static __inline__ int led_get_diskio_activity(void) { - static unsigned int diskio_total_last, diskio_max; - int major, disk, total; + static unsigned long last_pgpgin, last_pgpgout; + struct page_state pgstat; + int changed; - total = 0; -#if 0 - /* - * this section will no longer work in 2.5, as we no longer - * have either kstat.dk_drive nor DK_MAX_*. It can probably - * be rewritten to use the per-disk statistics now kept in the - * gendisk, but since I have no HP machines to test it on, I'm - * not really up to that. ricklind@us.ibm.com 11/7/02 - */ - for (major = 0; major < DK_MAX_MAJOR; major++) { - for (disk = 0; disk < DK_MAX_DISK; disk++) - total += dkstat.drive[major][disk]; - } - total -= diskio_total_last; - - if (total) { - if (total >= diskio_max) { - led_diskio_counter += addvalue; - diskio_max = total; /* new maximum value found */ - } else - led_diskio_counter += CALC_ADD(total, diskio_max, addvalue); - } -#endif + get_full_page_state(&pgstat); /* get no of sectors in & out */ + + /* Just use a very simple calculation here. Do not care about overflow, + since we only want to know if there was activity or not. */ + changed = (pgstat.pgpgin != last_pgpgin) || (pgstat.pgpgout != last_pgpgout); + last_pgpgin = pgstat.pgpgin; + last_pgpgout = pgstat.pgpgout; - diskio_total_last += total; + return (changed ? LED_DISK_IO : 0); } @@ -443,16 +428,23 @@ static void led_get_diskio_stats(int addvalue) - optimizations */ -static unsigned char currentleds; /* stores current value of the LEDs */ - #define HEARTBEAT_LEN (HZ*6/100) #define HEARTBEAT_2ND_RANGE_START (HZ*22/100) #define HEARTBEAT_2ND_RANGE_END (HEARTBEAT_2ND_RANGE_START + HEARTBEAT_LEN) +#if HZ==100 + #define NORMALIZED_COUNT(count) (count) +#else + #warning "Untested situation HZ != 100 !!" + #define NORMALIZED_COUNT(count) (count/(HZ/100)) +#endif + static void led_tasklet_func(unsigned long unused) { - static unsigned int count, count_HZ; static unsigned char lastleds; + unsigned char currentleds; /* stores current value of the LEDs */ + static unsigned long count; /* static incremented value, not wrapped */ + static unsigned long count_HZ; /* counter in range 0..HZ */ /* exit if not initialized */ if (!led_func_ptr) @@ -463,6 +455,8 @@ static void led_tasklet_func(unsigned long unused) if (++count_HZ == HZ) count_HZ = 0; + currentleds = lastleds; + if (led_heartbeat) { /* flash heartbeat-LED like a real heart (2 x short then a long delay) */ @@ -473,42 +467,25 @@ static void led_tasklet_func(unsigned long unused) currentleds &= ~LED_HEARTBEAT; } - /* gather network and diskio statistics and flash LEDs respectively */ - - if (led_lanrxtx) + /* look for network activity and flash LEDs respectively */ + if (led_lanrxtx && ((NORMALIZED_COUNT(count)+(8/2)) & 7) == 0) { - if ((count & 31) == 0) - led_get_net_stats(30); - - if (led_net_rx_counter) { - led_net_rx_counter--; - currentleds |= LED_LAN_RCV; - } - else - currentleds &= ~LED_LAN_RCV; - - if (led_net_tx_counter) { - led_net_tx_counter--; - currentleds |= LED_LAN_TX; - } - else - currentleds &= ~LED_LAN_TX; + currentleds &= ~(LED_LAN_RCV | LED_LAN_TX); + currentleds |= led_get_net_activity(); } - if (led_diskio) + /* avoid to calculate diskio-stats at same irq as netio-stats */ + if (led_diskio && (NORMALIZED_COUNT(count) & 7) == 0) { - /* avoid to calculate diskio-stats at same irq as netio-stats ! */ - if ((count & 31) == 15) - led_get_diskio_stats(30); - - if (led_diskio_counter) { - led_diskio_counter--; - currentleds |= LED_DISK_IO; - } - else - currentleds &= ~LED_DISK_IO; + currentleds &= ~LED_DISK_IO; + currentleds |= led_get_diskio_activity(); } + /* blink all LEDs twice a second if we got an Oops (HPMC) */ + if (oops_in_progress) { + currentleds = (count_HZ<=(HZ/2)) ? 0 : 0xff; + } + /* update the LCD/LEDs */ if (currentleds != lastleds) { led_func_ptr(currentleds); diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index 9c88a673fd9d..d8c98ea0c581 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c @@ -90,7 +90,7 @@ superio_inform_irq(int irq) sio_dev.iosapic_irq = irq; } -static void +static irqreturn_t superio_interrupt(int irq, void *devp, struct pt_regs *regs) { struct superio_device *sio = (struct superio_device *)devp; @@ -107,7 +107,7 @@ superio_interrupt(int irq, void *devp, struct pt_regs *regs) /* HACK: need to investigate why this happens if SMP enabled */ BUG(); /* This shouldn't happen */ #endif - return; + return IRQ_HANDLED; } /* Check to see which device is interrupting */ @@ -117,7 +117,7 @@ superio_interrupt(int irq, void *devp, struct pt_regs *regs) if (local_irq == 2 || local_irq > 7) { printk(KERN_ERR "SuperIO: slave interrupted!\n"); BUG(); - return; + return IRQ_HANDLED; } if (local_irq == 7) { @@ -128,7 +128,7 @@ superio_interrupt(int irq, void *devp, struct pt_regs *regs) results = inb(IC_PIC1+0); if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */ printk(KERN_WARNING "SuperIO: spurious interrupt!\n"); - return; + return IRQ_HANDLED; } } @@ -141,7 +141,7 @@ superio_interrupt(int irq, void *devp, struct pt_regs *regs) /* set EOI */ outb((OCW2_SEOI|local_irq),IC_PIC1 + 0); - return; + return IRQ_HANDLED; } /* Initialize Super I/O device */ diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c index 6ca71e47060d..3783b0d2f8de 100644 --- a/drivers/parport/parport_gsc.c +++ b/drivers/parport/parport_gsc.c @@ -81,9 +81,10 @@ static int clear_epp_timeout(struct parport *pb) * of these are in parport_gsc.h. */ -static void parport_gsc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t parport_gsc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { parport_generic_irq(irq, (struct parport *) dev_id, regs); + return IRQ_HANDLED; } void parport_gsc_write_data(struct parport *p, unsigned char d) diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 2eb655210f26..f65b33c9f5c6 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -1076,3 +1076,9 @@ struct sti_struct * sti_get_rom(unsigned int index) return sti_roms[index-1]; } +EXPORT_SYMBOL(sti_get_rom); + +MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer"); +MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines"); +MODULE_LICENSE("GPL v2"); + diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index 7078fbc1e501..0e2bf70dafd8 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -66,6 +66,7 @@ #include <linux/pci.h> #include <asm/grfioctl.h> /* for HP-UX compatibility */ +#include <asm/uaccess.h> #include "sticore.h" @@ -111,6 +112,7 @@ struct stifb_info { int deviceSpecificConfig; }; +static int __initdata bpp = 8; /* parameter from modprobe */ static int __initdata stifb_force_bpp[MAX_STI_ROMS]; /* ------------------- chipset specific functions -------------------------- */ @@ -1336,6 +1338,8 @@ stifb_init(void) sti = sti_get_rom(i); if (!sti) break; + if (bpp > 0) + stifb_force_bpp[i] = bpp; stifb_init_fb(sti, stifb_force_bpp[i]); } return 0; @@ -1355,8 +1359,14 @@ stifb_cleanup(void) sti = sti_get_rom(i); if (!sti) break; - if (sti->info) + if (sti->info) { + struct fb_info *info = sti->info; unregister_framebuffer(sti->info); + release_mem_region(info->fix.mmio_start, info->fix.mmio_len); + release_mem_region(info->fix.smem_start, info->fix.smem_len); + fb_dealloc_cmap(&info->cmap); + kfree(info); + } sti->info = NULL; } } @@ -1372,9 +1382,10 @@ stifb_setup(char *options) if (strncmp(options, "bpp", 3) == 0) { options += 3; for (i = 0; i < MAX_STI_ROMS; i++) { - if (*options++ == ':') + if (*options++ == ':') { stifb_force_bpp[i] = simple_strtoul(options, &options, 10); - else + bpp = -1; + } else break; } } @@ -1390,7 +1401,7 @@ module_exit(stifb_cleanup); MODULE_AUTHOR("Helge Deller <deller@gmx.de>, Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); MODULE_DESCRIPTION("Framebuffer driver for HP's NGLE series graphics cards in HP PARISC machines"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_PARM(bpp, "i"); MODULE_PARM_DESC(mem, "Bits per pixel (default: 8)"); diff --git a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h index 3a3ac178498d..f888716df94f 100644 --- a/include/asm-parisc/compat.h +++ b/include/asm-parisc/compat.h @@ -4,6 +4,7 @@ * Architecture specific compatibility types */ #include <linux/types.h> +#include <linux/sched.h> #define COMPAT_USER_HZ 100 @@ -124,4 +125,12 @@ static inline void *compat_ptr(compat_uptr_t uptr) return (void *)(unsigned long)uptr; } +static __inline__ void *compat_alloc_user_space(long len) +{ + struct pt_regs *regs = ¤t->thread.regs; + unsigned long usp = regs->gr[30]; + + return (void *)(usp + len); +} + #endif /* _ASM_PARISC_COMPAT_H */ diff --git a/include/asm-parisc/elf.h b/include/asm-parisc/elf.h index b1d2eaa70e1b..b9f6090b78f2 100644 --- a/include/asm-parisc/elf.h +++ b/include/asm-parisc/elf.h @@ -178,10 +178,11 @@ #define PF_HP_SBP 0x08000000 /* - * The following definitions are those for 32-bit ELF binaries on a 32-bit kernel - * and for 64-bit binaries on a 64-bit kernel. To run 32-bit binaries on a 64-bit - * kernel, arch/parisc64/kernel/binfmt_elf32.c defines these macros appropriately - * and then #includes binfmt_elf.c, which then includes this file. + * The following definitions are those for 32-bit ELF binaries on a 32-bit + * kernel and for 64-bit binaries on a 64-bit kernel. To run 32-bit binaries + * on a 64-bit kernel, arch/parisc64/kernel/binfmt_elf32.c defines these + * macros appropriately and then #includes binfmt_elf.c, which then includes + * this file. */ #ifndef ELF_CLASS @@ -267,6 +268,8 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; typedef double elf_fpreg_t; typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; +struct task_struct; + extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) diff --git a/include/asm-parisc/fixmap.h b/include/asm-parisc/fixmap.h index cbf916e4569b..52fc100f6b79 100644 --- a/include/asm-parisc/fixmap.h +++ b/include/asm-parisc/fixmap.h @@ -4,9 +4,16 @@ /* * Allocate a 8 Mb temporary mapping area for copy_user_page/clear_user_page. * This area needs to be aligned on a 8 Mb boundary. + * + * FIXME: + * + * For PA-RISC, this has no meaning. It is starting to be used on x86 + * for vsyscalls. PA will probably do this using space registers. */ +/* This TMPALIAS_MAP_START reserves some of the memory where the + * FIXMAP region is on x86. It's only real use is to constrain + * VMALLOC_END (see pktable.h) */ #define TMPALIAS_MAP_START (__PAGE_OFFSET - 0x01000000) -#define FIXADDR_START ((unsigned long)TMPALIAS_MAP_START) #endif diff --git a/include/asm-parisc/module.h b/include/asm-parisc/module.h index acf6770cd5d3..22c916b738f0 100644 --- a/include/asm-parisc/module.h +++ b/include/asm-parisc/module.h @@ -24,10 +24,10 @@ struct mod_arch_specific { - unsigned long got_offset; - unsigned long fdesc_offset, fdesc_count; - unsigned long stub_offset; - unsigned long stub_count; + unsigned long got_offset, got_count, got_max; + unsigned long fdesc_offset, fdesc_count, fdesc_max; + unsigned long stub_offset, stub_count, stub_max; + unsigned long init_stub_offset, init_stub_count, init_stub_max; }; #endif /* _ASM_PARISC_MODULE_H */ diff --git a/include/asm-parisc/pdc_chassis.h b/include/asm-parisc/pdc_chassis.h index df844ae34916..7378770f02eb 100644 --- a/include/asm-parisc/pdc_chassis.h +++ b/include/asm-parisc/pdc_chassis.h @@ -35,7 +35,7 @@ */ int pdc_chassis_send_status(int message); -void __init parisc_pdc_chassis_init(void); +void parisc_pdc_chassis_init(void); /* diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index 32b19f8bafa7..0262435e1514 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h @@ -109,7 +109,8 @@ extern void *vmalloc_start; #define PCXL_DMA_MAP_SIZE (8*1024*1024) #define VMALLOC_START ((unsigned long)vmalloc_start) #define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#define VMALLOC_END (FIXADDR_START) +/* this is a fixmap remnant, see fixmap.h */ +#define VMALLOC_END (TMPALIAS_MAP_START) #endif /* NB: The tlb miss handlers make certain assumptions about the order */ @@ -122,6 +123,7 @@ extern void *vmalloc_start; #define _PAGE_GATEWAY_BIT 28 /* (0x008) privilege promotion allowed */ #define _PAGE_DMB_BIT 27 /* (0x010) Data Memory Break enable (B bit) */ #define _PAGE_DIRTY_BIT 26 /* (0x020) Page Dirty (D bit) */ +#define _PAGE_FILE_BIT _PAGE_DIRTY_BIT /* overload this bit */ #define _PAGE_REFTRAP_BIT 25 /* (0x040) Page Ref. Trap enable (T bit) */ #define _PAGE_NO_CACHE_BIT 24 /* (0x080) Uncached Page (U bit) */ #define _PAGE_ACCESSED_BIT 23 /* (0x100) Software: Page Accessed */ @@ -135,6 +137,17 @@ extern void *vmalloc_start; #define xlate_pabit(x) (31 - x) +/* this defines the shift to the usable bits in the PTE it is set so + * that the valid bits _PAGE_PRESENT_BIT and _PAGE_USER_BIT are set + * to zero */ +#define PTE_SHIFT xlate_pabit(_PAGE_USER_BIT) + +/* this is how many bits may be used by the file functions */ +#define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_SHIFT) + +#define pte_to_pgoff(pte) (pte_val(pte) >> PTE_SHIFT) +#define pgoff_to_pte(off) ((pte_t) { ((off) << PTE_SHIFT) | _PAGE_FILE }) + #define _PAGE_READ (1 << xlate_pabit(_PAGE_READ_BIT)) #define _PAGE_WRITE (1 << xlate_pabit(_PAGE_WRITE_BIT)) #define _PAGE_RW (_PAGE_READ | _PAGE_WRITE) @@ -148,6 +161,7 @@ extern void *vmalloc_start; #define _PAGE_PRESENT (1 << xlate_pabit(_PAGE_PRESENT_BIT)) #define _PAGE_FLUSH (1 << xlate_pabit(_PAGE_FLUSH_BIT)) #define _PAGE_USER (1 << xlate_pabit(_PAGE_USER_BIT)) +#define _PAGE_FILE (1 << xlate_pabit(_PAGE_FILE_BIT)) #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED) #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) @@ -256,6 +270,8 @@ extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_READ; } extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } +extern inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } +extern inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; } extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_READ; return pte; } extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h index 30bdf987b3a5..55c38a184b8c 100644 --- a/include/asm-parisc/processor.h +++ b/include/asm-parisc/processor.h @@ -92,6 +92,7 @@ struct cpuinfo_parisc { unsigned long fp_model; unsigned int state; struct parisc_device *dev; + unsigned long loops_per_jiffy; }; extern struct system_cpuinfo_parisc boot_cpu_data; diff --git a/include/asm-parisc/timex.h b/include/asm-parisc/timex.h index 3808765c841a..a228b9167321 100644 --- a/include/asm-parisc/timex.h +++ b/include/asm-parisc/timex.h @@ -7,7 +7,6 @@ #define _ASMPARISC_TIMEX_H #include <asm/system.h> -#include <linux/time.h> #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index 9aa3ef58c78b..410a871f910c 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h @@ -720,6 +720,7 @@ #define __NR_epoll_ctl (__NR_Linux + 225) #define __NR_epoll_wait (__NR_Linux + 226) #define __NR_remap_file_pages (__NR_Linux + 227) +#define __NR_semtimedop (__NR_Linux + 228) #define __NR_Linux_syscalls 228 |
