diff options
90 files changed, 1301 insertions, 2767 deletions
diff --git a/Documentation/DocBook/genericirq.tmpl b/Documentation/DocBook/genericirq.tmpl index 0f4a4b6321e4..4215f69ce7e6 100644 --- a/Documentation/DocBook/genericirq.tmpl +++ b/Documentation/DocBook/genericirq.tmpl @@ -303,10 +303,10 @@ desc->status |= running; do { if (desc->status & masked) desc->chip->enable(); - desc-status &= ~pending; + desc->status &= ~pending; handle_IRQ_event(desc->action); } while (status & pending); -desc-status &= ~running; +desc->status &= ~running; desc->chip->end(); </programlisting> </para> @@ -496,11 +496,6 @@ else CFLAGS += -fomit-frame-pointer endif -ifdef CONFIG_UNWIND_INFO -CFLAGS += -fasynchronous-unwind-tables -LDFLAGS_vmlinux += --eh-frame-hdr -endif - ifdef CONFIG_DEBUG_INFO CFLAGS += -g endif diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 3265208e5899..e075ff05c46d 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -1493,8 +1493,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_FRAME_POINTER is not set -CONFIG_UNWIND_INFO=y -CONFIG_STACK_UNWIND=y # CONFIG_FORCED_INLINING is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 18f4715c655d..b735458c6e3a 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -126,27 +126,6 @@ static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data) } } -static void wrport(u16 port, u8 bit_width, u32 value) -{ - if (bit_width <= 8) - outb(value, port); - else if (bit_width <= 16) - outw(value, port); - else if (bit_width <= 32) - outl(value, port); -} - -static void rdport(u16 port, u8 bit_width, u32 * ret) -{ - *ret = 0; - if (bit_width <= 8) - *ret = inb(port); - else if (bit_width <= 16) - *ret = inw(port); - else if (bit_width <= 32) - *ret = inl(port); -} - struct msr_addr { u32 reg; }; @@ -177,7 +156,9 @@ static void do_drv_read(struct drv_cmd *cmd) rdmsr(cmd->addr.msr.reg, cmd->val, h); break; case SYSTEM_IO_CAPABLE: - rdport(cmd->addr.io.port, cmd->addr.io.bit_width, &cmd->val); + acpi_os_read_port((acpi_io_address)cmd->addr.io.port, + &cmd->val, + (u32)cmd->addr.io.bit_width); break; default: break; @@ -193,7 +174,9 @@ static void do_drv_write(struct drv_cmd *cmd) wrmsr(cmd->addr.msr.reg, cmd->val, h); break; case SYSTEM_IO_CAPABLE: - wrport(cmd->addr.io.port, cmd->addr.io.bit_width, cmd->val); + acpi_os_write_port((acpi_io_address)cmd->addr.io.port, + cmd->val, + (u32)cmd->addr.io.bit_width); break; default: break; @@ -699,14 +682,14 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) if (result) goto err_freqfree; - switch (data->cpu_feature) { + switch (perf->control_register.space_id) { case ACPI_ADR_SPACE_SYSTEM_IO: /* Current speed is unknown and not detectable by IO port */ policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); break; case ACPI_ADR_SPACE_FIXED_HARDWARE: acpi_cpufreq_driver.get = get_cur_freq_on_cpu; - get_cur_freq_on_cpu(cpu); + policy->cur = get_cur_freq_on_cpu(cpu); break; default: break; diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index c548daad3476..6d9c97a690fd 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -787,8 +787,10 @@ static int __init longhaul_init(void) switch (c->x86_model) { case 6 ... 9: return cpufreq_register_driver(&longhaul_driver); + case 10: + printk(KERN_ERR PFX "Use acpi-cpufreq driver for VIA C7\n"); default: - printk (KERN_INFO PFX "Unknown VIA CPU. Contact davej@codemonkey.org.uk\n"); + ;; } return -ENODEV; diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index de34b7fed3c1..06461b8b715d 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -979,38 +979,6 @@ ENTRY(spurious_interrupt_bug) jmp error_code CFI_ENDPROC -#ifdef CONFIG_STACK_UNWIND -ENTRY(arch_unwind_init_running) - CFI_STARTPROC - movl 4(%esp), %edx - movl (%esp), %ecx - leal 4(%esp), %eax - movl %ebx, PT_EBX(%edx) - xorl %ebx, %ebx - movl %ebx, PT_ECX(%edx) - movl %ebx, PT_EDX(%edx) - movl %esi, PT_ESI(%edx) - movl %edi, PT_EDI(%edx) - movl %ebp, PT_EBP(%edx) - movl %ebx, PT_EAX(%edx) - movl $__USER_DS, PT_DS(%edx) - movl $__USER_DS, PT_ES(%edx) - movl $0, PT_GS(%edx) - movl %ebx, PT_ORIG_EAX(%edx) - movl %ecx, PT_EIP(%edx) - movl 12(%esp), %ecx - movl $__KERNEL_CS, PT_CS(%edx) - movl %ebx, PT_EFLAGS(%edx) - movl %eax, PT_OLDESP(%edx) - movl 8(%esp), %eax - movl %ecx, 8(%esp) - movl PT_EBX(%edx), %ebx - movl $__KERNEL_DS, PT_OLDSS(%edx) - jmpl *%eax - CFI_ENDPROC -ENDPROC(arch_unwind_init_running) -#endif - ENTRY(kernel_thread_helper) pushl $0 # fake return address for unwinder CFI_STARTPROC diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 2b30dbf8d117..0efad8aeb41a 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -94,11 +94,6 @@ asmlinkage void spurious_interrupt_bug(void); asmlinkage void machine_check(void); int kstack_depth_to_print = 24; -#ifdef CONFIG_STACK_UNWIND -static int call_trace = 1; -#else -#define call_trace (-1) -#endif ATOMIC_NOTIFIER_HEAD(i386die_chain); int register_die_notifier(struct notifier_block *nb) @@ -152,33 +147,6 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, return ebp; } -struct ops_and_data { - struct stacktrace_ops *ops; - void *data; -}; - -static asmlinkage int -dump_trace_unwind(struct unwind_frame_info *info, void *data) -{ - struct ops_and_data *oad = (struct ops_and_data *)data; - int n = 0; - unsigned long sp = UNW_SP(info); - - if (arch_unw_user_mode(info)) - return -1; - while (unwind(info) == 0 && UNW_PC(info)) { - n++; - oad->ops->address(oad->data, UNW_PC(info)); - if (arch_unw_user_mode(info)) - break; - if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) - && sp > UNW_SP(info)) - break; - sp = UNW_SP(info); - } - return n; -} - #define MSG(msg) ops->warning(data, msg) void dump_trace(struct task_struct *task, struct pt_regs *regs, @@ -190,41 +158,6 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (!task) task = current; - if (call_trace >= 0) { - int unw_ret = 0; - struct unwind_frame_info info; - struct ops_and_data oad = { .ops = ops, .data = data }; - - if (regs) { - if (unwind_init_frame_info(&info, task, regs) == 0) - unw_ret = dump_trace_unwind(&info, &oad); - } else if (task == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, - &oad); - else { - if (unwind_init_blocked(&info, task) == 0) - unw_ret = dump_trace_unwind(&info, &oad); - } - if (unw_ret > 0) { - if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, - "DWARF2 unwinder stuck at %s", - UNW_PC(&info)); - if (UNW_SP(&info) >= PAGE_OFFSET) { - MSG("Leftover inexact backtrace:"); - stack = (void *)UNW_SP(&info); - if (!stack) - return; - ebp = UNW_FP(&info); - } else - MSG("Full inexact backtrace again:"); - } else if (call_trace >= 1) - return; - else - MSG("Full inexact backtrace again:"); - } else - MSG("Inexact backtrace:"); - } if (!stack) { unsigned long dummy; stack = &dummy; @@ -1258,19 +1191,3 @@ static int __init kstack_setup(char *s) return 1; } __setup("kstack=", kstack_setup); - -#ifdef CONFIG_STACK_UNWIND -static int __init call_trace_setup(char *s) -{ - if (strcmp(s, "old") == 0) - call_trace = -1; - else if (strcmp(s, "both") == 0) - call_trace = 0; - else if (strcmp(s, "newfallback") == 0) - call_trace = 1; - else if (strcmp(s, "new") == 2) - call_trace = 2; - return 1; -} -__setup("call_trace=", call_trace_setup); -#endif diff --git a/arch/s390/defconfig b/arch/s390/defconfig index a6ec919ba83f..5368cf4a350e 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -1,14 +1,15 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc2 -# Wed Oct 18 17:11:10 2006 +# Linux kernel version: 2.6.20-rc1 +# Fri Dec 15 16:52:28 2006 # CONFIG_MMU=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_TIME=y CONFIG_S390=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -37,12 +38,13 @@ CONFIG_AUDIT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_CPUSETS is not set +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set -# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -119,6 +121,7 @@ CONFIG_PACK_STACK=y CONFIG_CHECK_STACK=y CONFIG_STACK_GUARD=256 # CONFIG_WARN_STACK is not set +CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -128,6 +131,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_RESOURCES_64BIT=y +CONFIG_HOLES_IN_ZONE=y # # I/O subsystem configuration @@ -196,6 +200,7 @@ CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set @@ -211,7 +216,6 @@ CONFIG_INET6_XFRM_MODE_BEET=y # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=y # CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -246,6 +250,7 @@ CONFIG_IPV6_SIT=y # QoS and/or fair queueing # CONFIG_NET_SCHED=y +CONFIG_NET_SCH_FIFO=y CONFIG_NET_SCH_CLK_JIFFIES=y # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set # CONFIG_NET_SCH_CLK_CPU is not set @@ -277,6 +282,7 @@ CONFIG_NET_CLS_ROUTE=y CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m # CONFIG_CLS_U32_PERF is not set +CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m # CONFIG_NET_EMATCH is not set @@ -315,6 +321,7 @@ CONFIG_SYS_HYPERVISOR=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y @@ -335,6 +342,7 @@ CONFIG_CHR_DEV_SG=y CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y # # SCSI Transports @@ -546,6 +554,7 @@ CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +CONFIG_GENERIC_ACL=y # # CD-ROM/DVD Filesystems @@ -571,7 +580,7 @@ CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set +CONFIG_CONFIGFS_FS=m # # Miscellaneous filesystems @@ -616,7 +625,6 @@ CONFIG_SUNRPC=y # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set # CONFIG_9P_FS is not set -CONFIG_GENERIC_ACL=y # # Partition Types @@ -646,6 +654,14 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # +# Distributed Lock Manager +# +CONFIG_DLM=m +CONFIG_DLM_TCP=y +# CONFIG_DLM_SCTP is not set +# CONFIG_DLM_DEBUG is not set + +# # Instrumentation Support # @@ -663,6 +679,8 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +CONFIG_HEADERS_CHECK=y CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set @@ -679,13 +697,11 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set -CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_FRAME_POINTER is not set # CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y -CONFIG_HEADERS_CHECK=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_LKDTM is not set @@ -699,10 +715,11 @@ CONFIG_HEADERS_CHECK=y # Cryptographic options # CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=m -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set @@ -713,8 +730,10 @@ CONFIG_CRYPTO_MANAGER=m # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_DES is not set # CONFIG_CRYPTO_DES_S390 is not set # CONFIG_CRYPTO_BLOWFISH is not set @@ -740,8 +759,10 @@ CONFIG_CRYPTO_CBC=m # # Library routines # +CONFIG_BITREVERSE=m # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC32=m # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y +CONFIG_IOMAP_COPY=y diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index 443fa377d9ff..2782cf9da5b4 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c @@ -379,7 +379,7 @@ static void *diag204_alloc_vbuf(int pages) static void *diag204_alloc_rbuf(void) { diag204_buf = (void*)__get_free_pages(GFP_KERNEL,0); - if (diag204_buf) + if (!diag204_buf) return ERR_PTR(-ENOMEM); diag204_buf_pages = 1; return diag204_buf; @@ -521,7 +521,7 @@ __init int hypfs_diag_init(void) } rc = diag224_get_name_table(); if (rc) { - diag224_delete_name_table(); + diag204_free_buffer(); printk(KERN_ERR "hypfs: could not get name table.\n"); } return rc; diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index a36bea1188d9..9e9972e8a52b 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -609,42 +609,12 @@ static ssize_t on_panic_store(struct subsystem *subsys, const char *buf, static struct subsys_attribute on_panic_attr = __ATTR(on_panic, 0644, on_panic_show, on_panic_store); -static void print_fcp_block(struct ipl_parameter_block *fcp_block) -{ - printk(KERN_EMERG "wwpn: %016llx\n", - (unsigned long long)fcp_block->ipl_info.fcp.wwpn); - printk(KERN_EMERG "lun: %016llx\n", - (unsigned long long)fcp_block->ipl_info.fcp.lun); - printk(KERN_EMERG "bootprog: %lld\n", - (unsigned long long)fcp_block->ipl_info.fcp.bootprog); - printk(KERN_EMERG "br_lba: %lld\n", - (unsigned long long)fcp_block->ipl_info.fcp.br_lba); - printk(KERN_EMERG "device: %llx\n", - (unsigned long long)fcp_block->ipl_info.fcp.devno); - printk(KERN_EMERG "opt: %x\n", fcp_block->ipl_info.fcp.opt); -} - void do_reipl(void) { struct ccw_dev_id devid; static char buf[100]; char loadparm[LOADPARM_LEN + 1]; - switch (reipl_type) { - case IPL_TYPE_CCW: - reipl_get_ascii_loadparm(loadparm); - printk(KERN_EMERG "reboot on ccw device: 0.0.%04x\n", - reipl_block_ccw->ipl_info.ccw.devno); - printk(KERN_EMERG "loadparm = '%s'\n", loadparm); - break; - case IPL_TYPE_FCP: - printk(KERN_EMERG "reboot on fcp device:\n"); - print_fcp_block(reipl_block_fcp); - break; - default: - break; - } - switch (reipl_method) { case IPL_METHOD_CCW_CIO: devid.devno = reipl_block_ccw->ipl_info.ccw.devno; @@ -654,6 +624,7 @@ void do_reipl(void) reipl_ccw_dev(&devid); break; case IPL_METHOD_CCW_VM: + reipl_get_ascii_loadparm(loadparm); if (strlen(loadparm) == 0) sprintf(buf, "IPL %X", reipl_block_ccw->ipl_info.ccw.devno); @@ -683,7 +654,6 @@ void do_reipl(void) diag308(DIAG308_IPL, NULL); break; } - printk(KERN_EMERG "reboot failed!\n"); signal_processor(smp_processor_id(), sigp_stop_and_store_status); } @@ -692,19 +662,6 @@ static void do_dump(void) struct ccw_dev_id devid; static char buf[100]; - switch (dump_type) { - case IPL_TYPE_CCW: - printk(KERN_EMERG "Automatic dump on ccw device: 0.0.%04x\n", - dump_block_ccw->ipl_info.ccw.devno); - break; - case IPL_TYPE_FCP: - printk(KERN_EMERG "Automatic dump on fcp device:\n"); - print_fcp_block(dump_block_fcp); - break; - default: - return; - } - switch (dump_method) { case IPL_METHOD_CCW_CIO: smp_send_stop(); @@ -1037,15 +994,21 @@ static void do_reset_calls(void) } extern void reset_mcck_handler(void); +extern void reset_pgm_handler(void); +extern __u32 dump_prefix_page; void s390_reset_system(void) { struct _lowcore *lc; - /* Stack for interrupt/machine check handler */ lc = (struct _lowcore *)(unsigned long) store_prefix(); + + /* Stack for interrupt/machine check handler */ lc->panic_stack = S390_lowcore.panic_stack; + /* Save prefix page address for dump case */ + dump_prefix_page = (unsigned long) lc; + /* Disable prefixing */ set_prefix(0); @@ -1056,5 +1019,11 @@ void s390_reset_system(void) S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK; S390_lowcore.mcck_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) &reset_mcck_handler; + + /* Set new program check handler */ + S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK; + S390_lowcore.program_new_psw.addr = + PSW_ADDR_AMODE | (unsigned long) &reset_pgm_handler; + do_reset_calls(); } diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S index f9434d42ce9f..c3f4d9b95083 100644 --- a/arch/s390/kernel/reipl.S +++ b/arch/s390/kernel/reipl.S @@ -16,7 +16,7 @@ do_reipl_asm: basr %r13,0 stm %r0,%r15,__LC_GPREGS_SAVE_AREA stctl %c0,%c15,__LC_CREGS_SAVE_AREA stam %a0,%a15,__LC_AREGS_SAVE_AREA - stpx __LC_PREFIX_SAVE_AREA + mvc __LC_PREFIX_SAVE_AREA(4),dump_prefix_page-.Lpg0(%r13) stckc .Lclkcmp-.Lpg0(%r13) mvc __LC_CLOCK_COMP_SAVE_AREA(8),.Lclkcmp-.Lpg0(%r13) stpt __LC_CPU_TIMER_SAVE_AREA @@ -79,3 +79,7 @@ do_reipl_asm: basr %r13,0 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 + .globl dump_prefix_page +dump_prefix_page: + .long 0x00000000 + diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S index f18ef260ca23..dbb3eed38865 100644 --- a/arch/s390/kernel/reipl64.S +++ b/arch/s390/kernel/reipl64.S @@ -20,7 +20,7 @@ do_reipl_asm: basr %r13,0 stg %r0,__LC_GPREGS_SAVE_AREA-0x1000+8(%r1) stctg %c0,%c15,__LC_CREGS_SAVE_AREA-0x1000(%r1) stam %a0,%a15,__LC_AREGS_SAVE_AREA-0x1000(%r1) - stpx __LC_PREFIX_SAVE_AREA-0x1000(%r1) + mvc __LC_PREFIX_SAVE_AREA-0x1000(4,%r1),dump_prefix_page-.Lpg0(%r13) stfpc __LC_FP_CREG_SAVE_AREA-0x1000(%r1) stckc .Lclkcmp-.Lpg0(%r13) mvc __LC_CLOCK_COMP_SAVE_AREA-0x1000(8,%r1),.Lclkcmp-.Lpg0(%r13) @@ -103,3 +103,6 @@ do_reipl_asm: basr %r13,0 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 + .globl dump_prefix_page +dump_prefix_page: + .long 0x00000000 diff --git a/arch/s390/kernel/reset.S b/arch/s390/kernel/reset.S index be8688c0665c..8a87355161fa 100644 --- a/arch/s390/kernel/reset.S +++ b/arch/s390/kernel/reset.S @@ -3,6 +3,7 @@ * * Copyright (C) IBM Corp. 2006 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> + * Michael Holzheu <holzheu@de.ibm.com> */ #include <asm/ptrace.h> @@ -27,6 +28,26 @@ reset_mcck_handler: s390_reset_mcck_handler: .quad 0 + .globl reset_pgm_handler +reset_pgm_handler: + stmg %r0,%r15,__LC_SAVE_AREA + basr %r13,0 +0: lg %r15,__LC_PANIC_STACK # load panic stack + aghi %r15,-STACK_FRAME_OVERHEAD + lg %r1,s390_reset_pgm_handler-0b(%r13) + ltgr %r1,%r1 + jz 1f + basr %r14,%r1 + lmg %r0,%r15,__LC_SAVE_AREA + lpswe __LC_PGM_OLD_PSW +1: lpswe disabled_wait_psw-0b(%r13) + .globl s390_reset_pgm_handler +s390_reset_pgm_handler: + .quad 0 + .align 8 +disabled_wait_psw: + .quad 0x0002000180000000,0x0000000000000000 + reset_pgm_handler + #else /* CONFIG_64BIT */ .globl reset_mcck_handler @@ -45,4 +66,25 @@ reset_mcck_handler: s390_reset_mcck_handler: .long 0 + .globl reset_pgm_handler +reset_pgm_handler: + stm %r0,%r15,__LC_SAVE_AREA + basr %r13,0 +0: l %r15,__LC_PANIC_STACK # load panic stack + ahi %r15,-STACK_FRAME_OVERHEAD + l %r1,s390_reset_pgm_handler-0b(%r13) + ltr %r1,%r1 + jz 1f + basr %r14,%r1 + lm %r0,%r15,__LC_SAVE_AREA + lpsw __LC_PGM_OLD_PSW + +1: lpsw disabled_wait_psw-0b(%r13) + .globl s390_reset_pgm_handler +s390_reset_pgm_handler: + .long 0 +disabled_wait_psw: + .align 8 + .long 0x000a0000,0x00000000 + reset_pgm_handler + #endif /* CONFIG_64BIT */ diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig index a69856263009..79e54894529d 100644 --- a/arch/sparc/defconfig +++ b/arch/sparc/defconfig @@ -1,41 +1,59 @@ # # Automatically generated make config: don't edit +# Linux kernel version: 2.6.20-rc1 +# Sun Dec 17 14:20:47 2006 # CONFIG_MMU=y -CONFIG_UID16=y CONFIG_HIGHMEM=y CONFIG_GENERIC_ISA_DMA=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_STANDALONE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_HOTPLUG is not set # CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support @@ -43,17 +61,36 @@ CONFIG_IOSCHED_CFQ=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y # -# General setup +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# General machine setup # -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y # CONFIG_SMP is not set +CONFIG_SPARC=y CONFIG_SPARC32=y CONFIG_SBUS=y CONFIG_SBUSCHAR=y @@ -61,73 +98,170 @@ CONFIG_SERIAL_CONSOLE=y CONFIG_SUN_AUXIO=y CONFIG_SUN_IO=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_SUN_PM=y # CONFIG_SUN4 is not set CONFIG_PCI=y -# CONFIG_PCI_LEGACY_PROC is not set -# CONFIG_PCI_NAMES is not set +# CONFIG_PCI_MULTITHREAD_PROBE is not set +# CONFIG_PCI_DEBUG is not set CONFIG_SUN_OPENPROMFS=m +# CONFIG_SPARC_LED is not set CONFIG_BINFMT_ELF=y CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_MISC=m CONFIG_SUNOS_EMUL=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set # -# Parallel port support +# Networking # -# CONFIG_PARPORT is not set +CONFIG_NET=y # -# Generic Driver Options +# Networking options # -# CONFIG_DEBUG_DRIVER is not set +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_NET_KEY=m +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set # -# Graphics support +# DCCP Configuration (EXPERIMENTAL) # -# CONFIG_FB is not set +# CONFIG_IP_DCCP is not set # -# Console display driver support +# SCTP Configuration (EXPERIMENTAL) # -# CONFIG_MDA_CONSOLE is not set -# CONFIG_PROM_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +CONFIG_SCTP_DBG_OBJCNT=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y # -# Memory Technology Devices (MTD) +# TIPC Configuration (EXPERIMENTAL) # -# CONFIG_MTD is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set # -# Serial drivers +# QoS and/or fair queueing # -# CONFIG_SERIAL_8250 is not set +# CONFIG_NET_SCHED is not set # -# Non-8250 serial port support +# Network testing # -CONFIG_SERIAL_SUNCORE=y -CONFIG_SERIAL_SUNZILOG=y -CONFIG_SERIAL_SUNZILOG_CONSOLE=y -CONFIG_SERIAL_SUNSU=y -CONFIG_SERIAL_SUNSU_CONSOLE=y -# CONFIG_SERIAL_SUNSAB is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_NET_PKTGEN=m +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set # -# Misc Linux/SPARC drivers +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support # -CONFIG_SUN_OPENPROMIO=m -CONFIG_SUN_MOSTEK_RTC=m -# CONFIG_SUN_BPP is not set -# CONFIG_SUN_VIDEOPIX is not set -# CONFIG_SUN_AURORA is not set -# CONFIG_TADPOLE_TS102_UCTRL is not set -# CONFIG_SUN_JSFLASH is not set -CONFIG_APM_RTC_IS_GMT=y -CONFIG_RTC=m # # Block devices @@ -137,28 +271,37 @@ CONFIG_RTC=m # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_CRYPTOLOOP=m # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_CARMEL is not set +# CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set # -# ATA/ATAPI/MFM/RLL support +# Misc devices # -# CONFIG_IDE is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set # -# ISDN subsystem +# ATA/ATAPI/MFM/RLL support # -# CONFIG_ISDN is not set +# CONFIG_IDE is not set # # SCSI device support # +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y # @@ -170,6 +313,7 @@ CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=m # CONFIG_BLK_DEV_SR_VENDOR is not set CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -177,57 +321,58 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_MULTI_LUN is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set # -# SCSI Transport Attributes +# SCSI Transports # CONFIG_SCSI_SPI_ATTRS=m # CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers # +# CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set # CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLOGICPTI=m -CONFIG_SCSI_QLA2XXX=y -# CONFIG_SCSI_QLA21XX is not set -# CONFIG_SCSI_QLA22XX is not set -# CONFIG_SCSI_QLA2300 is not set -# CONFIG_SCSI_QLA2322 is not set -# CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set CONFIG_SCSI_SUNESP=y +# CONFIG_SCSI_SRP is not set # -# Fibre Channel support +# Serial ATA (prod) and Parallel ATA (experimental) drivers # -# CONFIG_FC4 is not set +# CONFIG_ATA is not set # # Multi-device support (RAID and LVM) @@ -235,85 +380,31 @@ CONFIG_SCSI_SUNESP=y # CONFIG_MD is not set # -# Networking support -# -CONFIG_NET=y - -# -# Networking options +# Fusion MPT device support # -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK_DEV=y -CONFIG_UNIX=y -CONFIG_NET_KEY=m -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -CONFIG_IPV6=m -CONFIG_IPV6_PRIVACY=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_TUNNEL=m -# CONFIG_NETFILTER is not set -CONFIG_XFRM=y -CONFIG_XFRM_USER=m +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set # -# SCTP Configuration (EXPERIMENTAL) +# IEEE 1394 (FireWire) support # -CONFIG_IP_SCTP=m -# CONFIG_SCTP_DBG_MSG is not set -CONFIG_SCTP_DBG_OBJCNT=y -# CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_HW_FLOWCONTROL is not set +# CONFIG_IEEE1394 is not set # -# QoS and/or fair queueing +# I2O device support # -# CONFIG_NET_SCHED is not set +# CONFIG_I2O is not set # -# Network testing +# Network device support # -CONFIG_NET_PKTGEN=m -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set CONFIG_NETDEVICES=y CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set CONFIG_TUN=m -# CONFIG_ETHERTAP is not set # # ARCnet devices @@ -321,6 +412,11 @@ CONFIG_TUN=m # CONFIG_ARCNET is not set # +# PHY device support +# +# CONFIG_PHYLIB is not set + +# # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y @@ -330,6 +426,7 @@ CONFIG_HAPPYMEAL=m CONFIG_SUNBMAC=m CONFIG_SUNQE=m # CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # @@ -350,14 +447,22 @@ CONFIG_SUNQE=m # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -380,17 +485,24 @@ CONFIG_SUNQE=m # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # -# Unix98 PTY support +# ISDN subsystem # -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set # # Input device support # CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -405,17 +517,6 @@ CONFIG_INPUT_EVDEV=m CONFIG_INPUT_EVBUG=m # -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=m -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=m -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PCIPS2 is not set - -# # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y @@ -424,6 +525,7 @@ CONFIG_KEYBOARD_SUNKBD=m # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=m CONFIG_MOUSE_SERIAL=m @@ -433,29 +535,239 @@ CONFIG_MOUSE_SERIAL=m # CONFIG_INPUT_MISC is not set # +# Hardware I/O ports +# +CONFIG_SERIO=m +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=m +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=m +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SUNCORE=y +CONFIG_SERIAL_SUNZILOG=y +CONFIG_SERIAL_SUNZILOG_CONSOLE=y +CONFIG_SERIAL_SUNSU=y +CONFIG_SERIAL_SUNSU_CONSOLE=y +# CONFIG_SERIAL_SUNSAB is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=m +CONFIG_RTC=m +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_PROM_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# HID Devices +# +CONFIG_HID=y + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Virtualization +# + +# +# Misc Linux/SPARC drivers +# +CONFIG_SUN_OPENPROMIO=m +CONFIG_SUN_MOSTEK_RTC=m +# CONFIG_SUN_BPP is not set +# CONFIG_SUN_VIDEOPIX is not set +# CONFIG_TADPOLE_TS102_UCTRL is not set +# CONFIG_SUN_JSFLASH is not set + +# +# Unix98 PTY support +# +CONFIG_UNIX98_PTY_COUNT=256 + +# # File systems # CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m -CONFIG_XFS_RT=y CONFIG_XFS_QUOTA=y CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=m +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_QUOTACTL=y +CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -468,7 +780,8 @@ CONFIG_ISO9660_FS=m # # DOS/FAT/NT Filesystems # -# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set # CONFIG_NTFS_FS is not set # @@ -476,13 +789,12 @@ CONFIG_ISO9660_FS=m # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -CONFIG_DEVPTS_FS_XATTR=y -# CONFIG_DEVPTS_FS_SECURITY is not set # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -512,17 +824,23 @@ CONFIG_NFS_FS=y # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y -# CONFIG_EXPORTFS is not set +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set CONFIG_AFS_FS=m CONFIG_RXRPC=m +# CONFIG_9P_FS is not set # # Partition Types @@ -559,6 +877,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set # CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set @@ -575,70 +894,104 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_UTF8 is not set # -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support +# Distributed Lock Manager # -# CONFIG_USB is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set +# CONFIG_DLM is not set # -# Watchdog Cards +# Instrumentation Support # -# CONFIG_WATCHDOG is not set +# CONFIG_PROFILING is not set # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_DEBUG_STACK_USAGE is not set # # Security options # +# CONFIG_KEYS is not set # CONFIG_SECURITY is not set # # Cryptographic options # CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_LRW is not set CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m +# CONFIG_CRYPTO_TEA is not set CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set # +# Hardware crypto devices +# + +# # Library routines # +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set CONFIG_CRC32=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_IOMAP_COPY=y diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 33dadd9f2871..d8e008a04e2b 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -83,9 +83,6 @@ extern int __divdi3(int, int); /* Private functions with odd calling conventions. */ extern void ___atomic24_add(void); extern void ___atomic24_sub(void); -extern void ___set_bit(void); -extern void ___clear_bit(void); -extern void ___change_bit(void); extern void ___rw_read_enter(void); extern void ___rw_read_try(void); extern void ___rw_read_exit(void); @@ -125,11 +122,6 @@ EXPORT_SYMBOL(pfn_base); EXPORT_SYMBOL(___atomic24_add); EXPORT_SYMBOL(___atomic24_sub); -/* Bit operations. */ -EXPORT_SYMBOL(___set_bit); -EXPORT_SYMBOL(___clear_bit); -EXPORT_SYMBOL(___change_bit); - /* Per-CPU information table */ EXPORT_PER_CPU_SYMBOL(__cpu_data); diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 6c7aa51b590f..2fcce000d877 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -78,7 +78,6 @@ unsigned long profile_pc(struct pt_regs *regs) extern char __copy_user_begin[], __copy_user_end[]; extern char __atomic_begin[], __atomic_end[]; extern char __bzero_begin[], __bzero_end[]; - extern char __bitops_begin[], __bitops_end[]; unsigned long pc = regs->pc; @@ -88,9 +87,7 @@ unsigned long profile_pc(struct pt_regs *regs) (pc >= (unsigned long) __atomic_begin && pc < (unsigned long) __atomic_end) || (pc >= (unsigned long) __bzero_begin && - pc < (unsigned long) __bzero_end) || - (pc >= (unsigned long) __bitops_begin && - pc < (unsigned long) __bitops_end)) + pc < (unsigned long) __bzero_end)) pc = regs->u_regs[UREG_RETPC]; return pc; } diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index 5db7e1d85385..9ddc5b9ce3bd 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -7,7 +7,7 @@ EXTRA_AFLAGS := -ansi -DST_DIV0=0x02 lib-y := mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o memcpy.o memset.o \ strlen.o checksum.o blockops.o memscan.o memcmp.o strncmp.o \ strncpy_from_user.o divdi3.o udivdi3.o strlen_user.o \ - copy_user.o locks.o atomic.o atomic32.o bitops.o \ + copy_user.o locks.o atomic.o \ lshrdi3.o ashldi3.o rwsem.o muldi3.o bitext.o -obj-y += iomap.o +obj-y += iomap.o atomic32.o diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c index de84f8534bac..53ddcd9d1e60 100644 --- a/arch/sparc/lib/atomic32.c +++ b/arch/sparc/lib/atomic32.c @@ -76,3 +76,42 @@ void atomic_set(atomic_t *v, int i) spin_unlock_irqrestore(ATOMIC_HASH(v), flags); } EXPORT_SYMBOL(atomic_set); + +unsigned long ___set_bit(unsigned long *addr, unsigned long mask) +{ + unsigned long old, flags; + + spin_lock_irqsave(ATOMIC_HASH(addr), flags); + old = *addr; + *addr = old | mask; + spin_unlock_irqrestore(ATOMIC_HASH(addr), flags); + + return old & mask; +} +EXPORT_SYMBOL(___set_bit); + +unsigned long ___clear_bit(unsigned long *addr, unsigned long mask) +{ + unsigned long old, flags; + + spin_lock_irqsave(ATOMIC_HASH(addr), flags); + old = *addr; + *addr = old & ~mask; + spin_unlock_irqrestore(ATOMIC_HASH(addr), flags); + + return old & mask; +} +EXPORT_SYMBOL(___clear_bit); + +unsigned long ___change_bit(unsigned long *addr, unsigned long mask) +{ + unsigned long old, flags; + + spin_lock_irqsave(ATOMIC_HASH(addr), flags); + old = *addr; + *addr = old ^ mask; + spin_unlock_irqrestore(ATOMIC_HASH(addr), flags); + + return old & mask; +} +EXPORT_SYMBOL(___change_bit); diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S deleted file mode 100644 index cb7fb66a40c8..000000000000 --- a/arch/sparc/lib/bitops.S +++ /dev/null @@ -1,109 +0,0 @@ -/* bitops.S: Low level assembler bit operations. - * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) - */ - -#include <asm/ptrace.h> -#include <asm/psr.h> - - .text - .align 4 - - .globl __bitops_begin -__bitops_begin: - - /* Take bits in %g2 and set them in word at %g1, - * return whether bits were set in original value - * in %g2. %g4 holds value to restore into %o7 - * in delay slot of jmpl return, %g3 + %g5 + %g7 can be - * used as temporaries and thus is considered clobbered - * by all callers. - */ - .globl ___set_bit -___set_bit: - rd %psr, %g3 - nop; nop; nop; - or %g3, PSR_PIL, %g5 - wr %g5, 0x0, %psr - nop; nop; nop -#ifdef CONFIG_SMP - set bitops_spinlock, %g5 -2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP. - orcc %g7, 0x0, %g0 ! Did we get it? - bne 2b ! Nope... -#endif - ld [%g1], %g7 - or %g7, %g2, %g5 - and %g7, %g2, %g2 -#ifdef CONFIG_SMP - st %g5, [%g1] - set bitops_spinlock, %g5 - stb %g0, [%g5] -#else - st %g5, [%g1] -#endif - wr %g3, 0x0, %psr - nop; nop; nop - jmpl %o7, %g0 - mov %g4, %o7 - - /* Same as above, but clears the bits from %g2 instead. */ - .globl ___clear_bit -___clear_bit: - rd %psr, %g3 - nop; nop; nop - or %g3, PSR_PIL, %g5 - wr %g5, 0x0, %psr - nop; nop; nop -#ifdef CONFIG_SMP - set bitops_spinlock, %g5 -2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP. - orcc %g7, 0x0, %g0 ! Did we get it? - bne 2b ! Nope... -#endif - ld [%g1], %g7 - andn %g7, %g2, %g5 - and %g7, %g2, %g2 -#ifdef CONFIG_SMP - st %g5, [%g1] - set bitops_spinlock, %g5 - stb %g0, [%g5] -#else - st %g5, [%g1] -#endif - wr %g3, 0x0, %psr - nop; nop; nop - jmpl %o7, %g0 - mov %g4, %o7 - - /* Same thing again, but this time toggles the bits from %g2. */ - .globl ___change_bit -___change_bit: - rd %psr, %g3 - nop; nop; nop - or %g3, PSR_PIL, %g5 - wr %g5, 0x0, %psr - nop; nop; nop -#ifdef CONFIG_SMP - set bitops_spinlock, %g5 -2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP. - orcc %g7, 0x0, %g0 ! Did we get it? - bne 2b ! Nope... -#endif - ld [%g1], %g7 - xor %g7, %g2, %g5 - and %g7, %g2, %g2 -#ifdef CONFIG_SMP - st %g5, [%g1] - set bitops_spinlock, %g5 - stb %g0, [%g5] -#else - st %g5, [%g1] -#endif - wr %g3, 0x0, %psr - nop; nop; nop - jmpl %o7, %g0 - mov %g4, %o7 - - .globl __bitops_end -__bitops_end: diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index 03ffaf895a22..baea10a98196 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S @@ -78,11 +78,7 @@ sparc_ramdisk_image64: /* PROM cif handler code address is in %o4. */ sparc64_boot: -1: rd %pc, %g7 - set 1b, %g1 - cmp %g1, %g7 - be,pn %xcc, sparc64_boot_after_remap - mov %o4, %l7 + mov %o4, %l7 /* We need to remap the kernel. Use position independant * code to remap us to KERNBASE. @@ -295,7 +291,6 @@ is_sun4v: add %sp, (192 + 128), %sp -sparc64_boot_after_remap: sethi %hi(prom_root_compatible), %g1 or %g1, %lo(prom_root_compatible), %g1 sethi %hi(prom_sun4v_name), %g7 diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index d64b1ea848de..c3d068c7a412 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -372,14 +372,14 @@ static void run_pre_handler(unsigned int virt_irq) } } -static struct hw_interrupt_type sun4u_irq = { +static struct irq_chip sun4u_irq = { .typename = "sun4u", .enable = sun4u_irq_enable, .disable = sun4u_irq_disable, .end = sun4u_irq_end, }; -static struct hw_interrupt_type sun4u_irq_ack = { +static struct irq_chip sun4u_irq_ack = { .typename = "sun4u+ack", .enable = sun4u_irq_enable, .disable = sun4u_irq_disable, @@ -387,14 +387,14 @@ static struct hw_interrupt_type sun4u_irq_ack = { .end = sun4u_irq_end, }; -static struct hw_interrupt_type sun4v_irq = { +static struct irq_chip sun4v_irq = { .typename = "sun4v", .enable = sun4v_irq_enable, .disable = sun4v_irq_disable, .end = sun4v_irq_end, }; -static struct hw_interrupt_type sun4v_irq_ack = { +static struct irq_chip sun4v_irq_ack = { .typename = "sun4v+ack", .enable = sun4v_irq_enable, .disable = sun4v_irq_disable, @@ -493,22 +493,6 @@ out: return bucket->virt_irq; } -void hw_resend_irq(struct hw_interrupt_type *handler, unsigned int virt_irq) -{ - struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); - unsigned long pstate; - unsigned int *ent; - - __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); - __asm__ __volatile__("wrpr %0, %1, %%pstate" - : : "r" (pstate), "i" (PSTATE_IE)); - ent = irq_work(smp_processor_id()); - bucket->irq_chain = *ent; - *ent = __irq(bucket); - set_softint(1 << PIL_DEVICE_IRQ); - __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); -} - void ack_bad_irq(unsigned int virt_irq) { struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index cc09d8266414..0a4958536bcd 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -1447,11 +1447,8 @@ void __init setup_per_cpu_areas(void) char *ptr; /* Copy section for each CPU (we discard the original) */ - goal = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); -#ifdef CONFIG_MODULES - if (goal < PERCPU_ENOUGH_ROOM) - goal = PERCPU_ENOUGH_ROOM; -#endif + goal = PERCPU_ENOUGH_ROOM; + __per_cpu_shift = 0; for (size = 1UL; size < goal; size <<= 1UL) __per_cpu_shift++; diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index b471b8550d03..2941a915d4ef 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -45,9 +45,7 @@ cflags-kernel-$(CONFIG_REORDER) += -ffunction-sections # actually it makes the kernel smaller too. cflags-y += -fno-reorder-blocks cflags-y += -Wno-sign-compare -ifneq ($(CONFIG_UNWIND_INFO),y) cflags-y += -fno-asynchronous-unwind-tables -endif ifneq ($(CONFIG_DEBUG_INFO),y) # -fweb shrinks the kernel a bit, but the difference is very small # it also messes up debugging, so don't use it for now. diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 1a1c6a1a299b..ac80b1209fc0 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig @@ -1523,8 +1523,6 @@ CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_FRAME_POINTER is not set -CONFIG_UNWIND_INFO=y -CONFIG_STACK_UNWIND=y # CONFIG_FORCED_INLINING is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 601d332c4b79..9f5dac64aa8f 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -1155,36 +1155,3 @@ ENTRY(call_softirq) ret CFI_ENDPROC ENDPROC(call_softirq) - -#ifdef CONFIG_STACK_UNWIND -ENTRY(arch_unwind_init_running) - CFI_STARTPROC - movq %r15, R15(%rdi) - movq %r14, R14(%rdi) - xchgq %rsi, %rdx - movq %r13, R13(%rdi) - movq %r12, R12(%rdi) - xorl %eax, %eax - movq %rbp, RBP(%rdi) - movq %rbx, RBX(%rdi) - movq (%rsp), %rcx - movq %rax, R11(%rdi) - movq %rax, R10(%rdi) - movq %rax, R9(%rdi) - movq %rax, R8(%rdi) - movq %rax, RAX(%rdi) - movq %rax, RCX(%rdi) - movq %rax, RDX(%rdi) - movq %rax, RSI(%rdi) - movq %rax, RDI(%rdi) - movq %rax, ORIG_RAX(%rdi) - movq %rcx, RIP(%rdi) - leaq 8(%rsp), %rcx - movq $__KERNEL_CS, CS(%rdi) - movq %rax, EFLAGS(%rdi) - movq %rcx, RSP(%rdi) - movq $__KERNEL_DS, SS(%rdi) - jmpq *%rdx - CFI_ENDPROC -ENDPROC(arch_unwind_init_running) -#endif diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index b54ccc07f379..1d9eb6db732a 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -110,11 +110,6 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) } int kstack_depth_to_print = 12; -#ifdef CONFIG_STACK_UNWIND -static int call_trace = 1; -#else -#define call_trace (-1) -#endif #ifdef CONFIG_KALLSYMS void printk_address(unsigned long address) @@ -217,32 +212,6 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, return NULL; } -struct ops_and_data { - struct stacktrace_ops *ops; - void *data; -}; - -static int dump_trace_unwind(struct unwind_frame_info *info, void *context) -{ - struct ops_and_data *oad = (struct ops_and_data *)context; - int n = 0; - unsigned long sp = UNW_SP(info); - - if (arch_unw_user_mode(info)) - return -1; - while (unwind(info) == 0 && UNW_PC(info)) { - n++; - oad->ops->address(oad->data, UNW_PC(info)); - if (arch_unw_user_mode(info)) - break; - if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) - && sp > UNW_SP(info)) - break; - sp = UNW_SP(info); - } - return n; -} - #define MSG(txt) ops->warning(data, txt) /* @@ -270,40 +239,6 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, if (!tsk) tsk = current; - if (call_trace >= 0) { - int unw_ret = 0; - struct unwind_frame_info info; - struct ops_and_data oad = { .ops = ops, .data = data }; - - if (regs) { - if (unwind_init_frame_info(&info, tsk, regs) == 0) - unw_ret = dump_trace_unwind(&info, &oad); - } else if (tsk == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, - &oad); - else { - if (unwind_init_blocked(&info, tsk) == 0) - unw_ret = dump_trace_unwind(&info, &oad); - } - if (unw_ret > 0) { - if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, - "DWARF2 unwinder stuck at %s", - UNW_PC(&info)); - if ((long)UNW_SP(&info) < 0) { - MSG("Leftover inexact backtrace:"); - stack = (unsigned long *)UNW_SP(&info); - if (!stack) - goto out; - } else - MSG("Full inexact backtrace again:"); - } else if (call_trace >= 1) - goto out; - else - MSG("Full inexact backtrace again:"); - } else - MSG("Inexact backtrace:"); - } if (!stack) { unsigned long dummy; stack = &dummy; @@ -387,7 +322,6 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, tinfo = current_thread_info(); HANDLE_STACK (valid_stack_ptr(tinfo, stack)); #undef HANDLE_STACK -out: put_cpu(); } EXPORT_SYMBOL(dump_trace); @@ -1188,21 +1122,3 @@ static int __init kstack_setup(char *s) return 0; } early_param("kstack", kstack_setup); - -#ifdef CONFIG_STACK_UNWIND -static int __init call_trace_setup(char *s) -{ - if (!s) - return -EINVAL; - if (strcmp(s, "old") == 0) - call_trace = -1; - else if (strcmp(s, "both") == 0) - call_trace = 0; - else if (strcmp(s, "newfallback") == 0) - call_trace = 1; - else if (strcmp(s, "new") == 0) - call_trace = 2; - return 0; -} -early_param("call_trace", call_trace_setup); -#endif diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 514be5dd2303..1e54ddf2338d 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -221,9 +221,7 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { *(.exitcall.exit) -#ifndef CONFIG_UNWIND_INFO *(.eh_frame) -#endif } STABS_DEBUG diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 984ab284382a..b34e0a958d0f 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -40,9 +40,9 @@ config ATA_PIIX tristate "Intel PIIX/ICH SATA support" depends on PCI help - This option enables support for ICH5/6/7/8 Serial ATA. - If PATA support was enabled previously, this enables - support for select Intel PIIX/ICH PATA host controllers. + This option enables support for ICH5/6/7/8 Serial ATA + and support for PATA on the Intel PIIX3/PIIX4/ICH series + PATA host controllers. If unsure, say N. diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index f36da488a2c1..dbae6d971041 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -645,8 +645,6 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) u32 cap_save, impl_save, tmp; cap_save = readl(mmio + HOST_CAP); - cap_save &= ( (1<<28) | (1<<17) ); - cap_save |= (1 << 27); impl_save = readl(mmio + HOST_PORTS_IMPL); /* global controller reset */ diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index c7de0bb1591f..47701b286f8b 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -226,14 +226,26 @@ static const struct pci_device_id piix_pci_tbl[] = { { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, /* 2801GBM/GHM (ICH7M, identical to ICH6M) */ { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci }, - /* Enterprise Southbridge 2 (where's the datasheet?) */ + /* Enterprise Southbridge 2 (631xESB/632xESB) */ { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci }, - /* SATA Controller 1 IDE (ICH8, no datasheet yet) */ + /* SATA Controller 1 IDE (ICH8) */ { 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, - /* SATA Controller 2 IDE (ICH8, ditto) */ + /* SATA Controller 2 IDE (ICH8) */ { 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, - /* Mobile SATA Controller IDE (ICH8M, ditto) */ + /* Mobile SATA Controller IDE (ICH8M) */ { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, + /* SATA Controller IDE (ICH9) */ + { 0x8086, 0x2920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, + /* SATA Controller IDE (ICH9) */ + { 0x8086, 0x2921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, + /* SATA Controller IDE (ICH9) */ + { 0x8086, 0x2926, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, + /* SATA Controller IDE (ICH9M) */ + { 0x8086, 0x2928, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, + /* SATA Controller IDE (ICH9M) */ + { 0x8086, 0x292d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, + /* SATA Controller IDE (ICH9M) */ + { 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, { } /* terminate list */ }; @@ -330,7 +342,7 @@ static const struct ata_port_operations ich_pata_ops = { .port_start = ata_port_start, .port_stop = ata_port_stop, - .host_stop = ata_host_stop, + .host_stop = piix_host_stop, }; static const struct ata_port_operations piix_sata_ops = { diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 011c0a8a2dcc..0d51d13b16bf 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1332,7 +1332,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, } /** - * ata_exec_internal_sg - execute libata internal command + * ata_exec_internal - execute libata internal command * @dev: Device to which the command is sent * @tf: Taskfile registers for the command and the result * @cdb: CDB for packet command @@ -1353,11 +1353,17 @@ unsigned ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf, const u8 *cdb, int dma_dir, void *buf, unsigned int buflen) { - struct scatterlist sg; + struct scatterlist *psg = NULL, sg; + unsigned int n_elem = 0; - sg_init_one(&sg, buf, buflen); + if (dma_dir != DMA_NONE) { + WARN_ON(!buf); + sg_init_one(&sg, buf, buflen); + psg = &sg; + n_elem++; + } - return ata_exec_internal_sg(dev, tf, cdb, dma_dir, &sg, 1); + return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem); } /** diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 664e1377b54c..a4790be41d1c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1539,7 +1539,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out) struct scatterlist *sg; sg = (struct scatterlist *) cmd->request_buffer; - buf = kmap_atomic(sg->page, KM_USER0) + sg->offset; + buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; buflen = sg->length; } else { buf = cmd->request_buffer; @@ -1567,7 +1567,7 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf) struct scatterlist *sg; sg = (struct scatterlist *) cmd->request_buffer; - kunmap_atomic(buf - sg->offset, KM_USER0); + kunmap_atomic(buf - sg->offset, KM_IRQ0); } } diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index c7d1738e4e69..e7bf9d89c8ee 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -698,8 +698,10 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl goto fail_io; pdev = platform_device_register_simple(DRV_NAME, nr_legacy_host, NULL, 0); - if (pdev == NULL) + if (IS_ERR(pdev)) { + ret = PTR_ERR(pdev); goto fail_dev; + } if (ht6560a & mask) { ops = &ht6560a_port_ops; diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c index 36f621abc390..afc0d990e7d6 100644 --- a/drivers/ata/pata_qdi.c +++ b/drivers/ata/pata_qdi.c @@ -247,8 +247,8 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i */ pdev = platform_device_register_simple(DRV_NAME, nr_qdi_host, NULL, 0); - if (pdev == NULL) - return -ENOMEM; + if (IS_ERR(pdev)) + return PTR_ERR(pdev); memset(&ae, 0, sizeof(struct ata_probe_ent)); INIT_LIST_HEAD(&ae.node); diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index 3677c642c9f9..adf4cc134f25 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c @@ -105,8 +105,6 @@ static struct ata_port_operations rz1000_port_ops = { .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, - .error_handler = rz1000_error_handler, - .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index cc09d47fb927..ff93e8f71cf8 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -161,10 +161,15 @@ static int via_pre_reset(struct ata_port *ap) return -ENOENT; } - if ((config->flags & VIA_UDMA) >= VIA_UDMA_66) + if ((config->flags & VIA_UDMA) >= VIA_UDMA_100) ap->cbl = via_cable_detect(ap); - else + /* The UDMA66 series has no cable detect so do drive side detect */ + else if ((config->flags & VIA_UDMA) < VIA_UDMA_66) ap->cbl = ATA_CBL_PATA40; + else + ap->cbl = ATA_CBL_PATA_UNK; + + return ata_std_prereset(ap); } diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c index 3ea345cde52e..5d1f518e1cc7 100644 --- a/drivers/ata/pata_winbond.c +++ b/drivers/ata/pata_winbond.c @@ -206,8 +206,8 @@ static __init int winbond_init_one(unsigned long port) */ pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0); - if (pdev == NULL) - return -ENOMEM; + if (IS_ERR(pdev)) + return PTR_ERR(pdev); memset(&ae, 0, sizeof(struct ata_probe_ent)); INIT_LIST_HEAD(&ae.node); diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index db32d15b7fa1..d89c9590b845 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -56,6 +56,8 @@ #define DRV_VERSION "2.0" enum { + K2_FLAG_NO_ATAPI_DMA = (1 << 29), + /* Taskfile registers offsets */ K2_SATA_TF_CMD_OFFSET = 0x00, K2_SATA_TF_DATA_OFFSET = 0x00, @@ -83,11 +85,33 @@ enum { /* Port stride */ K2_SATA_PORT_OFFSET = 0x100, + + board_svw4 = 0, + board_svw8 = 1, +}; + +static const struct k2_board_info { + unsigned int n_ports; + unsigned long port_flags; +} k2_board_info[] = { + /* board_svw4 */ + { 4, K2_FLAG_NO_ATAPI_DMA }, + + /* board_svw8 */ + { 8, K2_FLAG_NO_ATAPI_DMA }, }; static u8 k2_stat_check_status(struct ata_port *ap); +static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) +{ + if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA) + return -1; /* ATAPI DMA not supported */ + + return 0; +} + static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) @@ -313,6 +337,7 @@ static const struct ata_port_operations k2_sata_ops = { .check_status = k2_stat_check_status, .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, + .check_atapi_dma = k2_sata_check_atapi_dma, .bmdma_setup = k2_bmdma_setup_mmio, .bmdma_start = k2_bmdma_start_mmio, .bmdma_stop = ata_bmdma_stop, @@ -359,6 +384,8 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e struct ata_probe_ent *probe_ent = NULL; unsigned long base; void __iomem *mmio_base; + const struct k2_board_info *board_info = + &k2_board_info[ent->driver_data]; int pci_dev_busy = 0; int rc; int i; @@ -424,7 +451,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e probe_ent->sht = &k2_sata_sht; probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO; + ATA_FLAG_MMIO | board_info->port_flags; probe_ent->port_ops = &k2_sata_ops; probe_ent->n_ports = 4; probe_ent->irq = pdev->irq; @@ -441,7 +468,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e /* different controllers have different number of ports - currently 4 or 8 */ /* All ports are on the same function. Multi-function device is no * longer available. This should not be seen in any system. */ - for (i = 0; i < ent->driver_data; i++) + for (i = 0; i < board_info->n_ports; i++) k2_sata_setup_port(&probe_ent->port[i], base + i * K2_SATA_PORT_OFFSET); pci_set_master(pdev); @@ -469,11 +496,11 @@ err_out: * controller * */ static const struct pci_device_id k2_sata_pci_tbl[] = { - { PCI_VDEVICE(SERVERWORKS, 0x0240), 4 }, - { PCI_VDEVICE(SERVERWORKS, 0x0241), 4 }, - { PCI_VDEVICE(SERVERWORKS, 0x0242), 8 }, - { PCI_VDEVICE(SERVERWORKS, 0x024a), 4 }, - { PCI_VDEVICE(SERVERWORKS, 0x024b), 4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 }, + { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 }, { } }; diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index b418b16e910e..296f51002b55 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c @@ -34,7 +34,7 @@ void cn_queue_wrapper(struct work_struct *work) { struct cn_callback_entry *cbq = - container_of(work, struct cn_callback_entry, work.work); + container_of(work, struct cn_callback_entry, work); struct cn_callback_data *d = &cbq->data; d->callback(d->callback_priv); @@ -59,13 +59,12 @@ static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struc memcpy(&cbq->id.id, id, sizeof(struct cb_id)); cbq->data.callback = callback; - INIT_DELAYED_WORK(&cbq->work, &cn_queue_wrapper); + INIT_WORK(&cbq->work, &cn_queue_wrapper); return cbq; } static void cn_queue_free_callback(struct cn_callback_entry *cbq) { - cancel_delayed_work(&cbq->work); flush_workqueue(cbq->pdev->cn_queue); kfree(cbq); diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index 5e7cd45d10ee..a44db75bc25b 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -135,17 +135,15 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v spin_lock_bh(&dev->cbdev->queue_lock); list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) { if (cn_cb_equal(&__cbq->id.id, &msg->id)) { - if (likely(!test_bit(WORK_STRUCT_PENDING, - &__cbq->work.work.management) && + if (likely(!work_pending(&__cbq->work) && __cbq->data.ddata == NULL)) { __cbq->data.callback_priv = msg; __cbq->data.ddata = data; __cbq->data.destruct_data = destruct_data; - if (queue_delayed_work( - dev->cbdev->cn_queue, - &__cbq->work, 0)) + if (queue_work(dev->cbdev->cn_queue, + &__cbq->work)) err = 0; } else { struct cn_callback_data *d; @@ -159,12 +157,11 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v d->destruct_data = destruct_data; d->free = __cbq; - INIT_DELAYED_WORK(&__cbq->work, - &cn_queue_wrapper); + INIT_WORK(&__cbq->work, + &cn_queue_wrapper); - if (queue_delayed_work( - dev->cbdev->cn_queue, - &__cbq->work, 0)) + if (queue_work(dev->cbdev->cn_queue, + &__cbq->work)) err = 0; else { kfree(__cbq); diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 9fb2edf36611..d91330432ba2 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -959,7 +959,7 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, /** - * cpufreq_quick_get - get the CPU frequency (in kHz) frpm policy->cur + * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur * @cpu: CPU number * * This is the last known freq, without actually getting it from the driver. diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 0491ec7a7c0a..44bc6cc734ab 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c @@ -80,24 +80,61 @@ static int tune_pci = 0; module_param(tune_pci, int, 0444); MODULE_PARM_DESC(tune_pci, "increase PCI burst from the default set by BIOS if nonzero"); -struct mutex mthca_device_mutex; +DEFINE_MUTEX(mthca_device_mutex); + +#define MTHCA_DEFAULT_NUM_QP (1 << 16) +#define MTHCA_DEFAULT_RDB_PER_QP (1 << 2) +#define MTHCA_DEFAULT_NUM_CQ (1 << 16) +#define MTHCA_DEFAULT_NUM_MCG (1 << 13) +#define MTHCA_DEFAULT_NUM_MPT (1 << 17) +#define MTHCA_DEFAULT_NUM_MTT (1 << 20) +#define MTHCA_DEFAULT_NUM_UDAV (1 << 15) +#define MTHCA_DEFAULT_NUM_RESERVED_MTTS (1 << 18) +#define MTHCA_DEFAULT_NUM_UARC_SIZE (1 << 18) + +static struct mthca_profile hca_profile = { + .num_qp = MTHCA_DEFAULT_NUM_QP, + .rdb_per_qp = MTHCA_DEFAULT_RDB_PER_QP, + .num_cq = MTHCA_DEFAULT_NUM_CQ, + .num_mcg = MTHCA_DEFAULT_NUM_MCG, + .num_mpt = MTHCA_DEFAULT_NUM_MPT, + .num_mtt = MTHCA_DEFAULT_NUM_MTT, + .num_udav = MTHCA_DEFAULT_NUM_UDAV, /* Tavor only */ + .fmr_reserved_mtts = MTHCA_DEFAULT_NUM_RESERVED_MTTS, /* Tavor only */ + .uarc_size = MTHCA_DEFAULT_NUM_UARC_SIZE, /* Arbel only */ +}; + +module_param_named(num_qp, hca_profile.num_qp, int, 0444); +MODULE_PARM_DESC(num_qp, "maximum number of QPs per HCA"); + +module_param_named(rdb_per_qp, hca_profile.rdb_per_qp, int, 0444); +MODULE_PARM_DESC(rdb_per_qp, "number of RDB buffers per QP"); + +module_param_named(num_cq, hca_profile.num_cq, int, 0444); +MODULE_PARM_DESC(num_cq, "maximum number of CQs per HCA"); + +module_param_named(num_mcg, hca_profile.num_mcg, int, 0444); +MODULE_PARM_DESC(num_mcg, "maximum number of multicast groups per HCA"); + +module_param_named(num_mpt, hca_profile.num_mpt, int, 0444); +MODULE_PARM_DESC(num_mpt, + "maximum number of memory protection table entries per HCA"); + +module_param_named(num_mtt, hca_profile.num_mtt, int, 0444); +MODULE_PARM_DESC(num_mtt, + "maximum number of memory translation table segments per HCA"); + +module_param_named(num_udav, hca_profile.num_udav, int, 0444); +MODULE_PARM_DESC(num_udav, "maximum number of UD address vectors per HCA"); + +module_param_named(fmr_reserved_mtts, hca_profile.fmr_reserved_mtts, int, 0444); +MODULE_PARM_DESC(fmr_reserved_mtts, + "number of memory translation table segments reserved for FMR"); static const char mthca_version[] __devinitdata = DRV_NAME ": Mellanox InfiniBand HCA driver v" DRV_VERSION " (" DRV_RELDATE ")\n"; -static struct mthca_profile default_profile = { - .num_qp = 1 << 16, - .rdb_per_qp = 4, - .num_cq = 1 << 16, - .num_mcg = 1 << 13, - .num_mpt = 1 << 17, - .num_mtt = 1 << 20, - .num_udav = 1 << 15, /* Tavor only */ - .fmr_reserved_mtts = 1 << 18, /* Tavor only */ - .uarc_size = 1 << 18, /* Arbel only */ -}; - static int mthca_tune_pci(struct mthca_dev *mdev) { int cap; @@ -303,7 +340,7 @@ static int mthca_init_tavor(struct mthca_dev *mdev) goto err_disable; } - profile = default_profile; + profile = hca_profile; profile.num_uar = dev_lim.uar_size / PAGE_SIZE; profile.uarc_size = 0; if (mdev->mthca_flags & MTHCA_FLAG_SRQ) @@ -621,7 +658,7 @@ static int mthca_init_arbel(struct mthca_dev *mdev) goto err_stop_fw; } - profile = default_profile; + profile = hca_profile; profile.num_uar = dev_lim.uar_size / PAGE_SIZE; profile.num_udav = 0; if (mdev->mthca_flags & MTHCA_FLAG_SRQ) @@ -1278,11 +1315,55 @@ static struct pci_driver mthca_driver = { .remove = __devexit_p(mthca_remove_one) }; +static void __init __mthca_check_profile_val(const char *name, int *pval, + int pval_default) +{ + /* value must be positive and power of 2 */ + int old_pval = *pval; + + if (old_pval <= 0) + *pval = pval_default; + else + *pval = roundup_pow_of_two(old_pval); + + if (old_pval != *pval) { + printk(KERN_WARNING PFX "Invalid value %d for %s in module parameter.\n", + old_pval, name); + printk(KERN_WARNING PFX "Corrected %s to %d.\n", name, *pval); + } +} + +#define mthca_check_profile_val(name, default) \ + __mthca_check_profile_val(#name, &hca_profile.name, default) + +static void __init mthca_validate_profile(void) +{ + mthca_check_profile_val(num_qp, MTHCA_DEFAULT_NUM_QP); + mthca_check_profile_val(rdb_per_qp, MTHCA_DEFAULT_RDB_PER_QP); + mthca_check_profile_val(num_cq, MTHCA_DEFAULT_NUM_CQ); + mthca_check_profile_val(num_mcg, MTHCA_DEFAULT_NUM_MCG); + mthca_check_profile_val(num_mpt, MTHCA_DEFAULT_NUM_MPT); + mthca_check_profile_val(num_mtt, MTHCA_DEFAULT_NUM_MTT); + mthca_check_profile_val(num_udav, MTHCA_DEFAULT_NUM_UDAV); + mthca_check_profile_val(fmr_reserved_mtts, MTHCA_DEFAULT_NUM_RESERVED_MTTS); + + if (hca_profile.fmr_reserved_mtts >= hca_profile.num_mtt) { + printk(KERN_WARNING PFX "Invalid fmr_reserved_mtts module parameter %d.\n", + hca_profile.fmr_reserved_mtts); + printk(KERN_WARNING PFX "(Must be smaller than num_mtt %d)\n", + hca_profile.num_mtt); + hca_profile.fmr_reserved_mtts = hca_profile.num_mtt / 2; + printk(KERN_WARNING PFX "Corrected fmr_reserved_mtts to %d.\n", + hca_profile.fmr_reserved_mtts); + } +} + static int __init mthca_init(void) { int ret; - mutex_init(&mthca_device_mutex); + mthca_validate_profile(); + ret = mthca_catas_init(); if (ret) return ret; diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index e9b6a6f07dd7..cdecbf5911c8 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1898,7 +1898,7 @@ static void srp_add_one(struct ib_device *device) */ srp_dev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1); srp_dev->fmr_page_size = 1 << srp_dev->fmr_page_shift; - srp_dev->fmr_page_mask = ~((unsigned long) srp_dev->fmr_page_size - 1); + srp_dev->fmr_page_mask = ~((u64) srp_dev->fmr_page_size - 1); INIT_LIST_HEAD(&srp_dev->dev_list); diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index 868a540ef7cd..c21772317b86 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h @@ -87,7 +87,7 @@ struct srp_device { struct ib_fmr_pool *fmr_pool; int fmr_page_shift; int fmr_page_size; - unsigned long fmr_page_mask; + u64 fmr_page_mask; }; struct srp_host { diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 16583d71753b..c67e84ec2d6a 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c @@ -187,7 +187,7 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy) static int __init amikbd_init(void) { - int i, j; + int i, j, err; if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) return -ENODEV; diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index 3826db9403e6..cc0238366414 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c @@ -225,7 +225,7 @@ static void sunkbd_reinit(struct work_struct *work) static void sunkbd_enable(struct sunkbd *sunkbd, int enable) { serio_pause_rx(sunkbd->serio); - sunkbd->enabled = 1; + sunkbd->enabled = enable; serio_continue_rx(sunkbd->serio); } diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 7d824cf8ee2d..ada5e9b9988c 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -57,8 +57,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.5.1" -#define DRV_MODULE_RELDATE "November 15, 2006" +#define DRV_MODULE_VERSION "1.5.2" +#define DRV_MODULE_RELDATE "December 13, 2006" #define RUN_AT(x) (jiffies + (x)) @@ -217,9 +217,16 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp) u32 diff; smp_mb(); - diff = TX_RING_IDX(bp->tx_prod) - TX_RING_IDX(bp->tx_cons); - if (diff > MAX_TX_DESC_CNT) - diff = (diff & MAX_TX_DESC_CNT) - 1; + + /* The ring uses 256 indices for 255 entries, one of them + * needs to be skipped. + */ + diff = bp->tx_prod - bp->tx_cons; + if (unlikely(diff >= TX_DESC_CNT)) { + diff &= 0xffff; + if (diff == TX_DESC_CNT) + diff = MAX_TX_DESC_CNT; + } return (bp->tx_ring_size - diff); } @@ -3089,7 +3096,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, if ((align_start = (offset32 & 3))) { offset32 &= ~3; - len32 += align_start; + len32 += (4 - align_start); if ((rc = bnx2_nvram_read(bp, offset32, start, 4))) return rc; } @@ -3107,7 +3114,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, if (align_start || align_end) { buf = kmalloc(len32, GFP_KERNEL); - if (buf == 0) + if (buf == NULL) return -ENOMEM; if (align_start) { memcpy(buf, start, 4); @@ -3998,7 +4005,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) if (!skb) return -ENOMEM; packet = skb_put(skb, pkt_size); - memcpy(packet, bp->mac_addr, 6); + memcpy(packet, bp->dev->dev_addr, 6); memset(packet + 6, 0x0, 8); for (i = 14; i < pkt_size; i++) packet[i] = (unsigned char) (i & 0xff); diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 571320ae87ab..4056ba1ff3c7 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.70" -#define DRV_MODULE_RELDATE "December 1, 2006" +#define DRV_MODULE_VERSION "3.71" +#define DRV_MODULE_RELDATE "December 15, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -959,6 +959,13 @@ static int tg3_phy_reset(struct tg3 *tp) u32 phy_status; int err; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u32 val; + + val = tr32(GRC_MISC_CFG); + tw32_f(GRC_MISC_CFG, val & ~GRC_MISC_CFG_EPHY_IDDQ); + udelay(40); + } err = tg3_readphy(tp, MII_BMSR, &phy_status); err |= tg3_readphy(tp, MII_BMSR, &phy_status); if (err != 0) @@ -1170,7 +1177,15 @@ static void tg3_power_down_phy(struct tg3 *tp) if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) return; - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { + u32 val; + + tg3_bmcr_reset(tp); + val = tr32(GRC_MISC_CFG); + tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ); + udelay(40); + return; + } else { tg3_writephy(tp, MII_TG3_EXT_CTRL, MII_TG3_EXT_CTRL_FORCE_LED_OFF); tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); @@ -4426,7 +4441,7 @@ static void tg3_free_consistent(struct tg3 *tp) */ static int tg3_alloc_consistent(struct tg3 *tp) { - tp->rx_std_buffers = kmalloc((sizeof(struct ring_info) * + tp->rx_std_buffers = kzalloc((sizeof(struct ring_info) * (TG3_RX_RING_SIZE + TG3_RX_JUMBO_RING_SIZE)) + (sizeof(struct tx_ring_info) * @@ -4435,13 +4450,6 @@ static int tg3_alloc_consistent(struct tg3 *tp) if (!tp->rx_std_buffers) return -ENOMEM; - memset(tp->rx_std_buffers, 0, - (sizeof(struct ring_info) * - (TG3_RX_RING_SIZE + - TG3_RX_JUMBO_RING_SIZE)) + - (sizeof(struct tx_ring_info) * - TG3_TX_RING_SIZE)); - tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE]; tp->tx_buffers = (struct tx_ring_info *) &tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE]; @@ -6988,6 +6996,8 @@ static int tg3_open(struct net_device *dev) struct tg3 *tp = netdev_priv(dev); int err; + netif_carrier_off(tp->dev); + tg3_full_lock(tp, 0); err = tg3_set_power_state(tp, PCI_D0); @@ -7981,6 +7991,10 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) tp->link_config.duplex = cmd->duplex; } + tp->link_config.orig_speed = tp->link_config.speed; + tp->link_config.orig_duplex = tp->link_config.duplex; + tp->link_config.orig_autoneg = tp->link_config.autoneg; + if (netif_running(dev)) tg3_setup_phy(tp, 1); @@ -11923,6 +11937,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, */ pci_save_state(tp->pdev); + pci_set_drvdata(pdev, dev); + err = register_netdev(dev); if (err) { printk(KERN_ERR PFX "Cannot register net device, " @@ -11930,8 +11946,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, goto err_out_iounmap; } - pci_set_drvdata(pdev, dev); - printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %s Ethernet ", dev->name, tp->board_part_number, @@ -11962,8 +11976,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, (pdev->dma_mask == DMA_32BIT_MASK) ? 32 : (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64)); - netif_carrier_off(tp->dev); - return 0; err_out_iounmap: diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index dfaf4ed127bd..cf78a7e5997b 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1350,6 +1350,7 @@ #define GRC_MISC_CFG_BOARD_ID_5788 0x00010000 #define GRC_MISC_CFG_BOARD_ID_5788M 0x00018000 #define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000 +#define GRC_MISC_CFG_EPHY_IDDQ 0x00200000 #define GRC_MISC_CFG_KEEP_GPHY_POWER 0x04000000 #define GRC_LOCAL_CTRL 0x00006808 #define GRC_LCLCTRL_INT_ACTIVE 0x00000001 diff --git a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c index f7c10d954ec6..4f873ae148b7 100644 --- a/drivers/s390/char/sclp_cpi.c +++ b/drivers/s390/char/sclp_cpi.c @@ -49,6 +49,8 @@ static struct sclp_register sclp_cpi_event = .send_mask = EvTyp_CtlProgIdent_Mask }; +MODULE_LICENSE("GPL"); + MODULE_AUTHOR( "Martin Peschke, IBM Deutschland Entwicklung GmbH " "<mpeschke@de.ibm.com>"); diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 7835a714a405..3a403f195cf8 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -871,11 +871,32 @@ __clear_subchannel_easy(struct subchannel_id schid) return -EBUSY; } +static int pgm_check_occured; + +static void cio_reset_pgm_check_handler(void) +{ + pgm_check_occured = 1; +} + +static int stsch_reset(struct subchannel_id schid, volatile struct schib *addr) +{ + int rc; + + pgm_check_occured = 0; + s390_reset_pgm_handler = cio_reset_pgm_check_handler; + rc = stsch(schid, addr); + s390_reset_pgm_handler = NULL; + if (pgm_check_occured) + return -EIO; + else + return rc; +} + static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data) { struct schib schib; - if (stsch_err(schid, &schib)) + if (stsch_reset(schid, &schib)) return -ENXIO; if (!schib.pmcw.ena) return 0; @@ -972,7 +993,7 @@ static int __reipl_subchannel_match(struct subchannel_id schid, void *data) struct schib schib; struct sch_match_id *match_id = data; - if (stsch_err(schid, &schib)) + if (stsch_reset(schid, &schib)) return -ENXIO; if (schib.pmcw.dnv && (schib.pmcw.dev == match_id->devid.devno) && diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 4c81d890791e..9d6c02446863 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -139,6 +139,8 @@ css_register_subchannel(struct subchannel *sch) sch->dev.release = &css_subchannel_release; sch->dev.groups = subch_attr_groups; + css_get_ssd_info(sch); + /* make it known to the system */ ret = css_sch_device_register(sch); if (ret) { @@ -146,7 +148,6 @@ css_register_subchannel(struct subchannel *sch) __func__, sch->dev.bus_id); return ret; } - css_get_ssd_info(sch); return ret; } diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 9d4ea449a608..6fd1940842eb 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -979,12 +979,11 @@ __qdio_outbound_processing(struct qdio_q *q) if (q->is_iqdio_q) { /* - * for asynchronous queues, we better check, if the fill - * level is too high. for synchronous queues, the fill - * level will never be that high. + * for asynchronous queues, we better check, if the sent + * buffer is already switched from PRIMED to EMPTY. */ - if (atomic_read(&q->number_of_buffers_used)> - IQDIO_FILL_LEVEL_TO_POLL) + if ((q->queue_type == QDIO_IQDIO_QFMT_ASYNCH) && + !qdio_is_outbound_q_done(q)) qdio_mark_q(q); } else if (!q->hydra_gives_outbound_pcis) @@ -1825,6 +1824,10 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, q->sbal[j]=*(outbound_sbals_array++); q->queue_type=q_format; + if ((q->queue_type == QDIO_IQDIO_QFMT) && + (no_output_qs > 1) && + (i == no_output_qs-1)) + q->queue_type = QDIO_IQDIO_QFMT_ASYNCH; q->int_parm=int_parm; q->is_input_q=0; q->schid = irq_ptr->schid; diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index ad60afe5dd11..81b5899f4010 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1129,7 +1129,15 @@ static void ap_poll_thread_stop(void) mutex_unlock(&ap_poll_thread_mutex); } -static void ap_reset(void) +static void ap_reset_domain(void) +{ + int i; + + for (i = 0; i < AP_DEVICES; i++) + ap_reset_queue(AP_MKQID(i, ap_domain_index)); +} + +static void ap_reset_all(void) { int i, j; @@ -1139,7 +1147,7 @@ static void ap_reset(void) } static struct reset_call ap_reset_call = { - .fn = ap_reset, + .fn = ap_reset_all, }; /** @@ -1229,10 +1237,12 @@ void ap_module_exit(void) int i; struct device *dev; + ap_reset_domain(); ap_poll_thread_stop(); del_timer_sync(&ap_config_timer); del_timer_sync(&ap_poll_timer); destroy_workqueue(ap_work_queue); + tasklet_kill(&ap_tasklet); s390_root_dev_unregister(ap_root_device); while ((dev = bus_find_device(&ap_bus_type, NULL, NULL, __ap_match_all))) diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index 43f5b6aa7dc4..98e3fe10c1dc 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c @@ -266,7 +266,7 @@ static struct scsi_host_template *the_template = NULL; (struct NCR5380_hostdata *)(in)->hostdata #define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata) -#define NEXT(cmd) ((struct scsi_cmnd *)((cmd)->host_scribble)) +#define NEXT(cmd) (*(struct scsi_cmnd **)&((cmd)->host_scribble)) #define NEXTADDR(cmd) ((struct scsi_cmnd **)&((cmd)->host_scribble)) #define HOSTNO instance->host_no @@ -650,7 +650,7 @@ __inline__ void NCR5380_print_phase(struct Scsi_Host *instance) { }; #include <linux/interrupt.h> static volatile int main_running = 0; -static DECLARE_WORK(NCR5380_tqueue, (void (*)(void*))NCR5380_main, NULL); +static DECLARE_WORK(NCR5380_tqueue, NCR5380_main); static __inline__ void queue_main(void) { @@ -1031,7 +1031,7 @@ static int NCR5380_queue_command(struct scsi_cmnd *cmd, * reenable them. This prevents reentrancy and kernel stack overflow. */ -static void NCR5380_main (void *bl) +static void NCR5380_main (struct work_struct *bl) { struct scsi_cmnd *tmp, *prev; struct Scsi_Host *instance = first_instance; diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 7437ccaada77..1587121730c5 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -119,8 +119,6 @@ *(__ksymtab_strings) \ } \ \ - EH_FRAME \ - \ /* Built-in module parameters. */ \ __param : AT(ADDR(__param) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___param) = .; \ @@ -160,26 +158,6 @@ *(.kprobes.text) \ VMLINUX_SYMBOL(__kprobes_text_end) = .; -#ifdef CONFIG_STACK_UNWIND -#define EH_FRAME \ - /* Unwind data binary search table */ \ - . = ALIGN(8); \ - .eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start_unwind_hdr) = .; \ - *(.eh_frame_hdr) \ - VMLINUX_SYMBOL(__end_unwind_hdr) = .; \ - } \ - /* Unwind data */ \ - . = ALIGN(8); \ - .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start_unwind) = .; \ - *(.eh_frame) \ - VMLINUX_SYMBOL(__end_unwind) = .; \ - } -#else -#define EH_FRAME -#endif - /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ diff --git a/include/asm-i386/unwind.h b/include/asm-i386/unwind.h index aa2c931e30db..43c70c3de2f9 100644 --- a/include/asm-i386/unwind.h +++ b/include/asm-i386/unwind.h @@ -1,95 +1,6 @@ #ifndef _ASM_I386_UNWIND_H #define _ASM_I386_UNWIND_H -/* - * Copyright (C) 2002-2006 Novell, Inc. - * Jan Beulich <jbeulich@novell.com> - * This code is released under version 2 of the GNU GPL. - */ - -#ifdef CONFIG_STACK_UNWIND - -#include <linux/sched.h> -#include <asm/fixmap.h> -#include <asm/ptrace.h> -#include <asm/uaccess.h> - -struct unwind_frame_info -{ - struct pt_regs regs; - struct task_struct *task; - unsigned call_frame:1; -}; - -#define UNW_PC(frame) (frame)->regs.eip -#define UNW_SP(frame) (frame)->regs.esp -#ifdef CONFIG_FRAME_POINTER -#define UNW_FP(frame) (frame)->regs.ebp -#define FRAME_RETADDR_OFFSET 4 -#define FRAME_LINK_OFFSET 0 -#define STACK_BOTTOM(tsk) STACK_LIMIT((tsk)->thread.esp0) -#define STACK_TOP(tsk) ((tsk)->thread.esp0) -#else -#define UNW_FP(frame) ((void)(frame), 0) -#endif -#define STACK_LIMIT(ptr) (((ptr) - 1) & ~(THREAD_SIZE - 1)) - -#define UNW_REGISTER_INFO \ - PTREGS_INFO(eax), \ - PTREGS_INFO(ecx), \ - PTREGS_INFO(edx), \ - PTREGS_INFO(ebx), \ - PTREGS_INFO(esp), \ - PTREGS_INFO(ebp), \ - PTREGS_INFO(esi), \ - PTREGS_INFO(edi), \ - PTREGS_INFO(eip) - -#define UNW_DEFAULT_RA(raItem, dataAlign) \ - ((raItem).where == Memory && \ - !((raItem).value * (dataAlign) + 4)) - -static inline void arch_unw_init_frame_info(struct unwind_frame_info *info, - /*const*/ struct pt_regs *regs) -{ - if (user_mode_vm(regs)) - info->regs = *regs; - else { - memcpy(&info->regs, regs, offsetof(struct pt_regs, esp)); - info->regs.esp = (unsigned long)®s->esp; - info->regs.xss = __KERNEL_DS; - } -} - -static inline void arch_unw_init_blocked(struct unwind_frame_info *info) -{ - memset(&info->regs, 0, sizeof(info->regs)); - info->regs.eip = info->task->thread.eip; - info->regs.xcs = __KERNEL_CS; - __get_user(info->regs.ebp, (long *)info->task->thread.esp); - info->regs.esp = info->task->thread.esp; - info->regs.xss = __KERNEL_DS; - info->regs.xds = __USER_DS; - info->regs.xes = __USER_DS; - info->regs.xgs = __KERNEL_PDA; -} - -extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *, - asmlinkage int (*callback)(struct unwind_frame_info *, - void *arg), - void *arg); - -static inline int arch_unw_user_mode(/*const*/ struct unwind_frame_info *info) -{ - return user_mode_vm(&info->regs) - || info->regs.eip < PAGE_OFFSET - || (info->regs.eip >= __fix_to_virt(FIX_VDSO) - && info->regs.eip < __fix_to_virt(FIX_VDSO) + PAGE_SIZE) - || info->regs.esp < PAGE_OFFSET; -} - -#else - #define UNW_PC(frame) ((void)(frame), 0) #define UNW_SP(frame) ((void)(frame), 0) #define UNW_FP(frame) ((void)(frame), 0) @@ -99,6 +10,4 @@ static inline int arch_unw_user_mode(const void *info) return 0; } -#endif - #endif /* _ASM_I386_UNWIND_H */ diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h index 7189c79bc673..127f72e77419 100644 --- a/include/asm-s390/qdio.h +++ b/include/asm-s390/qdio.h @@ -34,6 +34,7 @@ #define QDIO_QETH_QFMT 0 #define QDIO_ZFCP_QFMT 1 #define QDIO_IQDIO_QFMT 2 +#define QDIO_IQDIO_QFMT_ASYNCH 3 struct qdio_buffer_element{ unsigned int flags; diff --git a/include/asm-s390/reset.h b/include/asm-s390/reset.h index 9b439cf67800..532e65a2aafc 100644 --- a/include/asm-s390/reset.h +++ b/include/asm-s390/reset.h @@ -19,5 +19,6 @@ extern void register_reset_call(struct reset_call *reset); extern void unregister_reset_call(struct reset_call *reset); extern void s390_reset_system(void); extern void (*s390_reset_mcck_handler)(void); +extern void (*s390_reset_pgm_handler)(void); #endif /* _ASM_S390_RESET_H */ diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h index 04aa3318f76a..329e696e7751 100644 --- a/include/asm-sparc/bitops.h +++ b/include/asm-sparc/bitops.h @@ -14,6 +14,10 @@ #ifdef __KERNEL__ +extern unsigned long ___set_bit(unsigned long *addr, unsigned long mask); +extern unsigned long ___clear_bit(unsigned long *addr, unsigned long mask); +extern unsigned long ___change_bit(unsigned long *addr, unsigned long mask); + /* * Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0' * is in the highest of the four bytes and bit '31' is the high bit @@ -22,134 +26,62 @@ */ static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr) { - register unsigned long mask asm("g2"); - register unsigned long *ADDR asm("g1"); - register int tmp1 asm("g3"); - register int tmp2 asm("g4"); - register int tmp3 asm("g5"); - register int tmp4 asm("g7"); + unsigned long *ADDR, mask; ADDR = ((unsigned long *) addr) + (nr >> 5); mask = 1 << (nr & 31); - __asm__ __volatile__( - "mov %%o7, %%g4\n\t" - "call ___set_bit\n\t" - " add %%o7, 8, %%o7\n" - : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4) - : "0" (mask), "r" (ADDR) - : "memory", "cc"); - - return mask != 0; + return ___set_bit(ADDR, mask) != 0; } static inline void set_bit(unsigned long nr, volatile unsigned long *addr) { - register unsigned long mask asm("g2"); - register unsigned long *ADDR asm("g1"); - register int tmp1 asm("g3"); - register int tmp2 asm("g4"); - register int tmp3 asm("g5"); - register int tmp4 asm("g7"); + unsigned long *ADDR, mask; ADDR = ((unsigned long *) addr) + (nr >> 5); mask = 1 << (nr & 31); - __asm__ __volatile__( - "mov %%o7, %%g4\n\t" - "call ___set_bit\n\t" - " add %%o7, 8, %%o7\n" - : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4) - : "0" (mask), "r" (ADDR) - : "memory", "cc"); + (void) ___set_bit(ADDR, mask); } static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) { - register unsigned long mask asm("g2"); - register unsigned long *ADDR asm("g1"); - register int tmp1 asm("g3"); - register int tmp2 asm("g4"); - register int tmp3 asm("g5"); - register int tmp4 asm("g7"); + unsigned long *ADDR, mask; ADDR = ((unsigned long *) addr) + (nr >> 5); mask = 1 << (nr & 31); - __asm__ __volatile__( - "mov %%o7, %%g4\n\t" - "call ___clear_bit\n\t" - " add %%o7, 8, %%o7\n" - : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4) - : "0" (mask), "r" (ADDR) - : "memory", "cc"); - - return mask != 0; + return ___clear_bit(ADDR, mask) != 0; } static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) { - register unsigned long mask asm("g2"); - register unsigned long *ADDR asm("g1"); - register int tmp1 asm("g3"); - register int tmp2 asm("g4"); - register int tmp3 asm("g5"); - register int tmp4 asm("g7"); + unsigned long *ADDR, mask; ADDR = ((unsigned long *) addr) + (nr >> 5); mask = 1 << (nr & 31); - __asm__ __volatile__( - "mov %%o7, %%g4\n\t" - "call ___clear_bit\n\t" - " add %%o7, 8, %%o7\n" - : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4) - : "0" (mask), "r" (ADDR) - : "memory", "cc"); + (void) ___clear_bit(ADDR, mask); } static inline int test_and_change_bit(unsigned long nr, volatile unsigned long *addr) { - register unsigned long mask asm("g2"); - register unsigned long *ADDR asm("g1"); - register int tmp1 asm("g3"); - register int tmp2 asm("g4"); - register int tmp3 asm("g5"); - register int tmp4 asm("g7"); + unsigned long *ADDR, mask; ADDR = ((unsigned long *) addr) + (nr >> 5); mask = 1 << (nr & 31); - __asm__ __volatile__( - "mov %%o7, %%g4\n\t" - "call ___change_bit\n\t" - " add %%o7, 8, %%o7\n" - : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4) - : "0" (mask), "r" (ADDR) - : "memory", "cc"); - - return mask != 0; + return ___change_bit(ADDR, mask) != 0; } static inline void change_bit(unsigned long nr, volatile unsigned long *addr) { - register unsigned long mask asm("g2"); - register unsigned long *ADDR asm("g1"); - register int tmp1 asm("g3"); - register int tmp2 asm("g4"); - register int tmp3 asm("g5"); - register int tmp4 asm("g7"); + unsigned long *ADDR, mask; ADDR = ((unsigned long *) addr) + (nr >> 5); mask = 1 << (nr & 31); - __asm__ __volatile__( - "mov %%o7, %%g4\n\t" - "call ___change_bit\n\t" - " add %%o7, 8, %%o7\n" - : "=&r" (mask), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3), "=r" (tmp4) - : "0" (mask), "r" (ADDR) - : "memory", "cc"); + (void) ___change_bit(ADDR, mask); } #include <asm-generic/bitops/non-atomic.h> diff --git a/include/asm-sparc64/hw_irq.h b/include/asm-sparc64/hw_irq.h index 599b3b073450..8e44a8360829 100644 --- a/include/asm-sparc64/hw_irq.h +++ b/include/asm-sparc64/hw_irq.h @@ -1,6 +1,4 @@ #ifndef __ASM_SPARC64_HW_IRQ_H #define __ASM_SPARC64_HW_IRQ_H -extern void hw_resend_irq(struct hw_interrupt_type *handler, unsigned int virt_irq); - #endif diff --git a/include/asm-sparc64/percpu.h b/include/asm-sparc64/percpu.h index ced8cbde046d..0d3df76aa47f 100644 --- a/include/asm-sparc64/percpu.h +++ b/include/asm-sparc64/percpu.h @@ -5,6 +5,16 @@ #ifdef CONFIG_SMP +#ifdef CONFIG_MODULES +# define PERCPU_MODULE_RESERVE 8192 +#else +# define PERCPU_MODULE_RESERVE 0 +#endif + +#define PERCPU_ENOUGH_ROOM \ + (ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES) + \ + PERCPU_MODULE_RESERVE) + extern void setup_per_cpu_areas(void); extern unsigned long __per_cpu_base; diff --git a/include/asm-x86_64/unwind.h b/include/asm-x86_64/unwind.h index 2f6349e48717..02710f6a4560 100644 --- a/include/asm-x86_64/unwind.h +++ b/include/asm-x86_64/unwind.h @@ -1,100 +1,6 @@ #ifndef _ASM_X86_64_UNWIND_H #define _ASM_X86_64_UNWIND_H -/* - * Copyright (C) 2002-2006 Novell, Inc. - * Jan Beulich <jbeulich@novell.com> - * This code is released under version 2 of the GNU GPL. - */ - -#ifdef CONFIG_STACK_UNWIND - -#include <linux/sched.h> -#include <asm/ptrace.h> -#include <asm/uaccess.h> -#include <asm/vsyscall.h> - -struct unwind_frame_info -{ - struct pt_regs regs; - struct task_struct *task; - unsigned call_frame:1; -}; - -#define UNW_PC(frame) (frame)->regs.rip -#define UNW_SP(frame) (frame)->regs.rsp -#ifdef CONFIG_FRAME_POINTER -#define UNW_FP(frame) (frame)->regs.rbp -#define FRAME_RETADDR_OFFSET 8 -#define FRAME_LINK_OFFSET 0 -#define STACK_BOTTOM(tsk) (((tsk)->thread.rsp0 - 1) & ~(THREAD_SIZE - 1)) -#define STACK_TOP(tsk) ((tsk)->thread.rsp0) -#endif -/* Might need to account for the special exception and interrupt handling - stacks here, since normally - EXCEPTION_STACK_ORDER < THREAD_ORDER < IRQSTACK_ORDER, - but the construct is needed only for getting across the stack switch to - the interrupt stack - thus considering the IRQ stack itself is unnecessary, - and the overhead of comparing against all exception handling stacks seems - not desirable. */ -#define STACK_LIMIT(ptr) (((ptr) - 1) & ~(THREAD_SIZE - 1)) - -#define UNW_REGISTER_INFO \ - PTREGS_INFO(rax), \ - PTREGS_INFO(rdx), \ - PTREGS_INFO(rcx), \ - PTREGS_INFO(rbx), \ - PTREGS_INFO(rsi), \ - PTREGS_INFO(rdi), \ - PTREGS_INFO(rbp), \ - PTREGS_INFO(rsp), \ - PTREGS_INFO(r8), \ - PTREGS_INFO(r9), \ - PTREGS_INFO(r10), \ - PTREGS_INFO(r11), \ - PTREGS_INFO(r12), \ - PTREGS_INFO(r13), \ - PTREGS_INFO(r14), \ - PTREGS_INFO(r15), \ - PTREGS_INFO(rip) - -#define UNW_DEFAULT_RA(raItem, dataAlign) \ - ((raItem).where == Memory && \ - !((raItem).value * (dataAlign) + 8)) - -static inline void arch_unw_init_frame_info(struct unwind_frame_info *info, - /*const*/ struct pt_regs *regs) -{ - info->regs = *regs; -} - -static inline void arch_unw_init_blocked(struct unwind_frame_info *info) -{ - extern const char thread_return[]; - - memset(&info->regs, 0, sizeof(info->regs)); - info->regs.rip = (unsigned long)thread_return; - info->regs.cs = __KERNEL_CS; - __get_user(info->regs.rbp, (unsigned long *)info->task->thread.rsp); - info->regs.rsp = info->task->thread.rsp; - info->regs.ss = __KERNEL_DS; -} - -extern int arch_unwind_init_running(struct unwind_frame_info *, - int (*callback)(struct unwind_frame_info *, - void *arg), - void *arg); - -static inline int arch_unw_user_mode(const struct unwind_frame_info *info) -{ - return user_mode(&info->regs) - || (long)info->regs.rip >= 0 - || (info->regs.rip >= VSYSCALL_START && info->regs.rip < VSYSCALL_END) - || (long)info->regs.rsp >= 0; -} - -#else - #define UNW_PC(frame) ((void)(frame), 0UL) #define UNW_SP(frame) ((void)(frame), 0UL) @@ -103,6 +9,4 @@ static inline int arch_unw_user_mode(const void *info) return 0; } -#endif - #endif /* _ASM_X86_64_UNWIND_H */ diff --git a/include/linux/connector.h b/include/linux/connector.h index 3ea1cd58de97..10eb56b2940a 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h @@ -133,7 +133,7 @@ struct cn_callback_data { struct cn_callback_entry { struct list_head callback_entry; struct cn_callback *cb; - struct delayed_work work; + struct work_struct work; struct cn_queue_dev *pdev; struct cn_callback_id id; diff --git a/include/linux/unwind.h b/include/linux/unwind.h index 749928c161fb..7760860fa170 100644 --- a/include/linux/unwind.h +++ b/include/linux/unwind.h @@ -14,63 +14,6 @@ struct module; -#ifdef CONFIG_STACK_UNWIND - -#include <asm/unwind.h> - -#ifndef ARCH_UNWIND_SECTION_NAME -#define ARCH_UNWIND_SECTION_NAME ".eh_frame" -#endif - -/* - * Initialize unwind support. - */ -extern void unwind_init(void); -extern void unwind_setup(void); - -#ifdef CONFIG_MODULES - -extern void *unwind_add_table(struct module *, - const void *table_start, - unsigned long table_size); - -extern void unwind_remove_table(void *handle, int init_only); - -#endif - -extern int unwind_init_frame_info(struct unwind_frame_info *, - struct task_struct *, - /*const*/ struct pt_regs *); - -/* - * Prepare to unwind a blocked task. - */ -extern int unwind_init_blocked(struct unwind_frame_info *, - struct task_struct *); - -/* - * Prepare to unwind the currently running thread. - */ -extern int unwind_init_running(struct unwind_frame_info *, - asmlinkage int (*callback)(struct unwind_frame_info *, - void *arg), - void *arg); - -/* - * Unwind to previous to frame. Returns 0 if successful, negative - * number in case of an error. - */ -extern int unwind(struct unwind_frame_info *); - -/* - * Unwind until the return pointer is in user-land (or until an error - * occurs). Returns 0 if successful, negative number in case of - * error. - */ -extern int unwind_to_user(struct unwind_frame_info *); - -#else - struct unwind_frame_info {}; static inline void unwind_init(void) {} @@ -85,12 +28,12 @@ static inline void *unwind_add_table(struct module *mod, return NULL; } -#endif - static inline void unwind_remove_table(void *handle, int init_only) { } +#endif + static inline int unwind_init_frame_info(struct unwind_frame_info *info, struct task_struct *tsk, const struct pt_regs *regs) @@ -122,6 +65,4 @@ static inline int unwind_to_user(struct unwind_frame_info *info) return -ENOSYS; } -#endif - #endif /* _LINUX_UNWIND_H */ diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index edef8d50b26b..2a7b38d87018 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -8,16 +8,21 @@ #include <linux/timer.h> #include <linux/linkage.h> #include <linux/bitops.h> +#include <asm/atomic.h> struct workqueue_struct; struct work_struct; typedef void (*work_func_t)(struct work_struct *work); +/* + * The first word is the work queue pointer and the flags rolled into + * one + */ +#define work_data_bits(work) ((unsigned long *)(&(work)->data)) + struct work_struct { - /* the first word is the work queue pointer and the flags rolled into - * one */ - unsigned long management; + atomic_long_t data; #define WORK_STRUCT_PENDING 0 /* T if work item pending execution */ #define WORK_STRUCT_NOAUTOREL 1 /* F if work item automatically released on exec */ #define WORK_STRUCT_FLAG_MASK (3UL) @@ -26,6 +31,9 @@ struct work_struct { work_func_t func; }; +#define WORK_DATA_INIT(autorelease) \ + ATOMIC_LONG_INIT((autorelease) << WORK_STRUCT_NOAUTOREL) + struct delayed_work { struct work_struct work; struct timer_list timer; @@ -36,13 +44,13 @@ struct execute_work { }; #define __WORK_INITIALIZER(n, f) { \ - .management = 0, \ + .data = WORK_DATA_INIT(0), \ .entry = { &(n).entry, &(n).entry }, \ .func = (f), \ } #define __WORK_INITIALIZER_NAR(n, f) { \ - .management = (1 << WORK_STRUCT_NOAUTOREL), \ + .data = WORK_DATA_INIT(1), \ .entry = { &(n).entry, &(n).entry }, \ .func = (f), \ } @@ -82,17 +90,21 @@ struct execute_work { /* * initialize all of a work item in one go + * + * NOTE! No point in using "atomic_long_set()": useing a direct + * assignment of the work data initializer allows the compiler + * to generate better code. */ #define INIT_WORK(_work, _func) \ do { \ - (_work)->management = 0; \ + (_work)->data = (atomic_long_t) WORK_DATA_INIT(0); \ INIT_LIST_HEAD(&(_work)->entry); \ PREPARE_WORK((_work), (_func)); \ } while (0) #define INIT_WORK_NAR(_work, _func) \ do { \ - (_work)->management = (1 << WORK_STRUCT_NOAUTOREL); \ + (_work)->data = (atomic_long_t) WORK_DATA_INIT(1); \ INIT_LIST_HEAD(&(_work)->entry); \ PREPARE_WORK((_work), (_func)); \ } while (0) @@ -114,15 +126,15 @@ struct execute_work { * @work: The work item in question */ #define work_pending(work) \ - test_bit(WORK_STRUCT_PENDING, &(work)->management) + test_bit(WORK_STRUCT_PENDING, work_data_bits(work)) /** * delayed_work_pending - Find out whether a delayable work item is currently * pending * @work: The work item in question */ -#define delayed_work_pending(work) \ - test_bit(WORK_STRUCT_PENDING, &(work)->work.management) +#define delayed_work_pending(w) \ + work_pending(&(w)->work) /** * work_release - Release a work item under execution @@ -143,7 +155,7 @@ struct execute_work { * This should also be used to release a delayed work item. */ #define work_release(work) \ - clear_bit(WORK_STRUCT_PENDING, &(work)->management) + clear_bit(WORK_STRUCT_PENDING, work_data_bits(work)) extern struct workqueue_struct *__create_workqueue(const char *name, @@ -188,7 +200,7 @@ static inline int cancel_delayed_work(struct delayed_work *work) ret = del_timer_sync(&work->timer); if (ret) - clear_bit(WORK_STRUCT_PENDING, &work->work.management); + work_release(&work->work); return ret; } diff --git a/include/net/ax25.h b/include/net/ax25.h index 14b72d868f03..5ae10dd2e32e 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -277,7 +277,7 @@ struct sock *ax25_get_socket(ax25_address *, ax25_address *, int); extern ax25_cb *ax25_find_cb(ax25_address *, ax25_address *, ax25_digi *, struct net_device *); extern void ax25_send_to_raw(ax25_address *, struct sk_buff *, int); extern void ax25_destroy_socket(ax25_cb *); -extern ax25_cb *ax25_create_cb(void); +extern ax25_cb * __must_check ax25_create_cb(void); extern void ax25_fillin_cb(ax25_cb *, ax25_dev *); extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *); @@ -333,11 +333,25 @@ extern void ax25_ds_t3timer_expiry(ax25_cb *); extern void ax25_ds_idletimer_expiry(ax25_cb *); /* ax25_iface.c */ -extern int ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, ax25_cb *)); + +struct ax25_protocol { + struct ax25_protocol *next; + unsigned int pid; + int (*func)(struct sk_buff *, ax25_cb *); +}; + +extern void ax25_register_pid(struct ax25_protocol *ap); extern void ax25_protocol_release(unsigned int); -extern int ax25_linkfail_register(void (*)(ax25_cb *, int)); -extern void ax25_linkfail_release(void (*)(ax25_cb *, int)); -extern int ax25_listen_register(ax25_address *, struct net_device *); + +struct ax25_linkfail { + struct hlist_node lf_node; + void (*func)(ax25_cb *, int); +}; + +extern void ax25_linkfail_register(struct ax25_linkfail *lf); +extern void ax25_linkfail_release(struct ax25_linkfail *lf); +extern int __must_check ax25_listen_register(ax25_address *, + struct net_device *); extern void ax25_listen_release(ax25_address *, struct net_device *); extern int (*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *); extern int ax25_listen_mine(ax25_address *, struct net_device *); @@ -415,7 +429,7 @@ extern unsigned long ax25_display_timer(struct timer_list *); /* ax25_uid.c */ extern int ax25_uid_policy; extern ax25_uid_assoc *ax25_findbyuid(uid_t); -extern int ax25_uid_ioctl(int, struct sockaddr_ax25 *); +extern int __must_check ax25_uid_ioctl(int, struct sockaddr_ax25 *); extern struct file_operations ax25_uid_fops; extern void ax25_uid_free(void); diff --git a/include/net/rose.h b/include/net/rose.h index 012b09ed2401..4c05a88b921b 100644 --- a/include/net/rose.h +++ b/include/net/rose.h @@ -188,13 +188,13 @@ extern void rose_kick(struct sock *); extern void rose_enquiry_response(struct sock *); /* rose_route.c */ -extern struct rose_neigh *rose_loopback_neigh; +extern struct rose_neigh rose_loopback_neigh; extern struct file_operations rose_neigh_fops; extern struct file_operations rose_nodes_fops; extern struct file_operations rose_routes_fops; -extern int rose_add_loopback_neigh(void); -extern int rose_add_loopback_node(rose_address *); +extern void rose_add_loopback_neigh(void); +extern int __must_check rose_add_loopback_node(rose_address *); extern void rose_del_loopback_node(rose_address *); extern void rose_rt_device_down(struct net_device *); extern void rose_link_device_down(struct net_device *); diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 3c2e10574b23..0bfa3328d686 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1639,7 +1639,14 @@ static inline void *ib_dma_alloc_coherent(struct ib_device *dev, { if (dev->dma_ops) return dev->dma_ops->alloc_coherent(dev, size, dma_handle, flag); - return dma_alloc_coherent(dev->dma_device, size, dma_handle, flag); + else { + dma_addr_t handle; + void *ret; + + ret = dma_alloc_coherent(dev->dma_device, size, &handle, flag); + *dma_handle = handle; + return ret; + } } /** diff --git a/kernel/Makefile b/kernel/Makefile index 5e3f3b75563a..14f4d45e0ae9 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -31,7 +31,6 @@ obj-$(CONFIG_PROVE_LOCKING) += spinlock.o obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_KALLSYMS) += kallsyms.o -obj-$(CONFIG_STACK_UNWIND) += unwind.o obj-$(CONFIG_PM) += power/ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_KEXEC) += kexec.o diff --git a/kernel/unwind.c b/kernel/unwind.c deleted file mode 100644 index 09c261329249..000000000000 --- a/kernel/unwind.c +++ /dev/null @@ -1,1305 +0,0 @@ -/* - * Copyright (C) 2002-2006 Novell, Inc. - * Jan Beulich <jbeulich@novell.com> - * This code is released under version 2 of the GNU GPL. - * - * A simple API for unwinding kernel stacks. This is used for - * debugging and error reporting purposes. The kernel doesn't need - * full-blown stack unwinding with all the bells and whistles, so there - * is not much point in implementing the full Dwarf2 unwind API. - */ - -#include <linux/unwind.h> -#include <linux/module.h> -#include <linux/bootmem.h> -#include <linux/sort.h> -#include <linux/stop_machine.h> -#include <linux/uaccess.h> -#include <asm/sections.h> -#include <asm/uaccess.h> -#include <asm/unaligned.h> - -extern const char __start_unwind[], __end_unwind[]; -extern const u8 __start_unwind_hdr[], __end_unwind_hdr[]; - -#define MAX_STACK_DEPTH 8 - -#define EXTRA_INFO(f) { \ - BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \ - % FIELD_SIZEOF(struct unwind_frame_info, f)) \ - + offsetof(struct unwind_frame_info, f) \ - / FIELD_SIZEOF(struct unwind_frame_info, f), \ - FIELD_SIZEOF(struct unwind_frame_info, f) \ - } -#define PTREGS_INFO(f) EXTRA_INFO(regs.f) - -static const struct { - unsigned offs:BITS_PER_LONG / 2; - unsigned width:BITS_PER_LONG / 2; -} reg_info[] = { - UNW_REGISTER_INFO -}; - -#undef PTREGS_INFO -#undef EXTRA_INFO - -#ifndef REG_INVALID -#define REG_INVALID(r) (reg_info[r].width == 0) -#endif - -#define DW_CFA_nop 0x00 -#define DW_CFA_set_loc 0x01 -#define DW_CFA_advance_loc1 0x02 -#define DW_CFA_advance_loc2 0x03 -#define DW_CFA_advance_loc4 0x04 -#define DW_CFA_offset_extended 0x05 -#define DW_CFA_restore_extended 0x06 -#define DW_CFA_undefined 0x07 -#define DW_CFA_same_value 0x08 -#define DW_CFA_register 0x09 -#define DW_CFA_remember_state 0x0a -#define DW_CFA_restore_state 0x0b -#define DW_CFA_def_cfa 0x0c -#define DW_CFA_def_cfa_register 0x0d -#define DW_CFA_def_cfa_offset 0x0e -#define DW_CFA_def_cfa_expression 0x0f -#define DW_CFA_expression 0x10 -#define DW_CFA_offset_extended_sf 0x11 -#define DW_CFA_def_cfa_sf 0x12 -#define DW_CFA_def_cfa_offset_sf 0x13 -#define DW_CFA_val_offset 0x14 -#define DW_CFA_val_offset_sf 0x15 -#define DW_CFA_val_expression 0x16 -#define DW_CFA_lo_user 0x1c -#define DW_CFA_GNU_window_save 0x2d -#define DW_CFA_GNU_args_size 0x2e -#define DW_CFA_GNU_negative_offset_extended 0x2f -#define DW_CFA_hi_user 0x3f - -#define DW_EH_PE_FORM 0x07 -#define DW_EH_PE_native 0x00 -#define DW_EH_PE_leb128 0x01 -#define DW_EH_PE_data2 0x02 -#define DW_EH_PE_data4 0x03 -#define DW_EH_PE_data8 0x04 -#define DW_EH_PE_signed 0x08 -#define DW_EH_PE_ADJUST 0x70 -#define DW_EH_PE_abs 0x00 -#define DW_EH_PE_pcrel 0x10 -#define DW_EH_PE_textrel 0x20 -#define DW_EH_PE_datarel 0x30 -#define DW_EH_PE_funcrel 0x40 -#define DW_EH_PE_aligned 0x50 -#define DW_EH_PE_indirect 0x80 -#define DW_EH_PE_omit 0xff - -typedef unsigned long uleb128_t; -typedef signed long sleb128_t; -#define sleb128abs __builtin_labs - -static struct unwind_table { - struct { - unsigned long pc; - unsigned long range; - } core, init; - const void *address; - unsigned long size; - const unsigned char *header; - unsigned long hdrsz; - struct unwind_table *link; - const char *name; -} root_table; - -struct unwind_item { - enum item_location { - Nowhere, - Memory, - Register, - Value - } where; - uleb128_t value; -}; - -struct unwind_state { - uleb128_t loc, org; - const u8 *cieStart, *cieEnd; - uleb128_t codeAlign; - sleb128_t dataAlign; - struct cfa { - uleb128_t reg, offs; - } cfa; - struct unwind_item regs[ARRAY_SIZE(reg_info)]; - unsigned stackDepth:8; - unsigned version:8; - const u8 *label; - const u8 *stack[MAX_STACK_DEPTH]; -}; - -static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 }; - -static unsigned unwind_debug; -static int __init unwind_debug_setup(char *s) -{ - unwind_debug = simple_strtoul(s, NULL, 0); - return 1; -} -__setup("unwind_debug=", unwind_debug_setup); -#define dprintk(lvl, fmt, args...) \ - ((void)(lvl > unwind_debug \ - || printk(KERN_DEBUG "unwind: " fmt "\n", ##args))) - -static struct unwind_table *find_table(unsigned long pc) -{ - struct unwind_table *table; - - for (table = &root_table; table; table = table->link) - if ((pc >= table->core.pc - && pc < table->core.pc + table->core.range) - || (pc >= table->init.pc - && pc < table->init.pc + table->init.range)) - break; - - return table; -} - -static unsigned long read_pointer(const u8 **pLoc, - const void *end, - signed ptrType, - unsigned long text_base, - unsigned long data_base); - -static void init_unwind_table(struct unwind_table *table, - const char *name, - const void *core_start, - unsigned long core_size, - const void *init_start, - unsigned long init_size, - const void *table_start, - unsigned long table_size, - const u8 *header_start, - unsigned long header_size) -{ - const u8 *ptr = header_start + 4; - const u8 *end = header_start + header_size; - - table->core.pc = (unsigned long)core_start; - table->core.range = core_size; - table->init.pc = (unsigned long)init_start; - table->init.range = init_size; - table->address = table_start; - table->size = table_size; - /* See if the linker provided table looks valid. */ - if (header_size <= 4 - || header_start[0] != 1 - || (void *)read_pointer(&ptr, end, header_start[1], 0, 0) - != table_start - || !read_pointer(&ptr, end, header_start[2], 0, 0) - || !read_pointer(&ptr, end, header_start[3], 0, - (unsigned long)header_start) - || !read_pointer(&ptr, end, header_start[3], 0, - (unsigned long)header_start)) - header_start = NULL; - table->hdrsz = header_size; - smp_wmb(); - table->header = header_start; - table->link = NULL; - table->name = name; -} - -void __init unwind_init(void) -{ - init_unwind_table(&root_table, "kernel", - _text, _end - _text, - NULL, 0, - __start_unwind, __end_unwind - __start_unwind, - __start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr); -} - -static const u32 bad_cie, not_fde; -static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *); -static signed fde_pointer_type(const u32 *cie); - -struct eh_frame_hdr_table_entry { - unsigned long start, fde; -}; - -static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2) -{ - const struct eh_frame_hdr_table_entry *e1 = p1; - const struct eh_frame_hdr_table_entry *e2 = p2; - - return (e1->start > e2->start) - (e1->start < e2->start); -} - -static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size) -{ - struct eh_frame_hdr_table_entry *e1 = p1; - struct eh_frame_hdr_table_entry *e2 = p2; - unsigned long v; - - v = e1->start; - e1->start = e2->start; - e2->start = v; - v = e1->fde; - e1->fde = e2->fde; - e2->fde = v; -} - -static void __init setup_unwind_table(struct unwind_table *table, - void *(*alloc)(unsigned long)) -{ - const u8 *ptr; - unsigned long tableSize = table->size, hdrSize; - unsigned n; - const u32 *fde; - struct { - u8 version; - u8 eh_frame_ptr_enc; - u8 fde_count_enc; - u8 table_enc; - unsigned long eh_frame_ptr; - unsigned int fde_count; - struct eh_frame_hdr_table_entry table[]; - } __attribute__((__packed__)) *header; - - if (table->header) - return; - - if (table->hdrsz) - printk(KERN_WARNING ".eh_frame_hdr for '%s' present but unusable\n", - table->name); - - if (tableSize & (sizeof(*fde) - 1)) - return; - - for (fde = table->address, n = 0; - tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde; - tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) { - const u32 *cie = cie_for_fde(fde, table); - signed ptrType; - - if (cie == ¬_fde) - continue; - if (cie == NULL - || cie == &bad_cie - || (ptrType = fde_pointer_type(cie)) < 0) - return; - ptr = (const u8 *)(fde + 2); - if (!read_pointer(&ptr, - (const u8 *)(fde + 1) + *fde, - ptrType, 0, 0)) - return; - ++n; - } - - if (tableSize || !n) - return; - - hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int) - + 2 * n * sizeof(unsigned long); - dprintk(2, "Binary lookup table size for %s: %lu bytes", table->name, hdrSize); - header = alloc(hdrSize); - if (!header) - return; - header->version = 1; - header->eh_frame_ptr_enc = DW_EH_PE_abs|DW_EH_PE_native; - header->fde_count_enc = DW_EH_PE_abs|DW_EH_PE_data4; - header->table_enc = DW_EH_PE_abs|DW_EH_PE_native; - put_unaligned((unsigned long)table->address, &header->eh_frame_ptr); - BUILD_BUG_ON(offsetof(typeof(*header), fde_count) - % __alignof(typeof(header->fde_count))); - header->fde_count = n; - - BUILD_BUG_ON(offsetof(typeof(*header), table) - % __alignof(typeof(*header->table))); - for (fde = table->address, tableSize = table->size, n = 0; - tableSize; - tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) { - const u32 *cie = fde + 1 - fde[1] / sizeof(*fde); - - if (!fde[1]) - continue; /* this is a CIE */ - ptr = (const u8 *)(fde + 2); - header->table[n].start = read_pointer(&ptr, - (const u8 *)(fde + 1) + *fde, - fde_pointer_type(cie), 0, 0); - header->table[n].fde = (unsigned long)fde; - ++n; - } - WARN_ON(n != header->fde_count); - - sort(header->table, - n, - sizeof(*header->table), - cmp_eh_frame_hdr_table_entries, - swap_eh_frame_hdr_table_entries); - - table->hdrsz = hdrSize; - smp_wmb(); - table->header = (const void *)header; -} - -static void *__init balloc(unsigned long sz) -{ - return __alloc_bootmem_nopanic(sz, - sizeof(unsigned int), - __pa(MAX_DMA_ADDRESS)); -} - -void __init unwind_setup(void) -{ - setup_unwind_table(&root_table, balloc); -} - -#ifdef CONFIG_MODULES - -static struct unwind_table *last_table; - -/* Must be called with module_mutex held. */ -void *unwind_add_table(struct module *module, - const void *table_start, - unsigned long table_size) -{ - struct unwind_table *table; - - if (table_size <= 0) - return NULL; - - table = kmalloc(sizeof(*table), GFP_KERNEL); - if (!table) - return NULL; - - init_unwind_table(table, module->name, - module->module_core, module->core_size, - module->module_init, module->init_size, - table_start, table_size, - NULL, 0); - - if (last_table) - last_table->link = table; - else - root_table.link = table; - last_table = table; - - return table; -} - -struct unlink_table_info -{ - struct unwind_table *table; - int init_only; -}; - -static int unlink_table(void *arg) -{ - struct unlink_table_info *info = arg; - struct unwind_table *table = info->table, *prev; - - for (prev = &root_table; prev->link && prev->link != table; prev = prev->link) - ; - - if (prev->link) { - if (info->init_only) { - table->init.pc = 0; - table->init.range = 0; - info->table = NULL; - } else { - prev->link = table->link; - if (!prev->link) - last_table = prev; - } - } else - info->table = NULL; - - return 0; -} - -/* Must be called with module_mutex held. */ -void unwind_remove_table(void *handle, int init_only) -{ - struct unwind_table *table = handle; - struct unlink_table_info info; - - if (!table || table == &root_table) - return; - - if (init_only && table == last_table) { - table->init.pc = 0; - table->init.range = 0; - return; - } - - info.table = table; - info.init_only = init_only; - stop_machine_run(unlink_table, &info, NR_CPUS); - - if (info.table) - kfree(table); -} - -#endif /* CONFIG_MODULES */ - -static uleb128_t get_uleb128(const u8 **pcur, const u8 *end) -{ - const u8 *cur = *pcur; - uleb128_t value; - unsigned shift; - - for (shift = 0, value = 0; cur < end; shift += 7) { - if (shift + 7 > 8 * sizeof(value) - && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) { - cur = end + 1; - break; - } - value |= (uleb128_t)(*cur & 0x7f) << shift; - if (!(*cur++ & 0x80)) - break; - } - *pcur = cur; - - return value; -} - -static sleb128_t get_sleb128(const u8 **pcur, const u8 *end) -{ - const u8 *cur = *pcur; - sleb128_t value; - unsigned shift; - - for (shift = 0, value = 0; cur < end; shift += 7) { - if (shift + 7 > 8 * sizeof(value) - && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) { - cur = end + 1; - break; - } - value |= (sleb128_t)(*cur & 0x7f) << shift; - if (!(*cur & 0x80)) { - value |= -(*cur++ & 0x40) << shift; - break; - } - } - *pcur = cur; - - return value; -} - -static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table) -{ - const u32 *cie; - - if (!*fde || (*fde & (sizeof(*fde) - 1))) - return &bad_cie; - if (!fde[1]) - return ¬_fde; /* this is a CIE */ - if ((fde[1] & (sizeof(*fde) - 1)) - || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address) - return NULL; /* this is not a valid FDE */ - cie = fde + 1 - fde[1] / sizeof(*fde); - if (*cie <= sizeof(*cie) + 4 - || *cie >= fde[1] - sizeof(*fde) - || (*cie & (sizeof(*cie) - 1)) - || cie[1]) - return NULL; /* this is not a (valid) CIE */ - return cie; -} - -static unsigned long read_pointer(const u8 **pLoc, - const void *end, - signed ptrType, - unsigned long text_base, - unsigned long data_base) -{ - unsigned long value = 0; - union { - const u8 *p8; - const u16 *p16u; - const s16 *p16s; - const u32 *p32u; - const s32 *p32s; - const unsigned long *pul; - } ptr; - - if (ptrType < 0 || ptrType == DW_EH_PE_omit) { - dprintk(1, "Invalid pointer encoding %02X (%p,%p).", ptrType, *pLoc, end); - return 0; - } - ptr.p8 = *pLoc; - switch(ptrType & DW_EH_PE_FORM) { - case DW_EH_PE_data2: - if (end < (const void *)(ptr.p16u + 1)) { - dprintk(1, "Data16 overrun (%p,%p).", ptr.p8, end); - return 0; - } - if(ptrType & DW_EH_PE_signed) - value = get_unaligned(ptr.p16s++); - else - value = get_unaligned(ptr.p16u++); - break; - case DW_EH_PE_data4: -#ifdef CONFIG_64BIT - if (end < (const void *)(ptr.p32u + 1)) { - dprintk(1, "Data32 overrun (%p,%p).", ptr.p8, end); - return 0; - } - if(ptrType & DW_EH_PE_signed) - value = get_unaligned(ptr.p32s++); - else - value = get_unaligned(ptr.p32u++); - break; - case DW_EH_PE_data8: - BUILD_BUG_ON(sizeof(u64) != sizeof(value)); -#else - BUILD_BUG_ON(sizeof(u32) != sizeof(value)); -#endif - case DW_EH_PE_native: - if (end < (const void *)(ptr.pul + 1)) { - dprintk(1, "DataUL overrun (%p,%p).", ptr.p8, end); - return 0; - } - value = get_unaligned(ptr.pul++); - break; - case DW_EH_PE_leb128: - BUILD_BUG_ON(sizeof(uleb128_t) > sizeof(value)); - value = ptrType & DW_EH_PE_signed - ? get_sleb128(&ptr.p8, end) - : get_uleb128(&ptr.p8, end); - if ((const void *)ptr.p8 > end) { - dprintk(1, "DataLEB overrun (%p,%p).", ptr.p8, end); - return 0; - } - break; - default: - dprintk(2, "Cannot decode pointer type %02X (%p,%p).", - ptrType, ptr.p8, end); - return 0; - } - switch(ptrType & DW_EH_PE_ADJUST) { - case DW_EH_PE_abs: - break; - case DW_EH_PE_pcrel: - value += (unsigned long)*pLoc; - break; - case DW_EH_PE_textrel: - if (likely(text_base)) { - value += text_base; - break; - } - dprintk(2, "Text-relative encoding %02X (%p,%p), but zero text base.", - ptrType, *pLoc, end); - return 0; - case DW_EH_PE_datarel: - if (likely(data_base)) { - value += data_base; - break; - } - dprintk(2, "Data-relative encoding %02X (%p,%p), but zero data base.", - ptrType, *pLoc, end); - return 0; - default: - dprintk(2, "Cannot adjust pointer type %02X (%p,%p).", - ptrType, *pLoc, end); - return 0; - } - if ((ptrType & DW_EH_PE_indirect) - && probe_kernel_address((unsigned long *)value, value)) { - dprintk(1, "Cannot read indirect value %lx (%p,%p).", - value, *pLoc, end); - return 0; - } - *pLoc = ptr.p8; - - return value; -} - -static signed fde_pointer_type(const u32 *cie) -{ - const u8 *ptr = (const u8 *)(cie + 2); - unsigned version = *ptr; - - if (version != 1) - return -1; /* unsupported */ - if (*++ptr) { - const char *aug; - const u8 *end = (const u8 *)(cie + 1) + *cie; - uleb128_t len; - - /* check if augmentation size is first (and thus present) */ - if (*ptr != 'z') - return -1; - /* check if augmentation string is nul-terminated */ - if ((ptr = memchr(aug = (const void *)ptr, 0, end - ptr)) == NULL) - return -1; - ++ptr; /* skip terminator */ - get_uleb128(&ptr, end); /* skip code alignment */ - get_sleb128(&ptr, end); /* skip data alignment */ - /* skip return address column */ - version <= 1 ? (void)++ptr : (void)get_uleb128(&ptr, end); - len = get_uleb128(&ptr, end); /* augmentation length */ - if (ptr + len < ptr || ptr + len > end) - return -1; - end = ptr + len; - while (*++aug) { - if (ptr >= end) - return -1; - switch(*aug) { - case 'L': - ++ptr; - break; - case 'P': { - signed ptrType = *ptr++; - - if (!read_pointer(&ptr, end, ptrType, 0, 0) - || ptr > end) - return -1; - } - break; - case 'R': - return *ptr; - default: - return -1; - } - } - } - return DW_EH_PE_native|DW_EH_PE_abs; -} - -static int advance_loc(unsigned long delta, struct unwind_state *state) -{ - state->loc += delta * state->codeAlign; - - return delta > 0; -} - -static void set_rule(uleb128_t reg, - enum item_location where, - uleb128_t value, - struct unwind_state *state) -{ - if (reg < ARRAY_SIZE(state->regs)) { - state->regs[reg].where = where; - state->regs[reg].value = value; - } -} - -static int processCFI(const u8 *start, - const u8 *end, - unsigned long targetLoc, - signed ptrType, - struct unwind_state *state) -{ - union { - const u8 *p8; - const u16 *p16; - const u32 *p32; - } ptr; - int result = 1; - - if (start != state->cieStart) { - state->loc = state->org; - result = processCFI(state->cieStart, state->cieEnd, 0, ptrType, state); - if (targetLoc == 0 && state->label == NULL) - return result; - } - for (ptr.p8 = start; result && ptr.p8 < end; ) { - switch(*ptr.p8 >> 6) { - uleb128_t value; - - case 0: - switch(*ptr.p8++) { - case DW_CFA_nop: - break; - case DW_CFA_set_loc: - state->loc = read_pointer(&ptr.p8, end, ptrType, 0, 0); - if (state->loc == 0) - result = 0; - break; - case DW_CFA_advance_loc1: - result = ptr.p8 < end && advance_loc(*ptr.p8++, state); - break; - case DW_CFA_advance_loc2: - result = ptr.p8 <= end + 2 - && advance_loc(*ptr.p16++, state); - break; - case DW_CFA_advance_loc4: - result = ptr.p8 <= end + 4 - && advance_loc(*ptr.p32++, state); - break; - case DW_CFA_offset_extended: - value = get_uleb128(&ptr.p8, end); - set_rule(value, Memory, get_uleb128(&ptr.p8, end), state); - break; - case DW_CFA_val_offset: - value = get_uleb128(&ptr.p8, end); - set_rule(value, Value, get_uleb128(&ptr.p8, end), state); - break; - case DW_CFA_offset_extended_sf: - value = get_uleb128(&ptr.p8, end); - set_rule(value, Memory, get_sleb128(&ptr.p8, end), state); - break; - case DW_CFA_val_offset_sf: - value = get_uleb128(&ptr.p8, end); - set_rule(value, Value, get_sleb128(&ptr.p8, end), state); - break; - case DW_CFA_restore_extended: - case DW_CFA_undefined: - case DW_CFA_same_value: - set_rule(get_uleb128(&ptr.p8, end), Nowhere, 0, state); - break; - case DW_CFA_register: - value = get_uleb128(&ptr.p8, end); - set_rule(value, - Register, - get_uleb128(&ptr.p8, end), state); - break; - case DW_CFA_remember_state: - if (ptr.p8 == state->label) { - state->label = NULL; - return 1; - } - if (state->stackDepth >= MAX_STACK_DEPTH) { - dprintk(1, "State stack overflow (%p,%p).", ptr.p8, end); - return 0; - } - state->stack[state->stackDepth++] = ptr.p8; - break; - case DW_CFA_restore_state: - if (state->stackDepth) { - const uleb128_t loc = state->loc; - const u8 *label = state->label; - - state->label = state->stack[state->stackDepth - 1]; - memcpy(&state->cfa, &badCFA, sizeof(state->cfa)); - memset(state->regs, 0, sizeof(state->regs)); - state->stackDepth = 0; - result = processCFI(start, end, 0, ptrType, state); - state->loc = loc; - state->label = label; - } else { - dprintk(1, "State stack underflow (%p,%p).", ptr.p8, end); - return 0; - } - break; - case DW_CFA_def_cfa: - state->cfa.reg = get_uleb128(&ptr.p8, end); - /*nobreak*/ - case DW_CFA_def_cfa_offset: - state->cfa.offs = get_uleb128(&ptr.p8, end); - break; - case DW_CFA_def_cfa_sf: - state->cfa.reg = get_uleb128(&ptr.p8, end); - /*nobreak*/ - case DW_CFA_def_cfa_offset_sf: - state->cfa.offs = get_sleb128(&ptr.p8, end) - * state->dataAlign; - break; - case DW_CFA_def_cfa_register: - state->cfa.reg = get_uleb128(&ptr.p8, end); - break; - /*todo case DW_CFA_def_cfa_expression: */ - /*todo case DW_CFA_expression: */ - /*todo case DW_CFA_val_expression: */ - case DW_CFA_GNU_args_size: - get_uleb128(&ptr.p8, end); - break; - case DW_CFA_GNU_negative_offset_extended: - value = get_uleb128(&ptr.p8, end); - set_rule(value, - Memory, - (uleb128_t)0 - get_uleb128(&ptr.p8, end), state); - break; - case DW_CFA_GNU_window_save: - default: - dprintk(1, "Unrecognized CFI op %02X (%p,%p).", ptr.p8[-1], ptr.p8 - 1, end); - result = 0; - break; - } - break; - case 1: - result = advance_loc(*ptr.p8++ & 0x3f, state); - break; - case 2: - value = *ptr.p8++ & 0x3f; - set_rule(value, Memory, get_uleb128(&ptr.p8, end), state); - break; - case 3: - set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state); - break; - } - if (ptr.p8 > end) { - dprintk(1, "Data overrun (%p,%p).", ptr.p8, end); - result = 0; - } - if (result && targetLoc != 0 && targetLoc < state->loc) - return 1; - } - - if (result && ptr.p8 < end) - dprintk(1, "Data underrun (%p,%p).", ptr.p8, end); - - return result - && ptr.p8 == end - && (targetLoc == 0 - || (/*todo While in theory this should apply, gcc in practice omits - everything past the function prolog, and hence the location - never reaches the end of the function. - targetLoc < state->loc &&*/ state->label == NULL)); -} - -/* Unwind to previous to frame. Returns 0 if successful, negative - * number in case of an error. */ -int unwind(struct unwind_frame_info *frame) -{ -#define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs]) - const u32 *fde = NULL, *cie = NULL; - const u8 *ptr = NULL, *end = NULL; - unsigned long pc = UNW_PC(frame) - frame->call_frame, sp; - unsigned long startLoc = 0, endLoc = 0, cfa; - unsigned i; - signed ptrType = -1; - uleb128_t retAddrReg = 0; - const struct unwind_table *table; - struct unwind_state state; - - if (UNW_PC(frame) == 0) - return -EINVAL; - if ((table = find_table(pc)) != NULL - && !(table->size & (sizeof(*fde) - 1))) { - const u8 *hdr = table->header; - unsigned long tableSize; - - smp_rmb(); - if (hdr && hdr[0] == 1) { - switch(hdr[3] & DW_EH_PE_FORM) { - case DW_EH_PE_native: tableSize = sizeof(unsigned long); break; - case DW_EH_PE_data2: tableSize = 2; break; - case DW_EH_PE_data4: tableSize = 4; break; - case DW_EH_PE_data8: tableSize = 8; break; - default: tableSize = 0; break; - } - ptr = hdr + 4; - end = hdr + table->hdrsz; - if (tableSize - && read_pointer(&ptr, end, hdr[1], 0, 0) - == (unsigned long)table->address - && (i = read_pointer(&ptr, end, hdr[2], 0, 0)) > 0 - && i == (end - ptr) / (2 * tableSize) - && !((end - ptr) % (2 * tableSize))) { - do { - const u8 *cur = ptr + (i / 2) * (2 * tableSize); - - startLoc = read_pointer(&cur, - cur + tableSize, - hdr[3], 0, - (unsigned long)hdr); - if (pc < startLoc) - i /= 2; - else { - ptr = cur - tableSize; - i = (i + 1) / 2; - } - } while (startLoc && i > 1); - if (i == 1 - && (startLoc = read_pointer(&ptr, - ptr + tableSize, - hdr[3], 0, - (unsigned long)hdr)) != 0 - && pc >= startLoc) - fde = (void *)read_pointer(&ptr, - ptr + tableSize, - hdr[3], 0, - (unsigned long)hdr); - } - } - if(hdr && !fde) - dprintk(3, "Binary lookup for %lx failed.", pc); - - if (fde != NULL) { - cie = cie_for_fde(fde, table); - ptr = (const u8 *)(fde + 2); - if(cie != NULL - && cie != &bad_cie - && cie != ¬_fde - && (ptrType = fde_pointer_type(cie)) >= 0 - && read_pointer(&ptr, - (const u8 *)(fde + 1) + *fde, - ptrType, 0, 0) == startLoc) { - if (!(ptrType & DW_EH_PE_indirect)) - ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed; - endLoc = startLoc - + read_pointer(&ptr, - (const u8 *)(fde + 1) + *fde, - ptrType, 0, 0); - if(pc >= endLoc) - fde = NULL; - } else - fde = NULL; - if(!fde) - dprintk(1, "Binary lookup result for %lx discarded.", pc); - } - if (fde == NULL) { - for (fde = table->address, tableSize = table->size; - cie = NULL, tableSize > sizeof(*fde) - && tableSize - sizeof(*fde) >= *fde; - tableSize -= sizeof(*fde) + *fde, - fde += 1 + *fde / sizeof(*fde)) { - cie = cie_for_fde(fde, table); - if (cie == &bad_cie) { - cie = NULL; - break; - } - if (cie == NULL - || cie == ¬_fde - || (ptrType = fde_pointer_type(cie)) < 0) - continue; - ptr = (const u8 *)(fde + 2); - startLoc = read_pointer(&ptr, - (const u8 *)(fde + 1) + *fde, - ptrType, 0, 0); - if (!startLoc) - continue; - if (!(ptrType & DW_EH_PE_indirect)) - ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed; - endLoc = startLoc - + read_pointer(&ptr, - (const u8 *)(fde + 1) + *fde, - ptrType, 0, 0); - if (pc >= startLoc && pc < endLoc) - break; - } - if(!fde) - dprintk(3, "Linear lookup for %lx failed.", pc); - } - } - if (cie != NULL) { - memset(&state, 0, sizeof(state)); - state.cieEnd = ptr; /* keep here temporarily */ - ptr = (const u8 *)(cie + 2); - end = (const u8 *)(cie + 1) + *cie; - frame->call_frame = 1; - if ((state.version = *ptr) != 1) - cie = NULL; /* unsupported version */ - else if (*++ptr) { - /* check if augmentation size is first (and thus present) */ - if (*ptr == 'z') { - while (++ptr < end && *ptr) { - switch(*ptr) { - /* check for ignorable (or already handled) - * nul-terminated augmentation string */ - case 'L': - case 'P': - case 'R': - continue; - case 'S': - frame->call_frame = 0; - continue; - default: - break; - } - break; - } - } - if (ptr >= end || *ptr) - cie = NULL; - } - if(!cie) - dprintk(1, "CIE unusable (%p,%p).", ptr, end); - ++ptr; - } - if (cie != NULL) { - /* get code aligment factor */ - state.codeAlign = get_uleb128(&ptr, end); - /* get data aligment factor */ - state.dataAlign = get_sleb128(&ptr, end); - if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end) - cie = NULL; - else if (UNW_PC(frame) % state.codeAlign - || UNW_SP(frame) % sleb128abs(state.dataAlign)) { - dprintk(1, "Input pointer(s) misaligned (%lx,%lx).", - UNW_PC(frame), UNW_SP(frame)); - return -EPERM; - } else { - retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end); - /* skip augmentation */ - if (((const char *)(cie + 2))[1] == 'z') { - uleb128_t augSize = get_uleb128(&ptr, end); - - ptr += augSize; - } - if (ptr > end - || retAddrReg >= ARRAY_SIZE(reg_info) - || REG_INVALID(retAddrReg) - || reg_info[retAddrReg].width != sizeof(unsigned long)) - cie = NULL; - } - if(!cie) - dprintk(1, "CIE validation failed (%p,%p).", ptr, end); - } - if (cie != NULL) { - state.cieStart = ptr; - ptr = state.cieEnd; - state.cieEnd = end; - end = (const u8 *)(fde + 1) + *fde; - /* skip augmentation */ - if (((const char *)(cie + 2))[1] == 'z') { - uleb128_t augSize = get_uleb128(&ptr, end); - - if ((ptr += augSize) > end) - fde = NULL; - } - if(!fde) - dprintk(1, "FDE validation failed (%p,%p).", ptr, end); - } - if (cie == NULL || fde == NULL) { -#ifdef CONFIG_FRAME_POINTER - unsigned long top, bottom; - - if ((UNW_SP(frame) | UNW_FP(frame)) % sizeof(unsigned long)) - return -EPERM; - top = STACK_TOP(frame->task); - bottom = STACK_BOTTOM(frame->task); -# if FRAME_RETADDR_OFFSET < 0 - if (UNW_SP(frame) < top - && UNW_FP(frame) <= UNW_SP(frame) - && bottom < UNW_FP(frame) -# else - if (UNW_SP(frame) > top - && UNW_FP(frame) >= UNW_SP(frame) - && bottom > UNW_FP(frame) -# endif - && !((UNW_SP(frame) | UNW_FP(frame)) - & (sizeof(unsigned long) - 1))) { - unsigned long link; - - if (!probe_kernel_address( - (unsigned long *)(UNW_FP(frame) - + FRAME_LINK_OFFSET), - link) -# if FRAME_RETADDR_OFFSET < 0 - && link > bottom && link < UNW_FP(frame) -# else - && link > UNW_FP(frame) && link < bottom -# endif - && !(link & (sizeof(link) - 1)) - && !probe_kernel_address( - (unsigned long *)(UNW_FP(frame) - + FRAME_RETADDR_OFFSET), UNW_PC(frame))) { - UNW_SP(frame) = UNW_FP(frame) + FRAME_RETADDR_OFFSET -# if FRAME_RETADDR_OFFSET < 0 - - -# else - + -# endif - sizeof(UNW_PC(frame)); - UNW_FP(frame) = link; - return 0; - } - } -#endif - return -ENXIO; - } - state.org = startLoc; - memcpy(&state.cfa, &badCFA, sizeof(state.cfa)); - /* process instructions */ - if (!processCFI(ptr, end, pc, ptrType, &state) - || state.loc > endLoc - || state.regs[retAddrReg].where == Nowhere - || state.cfa.reg >= ARRAY_SIZE(reg_info) - || reg_info[state.cfa.reg].width != sizeof(unsigned long) - || FRAME_REG(state.cfa.reg, unsigned long) % sizeof(unsigned long) - || state.cfa.offs % sizeof(unsigned long)) { - dprintk(1, "Unusable unwind info (%p,%p).", ptr, end); - return -EIO; - } - /* update frame */ -#ifndef CONFIG_AS_CFI_SIGNAL_FRAME - if(frame->call_frame - && !UNW_DEFAULT_RA(state.regs[retAddrReg], state.dataAlign)) - frame->call_frame = 0; -#endif - cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs; - startLoc = min((unsigned long)UNW_SP(frame), cfa); - endLoc = max((unsigned long)UNW_SP(frame), cfa); - if (STACK_LIMIT(startLoc) != STACK_LIMIT(endLoc)) { - startLoc = min(STACK_LIMIT(cfa), cfa); - endLoc = max(STACK_LIMIT(cfa), cfa); - } -#ifndef CONFIG_64BIT -# define CASES CASE(8); CASE(16); CASE(32) -#else -# define CASES CASE(8); CASE(16); CASE(32); CASE(64) -#endif - pc = UNW_PC(frame); - sp = UNW_SP(frame); - for (i = 0; i < ARRAY_SIZE(state.regs); ++i) { - if (REG_INVALID(i)) { - if (state.regs[i].where == Nowhere) - continue; - dprintk(1, "Cannot restore register %u (%d).", - i, state.regs[i].where); - return -EIO; - } - switch(state.regs[i].where) { - default: - break; - case Register: - if (state.regs[i].value >= ARRAY_SIZE(reg_info) - || REG_INVALID(state.regs[i].value) - || reg_info[i].width > reg_info[state.regs[i].value].width) { - dprintk(1, "Cannot restore register %u from register %lu.", - i, state.regs[i].value); - return -EIO; - } - switch(reg_info[state.regs[i].value].width) { -#define CASE(n) \ - case sizeof(u##n): \ - state.regs[i].value = FRAME_REG(state.regs[i].value, \ - const u##n); \ - break - CASES; -#undef CASE - default: - dprintk(1, "Unsupported register size %u (%lu).", - reg_info[state.regs[i].value].width, - state.regs[i].value); - return -EIO; - } - break; - } - } - for (i = 0; i < ARRAY_SIZE(state.regs); ++i) { - if (REG_INVALID(i)) - continue; - switch(state.regs[i].where) { - case Nowhere: - if (reg_info[i].width != sizeof(UNW_SP(frame)) - || &FRAME_REG(i, __typeof__(UNW_SP(frame))) - != &UNW_SP(frame)) - continue; - UNW_SP(frame) = cfa; - break; - case Register: - switch(reg_info[i].width) { -#define CASE(n) case sizeof(u##n): \ - FRAME_REG(i, u##n) = state.regs[i].value; \ - break - CASES; -#undef CASE - default: - dprintk(1, "Unsupported register size %u (%u).", - reg_info[i].width, i); - return -EIO; - } - break; - case Value: - if (reg_info[i].width != sizeof(unsigned long)) { - dprintk(1, "Unsupported value size %u (%u).", - reg_info[i].width, i); - return -EIO; - } - FRAME_REG(i, unsigned long) = cfa + state.regs[i].value - * state.dataAlign; - break; - case Memory: { - unsigned long addr = cfa + state.regs[i].value - * state.dataAlign; - - if ((state.regs[i].value * state.dataAlign) - % sizeof(unsigned long) - || addr < startLoc - || addr + sizeof(unsigned long) < addr - || addr + sizeof(unsigned long) > endLoc) { - dprintk(1, "Bad memory location %lx (%lx).", - addr, state.regs[i].value); - return -EIO; - } - switch(reg_info[i].width) { -#define CASE(n) case sizeof(u##n): \ - probe_kernel_address((u##n *)addr, FRAME_REG(i, u##n)); \ - break - CASES; -#undef CASE - default: - dprintk(1, "Unsupported memory size %u (%u).", - reg_info[i].width, i); - return -EIO; - } - } - break; - } - } - - if (UNW_PC(frame) % state.codeAlign - || UNW_SP(frame) % sleb128abs(state.dataAlign)) { - dprintk(1, "Output pointer(s) misaligned (%lx,%lx).", - UNW_PC(frame), UNW_SP(frame)); - return -EIO; - } - if (pc == UNW_PC(frame) && sp == UNW_SP(frame)) { - dprintk(1, "No progress (%lx,%lx).", pc, sp); - return -EIO; - } - - return 0; -#undef CASES -#undef FRAME_REG -} -EXPORT_SYMBOL(unwind); - -int unwind_init_frame_info(struct unwind_frame_info *info, - struct task_struct *tsk, - /*const*/ struct pt_regs *regs) -{ - info->task = tsk; - info->call_frame = 0; - arch_unw_init_frame_info(info, regs); - - return 0; -} -EXPORT_SYMBOL(unwind_init_frame_info); - -/* - * Prepare to unwind a blocked task. - */ -int unwind_init_blocked(struct unwind_frame_info *info, - struct task_struct *tsk) -{ - info->task = tsk; - info->call_frame = 0; - arch_unw_init_blocked(info); - - return 0; -} -EXPORT_SYMBOL(unwind_init_blocked); - -/* - * Prepare to unwind the currently running thread. - */ -int unwind_init_running(struct unwind_frame_info *info, - asmlinkage int (*callback)(struct unwind_frame_info *, - void *arg), - void *arg) -{ - info->task = current; - info->call_frame = 0; - - return arch_unwind_init_running(info, callback, arg); -} -EXPORT_SYMBOL(unwind_init_running); - -/* - * Unwind until the return pointer is in user-land (or until an error - * occurs). Returns 0 if successful, negative number in case of - * error. - */ -int unwind_to_user(struct unwind_frame_info *info) -{ - while (!arch_unw_user_mode(info)) { - int err = unwind(info); - - if (err < 0) - return err; - } - - return 0; -} -EXPORT_SYMBOL(unwind_to_user); diff --git a/kernel/workqueue.c b/kernel/workqueue.c index db49886bfae1..742cbbe49bdc 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -96,13 +96,13 @@ static inline void set_wq_data(struct work_struct *work, void *wq) BUG_ON(!work_pending(work)); new = (unsigned long) wq | (1UL << WORK_STRUCT_PENDING); - new |= work->management & WORK_STRUCT_FLAG_MASK; - work->management = new; + new |= WORK_STRUCT_FLAG_MASK & *work_data_bits(work); + atomic_long_set(&work->data, new); } static inline void *get_wq_data(struct work_struct *work) { - return (void *) (work->management & WORK_STRUCT_WQ_DATA_MASK); + return (void *) (atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK); } static int __run_work(struct cpu_workqueue_struct *cwq, struct work_struct *work) @@ -133,7 +133,7 @@ static int __run_work(struct cpu_workqueue_struct *cwq, struct work_struct *work list_del_init(&work->entry); spin_unlock_irqrestore(&cwq->lock, flags); - if (!test_bit(WORK_STRUCT_NOAUTOREL, &work->management)) + if (!test_bit(WORK_STRUCT_NOAUTOREL, work_data_bits(work))) work_release(work); f(work); @@ -206,7 +206,7 @@ int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work) { int ret = 0, cpu = get_cpu(); - if (!test_and_set_bit(WORK_STRUCT_PENDING, &work->management)) { + if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) { if (unlikely(is_single_threaded(wq))) cpu = singlethread_cpu; BUG_ON(!list_empty(&work->entry)); @@ -248,7 +248,7 @@ int fastcall queue_delayed_work(struct workqueue_struct *wq, if (delay == 0) return queue_work(wq, work); - if (!test_and_set_bit(WORK_STRUCT_PENDING, &work->management)) { + if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) { BUG_ON(timer_pending(timer)); BUG_ON(!list_empty(&work->entry)); @@ -280,7 +280,7 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, struct timer_list *timer = &dwork->timer; struct work_struct *work = &dwork->work; - if (!test_and_set_bit(WORK_STRUCT_PENDING, &work->management)) { + if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) { BUG_ON(timer_pending(timer)); BUG_ON(!list_empty(&work->entry)); @@ -321,7 +321,7 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq) spin_unlock_irqrestore(&cwq->lock, flags); BUG_ON(get_wq_data(work) != cwq); - if (!test_bit(WORK_STRUCT_NOAUTOREL, &work->management)) + if (!test_bit(WORK_STRUCT_NOAUTOREL, work_data_bits(work))) work_release(work); f(work); diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 818e4589f718..5c2681875b9a 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -354,24 +354,6 @@ config FRAME_POINTER some architectures or if you use external debuggers. If you don't debug the kernel, you can say N. -config UNWIND_INFO - bool "Compile the kernel with frame unwind information" - depends on !IA64 && !PARISC && !ARM - depends on !MODULES || !(MIPS || PPC || SUPERH || V850) - help - If you say Y here the resulting kernel image will be slightly larger - but not slower, and it will give very useful debugging information. - If you don't debug the kernel, you can say N, but we may not be able - to solve problems without frame unwind information or frame pointers. - -config STACK_UNWIND - bool "Stack unwind support" - depends on UNWIND_INFO - depends on X86 - help - This enables more precise stack traces, omitting all unrelated - occurrences of pointers into kernel code from the dump. - config FORCED_INLINING bool "Force gcc to inline functions marked 'inline'" depends on DEBUG_KERNEL diff --git a/lib/fault-inject.c b/lib/fault-inject.c index d143c0faf248..b5a90fc056d3 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c @@ -55,37 +55,7 @@ static bool fail_task(struct fault_attr *attr, struct task_struct *task) #define MAX_STACK_TRACE_DEPTH 32 -#ifdef CONFIG_STACK_UNWIND - -static asmlinkage int fail_stacktrace_callback(struct unwind_frame_info *info, - void *arg) -{ - int depth; - struct fault_attr *attr = arg; - bool found = (attr->require_start == 0 && attr->require_end == ULONG_MAX); - - for (depth = 0; depth < attr->stacktrace_depth - && unwind(info) == 0 && UNW_PC(info); depth++) { - if (arch_unw_user_mode(info)) - break; - if (attr->reject_start <= UNW_PC(info) && - UNW_PC(info) < attr->reject_end) - return false; - if (attr->require_start <= UNW_PC(info) && - UNW_PC(info) < attr->require_end) - found = true; - } - return found; -} - -static bool fail_stacktrace(struct fault_attr *attr) -{ - struct unwind_frame_info info; - - return unwind_init_running(&info, fail_stacktrace_callback, attr); -} - -#elif defined(CONFIG_STACKTRACE) +#if defined(CONFIG_STACKTRACE) static bool fail_stacktrace(struct fault_attr *attr) { diff --git a/mm/mincore.c b/mm/mincore.c index 72890780c1c9..8aca6f7167bb 100644 --- a/mm/mincore.c +++ b/mm/mincore.c @@ -1,7 +1,7 @@ /* * linux/mm/mincore.c * - * Copyright (C) 1994-1999 Linus Torvalds + * Copyright (C) 1994-2006 Linus Torvalds */ /* @@ -38,46 +38,51 @@ static unsigned char mincore_page(struct vm_area_struct * vma, return present; } -static long mincore_vma(struct vm_area_struct * vma, - unsigned long start, unsigned long end, unsigned char __user * vec) +/* + * Do a chunk of "sys_mincore()". We've already checked + * all the arguments, we hold the mmap semaphore: we should + * just return the amount of info we're asked for. + */ +static long do_mincore(unsigned long addr, unsigned char *vec, unsigned long pages) { - long error, i, remaining; - unsigned char * tmp; - - error = -ENOMEM; - if (!vma->vm_file) - return error; - - start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; - if (end > vma->vm_end) - end = vma->vm_end; - end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; + unsigned long i, nr, pgoff; + struct vm_area_struct *vma = find_vma(current->mm, addr); - error = -EAGAIN; - tmp = (unsigned char *) __get_free_page(GFP_KERNEL); - if (!tmp) - return error; + /* + * find_vma() didn't find anything above us, or we're + * in an unmapped hole in the address space: ENOMEM. + */ + if (!vma || addr < vma->vm_start) + return -ENOMEM; - /* (end - start) is # of pages, and also # of bytes in "vec */ - remaining = (end - start), + /* + * Ok, got it. But check whether it's a segment we support + * mincore() on. Right now, we don't do any anonymous mappings. + * + * FIXME: This is just stupid. And returning ENOMEM is + * stupid too. We should just look at the page tables. But + * this is what we've traditionally done, so we'll just + * continue doing it. + */ + if (!vma->vm_file) + return -ENOMEM; - error = 0; - for (i = 0; remaining > 0; remaining -= PAGE_SIZE, i++) { - int j = 0; - long thispiece = (remaining < PAGE_SIZE) ? - remaining : PAGE_SIZE; + /* + * Calculate how many pages there are left in the vma, and + * what the pgoff is for our address. + */ + nr = (vma->vm_end - addr) >> PAGE_SHIFT; + if (nr > pages) + nr = pages; - while (j < thispiece) - tmp[j++] = mincore_page(vma, start++); + pgoff = (addr - vma->vm_start) >> PAGE_SHIFT; + pgoff += vma->vm_pgoff; - if (copy_to_user(vec + PAGE_SIZE * i, tmp, thispiece)) { - error = -EFAULT; - break; - } - } + /* And then we just fill the sucker in.. */ + for (i = 0 ; i < nr; i++, pgoff++) + vec[i] = mincore_page(vma, pgoff); - free_page((unsigned long) tmp); - return error; + return nr; } /* @@ -107,82 +112,50 @@ static long mincore_vma(struct vm_area_struct * vma, asmlinkage long sys_mincore(unsigned long start, size_t len, unsigned char __user * vec) { - int index = 0; - unsigned long end, limit; - struct vm_area_struct * vma; - size_t max; - int unmapped_error = 0; - long error; - - /* check the arguments */ - if (start & ~PAGE_CACHE_MASK) - goto einval; - - limit = TASK_SIZE; - if (start >= limit) - goto enomem; - - if (!len) - return 0; - - max = limit - start; - len = PAGE_CACHE_ALIGN(len); - if (len > max || !len) - goto enomem; + long retval; + unsigned long pages; + unsigned char *tmp; - end = start + len; + /* Check the start address: needs to be page-aligned.. */ + if (start & ~PAGE_CACHE_MASK) + return -EINVAL; - /* check the output buffer whilst holding the lock */ - error = -EFAULT; - down_read(¤t->mm->mmap_sem); + /* ..and we need to be passed a valid user-space range */ + if (!access_ok(VERIFY_READ, (void __user *) start, len)) + return -ENOMEM; - if (!access_ok(VERIFY_WRITE, vec, len >> PAGE_SHIFT)) - goto out; + /* This also avoids any overflows on PAGE_CACHE_ALIGN */ + pages = len >> PAGE_SHIFT; + pages += (len & ~PAGE_MASK) != 0; - /* - * If the interval [start,end) covers some unmapped address - * ranges, just ignore them, but return -ENOMEM at the end. - */ - error = 0; - - vma = find_vma(current->mm, start); - while (vma) { - /* Here start < vma->vm_end. */ - if (start < vma->vm_start) { - unmapped_error = -ENOMEM; - start = vma->vm_start; - } + if (!access_ok(VERIFY_WRITE, vec, pages)) + return -EFAULT; - /* Here vma->vm_start <= start < vma->vm_end. */ - if (end <= vma->vm_end) { - if (start < end) { - error = mincore_vma(vma, start, end, - &vec[index]); - if (error) - goto out; - } - error = unmapped_error; - goto out; + tmp = (void *) __get_free_page(GFP_USER); + if (!tmp) + return -EAGAIN; + + retval = 0; + while (pages) { + /* + * Do at most PAGE_SIZE entries per iteration, due to + * the temporary buffer size. + */ + down_read(¤t->mm->mmap_sem); + retval = do_mincore(start, tmp, min(pages, PAGE_SIZE)); + up_read(¤t->mm->mmap_sem); + + if (retval <= 0) + break; + if (copy_to_user(vec, tmp, retval)) { + retval = -EFAULT; + break; } - - /* Here vma->vm_start <= start < vma->vm_end < end. */ - error = mincore_vma(vma, start, vma->vm_end, &vec[index]); - if (error) - goto out; - index += (vma->vm_end - start) >> PAGE_CACHE_SHIFT; - start = vma->vm_end; - vma = vma->vm_next; + pages -= retval; + vec += retval; + start += retval << PAGE_SHIFT; + retval = 0; } - - /* we found a hole in the area queried if we arrive here */ - error = -ENOMEM; - -out: - up_read(¤t->mm->mmap_sem); - return error; - -einval: - return -EINVAL; -enomem: - return -ENOMEM; + free_page((unsigned long) tmp); + return retval; } diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 6cabf6d8a751..42233df2b099 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -1088,8 +1088,8 @@ out: /* * FIXME: nonblock behaviour looks like it may have a bug. */ -static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, - int addr_len, int flags) +static int __must_check ax25_connect(struct socket *sock, + struct sockaddr *uaddr, int addr_len, int flags) { struct sock *sk = sock->sk; ax25_cb *ax25 = ax25_sk(sk), *ax25t; diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c index 07ac0207eb69..aff3e652c2d1 100644 --- a/net/ax25/ax25_iface.c +++ b/net/ax25/ax25_iface.c @@ -29,17 +29,10 @@ #include <linux/mm.h> #include <linux/interrupt.h> -static struct protocol_struct { - struct protocol_struct *next; - unsigned int pid; - int (*func)(struct sk_buff *, ax25_cb *); -} *protocol_list = NULL; +static struct ax25_protocol *protocol_list; static DEFINE_RWLOCK(protocol_list_lock); -static struct linkfail_struct { - struct linkfail_struct *next; - void (*func)(ax25_cb *, int); -} *linkfail_list = NULL; +static HLIST_HEAD(ax25_linkfail_list); static DEFINE_SPINLOCK(linkfail_lock); static struct listen_struct { @@ -49,36 +42,23 @@ static struct listen_struct { } *listen_list = NULL; static DEFINE_SPINLOCK(listen_lock); -int ax25_protocol_register(unsigned int pid, - int (*func)(struct sk_buff *, ax25_cb *)) +/* + * Do not register the internal protocols AX25_P_TEXT, AX25_P_SEGMENT, + * AX25_P_IP or AX25_P_ARP ... + */ +void ax25_register_pid(struct ax25_protocol *ap) { - struct protocol_struct *protocol; - - if (pid == AX25_P_TEXT || pid == AX25_P_SEGMENT) - return 0; -#ifdef CONFIG_INET - if (pid == AX25_P_IP || pid == AX25_P_ARP) - return 0; -#endif - if ((protocol = kmalloc(sizeof(*protocol), GFP_ATOMIC)) == NULL) - return 0; - - protocol->pid = pid; - protocol->func = func; - write_lock_bh(&protocol_list_lock); - protocol->next = protocol_list; - protocol_list = protocol; + ap->next = protocol_list; + protocol_list = ap; write_unlock_bh(&protocol_list_lock); - - return 1; } -EXPORT_SYMBOL(ax25_protocol_register); +EXPORT_SYMBOL_GPL(ax25_register_pid); void ax25_protocol_release(unsigned int pid) { - struct protocol_struct *s, *protocol; + struct ax25_protocol *s, *protocol; write_lock_bh(&protocol_list_lock); protocol = protocol_list; @@ -110,54 +90,19 @@ void ax25_protocol_release(unsigned int pid) EXPORT_SYMBOL(ax25_protocol_release); -int ax25_linkfail_register(void (*func)(ax25_cb *, int)) +void ax25_linkfail_register(struct ax25_linkfail *lf) { - struct linkfail_struct *linkfail; - - if ((linkfail = kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL) - return 0; - - linkfail->func = func; - spin_lock_bh(&linkfail_lock); - linkfail->next = linkfail_list; - linkfail_list = linkfail; + hlist_add_head(&lf->lf_node, &ax25_linkfail_list); spin_unlock_bh(&linkfail_lock); - - return 1; } EXPORT_SYMBOL(ax25_linkfail_register); -void ax25_linkfail_release(void (*func)(ax25_cb *, int)) +void ax25_linkfail_release(struct ax25_linkfail *lf) { - struct linkfail_struct *s, *linkfail; - spin_lock_bh(&linkfail_lock); - linkfail = linkfail_list; - if (linkfail == NULL) { - spin_unlock_bh(&linkfail_lock); - return; - } - - if (linkfail->func == func) { - linkfail_list = linkfail->next; - spin_unlock_bh(&linkfail_lock); - kfree(linkfail); - return; - } - - while (linkfail != NULL && linkfail->next != NULL) { - if (linkfail->next->func == func) { - s = linkfail->next; - linkfail->next = linkfail->next->next; - spin_unlock_bh(&linkfail_lock); - kfree(s); - return; - } - - linkfail = linkfail->next; - } + hlist_del_init(&lf->lf_node); spin_unlock_bh(&linkfail_lock); } @@ -171,7 +116,7 @@ int ax25_listen_register(ax25_address *callsign, struct net_device *dev) return 0; if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL) - return 0; + return -ENOMEM; listen->callsign = *callsign; listen->dev = dev; @@ -181,7 +126,7 @@ int ax25_listen_register(ax25_address *callsign, struct net_device *dev) listen_list = listen; spin_unlock_bh(&listen_lock); - return 1; + return 0; } EXPORT_SYMBOL(ax25_listen_register); @@ -223,7 +168,7 @@ EXPORT_SYMBOL(ax25_listen_release); int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *) { int (*res)(struct sk_buff *, ax25_cb *) = NULL; - struct protocol_struct *protocol; + struct ax25_protocol *protocol; read_lock(&protocol_list_lock); for (protocol = protocol_list; protocol != NULL; protocol = protocol->next) @@ -242,7 +187,8 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev) spin_lock_bh(&listen_lock); for (listen = listen_list; listen != NULL; listen = listen->next) - if (ax25cmp(&listen->callsign, callsign) == 0 && (listen->dev == dev || listen->dev == NULL)) { + if (ax25cmp(&listen->callsign, callsign) == 0 && + (listen->dev == dev || listen->dev == NULL)) { spin_unlock_bh(&listen_lock); return 1; } @@ -253,17 +199,18 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev) void ax25_link_failed(ax25_cb *ax25, int reason) { - struct linkfail_struct *linkfail; + struct ax25_linkfail *lf; + struct hlist_node *node; spin_lock_bh(&linkfail_lock); - for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next) - (linkfail->func)(ax25, reason); + hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node) + lf->func(ax25, reason); spin_unlock_bh(&linkfail_lock); } int ax25_protocol_is_registered(unsigned int pid) { - struct protocol_struct *protocol; + struct ax25_protocol *protocol; int res = 0; read_lock_bh(&protocol_list_lock); diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index 8580356ace5c..0a0381622b1c 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c @@ -71,7 +71,7 @@ void ax25_rt_device_down(struct net_device *dev) write_unlock(&ax25_route_lock); } -static int ax25_rt_add(struct ax25_routes_struct *route) +static int __must_check ax25_rt_add(struct ax25_routes_struct *route) { ax25_route *ax25_rt; ax25_dev *ax25_dev; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 1aaff0a2e098..2daa0dc19d33 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1325,7 +1325,8 @@ void ip_rt_send_redirect(struct sk_buff *skb) /* Check for load limit; set rate_last to the latest sent * redirect. */ - if (time_after(jiffies, + if (rt->u.dst.rate_tokens == 0 || + time_after(jiffies, (rt->u.dst.rate_last + (ip_rt_redirect_load << rt->u.dst.rate_tokens)))) { icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a1222d6968c4..bf7a22412bcb 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -928,6 +928,7 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr) if (tp->md5sig_info->entries4 == 0) { kfree(tp->md5sig_info->keys4); tp->md5sig_info->keys4 = NULL; + tp->md5sig_info->alloced4 = 0; } else if (tp->md5sig_info->entries4 != i) { /* Need to do some manipulation */ memcpy(&tp->md5sig_info->keys4[i], @@ -1185,7 +1186,7 @@ done_opts: return 0; if (hash_expected && !hash_location) { - LIMIT_NETDEBUG(KERN_INFO "MD5 Hash NOT expected but found " + LIMIT_NETDEBUG(KERN_INFO "MD5 Hash expected but NOT found " "(" NIPQUAD_FMT ", %d)->(" NIPQUAD_FMT ", %d)\n", NIPQUAD(iph->saddr), ntohs(th->source), NIPQUAD(iph->daddr), ntohs(th->dest)); diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index fc3e5eb4bc3f..adcd6131df2a 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig @@ -7,7 +7,7 @@ menu "IPv6: Netfilter Configuration (EXPERIMENTAL)" config NF_CONNTRACK_IPV6 tristate "IPv6 connection tracking support (EXPERIMENTAL)" - depends on EXPERIMENTAL && NF_CONNTRACK + depends on INET && IPV6 && EXPERIMENTAL && NF_CONNTRACK ---help--- Connection tracking keeps a record of what packets have passed through your machine, in order to figure out how they are related @@ -21,6 +21,7 @@ config NF_CONNTRACK_IPV6 config IP6_NF_QUEUE tristate "IP6 Userspace queueing via NETLINK (OBSOLETE)" + depends on INET && IPV6 && NETFILTER && EXPERIMENTAL ---help--- This option adds a queue handler to the kernel for IPv6 @@ -41,7 +42,7 @@ config IP6_NF_QUEUE config IP6_NF_IPTABLES tristate "IP6 tables support (required for filtering)" - depends on NETFILTER_XTABLES + depends on INET && IPV6 && EXPERIMENTAL && NETFILTER_XTABLES help ip6tables is a general, extensible packet identification framework. Currently only the packet filtering and packet mangling subsystem diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 1d50f801f181..43bbe2c9e49a 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -1377,6 +1377,15 @@ static struct notifier_block nr_dev_notifier = { static struct net_device **dev_nr; +static struct ax25_protocol nr_pid = { + .pid = AX25_P_NETROM, + .func = nr_route_frame +}; + +static struct ax25_linkfail nr_linkfail_notifier = { + .func = nr_link_failed, +}; + static int __init nr_proto_init(void) { int i; @@ -1424,8 +1433,8 @@ static int __init nr_proto_init(void) register_netdevice_notifier(&nr_dev_notifier); - ax25_protocol_register(AX25_P_NETROM, nr_route_frame); - ax25_linkfail_register(nr_link_failed); + ax25_register_pid(&nr_pid); + ax25_linkfail_register(&nr_linkfail_notifier); #ifdef CONFIG_SYSCTL nr_register_sysctl(); @@ -1474,7 +1483,7 @@ static void __exit nr_exit(void) nr_unregister_sysctl(); #endif - ax25_linkfail_release(nr_link_failed); + ax25_linkfail_release(&nr_linkfail_notifier); ax25_protocol_release(AX25_P_NETROM); unregister_netdevice_notifier(&nr_dev_notifier); diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c index 9b8eb54971ab..4700d5225b78 100644 --- a/net/netrom/nr_dev.c +++ b/net/netrom/nr_dev.c @@ -128,25 +128,37 @@ static int nr_header(struct sk_buff *skb, struct net_device *dev, unsigned short return -37; } -static int nr_set_mac_address(struct net_device *dev, void *addr) +static int __must_check nr_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = addr; + int err; + + if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len)) + return 0; + + if (dev->flags & IFF_UP) { + err = ax25_listen_register((ax25_address *)sa->sa_data, NULL); + if (err) + return err; - if (dev->flags & IFF_UP) ax25_listen_release((ax25_address *)dev->dev_addr, NULL); + } memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); - if (dev->flags & IFF_UP) - ax25_listen_register((ax25_address *)dev->dev_addr, NULL); - return 0; } static int nr_open(struct net_device *dev) { + int err; + + err = ax25_listen_register((ax25_address *)dev->dev_addr, NULL); + if (err) + return err; + netif_start_queue(dev); - ax25_listen_register((ax25_address *)dev->dev_addr, NULL); + return 0; } diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c index 0096105bcd47..8f88964099ef 100644 --- a/net/netrom/nr_route.c +++ b/net/netrom/nr_route.c @@ -87,8 +87,9 @@ static void nr_remove_neigh(struct nr_neigh *); * Add a new route to a node, and in the process add the node and the * neighbour if it is new. */ -static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax25, - ax25_digi *ax25_digi, struct net_device *dev, int quality, int obs_count) +static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic, + ax25_address *ax25, ax25_digi *ax25_digi, struct net_device *dev, + int quality, int obs_count) { struct nr_node *nr_node; struct nr_neigh *nr_neigh; @@ -406,7 +407,8 @@ static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct n /* * Lock a neighbour with a quality. */ -static int nr_add_neigh(ax25_address *callsign, ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality) +static int __must_check nr_add_neigh(ax25_address *callsign, + ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality) { struct nr_neigh *nr_neigh; @@ -777,9 +779,13 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25) nr_src = (ax25_address *)(skb->data + 0); nr_dest = (ax25_address *)(skb->data + 7); - if (ax25 != NULL) - nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat, - ax25->ax25_dev->dev, 0, sysctl_netrom_obsolescence_count_initialiser); + if (ax25 != NULL) { + ret = nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat, + ax25->ax25_dev->dev, 0, + sysctl_netrom_obsolescence_count_initialiser); + if (ret) + return ret; + } if ((dev = nr_dev_get(nr_dest)) != NULL) { /* Its for me */ if (ax25 == NULL) /* Its from me */ @@ -844,6 +850,7 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25) ret = (nr_neigh->ax25 != NULL); nr_node_unlock(nr_node); nr_node_put(nr_node); + return ret; } diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 08a542855654..9e279464c9d1 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -1314,7 +1314,8 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) if (copy_from_user(&rose_callsign, argp, sizeof(ax25_address))) return -EFAULT; if (ax25cmp(&rose_callsign, &null_ax25_address) != 0) - ax25_listen_register(&rose_callsign, NULL); + return ax25_listen_register(&rose_callsign, NULL); + return 0; case SIOCRSGL2CALL: @@ -1481,6 +1482,15 @@ static struct notifier_block rose_dev_notifier = { static struct net_device **dev_rose; +static struct ax25_protocol rose_pid = { + .pid = AX25_P_ROSE, + .func = rose_route_frame +}; + +static struct ax25_linkfail rose_linkfail_notifier = { + .func = rose_link_failed +}; + static int __init rose_proto_init(void) { int i; @@ -1530,8 +1540,8 @@ static int __init rose_proto_init(void) sock_register(&rose_family_ops); register_netdevice_notifier(&rose_dev_notifier); - ax25_protocol_register(AX25_P_ROSE, rose_route_frame); - ax25_linkfail_register(rose_link_failed); + ax25_register_pid(&rose_pid); + ax25_linkfail_register(&rose_linkfail_notifier); #ifdef CONFIG_SYSCTL rose_register_sysctl(); @@ -1579,7 +1589,7 @@ static void __exit rose_exit(void) rose_rt_free(); ax25_protocol_release(AX25_P_ROSE); - ax25_linkfail_release(rose_link_failed); + ax25_linkfail_release(&rose_linkfail_notifier); if (ax25cmp(&rose_callsign, &null_ax25_address) != 0) ax25_listen_release(&rose_callsign, NULL); diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c index 7c279e2659ec..50824d345fa6 100644 --- a/net/rose/rose_dev.c +++ b/net/rose/rose_dev.c @@ -93,20 +93,34 @@ static int rose_rebuild_header(struct sk_buff *skb) static int rose_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = addr; + int err; - rose_del_loopback_node((rose_address *)dev->dev_addr); + if (!memcpy(dev->dev_addr, sa->sa_data, dev->addr_len)) + return 0; - memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); + if (dev->flags & IFF_UP) { + err = rose_add_loopback_node((rose_address *)dev->dev_addr); + if (err) + return err; + + rose_del_loopback_node((rose_address *)dev->dev_addr); + } - rose_add_loopback_node((rose_address *)dev->dev_addr); + memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); return 0; } static int rose_open(struct net_device *dev) { + int err; + + err = rose_add_loopback_node((rose_address *)dev->dev_addr); + if (err) + return err; + netif_start_queue(dev); - rose_add_loopback_node((rose_address *)dev->dev_addr); + return 0; } diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c index 103b4d38f88a..3e41bd93ab9f 100644 --- a/net/rose/rose_loopback.c +++ b/net/rose/rose_loopback.c @@ -79,7 +79,8 @@ static void rose_loopback_timer(unsigned long param) skb->h.raw = skb->data; - if ((sk = rose_find_socket(lci_o, rose_loopback_neigh)) != NULL) { + sk = rose_find_socket(lci_o, &rose_loopback_neigh); + if (sk) { if (rose_process_rx_frame(sk, skb) == 0) kfree_skb(skb); continue; @@ -87,7 +88,7 @@ static void rose_loopback_timer(unsigned long param) if (frametype == ROSE_CALL_REQUEST) { if ((dev = rose_dev_get(dest)) != NULL) { - if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0) + if (rose_rx_call_request(skb, dev, &rose_loopback_neigh, lci_o) == 0) kfree_skb(skb); } else { kfree_skb(skb); diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index 7252344779a0..8028c0d425dc 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c @@ -46,13 +46,13 @@ static DEFINE_SPINLOCK(rose_neigh_list_lock); static struct rose_route *rose_route_list; static DEFINE_SPINLOCK(rose_route_list_lock); -struct rose_neigh *rose_loopback_neigh; +struct rose_neigh rose_loopback_neigh; /* * Add a new route to a node, and in the process add the node and the * neighbour if it is new. */ -static int rose_add_node(struct rose_route_struct *rose_route, +static int __must_check rose_add_node(struct rose_route_struct *rose_route, struct net_device *dev) { struct rose_node *rose_node, *rose_tmpn, *rose_tmpp; @@ -361,33 +361,30 @@ out: /* * Add the loopback neighbour. */ -int rose_add_loopback_neigh(void) +void rose_add_loopback_neigh(void) { - if ((rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_ATOMIC)) == NULL) - return -ENOMEM; + struct rose_neigh *sn = &rose_loopback_neigh; - rose_loopback_neigh->callsign = null_ax25_address; - rose_loopback_neigh->digipeat = NULL; - rose_loopback_neigh->ax25 = NULL; - rose_loopback_neigh->dev = NULL; - rose_loopback_neigh->count = 0; - rose_loopback_neigh->use = 0; - rose_loopback_neigh->dce_mode = 1; - rose_loopback_neigh->loopback = 1; - rose_loopback_neigh->number = rose_neigh_no++; - rose_loopback_neigh->restarted = 1; + sn->callsign = null_ax25_address; + sn->digipeat = NULL; + sn->ax25 = NULL; + sn->dev = NULL; + sn->count = 0; + sn->use = 0; + sn->dce_mode = 1; + sn->loopback = 1; + sn->number = rose_neigh_no++; + sn->restarted = 1; - skb_queue_head_init(&rose_loopback_neigh->queue); + skb_queue_head_init(&sn->queue); - init_timer(&rose_loopback_neigh->ftimer); - init_timer(&rose_loopback_neigh->t0timer); + init_timer(&sn->ftimer); + init_timer(&sn->t0timer); spin_lock_bh(&rose_neigh_list_lock); - rose_loopback_neigh->next = rose_neigh_list; - rose_neigh_list = rose_loopback_neigh; + sn->next = rose_neigh_list; + rose_neigh_list = sn; spin_unlock_bh(&rose_neigh_list_lock); - - return 0; } /* @@ -421,13 +418,13 @@ int rose_add_loopback_node(rose_address *address) rose_node->mask = 10; rose_node->count = 1; rose_node->loopback = 1; - rose_node->neighbour[0] = rose_loopback_neigh; + rose_node->neighbour[0] = &rose_loopback_neigh; /* Insert at the head of list. Address is always mask=10 */ rose_node->next = rose_node_list; rose_node_list = rose_node; - rose_loopback_neigh->count++; + rose_loopback_neigh.count++; out: spin_unlock_bh(&rose_node_list_lock); @@ -458,7 +455,7 @@ void rose_del_loopback_node(rose_address *address) rose_remove_node(rose_node); - rose_loopback_neigh->count--; + rose_loopback_neigh.count--; out: spin_unlock_bh(&rose_node_list_lock); diff --git a/sound/oss/dmasound/tas3001c.c b/sound/oss/dmasound/tas3001c.c index f227c9f688cc..2f21a3c00374 100644 --- a/sound/oss/dmasound/tas3001c.c +++ b/sound/oss/dmasound/tas3001c.c @@ -50,6 +50,7 @@ struct tas3001c_data_t { int output_id; int speaker_id; struct tas_drce_t drce_state; + struct work_struct change; }; @@ -667,14 +668,13 @@ tas3001c_update_device_parameters(struct tas3001c_data_t *self) } static void -tas3001c_device_change_handler(void *self) +tas3001c_device_change_handler(struct work_struct *work) { - if (self) - tas3001c_update_device_parameters(self); + struct tas3001c_data_t *self; + self = container_of(work, struct tas3001c_data_t, change); + tas3001c_update_device_parameters(self); } -static struct work_struct device_change; - static int tas3001c_output_device_change( struct tas3001c_data_t *self, int device_id, @@ -685,7 +685,7 @@ tas3001c_output_device_change( struct tas3001c_data_t *self, self->output_id=output_id; self->speaker_id=speaker_id; - schedule_work(&device_change); + schedule_work(&self->change); return 0; } @@ -823,7 +823,7 @@ tas3001c_init(struct i2c_client *client) tas3001c_write_biquad_shadow(self, i, j, &tas3001c_eq_unity); - INIT_WORK(&device_change, tas3001c_device_change_handler, self); + INIT_WORK(&self->change, tas3001c_device_change_handler); return 0; } diff --git a/sound/oss/dmasound/tas3004.c b/sound/oss/dmasound/tas3004.c index 82eaaca2db9a..af34fb39bc29 100644 --- a/sound/oss/dmasound/tas3004.c +++ b/sound/oss/dmasound/tas3004.c @@ -48,6 +48,7 @@ struct tas3004_data_t { int output_id; int speaker_id; struct tas_drce_t drce_state; + struct work_struct change; }; #define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000) @@ -914,15 +915,13 @@ tas3004_update_device_parameters(struct tas3004_data_t *self) } static void -tas3004_device_change_handler(void *self) +tas3004_device_change_handler(struct work_struct *work) { - if (!self) return; - - tas3004_update_device_parameters((struct tas3004_data_t *)self); + struct tas3004_data_t *self; + self = container_of(work, struct tas3004_data_t, change); + tas3004_update_device_parameters(self); } -static struct work_struct device_change; - static int tas3004_output_device_change( struct tas3004_data_t *self, int device_id, @@ -933,7 +932,7 @@ tas3004_output_device_change( struct tas3004_data_t *self, self->output_id=output_id; self->speaker_id=speaker_id; - schedule_work(&device_change); + schedule_work(&self->change); return 0; } @@ -1112,7 +1111,7 @@ tas3004_init(struct i2c_client *client) tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW); tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW); - INIT_WORK(&device_change, tas3004_device_change_handler, self); + INIT_WORK(&self->change, tas3004_device_change_handler); return 0; } |