diff options
| author | Matthew Wilcox <willy@debian.org> | 2003-09-30 08:06:44 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-09-30 08:06:44 -0700 |
| commit | 56f41d502fa117964cdb327326000bbe320fa8a9 (patch) | |
| tree | ff5c285802d9c0560030907c93b6d0446fc0e9ab | |
| parent | 7e2552dc4a71f92c9b2241ecb4ba8f7e87a247d4 (diff) | |
[PATCH] PA-RISC updates
PA-RISC updates for 2.6.0-test6
- Some more support for 64-bit userspace
- Move many EXPORT_SYMBOLs out of parisc_ksyms.c
- Make both the OSS and ALSA harmony drivers build
- ioctl typechecking
- Make math-emu build without warnings.
- Persuade SuckyIO to not crash the machine.
49 files changed, 741 insertions, 550 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 671488825699..05fd6ceaeb8a 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -150,6 +150,7 @@ config COMPAT config HPUX bool "Support for HP-UX binaries" + depends on !PARISC64 config NR_CPUS int "Maximum number of CPUs (2-32)" @@ -190,6 +191,8 @@ source drivers/message/fusion/Kconfig #source drivers/message/i2o/Kconfig +source "net/Kconfig" + #source "drivers/isdn/Kconfig" #source "drivers/telephony/Kconfig" diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c index a8a2fe311d45..6b9af532fd9e 100644 --- a/arch/parisc/kernel/asm-offsets.c +++ b/arch/parisc/kernel/asm-offsets.c @@ -8,6 +8,7 @@ #include <linux/sched.h> #include <linux/thread_info.h> #include <linux/version.h> +#include <linux/ptrace.h> #include <asm/ptrace.h> #include <asm/processor.h> @@ -249,5 +250,8 @@ int main(void) DEFINE(DTLB_OFF_COUNT, offsetof(struct pdc_cache_info, dt_off_count)); DEFINE(DTLB_LOOP, offsetof(struct pdc_cache_info, dt_loop)); BLANK(); + DEFINE(PA_BLOCKSTEP_BIT, 31-PT_BLOCKSTEP_BIT); + DEFINE(PA_SINGLESTEP_BIT, 31-PT_SINGLESTEP_BIT); + BLANK(); return 0; } diff --git a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c index 6a994d1c35e5..4486a745b0ef 100644 --- a/arch/parisc/kernel/binfmt_elf32.c +++ b/arch/parisc/kernel/binfmt_elf32.c @@ -88,7 +88,9 @@ struct elf_prpsinfo32 */ #define SET_PERSONALITY(ex, ibcs2) \ - current->personality = PER_LINUX_32BIT + current->personality = PER_LINUX32; \ + current->thread.map_base = DEFAULT_MAP_BASE32; \ + current->thread.task_size = DEFAULT_TASK_SIZE32 \ #define jiffies_to_timeval jiffies_to_compat_timeval static __inline__ void @@ -99,3 +101,25 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) } #include "../../../fs/binfmt_elf.c" + +/* Set up a separate execution domain for ELF32 binaries running + * on an ELF64 kernel */ + +static struct exec_domain parisc32_exec_domain = { + .name = "Linux/ELF32", + .pers_low = PER_LINUX32, + .pers_high = PER_LINUX32, +}; + +static int __init parisc32_exec_init(void) +{ + /* steal the identity signal mappings from the default domain */ + parisc32_exec_domain.signal_map = default_exec_domain.signal_map; + parisc32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; + + register_exec_domain(&parisc32_exec_domain); + + return 0; +} + +__initcall(parisc32_exec_init); diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index c5d8401dded7..1f3257973120 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -28,6 +28,7 @@ /* See comments in include/asm-parisc/pci.h */ struct hppa_dma_ops *hppa_dma_ops; +EXPORT_SYMBOL(hppa_dma_ops); static struct parisc_device root; @@ -155,6 +156,7 @@ int register_parisc_driver(struct parisc_driver *driver) return driver_register(&driver->drv); } +EXPORT_SYMBOL(register_parisc_driver); /** * count_parisc_driver - count # of devices this driver would match @@ -187,6 +189,7 @@ int unregister_parisc_driver(struct parisc_driver *driver) driver_unregister(&driver->drv); return 0; } +EXPORT_SYMBOL(unregister_parisc_driver); static struct parisc_device *find_device_by_addr(unsigned long hpa) { @@ -257,7 +260,7 @@ char *print_pa_hwpath(struct parisc_device *dev, char *output) path.mod = dev->hw_path; return print_hwpath(&path, output); } - +EXPORT_SYMBOL(print_pa_hwpath); #if defined(CONFIG_PCI) || defined(CONFIG_ISA) /** @@ -289,6 +292,7 @@ void get_pci_node_path(struct pci_dev *dev, struct hardware_path *path) padev = padev->parent; } } +EXPORT_SYMBOL(get_pci_node_path); /** * print_pci_hwpath - Returns hardware path for PCI devices @@ -306,6 +310,8 @@ char *print_pci_hwpath(struct pci_dev *dev, char *output) get_pci_node_path(dev, &path); return print_hwpath(&path, output); } +EXPORT_SYMBOL(print_pci_hwpath); + #endif /* defined(CONFIG_PCI) || defined(CONFIG_ISA) */ diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 78f20ebdbab8..c8f49a03fd88 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -2225,18 +2225,23 @@ syscall_exit: LDREG TI_TASK(%r1),%r1 STREG %r28,TASK_PT_GR28(%r1) - /* Save other hpux returns if personality is PER_HPUX */ +#ifdef CONFIG_HPUX /* <linux/personality.h> cannot be easily included */ #define PER_HPUX 0x10 LDREG TASK_PERSONALITY(%r1),%r19 -#warning the ldo+CMPIB could probably be done better but 0x10 i soutside of range of CMPIB + + /* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */ ldo -PER_HPUX(%r19), %r19 CMPIB<>,n 0,%r19,1f + + /* Save other hpux returns if personality is PER_HPUX */ STREG %r22,TASK_PT_GR22(%r1) STREG %r29,TASK_PT_GR29(%r1) 1: +#endif /* CONFIG_HPUX */ + /* Seems to me that dp could be wrong here, if the syscall involved * calling a module, and nothing got round to restoring dp on return. */ @@ -2315,18 +2320,16 @@ syscall_restore: depi 3,31,2,%r31 /* ensure return to user mode. */ #ifdef __LP64__ - /* Since we are returning to a 32 bit user process, we always - * clear the W bit. This means that the be (and mtsp) gets - * executed in narrow mode, but that is OK, since we are - * returning to a 32 bit process. When we support 64 bit processes - * we won't clear the W bit, so the be will run in wide mode. - */ - - be 0(%sr3,%r31) /* return to user space */ + /* decide whether to reset the wide mode bit + * + * For a syscall, the W bit is stored in the lowest bit + * of sp. Extract it and reset W if it is zero */ + extrd,u,*<> %r30,63,1,%r1 rsm PSW_SM_W, %r0 -#else - be,n 0(%sr3,%r31) /* return to user space */ + /* now reset the lowest bit of sp if it was set */ + xor %r30,%r1,%r30 #endif + be,n 0(%sr3,%r31) /* return to user space */ /* We have to return via an RFI, so that PSW T and R bits can be set * appropriately. @@ -2340,12 +2343,19 @@ syscall_restore_rfi: LDREG TASK_PT_PSW(%r1),%r2 /* Get old PSW */ ldi 0x0b,%r20 /* Create new PSW */ depi -1,13,1,%r20 /* C, Q, D, and I bits */ - bb,>=,n %r19,15,try_tbit /* PT_SINGLESTEP */ + + /* The values of PA_SINGLESTEP_BIT and PA_BLOCKSTEP_BIT are + * set in include/linux/ptrace.h and converted to PA bitmap + * numbers in asm-offsets.c */ + + /* if ((%r19.PA_SINGLESTEP_BIT)) { %r20.27=1} */ + extru,= %r19,PA_SINGLESTEP_BIT,1,%r0 depi -1,27,1,%r20 /* R bit */ -try_tbit: - bb,>=,n %r19,14,psw_setup /* PT_BLOCKSTEP, see ptrace.c */ + + /* if ((%r19.PA_BLOCKSTEP_BIT)) { %r20.7=1} */ + extru,= %r19,PA_BLOCKSTEP_BIT,1,%r0 depi -1,7,1,%r20 /* T bit */ -psw_setup: + STREG %r20,TASK_PT_PSW(%r1) /* Always store space registers, since sr3 can be changed (e.g. fork) */ diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index ed978ea3a688..4ada50a48a2d 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -41,19 +41,20 @@ * prumpf 991016 */ +#include <stdarg.h> + +#include <linux/delay.h> +#include <linux/init.h> #include <linux/kernel.h> +#include <linux/module.h> #include <linux/string.h> #include <linux/spinlock.h> -#include <linux/init.h> -#include <linux/delay.h> #include <asm/page.h> #include <asm/pdc.h> #include <asm/system.h> #include <asm/processor.h> /* for boot_cpu_data */ -#include <stdarg.h> - static spinlock_t pdc_lock = SPIN_LOCK_UNLOCKED; static unsigned long pdc_result[32] __attribute__ ((aligned (8))); static unsigned long pdc_result2[32] __attribute__ ((aligned (8))); @@ -151,6 +152,7 @@ int pdc_add_valid(unsigned long address) return retval; } +EXPORT_SYMBOL(pdc_add_valid); /** * pdc_chassis_info - Return chassis information. @@ -264,6 +266,7 @@ int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, return retval; } +EXPORT_SYMBOL(pdc_iodc_read); /** * pdc_system_map_find_mods - Locate unarchitected modules. @@ -518,6 +521,7 @@ int pdc_lan_station_id(char *lan_addr, unsigned long hpa) return retval; } +EXPORT_SYMBOL(pdc_lan_station_id); /** @@ -594,6 +598,7 @@ int pdc_get_initiator( struct hardware_path *hwpath, unsigned char *scsi_id, spin_unlock_irq(&pdc_lock); return retval >= PDC_OK; } +EXPORT_SYMBOL(pdc_get_initiator); /** @@ -660,6 +665,7 @@ int pdc_tod_read(struct pdc_tod *tod) return retval; } +EXPORT_SYMBOL(pdc_tod_read); /** * pdc_tod_set - Set the Time-Of-Day clock. @@ -678,6 +684,7 @@ int pdc_tod_set(unsigned long sec, unsigned long usec) return retval; } +EXPORT_SYMBOL(pdc_tod_set); #ifdef __LP64__ int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr, @@ -772,20 +779,34 @@ int pdc_soft_power_button(int sw_control) } /* - * pdc_suspend_usb - Stop USB controller + * pdc_io_reset - Hack to avoid overlapping range registers of Bridges devices. + * Primarily a problem on T600 (which parisc-linux doesn't support) but + * who knows what other platform firmware might do with this OS "hook". + */ +void pdc_io_reset(void) +{ + spin_lock_irq(&pdc_lock); + mem_pdc_call(PDC_IO, PDC_IO_RESET, 0); + spin_unlock_irq(&pdc_lock); +} + +/* + * pdc_io_reset_devices - Hack to Stop USB controller * * If PDC used the usb controller, the usb controller * is still running and will crash the machines during iommu * setup, because of still running DMA. This PDC call - * stops the USB controller + * stops the USB controller. + * Normally called after calling pdc_io_reset(). */ -void pdc_suspend_usb(void) +void pdc_io_reset_devices(void) { spin_lock_irq(&pdc_lock); - mem_pdc_call(PDC_IO, PDC_IO_SUSPEND_USB, 0); + mem_pdc_call(PDC_IO, PDC_IO_RESET_DEVICES, 0); spin_unlock_irq(&pdc_lock); } + /** * pdc_iodc_putc - Console character print using IODC. * @c: the character to output. @@ -905,6 +926,7 @@ int pdc_sti_call(unsigned long func, unsigned long flags, return retval; } +EXPORT_SYMBOL(pdc_sti_call); #ifdef __LP64__ /** diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c index 02b5049be9f4..dae3b0e924fa 100644 --- a/arch/parisc/kernel/inventory.c +++ b/arch/parisc/kernel/inventory.c @@ -526,12 +526,14 @@ static void __init system_map_inventory(void) int i; long status = PDC_OK; +#if defined(CONFIG_IOMMU_SBA) && defined(CONFIG_SUPERIO) /* - * first stop the usb controller, otherwise the machine - * might crash during iommu setup + * Stop the suckyio usb controller on Astro based systems. + * Otherwise the machine might crash during iommu setup. */ -#warning We still probably need to worry about USB here, but how? - /* pdc_suspend_usb(); */ + pdc_io_reset(); + pdc_io_reset_devices(); +#endif for (i = 0; status != PDC_BAD_PROC && status != PDC_NE_MOD; i++) { struct parisc_device *dev; diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index eafb849da3a0..4b5ce6a17bfa 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -193,6 +193,7 @@ void disable_irq(int irq) else BUG(); } +EXPORT_SYMBOL(disable_irq); void enable_irq(int irq) { @@ -208,6 +209,7 @@ void enable_irq(int irq) else BUG(); } +EXPORT_SYMBOL(enable_irq); int show_interrupts(struct seq_file *p, void *v) { @@ -698,6 +700,7 @@ void synchronize_irq(unsigned int irqnum) { while (in_irq()) ; } +EXPORT_SYMBOL(synchronize_irq); #endif @@ -847,6 +850,7 @@ unsigned int probe_irq_mask(unsigned long irqs) { return 0; } +EXPORT_SYMBOL(probe_irq_mask); void __init init_IRQ(void) { diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index f7d5964b4e97..2324954c9cf7 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -73,10 +73,7 @@ struct got_entry { Elf32_Addr addr; }; -struct fdesc_entry { - Elf32_Addr addr; - Elf32_Addr gp; -}; +#define Elf_Fdesc Elf32_Fdesc struct stub_entry { Elf32_Word insns[2]; /* each stub entry has two insns */ @@ -86,11 +83,7 @@ struct got_entry { Elf64_Addr addr; }; -struct fdesc_entry { - Elf64_Addr dummy[2]; - Elf64_Addr addr; - Elf64_Addr gp; -}; +#define Elf_Fdesc Elf64_Fdesc struct stub_entry { Elf64_Word insns[4]; /* each stub entry has four insns */ @@ -276,7 +269,7 @@ 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 += fdescs * sizeof(struct fdesc_entry); + me->core_size += fdescs * sizeof(Elf_Fdesc); me->core_size = ALIGN(me->core_size, 16); me->arch.stub_offset = me->core_size; @@ -322,7 +315,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend) #ifdef __LP64__ static Elf_Addr get_fdesc(struct module *me, unsigned long value) { - struct fdesc_entry *fdesc = me->module_core + me->arch.fdesc_offset; + Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset; if (!value) { printk(KERN_ERR "%s: zero OPD requested!\n", me->name); @@ -664,7 +657,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, *loc64 = get_fdesc(me, val+addend); DEBUGP("FDESC for %s at %p points to %lx\n", strtab + sym->st_name, *loc64, - ((struct fdesc_entry *)*loc64)->addr); + ((Elf_Fdesc *)*loc64)->addr); } else { /* if the symbol is not local to this * module then val+addend is a pointer @@ -696,10 +689,10 @@ int module_finalize(const Elf_Ehdr *hdr, Elf_Sym *newptr, *oldptr; Elf_Shdr *symhdr = NULL; #ifdef DEBUG - struct fdesc_entry *entry; + Elf_Fdesc *entry; u32 *addr; - entry = (struct fdesc_entry *)me->init; + entry = (Elf_Fdesc *)me->init; printk("FINALIZE, ->init FPTR is %p, GP %lx ADDR %lx\n", entry, entry->gp, entry->addr); addr = (u32 *)entry->addr; diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index f6d87e4d7575..4cd0cb06618e 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -26,19 +26,6 @@ EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(strpbrk); -#include <asm/hardware.h> /* struct parisc_device for asm/pci.h */ -#include <linux/pci.h> -EXPORT_SYMBOL(hppa_dma_ops); -#if defined(CONFIG_PCI) || defined(CONFIG_ISA) -EXPORT_SYMBOL(get_pci_node_path); -#endif - -#include <linux/sched.h> -#include <asm/irq.h> -EXPORT_SYMBOL(enable_irq); -EXPORT_SYMBOL(disable_irq); -EXPORT_SYMBOL(probe_irq_mask); - #include <asm/processor.h> EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(boot_cpu_data); @@ -46,10 +33,6 @@ EXPORT_SYMBOL(boot_cpu_data); #include <linux/pm.h> EXPORT_SYMBOL(pm_power_off); -#ifdef CONFIG_SMP -EXPORT_SYMBOL(synchronize_irq); -#endif /* CONFIG_SMP */ - #include <asm/atomic.h> EXPORT_SYMBOL(__xchg8); EXPORT_SYMBOL(__xchg32); @@ -74,14 +57,6 @@ extern int $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); EXPORT_SYMBOL(iounmap); @@ -89,22 +64,6 @@ EXPORT_SYMBOL(__memcpy_toio); EXPORT_SYMBOL(__memcpy_fromio); EXPORT_SYMBOL(__memset_io); -#if defined(CONFIG_PCI) || defined(CONFIG_ISA) -EXPORT_SYMBOL(inb); -EXPORT_SYMBOL(inw); -EXPORT_SYMBOL(inl); -EXPORT_SYMBOL(outb); -EXPORT_SYMBOL(outw); -EXPORT_SYMBOL(outl); - -EXPORT_SYMBOL(insb); -EXPORT_SYMBOL(insw); -EXPORT_SYMBOL(insl); -EXPORT_SYMBOL(outsb); -EXPORT_SYMBOL(outsw); -EXPORT_SYMBOL(outsl); -#endif - #include <asm/cache.h> EXPORT_SYMBOL(flush_kernel_dcache_range_asm); EXPORT_SYMBOL(flush_kernel_dcache_page); @@ -130,17 +89,6 @@ EXPORT_SYMBOL(__up); EXPORT_SYMBOL(__down_interruptible); EXPORT_SYMBOL(__down); -#include <linux/in6.h> -#include <asm/checksum.h> -EXPORT_SYMBOL(csum_partial_copy_nocheck); -EXPORT_SYMBOL(csum_partial_copy_from_user); - -#include <asm/pdc.h> -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); extern void $$remI(void); @@ -218,6 +166,3 @@ EXPORT_SYMBOL(__moddi3); extern void $$dyncall(void); EXPORT_SYMBOL($$dyncall); #endif - -#include <asm/pgtable.h> -EXPORT_SYMBOL(vmalloc_start); diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 189a6ae02bb9..c17ffa3e9be6 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -88,7 +88,8 @@ u##size in##type (int addr) \ EISA_IN(size); \ if (!parisc_pci_hba[b]) return (u##size) -1; \ return pci_port->in##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr)); \ -} +} \ +EXPORT_SYMBOL(in##type); PCI_PORT_IN(b, 8) PCI_PORT_IN(w, 16) @@ -102,7 +103,8 @@ void out##type (u##size d, int addr) \ EISA_OUT(size); \ if (!parisc_pci_hba[b]) return; \ pci_port->out##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr), d); \ -} +} \ +EXPORT_SYMBOL(out##type); PCI_PORT_OUT(b, 8) PCI_PORT_OUT(w, 16) diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 213c9a349673..2f484a0e2de0 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -23,16 +23,6 @@ #include <asm/processor.h> #include <asm/offsets.h> -/* These are used in entry.S, syscall_restore_rfi. We need to record the - * current stepping mode somewhere other than in PSW, because there is no - * concept of saving and restoring the users PSW over a syscall. We choose - * to use these two bits in task->ptrace. These bits must not clash with - * any PT_* defined in include/linux/sched.h, and must match with the bit - * tests in entry.S - */ -#define PT_SINGLESTEP 0x10000 -#define PT_BLOCKSTEP 0x20000 - /* PSW bits we allow the debugger to modify */ #define USER_PSW_BITS (PSW_N | PSW_V | PSW_CB) diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 42f74c99072b..1780944eb35e 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -43,6 +43,7 @@ #include <asm/led.h> #include <asm/machdep.h> /* for pa7300lc_init() proto */ #include <asm/pdc_chassis.h> +#include <asm/io.h> #define COMMAND_LINE_SIZE 1024 char saved_command_line[COMMAND_LINE_SIZE]; @@ -208,27 +209,32 @@ static void __init parisc_proc_mkdir(void) proc_runway_root = proc_mkdir("bus/runway", 0); } break; + default: + /* FIXME: this was added to prevent the compiler + * complaining about missing pcx, pcxs and pcxt + * I'm assuming they have neither gsc nor runway */ + break; } } static struct resource central_bus = { .name = "Central Bus", - .start = (unsigned long)0xfffffffffff80000, - .end = (unsigned long)0xfffffffffffaffff, + .start = F_EXTEND(0xfff80000), + .end = F_EXTEND(0xfffaffff), .flags = IORESOURCE_MEM, }; static struct resource local_broadcast = { .name = "Local Broadcast", - .start = (unsigned long)0xfffffffffffb0000, - .end = (unsigned long)0xfffffffffffdffff, + .start = F_EXTEND(0xfffb0000), + .end = F_EXTEND(0xfffdffff), .flags = IORESOURCE_MEM, }; static struct resource global_broadcast = { .name = "Global Broadcast", - .start = (unsigned long)0xfffffffffffe0000, - .end = (unsigned long)0xffffffffffffffff, + .start = F_EXTEND(0xfffe0000), + .end = F_EXTEND(0xffffffff), .flags = IORESOURCE_MEM, }; diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 45eb0dd888d6..3b2dbf860611 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -25,6 +25,8 @@ #include <linux/unistd.h> #include <linux/stddef.h> #include <linux/compat.h> +#include <linux/elf.h> +#include <linux/personality.h> #include <asm/ucontext.h> #include <asm/rt_sigframe.h> #include <asm/uaccess.h> @@ -41,8 +43,11 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -/* Use this to get at 32-bit user passed pointers. - * See sys_sparc32.c for description about these. */ +/* gcc will complain if a pointer is cast to an integer of different + * size. If you really need to do this (and we do for an ELF32 user + * application in an ELF64 kernel) then you have to do a cast to an + * integer of the same size first. The A() macro accomplishes + * this. */ #define A(__x) ((unsigned long)(__x)) int do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall); @@ -166,11 +171,17 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) struct rt_sigframe *frame; struct siginfo si; sigset_t set; - unsigned long usp = regs->gr[30]; + unsigned long usp = (regs->gr[30] & ~(0x01UL)); + unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE; +#ifdef __LP64__ + if(personality(current->personality) == PER_LINUX32) + sigframe_size = PARISC_RT_SIGFRAME_SIZE32; +#endif + /* Unwind the user stack to get the rt_sigframe structure. */ frame = (struct rt_sigframe *) - (usp - PARISC_RT_SIGFRAME_SIZE); + (usp - sigframe_size); DBG(("in sys_rt_sigreturn, frame is %p\n", frame)); if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) @@ -271,11 +282,12 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs, int in_syscall) { struct rt_sigframe *frame; - unsigned long rp, usp, haddr; + unsigned long rp, usp; + unsigned long haddr, sigframe_size; struct siginfo si; int err = 0; - usp = regs->gr[30]; + usp = (regs->gr[30] & ~(0x01UL)); frame = get_sigframe(ka, usp, sizeof(*frame)); DBG(("setup_rt_frame 1: frame %p info %p\n", frame, info)); @@ -308,64 +320,86 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, } #endif -#undef CACHE_FLUSHING_IS_NOT_BROKEN -#ifdef CACHE_FLUSHING_IS_NOT_BROKEN + flush_user_dcache_range((unsigned long) &frame->tramp[0], + (unsigned long) &frame->tramp[4]); flush_user_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[4]); -#else - /* It should *always* be cache line-aligned, but the compiler - sometimes screws up. */ - asm volatile("fdc 0(%%sr3,%0)\n\t" - "fdc %1(%%sr3,%0)\n\t" - "sync\n\t" - "fic 0(%%sr3,%0)\n\t" - "fic %1(%%sr3,%0)\n\t" - "sync\n\t" - : : "r" (frame->tramp), "r" (L1_CACHE_BYTES)); -#endif rp = (unsigned long) frame->tramp; if (err) goto give_sigsegv; -/* Much more has to happen with signals than this -- but it'll at least */ -/* provide a pointer to some places which definitely need a look. */ -#define HACK u32 + haddr = A(ka->sa.sa_handler); + /* The sa_handler may be a pointer to a function descriptor */ +#ifdef __LP64__ + if(personality(current->personality) == PER_LINUX32) { +#endif + if (haddr & PA_PLABEL_FDESC) { + Elf32_Fdesc fdesc; + Elf32_Fdesc *ufdesc = (Elf32_Fdesc *)A(haddr & ~3); + + err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc)); - haddr = (HACK)A(ka->sa.sa_handler); - /* ARGH! Fucking brain damage. You don't want to know. */ - if (haddr & 2) { - HACK *plabel; - HACK ltp; + if (err) + goto give_sigsegv; - plabel = (HACK *) (haddr & ~3); - err |= __get_user(haddr, plabel); - err |= __get_user(ltp, plabel + 1); + haddr = fdesc.addr; + regs->gr[19] = fdesc.gp; + } +#ifdef __LP64__ + } else { + Elf64_Fdesc fdesc; + Elf64_Fdesc *ufdesc = (Elf64_Fdesc *)A(haddr & ~3); + + err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc)); + if (err) goto give_sigsegv; - regs->gr[19] = ltp; + + haddr = fdesc.addr; + regs->gr[19] = fdesc.gp; + DBG(("64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n", + haddr, regs->gr[19], in_syscall)); } +#endif /* The syscall return path will create IAOQ values from r31. */ - if (in_syscall) - regs->gr[31] = (HACK) haddr; - else { - regs->gr[0] = USER_PSW; - regs->iaoq[0] = (HACK) haddr | 3; + sigframe_size = PARISC_RT_SIGFRAME_SIZE; +#ifdef __LP64__ + if(personality(current->personality) == PER_LINUX32) + sigframe_size = PARISC_RT_SIGFRAME_SIZE32; +#endif + if (in_syscall) { + regs->gr[31] = haddr; +#ifdef __LP64__ + if(personality(current->personality) == PER_LINUX) + sigframe_size |= 1; +#endif + } else { + unsigned long psw = USER_PSW; +#ifdef __LP64__ + if(personality(current->personality) == PER_LINUX) + psw |= PSW_W; +#endif + + regs->gr[0] = psw; + regs->iaoq[0] = haddr | 3; regs->iaoq[1] = regs->iaoq[0] + 4; } regs->gr[2] = rp; /* userland return pointer */ regs->gr[26] = sig; /* signal number */ - regs->gr[25] = (HACK)A(&frame->info); /* siginfo pointer */ - regs->gr[24] = (HACK)A(&frame->uc); /* ucontext pointer */ + regs->gr[25] = A(&frame->info); /* siginfo pointer */ + regs->gr[24] = A(&frame->uc); /* ucontext pointer */ + DBG(("making sigreturn frame: %#lx + %#x = %#lx\n", - regs->gr[30], PARISC_RT_SIGFRAME_SIZE, - regs->gr[30] + PARISC_RT_SIGFRAME_SIZE)); + regs->gr[30], sigframe_size, + regs->gr[30] + sigframe_size)); /* Raise the user stack pointer to make a proper call frame. */ - regs->gr[30] = ((HACK)A(frame) + PARISC_RT_SIGFRAME_SIZE); + regs->gr[30] = (A(frame) + sigframe_size); + DBG(("SIG deliver (%s:%d): frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n", current->comm, current->pid, frame, regs->gr[30], diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index b1743e58386d..41750219349d 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -65,7 +65,7 @@ static int get_offset(struct address_space *mapping) */ static int get_offset(struct address_space *mapping) { - int offset = (int) mapping << (PAGE_SHIFT - 8); + int offset = (unsigned long) mapping << (PAGE_SHIFT - 8); return offset & 0x3FF000; } #endif @@ -165,12 +165,13 @@ long sys_shmat_wrapper(int shmid, char *shmaddr, int shmflag) return raddr; } - /* Fucking broken ABI */ #ifdef CONFIG_PARISC64 extern asmlinkage long sys_truncate(const char *, unsigned long); extern asmlinkage long sys_ftruncate(unsigned int, unsigned long); +extern asmlinkage long sys_fcntl(unsigned int, unsigned int, unsigned long); + asmlinkage long parisc_truncate64(const char * path, unsigned int high, unsigned int low) { @@ -182,6 +183,21 @@ asmlinkage long parisc_ftruncate64(unsigned int fd, { return sys_ftruncate(fd, (long)high << 32 | low); } + +/* stubs for the benefit of the syscall_table since truncate64 and truncate + * are identical on LP64 */ +asmlinkage long sys_truncate64(const char * path, unsigned long length) +{ + return sys_truncate(path, length); +} +asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length) +{ + return sys_ftruncate(fd, length); +} +asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_fcntl(fd, cmd, arg); +} #else extern asmlinkage long sys_truncate64(const char *, loff_t); diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 08ffcb50fde0..9691da8b611c 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -69,9 +69,14 @@ linux_gateway_entry: * exit from the syscall, and also use that value to know * whether to do narrow or wide syscalls. -PB */ - ssm PSW_SM_W, %r0 + ssm PSW_SM_W, %r1 + extrd,u %r1,PSW_W_BIT,1,%r1 + /* sp must be aligned on 4, so deposit the W bit setting into + * the bottom of sp temporarily */ + or,ev %r1,%r30,%r30 + b,n 1f /* The top halves of argument registers must be cleared on syscall - * entry. + * entry from narrow executable. */ depdi 0, 31, 32, %r26 depdi 0, 31, 32, %r25 @@ -79,11 +84,13 @@ linux_gateway_entry: depdi 0, 31, 32, %r23 depdi 0, 31, 32, %r22 depdi 0, 31, 32, %r21 +1: #endif mfctl %cr30,%r1 xor %r1,%r30,%r30 /* ye olde xor trick */ xor %r1,%r30,%r1 xor %r1,%r30,%r30 + ldo THREAD_SZ_ALGN+FRAME_SIZE(%r30),%r30 /* set up kernel stack */ /* N.B.: It is critical that we don't set sr7 to 0 until r30 @@ -104,9 +111,19 @@ linux_gateway_entry: PSW value is stored. This is needed for gdb and sys_ptrace. */ STREG %r0, TASK_PT_PSW(%r1) STREG %r2, TASK_PT_GR2(%r1) /* preserve rp */ + STREG %r19, TASK_PT_GR19(%r1) + LDREGM -FRAME_SIZE(%r30), %r2 /* get users sp back */ +#ifdef __LP64__ + extrd,u %r2,63,1,%r19 /* W hidden in bottom bit */ +#if 0 + xor %r19,%r2,%r2 /* clear bottom bit */ + depd,z %r19,1,1,%r19 + std %r19,TASK_PT_PSW(%r1) +#endif +#endif STREG %r2, TASK_PT_GR30(%r1) /* ... and save it */ - STREG %r19, TASK_PT_GR19(%r1) + STREG %r20, TASK_PT_GR20(%r1) STREG %r21, TASK_PT_GR21(%r1) STREG %r22, TASK_PT_GR22(%r1) @@ -130,6 +147,7 @@ linux_gateway_entry: #ifdef __LP64__ ldo -16(%r30),%r29 /* Reference param save area */ + copy %r19,%r2 /* W bit back to r2 */ #else /* no need to save these on stack in wide mode because the first 8 * args are passed in registers */ @@ -144,9 +162,17 @@ linux_gateway_entry: /* Note! We cannot use the syscall table that is mapped nearby since the gateway page is mapped execute-only. */ +#ifdef __LP64__ + ldil L%sys_call_table, %r1 + or,= %r2,%r2,%r2 + addil L%(sys_call_table64-sys_call_table), %r1 + ldo R%sys_call_table(%r1), %r19 + or,= %r2,%r2,%r2 + ldo R%sys_call_table64(%r1), %r19 +#else ldil L%sys_call_table, %r1 ldo R%sys_call_table(%r1), %r19 - +#endif comiclr,>>= __NR_Linux_syscalls, %r20, %r0 b,n .Lsyscall_nosys @@ -317,304 +343,21 @@ tracesys_sigexit: ldil L%syscall_exit_rfi,%r1 be,n R%syscall_exit_rfi(%sr7,%r1) -#ifdef __LP64__ -/* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and - * narrow palinux. Use ENTRY_DIFF for those where a 32-bit specific - * implementation is required on wide palinux. Use ENTRY_COMP where - * the compatability layer has a useful 32-bit implementation. - */ -#define ENTRY_SAME(_name_) .dword sys_##_name_ -#define ENTRY_DIFF(_name_) .dword sys32_##_name_ -#define ENTRY_UHOH(_name_) .dword sys32_##unimplemented -#define ENTRY_OURS(_name_) .dword parisc_##_name_ -#define ENTRY_COMP(_name_) .dword compat_sys_##_name_ -#else -#define ENTRY_SAME(_name_) .word sys_##_name_ -#define ENTRY_DIFF(_name_) .word sys_##_name_ -#define ENTRY_UHOH(_name_) .word sys_##_name_ -#define ENTRY_OURS(_name_) .word parisc_##_name_ -#define ENTRY_COMP(_name_) .word sys_##_name_ -#endif - - .align 8 + .align 4096 .export sys_call_table .Lsys_call_table: sys_call_table: - ENTRY_SAME(ni_syscall) /* 0 - old "setup()" system call*/ - ENTRY_SAME(exit) - ENTRY_SAME(fork_wrapper) - ENTRY_SAME(read) - ENTRY_SAME(write) - ENTRY_SAME(open) /* 5 */ - ENTRY_SAME(close) - ENTRY_SAME(waitpid) - ENTRY_SAME(creat) - ENTRY_SAME(link) - ENTRY_SAME(unlink) /* 10 */ - ENTRY_DIFF(execve_wrapper) - ENTRY_SAME(chdir) - /* See comments in kernel/time.c!!! Maybe we don't need this? */ - ENTRY_DIFF(time) - ENTRY_SAME(mknod) - ENTRY_SAME(chmod) /* 15 */ - ENTRY_SAME(lchown) - ENTRY_SAME(socket) - /* struct stat is MAYBE identical wide and narrow ?? */ - ENTRY_COMP(newstat) - ENTRY_DIFF(lseek) - ENTRY_SAME(getpid) /* 20 */ - /* the 'void * data' parameter may need re-packing in wide */ - ENTRY_DIFF(mount) - /* concerned about struct sockaddr in wide/narrow */ - /* ---> I think sockaddr is OK unless the compiler packs the struct */ - /* differently to align the char array */ - ENTRY_SAME(bind) - ENTRY_SAME(setuid) - ENTRY_SAME(getuid) - ENTRY_SAME(stime) /* 25 */ - ENTRY_SAME(ptrace) - ENTRY_SAME(alarm) - /* see stat comment */ - ENTRY_COMP(newfstat) - ENTRY_SAME(pause) - /* struct utimbuf uses time_t which might vary */ - ENTRY_COMP(utime) /* 30 */ - /* struct sockaddr... */ - ENTRY_SAME(connect) - ENTRY_SAME(listen) - ENTRY_SAME(access) - ENTRY_SAME(nice) - /* struct sockaddr... */ - ENTRY_SAME(accept) /* 35 */ - ENTRY_SAME(sync) - ENTRY_SAME(kill) - ENTRY_SAME(rename) - ENTRY_SAME(mkdir) - ENTRY_SAME(rmdir) /* 40 */ - ENTRY_SAME(dup) - ENTRY_SAME(pipe) - ENTRY_COMP(times) - /* struct sockaddr... */ - ENTRY_SAME(getsockname) - /* it seems possible brk() could return a >4G pointer... */ - ENTRY_SAME(brk) /* 45 */ - ENTRY_SAME(setgid) - ENTRY_SAME(getgid) - ENTRY_SAME(signal) - ENTRY_SAME(geteuid) - ENTRY_SAME(getegid) /* 50 */ - ENTRY_SAME(acct) - ENTRY_SAME(umount) - /* struct sockaddr... */ - ENTRY_SAME(getpeername) - ENTRY_COMP(ioctl) - ENTRY_COMP(fcntl) /* 55 */ - ENTRY_SAME(socketpair) - ENTRY_SAME(setpgid) - ENTRY_SAME(send) - ENTRY_SAME(newuname) - ENTRY_SAME(umask) /* 60 */ - ENTRY_SAME(chroot) - ENTRY_SAME(ustat) - ENTRY_SAME(dup2) - ENTRY_SAME(getppid) - ENTRY_SAME(getpgrp) /* 65 */ - ENTRY_SAME(setsid) - ENTRY_SAME(pivot_root) - /* I don't like this */ - ENTRY_UHOH(sgetmask) - ENTRY_UHOH(ssetmask) - ENTRY_SAME(setreuid) /* 70 */ - ENTRY_SAME(setregid) - ENTRY_SAME(mincore) - ENTRY_COMP(sigpending) - ENTRY_SAME(sethostname) - /* Following 3 have linux-common-code structs containing longs -( */ - ENTRY_COMP(setrlimit) /* 75 */ - ENTRY_COMP(getrlimit) - ENTRY_COMP(getrusage) - /* struct timeval and timezone are maybe?? consistent wide and narrow */ - ENTRY_DIFF(gettimeofday) - ENTRY_DIFF(settimeofday) - ENTRY_SAME(getgroups) /* 80 */ - ENTRY_SAME(setgroups) - /* struct socketaddr... */ - ENTRY_SAME(sendto) - ENTRY_SAME(symlink) - /* see stat comment */ - ENTRY_COMP(newlstat) - ENTRY_SAME(readlink) /* 85 */ - ENTRY_SAME(ni_syscall) /* was uselib */ - ENTRY_SAME(swapon) - ENTRY_SAME(reboot) - ENTRY_SAME(mmap2) - ENTRY_SAME(mmap) /* 90 */ - ENTRY_SAME(munmap) - ENTRY_SAME(truncate) - ENTRY_SAME(ftruncate) - ENTRY_SAME(fchmod) - ENTRY_SAME(fchown) /* 95 */ - ENTRY_SAME(getpriority) - ENTRY_SAME(setpriority) - ENTRY_SAME(recv) - ENTRY_COMP(statfs) - ENTRY_COMP(fstatfs) /* 100 */ - ENTRY_SAME(stat64) - ENTRY_SAME(ni_syscall) /* was socketcall */ - ENTRY_SAME(syslog) - /* even though manpage says struct timeval contains longs, ours has - * time_t and suseconds_t -- both of which are safe wide/narrow */ - ENTRY_COMP(setitimer) - ENTRY_COMP(getitimer) /* 105 */ - ENTRY_SAME(capget) - ENTRY_SAME(capset) - ENTRY_OURS(pread64) - ENTRY_OURS(pwrite64) - ENTRY_SAME(getcwd) /* 110 */ - ENTRY_SAME(vhangup) - ENTRY_SAME(fstat64) - ENTRY_SAME(vfork_wrapper) - /* struct rusage contains longs... */ - ENTRY_COMP(wait4) - ENTRY_SAME(swapoff) /* 115 */ - ENTRY_DIFF(sysinfo) - ENTRY_SAME(shutdown) - ENTRY_SAME(fsync) - ENTRY_SAME(madvise) - ENTRY_SAME(clone_wrapper) /* 120 */ - ENTRY_SAME(setdomainname) - ENTRY_DIFF(sendfile) - /* struct sockaddr... */ - ENTRY_SAME(recvfrom) - /* struct timex contains longs */ - ENTRY_DIFF(adjtimex) - ENTRY_SAME(mprotect) /* 125 */ - /* old_sigset_t forced to 32 bits. Beware glibc sigset_t */ - ENTRY_COMP(sigprocmask) - ENTRY_SAME(ni_syscall) /* create_module */ - ENTRY_SAME(init_module) - ENTRY_SAME(delete_module) - ENTRY_SAME(ni_syscall) /* 130: get_kernel_syms */ - /* time_t inside struct dqblk */ - ENTRY_SAME(quotactl) - ENTRY_SAME(getpgid) - ENTRY_SAME(fchdir) - ENTRY_SAME(bdflush) - ENTRY_SAME(sysfs) /* 135 */ - ENTRY_SAME(personality) - ENTRY_SAME(ni_syscall) /* for afs_syscall */ - ENTRY_SAME(setfsuid) - ENTRY_SAME(setfsgid) - /* I think this might work */ - ENTRY_SAME(llseek) /* 140 */ - /* struct linux_dirent has longs, like 'unsigned long d_ino' which - * almost definitely should be 'ino_t d_ino' but it's too late now */ - ENTRY_DIFF(getdents) - /* it is POSSIBLE that select will be OK because even though fd_set - * contains longs, the macros and sizes are clever. */ - ENTRY_DIFF(select) - ENTRY_SAME(flock) - ENTRY_SAME(msync) - /* struct iovec contains pointers */ - ENTRY_DIFF(readv) /* 145 */ - ENTRY_DIFF(writev) - ENTRY_SAME(getsid) - ENTRY_SAME(fdatasync) - /* struct __sysctl_args is a mess */ - ENTRY_DIFF(sysctl) - ENTRY_SAME(mlock) /* 150 */ - ENTRY_SAME(munlock) - ENTRY_SAME(mlockall) - ENTRY_SAME(munlockall) - /* struct sched_param is ok for now */ - ENTRY_SAME(sched_setparam) - ENTRY_SAME(sched_getparam) /* 155 */ - ENTRY_SAME(sched_setscheduler) - ENTRY_SAME(sched_getscheduler) - ENTRY_SAME(sched_yield) - ENTRY_SAME(sched_get_priority_max) - ENTRY_SAME(sched_get_priority_min) /* 160 */ - /* These 2 would've worked if someone had defined struct timespec - * carefully, like timeval for example (which is about the same). - * Unfortunately it contains a long :-( */ - ENTRY_DIFF(sched_rr_get_interval) - ENTRY_COMP(nanosleep) - ENTRY_SAME(mremap) - ENTRY_SAME(setresuid) - ENTRY_SAME(getresuid) /* 165 */ - ENTRY_DIFF(sigaltstack_wrapper) - ENTRY_SAME(ni_syscall) /* query_module */ - ENTRY_SAME(poll) - /* structs contain pointers and an in_addr... */ - ENTRY_DIFF(nfsservctl) - ENTRY_SAME(setresgid) /* 170 */ - ENTRY_SAME(getresgid) - ENTRY_SAME(prctl) - /* signals need a careful review */ - ENTRY_SAME(rt_sigreturn_wrapper) - ENTRY_DIFF(rt_sigaction) - ENTRY_DIFF(rt_sigprocmask) /* 175 */ - ENTRY_DIFF(rt_sigpending) - ENTRY_UHOH(rt_sigtimedwait) - /* even though the struct siginfo_t is different, it appears like - * all the paths use values which should be same wide and narrow. - * Also the struct is padded to 128 bytes which means we don't have - * to worry about faulting trying to copy in a larger 64-bit - * struct from a 32-bit user-space app. - */ - ENTRY_SAME(rt_sigqueueinfo) - ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */ - ENTRY_SAME(chown) /* 180 */ - /* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */ - ENTRY_COMP(setsockopt) - ENTRY_SAME(getsockopt) - ENTRY_COMP(sendmsg) - ENTRY_COMP(recvmsg) - ENTRY_SAME(semop) /* 185 */ - ENTRY_SAME(semget) - ENTRY_DIFF(semctl_broken) - ENTRY_DIFF(msgsnd) - ENTRY_DIFF(msgrcv) - ENTRY_SAME(msgget) /* 190 */ - ENTRY_SAME(msgctl_broken) - ENTRY_SAME(shmat_wrapper) - ENTRY_SAME(shmdt) - ENTRY_SAME(shmget) - ENTRY_SAME(shmctl_broken) /* 195 */ - ENTRY_SAME(ni_syscall) /* streams1 */ - ENTRY_SAME(ni_syscall) /* streams2 */ - ENTRY_SAME(lstat64) - ENTRY_OURS(truncate64) - ENTRY_OURS(ftruncate64) /* 200 */ - ENTRY_SAME(getdents64) - ENTRY_COMP(fcntl64) - ENTRY_SAME(ni_syscall) - ENTRY_SAME(ni_syscall) - ENTRY_SAME(ni_syscall) /* 205 */ - ENTRY_SAME(gettid) - ENTRY_OURS(readahead) - ENTRY_SAME(ni_syscall) /* tkill */ - - ENTRY_SAME(sendfile64) - ENTRY_COMP(futex) /* 210 */ - ENTRY_COMP(sched_setaffinity) - ENTRY_COMP(sched_getaffinity) - ENTRY_SAME(ni_syscall) - ENTRY_SAME(ni_syscall) - ENTRY_SAME(io_setup) /* 215 */ - ENTRY_SAME(io_destroy) - ENTRY_SAME(io_getevents) - ENTRY_SAME(io_submit) - ENTRY_SAME(io_cancel) - ENTRY_SAME(alloc_hugepages) /* 220 */ - ENTRY_SAME(free_hugepages) - ENTRY_SAME(exit_group) - ENTRY_DIFF(lookup_dcookie) - ENTRY_SAME(epoll_create) - ENTRY_SAME(epoll_ctl) /* 225 */ - ENTRY_SAME(epoll_wait) - ENTRY_SAME(remap_file_pages) +#include "syscall_table.S" .end +#ifdef __LP64__ + .align 4096 + .export sys_call_table64 +.Lsys_call_table64: +sys_call_table64: +#define SYSCALL_TABLE_64BIT +#include "syscall_table.S" +#endif + /* Make sure nothing else is placed on this page */ diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S new file mode 100644 index 000000000000..2621f1c69c79 --- /dev/null +++ b/arch/parisc/kernel/syscall_table.S @@ -0,0 +1,304 @@ +#undef ENTRY_SAME +#undef ENTRY_DIFF +#undef ENTRY_UHOH +#undef ENTRY_COMP +#undef ENTRY_OURS +#if defined(__LP64__) && !defined(SYSCALL_TABLE_64BIT) +/* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and + * narrow palinux. Use ENTRY_DIFF for those where a 32-bit specific + * implementation is required on wide palinux. Use ENTRY_COMP where + * the compatability layer has a useful 32-bit implementation. + */ +#define ENTRY_SAME(_name_) .dword sys_##_name_ +#define ENTRY_DIFF(_name_) .dword sys32_##_name_ +#define ENTRY_UHOH(_name_) .dword sys32_##unimplemented +#define ENTRY_OURS(_name_) .dword parisc_##_name_ +#define ENTRY_COMP(_name_) .dword compat_sys_##_name_ +#elif defined(__LP64__) && defined(SYSCALL_TABLE_64BIT) +#define ENTRY_SAME(_name_) .dword sys_##_name_ +#define ENTRY_DIFF(_name_) .dword sys_##_name_ +#define ENTRY_UHOH(_name_) .dword sys_##_name_ +#define ENTRY_OURS(_name_) .dword sys_##_name_ +#define ENTRY_COMP(_name_) .dword sys_##_name_ +#else +#define ENTRY_SAME(_name_) .word sys_##_name_ +#define ENTRY_DIFF(_name_) .word sys_##_name_ +#define ENTRY_UHOH(_name_) .word sys_##_name_ +#define ENTRY_OURS(_name_) .word parisc_##_name_ +#define ENTRY_COMP(_name_) .word sys_##_name_ +#endif + + ENTRY_SAME(ni_syscall) /* 0 - old "setup()" system call*/ + ENTRY_SAME(exit) + ENTRY_SAME(fork_wrapper) + ENTRY_SAME(read) + ENTRY_SAME(write) + ENTRY_SAME(open) /* 5 */ + ENTRY_SAME(close) + ENTRY_SAME(waitpid) + ENTRY_SAME(creat) + ENTRY_SAME(link) + ENTRY_SAME(unlink) /* 10 */ + ENTRY_DIFF(execve_wrapper) + ENTRY_SAME(chdir) + /* See comments in kernel/time.c!!! Maybe we don't need this? */ + ENTRY_DIFF(time) + ENTRY_SAME(mknod) + ENTRY_SAME(chmod) /* 15 */ + ENTRY_SAME(lchown) + ENTRY_SAME(socket) + /* struct stat is MAYBE identical wide and narrow ?? */ + ENTRY_COMP(newstat) + ENTRY_DIFF(lseek) + ENTRY_SAME(getpid) /* 20 */ + /* the 'void * data' parameter may need re-packing in wide */ + ENTRY_DIFF(mount) + /* concerned about struct sockaddr in wide/narrow */ + /* ---> I think sockaddr is OK unless the compiler packs the struct */ + /* differently to align the char array */ + ENTRY_SAME(bind) + ENTRY_SAME(setuid) + ENTRY_SAME(getuid) + ENTRY_SAME(stime) /* 25 */ + ENTRY_SAME(ptrace) + ENTRY_SAME(alarm) + /* see stat comment */ + ENTRY_COMP(newfstat) + ENTRY_SAME(pause) + /* struct utimbuf uses time_t which might vary */ + ENTRY_COMP(utime) /* 30 */ + /* struct sockaddr... */ + ENTRY_SAME(connect) + ENTRY_SAME(listen) + ENTRY_SAME(access) + ENTRY_SAME(nice) + /* struct sockaddr... */ + ENTRY_SAME(accept) /* 35 */ + ENTRY_SAME(sync) + ENTRY_SAME(kill) + ENTRY_SAME(rename) + ENTRY_SAME(mkdir) + ENTRY_SAME(rmdir) /* 40 */ + ENTRY_SAME(dup) + ENTRY_SAME(pipe) + ENTRY_COMP(times) + /* struct sockaddr... */ + ENTRY_SAME(getsockname) + /* it seems possible brk() could return a >4G pointer... */ + ENTRY_SAME(brk) /* 45 */ + ENTRY_SAME(setgid) + ENTRY_SAME(getgid) + ENTRY_SAME(signal) + ENTRY_SAME(geteuid) + ENTRY_SAME(getegid) /* 50 */ + ENTRY_SAME(acct) + ENTRY_SAME(umount) + /* struct sockaddr... */ + ENTRY_SAME(getpeername) + ENTRY_COMP(ioctl) + ENTRY_COMP(fcntl) /* 55 */ + ENTRY_SAME(socketpair) + ENTRY_SAME(setpgid) + ENTRY_SAME(send) + ENTRY_SAME(newuname) + ENTRY_SAME(umask) /* 60 */ + ENTRY_SAME(chroot) + ENTRY_SAME(ustat) + ENTRY_SAME(dup2) + ENTRY_SAME(getppid) + ENTRY_SAME(getpgrp) /* 65 */ + ENTRY_SAME(setsid) + ENTRY_SAME(pivot_root) + /* I don't like this */ + ENTRY_UHOH(sgetmask) + ENTRY_UHOH(ssetmask) + ENTRY_SAME(setreuid) /* 70 */ + ENTRY_SAME(setregid) + ENTRY_SAME(mincore) + ENTRY_COMP(sigpending) + ENTRY_SAME(sethostname) + /* Following 3 have linux-common-code structs containing longs -( */ + ENTRY_COMP(setrlimit) /* 75 */ + ENTRY_COMP(getrlimit) + ENTRY_COMP(getrusage) + /* struct timeval and timezone are maybe?? consistent wide and narrow */ + ENTRY_DIFF(gettimeofday) + ENTRY_DIFF(settimeofday) + ENTRY_SAME(getgroups) /* 80 */ + ENTRY_SAME(setgroups) + /* struct socketaddr... */ + ENTRY_SAME(sendto) + ENTRY_SAME(symlink) + /* see stat comment */ + ENTRY_COMP(newlstat) + ENTRY_SAME(readlink) /* 85 */ + ENTRY_SAME(ni_syscall) /* was uselib */ + ENTRY_SAME(swapon) + ENTRY_SAME(reboot) + ENTRY_SAME(mmap2) + ENTRY_SAME(mmap) /* 90 */ + ENTRY_SAME(munmap) + ENTRY_SAME(truncate) + ENTRY_SAME(ftruncate) + ENTRY_SAME(fchmod) + ENTRY_SAME(fchown) /* 95 */ + ENTRY_SAME(getpriority) + ENTRY_SAME(setpriority) + ENTRY_SAME(recv) + ENTRY_COMP(statfs) + ENTRY_COMP(fstatfs) /* 100 */ + ENTRY_SAME(stat64) + ENTRY_SAME(ni_syscall) /* was socketcall */ + ENTRY_SAME(syslog) + /* even though manpage says struct timeval contains longs, ours has + * time_t and suseconds_t -- both of which are safe wide/narrow */ + ENTRY_COMP(setitimer) + ENTRY_COMP(getitimer) /* 105 */ + ENTRY_SAME(capget) + ENTRY_SAME(capset) + ENTRY_OURS(pread64) + ENTRY_OURS(pwrite64) + ENTRY_SAME(getcwd) /* 110 */ + ENTRY_SAME(vhangup) + ENTRY_SAME(fstat64) + ENTRY_SAME(vfork_wrapper) + /* struct rusage contains longs... */ + ENTRY_COMP(wait4) + ENTRY_SAME(swapoff) /* 115 */ + ENTRY_DIFF(sysinfo) + ENTRY_SAME(shutdown) + ENTRY_SAME(fsync) + ENTRY_SAME(madvise) + ENTRY_SAME(clone_wrapper) /* 120 */ + ENTRY_SAME(setdomainname) + ENTRY_DIFF(sendfile) + /* struct sockaddr... */ + ENTRY_SAME(recvfrom) + /* struct timex contains longs */ + ENTRY_DIFF(adjtimex) + ENTRY_SAME(mprotect) /* 125 */ + /* old_sigset_t forced to 32 bits. Beware glibc sigset_t */ + ENTRY_COMP(sigprocmask) + ENTRY_SAME(ni_syscall) /* create_module */ + ENTRY_SAME(init_module) + ENTRY_SAME(delete_module) + ENTRY_SAME(ni_syscall) /* 130: get_kernel_syms */ + /* time_t inside struct dqblk */ + ENTRY_SAME(quotactl) + ENTRY_SAME(getpgid) + ENTRY_SAME(fchdir) + ENTRY_SAME(bdflush) + ENTRY_SAME(sysfs) /* 135 */ + ENTRY_SAME(personality) + ENTRY_SAME(ni_syscall) /* for afs_syscall */ + ENTRY_SAME(setfsuid) + ENTRY_SAME(setfsgid) + /* I think this might work */ + ENTRY_SAME(llseek) /* 140 */ + /* struct linux_dirent has longs, like 'unsigned long d_ino' which + * almost definitely should be 'ino_t d_ino' but it's too late now */ + ENTRY_DIFF(getdents) + /* it is POSSIBLE that select will be OK because even though fd_set + * contains longs, the macros and sizes are clever. */ + ENTRY_DIFF(select) + ENTRY_SAME(flock) + ENTRY_SAME(msync) + /* struct iovec contains pointers */ + ENTRY_DIFF(readv) /* 145 */ + ENTRY_DIFF(writev) + ENTRY_SAME(getsid) + ENTRY_SAME(fdatasync) + /* struct __sysctl_args is a mess */ + ENTRY_DIFF(sysctl) + ENTRY_SAME(mlock) /* 150 */ + ENTRY_SAME(munlock) + ENTRY_SAME(mlockall) + ENTRY_SAME(munlockall) + /* struct sched_param is ok for now */ + ENTRY_SAME(sched_setparam) + ENTRY_SAME(sched_getparam) /* 155 */ + ENTRY_SAME(sched_setscheduler) + ENTRY_SAME(sched_getscheduler) + ENTRY_SAME(sched_yield) + ENTRY_SAME(sched_get_priority_max) + ENTRY_SAME(sched_get_priority_min) /* 160 */ + /* These 2 would've worked if someone had defined struct timespec + * carefully, like timeval for example (which is about the same). + * Unfortunately it contains a long :-( */ + ENTRY_DIFF(sched_rr_get_interval) + ENTRY_COMP(nanosleep) + ENTRY_SAME(mremap) + ENTRY_SAME(setresuid) + ENTRY_SAME(getresuid) /* 165 */ + ENTRY_DIFF(sigaltstack_wrapper) + ENTRY_SAME(ni_syscall) /* query_module */ + ENTRY_SAME(poll) + /* structs contain pointers and an in_addr... */ + ENTRY_DIFF(nfsservctl) + ENTRY_SAME(setresgid) /* 170 */ + ENTRY_SAME(getresgid) + ENTRY_SAME(prctl) + /* signals need a careful review */ + ENTRY_SAME(rt_sigreturn_wrapper) + ENTRY_DIFF(rt_sigaction) + ENTRY_DIFF(rt_sigprocmask) /* 175 */ + ENTRY_DIFF(rt_sigpending) + ENTRY_UHOH(rt_sigtimedwait) + /* even though the struct siginfo_t is different, it appears like + * all the paths use values which should be same wide and narrow. + * Also the struct is padded to 128 bytes which means we don't have + * to worry about faulting trying to copy in a larger 64-bit + * struct from a 32-bit user-space app. + */ + ENTRY_SAME(rt_sigqueueinfo) + ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */ + ENTRY_SAME(chown) /* 180 */ + /* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */ + ENTRY_COMP(setsockopt) + ENTRY_SAME(getsockopt) + ENTRY_COMP(sendmsg) + ENTRY_COMP(recvmsg) + ENTRY_SAME(semop) /* 185 */ + ENTRY_SAME(semget) + ENTRY_DIFF(semctl_broken) + ENTRY_DIFF(msgsnd) + ENTRY_DIFF(msgrcv) + ENTRY_SAME(msgget) /* 190 */ + ENTRY_SAME(msgctl_broken) + ENTRY_SAME(shmat_wrapper) + ENTRY_SAME(shmdt) + ENTRY_SAME(shmget) + ENTRY_SAME(shmctl_broken) /* 195 */ + ENTRY_SAME(ni_syscall) /* streams1 */ + ENTRY_SAME(ni_syscall) /* streams2 */ + ENTRY_SAME(lstat64) + ENTRY_OURS(truncate64) + ENTRY_OURS(ftruncate64) /* 200 */ + ENTRY_SAME(getdents64) + ENTRY_COMP(fcntl64) + ENTRY_SAME(ni_syscall) + ENTRY_SAME(ni_syscall) + ENTRY_SAME(ni_syscall) /* 205 */ + ENTRY_SAME(gettid) + ENTRY_OURS(readahead) + ENTRY_SAME(ni_syscall) /* tkill */ + + ENTRY_SAME(sendfile64) + ENTRY_COMP(futex) /* 210 */ + ENTRY_COMP(sched_setaffinity) + ENTRY_COMP(sched_getaffinity) + ENTRY_SAME(ni_syscall) + ENTRY_SAME(ni_syscall) + ENTRY_SAME(io_setup) /* 215 */ + ENTRY_SAME(io_destroy) + ENTRY_SAME(io_getevents) + ENTRY_SAME(io_submit) + ENTRY_SAME(io_cancel) + ENTRY_SAME(alloc_hugepages) /* 220 */ + ENTRY_SAME(free_hugepages) + ENTRY_SAME(exit_group) + ENTRY_DIFF(lookup_dcookie) + ENTRY_SAME(epoll_create) + ENTRY_SAME(epoll_ctl) /* 225 */ + ENTRY_SAME(epoll_wait) + ENTRY_SAME(remap_file_pages) diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 9d29078e5a24..b6da001f8681 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -48,7 +48,9 @@ static inline void parisc_do_profile(struct pt_regs *regs) { unsigned long pc = regs->iaoq[0]; +#if 0 extern unsigned long prof_cpu_mask; +#endif extern char _stext; profile_hook(regs); @@ -60,6 +62,10 @@ parisc_do_profile(struct pt_regs *regs) return; #if 0 + /* FIXME: when we have irq affinity to cpu, we need to + * only look at the cpus specified in this mask + */ + if (!((1 << smp_processor_id()) & prof_cpu_mask)) return; #endif @@ -206,7 +212,6 @@ do_settimeofday (struct timespec *tv) * done, and then undo it! */ nsec -= gettimeoffset() * 1000; - nsec -= (jiffies - wall_jiffies) * (NSEC_PER_SEC / HZ); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -223,6 +228,16 @@ do_settimeofday (struct timespec *tv) return 0; } +/* + * XXX: We can do better than this. + * Returns nanoseconds + */ + +unsigned long long sched_clock(void) +{ + return (unsigned long long)jiffies * (1000000000 / HZ); +} + void __init time_init(void) { diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 602cc50279b6..e1e102e2eb83 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -678,12 +678,13 @@ void handle_interruption(int code, struct pt_regs *regs) } if (user_mode(regs)) { - if (fault_space != regs->sr[7]) { + if ((fault_space>>SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) { #ifdef PRINT_USER_FAULTS if (fault_space == 0) printk(KERN_DEBUG "User Fault on Kernel Space "); else - printk(KERN_DEBUG "User Fault (long pointer) "); + printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ", + code); printk("pid=%d command='%s'\n", current->pid, current->comm); show_regs(regs); #endif diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index 75199b70349b..97d68cdd38e1 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -369,8 +369,8 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) void handle_unaligned(struct pt_regs *regs) { - unsigned long unaligned_count = 0; - unsigned long last_time = 0; + static unsigned long unaligned_count = 0; + static unsigned long last_time = 0; unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0; int modify = 0; int ret = -1; @@ -380,7 +380,6 @@ void handle_unaligned(struct pt_regs *regs) /* if the unaligned access is inside the kernel: * if the access is caused by a syscall, then we fault the calling * user process - * otherwise we halt the kernel */ if (!user_mode(regs)) { @@ -427,10 +426,10 @@ void handle_unaligned(struct pt_regs *regs) show_regs(regs); #endif } - } - if (!unaligned_enabled) - goto force_sigbus; + if (!unaligned_enabled) + goto force_sigbus; + } /* handle modification - OK, it's ugly, see the instruction manual */ switch (MAJOR_OP(regs->iir)) diff --git a/arch/parisc/lib/checksum.c b/arch/parisc/lib/checksum.c index 4145dd0442b6..368a095c5e74 100644 --- a/arch/parisc/lib/checksum.c +++ b/arch/parisc/lib/checksum.c @@ -16,8 +16,10 @@ * * $Id: checksum.c,v 1.3 1997/12/01 17:57:34 ralf Exp $ */ -#include <net/checksum.h> +#include <linux/module.h> #include <linux/types.h> + +#include <net/checksum.h> #include <asm/byteorder.h> #include <asm/string.h> #include <asm/uaccess.h> @@ -109,6 +111,7 @@ unsigned int csum_partial_copy_nocheck(const char *src, char *dst, return sum; } +EXPORT_SYMBOL(csum_partial_copy_nocheck); /* * Copy from userspace and compute checksum. If we catch an exception @@ -128,3 +131,4 @@ unsigned int csum_partial_copy_from_user (const char *src, char *dst, return csum_partial(dst, len, sum); } +EXPORT_SYMBOL(csum_partial_copy_from_user); diff --git a/arch/parisc/lib/io.c b/arch/parisc/lib/io.c index a87c02a8c0a0..27f635086a11 100644 --- a/arch/parisc/lib/io.c +++ b/arch/parisc/lib/io.c @@ -8,6 +8,7 @@ */ #include <linux/kernel.h> +#include <linux/module.h> #include <asm/io.h> /* Copies a block of memory to a device in an efficient manner. @@ -457,3 +458,10 @@ void outsl (unsigned long port, const void *src, unsigned long count) break; } } + +EXPORT_SYMBOL(insb); +EXPORT_SYMBOL(insw); +EXPORT_SYMBOL(insl); +EXPORT_SYMBOL(outsb); +EXPORT_SYMBOL(outsw); +EXPORT_SYMBOL(outsl); diff --git a/arch/parisc/math-emu/Makefile b/arch/parisc/math-emu/Makefile index 1755d661c3f6..affd4c80e3b7 100644 --- a/arch/parisc/math-emu/Makefile +++ b/arch/parisc/math-emu/Makefile @@ -2,6 +2,11 @@ # Makefile for the linux/parisc floating point code # +# See arch/parisc/math-emu/README +CFLAGS += -Wno-parentheses -Wno-implicit-function-declaration \ + -Wno-uninitialized -Wno-strict-prototypes -Wno-return-type \ + -Wno-implicit-int + obj-y := frnd.o driver.o decode_exc.o fpudispatch.o denormal.o \ dfmpy.o sfmpy.o sfsqrt.o dfsqrt.o dfadd.o fmpyfadd.o \ sfadd.o dfsub.o sfsub.o fcnvfxt.o fcnvff.o fcnvxf.o \ diff --git a/arch/parisc/math-emu/denormal.c b/arch/parisc/math-emu/denormal.c index 04835b56f46e..8c2363929510 100644 --- a/arch/parisc/math-emu/denormal.c +++ b/arch/parisc/math-emu/denormal.c @@ -47,7 +47,7 @@ #include "sgl_float.h" #include "dbl_float.h" #include "hppa.h" -#include "types.h" +#include <linux/kernel.h> /* #include <machine/sys/mdep_private.h> */ #undef Fpustatus_register diff --git a/arch/parisc/math-emu/fpudispatch.c b/arch/parisc/math-emu/fpudispatch.c index a829693c0087..3271a3249b44 100644 --- a/arch/parisc/math-emu/fpudispatch.c +++ b/arch/parisc/math-emu/fpudispatch.c @@ -50,7 +50,7 @@ #define FPUDEBUG 0 #include "float.h" -#include "types.h" +#include <linux/kernel.h> #include <asm/processor.h> /* #include <sys/debug.h> */ /* #include <machine/sys/mdep_private.h> */ diff --git a/arch/parisc/math-emu/types.h b/arch/parisc/math-emu/types.h deleted file mode 100644 index e2b9e1369729..000000000000 --- a/arch/parisc/math-emu/types.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Linux/PA-RISC Project (http://www.parisc-linux.org/) - * - * Floating-point emulation code - * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/kernel.h> -#define BUG() do { \ - printk(KERN_ERR "floating-pt emulation BUG at %s:%d!\n", __FILE__, __LINE__); \ -} while (0) diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 85504e531d35..fb18cfc572eb 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -430,6 +430,8 @@ void free_initmem(void) & ~(VM_MAP_OFFSET-1))) void *vmalloc_start; +EXPORT_SYMBOL(vmalloc_start); + #ifdef CONFIG_PA11 unsigned long pcxl_dma_start; #endif @@ -618,8 +620,6 @@ static void __init pagetable_init(void) { int range; - printk("pagetable_init\n"); - /* Map each physical memory range to its kernel vaddr */ for (range = 0; range < npmem_ranges; range++) { diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index aa5d0e0794c4..fbe8eb6312ed 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c @@ -530,11 +530,6 @@ static struct pci_driver superio_driver = { static int __init superio_modinit(void) { -#ifdef CONFIG_SERIAL_8250 - extern int serial8250_init(void); - serial8250_init(); -#endif - return pci_module_init(&superio_driver); } @@ -543,5 +538,10 @@ static void __exit superio_exit(void) pci_unregister_driver(&superio_driver); } -module_init(superio_modinit); +/* Make late initcall to ensure the serial and tty layers are initialised + * before we start superio. + * + * FIXME: does this break the superio console? + */ +late_initcall(superio_modinit); module_exit(superio_exit); diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 4363ea845216..7bbf41c35717 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -988,7 +988,7 @@ static int __devinit sticore_pci_init(struct pci_dev *pd, if (!sti) { printk(KERN_WARNING "Unable to handle STI device '%s'\n", - pd->dev.name); + pci_name(pd)); return -ENODEV; } #endif /* CONFIG_PCI */ diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index 1c02cb0b6a9c..4694912daffa 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -1238,7 +1238,7 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp) /* get framebuffer physical and virtual base addr & len (64bit ready) */ - fix->smem_start = fb->sti->regions_phys[1] | 0xffffffff00000000; + fix->smem_start = F_EXTEND(fb->sti->regions_phys[1]); fix->smem_len = fb->sti->regions[1].region_desc.length * 4096; fix->line_length = (fb->sti->glob_cfg->total_x * bpp) / 8; diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h index 808373512d6c..20ee097b599d 100644 --- a/include/asm-parisc/atomic.h +++ b/include/asm-parisc/atomic.h @@ -129,8 +129,9 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size) /* It's possible to reduce all atomic operations to either - * __atomic_add_return, __atomic_set and __atomic_ret (the latter - * is there only for consistency). */ + * __atomic_add_return, atomic_set and atomic_read (the latter + * is there only for consistency). + */ static __inline__ int __atomic_add_return(int i, atomic_t *v) { @@ -144,7 +145,7 @@ static __inline__ int __atomic_add_return(int i, atomic_t *v) return ret; } -static __inline__ void __atomic_set(atomic_t *v, int i) +static __inline__ void atomic_set(atomic_t *v, int i) { unsigned long flags; SPIN_LOCK_IRQSAVE(ATOMIC_HASH(v), flags); @@ -154,28 +155,25 @@ static __inline__ void __atomic_set(atomic_t *v, int i) SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(v), flags); } -static __inline__ int __atomic_read(atomic_t *v) +static __inline__ int atomic_read(const atomic_t *v) { return v->counter; } /* exported interface */ -#define atomic_add(i,v) ((void)(__atomic_add_return( (i),(v)))) -#define atomic_sub(i,v) ((void)(__atomic_add_return(-(i),(v)))) -#define atomic_inc(v) ((void)(__atomic_add_return( 1,(v)))) -#define atomic_dec(v) ((void)(__atomic_add_return( -1,(v)))) +#define atomic_add(i,v) ((void)(__atomic_add_return( ((int)i),(v)))) +#define atomic_sub(i,v) ((void)(__atomic_add_return(-((int)i),(v)))) +#define atomic_inc(v) ((void)(__atomic_add_return( 1,(v)))) +#define atomic_dec(v) ((void)(__atomic_add_return( -1,(v)))) -#define atomic_add_return(i,v) (__atomic_add_return( (i),(v))) -#define atomic_sub_return(i,v) (__atomic_add_return(-(i),(v))) +#define atomic_add_return(i,v) (__atomic_add_return( ((int)i),(v))) +#define atomic_sub_return(i,v) (__atomic_add_return(-((int)i),(v))) #define atomic_inc_return(v) (__atomic_add_return( 1,(v))) #define atomic_dec_return(v) (__atomic_add_return( -1,(v))) #define atomic_dec_and_test(v) (atomic_dec_return(v) == 0) -#define atomic_set(v,i) (__atomic_set((v),i)) -#define atomic_read(v) (__atomic_read(v)) - #define ATOMIC_INIT(i) { (i) } #define smp_mb__before_atomic_dec() smp_mb() diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h index 51f4871ac6ce..0ecabe5a2ec1 100644 --- a/include/asm-parisc/bitops.h +++ b/include/asm-parisc/bitops.h @@ -232,24 +232,24 @@ static __inline__ unsigned long __ffs(unsigned long x) #if BITS_PER_LONG > 32 " ldi 63,%1\n" " extrd,u,*<> %0,63,32,%%r0\n" - " extrd,u,*TR %0,31,32,%0\n" + " extrd,u,*TR %0,31,32,%0\n" /* move top 32-bits down */ " addi -32,%1,%1\n" #else " ldi 31,%1\n" #endif " extru,<> %0,31,16,%%r0\n" - " extru,TR %0,15,16,%0\n" + " extru,TR %0,15,16,%0\n" /* xxxx0000 -> 0000xxxx */ " addi -16,%1,%1\n" " extru,<> %0,31,8,%%r0\n" - " extru,TR %0,23,8,%0\n" + " extru,TR %0,23,8,%0\n" /* 0000xx00 -> 000000xx */ " addi -8,%1,%1\n" " extru,<> %0,31,4,%%r0\n" - " extru,TR %0,27,4,%0\n" + " extru,TR %0,27,4,%0\n" /* 000000x0 -> 0000000x */ " addi -4,%1,%1\n" " extru,<> %0,31,2,%%r0\n" - " extru,TR %0,29,2,%0\n" + " extru,TR %0,29,2,%0\n" /* 0000000y, 1100b -> 0011b */ " addi -2,%1,%1\n" - " extru,= %0,31,1,%%r0\n" + " extru,= %0,31,1,%%r0\n" /* check last bit */ " addi -1,%1,%1\n" : "+r" (x), "=r" (ret) ); return ret; @@ -291,7 +291,7 @@ static __inline__ int fls(int x) " zdep,TR %0,27,28,%0\n" /* x0000000 */ " addi 4,%1,%1\n" " extru,<> %0,1,2,%%r0\n" - " zdep,TR %0,29,30,%0\n" /* y0000000 (y&3 = 0 */ + " zdep,TR %0,29,30,%0\n" /* y0000000 (y&3 = 0) */ " addi 2,%1,%1\n" " extru,= %0,0,1,%%r0\n" " addi 1,%1,%1\n" /* if y & 8, add 1 */ diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h index a4c2bf437b61..3c7a4901537e 100644 --- a/include/asm-parisc/dma-mapping.h +++ b/include/asm-parisc/dma-mapping.h @@ -2,6 +2,7 @@ #define _PARISC_DMA_MAPPING_H #include <linux/mm.h> +#include <linux/config.h> #include <asm/cacheflush.h> /* diff --git a/include/asm-parisc/elf.h b/include/asm-parisc/elf.h index a01e946dfc57..adea65fc43c9 100644 --- a/include/asm-parisc/elf.h +++ b/include/asm-parisc/elf.h @@ -144,6 +144,30 @@ #define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ #define R_PARISC_HIRESERVE 255 +#define PA_PLABEL_FDESC 0x02 /* bit set if PLABEL points to + * a function descriptor, not + * an address */ + +/* The following are PA function descriptors + * + * addr: the absolute address of the function + * gp: either the data pointer (r27) for non-PIC code or the + * the PLT pointer (r19) for PIC code */ + +/* Format for the Elf32 Function descriptor */ +typedef struct elf32_fdesc { + __u32 addr; + __u32 gp; +} Elf32_Fdesc; + +/* Format for the Elf64 Function descriptor */ +typedef struct elf64_fdesc { + __u64 dummy[2]; /* FIXME: nothing uses these, why waste + * the space */ + __u64 addr; + __u64 gp; +} Elf64_Fdesc; + /* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ #define PT_HP_TLS (PT_LOOS + 0x0) @@ -215,7 +239,10 @@ typedef unsigned long elf_greg_t; #ifdef __KERNEL__ #define SET_PERSONALITY(ex, ibcs2) \ - current->personality = PER_LINUX + current->personality = PER_LINUX; \ + current->thread.map_base = DEFAULT_MAP_BASE; \ + current->thread.task_size = DEFAULT_TASK_SIZE \ + #endif /* diff --git a/include/asm-parisc/ioctl.h b/include/asm-parisc/ioctl.h index ff78546f6efa..75dc3e956457 100644 --- a/include/asm-parisc/ioctl.h +++ b/include/asm-parisc/ioctl.h @@ -44,11 +44,21 @@ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) +/* provoke compile error for invalid uses of size argument */ +extern int __invalid_size_argument_for_IOC; +#define _IOC_TYPECHECK(t) \ + ((sizeof(t) == sizeof(t[1]) && \ + sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ + sizeof(t) : __invalid_size_argument_for_IOC) + /* used to create numbers */ #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) -#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) -#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) -#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) /* used to decode ioctl numbers.. */ #define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) diff --git a/include/asm-parisc/irq.h b/include/asm-parisc/irq.h index f7ad20b692ef..39db70230740 100644 --- a/include/asm-parisc/irq.h +++ b/include/asm-parisc/irq.h @@ -17,6 +17,7 @@ #include <linux/string.h> #include <linux/interrupt.h> +#include <linux/config.h> #define CPU_IRQ_REGION 1 diff --git a/include/asm-parisc/keyboard.h b/include/asm-parisc/keyboard.h index a5f701806107..a7cec346b7d9 100644 --- a/include/asm-parisc/keyboard.h +++ b/include/asm-parisc/keyboard.h @@ -25,8 +25,6 @@ #ifndef _PARISC_KEYBOARD_H #define _PARISC_KEYBOARD_H -#include <linux/config.h> - #ifdef __KERNEL__ #include <linux/kernel.h> diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h index b5db7b3da584..7d848d2721c2 100644 --- a/include/asm-parisc/page.h +++ b/include/asm-parisc/page.h @@ -7,6 +7,7 @@ #define PAGE_MASK (~(PAGE_SIZE-1)) #ifdef __KERNEL__ +#include <linux/config.h> #ifndef __ASSEMBLY__ #include <asm/cache.h> diff --git a/include/asm-parisc/param.h b/include/asm-parisc/param.h index bf926025eb8c..139b92553500 100644 --- a/include/asm-parisc/param.h +++ b/include/asm-parisc/param.h @@ -2,6 +2,7 @@ #define _ASMPARISC_PARAM_H #ifdef __KERNEL__ +#include <linux/config.h> # ifdef CONFIG_PA20 # define HZ 1000 /* Faster machines */ # else diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h index c326ff050502..ce754492efa2 100644 --- a/include/asm-parisc/pci.h +++ b/include/asm-parisc/pci.h @@ -1,6 +1,7 @@ #ifndef __ASM_PARISC_PCI_H #define __ASM_PARISC_PCI_H +#include <linux/config.h> #include <asm/scatterlist.h> /* diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h index f9dea09157fa..b3214f1bfe53 100644 --- a/include/asm-parisc/pdc.h +++ b/include/asm-parisc/pdc.h @@ -1,6 +1,8 @@ #ifndef _PARISC_PDC_H #define _PARISC_PDC_H +#include <linux/config.h> + /* * PDC return values ... * All PDC calls return a subset of these errors. @@ -191,8 +193,8 @@ typedef struct { #define PDC_IO 135 /* log error info, reset IO system */ #define PDC_IO_READ_AND_CLEAR_ERRORS 0 -#define PDC_IO_READ_AND_LOG_ERRORS 1 -#define PDC_IO_SUSPEND_USB 2 +#define PDC_IO_RESET 1 +#define PDC_IO_RESET_DEVICES 2 /* sets bits 6&7 (little endian) of the HcControl Register */ #define PDC_IO_USB_SUSPEND 0xC000000000000000 #define PDC_IO_EEPROM_IO_ERR_TABLE_FULL -5 /* return value */ @@ -951,7 +953,8 @@ int pdc_do_firm_test_reset(unsigned long ftc_bitmap); int pdc_do_reset(void); int pdc_soft_power_info(unsigned long *power_reg); int pdc_soft_power_button(int sw_control); -void pdc_suspend_usb(void); +void pdc_io_reset(void); +void pdc_io_reset_devices(void); int pdc_iodc_getc(void); void pdc_iodc_putc(unsigned char c); void pdc_iodc_outc(unsigned char c); diff --git a/include/asm-parisc/pgalloc.h b/include/asm-parisc/pgalloc.h index bbc02cb134b7..eb97d25ff353 100644 --- a/include/asm-parisc/pgalloc.h +++ b/include/asm-parisc/pgalloc.h @@ -1,7 +1,6 @@ #ifndef _ASM_PGALLOC_H #define _ASM_PGALLOC_H -#include <linux/config.h> #include <linux/gfp.h> #include <linux/mm.h> #include <linux/threads.h> diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index be75436b1e51..79d19128946f 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h @@ -1,6 +1,7 @@ #ifndef _PARISC_PGTABLE_H #define _PARISC_PGTABLE_H +#include <linux/config.h> #include <asm/fixmap.h> #ifndef __ASSEMBLY__ diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h index 4779a6efeb91..3f407809ba73 100644 --- a/include/asm-parisc/processor.h +++ b/include/asm-parisc/processor.h @@ -36,10 +36,18 @@ #define current_text_addr() ({ void *pc; __asm__("\n\tblr 0,%0\n\tnop":"=r" (pc)); pc; }) #define TASK_SIZE (current->thread.task_size) -#define DEFAULT_TASK_SIZE (0xFFF00000UL) - #define TASK_UNMAPPED_BASE (current->thread.map_base) -#define DEFAULT_MAP_BASE (0x40000000UL) + +#define DEFAULT_TASK_SIZE32 (0xFFF00000UL) +#define DEFAULT_MAP_BASE32 (0x40000000UL) + +#ifdef __LP64__ +#define DEFAULT_TASK_SIZE (MAX_ADDRESS-0xf000000) +#define DEFAULT_MAP_BASE (0x200000000UL) +#else +#define DEFAULT_TASK_SIZE DEFAULT_TASK_SIZE32 +#define DEFAULT_MAP_BASE DEFAULT_MAP_BASE32 +#endif #ifndef __ASSEMBLY__ @@ -247,8 +255,18 @@ on downward growing arches, it looks like this: * * Note that the S/390 people took the easy way out and hacked their * GCC to make the stack grow downwards. + * + * Final Note: For entry from syscall, the W (wide) bit of the PSW + * is stuffed into the lowest bit of the user sp (%r30), so we fill + * it in here from the current->personality */ +#ifdef __LP64__ +#define USER_WIDE_MODE (personality(current->personality) == PER_LINUX) +#else +#define USER_WIDE_MODE 0 +#endif + #define start_thread(regs, new_pc, new_sp) do { \ elf_addr_t *sp = (elf_addr_t *)new_sp; \ __u32 spaceid = (__u32)current->mm->context; \ @@ -266,12 +284,12 @@ on downward growing arches, it looks like this: regs->sr[5] = spaceid; \ regs->sr[6] = spaceid; \ regs->sr[7] = spaceid; \ - regs->gr[ 0] = USER_PSW; \ + regs->gr[ 0] = USER_PSW | (USER_WIDE_MODE ? PSW_W : 0); \ regs->fr[ 0] = 0LL; \ regs->fr[ 1] = 0LL; \ regs->fr[ 2] = 0LL; \ regs->fr[ 3] = 0LL; \ - regs->gr[30] = ((unsigned long)sp + 63) &~ 63; \ + regs->gr[30] = (((unsigned long)sp + 63) &~ 63) | (USER_WIDE_MODE ? 1 : 0); \ regs->gr[31] = pc; \ \ get_user(regs->gr[25], (argv - 1)); \ @@ -299,8 +317,6 @@ static inline unsigned long get_wchan(struct task_struct *p) #define KSTK_EIP(tsk) ((tsk)->thread.regs.iaoq[0]) #define KSTK_ESP(tsk) ((tsk)->thread.regs.gr[30]) -#endif /* __ASSEMBLY__ */ - #ifdef CONFIG_PA20 #define ARCH_HAS_PREFETCH extern inline void prefetch(const void *addr) @@ -317,4 +333,6 @@ extern inline void prefetchw(const void *addr) #define cpu_relax() barrier() +#endif /* __ASSEMBLY__ */ + #endif /* __ASM_PARISC_PROCESSOR_H */ diff --git a/include/asm-parisc/rt_sigframe.h b/include/asm-parisc/rt_sigframe.h index 5bae2e0c3152..a9b5193ff27a 100644 --- a/include/asm-parisc/rt_sigframe.h +++ b/include/asm-parisc/rt_sigframe.h @@ -13,7 +13,20 @@ struct rt_sigframe { * which Linux/parisc uses is sp-20 for the saved return pointer...) * Then, the stack pointer must be rounded to a cache line (64 bytes). */ +#define SIGFRAME32 64 +#define FUNCTIONCALLFRAME32 48 +#define PARISC_RT_SIGFRAME_SIZE32 \ + (((sizeof(struct rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32) + +#ifdef __LP64__ +#define SIGFRAME 128 +#define FUNCTIONCALLFRAME 96 #define PARISC_RT_SIGFRAME_SIZE \ - (((sizeof(struct rt_sigframe) + 48) + 63) & -64) + (((sizeof(struct rt_sigframe) + FUNCTIONCALLFRAME) + SIGFRAME) & -SIGFRAME) +#else +#define SIGFRAME SIGFRAME32 +#define FUNCTIONCALLFRAME FUNCTIONCALLFRAME32 +#define PARISC_RT_SIGFRAME_SIZE PARISC_RT_SIGFRAME_SIZE32 +#endif #endif diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h index ea8cf008dad9..a5b731f654cb 100644 --- a/include/asm-parisc/tlbflush.h +++ b/include/asm-parisc/tlbflush.h @@ -3,6 +3,7 @@ /* TLB flushing routines.... */ +#include <linux/config.h> #include <linux/mm.h> #include <asm/mmu_context.h> diff --git a/include/sound/sndmagic.h b/include/sound/sndmagic.h index 646f7dc6369a..c88c332ccc93 100644 --- a/include/sound/sndmagic.h +++ b/include/sound/sndmagic.h @@ -198,6 +198,8 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic) #define vx_pipe_t_magic 0xa15a4112 #define azf3328_t_magic 0xa15a4200 +#define snd_card_harmony_t_magic 0xa15a4300 + #else #define snd_magic_kcalloc(type, extra, flags) (type *) snd_kcalloc(sizeof(type) + extra, flags) diff --git a/sound/oss/harmony.c b/sound/oss/harmony.c index 934f079ebe39..3ca1d609c4d0 100644 --- a/sound/oss/harmony.c +++ b/sound/oss/harmony.c @@ -28,14 +28,14 @@ TODO: #include <linux/delay.h> #include <linux/errno.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/types.h> #include <linux/mm.h> #include <linux/pci.h> -#include <asm/gsc.h> +#include <asm/parisc-device.h> #include <asm/io.h> -#include <asm/pgalloc.h> #include "sound_config.h" diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index 1bd43e4ee7d2..6dd9597c80b7 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c @@ -66,6 +66,7 @@ #include <linux/delay.h> #include <sound/driver.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/slab.h> #include <linux/time.h> #include <linux/wait.h> @@ -77,8 +78,8 @@ #include <sound/initval.h> #include <sound/info.h> #include <asm/hardware.h> -#include <asm/gsc.h> #include <asm/io.h> +#include <asm/parisc-device.h> MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>"); MODULE_DESCRIPTION("ALSA Harmony sound driver"); @@ -709,8 +710,8 @@ static int snd_card_harmony_playback_open(snd_pcm_substream_t * substream) * harmony is not "real" pci, but we need a pci_dev * to alloc PCI DMA pages */ - substream->dma_private = harmony->fake_pci_dev; - substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI; + substream->runtime->dma_private = harmony->fake_pci_dev; +// substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI; harmony->playback_substream = substream; runtime->hw = snd_card_harmony_playback; @@ -733,8 +734,8 @@ static int snd_card_harmony_capture_open(snd_pcm_substream_t * substream) * harmony is not "real" pci, but we need a pci_dev * to alloc PCI DMA pages */ - substream->dma_private = harmony->fake_pci_dev; - substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI; + substream->runtime->dma_private = harmony->fake_pci_dev; +// substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI; harmony->capture_substream = substream; runtime->hw = snd_card_harmony_capture; |
