diff options
author | davem <davem> | 2002-02-09 19:49:28 +0000 |
---|---|---|
committer | davem <davem> | 2002-02-09 19:49:28 +0000 |
commit | 80048cfb639d5a43a554f7d7aa1be0152ab24d55 (patch) | |
tree | fcc74fdf27b55ba3fb5f0cf7464316377bb7c16f | |
parent | 35f6bf4a4e288f2ccd8f44cdd1b25384a0ea4f74 (diff) | |
download | netdev-vger-cvs-80048cfb639d5a43a554f7d7aa1be0152ab24d55.tar.gz |
Merge mainline to 2.5.4-pre3
159 files changed, 4049 insertions, 2086 deletions
diff --git a/Documentation/networking/8139too.txt b/Documentation/networking/8139too.txt index 25c7195db..684f54e9c 100644 --- a/Documentation/networking/8139too.txt +++ b/Documentation/networking/8139too.txt @@ -96,7 +96,10 @@ AT-2500TX 10/100 PCI Fast Ethernet Network Adapter Card KTI KF-230TX KTI KF-230TX/2 Lantech FastNet TX +Ovislink Fast Ethernet +Planet ENW-9504 (V.4) 10/100 SMC EZNET 10/100 +UNEX NexNIC ND012C (please add your adapter model to this list) @@ -181,11 +184,18 @@ suggestions welcome) (WIP) Change History -------------- +Version 0.9.23 - In progress + +* New, compile-time conditional for testing better RX reset +* Only account specific RX errors if rx_status is !OK + + Version 0.9.22 - November 8, 2001 * Additional retries before aborting Tx * Do not write other TxConfig bits when writing clear-abort bit. * Ack TxErr intr status after each Tx abort, too. +* Fix oops in interface restart Version 0.9.21 - November 1, 2001 diff --git a/Documentation/networking/dl2k.txt b/Documentation/networking/dl2k.txt index a3ca9ff67..04b18033b 100644 --- a/Documentation/networking/dl2k.txt +++ b/Documentation/networking/dl2k.txt @@ -1,7 +1,7 @@ D-Link DL2000-based Gigabit Ethernet Adapter Installation for Linux - Nov 12, 2001 + Jan 02, 2002 Contents ======== @@ -182,7 +182,7 @@ driver. mtu=packet_size - Specifies the maximum packet size. default is 1500. -media=xxxxxxxxx - Specifies the media type the NIC operates at. +media=media_type - Specifies the media type the NIC operates at. autosense Autosensing active media. 10mbps_hd 10Mbps half duplex. 10mbps_fd 10Mbps full duplex. @@ -195,28 +195,41 @@ media=xxxxxxxxx - Specifies the media type the NIC operates at. 2 10Mbps full duplex. 3 100Mbps half duplex. 4 100Mbps full duplex. - 5 1000Mbps full duplex. - 6 1000Mbps half duplex. + 5 1000Mbps half duplex. + 6 1000Mbps full duplex. By default, the NIC operates at autosense. Note that only 1000mbps_fd and 1000mbps_hd types are available for fiber adapter. -vlan=x - Specifies the VLAN ID. If vlan=0, the +vlan=[0|1] - Specifies the VLAN ID. If vlan=0, the Virtual Local Area Network (VLAN) function is disable. -jumbo=x - Specifies the jumbo frame support. If jumbo=1, +jumbo=[0|1] - Specifies the jumbo frame support. If jumbo=1, the NIC accept jumbo frames. By default, this function is disabled. Jumbo frame usually improve the performance int gigabit. -int_count - Rx frame count each interrupt. -int_timeout - Rx DMA wait time for an interrupt. Proper - values of int_count and int_timeout bring - a conspicuous performance in the fast machine. - Ex. int_count=5 and int_timeout=750 +rx_coalesce=n - Rx frame count each interrupt. +rx_timeout=n - Rx DMA wait time for an interrupt. Proper + values of rx_coalesce and rx_timeout bring + a conspicuous performance in the fast machine. + Ex. rx_coalesce=5 and rx_timeout=750 + +tx_coalesce=n - Tx transmit count each TxComp interrupt. + Setting value larger than 1 will improve + performance, but this is possible to lower + stability in slow UP machines. By default, + tx_coalesce=1. (dl2k) + +tx_flow=[1|0] - Specifies the Tx flow control. If tx_flow=1, + the Tx flow control enable. + +rx_flow=[1|0] - Specifies the Rx flow control. If rx_flow=1, + the Rx flow control enable. + Configuration Script Sample =========================== @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 5 SUBLEVEL = 4 -EXTRAVERSION =-pre2 +EXTRAVERSION =-pre3 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 94a3c1a18..58c0ee067 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -436,8 +436,8 @@ static void srm_console_write(struct console *co, const char *s, static kdev_t srm_console_device(struct console *c) { - /* Huh? */ - return MKDEV(TTY_MAJOR, 64 + c->index); + /* Huh? */ + return mk_kdev(TTY_MAJOR, 64 + c->index); } static int __init srm_console_setup(struct console *co, char *options) diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index ca766f205..1aa7a84c3 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c @@ -196,8 +196,7 @@ no_context: */ out_of_memory: if (current->pid == 1) { - current->policy |= SCHED_YIELD; - schedule(); + yield(); down_read(&mm->mmap_sem); goto survive; } diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 27ca507b4..65bfc86e6 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -43,6 +43,8 @@ #include <linux/config.h> #include <linux/sys.h> #include <linux/linkage.h> +#include <asm/thread_info.h> +#include <asm/errno.h> #include <asm/segment.h> #include <asm/smp.h> @@ -67,24 +69,6 @@ IF_MASK = 0x00000200 NT_MASK = 0x00004000 VM_MASK = 0x00020000 -/* - * these are offsets into the task-struct. - */ -state = 0 -flags = 4 -work = 8 -need_resched = work+0 -syscall_trace = work+1 -sigpending = work+2 -notify_resume = work+3 -addr_limit = 12 -exec_domain = 16 -tsk_ptrace = 24 -cpu = 32 - -ENOSYS = 38 - - #define SAVE_ALL \ cld; \ pushl %es; \ @@ -131,10 +115,6 @@ ENOSYS = 38 .long 3b,6b; \ .previous -#define GET_CURRENT(reg) \ - movl $-8192, reg; \ - andl %esp, reg - ENTRY(lcall7) pushfl # We get a different stack layout with call gates, pushl %eax # which has to be cleaned up later.. @@ -147,8 +127,8 @@ ENTRY(lcall7) movl %ecx,CS(%esp) # movl %esp,%ebx pushl %ebx - andl $-8192,%ebx # GET_CURRENT - movl exec_domain(%ebx),%edx # Get the execution domain + andl $-8192,%ebx # GET_THREAD_INFO + movl TI_EXEC_DOMAIN(%ebx),%edx # Get the execution domain movl 4(%edx),%edx # Get the lcall7 handler for the domain pushl $0x7 call *%edx @@ -168,8 +148,8 @@ ENTRY(lcall27) movl %ecx,CS(%esp) # movl %esp,%ebx pushl %ebx - andl $-8192,%ebx # GET_CURRENT - movl exec_domain(%ebx),%edx # Get the execution domain + andl $-8192,%ebx # GET_THREAD_INFO + movl TI_EXEC_DOMAIN(%ebx),%edx # Get the execution domain movl 4(%edx),%edx # Get the lcall7 handler for the domain pushl $0x27 call *%edx @@ -182,7 +162,7 @@ ENTRY(ret_from_fork) pushl %ebx call SYMBOL_NAME(schedule_tail) addl $4, %esp - GET_CURRENT(%ebx) + GET_THREAD_INFO(%ebx) jmp syscall_exit /* @@ -195,17 +175,17 @@ ENTRY(ret_from_fork) # userspace resumption stub bypassing syscall exit tracing ALIGN ENTRY(ret_from_intr) - GET_CURRENT(%ebx) + GET_THREAD_INFO(%ebx) ret_from_exception: movl EFLAGS(%esp),%eax # mix EFLAGS and CS movb CS(%esp),%al testl $(VM_MASK | 3),%eax jz restore_all # returning to kernel-space or vm86-space ENTRY(resume_userspace) - cli # make sure need_resched and sigpending don't change - # between sampling and the iret - movl work(%ebx),%ecx - andl $0xffff00ff,%ecx # current->work (ignoring syscall_trace) + cli # make sure we don't miss an interrupt setting need_resched + # or sigpending between sampling and the iret + movl TI_FLAGS(%ebx),%ecx + andl $_TIF_WORK_MASK,%ecx # is there any work to be done on int/excp return? jne work_pending jmp restore_all @@ -214,19 +194,19 @@ ENTRY(resume_userspace) ENTRY(system_call) pushl %eax # save orig_eax SAVE_ALL - GET_CURRENT(%ebx) + GET_THREAD_INFO(%ebx) cmpl $(NR_syscalls),%eax jae syscall_badsys - testb $0xff,syscall_trace(%ebx) # system call tracing in operation + testb $_TIF_SYSCALL_TRACE,TI_FLAGS(%ebx) # system call tracing in operation jnz syscall_trace_entry -syscall_traced: +syscall_call: call *SYMBOL_NAME(sys_call_table)(,%eax,4) movl %eax,EAX(%esp) # store the return value syscall_exit: - cli # make sure need_resched and sigpending don't change - # between sampling and the iret - movl work(%ebx),%ecx - testl %ecx,%ecx # current->work + cli # make sure we don't miss an interrupt setting need_resched + # or sigpending between sampling and the iret + movl TI_FLAGS(%ebx),%ecx + testw $_TIF_ALLWORK_MASK,%cx # current->work jne syscall_exit_work restore_all: RESTORE_ALL @@ -234,16 +214,16 @@ restore_all: # perform work that needs to be done immediately before resumption ALIGN work_pending: - testb %cl,%cl # current->work.need_resched + testb $_TIF_NEED_RESCHED,%cl jz work_notifysig work_resched: call SYMBOL_NAME(schedule) - cli # make sure need_resched and sigpending don't change - # between sampling and the iret - movl work(%ebx),%ecx - andl $0xffff00ff,%ecx # ignore the syscall trace counter + cli # make sure we don't miss an interrupt setting need_resched + # or sigpending between sampling and the iret + movl TI_FLAGS(%ebx),%ecx + andl $_TIF_WORK_MASK,%ecx # is there any work to be done other than syscall tracing? jz restore_all - testb %cl,%cl # current->work.need_resched + testb $_TIF_NEED_RESCHED,%cl jnz work_resched work_notifysig: # deal with pending signals and notify-resume requests @@ -273,13 +253,13 @@ syscall_trace_entry: call SYMBOL_NAME(do_syscall_trace) movl ORIG_EAX(%esp),%eax cmpl $(NR_syscalls),%eax - jnae syscall_traced + jnae syscall_call jmp syscall_exit # perform syscall exit tracing ALIGN syscall_exit_work: - testb %ch,%ch # current->work.syscall_trace + testb $_TIF_SYSCALL_TRACE,%cl jz work_pending sti # could let do_syscall_trace() call schedule() instead movl %esp,%eax @@ -319,7 +299,7 @@ error_code: movl $(__KERNEL_DS),%edx movl %edx,%ds movl %edx,%es - GET_CURRENT(%ebx) + GET_THREAD_INFO(%ebx) call *%edi addl $8,%esp jmp ret_from_exception @@ -337,7 +317,7 @@ ENTRY(simd_coprocessor_error) ENTRY(device_not_available) pushl $-1 # mark this as an int SAVE_ALL - GET_CURRENT(%ebx) + GET_THREAD_INFO(%ebx) movl %cr0,%eax testl $0x4,%eax # EM (math emulation bit) jne device_not_available_emulate diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index b52e143f3..02e19533c 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -320,7 +320,7 @@ rp_sidt: ret ENTRY(stack_start) - .long SYMBOL_NAME(init_task_union)+8192 + .long SYMBOL_NAME(init_thread_union)+8192 .long __KERNEL_DS /* This is the default interrupt "handler" :-) */ diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c index 0a2973cfa..0732feda4 100644 --- a/arch/i386/kernel/i387.c +++ b/arch/i386/kernel/i387.c @@ -52,7 +52,7 @@ static inline void __save_init_fpu( struct task_struct *tsk ) asm volatile( "fnsave %0 ; fwait" : "=m" (tsk->thread.i387.fsave) ); } - tsk->flags &= ~PF_USEDFPU; + clear_thread_flag(TIF_USEDFPU); } void save_init_fpu( struct task_struct *tsk ) @@ -65,7 +65,7 @@ void kernel_fpu_begin(void) { struct task_struct *tsk = current; - if (tsk->flags & PF_USEDFPU) { + if (test_thread_flag(TIF_USEDFPU)) { __save_init_fpu(tsk); return; } diff --git a/arch/i386/kernel/init_task.c b/arch/i386/kernel/init_task.c index c7ace3bbe..d12703283 100644 --- a/arch/i386/kernel/init_task.c +++ b/arch/i386/kernel/init_task.c @@ -13,15 +13,22 @@ static struct signal_struct init_signals = INIT_SIGNALS; struct mm_struct init_mm = INIT_MM(init_mm); /* - * Initial task structure. + * Initial thread structure. * * We need to make sure that this is 8192-byte aligned due to the * way process stacks are handled. This is done by having a special * "init_task" linker map entry.. */ -union task_union init_task_union +union thread_union init_thread_union __attribute__((__section__(".data.init_task"))) = - { INIT_TASK(init_task_union.task) }; + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); /* * per-CPU TSS segments. Threads are completely 'soft' on Linux, diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 75637e655..ec7b8a5da 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -220,7 +220,7 @@ static void show(char * str) continue; } esp &= ~(THREAD_SIZE-1); - esp += sizeof(struct task_struct); + esp += sizeof(struct thread_info); show_stack((void*)esp); } printk("\nCPU %d:",cpu); diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index a73237983..f91e5a3bd 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -263,8 +263,9 @@ void nmi_watchdog_tick (struct pt_regs * regs) { /* - * Since current-> is always on the stack, and we always switch - * the stack NMI-atomically, it's safe to use smp_processor_id(). + * Since current_thread_info()-> is always on the stack, and we + * always switch the stack NMI-atomically, it's safe to use + * smp_processor_id(). */ int sum, cpu = smp_processor_id(); diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 50bd8e2ab..b955ff2bb 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -102,15 +102,21 @@ static void poll_idle (void) * Deal with another CPU just having chosen a thread to * run here: */ - oldval = xchg(¤t->work.need_resched, -1); + oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); - if (!oldval) + if (!oldval) { + set_thread_flag(TIF_POLLING_NRFLAG); asm volatile( "2:" - "cmpb $-1, %0;" + "testl %0, %1;" "rep; nop;" "je 2b;" - : :"m" (current->work.need_resched)); + : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags)); + + clear_thread_flag(TIF_POLLING_NRFLAG); + } else { + set_need_resched(); + } } /* @@ -576,7 +582,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, { struct pt_regs * childregs; - childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1; + childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; struct_cpy(childregs, regs); childregs->eax = 0; childregs->esp = esp; @@ -674,6 +680,8 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p) *next = &next_p->thread; struct tss_struct *tss = init_tss + smp_processor_id(); + /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ + unlazy_fpu(prev_p); /* diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index 96466d39a..a6573e39d 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -278,16 +278,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if ((unsigned long) data > _NSIG) break; if (request == PTRACE_SYSCALL) { - if (!(child->ptrace & PT_SYSCALLTRACE)) { - child->ptrace |= PT_SYSCALLTRACE; - child->work.syscall_trace++; - } + set_thread_flag(TIF_SYSCALL_TRACE); } else { - if (child->ptrace & PT_SYSCALLTRACE) { - child->ptrace &= ~PT_SYSCALLTRACE; - child->work.syscall_trace--; - } + clear_thread_flag(TIF_SYSCALL_TRACE); } child->exit_code = data; /* make sure the single step bit is not set. */ @@ -323,10 +317,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ret = -EIO; if ((unsigned long) data > _NSIG) break; - if (child->ptrace & PT_SYSCALLTRACE) { - child->ptrace &= ~PT_SYSCALLTRACE; - child->work.syscall_trace--; - } + clear_thread_flag(TIF_SYSCALL_TRACE); if ((child->ptrace & PT_DTRACE) == 0) { /* Spurious delayed TF traps may occur */ child->ptrace |= PT_DTRACE; @@ -444,7 +435,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) break; } out_tsk: - free_task_struct(child); + put_task_struct(child); out: unlock_kernel(); return ret; @@ -456,8 +447,9 @@ out: __attribute__((regparm(3))) void do_syscall_trace(struct pt_regs *regs, int entryexit) { - if ((current->ptrace & (PT_PTRACED|PT_SYSCALLTRACE)) != - (PT_PTRACED|PT_SYSCALLTRACE)) + if (!test_thread_flag(TIF_SYSCALL_TRACE)) + return; + if (current->ptrace & PT_PTRACED) return; /* the 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ @@ -476,15 +468,3 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit) current->exit_code = 0; } } - -/* notification of userspace execution resumption - * - triggered by current->work.notify_resume - */ -__attribute__((regparm(3))) -void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, - struct task_work work_pending) -{ - /* deal with pending signal delivery */ - if (work_pending.sigpending) - do_signal(regs,oldset); -} diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 66871bc40..691cd19ae 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -2817,7 +2817,7 @@ void __init cpu_init (void) /* * Force FPU initialization: */ - current->flags &= ~PF_USEDFPU; + clear_thread_flag(TIF_USEDFPU); current->used_math = 0; stts(); } diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index f004ea327..fabd3cf91 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c @@ -394,10 +394,10 @@ static void setup_frame(int sig, struct k_sigaction *ka, if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; - err |= __put_user((current->exec_domain - && current->exec_domain->signal_invmap + err |= __put_user((current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap && sig < 32 - ? current->exec_domain->signal_invmap[sig] + ? current_thread_info()->exec_domain->signal_invmap[sig] : sig), &frame->sig); if (err) @@ -464,10 +464,10 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; - err |= __put_user((current->exec_domain - && current->exec_domain->signal_invmap + err |= __put_user((current_thread_info()->exec_domain + && current_thread_info()->exec_domain->signal_invmap && sig < 32 - ? current->exec_domain->signal_invmap[sig] + ? current_thread_info()->exec_domain->signal_invmap[sig] : sig), &frame->sig); err |= __put_user(&frame->info, &frame->pinfo); @@ -712,3 +712,16 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) } return 0; } + +/* + * notification of userspace execution resumption + * - triggered by current->work.notify_resume + */ +__attribute__((regparm(3))) +void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, + __u32 thread_info_flags) +{ + /* deal with pending signal delivery */ + if (thread_info_flags & _TIF_SIGPENDING) + do_signal(regs,oldset); +} diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index e8afcadb7..66417cef4 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -818,7 +818,7 @@ static void __init do_boot_cpu (int apicid) /* So we see what's up */ printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip); - stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle); + stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle->thread_info); /* * This grunge runs the startup process for @@ -1024,7 +1024,7 @@ void __init smp_boot_cpus(void) map_cpu_to_boot_apicid(0, boot_cpu_apicid); global_irq_holder = NO_PROC_ID; - current->cpu = 0; + current_thread_info()->cpu = 0; smp_tune_scheduling(); /* diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 130c45eab..ad68256f8 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -158,7 +158,7 @@ void show_trace_task(struct task_struct *tsk) unsigned long esp = tsk->thread.esp; /* User space on another CPU? */ - if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1)) + if ((esp ^ (unsigned long)tsk->thread_info) & (PAGE_MASK<<1)) return; show_trace((unsigned long *)esp); } @@ -208,8 +208,8 @@ void show_registers(struct pt_regs *regs) regs->esi, regs->edi, regs->ebp, esp); printk("ds: %04x es: %04x ss: %04x\n", regs->xds & 0xffff, regs->xes & 0xffff, ss); - printk("Process %s (pid: %d, stackpage=%08lx)", - current->comm, current->pid, 4096+(unsigned long)current); + printk("Process %s (pid: %d, threadinfo=%p task=%p)", + current->comm, current->pid, current_thread_info(), current); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. @@ -720,7 +720,7 @@ asmlinkage void math_state_restore(struct pt_regs regs) } else { init_fpu(); } - current->flags |= PF_USEDFPU; /* So we fnsave on switch_to() */ + set_thread_flag(TIF_USEDFPU); /* So we fnsave on switch_to() */ } #ifndef CONFIG_MATH_EMULATION diff --git a/arch/i386/lib/getuser.S b/arch/i386/lib/getuser.S index c244721e7..3814c2419 100644 --- a/arch/i386/lib/getuser.S +++ b/arch/i386/lib/getuser.S @@ -8,6 +8,8 @@ * return an error value in addition to the "real" * return value. */ +#include <asm/thread_info.h> + /* * __get_user_X @@ -21,15 +23,12 @@ * as they get called from within inline assembly. */ -addr_limit = 12 - .text .align 4 .globl __get_user_1 __get_user_1: - movl %esp,%edx - andl $0xffffe000,%edx - cmpl addr_limit(%edx),%eax + GET_THREAD_INFO(%edx) + cmpl TI_ADDR_LIMIT(%edx),%eax jae bad_get_user 1: movzbl (%eax),%edx xorl %eax,%eax @@ -39,10 +38,9 @@ __get_user_1: .globl __get_user_2 __get_user_2: addl $1,%eax - movl %esp,%edx jc bad_get_user - andl $0xffffe000,%edx - cmpl addr_limit(%edx),%eax + GET_THREAD_INFO(%edx) + cmpl TI_ADDR_LIMIT(%edx),%eax jae bad_get_user 2: movzwl -1(%eax),%edx xorl %eax,%eax @@ -52,10 +50,9 @@ __get_user_2: .globl __get_user_4 __get_user_4: addl $3,%eax - movl %esp,%edx jc bad_get_user - andl $0xffffe000,%edx - cmpl addr_limit(%edx),%eax + GET_THREAD_INFO(%edx) + cmpl TI_ADDR_LIMIT(%edx),%eax jae bad_get_user 3: movl -3(%eax),%edx xorl %eax,%eax diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 307b498f7..832f396e4 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1133,7 +1133,6 @@ sys_call_table: data8 sys_tkill data8 ia64_ni_syscall data8 ia64_ni_syscall - data8 ia64_ni_syscall data8 ia64_ni_syscall // 1220 data8 ia64_ni_syscall data8 ia64_ni_syscall diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile index 76948285e..3c06af99b 100644 --- a/arch/sparc64/Makefile +++ b/arch/sparc64/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.51 2001-11-17 00:15:27 davem Exp $ +# $Id: Makefile,v 1.52 2002-02-09 19:49:31 davem Exp $ # sparc64/Makefile # # Makefile for the architecture dependent flags and dependencies on the @@ -79,12 +79,8 @@ archclean: rm -f $(TOPDIR)/vmlinux.aout archmrproper: - rm -f $(TOPDIR)/include/asm-sparc64/asm_offsets.h -archdep: check_asm - -check_asm: include/linux/version.h - $(MAKE) -C arch/sparc64/kernel check_asm +archdep: tftpboot.img: $(MAKE) -C arch/sparc64/boot tftpboot.img diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 8ec7b357f..7cfcab034 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -494,6 +494,7 @@ CONFIG_8139TOO=m # CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set +# CONFIG_8139_NEW_RX_RESET is not set CONFIG_SIS900=m CONFIG_EPIC100=m CONFIG_SUNDANCE=m diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 314077877..be72c99d2 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.69 2001-11-19 04:09:53 davem Exp $ +# $Id: Makefile,v 1.70 2002-02-09 19:49:30 davem Exp $ # Makefile for the linux kernel. # # Note! Dependencies are done automagically by 'make dep', which also @@ -56,118 +56,4 @@ else CMODEL_CFLAG := -m64 -mcmodel=medlow endif -check_asm: dummy - @if [ ! -r $(HPATH)/asm/asm_offsets.h ] ; then \ - touch $(HPATH)/asm/asm_offsets.h ; \ - fi - @echo "/* Automatically generated. Do not edit. */" > asm_offsets.h - @echo "#ifndef __ASM_OFFSETS_H__" >> asm_offsets.h - @echo -e "#define __ASM_OFFSETS_H__\n" >> asm_offsets.h - @echo -e "#include <linux/config.h>\n" >> asm_offsets.h - @echo -e "#ifndef CONFIG_SMP\n" >> asm_offsets.h - @echo "#include <linux/config.h>" > tmp.c - @echo "#undef CONFIG_SMP" >> tmp.c - @echo "#include <linux/sched.h>" >> tmp.c - $(CPP) $(CPPFLAGS) -P tmp.c -o tmp.i - @echo "/* Automatically generated. Do not edit. */" > check_asm_data.c - @echo "#include <linux/config.h>" >> check_asm_data.c - @echo "#undef CONFIG_SMP" >> check_asm_data.c - @echo "#include <linux/sched.h>" >> check_asm_data.c - @echo 'unsigned int check_asm_data[] = {' >> check_asm_data.c - $(SH) ./check_asm.sh -data task tmp.i check_asm_data.c - $(SH) ./check_asm.sh -data mm tmp.i check_asm_data.c - $(SH) ./check_asm.sh -data thread tmp.i check_asm_data.c - @echo '};' >> check_asm_data.c - $(CC) $(CPPFLAGS) $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm_data.s check_asm_data.c - @echo "/* Automatically generated. Do not edit. */" > check_asm.c - @echo 'extern int printf(const char *fmt, ...);' >>check_asm.c - @echo 'unsigned int check_asm_data[] = {' >> check_asm.c - $(SH) ./check_asm.sh -ints check_asm_data.s check_asm.c - @echo '};' >> check_asm.c - @echo 'int main(void) {' >> check_asm.c - @echo 'int i = 0;' >> check_asm.c - $(SH) ./check_asm.sh -printf task tmp.i check_asm.c - $(SH) ./check_asm.sh -printf mm tmp.i check_asm.c - $(SH) ./check_asm.sh -printf thread tmp.i check_asm.c - @echo 'return 0; }' >> check_asm.c - @rm -f tmp.[ci] check_asm_data.[cs] - $(HOSTCC) -o check_asm check_asm.c - ./check_asm >> asm_offsets.h - @rm -f check_asm check_asm.c - @echo -e "\n#else /* CONFIG_SMP */\n" >> asm_offsets.h - @echo -e "#ifndef CONFIG_DEBUG_SPINLOCK\n" >>asm_offsets.h - @echo "#include <linux/config.h>" > tmp.c - @echo "#undef CONFIG_SMP" >> tmp.c - @echo "#define CONFIG_SMP 1" >> tmp.c - @echo "#include <linux/sched.h>" >> tmp.c - $(CPP) $(CPPFLAGS) -P tmp.c -o tmp.i - @echo "/* Automatically generated. Do not edit. */" > check_asm_data.c - @echo "#include <linux/config.h>" >> check_asm_data.c - @echo "#undef CONFIG_SMP" >> check_asm_data.c - @echo "#define CONFIG_SMP 1" >> check_asm_data.c - @echo "#include <linux/sched.h>" >> check_asm_data.c - @echo 'unsigned int check_asm_data[] = {' >> check_asm_data.c - $(SH) ./check_asm.sh -data task tmp.i check_asm_data.c - $(SH) ./check_asm.sh -data mm tmp.i check_asm_data.c - $(SH) ./check_asm.sh -data thread tmp.i check_asm_data.c - @echo '};' >> check_asm_data.c - $(CC) $(CPPFLAGS) $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm_data.s check_asm_data.c - @echo "/* Automatically generated. Do not edit. */" > check_asm.c - @echo 'extern int printf(const char *fmt, ...);' >>check_asm.c - @echo 'unsigned int check_asm_data[] = {' >> check_asm.c - $(SH) ./check_asm.sh -ints check_asm_data.s check_asm.c - @echo '};' >> check_asm.c - @echo 'int main(void) {' >> check_asm.c - @echo 'int i = 0;' >> check_asm.c - $(SH) ./check_asm.sh -printf task tmp.i check_asm.c - $(SH) ./check_asm.sh -printf mm tmp.i check_asm.c - $(SH) ./check_asm.sh -printf thread tmp.i check_asm.c - @echo 'return 0; }' >> check_asm.c - @rm -f tmp.[ci] check_asm_data.[cs] - $(HOSTCC) -o check_asm check_asm.c - ./check_asm >> asm_offsets.h - @rm -f check_asm check_asm.c - @echo -e "\n#else /* CONFIG_DEBUG_SPINLOCK */\n" >> asm_offsets.h - @echo "#include <linux/sched.h>" > tmp.c - $(CPP) $(CPPFLAGS) -P -DCONFIG_DEBUG_SPINLOCK tmp.c -o tmp.i - @echo "/* Automatically generated. Do not edit. */" > check_asm_data.c - @echo "#include <linux/config.h>" >> check_asm_data.c - @echo "#undef CONFIG_SMP" >> check_asm_data.c - @echo "#define CONFIG_SMP 1" >> check_asm_data.c - @echo "#include <linux/sched.h>" >> check_asm_data.c - @echo 'unsigned int check_asm_data[] = {' >> check_asm_data.c - $(SH) ./check_asm.sh -data task tmp.i check_asm_data.c - $(SH) ./check_asm.sh -data mm tmp.i check_asm_data.c - $(SH) ./check_asm.sh -data thread tmp.i check_asm_data.c - @echo '};' >> check_asm_data.c - $(CC) $(CPPFLAGS) -DCONFIG_DEBUG_SPINLOCK $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm_data.s check_asm_data.c - @echo "/* Automatically generated. Do not edit. */" > check_asm.c - @echo 'extern int printf(const char *fmt, ...);' >>check_asm.c - @echo 'unsigned int check_asm_data[] = {' >> check_asm.c - $(SH) ./check_asm.sh -ints check_asm_data.s check_asm.c - @echo '};' >> check_asm.c - @echo 'int main(void) {' >> check_asm.c - @echo 'int i = 0;' >> check_asm.c - $(SH) ./check_asm.sh -printf task tmp.i check_asm.c - $(SH) ./check_asm.sh -printf mm tmp.i check_asm.c - $(SH) ./check_asm.sh -printf thread tmp.i check_asm.c - @echo 'return 0; }' >> check_asm.c - @rm -f tmp.[ci] check_asm_data.[cs] - $(HOSTCC) -o check_asm check_asm.c - ./check_asm >> asm_offsets.h - @rm -f check_asm check_asm.c - @echo -e "#endif /* CONFIG_DEBUG_SPINLOCK */\n" >> asm_offsets.h - @echo -e "#endif /* CONFIG_SMP */\n" >> asm_offsets.h - @echo "#endif /* __ASM_OFFSETS_H__ */" >> asm_offsets.h - @if test -r $(HPATH)/asm/asm_offsets.h; then \ - if cmp -s asm_offsets.h $(HPATH)/asm/asm_offsets.h; then \ - echo $(HPATH)/asm/asm_offsets.h is unchanged; \ - rm -f asm_offsets.h; \ - else \ - mv -f asm_offsets.h $(HPATH)/asm/asm_offsets.h; \ - fi; \ - else \ - mv -f asm_offsets.h $(HPATH)/asm/asm_offsets.h; \ - fi - include $(TOPDIR)/Rules.make diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c index f05e57c82..1feb6bd38 100644 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ b/arch/sparc64/kernel/binfmt_aout32.c @@ -314,7 +314,7 @@ beyond_if: current->mm->start_stack = (unsigned long) create_aout32_tables((char *)bprm->p, bprm); - if (!(current->thread.flags & SPARC_FLAG_32BIT)) { + if (!(test_thread_flag(TIF_32BIT))) { unsigned long pgd_cache; pgd_cache = ((unsigned long)current->mm->pgd[0])<<11UL; @@ -323,7 +323,7 @@ beyond_if: : /* no outputs */ : "r" (pgd_cache), "r" (TSB_REG), "i" (ASI_DMMU)); - current->thread.flags |= SPARC_FLAG_32BIT; + set_thread_flag(TIF_32BIT); } start_thread32(regs, ex.a_entry, current->mm->start_stack); if (current->ptrace & PT_PTRACED) diff --git a/arch/sparc64/kernel/binfmt_elf32.c b/arch/sparc64/kernel/binfmt_elf32.c index 6d9e291d4..5b742bc44 100644 --- a/arch/sparc64/kernel/binfmt_elf32.c +++ b/arch/sparc64/kernel/binfmt_elf32.c @@ -149,7 +149,7 @@ struct elf_prpsinfo32 #ifdef CONFIG_BINFMT_ELF32_MODULE #define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE #endif -#define ELF_FLAGS_INIT current->thread.flags |= SPARC_FLAG_32BIT +#define ELF_FLAGS_INIT set_thread_flag(TIF_32BIT) MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit SparcLinux binaries on the Ultra"); MODULE_AUTHOR("Eric Youngdale, David S. Miller, Jakub Jelinek"); diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 4495a1b88..285da2180 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.143 2002-01-31 22:38:25 davem Exp $ +/* $Id: entry.S,v 1.144 2002-02-09 19:49:30 davem Exp $ * arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points. * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) @@ -151,12 +151,12 @@ do_fpdis: add %g0, %g0, %g0 ba,a,pt %xcc, rtrap_clr_l6 -1: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g5 ! Load Group +1: ldub [%g6 + TI_FPSAVED], %g5 ! Load Group wr %g0, FPRS_FEF, %fprs ! LSU Group+4bubbles andcc %g5, FPRS_FEF, %g0 ! IEU1 Group be,a,pt %icc, 1f ! CTI clr %g7 ! IEU0 - ldx [%g6 + AOFF_task_thread + AOFF_thread_gsr], %g7 ! Load Group + ldx [%g6 + TI_GSR], %g7 ! Load Group 1: andcc %g5, FPRS_DL, %g0 ! IEU1 bne,pn %icc, 2f ! CTI fzero %f0 ! FPA @@ -194,11 +194,11 @@ do_fpdis: b,pt %xcc, fpdis_exit2 faddd %f0, %f2, %f60 1: mov SECONDARY_CONTEXT, %g3 - add %g6, AOFF_task_fpregs + 0x80, %g1 + add %g6, TI_FPREGS + 0x80, %g1 faddd %f0, %f2, %f4 fmuld %f0, %f2, %f6 ldxa [%g3] ASI_DMMU, %g5 - add %g6, AOFF_task_fpregs + 0xc0, %g2 + add %g6, TI_FPREGS + 0xc0, %g2 stxa %g0, [%g3] ASI_DMMU membar #Sync faddd %f0, %f2, %f8 @@ -223,10 +223,10 @@ do_fpdis: mov SECONDARY_CONTEXT, %g3 fzero %f34 ldxa [%g3] ASI_DMMU, %g5 - add %g6, AOFF_task_fpregs, %g1 + add %g6, TI_FPREGS, %g1 stxa %g0, [%g3] ASI_DMMU membar #Sync - add %g6, AOFF_task_fpregs + 0x40, %g2 + add %g6, TI_FPREGS + 0x40, %g2 faddd %f32, %f34, %f36 fmuld %f32, %f34, %f38 ldda [%g1] ASI_BLK_S, %f0 ! grrr, where is ASI_BLK_NUCLEUS 8-( @@ -246,7 +246,7 @@ do_fpdis: ba,pt %xcc, fpdis_exit membar #Sync 3: mov SECONDARY_CONTEXT, %g3 - add %g6, AOFF_task_fpregs, %g1 + add %g6, TI_FPREGS, %g1 ldxa [%g3] ASI_DMMU, %g5 mov 0x40, %g2 stxa %g0, [%g3] ASI_DMMU @@ -262,7 +262,7 @@ fpdis_exit: membar #Sync fpdis_exit2: wr %g7, 0, %gsr - ldx [%g6 + AOFF_task_thread + AOFF_thread_xfsr], %fsr + ldx [%g6 + TI_XFSR], %fsr rdpr %tstate, %g3 or %g3, %g4, %g3 ! anal... wrpr %g3, %tstate @@ -285,12 +285,12 @@ do_fpother_check_fitos: /* NOTE: Need to preserve %g7 until we fully commit * to the fitos fixup. */ - stx %fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr] + stx %fsr, [%g6 + TI_XFSR] rdpr %tstate, %g3 andcc %g3, TSTATE_PRIV, %g0 bne,pn %xcc, do_fptrap_after_fsr nop - ldx [%g6 + AOFF_task_thread + AOFF_thread_xfsr], %g3 + ldx [%g6 + TI_XFSR], %g3 srlx %g3, 14, %g1 and %g1, 7, %g1 cmp %g1, 2 ! Unfinished FP-OP @@ -310,7 +310,7 @@ do_fpother_check_fitos: cmp %g1, %g2 bne,pn %xcc, do_fptrap_after_fsr nop - std %f62, [%g6 + AOFF_task_fpregs + (62 * 4)] + std %f62, [%g6 + TI_FPREGS + (62 * 4)] sethi %hi(fitos_table_1), %g1 and %g3, 0x1f, %g2 or %g1, %lo(fitos_table_1), %g1 @@ -396,22 +396,22 @@ fitos_table_2: fdtos %f62, %f31 fitos_emul_fini: - ldd [%g6 + AOFF_task_fpregs + (62 * 4)], %f62 + ldd [%g6 + TI_FPREGS + (62 * 4)], %f62 done .globl do_fptrap .align 32 do_fptrap: - stx %fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr] + stx %fsr, [%g6 + TI_XFSR] do_fptrap_after_fsr: - ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3 + ldub [%g6 + TI_FPSAVED], %g3 rd %fprs, %g1 or %g3, %g1, %g3 - stb %g3, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved] + stb %g3, [%g6 + TI_FPSAVED] rd %gsr, %g3 - stx %g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr] + stx %g3, [%g6 + TI_GSR] mov SECONDARY_CONTEXT, %g3 - add %g6, AOFF_task_fpregs, %g2 + add %g6, TI_FPREGS, %g2 ldxa [%g3] ASI_DMMU, %g5 stxa %g0, [%g3] ASI_DMMU membar #Sync @@ -1384,8 +1384,8 @@ sys_ptrace: add %sp, STACK_BIAS + REGWIN_SZ, %o0 add %o7, 1f-.-4, %o7 nop .align 32 -1: ldub [%curptr + AOFF_task_work + 1], %l5 - andcc %l5, 0xff, %g0 +1: ldx [%curptr + TI_FLAGS], %l5 + andcc %l5, _TIF_SYSCALL_TRACE, %g0 be,pt %icc, rtrap clr %l6 call syscall_trace @@ -1435,14 +1435,14 @@ ret_from_syscall: /* Clear SPARC_FLAG_NEWCHILD, switch_to leaves thread.flags in * %o7 for us. Check performance counter stuff too. */ - andn %o7, SPARC_FLAG_NEWCHILD, %l0 + andn %o7, _TIF_NEWCHILD, %l0 mov %g5, %o0 /* 'prev' */ call schedule_tail - stb %l0, [%g6 + AOFF_task_thread + AOFF_thread_flags] - andcc %l0, SPARC_FLAG_PERFCTR, %g0 + stx %l0, [%g6 + TI_FLAGS] + andcc %l0, _TIF_PERFCTR, %g0 be,pt %icc, 1f nop - ldx [%g6 + AOFF_task_thread + AOFF_thread_pcr_reg], %o7 + ldx [%g6 + TI_PCR], %o7 wr %g0, %o7, %pcr /* Blackbird errata workaround. See commentary in @@ -1465,7 +1465,7 @@ sparc_exit: wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV), %pstate wrpr %g0, 0x0, %otherwin wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV | PSTATE_IE), %pstate ba,pt %xcc, sys_exit - stb %g0, [%g6 + AOFF_task_thread + AOFF_thread_w_saved] + stb %g0, [%g6 + TI_WSAVED] linux_sparc_ni_syscall: sethi %hi(sys_ni_syscall), %l7 @@ -1510,11 +1510,11 @@ linux_sparc_syscall32: mov %i4, %o4 ! IEU1 lduw [%l7 + %l4], %l7 ! Load srl %i1, 0, %o1 ! IEU0 Group - ldub [%curptr + AOFF_task_work + 1], %l0 ! Load + ldx [%curptr + TI_FLAGS], %l0 ! Load mov %i5, %o5 ! IEU1 srl %i2, 0, %o2 ! IEU0 Group - andcc %l0, 0xff, %g0 ! IEU0 Group + andcc %l0, _TIF_SYSCALL_TRACE, %g0 ! IEU0 Group bne,pn %icc, linux_syscall_trace32 ! CTI mov %i0, %l5 ! IEU1 call %l7 ! CTI Group brk forced @@ -1538,11 +1538,11 @@ linux_sparc_syscall: mov %i1, %o1 ! IEU1 lduw [%l7 + %l4], %l7 ! Load 4: mov %i2, %o2 ! IEU0 Group - ldub [%curptr + AOFF_task_work + 1], %l0 ! Load + ldx [%curptr + TI_FLAGS], %l0 ! Load mov %i3, %o3 ! IEU1 mov %i4, %o4 ! IEU0 Group - andcc %l0, 0xff, %g0 ! IEU1 Group+1 bubble + andcc %l0, _TIF_SYSCALL_TRACE, %g0 ! IEU1 Group+1 bubble bne,pn %icc, linux_syscall_trace ! CTI Group mov %i0, %l5 ! IEU0 2: call %l7 ! CTI Group brk forced @@ -1565,7 +1565,7 @@ ret_sys_call: sllx %g2, 32, %g2 bgeu,pn %xcc, 1f - andcc %l0, 0xff, %l6 + andcc %l0, _TIF_SYSCALL_TRACE, %l6 andn %g3, %g2, %g3 /* System call success, clear Carry condition code. */ stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE] bne,pn %icc, linux_syscall_trace2 diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S index db18772a6..70e07eff4 100644 --- a/arch/sparc64/kernel/etrap.S +++ b/arch/sparc64/kernel/etrap.S @@ -1,4 +1,4 @@ -/* $Id: etrap.S,v 1.45 2001-09-07 21:04:40 kanoj Exp $ +/* $Id: etrap.S,v 1.46 2002-02-09 19:49:30 davem Exp $ * etrap.S: Preparing for entry into the kernel on Sparc V9. * * Copyright (C) 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -60,7 +60,7 @@ etrap_irq: rdpr %tstate, %g1 ! Single Group wrpr %g0, 0, %canrestore ! Single Group+4bubbles sll %g2, 3, %g2 ! IEU0 Group mov 1, %l5 ! IEU1 - stb %l5, [%l6 + AOFF_task_thread + AOFF_thread_fpdepth] ! Store + stb %l5, [%l6 + TI_FPDEPTH] ! Store wrpr %g3, 0, %otherwin ! Single Group+4bubbles wrpr %g2, 0, %wstate ! Single Group+4bubbles @@ -98,11 +98,11 @@ etrap_irq: rdpr %tstate, %g1 ! Single Group nop nop -3: ldub [%l6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5 ! Load Group - add %l6, AOFF_task_thread + AOFF_thread_fpsaved + 1, %l4 ! IEU0 +3: ldub [%l6 + TI_FPDEPTH], %l5 ! Load Group + add %l6, TI_FPSAVED + 1, %l4 ! IEU0 srl %l5, 1, %l3 ! IEU0 Group add %l5, 2, %l5 ! IEU1 - stb %l5, [%l6 + AOFF_task_thread + AOFF_thread_fpdepth] ! Store + stb %l5, [%l6 + TI_FPDEPTH] ! Store ba,pt %xcc, 2b ! CTI stb %g0, [%l4 + %l3] ! Store Group nop diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index 0bc9d83b7..e667289e7 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.86 2001-12-05 01:02:16 davem Exp $ +/* $Id: head.S,v 1.87 2002-02-09 19:49:31 davem Exp $ * head.S: Initial boot code for the Sparc64 port of Linux. * * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu) @@ -10,7 +10,7 @@ #include <linux/config.h> #include <linux/version.h> #include <linux/errno.h> -#include <asm/asm_offsets.h> +#include <asm/thread_info.h> #include <asm/asi.h> #include <asm/pstate.h> #include <asm/ptrace.h> @@ -491,8 +491,8 @@ spitfire_tlb_fixup: stw %g2, [%g5 + %lo(tlb_type)] tlb_fixup_done: - sethi %hi(init_task_union), %g6 - or %g6, %lo(init_task_union), %g6 + sethi %hi(init_thread_union), %g6 + or %g6, %lo(init_thread_union), %g6 mov %sp, %l6 mov %o4, %l7 diff --git a/arch/sparc64/kernel/init_task.c b/arch/sparc64/kernel/init_task.c index ae8150a32..1def38180 100644 --- a/arch/sparc64/kernel/init_task.c +++ b/arch/sparc64/kernel/init_task.c @@ -12,17 +12,25 @@ static struct signal_struct init_signals = INIT_SIGNALS; struct mm_struct init_mm = INIT_MM(init_mm); /* .text section in head.S is aligned at 2 page boundry and this gets linked - * right after that so that the init_task_union is aligned properly as well. + * right after that so that the init_thread_union is aligned properly as well. * We really don't need this special alignment like the Intel does, but * I do it anyways for completeness. */ __asm__ (".text"); -union task_union init_task_union = { INIT_TASK(init_task_union.task) }; +union thread_union init_thread_union = { INIT_THREAD_INFO(init_task) }; /* - * This is to make the init_task+stack of the right size for >8k pagesize. - * The definition of task_union in sched.h makes it 16k wide. + * This is to make the init_thread+stack be the right size for >8k pagesize. + * The definition of thread_union in sched.h makes it 16k wide. */ #if PAGE_SHIFT != 13 -char init_task_stack[THREAD_SIZE - INIT_TASK_SIZE] = { 0 }; +char init_task_stack[THREAD_SIZE - INIT_THREAD_SIZE] = { 0 }; #endif + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +__asm__(".data"); +struct task_struct init_task = INIT_TASK(init_task); diff --git a/arch/sparc64/kernel/itlb_base.S b/arch/sparc64/kernel/itlb_base.S index d070c9ed0..0f2cbe238 100644 --- a/arch/sparc64/kernel/itlb_base.S +++ b/arch/sparc64/kernel/itlb_base.S @@ -1,4 +1,4 @@ -/* $Id: itlb_base.S,v 1.11 2001-08-17 04:55:09 kanoj Exp $ +/* $Id: itlb_base.S,v 1.12 2002-02-09 19:49:30 davem Exp $ * itlb_base.S: Front end to ITLB miss replacement strategy. * This is included directly into the trap table. * @@ -51,8 +51,8 @@ rdpr %tpc, %g5 ! And load faulting VA mov FAULT_CODE_ITLB, %g4 ! It was read from ITLB sparc64_realfault_common: ! Called by TL0 dtlb_miss too - stb %g4, [%g6 + AOFF_task_thread + AOFF_thread_fault_code] - stx %g5, [%g6 + AOFF_task_thread + AOFF_thread_fault_address] + stb %g4, [%g6 + TI_FAULT_CODE] + stx %g5, [%g6 + TI_FAULT_ADDR] ba,pt %xcc, etrap ! Save state 1: rd %pc, %g7 ! ... nop diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 1a30ec0bc..a06f21bdc 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.130 2002-01-31 03:30:06 davem Exp $ +/* $Id: process.c,v 1.131 2002-02-09 19:49:30 davem Exp $ * arch/sparc64/kernel/process.c * * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) @@ -79,10 +79,13 @@ int cpu_idle(void) #define unidle_me() (cpu_data[smp_processor_id()].idle_volume = 0) int cpu_idle(void) { + set_thread_flag(TIF_POLLING_NRFLAG); while(1) { if (need_resched()) { unidle_me(); + clear_thread_flag(TIF_POLLING_NRFLAG); schedule(); + set_thread_flag(TIF_POLLING_NRFLAG); check_pgt_cache(); } idle_me_harder(); @@ -176,7 +179,7 @@ static void show_regwindow(struct pt_regs *regs) struct reg_window r_w; mm_segment_t old_fs; - if ((regs->tstate & TSTATE_PRIV) || !(current->thread.flags & SPARC_FLAG_32BIT)) { + if ((regs->tstate & TSTATE_PRIV) || !(test_thread_flag(TIF_32BIT))) { __asm__ __volatile__ ("flushw"); rw = (struct reg_window *)(regs->u_regs[14] + STACK_BIAS); if (!(regs->tstate & TSTATE_PRIV)) { @@ -364,34 +367,28 @@ void show_regs32(struct pt_regs32 *regs) regs->u_regs[15]); } -void show_thread(struct thread_struct *thread) +unsigned long thread_saved_pc(struct thread_info *ti) { - int i; - -#if 0 - printk("kregs: 0x%016lx\n", (unsigned long)thread->kregs); - show_regs(thread->kregs); -#endif - printk("ksp: 0x%016lx\n", thread->ksp); - - if (thread->w_saved) { - for (i = 0; i < NSWINS; i++) { - if (!thread->rwbuf_stkptrs[i]) - continue; - printk("reg_window[%d]:\n", i); - printk("stack ptr: 0x%016lx\n", thread->rwbuf_stkptrs[i]); + unsigned long ret = 0xdeadbeefUL; + + if (ti && ti->ksp) { + unsigned long *sp; + sp = (unsigned long *)(ti->ksp + STACK_BIAS); + if (((unsigned long)sp & (sizeof(long) - 1)) == 0UL && + sp[14]) { + unsigned long *fp; + fp = (unsigned long *)(sp[14] + STACK_BIAS); + if (((unsigned long)fp & (sizeof(long) - 1)) == 0UL) + ret = fp[15]; } - printk("w_saved: 0x%04x\n", thread->w_saved); } - - printk("flags: 0x%08x\n", thread->flags); - printk("current_ds: 0x%x\n", thread->current_ds.seg); + return ret; } /* Free current thread data structures etc.. */ void exit_thread(void) { - struct thread_struct *t = ¤t->thread; + struct thread_info *t = current_thread_info(); if (t->utraps) { if (t->utraps[0] < 2) @@ -400,22 +397,20 @@ void exit_thread(void) t->utraps[0]--; } - /* Turn off performance counters if on. */ - if (t->flags & SPARC_FLAG_PERFCTR) { + if (test_and_clear_thread_flag(TIF_PERFCTR)) { t->user_cntd0 = t->user_cntd1 = NULL; t->pcr_reg = 0; - t->flags &= ~(SPARC_FLAG_PERFCTR); write_pcr(0); } } void flush_thread(void) { - struct thread_struct *t = ¤t->thread; + struct thread_info *t = current_thread_info(); - if (current->mm) { - if (t->flags & SPARC_FLAG_32BIT) { - struct mm_struct *mm = current->mm; + if (t->task->mm) { + if (test_thread_flag(TIF_32BIT)) { + struct mm_struct *mm = t->task->mm; pgd_t *pgd0 = &mm->pgd[0]; unsigned long pgd_cache; @@ -434,24 +429,23 @@ void flush_thread(void) "i" (ASI_DMMU)); } } - t->w_saved = 0; + set_thread_wsaved(0); /* Turn off performance counters if on. */ - if (t->flags & SPARC_FLAG_PERFCTR) { + if (test_and_clear_thread_flag(TIF_PERFCTR)) { t->user_cntd0 = t->user_cntd1 = NULL; t->pcr_reg = 0; - t->flags &= ~(SPARC_FLAG_PERFCTR); write_pcr(0); } /* Clear FPU register state. */ t->fpsaved[0] = 0; - if (t->current_ds.seg != ASI_AIUS) + if (get_thread_current_ds() != ASI_AIUS) set_fs(USER_DS); /* Init new signal delivery disposition. */ - t->flags &= ~SPARC_FLAG_NEWSIGNALS; + clear_thread_flag(TIF_NEWSIGNALS); } /* It's a bit more tricky when 64-bit tasks are involved... */ @@ -459,7 +453,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) { unsigned long fp, distance, rval; - if (!(current->thread.flags & SPARC_FLAG_32BIT)) { + if (!(test_thread_flag(TIF_32BIT))) { csp += STACK_BIAS; psp += STACK_BIAS; __get_user(fp, &(((struct reg_window *)psp)->ins[6])); @@ -477,7 +471,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) rval = (csp - distance); if (copy_in_user(rval, psp, distance)) rval = 0; - else if (current->thread.flags & SPARC_FLAG_32BIT) { + else if (test_thread_flag(TIF_32BIT)) { if (put_user(((u32)csp), &(((struct reg_window32 *)rval)->ins[6]))) rval = 0; } else { @@ -493,7 +487,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) /* Standard stuff. */ static inline void shift_window_buffer(int first_win, int last_win, - struct thread_struct *t) + struct thread_info *t) { int i; @@ -506,15 +500,15 @@ static inline void shift_window_buffer(int first_win, int last_win, void synchronize_user_stack(void) { - struct thread_struct *t = ¤t->thread; + struct thread_info *t = current_thread_info(); unsigned long window; flush_user_windows(); - if ((window = t->w_saved) != 0) { + if ((window = get_thread_wsaved()) != 0) { int winsize = REGWIN_SZ; int bias = 0; - if (t->flags & SPARC_FLAG_32BIT) + if (test_thread_flag(TIF_32BIT)) winsize = REGWIN32_SZ; else bias = STACK_BIAS; @@ -525,8 +519,8 @@ void synchronize_user_stack(void) struct reg_window *rwin = &t->reg_window[window]; if (!copy_to_user((char *)sp, rwin, winsize)) { - shift_window_buffer(window, t->w_saved - 1, t); - t->w_saved--; + shift_window_buffer(window, get_thread_wsaved() - 1, t); + set_thread_wsaved(get_thread_wsaved() - 1); } } while (window--); } @@ -534,18 +528,18 @@ void synchronize_user_stack(void) void fault_in_user_windows(void) { - struct thread_struct *t = ¤t->thread; + struct thread_info *t = current_thread_info(); unsigned long window; int winsize = REGWIN_SZ; int bias = 0; - if (t->flags & SPARC_FLAG_32BIT) + if (test_thread_flag(TIF_32BIT)) winsize = REGWIN32_SZ; else bias = STACK_BIAS; flush_user_windows(); - window = t->w_saved; + window = get_thread_wsaved(); if (window != 0) { window -= 1; @@ -557,11 +551,11 @@ void fault_in_user_windows(void) goto barf; } while (window--); } - t->w_saved = 0; + set_thread_wsaved(0); return; barf: - t->w_saved = window + 1; + set_thread_wsaved(window + 1); do_exit(SIGILL); } @@ -581,21 +575,23 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { - struct thread_struct *t = &p->thread; + struct thread_info *t = p->thread_info; char *child_trap_frame; #ifdef CONFIG_DEBUG_SPINLOCK - t->smp_lock_count = 0; - t->smp_lock_pc = 0; + p->thread.smp_lock_count = 0; + p->thread.smp_lock_pc = 0; #endif /* Calculate offset to stack_frame & pt_regs */ - child_trap_frame = ((char *)p) + (THREAD_SIZE - (TRACEREG_SZ+REGWIN_SZ)); + child_trap_frame = ((char *)t) + (THREAD_SIZE - (TRACEREG_SZ+REGWIN_SZ)); memcpy(child_trap_frame, (((struct reg_window *)regs)-1), (TRACEREG_SZ+REGWIN_SZ)); + + t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) | + _TIF_NEWCHILD | + (((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT); t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS; - t->flags |= SPARC_FLAG_NEWCHILD; t->kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct reg_window)); - t->cwp = (regs->tstate + 1) & TSTATE_CWP; t->fpsaved[0] = 0; if (regs->tstate & TSTATE_PRIV) { @@ -604,25 +600,25 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, * disable performance counters in the child because the * address space and protection realm are changing. */ - if (t->flags & SPARC_FLAG_PERFCTR) { + if (t->flags & _TIF_PERFCTR) { t->user_cntd0 = t->user_cntd1 = NULL; t->pcr_reg = 0; - t->flags &= ~(SPARC_FLAG_PERFCTR); + t->flags &= ~_TIF_PERFCTR; } - t->kregs->u_regs[UREG_FP] = p->thread.ksp; - t->current_ds = KERNEL_DS; + t->kregs->u_regs[UREG_FP] = t->ksp; + t->flags |= ((long)ASI_P << TI_FLAG_CURRENT_DS_SHIFT); flush_register_windows(); memcpy((void *)(t->ksp + STACK_BIAS), (void *)(regs->u_regs[UREG_FP] + STACK_BIAS), sizeof(struct reg_window)); - t->kregs->u_regs[UREG_G6] = (unsigned long) p; + t->kregs->u_regs[UREG_G6] = (unsigned long) t; } else { - if (t->flags & SPARC_FLAG_32BIT) { + if (t->flags & _TIF_32BIT) { sp &= 0x00000000ffffffffUL; regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; } t->kregs->u_regs[UREG_FP] = sp; - t->current_ds = USER_DS; + t->flags |= ((long)ASI_AIUS << TI_FLAG_CURRENT_DS_SHIFT); if (sp != regs->u_regs[UREG_FP]) { unsigned long csp; @@ -688,33 +684,10 @@ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) */ void dump_thread(struct pt_regs * regs, struct user * dump) { -#if 1 /* Only should be used for SunOS and ancient a.out - * SparcLinux binaries... Fixme some day when bored. - * But for now at least plug the security hole :-) + * SparcLinux binaries... Not worth implementing. */ memset(dump, 0, sizeof(struct user)); -#else - unsigned long first_stack_page; - dump->magic = SUNOS_CORE_MAGIC; - dump->len = sizeof(struct user); - dump->regs.psr = regs->psr; - dump->regs.pc = regs->pc; - dump->regs.npc = regs->npc; - dump->regs.y = regs->y; - /* fuck me plenty */ - memcpy(&dump->regs.regs[0], ®s->u_regs[1], (sizeof(unsigned long) * 15)); - dump->u_tsize = (((unsigned long) current->mm->end_code) - - ((unsigned long) current->mm->start_code)) & ~(PAGE_SIZE - 1); - dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))); - dump->u_dsize -= dump->u_tsize; - dump->u_dsize &= ~(PAGE_SIZE - 1); - first_stack_page = (regs->u_regs[UREG_FP] & ~(PAGE_SIZE - 1)); - dump->u_ssize = (TASK_SIZE - first_stack_page) & ~(PAGE_SIZE - 1); - memcpy(&dump->fpu.fpstatus.fregs.regs[0], ¤t->thread.float_regs[0], (sizeof(unsigned long) * 32)); - dump->fpu.fpstatus.fsr = current->thread.fsr; - dump->fpu.fpstatus.flags = dump->fpu.fpstatus.extra = 0; -#endif } typedef struct { @@ -735,10 +708,10 @@ typedef struct { */ int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs) { - unsigned long *kfpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs); - unsigned long fprs = current->thread.fpsaved[0]; + unsigned long *kfpregs = current_thread_info()->fpregs; + unsigned long fprs = current_thread_info()->fpsaved[0]; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { elf_fpregset_t32 *fpregs32 = (elf_fpregset_t32 *)fpregs; if (fprs & FPRS_DL) @@ -752,7 +725,7 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs) memset(&fpregs32->pr_q[0], 0, (sizeof(unsigned int) * 64)); if (fprs & FPRS_FEF) { - fpregs32->pr_fsr = (unsigned int) current->thread.xfsr[0]; + fpregs32->pr_fsr = (unsigned int) current_thread_info()->xfsr[0]; fpregs32->pr_en = 1; } else { fpregs32->pr_fsr = 0; @@ -772,8 +745,8 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs) memset(&fpregs->pr_regs[16], 0, sizeof(unsigned int) * 32); if(fprs & FPRS_FEF) { - fpregs->pr_fsr = current->thread.xfsr[0]; - fpregs->pr_gsr = current->thread.gsr[0]; + fpregs->pr_fsr = current_thread_info()->xfsr[0]; + fpregs->pr_gsr = current_thread_info()->gsr[0]; } else { fpregs->pr_fsr = fpregs->pr_gsr = 0; } @@ -806,8 +779,8 @@ asmlinkage int sparc_execve(struct pt_regs *regs) putname(filename); if (!error) { fprs_write(0); - current->thread.xfsr[0] = 0; - current->thread.fpsaved[0] = 0; + current_thread_info()->xfsr[0] = 0; + current_thread_info()->fpsaved[0] = 0; regs->tstate &= ~TSTATE_PEF; } out: diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index 6ccc59685..08937d3b9 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -27,8 +27,6 @@ #include <asm/visasm.h> #include <asm/spitfire.h> -#define MAGIC_CONSTANT 0x80000000 - /* Returning from ptrace is a bit tricky because the syscall return * low level code assumes any value returned which is negative and * is a valid errno will mean setting the condition codes to indicate @@ -53,7 +51,7 @@ static inline void pt_succ_return(struct pt_regs *regs, unsigned long value) static inline void pt_succ_return_linux(struct pt_regs *regs, unsigned long value, long *addr) { - if (current->thread.flags & SPARC_FLAG_32BIT) { + if (test_thread_flag(TIF_32BIT)) { if (put_user(value, (unsigned int *)addr)) return pt_error_return(regs, EFAULT); } else { @@ -125,7 +123,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) unsigned long addr2 = regs->u_regs[UREG_I4]; struct task_struct *child; - if (current->thread.flags & SPARC_FLAG_32BIT) { + if (test_thread_flag(TIF_32BIT)) { addr &= 0xffffffffUL; data &= 0xffffffffUL; addr2 &= 0xffffffffUL; @@ -201,7 +199,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) goto out_tsk; } - if (!(child->thread.flags & SPARC_FLAG_32BIT) && + if (!(test_thread_flag(TIF_32BIT)) && ((request == PTRACE_READDATA64) || (request == PTRACE_WRITEDATA64) || (request == PTRACE_READTEXT64) || @@ -223,7 +221,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) int res, copied; res = -EIO; - if (current->thread.flags & SPARC_FLAG_32BIT) { + if (test_thread_flag(TIF_32BIT)) { copied = access_process_vm(child, addr, &tmp32, sizeof(tmp32), 0); tmp64 = (unsigned long) tmp32; @@ -248,7 +246,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) unsigned int tmp32; int copied, res = -EIO; - if (current->thread.flags & SPARC_FLAG_32BIT) { + if (test_thread_flag(TIF_32BIT)) { tmp32 = data; copied = access_process_vm(child, addr, &tmp32, sizeof(tmp32), 1); @@ -270,7 +268,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_GETREGS: { struct pt_regs32 *pregs = (struct pt_regs32 *) addr; - struct pt_regs *cregs = child->thread.kregs; + struct pt_regs *cregs = child->thread_info->kregs; int rval; if (__put_user(tstate_to_psr(cregs->tstate), (&pregs->psr)) || @@ -294,11 +292,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_GETREGS64: { struct pt_regs *pregs = (struct pt_regs *) addr; - struct pt_regs *cregs = child->thread.kregs; + struct pt_regs *cregs = child->thread_info->kregs; unsigned long tpc = cregs->tpc; int rval; - if ((child->thread.flags & SPARC_FLAG_32BIT) != 0) + if ((child->thread_info->flags & _TIF_32BIT) != 0) tpc &= 0xffffffff; if (__put_user(cregs->tstate, (&pregs->tstate)) || __put_user(tpc, (&pregs->tpc)) || @@ -321,7 +319,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_SETREGS: { struct pt_regs32 *pregs = (struct pt_regs32 *) addr; - struct pt_regs *cregs = child->thread.kregs; + struct pt_regs *cregs = child->thread_info->kregs; unsigned int psr, pc, npc, y; int i; @@ -354,7 +352,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) case PTRACE_SETREGS64: { struct pt_regs *pregs = (struct pt_regs *) addr; - struct pt_regs *cregs = child->thread.kregs; + struct pt_regs *cregs = child->thread_info->kregs; unsigned long tstate, tpc, tnpc, y; int i; @@ -368,7 +366,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) pt_error_return(regs, EFAULT); goto out_tsk; } - if ((child->thread.flags & SPARC_FLAG_32BIT) != 0) { + if ((child->thread_info->flags & _TIF_32BIT) != 0) { tpc &= 0xffffffff; tnpc &= 0xffffffff; } @@ -402,11 +400,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs) unsigned int insn; } fpq[16]; } *fps = (struct fps *) addr; - unsigned long *fpregs = (unsigned long *)(((char *)child) + AOFF_task_fpregs); + unsigned long *fpregs = child->thread_info->fpregs; if (copy_to_user(&fps->regs[0], fpregs, (32 * sizeof(unsigned int))) || - __put_user(child->thread.xfsr[0], (&fps->fsr)) || + __put_user(child->thread_info->xfsr[0], (&fps->fsr)) || __put_user(0, (&fps->fpqd)) || __put_user(0, (&fps->flags)) || __put_user(0, (&fps->extra)) || @@ -423,11 +421,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs) unsigned int regs[64]; unsigned long fsr; } *fps = (struct fps *) addr; - unsigned long *fpregs = (unsigned long *)(((char *)child) + AOFF_task_fpregs); + unsigned long *fpregs = child->thread_info->fpregs; if (copy_to_user(&fps->regs[0], fpregs, (64 * sizeof(unsigned int))) || - __put_user(child->thread.xfsr[0], (&fps->fsr))) { + __put_user(child->thread_info->xfsr[0], (&fps->fsr))) { pt_error_return(regs, EFAULT); goto out_tsk; } @@ -447,7 +445,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) unsigned int insn; } fpq[16]; } *fps = (struct fps *) addr; - unsigned long *fpregs = (unsigned long *)(((char *)child) + AOFF_task_fpregs); + unsigned long *fpregs = child->thread_info->fpregs; unsigned fsr; if (copy_from_user(fpregs, &fps->regs[0], @@ -456,11 +454,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs) pt_error_return(regs, EFAULT); goto out_tsk; } - child->thread.xfsr[0] &= 0xffffffff00000000UL; - child->thread.xfsr[0] |= fsr; - if (!(child->thread.fpsaved[0] & FPRS_FEF)) - child->thread.gsr[0] = 0; - child->thread.fpsaved[0] |= (FPRS_FEF | FPRS_DL); + child->thread_info->xfsr[0] &= 0xffffffff00000000UL; + child->thread_info->xfsr[0] |= fsr; + if (!(child->thread_info->fpsaved[0] & FPRS_FEF)) + child->thread_info->gsr[0] = 0; + child->thread_info->fpsaved[0] |= (FPRS_FEF | FPRS_DL); pt_succ_return(regs, 0); goto out_tsk; } @@ -470,17 +468,17 @@ asmlinkage void do_ptrace(struct pt_regs *regs) unsigned int regs[64]; unsigned long fsr; } *fps = (struct fps *) addr; - unsigned long *fpregs = (unsigned long *)(((char *)child) + AOFF_task_fpregs); + unsigned long *fpregs = child->thread_info->fpregs; if (copy_from_user(fpregs, &fps->regs[0], (64 * sizeof(unsigned int))) || - __get_user(child->thread.xfsr[0], (&fps->fsr))) { + __get_user(child->thread_info->xfsr[0], (&fps->fsr))) { pt_error_return(regs, EFAULT); goto out_tsk; } - if (!(child->thread.fpsaved[0] & FPRS_FEF)) - child->thread.gsr[0] = 0; - child->thread.fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU); + if (!(child->thread_info->fpsaved[0] & FPRS_FEF)) + child->thread_info->gsr[0] = 0; + child->thread_info->fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU); pt_succ_return(regs, 0); goto out_tsk; } @@ -523,7 +521,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs) if (addr != 1) { unsigned long pc_mask = ~0UL; - if ((child->thread.flags & SPARC_FLAG_32BIT) != 0) + if ((child->thread_info->flags & _TIF_32BIT) != 0) pc_mask = 0xffffffff; if (addr & 3) { @@ -531,27 +529,27 @@ asmlinkage void do_ptrace(struct pt_regs *regs) goto out_tsk; } #ifdef DEBUG_PTRACE - printk ("Original: %016lx %016lx\n", child->thread.kregs->tpc, child->thread.kregs->tnpc); + printk ("Original: %016lx %016lx\n", + child->thread_info->kregs->tpc, + child->thread_info->kregs->tnpc); printk ("Continuing with %016lx %016lx\n", addr, addr+4); #endif - child->thread.kregs->tpc = (addr & pc_mask); - child->thread.kregs->tnpc = ((addr + 4) & pc_mask); + child->thread_info->kregs->tpc = (addr & pc_mask); + child->thread_info->kregs->tnpc = ((addr + 4) & pc_mask); } if (request == PTRACE_SYSCALL) { - child->ptrace |= PT_SYSCALLTRACE; - child->work.syscall_trace++; + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); } else { - child->ptrace &= ~PT_SYSCALLTRACE; - child->work.syscall_trace--; + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); } child->exit_code = data; #ifdef DEBUG_PTRACE printk("CONT: %s [%d]: set exit_code = %x %lx %lx\n", child->comm, child->pid, child->exit_code, - child->thread.kregs->tpc, - child->thread.kregs->tnpc); + child->thread_info->kregs->tpc, + child->thread_info->kregs->tnpc); #endif wake_up_process(child); @@ -614,7 +612,7 @@ flush_and_out: } out_tsk: if (child) - free_task_struct(child); + put_task_struct(child); out: unlock_kernel(); } @@ -624,12 +622,12 @@ asmlinkage void syscall_trace(void) #ifdef DEBUG_PTRACE printk("%s [%d]: syscall_trace\n", current->comm, current->pid); #endif - if ((current->ptrace & (PT_PTRACED|PT_SYSCALLTRACE)) - != (PT_PTRACED|PT_SYSCALLTRACE)) + if (!test_thread_flag(TIF_SYSCALL_TRACE)) + return; + if (!(current->ptrace & PT_PTRACED)) return; current->exit_code = SIGTRAP; current->state = TASK_STOPPED; - current->thread.flags ^= MAGIC_CONSTANT; notify_parent(current, SIGCHLD); schedule(); /* diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index f014e4deb..76b9b32de 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S @@ -1,4 +1,4 @@ -/* $Id: rtrap.S,v 1.60 2002-01-31 03:30:06 davem Exp $ +/* $Id: rtrap.S,v 1.61 2002-02-09 19:49:31 davem Exp $ * rtrap.S: Preparing for return from trap on Sparc V9. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -42,18 +42,18 @@ __handle_user_windows: wrpr %g0, RTRAP_PSTATE, %pstate wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate /* Redo sched+sig checks */ - lduw [%g6 + AOFF_task_work], %l0 - srlx %l0, 24, %o0 + ldx [%g6 + TI_FLAGS], %l0 + andcc %l0, _TIF_NEED_RESCHED, %g0 - brz,pt %o0, 1f + be,pt %xcc, 1f nop call schedule wrpr %g0, RTRAP_PSTATE, %pstate wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate - lduw [%g6 + AOFF_task_work], %l0 + ldx [%g6 + TI_FLAGS], %l0 -1: sllx %l0, 48, %o0 - brz,pt %o0, __handle_user_windows_continue +1: andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 + be,pt %xcc, __handle_user_windows_continue nop clr %o0 mov %l5, %o2 @@ -78,7 +78,7 @@ __handle_perfctrs: call update_perfctrs wrpr %g0, RTRAP_PSTATE, %pstate wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate - ldub [%g6 + AOFF_task_thread + AOFF_thread_w_saved], %o2 + ldub [%g6 + TI_WSAVED], %o2 brz,pt %o2, 1f nop /* Redo userwin+sched+sig checks */ @@ -86,18 +86,18 @@ __handle_perfctrs: wrpr %g0, RTRAP_PSTATE, %pstate wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate - lduw [%g6 + AOFF_task_work], %l0 - srlx %l0, 24, %o0 - brz,pt %o0, 1f + ldx [%g6 + TI_FLAGS], %l0 + andcc %l0, _TIF_NEED_RESCHED, %g0 + be,pt %xcc, 1f nop call schedule wrpr %g0, RTRAP_PSTATE, %pstate wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate - lduw [%g6 + AOFF_task_work], %l0 -1: sllx %l0, 48, %o0 + ldx [%g6 + TI_FLAGS], %l0 +1: andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 - brz,pt %o0, __handle_perfctrs_continue + be,pt %xcc, __handle_perfctrs_continue sethi %hi(TSTATE_PEF), %o0 clr %o0 mov %l5, %o2 @@ -150,7 +150,7 @@ __handle_signal: .align 64 .globl rtrap_clr_l6, rtrap, irqsz_patchme rtrap_clr_l6: clr %l6 -rtrap: lduw [%g6 + AOFF_task_cpu], %l0 +rtrap: ldub [%g6 + TI_CPU], %l0 sethi %hi(irq_stat), %l2 ! &softirq_active or %l2, %lo(irq_stat), %l2 ! &softirq_active irqsz_patchme: sllx %l0, 0, %l0 @@ -182,26 +182,33 @@ __handle_softirq_continue: */ to_user: wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate __handle_preemption_continue: - lduw [%g6 + AOFF_task_work], %l0 - srlx %l0, 24, %o0 - brnz,pn %o0, __handle_preemption - sllx %l0, 48, %o0 - brnz,pn %o0, __handle_signal + ldx [%g6 + TI_FLAGS], %l0 + sethi %hi(_TIF_USER_WORK_MASK), %o0 + or %o0, %lo(_TIF_USER_WORK_MASK), %o0 + andcc %l0, %o0, %g0 + sethi %hi(TSTATE_PEF), %o0 + be,pt %xcc, user_nowork + andcc %l1, %o0, %g0 + andcc %l0, _TIF_NEED_RESCHED, %g0 + bne,pn %xcc, __handle_preemption + andcc %l0, (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING), %g0 + bne,pn %xcc, __handle_signal __handle_signal_continue: - ldub [%g6 + AOFF_task_thread + AOFF_thread_w_saved], %o2 + ldub [%g6 + TI_WSAVED], %o2 brnz,pn %o2, __handle_user_windows nop __handle_user_windows_continue: - ldub [%g6 + AOFF_task_thread + AOFF_thread_flags], %l5 - andcc %l5, SPARC_FLAG_PERFCTR, %g0 + ldx [%g6 + TI_FLAGS], %l5 + andcc %l5, _TIF_PERFCTR, %g0 sethi %hi(TSTATE_PEF), %o0 bne,pn %xcc, __handle_perfctrs __handle_perfctrs_continue: andcc %l1, %o0, %g0 /* This fpdepth clear is neccessary for non-syscall rtraps only */ +user_nowork: bne,pn %xcc, __handle_userfpu - stb %g0, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth] + stb %g0, [%g6 + TI_FPDEPTH] __handle_userfpu_continue: rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 @@ -254,14 +261,14 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 kern_rtt: restore retry -to_kernel: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5 +to_kernel: ldub [%g6 + TI_FPDEPTH], %l5 brz,pt %l5, rt_continue srl %l5, 1, %o0 - add %g6, AOFF_task_thread + AOFF_thread_fpsaved, %l6 + add %g6, TI_FPSAVED, %l6 ldub [%l6 + %o0], %l2 sub %l5, 2, %l5 - add %g6, AOFF_task_thread + AOFF_thread_gsr, %o1 + add %g6, TI_GSR, %o1 andcc %l2, (FPRS_FEF|FPRS_DU), %g0 be,pt %icc, 2f and %l2, FPRS_DL, %l6 @@ -272,12 +279,12 @@ to_kernel: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5 wr %g5, FPRS_FEF, %fprs ldx [%o1 + %o5], %g5 - add %g6, AOFF_task_thread + AOFF_thread_xfsr, %o1 + add %g6, TI_XFSR, %o1 membar #StoreLoad | #LoadLoad sll %o0, 8, %o2 - add %g6, AOFF_task_fpregs, %o3 + add %g6, TI_FPREGS, %o3 brz,pn %l6, 1f - add %g6, AOFF_task_fpregs+0x40, %o4 + add %g6, TI_FPREGS+0x40, %o4 ldda [%o3 + %o2] ASI_BLK_P, %f0 ldda [%o4 + %o2] ASI_BLK_P, %f16 @@ -290,20 +297,20 @@ to_kernel: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5 1: membar #Sync ldx [%o1 + %o5], %fsr -2: stb %l5, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth] +2: stb %l5, [%g6 + TI_FPDEPTH] ba,pt %xcc, rt_continue nop 5: wr %g0, FPRS_FEF, %fprs membar #StoreLoad | #LoadLoad sll %o0, 8, %o2 - add %g6, AOFF_task_fpregs+0x80, %o3 - add %g6, AOFF_task_fpregs+0xc0, %o4 + add %g6, TI_FPREGS+0x80, %o3 + add %g6, TI_FPREGS+0xc0, %o4 ldda [%o3 + %o2] ASI_BLK_P, %f32 ldda [%o4 + %o2] ASI_BLK_P, %f48 membar #Sync wr %g0, FPRS_DU, %fprs ba,pt %xcc, rt_continue - stb %l5, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth] + stb %l5, [%g6 + TI_FPDEPTH] #undef PTREGS_OFF diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index ba31e8a5f..3d6477bbc 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.71 2001-11-13 00:49:28 davem Exp $ +/* $Id: setup.c,v 1.72 2002-02-09 19:49:30 davem Exp $ * linux/arch/sparc64/kernel/setup.c * * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) @@ -536,7 +536,7 @@ void __init setup_arch(char **cmdline_p) rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0); #endif - init_task.thread.kregs = &fake_swapper_regs; + init_task.thread_info->kregs = &fake_swapper_regs; #ifdef CONFIG_IP_PNP if (!ic_set_manually) { diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 85b3fd656..9aae45463 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -1,4 +1,4 @@ -/* $Id: signal.c,v 1.59 2002-02-08 03:57:14 davem Exp $ +/* $Id: signal.c,v 1.60 2002-02-09 19:49:31 davem Exp $ * arch/sparc64/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -76,7 +76,6 @@ int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) asmlinkage void sparc64_set_context(struct pt_regs *regs) { struct ucontext *ucp = (struct ucontext *) regs->u_regs[UREG_I0]; - struct thread_struct *tp = ¤t->thread; mc_gregset_t *grp; unsigned long pc, npc, tstate; unsigned long fp, i7; @@ -84,16 +83,16 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) int err; flush_user_windows(); - if(tp->w_saved || - (((unsigned long)ucp) & (sizeof(unsigned long)-1)) || - (!__access_ok((unsigned long)ucp, sizeof(*ucp)))) + if (get_thread_wsaved() || + (((unsigned long)ucp) & (sizeof(unsigned long)-1)) || + (!__access_ok((unsigned long)ucp, sizeof(*ucp)))) goto do_sigsegv; grp = &ucp->uc_mcontext.mc_gregs; err = __get_user(pc, &((*grp)[MC_PC])); err |= __get_user(npc, &((*grp)[MC_NPC])); - if(err || ((pc | npc) & 3)) + if (err || ((pc | npc) & 3)) goto do_sigsegv; - if(regs->u_regs[UREG_I1]) { + if (regs->u_regs[UREG_I1]) { sigset_t set; if (_NSIG_WORDS == 1) { @@ -109,7 +108,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); } - if ((tp->flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { pc &= 0xffffffff; npc &= 0xffffffff; } @@ -143,8 +142,8 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) (&(((struct reg_window *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7]))); err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab)); - if(fenab) { - unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs); + if (fenab) { + unsigned long *fpregs = current_thread_info()->fpregs; unsigned long fprs; fprs_write(0); @@ -157,9 +156,9 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) err |= copy_from_user(fpregs+16, ((unsigned long *)&(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs))+16, (sizeof(unsigned int) * 32)); - err |= __get_user(current->thread.xfsr[0], + err |= __get_user(current_thread_info()->xfsr[0], &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr)); - err |= __get_user(current->thread.gsr[0], + err |= __get_user(current_thread_info()->gsr[0], &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr)); regs->tstate &= ~TSTATE_PEF; } @@ -174,7 +173,6 @@ do_sigsegv: asmlinkage void sparc64_get_context(struct pt_regs *regs) { struct ucontext *ucp = (struct ucontext *) regs->u_regs[UREG_I0]; - struct thread_struct *tp = ¤t->thread; mc_gregset_t *grp; mcontext_t *mcp; unsigned long fp, i7; @@ -182,20 +180,20 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs) int err; synchronize_user_stack(); - if(tp->w_saved || clear_user(ucp, sizeof(*ucp))) + if (get_thread_wsaved() || clear_user(ucp, sizeof(*ucp))) goto do_sigsegv; #if 1 fenab = 0; /* IMO get_context is like any other system call, thus modifies FPU state -jj */ #else - fenab = (current->thread.fpsaved[0] & FPRS_FEF); + fenab = (current_thread_info()->fpsaved[0] & FPRS_FEF); #endif mcp = &ucp->uc_mcontext; grp = &mcp->mc_gregs; /* Skip over the trap instruction, first. */ - if ((tp->flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc = (regs->tnpc & 0xffffffff); regs->tnpc = (regs->tnpc + 4) & 0xffffffff; } else { @@ -238,11 +236,11 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs) err |= __put_user(i7, &(mcp->mc_i7)); err |= __put_user(fenab, &(mcp->mc_fpregs.mcfpu_enab)); - if(fenab) { - unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs); + if (fenab) { + unsigned long *fpregs = current_thread_info()->fpregs; unsigned long fprs; - fprs = current->thread.fpsaved[0]; + fprs = current_thread_info()->fpsaved[0]; if (fprs & FPRS_DL) err |= copy_to_user(&(mcp->mc_fpregs.mcfpu_fregs), fpregs, (sizeof(unsigned int) * 32)); @@ -250,8 +248,8 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs) err |= copy_to_user( ((unsigned long *)&(mcp->mc_fpregs.mcfpu_fregs))+16, fpregs+16, (sizeof(unsigned int) * 32)); - err |= __put_user(current->thread.xfsr[0], &(mcp->mc_fpregs.mcfpu_fsr)); - err |= __put_user(current->thread.gsr[0], &(mcp->mc_fpregs.mcfpu_gsr)); + err |= __put_user(current_thread_info()->xfsr[0], &(mcp->mc_fpregs.mcfpu_fsr)); + err |= __put_user(current_thread_info()->gsr[0], &(mcp->mc_fpregs.mcfpu_gsr)); err |= __put_user(fprs, &(mcp->mc_fpregs.mcfpu_fprs)); } if (err) @@ -284,7 +282,7 @@ asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs) sigset_t saveset; #ifdef CONFIG_SPARC32_COMPAT - if (current->thread.flags & SPARC_FLAG_32BIT) { + if (test_thread_flag(TIF_32BIT)) { extern asmlinkage void _sigpause32_common(old_sigset_t32, struct pt_regs *); _sigpause32_common(set, regs); @@ -298,7 +296,7 @@ asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs) recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc = (regs->tnpc & 0xffffffff); regs->tnpc = (regs->tnpc + 4) & 0xffffffff; } else { @@ -358,7 +356,7 @@ asmlinkage void do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize, struct pt_re recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc = (regs->tnpc & 0xffffffff); regs->tnpc = (regs->tnpc + 4) & 0xffffffff; } else { @@ -388,7 +386,7 @@ asmlinkage void do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize, struct pt_re static inline int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu) { - unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs); + unsigned long *fpregs = current_thread_info()->fpregs; unsigned long fprs; int err; @@ -401,9 +399,9 @@ restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu) if (fprs & FPRS_DU) err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32)); - err |= __get_user(current->thread.xfsr[0], &fpu->si_fsr); - err |= __get_user(current->thread.gsr[0], &fpu->si_gsr); - current->thread.fpsaved[0] |= fprs; + err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr); + err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr); + current_thread_info()->fpsaved[0] |= fprs; return err; } @@ -426,7 +424,7 @@ void do_rt_sigreturn(struct pt_regs *regs) err = get_user(tpc, &sf->regs.tpc); err |= __get_user(tnpc, &sf->regs.tnpc); - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { tpc &= 0xffffffff; tnpc &= 0xffffffff; } @@ -483,15 +481,15 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu) unsigned long fprs; int err = 0; - fprs = current->thread.fpsaved[0]; + fprs = current_thread_info()->fpsaved[0]; if (fprs & FPRS_DL) err |= copy_to_user(&fpu->si_float_regs[0], fpregs, (sizeof(unsigned int) * 32)); if (fprs & FPRS_DU) err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16, (sizeof(unsigned int) * 32)); - err |= __put_user(current->thread.xfsr[0], &fpu->si_fsr); - err |= __put_user(current->thread.gsr[0], &fpu->si_gsr); + err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr); + err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr); err |= __put_user(fprs, &fpu->si_fprs); return err; @@ -524,7 +522,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, save_and_clear_fpu(); sigframe_size = RT_ALIGNEDSZ; - if (!(current->thread.fpsaved[0] & FPRS_FEF)) + if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) sigframe_size -= sizeof(__siginfo_fpu_t); sf = (struct rt_signal_frame *)get_sigframe(ka, regs, sigframe_size); @@ -532,7 +530,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, if (invalid_frame_pointer (sf, sigframe_size)) goto sigill; - if (current->thread.w_saved != 0) { + if (get_thread_wsaved() != 0) { #ifdef DEBUG_SIGNALS printk ("%s[%d]: Invalid user stack frame for " "signal delivery.\n", current->comm, current->pid); @@ -543,7 +541,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, /* 2. Save the current process state */ err = copy_to_user(&sf->regs, regs, sizeof (*regs)); - if (current->thread.fpsaved[0] & FPRS_FEF) { + if (current_thread_info()->fpsaved[0] & FPRS_FEF) { err |= save_fpu_state(regs, &sf->fpu_state); err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save); } else { @@ -578,7 +576,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, /* 5. signal handler */ regs->tpc = (unsigned long) ka->sa.sa_handler; regs->tnpc = (regs->tpc + 4); - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -597,9 +595,9 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) { setup_rt_frame(ka, regs, signr, oldset, (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); - if(ka->sa.sa_flags & SA_ONESHOT) + if (ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; - if(!(ka->sa.sa_flags & SA_NOMASK)) { + if (!(ka->sa.sa_flags & SA_NOMASK)) { spin_lock_irq(¤t->sigmask_lock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,signr); @@ -611,14 +609,14 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, struct sigaction *sa) { - switch(regs->u_regs[UREG_I0]) { + switch (regs->u_regs[UREG_I0]) { case ERESTARTNOHAND: no_system_call_restart: regs->u_regs[UREG_I0] = EINTR; regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY); break; case ERESTARTSYS: - if(!(sa->sa_flags & SA_RESTART)) + if (!(sa->sa_flags & SA_RESTART)) goto no_system_call_restart; /* fallthrough */ case ERESTARTNOINTR: @@ -699,7 +697,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, oldset = ¤t->blocked; #ifdef CONFIG_SPARC32_COMPAT - if (current->thread.flags & SPARC_FLAG_32BIT) { + if (test_thread_flag(TIF_32BIT)) { extern int do_signal32(sigset_t *, struct pt_regs *, unsigned long, int); return do_signal32(oldset, regs, orig_i0, restart_syscall); @@ -741,8 +739,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ka = ¤t->sig->action[signr-1]; - if(ka->sa.sa_handler == SIG_IGN) { - if(signr != SIGCHLD) + if (ka->sa.sa_handler == SIG_IGN) { + if (signr != SIGCHLD) continue; /* sys_wait4() grabs the master kernel lock, so @@ -750,16 +748,16 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, * threaded and would not be that difficult to * do anyways. */ - while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0) + while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) ; continue; } - if(ka->sa.sa_handler == SIG_DFL) { + if (ka->sa.sa_handler == SIG_DFL) { unsigned long exit_code = signr; - if(current->pid == 1) + if (current->pid == 1) continue; - switch(signr) { + switch (signr) { case SIGCONT: case SIGCHLD: case SIGWINCH: continue; @@ -772,8 +770,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, continue; current->state = TASK_STOPPED; current->exit_code = signr; - if(!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & - SA_NOCLDSTOP)) + if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & + SA_NOCLDSTOP)) notify_parent(current, SIGCHLD); schedule(); continue; @@ -792,8 +790,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, struct reg_window *rw = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); unsigned long ins[8]; - while(rw && - !(((unsigned long) rw) & 0x3)) { + while (rw && + !(((unsigned long) rw) & 0x3)) { copy_from_user(ins, &rw->ins[0], sizeof(ins)); printk("Caller[%016lx](%016lx,%016lx,%016lx,%016lx,%016lx,%016lx)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]); rw = (struct reg_window *)(unsigned long)(ins[6] + STACK_BIAS); @@ -811,15 +809,15 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, /* NOT REACHED */ } } - if(restart_syscall) + if (restart_syscall) syscall_restart(orig_i0, regs, &ka->sa); handle_signal(signr, ka, &info, oldset, regs); return 1; } - if(restart_syscall && - (regs->u_regs[UREG_I0] == ERESTARTNOHAND || - regs->u_regs[UREG_I0] == ERESTARTSYS || - regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { + if (restart_syscall && + (regs->u_regs[UREG_I0] == ERESTARTNOHAND || + regs->u_regs[UREG_I0] == ERESTARTSYS || + regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; @@ -830,12 +828,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, void do_notify_resume(sigset_t *oldset, struct pt_regs *regs, unsigned long orig_i0, int restart_syscall, - unsigned int work_pending) + unsigned long thread_info_flags) { - /* We don't pass in the task_work struct as a struct because - * GCC always bounces that onto the stack due to the - * ABI calling conventions. - */ - if (work_pending & 0x0000ff00) + if (thread_info_flags & _TIF_SIGPENDING) do_signal(oldset, regs, orig_i0, restart_syscall); } diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 0549a6da8..ed0b8dc98 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -1,4 +1,4 @@ -/* $Id: signal32.c,v 1.73 2002-02-08 03:57:14 davem Exp $ +/* $Id: signal32.c,v 1.74 2002-02-09 19:49:30 davem Exp $ * arch/sparc64/kernel/signal32.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -156,7 +156,7 @@ asmlinkage void _sigpause32_common(old_sigset_t32 set, struct pt_regs *regs) regs->tpc = regs->tnpc; regs->tnpc += 4; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -211,7 +211,7 @@ asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs * regs->tpc = regs->tnpc; regs->tnpc += 4; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -237,7 +237,7 @@ asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs * static inline int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu) { - unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs); + unsigned long *fpregs = current_thread_info()->fpregs; unsigned long fprs; int err; @@ -248,9 +248,9 @@ static inline int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu err |= copy_from_user(fpregs, &fpu->si_float_regs[0], (sizeof(unsigned int) * 32)); if (fprs & FPRS_DU) err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32], (sizeof(unsigned int) * 32)); - err |= __get_user(current->thread.xfsr[0], &fpu->si_fsr); - err |= __get_user(current->thread.gsr[0], &fpu->si_gsr); - current->thread.fpsaved[0] |= fprs; + err |= __get_user(current_thread_info()->xfsr[0], &fpu->si_fsr); + err |= __get_user(current_thread_info()->gsr[0], &fpu->si_gsr); + current_thread_info()->fpsaved[0] |= fprs; return err; } @@ -277,7 +277,7 @@ void do_new_sigreturn32(struct pt_regs *regs) if ((pc | npc) & 3) goto segv; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { pc &= 0xffffffff; npc &= 0xffffffff; } @@ -335,20 +335,20 @@ asmlinkage void do_sigreturn32(struct pt_regs *regs) int err; synchronize_user_stack(); - if (current->thread.flags & SPARC_FLAG_NEWSIGNALS) + if (test_thread_flag(TIF_NEWSIGNALS)) return do_new_sigreturn32(regs); scptr = (struct sigcontext32 *) (regs->u_regs[UREG_I0] & 0x00000000ffffffffUL); /* Check sanity of the user arg. */ - if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext32)) || - (((unsigned long) scptr) & 3)) + if (verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext32)) || + (((unsigned long) scptr) & 3)) goto segv; err = __get_user(pc, &scptr->sigc_pc); err |= __get_user(npc, &scptr->sigc_npc); - if((pc | npc) & 3) + if ((pc | npc) & 3) goto segv; /* Nice try. */ err |= __get_user(seta[0], &scptr->sigc_mask); @@ -368,7 +368,7 @@ asmlinkage void do_sigreturn32(struct pt_regs *regs) recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { pc &= 0xffffffff; npc &= 0xffffffff; } @@ -415,7 +415,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) if ((pc | npc) & 3) goto segv; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { pc &= 0xffffffff; npc &= 0xffffffff; } @@ -510,7 +510,7 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o #endif unsigned psr; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { pc &= 0xffffffff; npc &= 0xffffffff; } @@ -555,20 +555,20 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o err |= __put_user(pc, &sc->sigc_pc); err |= __put_user(npc, &sc->sigc_npc); psr = tstate_to_psr (regs->tstate); - if(current->thread.fpsaved[0] & FPRS_FEF) + if (current_thread_info()->fpsaved[0] & FPRS_FEF) psr |= PSR_EF; err |= __put_user(psr, &sc->sigc_psr); err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1); err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0); - err |= __put_user(current->thread.w_saved, &sc->sigc_oswins); + err |= __put_user(get_thread_wsaved(), &sc->sigc_oswins); #if 0 /* w_saved is not currently used... */ - if(current->thread.w_saved) - for(window = 0; window < current->thread.w_saved; window++) { + if (get_thread_wsaved()) + for (window = 0; window < get_thread_wsaved(); window++) { sc->sigc_spbuf[window] = - (char *)current->thread.rwbuf_stkptrs[window]; + (char *) current_thread_info()->rwbuf_stkptrs[window]; err |= copy_to_user(&sc->sigc_wbuf[window], - ¤t->thread.reg_window[window], + ¤t_thread_info()->reg_window[window], sizeof(struct reg_window)); } else @@ -577,7 +577,7 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o (u32 *)(regs->u_regs[UREG_FP]), sizeof(struct reg_window32)); - current->thread.w_saved = 0; /* So process is allowed to execute. */ + set_thread_wsaved(0); /* So process is allowed to execute. */ err |= __put_user(signr, &sframep->sig_num); sig_address = NULL; sig_code = 0; @@ -641,7 +641,7 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o regs->u_regs[UREG_FP] = (unsigned long) sframep; regs->tpc = (unsigned long) sa->sa_handler; regs->tnpc = (regs->tpc + 4); - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -654,19 +654,19 @@ sigsegv: static inline int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu) { - unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs); + unsigned long *fpregs = current_thread_info()->fpregs; unsigned long fprs; int err = 0; - fprs = current->thread.fpsaved[0]; + fprs = current_thread_info()->fpsaved[0]; if (fprs & FPRS_DL) err |= copy_to_user(&fpu->si_float_regs[0], fpregs, (sizeof(unsigned int) * 32)); if (fprs & FPRS_DU) err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16, (sizeof(unsigned int) * 32)); - err |= __put_user(current->thread.xfsr[0], &fpu->si_fsr); - err |= __put_user(current->thread.gsr[0], &fpu->si_gsr); + err |= __put_user(current_thread_info()->xfsr[0], &fpu->si_fsr); + err |= __put_user(current_thread_info()->gsr[0], &fpu->si_gsr); err |= __put_user(fprs, &fpu->si_fprs); return err; @@ -686,7 +686,7 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg save_and_clear_fpu(); sigframe_size = NF_ALIGNEDSZ; - if (!(current->thread.fpsaved[0] & FPRS_FEF)) + if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) sigframe_size -= sizeof(__siginfo_fpu_t); sf = (struct new_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size); @@ -699,7 +699,7 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg goto sigill; } - if (current->thread.w_saved != 0) { + if (get_thread_wsaved() != 0) { #ifdef DEBUG_SIGNALS printk ("%s[%d]: Invalid user stack frame for " "signal delivery.\n", current->comm, current->pid); @@ -708,7 +708,7 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg } /* 2. Save the current process state */ - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -716,7 +716,7 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg err |= __put_user(regs->tnpc, &sf->info.si_regs.npc); err |= __put_user(regs->y, &sf->info.si_regs.y); psr = tstate_to_psr (regs->tstate); - if(current->thread.fpsaved[0] & FPRS_FEF) + if (current_thread_info()->fpsaved[0] & FPRS_FEF) psr |= PSR_EF; err |= __put_user(psr, &sf->info.si_regs.psr); for (i = 0; i < 16; i++) @@ -762,7 +762,7 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg /* 4. signal handler */ regs->tpc = (unsigned long) ka->sa.sa_handler; regs->tnpc = (regs->tpc + 4); - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -781,10 +781,10 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg err = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/ err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/ - if(err) + if (err) goto sigsegv; - if(pte_present(*ptep)) { + if (pte_present(*ptep)) { unsigned long page = (unsigned long) page_address(pte_page(*ptep)); __asm__ __volatile__( @@ -857,14 +857,14 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned)); /* Store registers */ - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } err |= __put_user(regs->tpc, &((*gr) [SVR4_PC])); err |= __put_user(regs->tnpc, &((*gr) [SVR4_NPC])); psr = tstate_to_psr (regs->tstate); - if(current->thread.fpsaved[0] & FPRS_FEF) + if (current_thread_info()->fpsaved[0] & FPRS_FEF) psr |= PSR_EF; err |= __put_user(psr, &((*gr) [SVR4_PSR])); err |= __put_user(regs->y, &((*gr) [SVR4_Y])); @@ -886,7 +886,7 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, err |= __put_user((u32)(long)gw, &mc->gwin); /* 2. Number of windows to restore at setcontext (): */ - err |= __put_user(current->thread.w_saved, &gw->count); + err |= __put_user(get_thread_wsaved(), &gw->count); /* 3. Save each valid window * Currently, it makes a copy of the windows from the kernel copy. @@ -900,18 +900,18 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, * to flush the user windows. */ #if 0 - for(window = 0; window < current->thread.w_saved; window++) { - err |= __put_user((int *) &(gw->win [window]), - (int **)gw->winptr +window ); - err |= copy_to_user(&gw->win [window], - ¤t->thread.reg_window [window], + for (window = 0; window < get_thread_wsaved(); window++) { + err |= __put_user((int *) &(gw->win[window]), + (int **) gw->winptr + window); + err |= copy_to_user(&gw->win[window], + ¤t_thread_info()->reg_window[window], sizeof (svr4_rwindow_t)); - err |= __put_user(0, (int *)gw->winptr + window); + err |= __put_user(0, (int *) gw->winptr + window); } #endif /* 4. We just pay attention to the gw->count field on setcontext */ - current->thread.w_saved = 0; /* So process is allowed to execute. */ + set_thread_wsaved(0); /* So process is allowed to execute. */ /* Setup the signal information. Solaris expects a bunch of * information to be passed to the signal handler, we don't provide @@ -925,7 +925,7 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc, regs->u_regs[UREG_FP] = (unsigned long) sfp; regs->tpc = (unsigned long) sa->sa_handler; regs->tnpc = (regs->tpc + 4); - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -966,8 +966,10 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs) synchronize_user_stack(); save_and_clear_fpu(); - if (current->thread.w_saved){ - printk ("Uh oh, w_saved is not zero (%d)\n", (int) current->thread.w_saved); + if (get_thread_wsaved()) { +#ifdef DEBUG_SIGNALS + printk ("Uh oh, w_saved is not zero (%d)\n", (int) get_thread_wsaved()); +#endif do_exit (SIGSEGV); } err = clear_user(uc, sizeof (*uc)); @@ -986,7 +988,7 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs) err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned)); /* Store registers */ - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -996,7 +998,7 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs) err |= __put_user(0, &uc->mcontext.greg [SVR4_PSR]); #else i = tstate_to_psr(regs->tstate) & ~PSR_EF; - if (current->thread.fpsaved[0] & FPRS_FEF) + if (current_thread_info()->fpsaved[0] & FPRS_FEF) i |= PSR_EF; err |= __put_user(i, &uc->mcontext.greg [SVR4_PSR]); #endif @@ -1023,7 +1025,6 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs) /* Set the context for a svr4 application, this is Solaris way to sigreturn */ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) { - struct thread_struct *tp = ¤t->thread; svr4_gregset_t *gr; u32 pc, npc, psr; sigset_t set; @@ -1036,8 +1037,10 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) */ flush_user_windows(); - if (tp->w_saved){ - printk ("Uh oh, w_saved is: 0x%x\n", tp->w_saved); + if (get_thread_wsaved()) { +#ifdef DEBUG_SIGNALS + printk ("Uh oh, w_saved is: 0x%x\n", get_thread_wsaved()); +#endif goto sigsegv; } if (((unsigned long) c) & 3){ @@ -1045,7 +1048,7 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) goto sigsegv; } - if(!__access_ok((unsigned long)c, sizeof(*c))) { + if (!__access_ok((unsigned long)c, sizeof(*c))) { /* Miguel, add nice debugging msg _here_. ;-) */ goto sigsegv; } @@ -1054,7 +1057,7 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) gr = &c->mcontext.greg; err = __get_user(pc, &((*gr)[SVR4_PC])); err |= __get_user(npc, &((*gr)[SVR4_NPC])); - if((pc | npc) & 3) { + if ((pc | npc) & 3) { #ifdef DEBUG_SIGNALS printk ("setcontext, PC or nPC were bogus\n"); #endif @@ -1087,7 +1090,7 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) spin_unlock_irq(¤t->sigmask_lock); regs->tpc = pc; regs->tnpc = npc | 1; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -1096,7 +1099,7 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); regs->tstate |= psr_to_tstate_icc(psr); #if 0 - if(psr & PSR_EF) + if (psr & PSR_EF) regs->tstate |= TSTATE_PEF; #endif /* Restore g[1..7] and o[0..7] registers */ @@ -1104,7 +1107,7 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs) err |= __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i); for (i = 0; i < 8; i++) err |= __get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i); - if(err) + if (err) goto sigsegv; return -EINTR; @@ -1127,7 +1130,7 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs save_and_clear_fpu(); sigframe_size = RT_ALIGNEDSZ; - if (!(current->thread.fpsaved[0] & FPRS_FEF)) + if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) sigframe_size -= sizeof(__siginfo_fpu_t); sf = (struct rt_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size); @@ -1140,7 +1143,7 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs goto sigill; } - if (current->thread.w_saved != 0) { + if (get_thread_wsaved() != 0) { #ifdef DEBUG_SIGNALS printk ("%s[%d]: Invalid user stack frame for " "signal delivery.\n", current->comm, current->pid); @@ -1149,7 +1152,7 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs } /* 2. Save the current process state */ - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -1157,7 +1160,7 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs err |= __put_user(regs->tnpc, &sf->regs.npc); err |= __put_user(regs->y, &sf->regs.y); psr = tstate_to_psr (regs->tstate); - if(current->thread.fpsaved[0] & FPRS_FEF) + if (current_thread_info()->fpsaved[0] & FPRS_FEF) psr |= PSR_EF; err |= __put_user(psr, &sf->regs.psr); for (i = 0; i < 16; i++) @@ -1208,7 +1211,7 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs /* 4. signal handler */ regs->tpc = (unsigned long) ka->sa.sa_handler; regs->tnpc = (regs->tpc + 4); - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -1233,7 +1236,7 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs if (err) goto sigsegv; - if(pte_present(*ptep)) { + if (pte_present(*ptep)) { unsigned long page = (unsigned long) page_address(pte_page(*ptep)); __asm__ __volatile__( @@ -1256,19 +1259,19 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs, int svr4_signal) { - if(svr4_signal) + if (svr4_signal) setup_svr4_frame32(&ka->sa, regs->tpc, regs->tnpc, regs, signr, oldset); else { if (ka->sa.sa_flags & SA_SIGINFO) setup_rt_frame32(ka, regs, signr, oldset, info); - else if (current->thread.flags & SPARC_FLAG_NEWSIGNALS) + else if (test_thread_flag(TIF_NEWSIGNALS)) new_setup_frame32(ka, regs, signr, oldset); else setup_frame32(&ka->sa, regs, signr, oldset, info); } - if(ka->sa.sa_flags & SA_ONESHOT) + if (ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; - if(!(ka->sa.sa_flags & SA_NOMASK)) { + if (!(ka->sa.sa_flags & SA_NOMASK)) { spin_lock_irq(¤t->sigmask_lock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,signr); @@ -1280,14 +1283,14 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, struct sigaction *sa) { - switch(regs->u_regs[UREG_I0]) { + switch (regs->u_regs[UREG_I0]) { case ERESTARTNOHAND: no_system_call_restart: regs->u_regs[UREG_I0] = EINTR; regs->tstate |= TSTATE_ICARRY; break; case ERESTARTSYS: - if(!(sa->sa_flags & SA_RESTART)) + if (!(sa->sa_flags & SA_RESTART)) goto no_system_call_restart; /* fallthrough */ case ERESTARTNOINTR: @@ -1402,8 +1405,8 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, ka = ¤t->sig->action[signr-1]; - if(ka->sa.sa_handler == SIG_IGN) { - if(signr != SIGCHLD) + if (ka->sa.sa_handler == SIG_IGN) { + if (signr != SIGCHLD) continue; /* sys_wait4() grabs the master kernel lock, so @@ -1411,16 +1414,16 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, * threaded and would not be that difficult to * do anyways. */ - while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0) + while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) ; continue; } - if(ka->sa.sa_handler == SIG_DFL) { + if (ka->sa.sa_handler == SIG_DFL) { unsigned long exit_code = signr; - if(current->pid == 1) + if (current->pid == 1) continue; - switch(signr) { + switch (signr) { case SIGCONT: case SIGCHLD: case SIGWINCH: continue; @@ -1433,8 +1436,8 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, continue; current->state = TASK_STOPPED; current->exit_code = signr; - if(!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & - SA_NOCLDSTOP)) + if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & + SA_NOCLDSTOP)) notify_parent(current, SIGCHLD); schedule(); continue; @@ -1457,15 +1460,15 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, extern void sparc_ultra_dump_dtlb(void); sparc_ultra_dump_dtlb(); sparc_ultra_dump_itlb(); - } while(0); + } while (0); #endif #ifdef DEBUG_SIGNALS_TRACE { struct reg_window32 *rw = (struct reg_window32 *)(regs->u_regs[UREG_FP] & 0xffffffff); unsigned int ins[8]; - while(rw && - !(((unsigned long) rw) & 0x3)) { + while (rw && + !(((unsigned long) rw) & 0x3)) { copy_from_user(ins, &rw->ins[0], sizeof(ins)); printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]); rw = (struct reg_window32 *)(unsigned long)ins[6]; @@ -1483,15 +1486,15 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, /* NOT REACHED */ } } - if(restart_syscall) + if (restart_syscall) syscall_restart32(orig_i0, regs, &ka->sa); handle_signal32(signr, ka, &info, oldset, regs, svr4_signal); return 1; } - if(restart_syscall && - (regs->u_regs[UREG_I0] == ERESTARTNOHAND || - regs->u_regs[UREG_I0] == ERESTARTSYS || - regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { + if (restart_syscall && + (regs->u_regs[UREG_I0] == ERESTARTNOHAND || + regs->u_regs[UREG_I0] == ERESTARTSYS || + regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { /* replay the system call when we are done */ regs->u_regs[UREG_I0] = orig_i0; regs->tpc -= 4; diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 988b6a98b..218b9d31c 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -212,7 +212,7 @@ void __init smp_callin(void) /* Clear this or we will die instantly when we * schedule back to this idler... */ - current->thread.flags &= ~(SPARC_FLAG_NEWCHILD); + clear_thread_flag(TIF_NEWCHILD); /* Attach to the address space of init_task. */ atomic_inc(&init_mm.mm_count); @@ -236,7 +236,7 @@ extern unsigned long sparc64_cpu_startup; * 32-bits (I think) so to be safe we have it read the pointer * contained here so we work on >4GB machines. -DaveM */ -static struct task_struct *cpu_new_task = NULL; +static struct thread_info *cpu_new_thread = NULL; static void smp_tune_scheduling(void); @@ -261,7 +261,7 @@ void __init smp_boot_cpus(void) goto ignorecpu; if (cpu_present_map & (1UL << i)) { unsigned long entry = (unsigned long)(&sparc64_cpu_startup); - unsigned long cookie = (unsigned long)(&cpu_new_task); + unsigned long cookie = (unsigned long)(&cpu_new_thread); struct task_struct *p; int timeout; int no; @@ -280,7 +280,7 @@ void __init smp_boot_cpus(void) for (no = 0; no < linux_num_cpus; no++) if (linux_cpus[no].mid == i) break; - cpu_new_task = p; + cpu_new_thread = p->thread_info; prom_startcpu(linux_cpus[no].prom_node, entry, cookie); for (timeout = 0; timeout < 5000000; timeout++) { @@ -305,7 +305,7 @@ ignorecpu: __cpu_number_map[i] = -1; } } - cpu_new_task = NULL; + cpu_new_thread = NULL; if (cpucount == 0) { if (max_cpus != 1) printk("Error: only one processor found.\n"); diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 7e833f120..f810ab83b 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.120 2001-12-21 04:56:15 davem Exp $ +/* $Id: sparc64_ksyms.c,v 1.121 2002-02-09 19:49:31 davem Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -80,6 +80,11 @@ extern u32 sunos_sys_table[], sys_call_table32[]; extern void tl0_solaris(void); extern void sys_sigsuspend(void); extern int sys_getppid(void); +extern int sys_getpid(void); +extern int sys_geteuid(void); +extern int sys_getuid(void); +extern int sys_getegid(void); +extern int sys_getgid(void); extern int svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs); extern int svr4_setcontext(svr4_ucontext_t *uc, struct pt_regs *regs); extern int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); @@ -307,6 +312,11 @@ EXPORT_SYMBOL(sys_call_table32); EXPORT_SYMBOL(tl0_solaris); EXPORT_SYMBOL(sys_sigsuspend); EXPORT_SYMBOL(sys_getppid); +EXPORT_SYMBOL(sys_getpid); +EXPORT_SYMBOL(sys_geteuid); +EXPORT_SYMBOL(sys_getuid); +EXPORT_SYMBOL(sys_getegid); +EXPORT_SYMBOL(sys_getgid); EXPORT_SYMBOL(svr4_getcontext); EXPORT_SYMBOL(svr4_setcontext); EXPORT_SYMBOL(prom_cpu_nodes); diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 90852ef93..7ef96ccb2 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.56 2001-12-21 04:56:15 davem Exp $ +/* $Id: sys_sparc.c,v 1.57 2002-02-09 19:49:30 davem Exp $ * linux/arch/sparc64/kernel/sys_sparc.c * * This file contains various random system calls that @@ -59,7 +59,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi return addr; } - if (current->thread.flags & SPARC_FLAG_32BIT) + if (test_thread_flag(TIF_32BIT)) task_size = 0xf0000000UL; if (len > task_size || len > -PAGE_OFFSET) return -ENOMEM; @@ -140,7 +140,7 @@ extern asmlinkage unsigned long sys_brk(unsigned long brk); asmlinkage unsigned long sparc_brk(unsigned long brk) { /* People could try to be nasty and use ta 0x6d in 32bit programs */ - if ((current->thread.flags & SPARC_FLAG_32BIT) && + if (test_thread_flag(TIF_32BIT) && brk >= 0xf0000000UL) return current->mm->brk; @@ -289,7 +289,7 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, len = PAGE_ALIGN(len); retval = -EINVAL; - if (current->thread.flags & SPARC_FLAG_32BIT) { + if (test_thread_flag(TIF_32BIT)) { if (len > 0xf0000000UL || ((flags & MAP_FIXED) && addr > 0xf0000000UL - len)) goto out_putf; @@ -334,7 +334,7 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr, { struct vm_area_struct *vma; unsigned long ret = -EINVAL; - if (current->thread.flags & SPARC_FLAG_32BIT) + if (test_thread_flag(TIF_32BIT)) goto out; if (old_len > -PAGE_OFFSET || new_len > -PAGE_OFFSET) goto out; @@ -401,7 +401,7 @@ sparc_breakpoint (struct pt_regs *regs) { siginfo_t info; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -454,7 +454,7 @@ asmlinkage int solaris_syscall(struct pt_regs *regs) regs->tpc = regs->tnpc; regs->tnpc += 4; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -474,7 +474,7 @@ asmlinkage int sunos_syscall(struct pt_regs *regs) regs->tpc = regs->tnpc; regs->tnpc += 4; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -494,11 +494,11 @@ asmlinkage int sys_utrap_install(utrap_entry_t type, utrap_handler_t new_p, return -EINVAL; if (new_p == (utrap_handler_t)(long)UTH_NOCHANGE) { if (old_p) { - if (!current->thread.utraps) { + if (!current_thread_info()->utraps) { if (put_user(NULL, old_p)) return -EFAULT; } else { - if (put_user((utrap_handler_t)(current->thread.utraps[type]), old_p)) + if (put_user((utrap_handler_t)(current_thread_info()->utraps[type]), old_p)) return -EFAULT; } } @@ -508,39 +508,39 @@ asmlinkage int sys_utrap_install(utrap_entry_t type, utrap_handler_t new_p, } return 0; } - if (!current->thread.utraps) { - current->thread.utraps = + if (!current_thread_info()->utraps) { + current_thread_info()->utraps = kmalloc((UT_TRAP_INSTRUCTION_31+1)*sizeof(long), GFP_KERNEL); - if (!current->thread.utraps) return -ENOMEM; - current->thread.utraps[0] = 1; - memset(current->thread.utraps+1, 0, UT_TRAP_INSTRUCTION_31*sizeof(long)); + if (!current_thread_info()->utraps) return -ENOMEM; + current_thread_info()->utraps[0] = 1; + memset(current_thread_info()->utraps+1, 0, UT_TRAP_INSTRUCTION_31*sizeof(long)); } else { - if ((utrap_handler_t)current->thread.utraps[type] != new_p && - current->thread.utraps[0] > 1) { - long *p = current->thread.utraps; + if ((utrap_handler_t)current_thread_info()->utraps[type] != new_p && + current_thread_info()->utraps[0] > 1) { + long *p = current_thread_info()->utraps; - current->thread.utraps = + current_thread_info()->utraps = kmalloc((UT_TRAP_INSTRUCTION_31+1)*sizeof(long), GFP_KERNEL); - if (!current->thread.utraps) { - current->thread.utraps = p; + if (!current_thread_info()->utraps) { + current_thread_info()->utraps = p; return -ENOMEM; } p[0]--; - current->thread.utraps[0] = 1; - memcpy(current->thread.utraps+1, p+1, + current_thread_info()->utraps[0] = 1; + memcpy(current_thread_info()->utraps+1, p+1, UT_TRAP_INSTRUCTION_31*sizeof(long)); } } if (old_p) { - if (put_user((utrap_handler_t)(current->thread.utraps[type]), old_p)) + if (put_user((utrap_handler_t)(current_thread_info()->utraps[type]), old_p)) return -EFAULT; } if (old_d) { if (put_user(NULL, old_d)) return -EFAULT; } - current->thread.utraps[type] = (long)new_p; + current_thread_info()->utraps[type] = (long)new_p; return 0; } @@ -589,10 +589,10 @@ update_perfctrs(void) unsigned long pic, tmp; read_pic(pic); - tmp = (current->thread.kernel_cntd0 += (unsigned int)pic); - __put_user(tmp, current->thread.user_cntd0); - tmp = (current->thread.kernel_cntd1 += (pic >> 32)); - __put_user(tmp, current->thread.user_cntd1); + tmp = (current_thread_info()->kernel_cntd0 += (unsigned int)pic); + __put_user(tmp, current_thread_info()->user_cntd0); + tmp = (current_thread_info()->kernel_cntd1 += (pic >> 32)); + __put_user(tmp, current_thread_info()->user_cntd1); reset_pic(); } @@ -603,24 +603,24 @@ sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1, unsigned long ar switch(opcode) { case PERFCTR_ON: - current->thread.pcr_reg = arg2; - current->thread.user_cntd0 = (u64 *) arg0; - current->thread.user_cntd1 = (u64 *) arg1; - current->thread.kernel_cntd0 = - current->thread.kernel_cntd1 = 0; + current_thread_info()->pcr_reg = arg2; + current_thread_info()->user_cntd0 = (u64 *) arg0; + current_thread_info()->user_cntd1 = (u64 *) arg1; + current_thread_info()->kernel_cntd0 = + current_thread_info()->kernel_cntd1 = 0; write_pcr(arg2); reset_pic(); - current->thread.flags |= SPARC_FLAG_PERFCTR; + set_thread_flag(TIF_PERFCTR); break; case PERFCTR_OFF: err = -EINVAL; - if ((current->thread.flags & SPARC_FLAG_PERFCTR) != 0) { - current->thread.user_cntd0 = - current->thread.user_cntd1 = NULL; - current->thread.pcr_reg = 0; + if (test_thread_flag(TIF_PERFCTR)) { + current_thread_info()->user_cntd0 = + current_thread_info()->user_cntd1 = NULL; + current_thread_info()->pcr_reg = 0; write_pcr(0); - current->thread.flags &= ~(SPARC_FLAG_PERFCTR); + clear_thread_flag(TIF_PERFCTR); err = 0; } break; @@ -628,50 +628,50 @@ sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1, unsigned long ar case PERFCTR_READ: { unsigned long pic, tmp; - if (!(current->thread.flags & SPARC_FLAG_PERFCTR)) { + if (!test_thread_flag(TIF_PERFCTR)) { err = -EINVAL; break; } read_pic(pic); - tmp = (current->thread.kernel_cntd0 += (unsigned int)pic); - err |= __put_user(tmp, current->thread.user_cntd0); - tmp = (current->thread.kernel_cntd1 += (pic >> 32)); - err |= __put_user(tmp, current->thread.user_cntd1); + tmp = (current_thread_info()->kernel_cntd0 += (unsigned int)pic); + err |= __put_user(tmp, current_thread_info()->user_cntd0); + tmp = (current_thread_info()->kernel_cntd1 += (pic >> 32)); + err |= __put_user(tmp, current_thread_info()->user_cntd1); reset_pic(); break; } case PERFCTR_CLRPIC: - if (!(current->thread.flags & SPARC_FLAG_PERFCTR)) { + if (!test_thread_flag(TIF_PERFCTR)) { err = -EINVAL; break; } - current->thread.kernel_cntd0 = - current->thread.kernel_cntd1 = 0; + current_thread_info()->kernel_cntd0 = + current_thread_info()->kernel_cntd1 = 0; reset_pic(); break; case PERFCTR_SETPCR: { u64 *user_pcr = (u64 *)arg0; - if (!(current->thread.flags & SPARC_FLAG_PERFCTR)) { + if (!test_thread_flag(TIF_PERFCTR)) { err = -EINVAL; break; } - err |= __get_user(current->thread.pcr_reg, user_pcr); - write_pcr(current->thread.pcr_reg); - current->thread.kernel_cntd0 = - current->thread.kernel_cntd1 = 0; + err |= __get_user(current_thread_info()->pcr_reg, user_pcr); + write_pcr(current_thread_info()->pcr_reg); + current_thread_info()->kernel_cntd0 = + current_thread_info()->kernel_cntd1 = 0; reset_pic(); break; } case PERFCTR_GETPCR: { u64 *user_pcr = (u64 *)arg0; - if (!(current->thread.flags & SPARC_FLAG_PERFCTR)) { + if (!test_thread_flag(TIF_PERFCTR)) { err = -EINVAL; break; } - err |= __put_user(current->thread.pcr_reg, user_pcr); + err |= __put_user(current_thread_info()->pcr_reg, user_pcr); break; } diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 444454783..b5a876d10 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.183 2002-02-08 03:57:14 davem Exp $ +/* $Id: sys_sparc32.c,v 1.184 2002-02-09 19:49:31 davem Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -2726,8 +2726,8 @@ asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old struct k_sigaction new_ka, old_ka; int ret; - if(sig < 0) { - current->thread.flags |= SPARC_FLAG_NEWSIGNALS; + if (sig < 0) { + set_thread_flag(TIF_NEWSIGNALS); sig = -sig; } @@ -2771,7 +2771,7 @@ sys32_rt_sigaction(int sig, struct sigaction32 *act, struct sigaction32 *oact, /* All tasks which use RT signals (effectively) use * new style signals. */ - current->thread.flags |= SPARC_FLAG_NEWSIGNALS; + set_thread_flag(TIF_NEWSIGNALS); if (act) { new_ka.ka_restorer = restorer; @@ -2994,8 +2994,8 @@ asmlinkage int sparc32_execve(struct pt_regs *regs) if(!error) { fprs_write(0); - current->thread.xfsr[0] = 0; - current->thread.fpsaved[0] = 0; + current_thread_info()->xfsr[0] = 0; + current_thread_info()->fpsaved[0] = 0; regs->tstate &= ~TSTATE_PEF; } out: diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index a9aec1429..c0f90d367 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sunos32.c,v 1.63 2002-02-08 03:57:14 davem Exp $ +/* $Id: sys_sunos32.c,v 1.64 2002-02-09 19:49:31 davem Exp $ * sys_sunos32.c: SunOS binary compatability layer on sparc64. * * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -455,8 +455,8 @@ asmlinkage int sunos_nosys(void) siginfo_t info; static int cnt; - regs = current->thread.kregs; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + regs = current_thread_info()->kregs; + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -1046,7 +1046,7 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) if(!kmbuf) break; sp = (struct sparc_stackf32 *) - (current->thread.kregs->u_regs[UREG_FP] & 0xffffffffUL); + (current_thread_info()->kregs->u_regs[UREG_FP] & 0xffffffffUL); if(get_user(arg5, &sp->xxargs[0])) { rval = -EFAULT; kfree(kmbuf); diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index 58b122929..b920d559f 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S @@ -1,4 +1,4 @@ -/* $Id: trampoline.S,v 1.25 2002-01-11 08:45:38 davem Exp $ +/* $Id: trampoline.S,v 1.26 2002-02-09 19:49:30 davem Exp $ * trampoline.S: Jump start slave processors on sparc64. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -14,7 +14,7 @@ #include <asm/pgtable.h> #include <asm/spitfire.h> #include <asm/processor.h> -#include <asm/asm_offsets.h> +#include <asm/thread_info.h> .data .align 8 @@ -262,7 +262,7 @@ startup_continue: wrpr %o1, PSTATE_IG, %pstate /* Get our UPA MID. */ - lduw [%o2 + AOFF_task_cpu], %g1 + ldub [%o2 + TI_CPU], %g1 sethi %hi(cpu_data), %g5 or %g5, %lo(cpu_data), %g5 diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index a89fcd43b..3f8e7abeb 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.84 2002-01-30 01:39:56 davem Exp $ +/* $Id: traps.c,v 1.85 2002-02-09 19:49:31 davem Exp $ * arch/sparc64/kernel/traps.c * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) @@ -51,7 +51,7 @@ void bad_trap (struct pt_regs *regs, long lvl) sprintf(buffer, "Kernel bad sw trap %lx", lvl); die_if_kernel (buffer, regs); } - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -89,7 +89,7 @@ void instruction_access_exception (struct pt_regs *regs, sfsr, sfar); die_if_kernel("Iax", regs); } - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -1311,14 +1311,14 @@ void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned void do_fpe_common(struct pt_regs *regs) { - if(regs->tstate & TSTATE_PRIV) { + if (regs->tstate & TSTATE_PRIV) { regs->tpc = regs->tnpc; regs->tnpc += 4; } else { - unsigned long fsr = current->thread.xfsr[0]; + unsigned long fsr = current_thread_info()->xfsr[0]; siginfo_t info; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -1355,7 +1355,7 @@ void do_fpother(struct pt_regs *regs) struct fpustate *f = FPUSTATE; int ret = 0; - switch ((current->thread.xfsr[0] & 0x1c000)) { + switch ((current_thread_info()->xfsr[0] & 0x1c000)) { case (2 << 14): /* unfinished_FPop */ case (3 << 14): /* unimplemented_FPop */ ret = do_mathemu(regs, f); @@ -1370,9 +1370,9 @@ void do_tof(struct pt_regs *regs) { siginfo_t info; - if(regs->tstate & TSTATE_PRIV) + if (regs->tstate & TSTATE_PRIV) die_if_kernel("Penguin overflow trap from kernel mode", regs); - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -1388,7 +1388,7 @@ void do_div0(struct pt_regs *regs) { siginfo_t info; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -1404,11 +1404,11 @@ void instruction_dump (unsigned int *pc) { int i; - if((((unsigned long) pc) & 3)) + if ((((unsigned long) pc) & 3)) return; printk("Instruction DUMP:"); - for(i = -3; i < 6; i++) + for (i = -3; i < 6; i++) printk("%c%08x%c",i?' ':'<',pc[i],i?' ':'>'); printk("\n"); } @@ -1418,14 +1418,14 @@ void user_instruction_dump (unsigned int *pc) int i; unsigned int buf[9]; - if((((unsigned long) pc) & 3)) + if ((((unsigned long) pc) & 3)) return; - if(copy_from_user(buf, pc - 3, sizeof(buf))) + if (copy_from_user(buf, pc - 3, sizeof(buf))) return; printk("Instruction DUMP:"); - for(i = 0; i < 9; i++) + for (i = 0; i < 9; i++) printk("%c%08x%c",i==3?' ':'<',buf[i],i==3?' ':'>'); printk("\n"); } @@ -1433,18 +1433,18 @@ void user_instruction_dump (unsigned int *pc) void show_trace_task(struct task_struct *tsk) { unsigned long pc, fp; - unsigned long task_base = (unsigned long)tsk; + unsigned long thread_base = (unsigned long) tsk->thread_info; struct reg_window *rw; int count = 0; if (!tsk) return; - fp = tsk->thread.ksp + STACK_BIAS; + fp = tsk->thread_info->ksp + STACK_BIAS; do { /* Bogus frame pointer? */ - if (fp < (task_base + sizeof(struct task_struct)) || - fp >= (task_base + THREAD_SIZE)) + if (fp < (thread_base + sizeof(struct thread_info)) || + fp >= (thread_base + THREAD_SIZE)) break; rw = (struct reg_window *)fp; pc = rw->ins[7]; @@ -1471,7 +1471,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) printk("%s(%d): %s\n", current->comm, current->pid, str); __asm__ __volatile__("flushw"); __show_regs(regs); - if(regs->tstate & TSTATE_PRIV) { + if (regs->tstate & TSTATE_PRIV) { struct reg_window *rw = (struct reg_window *) (regs->u_regs[UREG_FP] + STACK_BIAS); @@ -1479,12 +1479,12 @@ void die_if_kernel(char *str, struct pt_regs *regs) * find some badly aligned kernel stack. */ lastrw = (struct reg_window *)current; - while(rw && - count++ < 30 && - rw >= lastrw && - (char *) rw < ((char *) current) - + sizeof (union task_union) && - !(((unsigned long) rw) & 0x7)) { + while (rw && + count++ < 30 && + rw >= lastrw && + (char *) rw < ((char *) current) + + sizeof (union thread_union) && + !(((unsigned long) rw) & 0x7)) { printk("Caller[%016lx]\n", rw->ins[7]); lastrw = rw; rw = (struct reg_window *) @@ -1492,7 +1492,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) } instruction_dump ((unsigned int *) regs->tpc); } else { - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -1502,7 +1502,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) smp_report_regs(); #endif - if(regs->tstate & TSTATE_PRIV) + if (regs->tstate & TSTATE_PRIV) do_exit(SIGKILL); do_exit(SIGSEGV); } @@ -1517,9 +1517,9 @@ void do_illegal_instruction(struct pt_regs *regs) u32 insn; siginfo_t info; - if(tstate & TSTATE_PRIV) + if (tstate & TSTATE_PRIV) die_if_kernel("Kernel illegal instruction", regs); - if(current->thread.flags & SPARC_FLAG_32BIT) + if (test_thread_flag(TIF_32BIT)) pc = (u32)pc; if (get_user(insn, (u32 *)pc) != -EFAULT) { if ((insn & 0xc1ffc000) == 0x81700000) /* POPC */ { @@ -1542,7 +1542,7 @@ void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned lo { siginfo_t info; - if(regs->tstate & TSTATE_PRIV) { + if (regs->tstate & TSTATE_PRIV) { extern void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, unsigned long sfar, unsigned long sfsr); @@ -1561,7 +1561,7 @@ void do_privop(struct pt_regs *regs) { siginfo_t info; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -1669,15 +1669,41 @@ void do_getpsr(struct pt_regs *regs) regs->u_regs[UREG_I0] = tstate_to_psr(regs->tstate); regs->tpc = regs->tnpc; regs->tnpc += 4; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } } +extern void thread_info_offsets_are_bolixed_dave(void); + /* Only invoked on boot processor. */ void trap_init(void) { + /* Compile time sanity check. */ + if (TI_TASK != offsetof(struct thread_info, task) || + TI_FLAGS != offsetof(struct thread_info, flags) || + TI_CPU != offsetof(struct thread_info, cpu) || + TI_FPSAVED != offsetof(struct thread_info, fpsaved) || + TI_KSP != offsetof(struct thread_info, ksp) || + TI_FAULT_ADDR != offsetof(struct thread_info, fault_address) || + TI_KREGS != offsetof(struct thread_info, kregs) || + TI_UTRAPS != offsetof(struct thread_info, utraps) || + TI_EXEC_DOMAIN != offsetof(struct thread_info, exec_domain) || + TI_REG_WINDOW != offsetof(struct thread_info, reg_window) || + TI_RWIN_SPTRS != offsetof(struct thread_info, rwbuf_stkptrs) || + TI_GSR != offsetof(struct thread_info, gsr) || + TI_XFSR != offsetof(struct thread_info, xfsr) || + TI_USER_CNTD0 != offsetof(struct thread_info, user_cntd0) || + TI_USER_CNTD1 != offsetof(struct thread_info, user_cntd1) || + TI_KERN_CNTD0 != offsetof(struct thread_info, kernel_cntd0) || + TI_KERN_CNTD1 != offsetof(struct thread_info, kernel_cntd1) || + TI_PCR != offsetof(struct thread_info, pcr_reg) || + TI_CEE_STUFF != offsetof(struct thread_info, cee_stuff) || + TI_FPREGS != offsetof(struct thread_info, fpregs) || + (TI_FPREGS & (64 - 1))) + thread_info_offsets_are_bolixed_dave(); + /* Attach to the address space of init_task. On SMP we * do this in smp.c:smp_callin for other cpus. */ @@ -1685,6 +1711,6 @@ void trap_init(void) current->active_mm = &init_mm; #ifdef CONFIG_SMP - current->cpu = hard_smp_processor_id(); + current_thread_info()->cpu = hard_smp_processor_id(); #endif } diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S index 3e1575346..4e9754085 100644 --- a/arch/sparc64/kernel/ttable.S +++ b/arch/sparc64/kernel/ttable.S @@ -1,4 +1,4 @@ -/* $Id: ttable.S,v 1.37 2002-01-23 11:27:32 davem Exp $ +/* $Id: ttable.S,v 1.38 2002-02-09 19:49:30 davem Exp $ * ttable.S: Sparc V9 Trap Table(s) with SpitFire/Cheetah extensions. * * Copyright (C) 1996, 2001 David S. Miller (davem@caip.rutgers.edu) @@ -211,20 +211,20 @@ tl1_ivec: TRAP_IVEC tl1_paw: TRAPTL1(do_paw_tl1) tl1_vaw: TRAPTL1(do_vaw_tl1) - /* The grotty trick to save %g1 into current->thread.kernel_cntd0 + /* The grotty trick to save %g1 into current->thread.cee_stuff * is because when we take this trap we could be interrupting trap - * code already using the trap alternate global registers. It is - * better to corrupt a performance counter than corrupt trap register - * state. We cross our fingers and pray that this store/load does + * code already using the trap alternate global registers. + * + * We cross our fingers and pray that this store/load does * not cause yet another CEE trap. */ tl1_cee: membar #Sync - stx %g1, [%g6 + AOFF_task_thread + AOFF_thread_kernel_cntd0] + stx %g1, [%g6 + TI_CEE_STUFF] ldxa [%g0] ASI_AFSR, %g1 membar #Sync stxa %g1, [%g0] ASI_AFSR membar #Sync - ldx [%g6 + AOFF_task_thread + AOFF_thread_kernel_cntd0], %g1 + ldx [%g6 + TI_CEE_STUFF], %g1 retry tl1_iamiss: BTRAPTL1(0x64) BTRAPTL1(0x65) BTRAPTL1(0x66) BTRAPTL1(0x67) diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c index b6b57850b..ec0207672 100644 --- a/arch/sparc64/kernel/unaligned.c +++ b/arch/sparc64/kernel/unaligned.c @@ -1,4 +1,4 @@ -/* $Id: unaligned.c,v 1.23 2001-04-09 04:29:03 davem Exp $ +/* $Id: unaligned.c,v 1.24 2002-02-09 19:49:31 davem Exp $ * unaligned.c: Unaligned load/store trap handling with special * cases for the kernel to do them more quickly. * @@ -42,7 +42,7 @@ static inline enum direction decode_direction(unsigned int insn) { unsigned long tmp = (insn >> 21) & 1; - if(!tmp) + if (!tmp) return load; else { switch ((insn>>19)&0xf) { @@ -63,15 +63,15 @@ static inline int decode_access_size(unsigned int insn) if (tmp == 11 || tmp == 14) /* ldx/stx */ return 8; tmp &= 3; - if(!tmp) + if (!tmp) return 4; - else if(tmp == 3) + else if (tmp == 3) return 16; /* ldd/std - Although it is actually 8 */ - else if(tmp == 2) + else if (tmp == 2) return 2; else { printk("Impossible unaligned trap. insn=%08x\n", insn); - die_if_kernel("Byte sized unaligned access?!?!", current->thread.kregs); + die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs); } } @@ -95,8 +95,8 @@ static inline int decode_signedness(unsigned int insn) static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2, unsigned int rd, int from_kernel) { - if(rs2 >= 16 || rs1 >= 16 || rd >= 16) { - if(from_kernel != 0) + if (rs2 >= 16 || rs1 >= 16 || rd >= 16) { + if (from_kernel != 0) __asm__ __volatile__("flushw"); else flushw_user(); @@ -112,13 +112,13 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) { unsigned long value; - if(reg < 16) + if (reg < 16) return (!reg ? 0 : regs->u_regs[reg]); if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); value = win->locals[reg - 16]; - } else if (current->thread.flags & SPARC_FLAG_32BIT) { + } else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 *win32; win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); get_user(value, &win32->locals[reg - 16]); @@ -132,13 +132,13 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) { - if(reg < 16) + if (reg < 16) return ®s->u_regs[reg]; if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); return &win->locals[reg - 16]; - } else if (current->thread.flags & SPARC_FLAG_32BIT) { + } else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 *win32; win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); return (unsigned long *)&win32->locals[reg - 16]; @@ -156,7 +156,7 @@ static inline unsigned long compute_effective_address(struct pt_regs *regs, unsigned int rs2 = insn & 0x1f; int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; - if(insn & 0x2000) { + if (insn & 0x2000) { maybe_flush_windows(rs1, 0, rd, from_kernel); return (fetch_reg(rs1, regs) + sign_extend_imm13(insn)); } else { @@ -335,7 +335,7 @@ static inline void advance(struct pt_regs *regs) { regs->tpc = regs->tnpc; regs->tnpc += 4; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } @@ -360,7 +360,7 @@ void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) if (!fixup) { unsigned long address = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f)); - if(address < PAGE_SIZE) { + if (address < PAGE_SIZE) { printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference in mna handler"); } else printk(KERN_ALERT "Unable to handle kernel paging request in mna handler"); @@ -387,7 +387,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u enum direction dir = decode_direction(insn); int size = decode_access_size(insn); - if(!ok_for_kernel(insn) || dir == both) { + if (!ok_for_kernel(insn) || dir == both) { printk("Unsupported unaligned load/store trap for kernel at <%016lx>.\n", regs->tpc); unaligned_panic("Kernel does fpu/atomic unaligned load/store.", regs); @@ -408,7 +408,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] retpc[%016lx]\n", regs->tpc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); #endif - switch(dir) { + switch (dir) { case load: do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs), size, (unsigned long *) addr, @@ -459,11 +459,11 @@ int handle_popc(u32 insn, struct pt_regs *regs) ret += popc_helper[value & 0xf]; value >>= 4; } - if(rd < 16) { + if (rd < 16) { if (rd) regs->u_regs[rd] = ret; } else { - if (current->thread.flags & SPARC_FLAG_32BIT) { + if (test_thread_flag(TIF_32BIT)) { struct reg_window32 *win32; win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); put_user(ret, &win32->locals[rd - 16]); @@ -490,9 +490,9 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs) int flag = (freg < 32) ? FPRS_DL : FPRS_DU; save_and_clear_fpu(); - current->thread.xfsr[0] &= ~0x1c000; + current_thread_info()->xfsr[0] &= ~0x1c000; if (freg & 3) { - current->thread.xfsr[0] |= (6 << 14) /* invalid_fp_register */; + current_thread_info()->xfsr[0] |= (6 << 14) /* invalid_fp_register */; do_fpother(regs); return 0; } @@ -500,7 +500,7 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs) /* STQ */ u64 first = 0, second = 0; - if (current->thread.fpsaved[0] & flag) { + if (current_thread_info()->fpsaved[0] & flag) { first = *(u64 *)&f->regs[freg]; second = *(u64 *)&f->regs[freg+2]; } @@ -575,18 +575,18 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs) break; } } - if (!(current->thread.fpsaved[0] & FPRS_FEF)) { - current->thread.fpsaved[0] = FPRS_FEF; - current->thread.gsr[0] = 0; + if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) { + current_thread_info()->fpsaved[0] = FPRS_FEF; + current_thread_info()->gsr[0] = 0; } - if (!(current->thread.fpsaved[0] & flag)) { + if (!(current_thread_info()->fpsaved[0] & flag)) { if (freg < 32) memset(f->regs, 0, 32*sizeof(u32)); else memset(f->regs+32, 0, 32*sizeof(u32)); } memcpy(f->regs + freg, data, size * 4); - current->thread.fpsaved[0] |= flag; + current_thread_info()->fpsaved[0] |= flag; } advance(regs); return 1; @@ -604,7 +604,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) reg[0] = 0; if ((insn & 0x780000) == 0x180000) reg[1] = 0; - } else if (current->thread.flags & SPARC_FLAG_32BIT) { + } else if (test_thread_flag(TIF_32BIT)) { put_user(0, (int *)reg); if ((insn & 0x780000) == 0x180000) put_user(0, ((int *)reg) + 1); @@ -627,9 +627,9 @@ void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr int flag; struct fpustate *f = FPUSTATE; - if(tstate & TSTATE_PRIV) + if (tstate & TSTATE_PRIV) die_if_kernel("lddfmna from kernel", regs); - if(current->thread.flags & SPARC_FLAG_32BIT) + if (test_thread_flag(TIF_32BIT)) pc = (u32)pc; if (get_user(insn, (u32 *)pc) != -EFAULT) { asi = sfsr >> 16; @@ -649,18 +649,18 @@ void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr if (asi & 0x8) /* Little */ value = __swab64p(&value); flag = (freg < 32) ? FPRS_DL : FPRS_DU; - if (!(current->thread.fpsaved[0] & FPRS_FEF)) { - current->thread.fpsaved[0] = FPRS_FEF; - current->thread.gsr[0] = 0; + if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) { + current_thread_info()->fpsaved[0] = FPRS_FEF; + current_thread_info()->gsr[0] = 0; } - if (!(current->thread.fpsaved[0] & flag)) { + if (!(current_thread_info()->fpsaved[0] & flag)) { if (freg < 32) memset(f->regs, 0, 32*sizeof(u32)); else memset(f->regs+32, 0, 32*sizeof(u32)); } *(u64 *)(f->regs + freg) = value; - current->thread.fpsaved[0] |= flag; + current_thread_info()->fpsaved[0] |= flag; } else { daex: data_access_exception(regs); return; @@ -679,9 +679,9 @@ void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr int flag; struct fpustate *f = FPUSTATE; - if(tstate & TSTATE_PRIV) + if (tstate & TSTATE_PRIV) die_if_kernel("stdfmna from kernel", regs); - if(current->thread.flags & SPARC_FLAG_32BIT) + if (test_thread_flag(TIF_32BIT)) pc = (u32)pc; if (get_user(insn, (u32 *)pc) != -EFAULT) { freg = ((insn >> 25) & 0x1e) | ((insn >> 20) & 0x20); @@ -692,7 +692,7 @@ void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr (asi < ASI_P)) goto daex; save_and_clear_fpu(); - if (current->thread.fpsaved[0] & flag) + if (current_thread_info()->fpsaved[0] & flag) value = *(u64 *)&f->regs[freg]; switch (asi) { case ASI_P: diff --git a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S index a80260149..025733715 100644 --- a/arch/sparc64/kernel/winfixup.S +++ b/arch/sparc64/kernel/winfixup.S @@ -1,4 +1,4 @@ -/* $Id: winfixup.S,v 1.29 2000-03-26 09:13:48 davem Exp $ +/* $Id: winfixup.S,v 1.30 2002-02-09 19:49:30 davem Exp $ * * winfixup.S: Handle cases where user stack pointer is found to be bogus. * @@ -11,7 +11,7 @@ #include <asm/ptrace.h> #include <asm/processor.h> #include <asm/spitfire.h> -#include <asm/asm_offsets.h> +#include <asm/thread_info.h> .text .align 32 @@ -69,8 +69,8 @@ fill_fixup: mov %g6, %o7 ! Get current. andn %l1, PSTATE_MM, %l1 ! We want to be in RMO - stb %g4, [%g6 + AOFF_task_thread + AOFF_thread_fault_code] - stx %g5, [%g6 + AOFF_task_thread + AOFF_thread_fault_address] + stb %g4, [%g6 + TI_FAULT_CODE] + stx %g5, [%g6 + TI_FAULT_ADDR] wrpr %g0, 0x0, %tl ! Out of trap levels. wrpr %l1, (PSTATE_IE | PSTATE_AG | PSTATE_RMO), %pstate sethi %uhi(PAGE_OFFSET), %g4 ! Prepare page_offset global reg @@ -94,56 +94,56 @@ fill_fixup: * do not touch %g7 or %g2 so we handle the two cases fine. */ spill_fixup: - ldub [%g6 + AOFF_task_thread + AOFF_thread_flags], %g1 - andcc %g1, SPARC_FLAG_32BIT, %g0 - ldub [%g6 + AOFF_task_thread + AOFF_thread_w_saved], %g1 + ldx [%g6 + TI_FLAGS], %g1 + andcc %g1, _TIF_32BIT, %g0 + ldub [%g6 + TI_WSAVED], %g1 sll %g1, 3, %g3 add %g6, %g3, %g3 - stx %sp, [%g3 + AOFF_task_thread + AOFF_thread_rwbuf_stkptrs] + stx %sp, [%g3 + TI_RWIN_SPTRS] sll %g1, 7, %g3 bne,pt %xcc, 1f add %g6, %g3, %g3 - stx %l0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x00] - stx %l1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x08] - - stx %l2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x10] - stx %l3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x18] - stx %l4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x20] - stx %l5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x28] - stx %l6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x30] - stx %l7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x38] - stx %i0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x40] - stx %i1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x48] - - stx %i2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x50] - stx %i3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x58] - stx %i4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x60] - stx %i5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x68] - stx %i6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x70] + stx %l0, [%g3 + TI_REG_WINDOW + 0x00] + stx %l1, [%g3 + TI_REG_WINDOW + 0x08] + + stx %l2, [%g3 + TI_REG_WINDOW + 0x10] + stx %l3, [%g3 + TI_REG_WINDOW + 0x18] + stx %l4, [%g3 + TI_REG_WINDOW + 0x20] + stx %l5, [%g3 + TI_REG_WINDOW + 0x28] + stx %l6, [%g3 + TI_REG_WINDOW + 0x30] + stx %l7, [%g3 + TI_REG_WINDOW + 0x38] + stx %i0, [%g3 + TI_REG_WINDOW + 0x40] + stx %i1, [%g3 + TI_REG_WINDOW + 0x48] + + stx %i2, [%g3 + TI_REG_WINDOW + 0x50] + stx %i3, [%g3 + TI_REG_WINDOW + 0x58] + stx %i4, [%g3 + TI_REG_WINDOW + 0x60] + stx %i5, [%g3 + TI_REG_WINDOW + 0x68] + stx %i6, [%g3 + TI_REG_WINDOW + 0x70] b,pt %xcc, 2f - stx %i7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x78] -1: stw %l0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x00] - - stw %l1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x04] - stw %l2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x08] - stw %l3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x0c] - stw %l4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x10] - stw %l5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x14] - stw %l6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x18] - stw %l7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x1c] - stw %i0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x20] - - stw %i1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x24] - stw %i2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x28] - stw %i3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x2c] - stw %i4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x30] - stw %i5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x34] - stw %i6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x38] - stw %i7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x3c] + stx %i7, [%g3 + TI_REG_WINDOW + 0x78] +1: stw %l0, [%g3 + TI_REG_WINDOW + 0x00] + + stw %l1, [%g3 + TI_REG_WINDOW + 0x04] + stw %l2, [%g3 + TI_REG_WINDOW + 0x08] + stw %l3, [%g3 + TI_REG_WINDOW + 0x0c] + stw %l4, [%g3 + TI_REG_WINDOW + 0x10] + stw %l5, [%g3 + TI_REG_WINDOW + 0x14] + stw %l6, [%g3 + TI_REG_WINDOW + 0x18] + stw %l7, [%g3 + TI_REG_WINDOW + 0x1c] + stw %i0, [%g3 + TI_REG_WINDOW + 0x20] + + stw %i1, [%g3 + TI_REG_WINDOW + 0x24] + stw %i2, [%g3 + TI_REG_WINDOW + 0x28] + stw %i3, [%g3 + TI_REG_WINDOW + 0x2c] + stw %i4, [%g3 + TI_REG_WINDOW + 0x30] + stw %i5, [%g3 + TI_REG_WINDOW + 0x34] + stw %i6, [%g3 + TI_REG_WINDOW + 0x38] + stw %i7, [%g3 + TI_REG_WINDOW + 0x3c] 2: add %g1, 1, %g1 - stb %g1, [%g6 + AOFF_task_thread + AOFF_thread_w_saved] + stb %g1, [%g6 + TI_WSAVED] rdpr %tstate, %g1 andcc %g1, TSTATE_PRIV, %g0 saved @@ -153,8 +153,8 @@ spill_fixup: retry window_scheisse_from_user_common: - stb %g4, [%g6 + AOFF_task_thread + AOFF_thread_fault_code] - stx %g5, [%g6 + AOFF_task_thread + AOFF_thread_fault_address] + stb %g4, [%g6 + TI_FAULT_CODE] + stx %g5, [%g6 + TI_FAULT_ADDR] wrpr %g1, %cwp ba,pt %xcc, etrap rd %pc, %g7 @@ -204,47 +204,47 @@ fill_fixup_mna: b,pt %xcc, rtrap nop ! yes, the nop is correct spill_fixup_mna: - ldub [%g6 + AOFF_task_thread + AOFF_thread_flags], %g1 - andcc %g1, SPARC_FLAG_32BIT, %g0 - ldub [%g6 + AOFF_task_thread + AOFF_thread_w_saved], %g1 + ldx [%g6 + TI_FLAGS], %g1 + andcc %g1, _TIF_32BIT, %g0 + ldub [%g6 + TI_WSAVED], %g1 sll %g1, 3, %g3 add %g6, %g3, %g3 - stx %sp, [%g3 + AOFF_task_thread + AOFF_thread_rwbuf_stkptrs] + stx %sp, [%g3 + TI_RWIN_SPTRS] sll %g1, 7, %g3 bne,pt %xcc, 1f add %g6, %g3, %g3 - stx %l0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x00] - stx %l1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x08] - stx %l2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x10] - stx %l3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x18] - stx %l4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x20] - - stx %l5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x28] - stx %l6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x30] - stx %l7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x38] - stx %i0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x40] - stx %i1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x48] - stx %i2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x50] - stx %i3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x58] - stx %i4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x60] - - stx %i5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x68] - stx %i6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x70] - stx %i7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x78] + stx %l0, [%g3 + TI_REG_WINDOW + 0x00] + stx %l1, [%g3 + TI_REG_WINDOW + 0x08] + stx %l2, [%g3 + TI_REG_WINDOW + 0x10] + stx %l3, [%g3 + TI_REG_WINDOW + 0x18] + stx %l4, [%g3 + TI_REG_WINDOW + 0x20] + + stx %l5, [%g3 + TI_REG_WINDOW + 0x28] + stx %l6, [%g3 + TI_REG_WINDOW + 0x30] + stx %l7, [%g3 + TI_REG_WINDOW + 0x38] + stx %i0, [%g3 + TI_REG_WINDOW + 0x40] + stx %i1, [%g3 + TI_REG_WINDOW + 0x48] + stx %i2, [%g3 + TI_REG_WINDOW + 0x50] + stx %i3, [%g3 + TI_REG_WINDOW + 0x58] + stx %i4, [%g3 + TI_REG_WINDOW + 0x60] + + stx %i5, [%g3 + TI_REG_WINDOW + 0x68] + stx %i6, [%g3 + TI_REG_WINDOW + 0x70] + stx %i7, [%g3 + TI_REG_WINDOW + 0x78] b,pt %xcc, 2f add %g1, 1, %g1 -1: std %l0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x00] - std %l2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x08] - std %l4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x10] - - std %l6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x18] - std %i0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x20] - std %i2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x28] - std %i4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x30] - std %i6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x38] +1: std %l0, [%g3 + TI_REG_WINDOW + 0x00] + std %l2, [%g3 + TI_REG_WINDOW + 0x08] + std %l4, [%g3 + TI_REG_WINDOW + 0x10] + + std %l6, [%g3 + TI_REG_WINDOW + 0x18] + std %i0, [%g3 + TI_REG_WINDOW + 0x20] + std %i2, [%g3 + TI_REG_WINDOW + 0x28] + std %i4, [%g3 + TI_REG_WINDOW + 0x30] + std %i6, [%g3 + TI_REG_WINDOW + 0x38] add %g1, 1, %g1 -2: stb %g1, [%g6 + AOFF_task_thread + AOFF_thread_w_saved] +2: stb %g1, [%g6 + TI_WSAVED] rdpr %tstate, %g1 andcc %g1, TSTATE_PRIV, %g0 @@ -311,47 +311,47 @@ fill_fixup_dax: b,pt %xcc, rtrap nop ! yes, the nop is correct spill_fixup_dax: - ldub [%g6 + AOFF_task_thread + AOFF_thread_flags], %g1 - andcc %g1, SPARC_FLAG_32BIT, %g0 - ldub [%g6 + AOFF_task_thread + AOFF_thread_w_saved], %g1 + ldx [%g6 + TI_FLAGS], %g1 + andcc %g1, _TIF_32BIT, %g0 + ldub [%g6 + TI_WSAVED], %g1 sll %g1, 3, %g3 add %g6, %g3, %g3 - stx %sp, [%g3 + AOFF_task_thread + AOFF_thread_rwbuf_stkptrs] + stx %sp, [%g3 + TI_RWIN_SPTRS] sll %g1, 7, %g3 bne,pt %xcc, 1f add %g6, %g3, %g3 - stx %l0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x00] - stx %l1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x08] - stx %l2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x10] - stx %l3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x18] - stx %l4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x20] - - stx %l5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x28] - stx %l6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x30] - stx %l7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x38] - stx %i0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x40] - stx %i1, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x48] - stx %i2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x50] - stx %i3, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x58] - stx %i4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x60] - - stx %i5, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x68] - stx %i6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x70] - stx %i7, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x78] + stx %l0, [%g3 + TI_REG_WINDOW + 0x00] + stx %l1, [%g3 + TI_REG_WINDOW + 0x08] + stx %l2, [%g3 + TI_REG_WINDOW + 0x10] + stx %l3, [%g3 + TI_REG_WINDOW + 0x18] + stx %l4, [%g3 + TI_REG_WINDOW + 0x20] + + stx %l5, [%g3 + TI_REG_WINDOW + 0x28] + stx %l6, [%g3 + TI_REG_WINDOW + 0x30] + stx %l7, [%g3 + TI_REG_WINDOW + 0x38] + stx %i0, [%g3 + TI_REG_WINDOW + 0x40] + stx %i1, [%g3 + TI_REG_WINDOW + 0x48] + stx %i2, [%g3 + TI_REG_WINDOW + 0x50] + stx %i3, [%g3 + TI_REG_WINDOW + 0x58] + stx %i4, [%g3 + TI_REG_WINDOW + 0x60] + + stx %i5, [%g3 + TI_REG_WINDOW + 0x68] + stx %i6, [%g3 + TI_REG_WINDOW + 0x70] + stx %i7, [%g3 + TI_REG_WINDOW + 0x78] b,pt %xcc, 2f add %g1, 1, %g1 -1: std %l0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x00] - std %l2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x08] - std %l4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x10] - - std %l6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x18] - std %i0, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x20] - std %i2, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x28] - std %i4, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x30] - std %i6, [%g3 + AOFF_task_thread + AOFF_thread_reg_window + 0x38] +1: std %l0, [%g3 + TI_REG_WINDOW + 0x00] + std %l2, [%g3 + TI_REG_WINDOW + 0x08] + std %l4, [%g3 + TI_REG_WINDOW + 0x10] + + std %l6, [%g3 + TI_REG_WINDOW + 0x18] + std %i0, [%g3 + TI_REG_WINDOW + 0x20] + std %i2, [%g3 + TI_REG_WINDOW + 0x28] + std %i4, [%g3 + TI_REG_WINDOW + 0x30] + std %i6, [%g3 + TI_REG_WINDOW + 0x38] add %g1, 1, %g1 -2: stb %g1, [%g6 + AOFF_task_thread + AOFF_thread_w_saved] +2: stb %g1, [%g6 + TI_WSAVED] rdpr %tstate, %g1 andcc %g1, TSTATE_PRIV, %g0 diff --git a/arch/sparc64/lib/VIScopy.S b/arch/sparc64/lib/VIScopy.S index c64b7d46c..300ca249e 100644 --- a/arch/sparc64/lib/VIScopy.S +++ b/arch/sparc64/lib/VIScopy.S @@ -1,4 +1,4 @@ -/* $Id: VIScopy.S,v 1.26 2001-09-27 04:36:24 kanoj Exp $ +/* $Id: VIScopy.S,v 1.27 2002-02-09 19:49:30 davem Exp $ * VIScopy.S: High speed copy operations utilizing the UltraSparc * Visual Instruction Set. * @@ -26,24 +26,24 @@ #ifdef __KERNEL__ #include <asm/visasm.h> -#include <asm/asm_offsets.h> +#include <asm/thread_info.h> -#define FPU_CLEAN_RETL \ - ldub [%g6 + AOFF_task_thread + AOFF_thread_current_ds], %o1; \ - VISExit \ - clr %o0; \ - retl; \ +#define FPU_CLEAN_RETL \ + ldub [%g6 + TI_CURRENT_DS], %o1; \ + VISExit \ + clr %o0; \ + retl; \ wr %o1, %g0, %asi; -#define FPU_RETL \ - ldub [%g6 + AOFF_task_thread + AOFF_thread_current_ds], %o1; \ - VISExit \ - clr %o0; \ - retl; \ +#define FPU_RETL \ + ldub [%g6 + TI_CURRENT_DS], %o1; \ + VISExit \ + clr %o0; \ + retl; \ wr %o1, %g0, %asi; -#define NORMAL_RETL \ - ldub [%g6 + AOFF_task_thread + AOFF_thread_current_ds], %o1; \ - clr %o0; \ - retl; \ +#define NORMAL_RETL \ + ldub [%g6 + TI_CURRENT_DS], %o1; \ + clr %o0; \ + retl; \ wr %o1, %g0, %asi; #define EX(x,y,a,b) \ 98: x,y; \ @@ -1032,7 +1032,7 @@ VIScopyfixup_ret: /* If this is copy_from_user(), zero out the rest of the * kernel buffer. */ - ldub [%g6 + AOFF_task_thread + AOFF_thread_current_ds], %o4 + ldub [%g6 + TI_CURRENT_DS], %o4 andcc asi_src, 0x1, %g0 be,pt %icc, 1f VISExit diff --git a/arch/sparc64/lib/VIScsum.S b/arch/sparc64/lib/VIScsum.S index a1b369e64..70651eda2 100644 --- a/arch/sparc64/lib/VIScsum.S +++ b/arch/sparc64/lib/VIScsum.S @@ -1,4 +1,4 @@ -/* $Id: VIScsum.S,v 1.6 2000-02-20 23:21:39 davem Exp $ +/* $Id: VIScsum.S,v 1.7 2002-02-09 19:49:30 davem Exp $ * VIScsum.S: High bandwidth IP checksumming utilizing the UltraSparc * Visual Instruction Set. * @@ -28,7 +28,7 @@ #include <asm/head.h> #include <asm/asi.h> #include <asm/visasm.h> -#include <asm/asm_offsets.h> +#include <asm/thread_info.h> #else #define ASI_BLK_P 0xf0 #define FRPS_FEF 0x04 @@ -342,7 +342,7 @@ csum_partial: DO_THE_TRICK(f44,f46,f48,f50,f52,f54,f56,f58,f60,f62,f0,f2,f4,f6,f8,f10,f12,f14) END_THE_TRICK(f60,f62,f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30) #ifdef __KERNEL__ - ldub [%g6 + AOFF_task_thread + AOFF_thread_current_ds], %g7 + ldub [%g6 + TI_CURRENT_DS], %g7 #endif and %o1, 0x3f, %o1 /* IEU0 Group */ #ifdef __KERNEL__ diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S index d65e5dafd..b95beb596 100644 --- a/arch/sparc64/lib/VISsave.S +++ b/arch/sparc64/lib/VISsave.S @@ -1,4 +1,4 @@ -/* $Id: VISsave.S,v 1.5 2001-03-08 22:08:51 davem Exp $ +/* $Id: VISsave.S,v 1.6 2002-02-09 19:49:30 davem Exp $ * VISsave.S: Code for saving FPU register state for * VIS routines. One should not call this directly, * but use macros provided in <asm/visasm.h>. @@ -10,6 +10,7 @@ #include <asm/page.h> #include <asm/ptrace.h> #include <asm/visasm.h> +#include <asm/thread_info.h> .text .globl VISenter, VISenterhalf @@ -19,45 +20,45 @@ .align 32 VISenter: - ldub [%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %g1 + ldub [%g6 + TI_FPDEPTH], %g1 brnz,a,pn %g1, 1f cmp %g1, 1 - stb %g0, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved] - stx %fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr] + stb %g0, [%g6 + TI_FPSAVED] + stx %fsr, [%g6 + TI_XFSR] 9: jmpl %g7 + %g0, %g0 nop 1: bne,pn %icc, 2f srl %g1, 1, %g1 -vis1: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3 - stx %fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr] +vis1: ldub [%g6 + TI_FPSAVED], %g3 + stx %fsr, [%g6 + TI_XFSR] or %g3, %o5, %g3 - stb %g3, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved] + stb %g3, [%g6 + TI_FPSAVED] rd %gsr, %g3 clr %g1 ba,pt %xcc, 3f - stx %g3, [%g6 + AOFF_task_thread + AOFF_thread_gsr] + stx %g3, [%g6 + TI_GSR] 2: add %g6, %g1, %g3 cmp %o5, FPRS_DU be,pn %icc, 6f sll %g1, 3, %g1 - stb %o5, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved] + stb %o5, [%g3 + TI_FPSAVED] rd %gsr, %g2 add %g6, %g1, %g3 - stx %g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr] + stx %g2, [%g3 + TI_GSR] add %g6, %g1, %g2 - stx %fsr, [%g2 + AOFF_task_thread + AOFF_thread_xfsr] + stx %fsr, [%g2 + TI_XFSR] sll %g1, 5, %g1 3: andcc %o5, FPRS_DL|FPRS_DU, %g0 be,pn %icc, 9b - add %g6, AOFF_task_fpregs, %g2 + add %g6, TI_FPREGS, %g2 andcc %o5, FPRS_DL, %g0 membar #StoreStore | #LoadStore be,pn %icc, 4f - add %g6, AOFF_task_fpregs+0x40, %g3 + add %g6, TI_FPREGS+0x40, %g3 stda %f0, [%g2 + %g1] ASI_BLK_P stda %f16, [%g3 + %g1] ASI_BLK_P andcc %o5, FPRS_DU, %g0 @@ -70,13 +71,13 @@ vis1: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3 jmpl %g7 + %g0, %g0 nop -6: ldub [%g3 + AOFF_task_thread + AOFF_thread_fpsaved], %o5 +6: ldub [%g3 + TI_FPSAVED], %o5 or %o5, FPRS_DU, %o5 - add %g6, AOFF_task_fpregs+0x80, %g2 - stb %o5, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved] + add %g6, TI_FPREGS+0x80, %g2 + stb %o5, [%g3 + TI_FPSAVED] sll %g1, 5, %g1 - add %g6, AOFF_task_fpregs+0xc0, %g3 + add %g6, TI_FPREGS+0xc0, %g3 wr %g0, FPRS_FEF, %fprs membar #StoreStore | #LoadStore stda %f32, [%g2 + %g1] ASI_BLK_P @@ -88,11 +89,11 @@ vis1: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpsaved], %g3 .align 32 VISenterhalf: - ldub [%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %g1 + ldub [%g6 + TI_FPDEPTH], %g1 brnz,a,pn %g1, 1f cmp %g1, 1 - stb %g0, [%g6 + AOFF_task_thread + AOFF_thread_fpsaved] - stx %fsr, [%g6 + AOFF_task_thread + AOFF_thread_xfsr] + stb %g0, [%g6 + TI_FPSAVED] + stx %fsr, [%g6 + TI_XFSR] clr %o5 jmpl %g7 + %g0, %g0 wr %g0, FPRS_FEF, %fprs @@ -104,20 +105,20 @@ VISenterhalf: 2: addcc %g6, %g1, %g3 sll %g1, 3, %g1 andn %o5, FPRS_DU, %g2 - stb %g2, [%g3 + AOFF_task_thread + AOFF_thread_fpsaved] + stb %g2, [%g3 + TI_FPSAVED] rd %gsr, %g2 add %g6, %g1, %g3 - stx %g2, [%g3 + AOFF_task_thread + AOFF_thread_gsr] + stx %g2, [%g3 + TI_GSR] add %g6, %g1, %g2 - stx %fsr, [%g2 + AOFF_task_thread + AOFF_thread_xfsr] + stx %fsr, [%g2 + TI_XFSR] sll %g1, 5, %g1 3: andcc %o5, FPRS_DL, %g0 be,pn %icc, 4f - add %g6, AOFF_task_fpregs, %g2 + add %g6, TI_FPREGS, %g2 membar #StoreStore | #LoadStore - add %g6, AOFF_task_fpregs+0x40, %g3 + add %g6, TI_FPREGS+0x40, %g3 stda %f0, [%g2 + %g1] ASI_BLK_P stda %f16, [%g3 + %g1] ASI_BLK_P membar #Sync diff --git a/arch/sparc64/lib/blockops.S b/arch/sparc64/lib/blockops.S index 5903c09a7..a3d8bf7f6 100644 --- a/arch/sparc64/lib/blockops.S +++ b/arch/sparc64/lib/blockops.S @@ -1,4 +1,4 @@ -/* $Id: blockops.S,v 1.41 2001-12-05 06:05:35 davem Exp $ +/* $Id: blockops.S,v 1.42 2002-02-09 19:49:30 davem Exp $ * blockops.S: UltraSparc block zero optimized routines. * * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com) @@ -7,9 +7,9 @@ #include "VIS.h" #include <asm/visasm.h> +#include <asm/thread_info.h> #include <asm/page.h> #include <asm/pgtable.h> -#include <asm/asm_offsets.h> #define TOUCH(reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7) \ fmovd %reg0, %f48; fmovd %reg1, %f50; \ @@ -61,7 +61,7 @@ cheetah_patch_1: * so we do not risk a multiple TLB match condition later when * restoring those entries. */ - ldub [%g6 + AOFF_task_thread + AOFF_thread_use_blkcommit], %g3 + ldx [%g6 + TI_FLAGS], %g3 /* Spitfire Errata #32 workaround */ mov 0x8, %o4 @@ -100,7 +100,7 @@ cheetah_patch_1: stxa %g2, [%o3] ASI_DTLB_DATA_ACCESS membar #Sync - cmp %g3, 0 + andcc %g3, _TIF_BLKCOMMIT, %g0 bne,pn %xcc, copy_page_using_blkcommit nop diff --git a/arch/sparc64/lib/checksum.S b/arch/sparc64/lib/checksum.S index 4e962ed47..f87faa513 100644 --- a/arch/sparc64/lib/checksum.S +++ b/arch/sparc64/lib/checksum.S @@ -18,7 +18,7 @@ #include <asm/ptrace.h> #include <asm/asi.h> #include <asm/page.h> -#include <asm/asm_offsets.h> +#include <asm/thread_info.h> /* The problem with the "add with carry" instructions on Ultra * are two fold. Firstly, they cannot pair with jack shit, @@ -498,7 +498,7 @@ cpc_user_end: .globl cpc_handler cpc_handler: ldx [%sp + 0x7ff + 128], %g1 - ldub [%g6 + AOFF_task_thread + AOFF_thread_current_ds], %g3 + ldub [%g6 + TI_CURRENT_DS], %g3 sub %g0, EFAULT, %g2 brnz,a,pt %g1, 1f st %g2, [%g1] diff --git a/arch/sparc64/math-emu/math.c b/arch/sparc64/math-emu/math.c index 4528ed9a5..f2855a109 100644 --- a/arch/sparc64/math-emu/math.c +++ b/arch/sparc64/math-emu/math.c @@ -1,4 +1,4 @@ -/* $Id: math.c,v 1.11 1999-12-20 05:02:25 davem Exp $ +/* $Id: math.c,v 1.12 2002-02-09 19:49:31 davem Exp $ * arch/sparc64/math-emu/math.c * * Copyright (C) 1997,1999 Jakub Jelinek (jj@ultra.linux.cz) @@ -90,25 +90,25 @@ */ static inline int record_exception(struct pt_regs *regs, int eflag) { - u64 fsr = current->thread.xfsr[0]; + u64 fsr = current_thread_info()->xfsr[0]; int would_trap; /* Determine if this exception would have generated a trap. */ would_trap = (fsr & ((long)eflag << FSR_TEM_SHIFT)) != 0UL; /* If trapping, we only want to signal one bit. */ - if(would_trap != 0) { + if (would_trap != 0) { eflag &= ((fsr & FSR_TEM_MASK) >> FSR_TEM_SHIFT); - if((eflag & (eflag - 1)) != 0) { - if(eflag & FP_EX_INVALID) + if ((eflag & (eflag - 1)) != 0) { + if (eflag & FP_EX_INVALID) eflag = FP_EX_INVALID; - else if(eflag & FP_EX_OVERFLOW) + else if (eflag & FP_EX_OVERFLOW) eflag = FP_EX_OVERFLOW; - else if(eflag & FP_EX_UNDERFLOW) + else if (eflag & FP_EX_UNDERFLOW) eflag = FP_EX_UNDERFLOW; - else if(eflag & FP_EX_DIVZERO) + else if (eflag & FP_EX_DIVZERO) eflag = FP_EX_DIVZERO; - else if(eflag & FP_EX_INEXACT) + else if (eflag & FP_EX_INEXACT) eflag = FP_EX_INEXACT; } } @@ -128,19 +128,19 @@ static inline int record_exception(struct pt_regs *regs, int eflag) * CEXC just generated is OR'd into the * existing value of AEXC. */ - if(would_trap == 0) + if (would_trap == 0) fsr |= ((long)eflag << FSR_AEXC_SHIFT); /* If trapping, indicate fault trap type IEEE. */ - if(would_trap != 0) + if (would_trap != 0) fsr |= (1UL << 14); - current->thread.xfsr[0] = fsr; + current_thread_info()->xfsr[0] = fsr; /* If we will not trap, advance the program counter over * the instruction being handled. */ - if(would_trap == 0) { + if (would_trap == 0) { regs->tpc = regs->tnpc; regs->tnpc += 4; } @@ -174,10 +174,10 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) int IR; long XR, xfsr; - if(tstate & TSTATE_PRIV) + if (tstate & TSTATE_PRIV) die_if_kernel("FPQuad from kernel", regs); - if(current->thread.flags & SPARC_FLAG_32BIT) - pc = (u32)pc; + if (test_thread_flag(TIF_32BIT)) + pc &= 0xffffffff; if (get_user(insn, (u32 *)pc) != -EFAULT) { if ((insn & 0xc1f80000) == 0x81a00000) /* FPOP1 */ { switch ((insn >> 5) & 0x1ff) { @@ -231,9 +231,9 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) case FMOVQ3: /* fmovq %fccX, %fY, %fZ */ if (!((insn >> 11) & 3)) - XR = current->thread.xfsr[0] >> 10; + XR = current_thread_info()->xfsr[0] >> 10; else - XR = current->thread.xfsr[0] >> (30 + ((insn >> 10) & 0x6)); + XR = current_thread_info()->xfsr[0] >> (30 + ((insn >> 10) & 0x6)); XR &= 3; IR = 0; switch ((insn >> 14) & 0x7) { @@ -282,7 +282,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) XR = 0; else if (freg < 16) XR = regs->u_regs[freg]; - else if (current->thread.flags & SPARC_FLAG_32BIT) { + else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 *win32; flushw_user (); win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); @@ -305,7 +305,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) } if (IR == 0) { /* The fmov test was false. Do a nop instead */ - current->thread.xfsr[0] &= ~(FSR_CEXC_MASK); + current_thread_info()->xfsr[0] &= ~(FSR_CEXC_MASK); regs->tpc = regs->tnpc; regs->tnpc += 4; return 1; @@ -319,20 +319,20 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) if (type) { argp rs1 = NULL, rs2 = NULL, rd = NULL; - freg = (current->thread.xfsr[0] >> 14) & 0xf; + freg = (current_thread_info()->xfsr[0] >> 14) & 0xf; if (freg != (type >> 9)) goto err; - current->thread.xfsr[0] &= ~0x1c000; + current_thread_info()->xfsr[0] &= ~0x1c000; freg = ((insn >> 14) & 0x1f); switch (type & 0x3) { case 3: if (freg & 2) { - current->thread.xfsr[0] |= (6 << 14) /* invalid_fp_register */; + current_thread_info()->xfsr[0] |= (6 << 14) /* invalid_fp_register */; goto err; } case 2: freg = ((freg & 1) << 5) | (freg & 0x1e); case 1: rs1 = (argp)&f->regs[freg]; flags = (freg < 32) ? FPRS_DL : FPRS_DU; - if (!(current->thread.fpsaved[0] & flags)) + if (!(current_thread_info()->fpsaved[0] & flags)) rs1 = (argp)&zero; break; } @@ -344,13 +344,13 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) freg = (insn & 0x1f); switch ((type >> 3) & 0x3) { case 3: if (freg & 2) { - current->thread.xfsr[0] |= (6 << 14) /* invalid_fp_register */; + current_thread_info()->xfsr[0] |= (6 << 14) /* invalid_fp_register */; goto err; } case 2: freg = ((freg & 1) << 5) | (freg & 0x1e); case 1: rs2 = (argp)&f->regs[freg]; flags = (freg < 32) ? FPRS_DL : FPRS_DU; - if (!(current->thread.fpsaved[0] & flags)) + if (!(current_thread_info()->fpsaved[0] & flags)) rs2 = (argp)&zero; break; } @@ -362,23 +362,23 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) freg = ((insn >> 25) & 0x1f); switch ((type >> 6) & 0x3) { case 3: if (freg & 2) { - current->thread.xfsr[0] |= (6 << 14) /* invalid_fp_register */; + current_thread_info()->xfsr[0] |= (6 << 14) /* invalid_fp_register */; goto err; } case 2: freg = ((freg & 1) << 5) | (freg & 0x1e); case 1: rd = (argp)&f->regs[freg]; flags = (freg < 32) ? FPRS_DL : FPRS_DU; - if (!(current->thread.fpsaved[0] & FPRS_FEF)) { - current->thread.fpsaved[0] = FPRS_FEF; - current->thread.gsr[0] = 0; + if (!(current_thread_info()->fpsaved[0] & FPRS_FEF)) { + current_thread_info()->fpsaved[0] = FPRS_FEF; + current_thread_info()->gsr[0] = 0; } - if (!(current->thread.fpsaved[0] & flags)) { + if (!(current_thread_info()->fpsaved[0] & flags)) { if (freg < 32) memset(f->regs, 0, 32*sizeof(u32)); else memset(f->regs+32, 0, 32*sizeof(u32)); } - current->thread.fpsaved[0] |= flags; + current_thread_info()->fpsaved[0] |= flags; break; } switch ((insn >> 5) & 0x1ff) { @@ -439,7 +439,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) } if (!FP_INHIBIT_RESULTS) { switch ((type >> 6) & 0x7) { - case 0: xfsr = current->thread.xfsr[0]; + case 0: xfsr = current_thread_info()->xfsr[0]; if (XR == -1) XR = 2; switch (freg & 3) { /* fcc0, 1, 2, 3 */ @@ -448,7 +448,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) case 2: xfsr &= ~0xc00000000UL; xfsr |= (XR << 34); break; case 3: xfsr &= ~0x3000000000UL; xfsr |= (XR << 36); break; } - current->thread.xfsr[0] = xfsr; + current_thread_info()->xfsr[0] = xfsr; break; case 1: rd->s = IR; break; case 2: rd->d = XR; break; @@ -458,11 +458,11 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f) } } - if(_fex != 0) + if (_fex != 0) return record_exception(regs, _fex); /* Success and no exceptions detected. */ - current->thread.xfsr[0] &= ~(FSR_CEXC_MASK); + current_thread_info()->xfsr[0] &= ~(FSR_CEXC_MASK); regs->tpc = regs->tnpc; regs->tnpc += 4; return 1; diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index ad8fb1baa..105249847 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.58 2001-09-01 00:11:16 kanoj Exp $ +/* $Id: fault.c,v 1.59 2002-02-09 19:49:31 davem Exp $ * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -287,8 +287,8 @@ asmlinkage void do_sparc64_fault(struct pt_regs *regs) unsigned long address; si_code = SEGV_MAPERR; - fault_code = current->thread.fault_code; - address = current->thread.fault_address; + fault_code = get_thread_fault_code(); + address = current_thread_info()->fault_address; if ((fault_code & FAULT_CODE_ITLB) && (fault_code & FAULT_CODE_DTLB)) @@ -301,7 +301,7 @@ asmlinkage void do_sparc64_fault(struct pt_regs *regs) if (in_interrupt() || !mm) goto intr_or_no_mm; - if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { + if (test_thread_flag(TIF_32BIT)) { regs->tpc &= 0xffffffff; address &= 0xffffffff; } @@ -358,7 +358,7 @@ good_area: if (tlb_type == spitfire && (vma->vm_flags & VM_EXEC) != 0 && vma->vm_file != NULL) - current->thread.use_blkcommit = 1; + set_thread_flag(TIF_BLKCOMMIT); } else { /* Allow reads even for write-only mappings */ if (!(vma->vm_flags & (VM_READ | VM_EXEC))) @@ -426,7 +426,7 @@ do_sigbus: fault_done: /* These values are no longer needed, clear them. */ - current->thread.fault_code = 0; - current->thread.use_blkcommit = 0; - current->thread.fault_address = 0; + set_thread_fault_code(0); + clear_thread_flag(TIF_BLKCOMMIT); + current_thread_info()->fault_address = 0; } diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index beef48f3f..fe80462c3 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.208 2001-12-21 04:56:15 davem Exp $ +/* $Id: init.c,v 1.209 2002-02-09 19:49:31 davem Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) @@ -111,8 +111,6 @@ int do_check_pgt_cache(int low, int high) return freed; } -extern void __update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t); - #ifdef CONFIG_DEBUG_DCFLUSH atomic_t dcpage_flushes = ATOMIC_INIT(0); #ifdef CONFIG_SMP @@ -181,6 +179,8 @@ static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long c : "g5", "g7"); } +extern void __update_mmu_cache(unsigned long mmu_context_hw, unsigned long address, pte_t pte, int code); + void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) { struct page *page = pte_page(pte); @@ -201,7 +201,9 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p clear_dcache_dirty_cpu(page, cpu); } - __update_mmu_cache(vma, address, pte); + if (get_thread_fault_code()) + __update_mmu_cache(vma->vm_mm->context & TAG_CONTEXT_BITS, + address, pte, get_thread_fault_code()); } void flush_dcache_page(struct page *page) @@ -706,7 +708,7 @@ void prom_world(int enter) int i; if (!enter) - set_fs(current->thread.current_ds); + set_fs((mm_segment_t) { get_thread_current_ds() }); if (!prom_ditlb_set) return; diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index 6c9a963c7..948a3b4fb 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -1,4 +1,4 @@ -/* $Id: ultra.S,v 1.71 2002-01-23 11:27:36 davem Exp $ +/* $Id: ultra.S,v 1.72 2002-02-09 19:49:31 davem Exp $ * ultra.S: Don't expand these all over the place... * * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com) @@ -391,8 +391,8 @@ __prefill_dtlb: rdpr %pstate, %g7 wrpr %g7, PSTATE_IE, %pstate mov TLB_TAG_ACCESS, %g1 - stxa %o0, [%g1] ASI_DMMU - stxa %o1, [%g0] ASI_DTLB_DATA_IN + stxa %o5, [%g1] ASI_DMMU + stxa %o2, [%g0] ASI_DTLB_DATA_IN flush %g6 retl wrpr %g7, %pstate @@ -400,28 +400,20 @@ __prefill_itlb: rdpr %pstate, %g7 wrpr %g7, PSTATE_IE, %pstate mov TLB_TAG_ACCESS, %g1 - stxa %o0, [%g1] ASI_IMMU - stxa %o1, [%g0] ASI_ITLB_DATA_IN + stxa %o5, [%g1] ASI_IMMU + stxa %o2, [%g0] ASI_ITLB_DATA_IN flush %g6 retl wrpr %g7, %pstate .globl __update_mmu_cache -__update_mmu_cache: /* %o0=vma, %o1=address, %o2=pte */ - ldub [%g6 + AOFF_task_thread + AOFF_thread_fault_code], %o3 +__update_mmu_cache: /* %o0=hw_context, %o1=address, %o2=pte, %o3=fault_code */ srlx %o1, PAGE_SHIFT, %o1 - ldx [%o0 + 0x0], %o4 /* XXX vma->vm_mm */ - brz,pn %o3, 1f - sllx %o1, PAGE_SHIFT, %o0 - ldx [%o4 + AOFF_mm_context], %o5 andcc %o3, FAULT_CODE_DTLB, %g0 - mov %o2, %o1 - and %o5, TAG_CONTEXT_BITS, %o5 + sllx %o1, PAGE_SHIFT, %o5 bne,pt %xcc, __prefill_dtlb - or %o0, %o5, %o0 + or %o5, %o0, %o5 ba,a,pt %xcc, __prefill_itlb -1: retl - nop #ifdef CONFIG_SMP /* These are all called by the slaves of a cross call, at diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S index 3fcf07263..8b880f674 100644 --- a/arch/sparc64/solaris/entry64.S +++ b/arch/sparc64/solaris/entry64.S @@ -1,4 +1,4 @@ -/* $Id: entry64.S,v 1.6 2000-01-12 02:59:26 davem Exp $ +/* $Id: entry64.S,v 1.7 2002-02-09 19:49:31 davem Exp $ * entry64.S: Solaris syscall emulation entry point. * * Copyright (C) 1996,1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -68,9 +68,11 @@ linux_syscall_for_solaris: /* Solaris system calls enter here... */ .align 32 - .globl solaris_sparc_syscall + .globl solaris_sparc_syscall, entry64_personality_patch solaris_sparc_syscall: - ldub [%g6 + AOFF_task_personality + ASIZ_task_personality - 1], %l0 + ldx [%g6 + TI_TASK], %l0 +entry64_personality_patch: + ldub [%l0 + 0x0], %l0 cmp %g1, 255 bg,pn %icc, solaris_unimplemented srl %g1, 0, %g1 @@ -83,7 +85,7 @@ solaris_sparc_syscall: 1: srl %i0, 0, %o0 lduw [%l7 + %l4], %l3 srl %i1, 0, %o1 - ldx [%g6 + AOFF_task_flags], %l5 + ldx [%g6 + TI_FLAGS], %l5 cmp %l3, NR_SYSCALLS bleu,a,pn %xcc, linux_syscall_for_solaris sethi %hi(sys_call_table32), %l6 @@ -93,21 +95,21 @@ solaris_sparc_syscall: 10: srl %i2, 0, %o2 mov %i5, %o5 andn %l3, 3, %l7 - andcc %l5, 0x20, %g0 + andcc %l5, _TIF_SYSCALL_TRACE, %g0 bne,pn %icc, solaris_syscall_trace mov %i0, %l5 2: call %l7 srl %i3, 0, %o3 ret_from_solaris: stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] - ldx [%g6 + AOFF_task_flags], %l6 + ldx [%g6 + TI_FLAGS], %l6 sra %o0, 0, %o0 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE], %g3 cmp %o0, -ENOIOCTLCMD sllx %g2, 32, %g2 bgeu,pn %xcc, 1f - andcc %l6, 0x20, %l6 + andcc %l6, _TIF_SYSCALL_TRACE, %l6 /* System call success, clear Carry condition code. */ andn %g3, %g2, %g3 @@ -175,25 +177,30 @@ solaris_sigsuspend: .globl solaris_getpid solaris_getpid: - call sys_getppid /* This is tricky, so don't do it in assembly */ + call sys_getppid nop - stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] + call sys_getpid + stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] b,pt %xcc, ret_from_solaris - lduw [%g6 + AOFF_task_pid], %o0 + nop .globl solaris_getuid solaris_getuid: - lduw [%g6 + AOFF_task_euid], %o1 - lduw [%g6 + AOFF_task_uid], %o0 - b,pt %xcc, ret_from_solaris + call sys_geteuid + nop + call sys_getuid stx %o1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] + b,pt %xcc, ret_from_solaris + nop .globl solaris_getgid solaris_getgid: - lduw [%g6 + AOFF_task_egid], %o1 - lduw [%g6 + AOFF_task_gid], %o0 - b,pt %xcc, ret_from_solaris + call sys_getegid + nop + call sys_getgid stx %o1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] + b,pt %xcc, ret_from_solaris + nop .globl solaris_unimplemented solaris_unimplemented: diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c index 427de755f..49da3c7f9 100644 --- a/arch/sparc64/solaris/misc.c +++ b/arch/sparc64/solaris/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.35 2002-01-08 16:00:21 davem Exp $ +/* $Id: misc.c,v 1.36 2002-02-09 19:49:31 davem Exp $ * misc.c: Miscelaneous syscall emulation for Solaris * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -739,6 +739,8 @@ extern u32 solaris_sparc_syscall[]; extern u32 solaris_syscall[]; extern void cleanup_socksys(void); +extern u32 entry64_personality_patch; + int init_module(void) { int ret; @@ -750,6 +752,11 @@ int init_module(void) return ret; } update_ttable(solaris_sparc_syscall); + entry64_personality_patch |= + (offsetof(struct task_struct, personality) + + (sizeof(unsigned long) - 1)); + __asm__ __volatile__("membar #StoreStore; flush %0" + : : "r" (&entry64_personality_patch)); return 0; } diff --git a/drivers/block/blkpg.c b/drivers/block/blkpg.c index 9d1fdf03a..2e1d2a6e7 100644 --- a/drivers/block/blkpg.c +++ b/drivers/block/blkpg.c @@ -280,7 +280,8 @@ int blk_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg) if (cmd == BLKGETSIZE) return put_user((unsigned long)ullval, (unsigned long *)arg); - return put_user(ullval, (u64 *)arg); + else + return put_user((u64)ullval << 9 , (u64 *)arg); #if 0 case BLKRRPART: /* Re-read partition tables */ if (!capable(CAP_SYS_ADMIN)) diff --git a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c index 27e20390d..108821563 100644 --- a/drivers/hotplug/pci_hotplug_core.c +++ b/drivers/hotplug/pci_hotplug_core.c @@ -414,7 +414,7 @@ static int get_mount (void) } spin_unlock (&mount_lock); - mnt = kern_mount (&pcihpfs_fs_type); + mnt = kern_mount (&pcihpfs_type); if (IS_ERR(mnt)) { err ("could not mount the fs...erroring out!\n"); return -ENODEV; @@ -1114,7 +1114,7 @@ static int __init pci_hotplug_init (void) spin_lock_init(&list_lock); dbg("registering filesystem.\n"); - result = register_filesystem(&pcihpfs_fs_type); + result = register_filesystem(&pcihpfs_type); if (result) { err("register_filesystem failed with %d\n", result); goto exit; @@ -1128,7 +1128,7 @@ exit: static void __exit pci_hotplug_exit (void) { - unregister_filesystem(&pcihpfs_fs_type); + unregister_filesystem(&pcihpfs_type); } module_init(pci_hotplug_init); diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index baf50487d..27e3aebb2 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -192,11 +192,6 @@ static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsi sectors = rq->nr_sectors; if (sectors == 256) sectors = 0; - if (command == WIN_MULTWRITE_EXT || command == WIN_MULTWRITE) { - sectors = drive->mult_count; - if (sectors > rq->current_nr_sectors) - sectors = rq->current_nr_sectors; - } taskfile.sector_count = sectors; taskfile.sector_number = sect; @@ -241,11 +236,6 @@ static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, u sectors = rq->nr_sectors; if (sectors == 256) sectors = 0; - if (command == WIN_MULTWRITE_EXT || command == WIN_MULTWRITE) { - sectors = drive->mult_count; - if (sectors > rq->current_nr_sectors) - sectors = rq->current_nr_sectors; - } memset(&taskfile, 0, sizeof(task_struct_t)); memset(&hobfile, 0, sizeof(hob_struct_t)); @@ -300,13 +290,8 @@ static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, u memset(&hobfile, 0, sizeof(hob_struct_t)); sectors = rq->nr_sectors; - if (sectors == 256) + if (sectors == 65536) sectors = 0; - if (command == WIN_MULTWRITE_EXT || command == WIN_MULTWRITE) { - sectors = drive->mult_count; - if (sectors > rq->current_nr_sectors) - sectors = rq->current_nr_sectors; - } taskfile.sector_count = sectors; hobfile.sector_count = sectors >> 8; diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index daae0cfdd..f7714babb 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -255,6 +255,7 @@ int drive_is_ready (ide_drive_t *drive) return 1; /* drive ready: *might* be interrupting */ } +ide_startstop_t bio_mulout_intr (ide_drive_t *drive); ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) { task_struct_t *taskfile = (task_struct_t *) task->tfRegister; @@ -263,7 +264,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) byte HIHI = (drive->addressing) ? 0xE0 : 0xEF; /* (ks/hs): Moved to start, do not use for multiple out commands */ - if (task->handler != task_mulout_intr) { + if (task->handler != task_mulout_intr && task->handler != bio_mulout_intr) { if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ SELECT_MASK(HWIF(drive), drive, 0); @@ -313,7 +314,7 @@ void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct byte HIHI = (drive->addressing) ? 0xE0 : 0xEF; /* (ks/hs): Moved to start, do not use for multiple out commands */ - if (*handler != task_mulout_intr) { + if (*handler != task_mulout_intr && handler != bio_mulout_intr) { if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ SELECT_MASK(HWIF(drive), drive, 0); @@ -936,15 +937,12 @@ ide_startstop_t task_out_intr (ide_drive_t *drive) char *pBuf = NULL; unsigned long flags; - if (!rq->current_nr_sectors) { - printk("task_out_intr: should not trigger\n"); - ide_end_request(1, HWGROUP(drive)); - return ide_stopped; - } - - if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) { + if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) return ide_error(drive, "task_out_intr", stat); - } + + if (!rq->current_nr_sectors) + if (!ide_end_request(1, HWGROUP(drive))) + return ide_stopped; if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) { rq = HWGROUP(drive)->rq; @@ -958,16 +956,8 @@ ide_startstop_t task_out_intr (ide_drive_t *drive) rq->current_nr_sectors--; } - if (rq->current_nr_sectors <= 0) { - if (ide_end_request(1, HWGROUP(drive))) { - ide_set_handler(drive, &task_out_intr, WAIT_CMD, NULL); - return ide_started; - } - } else { - ide_set_handler(drive, &task_out_intr, WAIT_CMD, NULL); - return ide_started; - } - return ide_stopped; + ide_set_handler(drive, task_out_intr, WAIT_CMD, NULL); + return ide_started; } /* @@ -1061,14 +1051,132 @@ ide_startstop_t task_mulout_intr (ide_drive_t *drive) return ide_started; } +ide_startstop_t pre_bio_out_intr (ide_drive_t *drive, struct request *rq) +{ + ide_task_t *args = rq->special; + ide_startstop_t startstop; + + /* + * assign private copy for multi-write + */ + memcpy(&HWGROUP(drive)->wrq, rq, sizeof(struct request)); + + if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) + return startstop; + + /* + * (ks/hs): Stuff the first sector(s) + * by implicitly calling the handler + */ + if (!(drive_is_ready(drive))) { + int i; + /* + * (ks/hs): FIXME: Replace hard-coded + * 100, error handling? + */ + for (i=0; i<100; i++) { + if (drive_is_ready(drive)) + break; + } + } + + return args->handler(drive); +} + + +ide_startstop_t bio_mulout_intr (ide_drive_t *drive) +{ +#ifdef ALTSTAT_SCREW_UP + byte stat = altstat_multi_busy(drive, GET_ALTSTAT(), "write"); +#else + byte stat = GET_STAT(); +#endif /* ALTSTAT_SCREW_UP */ + + byte io_32bit = drive->io_32bit; + struct request *rq = &HWGROUP(drive)->wrq; + ide_hwgroup_t *hwgroup = HWGROUP(drive); + int mcount = drive->mult_count; + ide_startstop_t startstop; + + /* + * (ks/hs): Handle last IRQ on multi-sector transfer, + * occurs after all data was sent in this chunk + */ + if (!rq->nr_sectors) { + if (stat & (ERR_STAT|DRQ_STAT)) { + startstop = ide_error(drive, "bio_mulout_intr", stat); + memcpy(rq, HWGROUP(drive)->rq, sizeof(struct request)); + return startstop; + } + + __ide_end_request(HWGROUP(drive), 1, rq->hard_nr_sectors); + HWGROUP(drive)->wrq.bio = NULL; + return ide_stopped; + } + + if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { + if (stat & (ERR_STAT | DRQ_STAT)) { + startstop = ide_error(drive, "bio_mulout_intr", stat); + memcpy(rq, HWGROUP(drive)->rq, sizeof(struct request)); + return startstop; + } + + /* no data yet, so wait for another interrupt */ + if (hwgroup->handler == NULL) + ide_set_handler(drive, bio_mulout_intr, WAIT_CMD, NULL); + + return ide_started; + } + + do { + char *buffer; + int nsect = rq->current_nr_sectors; + unsigned long flags; + + if (nsect > mcount) + nsect = mcount; + mcount -= nsect; + + buffer = ide_map_buffer(rq, &flags); + rq->sector += nsect; + rq->nr_sectors -= nsect; + rq->current_nr_sectors -= nsect; + + /* Do we move to the next bio after this? */ + if (!rq->current_nr_sectors) { + /* remember to fix this up /jens */ + struct bio *bio = rq->bio->bi_next; + + /* end early early we ran out of requests */ + if (!bio) { + mcount = 0; + } else { + rq->bio = bio; + rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9; + } + } + + /* + * Ok, we're all setup for the interrupt + * re-entering us on the last transfer. + */ + taskfile_output_data(drive, buffer, nsect * SECTOR_WORDS); + ide_unmap_buffer(buffer, &flags); + } while (mcount); + + drive->io_32bit = io_32bit; + rq->errors = 0; + if (hwgroup->handler == NULL) + ide_set_handler(drive, bio_mulout_intr, WAIT_CMD, NULL); + + return ide_started; +} + /* Called by internal to feature out type of command being called */ ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile) { switch(taskfile->command) { /* IDE_DRIVE_TASK_RAW_WRITE */ - case CFA_WRITE_MULTI_WO_ERASE: - case WIN_MULTWRITE: - case WIN_MULTWRITE_EXT: /* IDE_DRIVE_TASK_OUT */ case WIN_WRITE: case WIN_WRITE_EXT: @@ -1077,7 +1185,10 @@ ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, case CFA_WRITE_SECT_WO_ERASE: case WIN_DOWNLOAD_MICROCODE: return &pre_task_out_intr; - /* IDE_DRIVE_TASK_OUT */ + case CFA_WRITE_MULTI_WO_ERASE: + case WIN_MULTWRITE: + case WIN_MULTWRITE_EXT: + return &pre_bio_out_intr; case WIN_SMART: if (taskfile->feature == SMART_WRITE_LOG_SECTOR) return &pre_task_out_intr; @@ -1120,7 +1231,7 @@ ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct h case CFA_WRITE_MULTI_WO_ERASE: case WIN_MULTWRITE: case WIN_MULTWRITE_EXT: - return &task_mulout_intr; + return &bio_mulout_intr; case WIN_SMART: switch(taskfile->feature) { case SMART_READ_VALUES: diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 4fa77c99c..413002ffa 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -1,11 +1,9 @@ /* - * $Id: evdev.c,v 1.27 2001/05/28 09:06:44 vojtech Exp $ + * $Id: evdev.c,v 1.42 2002/01/02 11:59:56 vojtech Exp $ * * Copyright (c) 1999-2001 Vojtech Pavlik * * Event char devices, giving access to raw input device events. - * - * Sponsored by SuSE */ /* @@ -24,8 +22,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by - * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic + * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ #define EVDEV_MINOR_BASE 64 @@ -42,7 +40,9 @@ struct evdev { int exist; int open; + int open_for_write; int minor; + char name[16]; struct input_handle handle; wait_queue_head_t wait; devfs_handle_t devfs; @@ -89,6 +89,11 @@ static int evdev_fasync(int fd, struct file *file, int on) return retval < 0 ? retval : 0; } +static int evdev_flush(struct file * file) +{ + return input_flush_device(&((struct evdev_list*)file->private_data)->evdev->handle, file); +} + static int evdev_release(struct inode * inode, struct file * file) { struct evdev_list *list = file->private_data; @@ -120,10 +125,16 @@ static int evdev_open(struct inode * inode, struct file * file) { struct evdev_list *list; int i = minor(inode->i_rdev) - EVDEV_MINOR_BASE; + int accept_err; if (i >= EVDEV_MINORS || !evdev_table[i]) return -ENODEV; + /* Ask the driver if he wishes to accept the open() */ + if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file))) { + return accept_err; + } + if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL))) return -ENOMEM; memset(list, 0, sizeof(struct evdev_list)); @@ -167,7 +178,7 @@ static ssize_t evdev_read(struct file * file, char * buffer, size_t count, loff_ if (list->head == list->tail) { add_wait_queue(&list->evdev->wait, &wait); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); while (list->head == list->tail) { @@ -187,7 +198,7 @@ static ssize_t evdev_read(struct file * file, char * buffer, size_t count, loff_ schedule(); } - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); remove_wait_queue(&list->evdev->wait, &wait); } @@ -219,7 +230,7 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, struct evdev_list *list = file->private_data; struct evdev *evdev = list->evdev; struct input_dev *dev = evdev->handle.dev; - int retval; + int retval, t, u; switch (cmd) { @@ -232,6 +243,40 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, if ((retval = put_user(dev->idproduct, ((short *) arg) + 2))) return retval; if ((retval = put_user(dev->idversion, ((short *) arg) + 3))) return retval; return 0; + + case EVIOCGREP: + if ((retval = put_user(dev->rep[0], ((int *) arg) + 0))) return retval; + if ((retval = put_user(dev->rep[1], ((int *) arg) + 1))) return retval; + return 0; + + case EVIOCSREP: + if ((retval = get_user(dev->rep[0], ((int *) arg) + 0))) return retval; + if ((retval = get_user(dev->rep[1], ((int *) arg) + 1))) return retval; + return 0; + + case EVIOCGKEYCODE: + if ((retval = get_user(t, ((int *) arg) + 0))) return retval; + if (t < 0 || t > dev->keycodemax) return -EINVAL; + switch (dev->keycodesize) { + case 1: u = *(u8*)(dev->keycode + t); break; + case 2: u = *(u16*)(dev->keycode + t * 2); break; + case 4: u = *(u32*)(dev->keycode + t * 4); break; + default: return -EINVAL; + } + if ((retval = put_user(u, ((int *) arg) + 1))) return retval; + return 0; + + case EVIOCSKEYCODE: + if ((retval = get_user(t, ((int *) arg) + 0))) return retval; + if (t < 0 || t > dev->keycodemax) return -EINVAL; + if ((retval = get_user(u, ((int *) arg) + 1))) return retval; + switch (dev->keycodesize) { + case 1: *(u8*)(dev->keycode + t) = u; break; + case 2: *(u16*)(dev->keycode + t * 2) = u; break; + case 4: *(u32*)(dev->keycode + t * 4) = u; break; + default: return -EINVAL; + } + return 0; case EVIOCSFF: if (dev->upload_effect) { @@ -280,22 +325,55 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, default: return -EINVAL; } len = NBITS(len) * sizeof(long); - if (len > _IOC_SIZE(cmd)) { - printk(KERN_WARNING "evdev.c: Truncating bitfield length from %d to %d\n", - len, _IOC_SIZE(cmd)); - len = _IOC_SIZE(cmd); - } + if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); return copy_to_user((char *) arg, bits, len) ? -EFAULT : len; } + if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) { + int len; + len = NBITS(KEY_MAX) * sizeof(long); + if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); + return copy_to_user((char *) arg, dev->key, len) ? -EFAULT : len; + } + + if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) { + int len; + len = NBITS(LED_MAX) * sizeof(long); + if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); + return copy_to_user((char *) arg, dev->led, len) ? -EFAULT : len; + } + + if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) { + int len; + len = NBITS(SND_MAX) * sizeof(long); + if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); + return copy_to_user((char *) arg, dev->snd, len) ? -EFAULT : len; + } + if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) { int len; - if (!dev->name) return 0; + if (!dev->name) return -ENOENT; len = strlen(dev->name) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); return copy_to_user((char *) arg, dev->name, len) ? -EFAULT : len; } + if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) { + int len; + if (!dev->phys) return -ENOENT; + len = strlen(dev->phys) + 1; + if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); + return copy_to_user((char *) arg, dev->phys, len) ? -EFAULT : len; + } + + if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) { + int len; + if (!dev->uniq) return -ENOENT; + len = strlen(dev->uniq) + 1; + if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); + return copy_to_user((char *) arg, dev->uniq, len) ? -EFAULT : len; + } + if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { int t = _IOC_NR(cmd) & ABS_MAX; @@ -321,9 +399,10 @@ static struct file_operations evdev_fops = { release: evdev_release, ioctl: evdev_ioctl, fasync: evdev_fasync, + flush: evdev_flush }; -static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev) +static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id) { struct evdev *evdev; int minor; @@ -342,16 +421,17 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct evdev->minor = minor; evdev_table[minor] = evdev; + + sprintf(evdev->name, "event%d", minor); evdev->handle.dev = dev; + evdev->handle.name = evdev->name; evdev->handle.handler = handler; evdev->handle.private = evdev; - evdev->exist = 1; - evdev->devfs = input_register_minor("event%d", minor, EVDEV_MINOR_BASE); -// printk(KERN_INFO "event%d: Event device for input%d\n", minor, dev->number); + evdev->exist = 1; return &evdev->handle; } @@ -372,12 +452,21 @@ static void evdev_disconnect(struct input_handle *handle) } } +static struct input_device_id evdev_ids[] = { + { driver_info: 1 }, /* Matches all devices */ + { }, /* Terminating zero entry */ +}; + +MODULE_DEVICE_TABLE(input, evdev_ids); + static struct input_handler evdev_handler = { event: evdev_event, connect: evdev_connect, disconnect: evdev_disconnect, fops: &evdev_fops, minor: EVDEV_MINOR_BASE, + name: "evdev", + id_table: evdev_ids, }; static int __init evdev_init(void) @@ -394,7 +483,6 @@ static void __exit evdev_exit(void) module_init(evdev_init); module_exit(evdev_exit); -MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); -MODULE_DESCRIPTION("Event character device driver"); +MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); +MODULE_DESCRIPTION("Input driver event char devices"); MODULE_LICENSE("GPL"); - diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index f17165bdd..e5b845e29 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -1,12 +1,10 @@ /* - * $Id: joydev.c,v 1.19 2001/01/10 19:49:40 vojtech Exp $ + * $Id: joydev.c,v 1.38 2001/12/27 10:37:41 vojtech Exp $ * - * Copyright (c) 1999-2000 Vojtech Pavlik + * Copyright (c) 1999-2001 Vojtech Pavlik * Copyright (c) 1999 Colin Van Dyke * * Joystick device driver for the input driver suite. - * - * Sponsored by SuSE and Intel */ /* @@ -25,8 +23,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by - * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic + * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ #include <asm/io.h> @@ -45,14 +43,22 @@ #include <linux/init.h> #include <linux/smp_lock.h> +MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); +MODULE_DESCRIPTION("Joystick device interfaces"); +MODULE_SUPPORTED_DEVICE("input/js"); +MODULE_LICENSE("GPL"); + #define JOYDEV_MINOR_BASE 0 #define JOYDEV_MINORS 32 #define JOYDEV_BUFFER_SIZE 64 +#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ) + struct joydev { int exist; int open; int minor; + char name[16]; struct input_handle handle; wait_queue_head_t wait; devfs_handle_t devfs; @@ -81,11 +87,6 @@ struct joydev_list { static struct joydev *joydev_table[JOYDEV_MINORS]; -MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); -MODULE_DESCRIPTION("Joystick device driver"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("input/js"); - static int joydev_correct(int value, struct js_corr *corr) { switch (corr->type) { @@ -133,7 +134,7 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne return; } - event.time = jiffies * (1000 / HZ); + event.time = MSECS(jiffies); while (list) { @@ -163,7 +164,7 @@ static int joydev_release(struct inode * inode, struct file * file) { struct joydev_list *list = file->private_data; struct joydev_list **listptr; - + listptr = &list->joydev->list; joydev_fasync(-1, file, 0); @@ -249,7 +250,7 @@ static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *p if (list->head == list->tail && list->startup == joydev->nabs + joydev->nkey) { add_wait_queue(&list->joydev->wait, &wait); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); while (list->head == list->tail) { @@ -265,7 +266,7 @@ static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *p schedule(); } - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); remove_wait_queue(&list->joydev->wait, &wait); } @@ -276,7 +277,7 @@ static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *p struct js_event event; - event.time = jiffies * (1000/HZ); + event.time = MSECS(jiffies); if (list->startup < joydev->nkey) { event.type = JS_EVENT_BUTTON | JS_EVENT_INIT; @@ -360,9 +361,9 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd return copy_to_user((struct js_corr *) arg, joydev->corr, sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0; case JSIOCSAXMAP: - if (copy_from_user((__u8 *) arg, joydev->abspam, sizeof(__u8) * ABS_MAX)) + if (copy_from_user(joydev->abspam, (__u8 *) arg, sizeof(__u8) * ABS_MAX)) return -EFAULT; - for (i = 0; i < ABS_MAX; i++) { + for (i = 0; i < joydev->nabs; i++) { if (joydev->abspam[i] > ABS_MAX) return -EINVAL; joydev->absmap[joydev->abspam[i]] = i; } @@ -371,11 +372,11 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd return copy_to_user((__u8 *) arg, joydev->abspam, sizeof(__u8) * ABS_MAX) ? -EFAULT : 0; case JSIOCSBTNMAP: - if (copy_from_user((__u16 *) arg, joydev->absmap, sizeof(__u16) * (KEY_MAX - BTN_MISC))) + if (copy_from_user(joydev->keypam, (__u16 *) arg, sizeof(__u16) * (KEY_MAX - BTN_MISC))) return -EFAULT; - for (i = 0; i < KEY_MAX - BTN_MISC; i++); { + for (i = 0; i < joydev->nkey; i++); { if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL; - joydev->keymap[joydev->abspam[i - BTN_MISC]] = i; + joydev->keymap[joydev->keypam[i] - BTN_MISC] = i; } return 0; case JSIOCGBTNMAP: @@ -405,15 +406,13 @@ static struct file_operations joydev_fops = { fasync: joydev_fasync, }; -static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev) +static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id) { struct joydev *joydev; - int i, j, minor; + int i, j, t, minor; - if (!(test_bit(EV_KEY, dev->evbit) && test_bit(EV_ABS, dev->evbit) && - (test_bit(ABS_X, dev->absbit) || test_bit(ABS_Y, dev->absbit)) && - (test_bit(BTN_TRIGGER, dev->keybit) || test_bit(BTN_A, dev->keybit) - || test_bit(BTN_1, dev->keybit)))) return NULL; + if (test_bit(BTN_TOUCH, dev->keybit)) + return NULL; for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); if (minor == JOYDEV_MINORS) { @@ -430,12 +429,13 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct joydev->minor = minor; joydev_table[minor] = joydev; + sprintf(joydev->name, "js%d", minor); + joydev->handle.dev = dev; + joydev->handle.name = joydev->name; joydev->handle.handler = handler; joydev->handle.private = joydev; - joydev->exist = 1; - for (i = 0; i < ABS_MAX; i++) if (test_bit(i, dev->absbit)) { joydev->absmap[i] = joydev->nabs; @@ -467,15 +467,17 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct joydev->corr[i].prec = dev->absfuzz[j]; joydev->corr[i].coef[0] = (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j]; joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j]; - joydev->corr[i].coef[2] = (1 << 29) / ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]); - joydev->corr[i].coef[3] = (1 << 29) / ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]); + if (!(t = ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]))) + continue; + joydev->corr[i].coef[2] = (1 << 29) / t; + joydev->corr[i].coef[3] = (1 << 29) / t; joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i); } joydev->devfs = input_register_minor("js%d", minor, JOYDEV_MINOR_BASE); -// printk(KERN_INFO "js%d: Joystick device for input%d\n", minor, dev->number); + joydev->exist = 1; return &joydev->handle; } @@ -495,12 +497,35 @@ static void joydev_disconnect(struct input_handle *handle) } } +static struct input_device_id joydev_ids[] = { + { + flags: INPUT_DEVICE_ID_MATCH_EVBIT, + evbit: { BIT(EV_KEY) | BIT(EV_ABS) }, + absbit: { BIT(ABS_X) }, + }, + { + flags: INPUT_DEVICE_ID_MATCH_EVBIT, + evbit: { BIT(EV_KEY) | BIT(EV_ABS) }, + absbit: { BIT(ABS_WHEEL) }, + }, + { + flags: INPUT_DEVICE_ID_MATCH_EVBIT, + evbit: { BIT(EV_KEY) | BIT(EV_ABS) }, + absbit: { BIT(ABS_THROTTLE) }, + }, + { }, /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(input, joydev_ids); + static struct input_handler joydev_handler = { event: joydev_event, connect: joydev_connect, disconnect: joydev_disconnect, fops: &joydev_fops, minor: JOYDEV_MINOR_BASE, + name: "joydev", + id_table: joydev_ids, }; static int __init joydev_init(void) diff --git a/drivers/input/joystick/iforce.c b/drivers/input/joystick/iforce.c index f77ec220b..3dd126a42 100644 --- a/drivers/input/joystick/iforce.c +++ b/drivers/input/joystick/iforce.c @@ -641,7 +641,7 @@ static int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effec effect->replay.delay, effect->trigger.button, effect->trigger.interval, - effect->u.periodic.direction); + effect->direction); return err; } @@ -680,7 +680,7 @@ static int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effec effect->replay.delay, effect->trigger.button, effect->trigger.interval, - effect->u.constant.direction); + effect->direction); return err; } @@ -722,7 +722,7 @@ static int iforce_upload_interactive(struct iforce* iforce, struct ff_effect* ef case 0: /* Only one axis, choose orientation */ mod1 = mod_chunk->start; mod2 = 0xffff; - direction = effect->u.interactive.direction; + direction = effect->direction; axes = 0x20; break; diff --git a/drivers/input/keybdev.c b/drivers/input/keybdev.c index a437ac103..6731dd254 100644 --- a/drivers/input/keybdev.c +++ b/drivers/input/keybdev.c @@ -1,11 +1,9 @@ /* - * $Id: keybdev.c,v 1.3 2000/05/28 17:31:36 vojtech Exp $ + * $Id: keybdev.c,v 1.16 2002/01/09 04:21:41 lethal Exp $ * - * Copyright (c) 1999-2000 Vojtech Pavlik + * Copyright (c) 1999-2001 Vojtech Pavlik * - * Input driver to keyboard driver binding. - * - * Sponsored by SuSE + * Input core to console keyboard binding. */ /* @@ -24,8 +22,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by - * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic + * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ #include <linux/config.h> @@ -37,10 +35,16 @@ #include <linux/module.h> #include <linux/kbd_kern.h> +MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); +MODULE_DESCRIPTION("Input core to console keyboard binding"); +MODULE_LICENSE("GPL"); + +char keybdev_name[] = "keyboard"; + #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(__alpha__) || \ defined(__mips__) || defined(CONFIG_SPARC64) || defined(CONFIG_SUPERH) || \ defined(CONFIG_PPC) || defined(__mc68000__) || defined(__hppa__) || \ - defined(__arm__) + defined(__arm__) || defined(__x86_64__) static int x86_sysrq_alt = 0; #ifdef CONFIG_SPARC64 @@ -48,8 +52,6 @@ static int sparc_l1_a_state = 0; extern void batten_down_hatches(void); #endif -static int jp_kbd_109 = 1; /* Yes, .jp is the default. See 51142. */ - static unsigned short x86_keycodes[256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -62,7 +64,7 @@ static unsigned short x86_keycodes[256] = 360, 93, 94, 95, 98,376,100,101,357,316,354,304,289,102,351,355, 103,104,105,275,281,272,306,106,274,107,288,364,358,363,362,361, 291,108,381,290,287,292,279,305,280, 99,112,257,258,113,270,114, - 118,117,125,374,379,259,260,261,262,263,264,265,266,267,268,269, + 118,117,125,374,379,115,112,125,121,123,264,265,266,267,268,269, 271,273,276,277,278,282,283,295,296,297,299,300,301,302,303,307, 308,310,313,314,315,317,318,319,320,321,322,323,324,325,326,330, 332,340,341,342,343,344,345,346,356,359,365,368,369,370,371,372 }; @@ -167,26 +169,38 @@ void keybdev_ledfunc(unsigned int led) } } +/* Tell the user who may be running in X and not see the console that we have + panic'ed. This is to distingush panics from "real" lockups. + Could in theory send the panic message as morse, but that is left as an + exercise for the reader. */ + +void panic_blink(void) +{ + static unsigned long last_jiffie; + static char led; + /* Roughly 1/2s frequency. KDB uses about 1s. Make sure it is different. */ + if (jiffies - last_jiffie > HZ/2) { + led ^= 0x01 | 0x04; + keybdev_ledfunc(led); + last_jiffie = jiffies; + } +} + void keybdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int down) { if (type != EV_KEY) return; - - if (emulate_raw(code, down)) - printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", code); - + emulate_raw(code, down); tasklet_schedule(&keyboard_tasklet); } -static struct input_handle *keybdev_connect(struct input_handler *handler, struct input_dev *dev) +static struct input_handle *keybdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id) { struct input_handle *handle; int i; - if (!test_bit(EV_KEY, dev->evbit)) - return NULL; - - for (i = KEY_RESERVED; i < BTN_MISC; i++) - if (test_bit(i, dev->keybit)) break; + for (i = KEY_ESC; i < BTN_MISC; i++) + if (test_bit(i, dev->keybit)) + break; if (i == BTN_MISC) return NULL; @@ -196,41 +210,42 @@ static struct input_handle *keybdev_connect(struct input_handler *handler, struc memset(handle, 0, sizeof(struct input_handle)); handle->dev = dev; + handle->name = keybdev_name; handle->handler = handler; input_open_device(handle); -// printk(KERN_INFO "keybdev.c: Adding keyboard: input%d\n", dev->number); - return handle; } static void keybdev_disconnect(struct input_handle *handle) { -// printk(KERN_INFO "keybdev.c: Removing keyboard: input%d\n", handle->dev->number); input_close_device(handle); kfree(handle); } + +static struct input_device_id keybdev_ids[] = { + { + flags: INPUT_DEVICE_ID_MATCH_EVBIT, + evbit: { BIT(EV_KEY) }, + }, + { }, /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(input, keybdev_ids); static struct input_handler keybdev_handler = { event: keybdev_event, connect: keybdev_connect, disconnect: keybdev_disconnect, + name: "keybdev", + id_table: keybdev_ids, }; static int __init keybdev_init(void) { input_register_handler(&keybdev_handler); kbd_ledfunc = keybdev_ledfunc; - - if (jp_kbd_109) { - x86_keycodes[0xb5] = 0x73; /* backslash, underscore */ - x86_keycodes[0xb6] = 0x70; - x86_keycodes[0xb7] = 0x7d; /* Yen, pipe */ - x86_keycodes[0xb8] = 0x79; - x86_keycodes[0xb9] = 0x7b; - } - return 0; } @@ -243,7 +258,3 @@ static void __exit keybdev_exit(void) module_init(keybdev_init); module_exit(keybdev_exit); -MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); -MODULE_DESCRIPTION("Input driver to keyboard driver binding"); -MODULE_PARM(jp_kbd_109, "i"); -MODULE_LICENSE("GPL"); diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index c37b6a0dd..01fb98c7f 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -1,11 +1,9 @@ /* - * $Id: mousedev.c,v 1.24 2000/11/15 10:57:45 vojtech Exp $ + * $Id: mousedev.c,v 1.38 2001/12/26 21:08:33 jsimmons Exp $ * - * Copyright (c) 1999-2000 Vojtech Pavlik + * Copyright (c) 1999-2001 Vojtech Pavlik * - * Input driver to ImExPS/2 device driver module. - * - * Sponsored by SuSE + * Input driver to ExplorerPS/2 device driver module. */ /* @@ -24,8 +22,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by - * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic + * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ #define MOUSEDEV_MINOR_BASE 32 @@ -41,6 +39,10 @@ #include <linux/smp_lock.h> #include <linux/random.h> +MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); +MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces"); +MODULE_LICENSE("GPL"); + #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X #define CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024 #endif @@ -52,6 +54,7 @@ struct mousedev { int exist; int open; int minor; + char name[16]; wait_queue_head_t wait; struct mousedev_list *list; struct input_handle handle; @@ -89,8 +92,6 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig struct mousedev_list *list; int index, size; - add_mouse_randomness((type << 4) ^ code ^ (code >> 4) ^ value); - while (*mousedev) { list = (*mousedev)->list; while (list) { @@ -101,13 +102,23 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig switch (code) { case ABS_X: size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X]; - list->dx += (value * xres - list->oldx) / size; - list->oldx += list->dx * size; + if (size != 0) { + list->dx += (value * xres - list->oldx) / size; + list->oldx += list->dx * size; + } else { + list->dx += value - list->oldx; + list->oldx += list->dx; + } break; case ABS_Y: size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y]; - list->dy -= (value * yres - list->oldy) / size; - list->oldy -= list->dy * size; + if (size != 0) { + list->dy -= (value * yres - list->oldy) / size; + list->oldy -= list->dy * size; + } else { + list->dy -= value - list->oldy; + list->oldy -= list->dy; + } break; } break; @@ -169,7 +180,7 @@ static int mousedev_release(struct inode * inode, struct file * file) { struct mousedev_list *list = file->private_data; struct mousedev_list **listptr; - + listptr = &list->mousedev->list; mousedev_fasync(-1, file, 0); @@ -344,7 +355,7 @@ static ssize_t mousedev_read(struct file * file, char * buffer, size_t count, lo if (!list->ready && !list->buffer) { add_wait_queue(&list->mousedev->wait, &wait); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); while (!list->ready) { @@ -360,7 +371,7 @@ static ssize_t mousedev_read(struct file * file, char * buffer, size_t count, lo schedule(); } - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); remove_wait_queue(&list->mousedev->wait, &wait); } @@ -401,19 +412,11 @@ struct file_operations mousedev_fops = { fasync: mousedev_fasync, }; -static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev) +static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id) { struct mousedev *mousedev; int minor = 0; - if (!test_bit(EV_KEY, dev->evbit) || - (!test_bit(BTN_LEFT, dev->keybit) && !test_bit(BTN_TOUCH, dev->keybit))) - return NULL; - - if ((!test_bit(EV_REL, dev->evbit) || !test_bit(REL_X, dev->relbit)) && - (!test_bit(EV_ABS, dev->evbit) || !test_bit(ABS_X, dev->absbit))) - return NULL; - for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++); if (minor == MOUSEDEV_MINORS) { printk(KERN_ERR "mousedev: no more free mousedev devices\n"); @@ -425,11 +428,12 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru memset(mousedev, 0, sizeof(struct mousedev)); init_waitqueue_head(&mousedev->wait); - mousedev->exist = 1; mousedev->minor = minor; mousedev_table[minor] = mousedev; + sprintf(mousedev->name, "mouse%d", minor); mousedev->handle.dev = dev; + mousedev->handle.name = mousedev->name; mousedev->handle.handler = handler; mousedev->handle.private = mousedev; @@ -438,7 +442,7 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru if (mousedev_mix.open) input_open_device(&mousedev->handle); -// printk(KERN_INFO "mouse%d: PS/2 mouse device for input%d\n", minor, dev->number); + mousedev->exist = 1; return &mousedev->handle; } @@ -459,6 +463,26 @@ static void mousedev_disconnect(struct input_handle *handle) kfree(mousedev); } } + +static struct input_device_id mousedev_ids[] = { + { + flags: INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT, + evbit: { BIT(EV_KEY) | BIT(EV_REL) }, + keybit: { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) }, + relbit: { BIT(REL_X) | BIT(REL_Y) }, + }, /* A mouse like device, at least one button, two relative axes */ + + { + flags: INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, + evbit: { BIT(EV_KEY) | BIT(EV_ABS) }, + keybit: { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, + absbit: { BIT(ABS_X) | BIT(ABS_Y) }, + }, /* A tablet like device, at least touch detection, two absolute axes */ + + { }, /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(input, mousedev_ids); static struct input_handler mousedev_handler = { event: mousedev_event, @@ -466,6 +490,8 @@ static struct input_handler mousedev_handler = { disconnect: mousedev_disconnect, fops: &mousedev_fops, minor: MOUSEDEV_MINOR_BASE, + name: "mousedev", + id_table: mousedev_ids, }; static int __init mousedev_init(void) @@ -493,10 +519,6 @@ static void __exit mousedev_exit(void) module_init(mousedev_init); module_exit(mousedev_exit); -MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); -MODULE_DESCRIPTION("Input driver to PS/2 or ImPS/2 device driver"); -MODULE_LICENSE("GPL"); - MODULE_PARM(xres, "i"); MODULE_PARM_DESC(xres, "Horizontal screen resolution"); MODULE_PARM(yres, "i"); diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index 13a272d5f..74f82b397 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -87,8 +87,12 @@ * */ +#define DRV_NAME "3c501" +#define DRV_VERSION "2001/11/17" + + static const char version[] = - "3c501.c: 2000/02/08 Alan Cox (alan@redhat.com).\n"; + DRV_NAME ".c: " DRV_VERSION " Alan Cox (alan@redhat.com).\n"; /* * Braindamage remaining: @@ -108,7 +112,9 @@ static const char version[] = #include <linux/errno.h> #include <linux/config.h> /* for CONFIG_IP_MULTICAST */ #include <linux/spinlock.h> +#include <linux/ethtool.h> +#include <asm/uaccess.h> #include <asm/bitops.h> #include <asm/io.h> @@ -139,12 +145,14 @@ static void el_reset(struct net_device *dev); static int el1_close(struct net_device *dev); static struct net_device_stats *el1_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); #define EL1_IO_EXTENT 16 #ifndef EL_DEBUG #define EL_DEBUG 0 /* use 0 for production, 1 for devel., >2 for debug */ #endif /* Anything above 5 is wordy death! */ +#define debug el_debug static int el_debug = EL_DEBUG; /* @@ -377,6 +385,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr) dev->stop = &el1_close; dev->get_stats = &el1_get_stats; dev->set_multicast_list = &set_multicast_list; + dev->do_ioctl = netdev_ioctl; /* * Setup the generic properties @@ -915,6 +924,86 @@ static void set_multicast_list(struct net_device *dev) } } +/** + * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls + * @dev: network interface on which out-of-band action is to be performed + * @useraddr: userspace address to which data is to be read and returned + * + * Process the various commands of the SIOCETHTOOL interface. + */ + +static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + /* dev_ioctl() in ../../net/core/dev.c has already checked + capable(CAP_NET_ADMIN), so don't bother with that here. */ + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + debug = edata.data; + return 0; + } + + default: + break; + } + + return -EOPNOTSUPP; +} + +/** + * netdev_ioctl: Handle network interface ioctls + * @dev: network interface on which out-of-band action is to be performed + * @rq: user request data + * @cmd: command issued by user + * + * Process the various out-of-band ioctls passed to this driver. + */ + +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +{ + int rc = 0; + + switch (cmd) { + case SIOCETHTOOL: + rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + break; + + default: + rc = -EOPNOTSUPP; + break; + } + + return rc; +} + #ifdef MODULE static struct net_device dev_3c501 = { diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index c1768a1d0..b09674461 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -29,11 +29,17 @@ Paul Gortmaker : add support for the 2nd 8kB of RAM on 16 bit cards. Paul Gortmaker : multiple card support for module users. rjohnson@analogic.com : Fix up PIO interface for efficient operation. + Jeff Garzik : ethtool support */ +#define DRV_NAME "3c503" +#define DRV_VERSION "1.10a" +#define DRV_RELDATE "11/17/2001" + + static const char version[] = - "3c503.c:v1.10 9/23/93 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; + DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Donald Becker (becker@scyld.com)\n"; #include <linux/module.h> @@ -45,7 +51,9 @@ static const char version[] = #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/init.h> +#include <linux/ethtool.h> +#include <asm/uaccess.h> #include <asm/io.h> #include <asm/system.h> #include <asm/byteorder.h> @@ -74,6 +82,7 @@ static void el2_block_input(struct net_device *dev, int count, struct sk_buff *s int ring_offset); static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); /* This routine probes for a memory-mapped 3c503 board by looking for @@ -301,6 +310,7 @@ el2_probe1(struct net_device *dev, int ioaddr) dev->open = &el2_open; dev->stop = &el2_close; + dev->do_ioctl = &netdev_ioctl; if (dev->mem_start) printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n", @@ -607,6 +617,71 @@ el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL); return; } + +/** + * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls + * @dev: network interface on which out-of-band action is to be performed + * @useraddr: userspace address to which data is to be read and returned + * + * Process the various commands of the SIOCETHTOOL interface. + */ + +static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + /* dev_ioctl() in ../../net/core/dev.c has already checked + capable(CAP_NET_ADMIN), so don't bother with that here. */ + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + default: + break; + } + + return -EOPNOTSUPP; +} + +/** + * netdev_ioctl: Handle network interface ioctls + * @dev: network interface on which out-of-band action is to be performed + * @rq: user request data + * @cmd: command issued by user + * + * Process the various out-of-band ioctls passed to this driver. + */ + +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +{ + int rc = 0; + + switch (cmd) { + case SIOCETHTOOL: + rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + break; + + default: + rc = -EOPNOTSUPP; + break; + } + + return rc; +} + + #ifdef MODULE #define MAX_EL2_CARDS 4 /* Max number of EL2 cards per module */ diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index 8386addb6..6327ec483 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -35,8 +35,13 @@ * Philip Blundell <Philip.Blundell@pobox.com> * Multicard/soft configurable dma channel/rev 2 hardware support * by Christopher Collins <ccollins@pcug.org.au> + * Ethtool support (jgarzik), 11/17/2001 */ +#define DRV_NAME "3c505" +#define DRV_VERSION "1.10a" + + /* Theory of operation: * * The 3c505 is quite an intelligent board. All communication with it is done @@ -103,6 +108,9 @@ #include <linux/slab.h> #include <linux/ioport.h> #include <linux/spinlock.h> +#include <linux/ethtool.h> + +#include <asm/uaccess.h> #include <asm/bitops.h> #include <asm/io.h> #include <asm/dma.h> @@ -148,10 +156,11 @@ static char couldnot_msg[] __initdata = "%s: 3c505 not found\n"; *********************************************************/ #ifdef ELP_DEBUG -static const int elp_debug = ELP_DEBUG; +static int elp_debug = ELP_DEBUG; #else -static const int elp_debug; +static int elp_debug; #endif +#define debug elp_debug /* * 0 = no messages (well, some) @@ -1260,6 +1269,87 @@ static void elp_set_mc_list(struct net_device *dev) } } +/** + * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls + * @dev: network interface on which out-of-band action is to be performed + * @useraddr: userspace address to which data is to be read and returned + * + * Process the various commands of the SIOCETHTOOL interface. + */ + +static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + /* dev_ioctl() in ../../net/core/dev.c has already checked + capable(CAP_NET_ADMIN), so don't bother with that here. */ + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + debug = edata.data; + return 0; + } + + default: + break; + } + + return -EOPNOTSUPP; +} + +/** + * netdev_ioctl: Handle network interface ioctls + * @dev: network interface on which out-of-band action is to be performed + * @rq: user request data + * @cmd: command issued by user + * + * Process the various out-of-band ioctls passed to this driver. + */ + +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +{ + int rc = 0; + + switch (cmd) { + case SIOCETHTOOL: + rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + break; + + default: + rc = -EOPNOTSUPP; + break; + } + + return rc; +} + + /****************************************************** * * initialise Etherlink Plus board @@ -1280,6 +1370,7 @@ static inline void elp_init(struct net_device *dev) dev->tx_timeout = elp_timeout; /* local */ dev->watchdog_timeo = 10*HZ; dev->set_multicast_list = elp_set_mc_list; /* local */ + dev->do_ioctl = netdev_ioctl; /* local */ /* Setup the generic properties */ ether_setup(dev); diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index df46dbbeb..3de089075 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -25,8 +25,12 @@ The statistics need to be updated correctly. */ +#define DRV_NAME "3c507" +#define DRV_VERSION "1.10a" +#define DRV_RELDATE "11/17/2001" + static const char version[] = - "3c507.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; + DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Donald Becker (becker@scyld.com)\n"; #include <linux/module.h> @@ -52,6 +56,9 @@ static const char version[] = #include <linux/in.h> #include <linux/string.h> #include <linux/spinlock.h> +#include <linux/ethtool.h> + +#include <asm/uaccess.h> #include <asm/system.h> #include <asm/bitops.h> #include <asm/io.h> @@ -70,6 +77,8 @@ static const char version[] = #define NET_DEBUG 1 #endif static unsigned int net_debug = NET_DEBUG; +#define debug net_debug + /* A zero-terminated list of common I/O addresses to be probed. */ static unsigned int netcard_portlist[] __initdata = @@ -296,6 +305,7 @@ static void el16_tx_timeout (struct net_device *dev); static void hardware_send_packet(struct net_device *dev, void *buf, short length); static void init_82586_mem(struct net_device *dev); +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); /* Check for a network adaptor of this type, and return '0' iff one exists. @@ -427,6 +437,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) dev->get_stats = el16_get_stats; dev->tx_timeout = el16_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; + dev->do_ioctl = netdev_ioctl; ether_setup(dev); /* Generic ethernet behaviour */ @@ -864,6 +875,88 @@ static void el16_rx(struct net_device *dev) lp->rx_head = rx_head; lp->rx_tail = rx_tail; } + +/** + * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls + * @dev: network interface on which out-of-band action is to be performed + * @useraddr: userspace address to which data is to be read and returned + * + * Process the various commands of the SIOCETHTOOL interface. + */ + +static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + /* dev_ioctl() in ../../net/core/dev.c has already checked + capable(CAP_NET_ADMIN), so don't bother with that here. */ + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + debug = edata.data; + return 0; + } + + default: + break; + } + + return -EOPNOTSUPP; +} + +/** + * netdev_ioctl: Handle network interface ioctls + * @dev: network interface on which out-of-band action is to be performed + * @rq: user request data + * @cmd: command issued by user + * + * Process the various out-of-band ioctls passed to this driver. + */ + +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +{ + int rc = 0; + + switch (cmd) { + case SIOCETHTOOL: + rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + break; + + default: + rc = -EOPNOTSUPP; + break; + } + + return rc; +} + + #ifdef MODULE static struct net_device dev_3c507; static int io = 0x300; diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index e6eddb3f0..4f5c959c5 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -43,8 +43,14 @@ v1.18 12Mar2001 Andrew Morton <andrewm@uow.edu.au> - Avoid bogus detect of 3c590's (Andrzej Krzysztofowicz) - Reviewed against 1.18 from scyld.com + v1.18 17Nov2001 Jeff Garzik <jgarzik@mandrakesoft.com> + - ethtool support */ +#define DRV_NAME "3c509" +#define DRV_VERSION "1.18a" +#define DRV_RELDATE "17Nov2001" + /* A few values that may be tweaked. */ /* Time in jiffies before concluding the transmitter is hung. */ @@ -70,12 +76,14 @@ static int max_interrupt_work = 10; #include <linux/skbuff.h> #include <linux/delay.h> /* for udelay() */ #include <linux/spinlock.h> +#include <linux/ethtool.h> +#include <asm/uaccess.h> #include <asm/bitops.h> #include <asm/io.h> #include <asm/irq.h> -static char versionA[] __initdata = "3c509.c:1.18 12Mar2001 becker@scyld.com\n"; +static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE "becker@scyld.com\n"; static char versionB[] __initdata = "http://www.scyld.com/network/3c509.html\n"; #ifdef EL3_DEBUG @@ -84,6 +92,7 @@ static int el3_debug = EL3_DEBUG; static int el3_debug = 2; #endif + /* To minimize the size of the driver source I only define operating constants if they are used several times. You'll need the manual anyway if you want to understand driver details. */ @@ -158,6 +167,7 @@ static int el3_rx(struct net_device *dev); static int el3_close(struct net_device *dev); static void set_multicast_list(struct net_device *dev); static void el3_tx_timeout (struct net_device *dev); +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); #ifdef CONFIG_MCA struct el3_mca_adapters_struct { @@ -513,6 +523,7 @@ no_pnp: dev->set_multicast_list = &set_multicast_list; dev->tx_timeout = el3_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; + dev->do_ioctl = netdev_ioctl; /* Fill in the generic fields of the device structure. */ ether_setup(dev); @@ -1003,6 +1014,85 @@ el3_close(struct net_device *dev) return 0; } +/** + * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls + * @dev: network interface on which out-of-band action is to be performed + * @useraddr: userspace address to which data is to be read and returned + * + * Process the various commands of the SIOCETHTOOL interface. + */ + +static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + /* dev_ioctl() in ../../net/core/dev.c has already checked + capable(CAP_NET_ADMIN), so don't bother with that here. */ + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = el3_debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + el3_debug = edata.data; + return 0; + } + + default: + break; + } + + return -EOPNOTSUPP; +} + +/** + * netdev_ioctl: Handle network interface ioctls + * @dev: network interface on which out-of-band action is to be performed + * @rq: user request data + * @cmd: command issued by user + * + * Process the various out-of-band ioctls passed to this driver. + */ + +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +{ + int rc = 0; + + switch (cmd) { + case SIOCETHTOOL: + rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + break; + + default: + rc = -EOPNOTSUPP; + break; + } + + return rc; +} + #ifdef MODULE /* Parameters that may be passed into the module. */ static int debug = -1; diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 83cecdc7e..73502bc08 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -16,9 +16,17 @@ 2/2/00- Added support for kernel-level ISAPnP by Stephen Frost <sfrost@snowman.net> and Alessandro Zummo Cleaned up for 2.3.x/softnet by Jeff Garzik and Alan Cox. + + 11/17/2001 - Added ethtool support (jgarzik) + */ -static char *version = "3c515.c:v0.99-sn 2000/02/12 becker@cesdis.gsfc.nasa.gov and others\n"; +#define DRV_NAME "3c515" +#define DRV_VERSION "0.99t" +#define DRV_RELDATE "17-Nov-2001" + +static char *version = +DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " becker@scyld.com and others\n"; #define CORKSCREW 1 @@ -63,6 +71,9 @@ static int max_interrupt_work = 20; #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/timer.h> +#include <linux/ethtool.h> + +#include <asm/uaccess.h> #include <asm/bitops.h> #include <asm/io.h> #include <asm/dma.h> @@ -393,6 +404,7 @@ static int corkscrew_close(struct net_device *dev); static void update_stats(int addr, struct net_device *dev); static struct net_device_stats *corkscrew_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); /* @@ -721,6 +733,7 @@ static int corkscrew_probe1(struct net_device *dev) dev->stop = &corkscrew_close; dev->get_stats = &corkscrew_get_stats; dev->set_multicast_list = &set_rx_mode; + dev->do_ioctl = netdev_ioctl; return 0; } @@ -1591,6 +1604,87 @@ static void set_rx_mode(struct net_device *dev) outw(new_mode, ioaddr + EL3_CMD); } + +/** + * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls + * @dev: network interface on which out-of-band action is to be performed + * @useraddr: userspace address to which data is to be read and returned + * + * Process the various commands of the SIOCETHTOOL interface. + */ + +static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + /* dev_ioctl() in ../../net/core/dev.c has already checked + capable(CAP_NET_ADMIN), so don't bother with that here. */ + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + sprintf(info.bus_info, "ISA 0x%lx", dev->base_addr); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = corkscrew_debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + corkscrew_debug = edata.data; + return 0; + } + + default: + break; + } + + return -EOPNOTSUPP; +} + +/** + * netdev_ioctl: Handle network interface ioctls + * @dev: network interface on which out-of-band action is to be performed + * @rq: user request data + * @cmd: command issued by user + * + * Process the various out-of-band ioctls passed to this driver. + */ + +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +{ + int rc = 0; + + switch (cmd) { + case SIOCETHTOOL: + rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + break; + + default: + rc = -EOPNOTSUPP; + break; + } + + return rc; +} + #ifdef MODULE void cleanup_module(void) diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index eb2480f3a..1837f30fb 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -81,10 +81,15 @@ added option to disable multicast as is causes problems Ganesh Sittampalam <ganesh.sittampalam@magdalen.oxford.ac.uk> Stuart Adamson <stuart.adamson@compsoc.net> + Nov 2001 + added support for ethtool (jgarzik) $Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $ */ +#define DRV_NAME "3c523" +#define DRV_VERSION "17-Nov-2001" + #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -95,6 +100,9 @@ #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/mca.h> +#include <linux/ethtool.h> + +#include <asm/uaccess.h> #include <asm/processor.h> #include <asm/bitops.h> #include <asm/io.h> @@ -182,6 +190,7 @@ static void elmc_timeout(struct net_device *dev); #ifdef ELMC_MULTICAST static void set_multicast_list(struct net_device *dev); #endif +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); /* helper-functions */ static int init586(struct net_device *dev); @@ -563,7 +572,8 @@ int __init elmc_probe(struct net_device *dev) #else dev->set_multicast_list = NULL; #endif - + dev->do_ioctl = netdev_ioctl; + ether_setup(dev); /* note that we haven't actually requested the IRQ from the kernel. @@ -1214,6 +1224,69 @@ static void set_multicast_list(struct net_device *dev) } #endif +/** + * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls + * @dev: network interface on which out-of-band action is to be performed + * @useraddr: userspace address to which data is to be read and returned + * + * Process the various commands of the SIOCETHTOOL interface. + */ + +static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + /* dev_ioctl() in ../../net/core/dev.c has already checked + capable(CAP_NET_ADMIN), so don't bother with that here. */ + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + sprintf(info.bus_info, "MCA 0x%lx", dev->base_addr); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + default: + break; + } + + return -EOPNOTSUPP; +} + +/** + * netdev_ioctl: Handle network interface ioctls + * @dev: network interface on which out-of-band action is to be performed + * @rq: user request data + * @cmd: command issued by user + * + * Process the various out-of-band ioctls passed to this driver. + */ + +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +{ + int rc = 0; + + switch (cmd) { + case SIOCETHTOOL: + rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + break; + + default: + rc = -EOPNOTSUPP; + break; + } + + return rc; +} + /*************************************************************************/ #ifdef MODULE diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index 75bd0aedb..50f70f9fc 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -16,8 +16,12 @@ * */ +#define DRV_NAME "3c527" +#define DRV_VERSION "0.6a" +#define DRV_RELDATE "2001/11/17" + static const char *version = - "3c527.c:v0.6 2001/03/03 Richard Proctor (rnp@netlink.co.nz)\n"; +DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Richard Proctor (rnp@netlink.co.nz)\n"; /** * DOC: Traps for the unwary @@ -90,6 +94,9 @@ static const char *version = #include <linux/in.h> #include <linux/slab.h> #include <linux/string.h> +#include <linux/ethtool.h> + +#include <asm/uaccess.h> #include <asm/system.h> #include <asm/bitops.h> #include <asm/io.h> @@ -108,7 +115,7 @@ static const char *version = * The name of the card. Is used for messages and in the requests for * io regions, irqs and dma channels */ -static const char* cardname = "3c527"; +static const char* cardname = DRV_NAME; /* use 0 for production, 1 for verification, >2 for debug */ #ifndef NET_DEBUG @@ -213,6 +220,7 @@ static int mc32_close(struct net_device *dev); static struct net_device_stats *mc32_get_stats(struct net_device *dev); static void mc32_set_multicast_list(struct net_device *dev); static void mc32_reset_multicast_list(struct net_device *dev); +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); /** * mc32_probe - Search for supported boards @@ -502,7 +510,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot) dev->set_multicast_list = mc32_set_multicast_list; dev->tx_timeout = mc32_timeout; dev->watchdog_timeo = HZ*5; /* Board does all the work */ - + dev->do_ioctl = netdev_ioctl; lp->xceiver_state = HALTED; @@ -1644,6 +1652,86 @@ static void mc32_reset_multicast_list(struct net_device *dev) do_mc32_set_multicast_list(dev,1); } +/** + * netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls + * @dev: network interface on which out-of-band action is to be performed + * @useraddr: userspace address to which data is to be read and returned + * + * Process the various commands of the SIOCETHTOOL interface. + */ + +static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + /* dev_ioctl() in ../../net/core/dev.c has already checked + capable(CAP_NET_ADMIN), so don't bother with that here. */ + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + sprintf(info.bus_info, "MCA 0x%lx", dev->base_addr); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = mc32_debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + mc32_debug = edata.data; + return 0; + } + + default: + break; + } + + return -EOPNOTSUPP; +} + +/** + * netdev_ioctl: Handle network interface ioctls + * @dev: network interface on which out-of-band action is to be performed + * @rq: user request data + * @cmd: command issued by user + * + * Process the various out-of-band ioctls passed to this driver. + */ + +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +{ + int rc = 0; + + switch (cmd) { + case SIOCETHTOOL: + rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + break; + + default: + rc = -EOPNOTSUPP; + break; + } + + return rc; +} + #ifdef MODULE static struct net_device this_device; diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index e5745847f..944407bda 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -20,7 +20,6 @@ TODO, in rough priority order: * dev->tx_timeout * LinkChg interrupt - * ETHTOOL_[GS]SET * Support forcing media type with a module parameter, like dl2k.c/sundance.c * Implement PCI suspend/resume @@ -33,18 +32,19 @@ * Rx checksumming * Tx checksumming * ETHTOOL_GREGS, ETHTOOL_[GS]WOL, - ETHTOOL_[GS]MSGLVL, ETHTOOL_NWAY_RST * Jumbo frames / dev->change_mtu * Investigate using skb->priority with h/w VLAN priority * Investigate using High Priority Tx Queue with skb->priority * Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error * Adjust Tx FIFO threshold and Max Tx DMA burst on Tx FIFO error + * Implement Tx software interrupt mitigation via + Tx descriptor bit */ #define DRV_NAME "8139cp" -#define DRV_VERSION "0.0.5" -#define DRV_RELDATE "Oct 19, 2001" +#define DRV_VERSION "0.0.6cvs" +#define DRV_RELDATE "Nov 19, 2001" #include <linux/module.h> @@ -56,6 +56,7 @@ #include <linux/delay.h> #include <linux/ethtool.h> #include <linux/crc32.h> +#include <linux/mii.h> #include <asm/io.h> #include <asm/uaccess.h> @@ -94,10 +95,10 @@ MODULE_PARM_DESC (multicast_filter_limit, "8139cp maximum number of filtered mul (((CP)->tx_tail <= (CP)->tx_head) ? \ (CP)->tx_tail + (CP_TX_RING_SIZE - 1) - (CP)->tx_head : \ (CP)->tx_tail - (CP)->tx_head - 1) -#define CP_CHIP_VERSION 0x76 #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ #define RX_OFFSET 2 +#define CP_INTERNAL_PHY 32 /* The following settings are log_2(bytes)-4: 0 == 16 bytes .. 6==1024, 7==end of packet. */ #define RX_FIFO_THRESH 5 /* Rx buffer level before first PCI xfer. */ @@ -126,6 +127,11 @@ enum { Config3 = 0x59, /* Config3 */ Config4 = 0x5A, /* Config4 */ MultiIntr = 0x5C, /* Multiple interrupt select */ + BasicModeCtrl = 0x62, /* MII BMCR */ + BasicModeStatus = 0x64, /* MII BMSR */ + NWayAdvert = 0x66, /* MII ADVERTISE */ + NWayLPAR = 0x68, /* MII LPA */ + NWayExpansion = 0x6A, /* MII Expansion */ Config5 = 0xD8, /* Config5 */ TxPoll = 0xD9, /* Tell chip to check Tx descriptors for work */ CpCmd = 0xE0, /* C+ Command register (C+ mode only) */ @@ -279,6 +285,8 @@ struct cp_private { struct sk_buff *frag_skb; unsigned dropping_frag : 1; + + struct mii_if_info mii_if; }; #define cpr8(reg) readb(cp->regs + (reg)) @@ -985,6 +993,39 @@ static int cp_close (struct net_device *dev) return 0; } +static char mii_2_8139_map[8] = { + BasicModeCtrl, + BasicModeStatus, + 0, + 0, + NWayAdvert, + NWayLPAR, + NWayExpansion, + 0 +}; + +static int mdio_read(struct net_device *dev, int phy_id, int location) +{ + struct cp_private *cp = dev->priv; + + return location < 8 && mii_2_8139_map[location] ? + readw(cp->regs + mii_2_8139_map[location]) : 0; +} + + +static void mdio_write(struct net_device *dev, int phy_id, int location, + int value) +{ + struct cp_private *cp = dev->priv; + + if (location == 0) { + cpw8(Cfg9346, Cfg9346_Unlock); + cpw16(BasicModeCtrl, value); + cpw8(Cfg9346, Cfg9346_Lock); + } else if (location < 8 && mii_2_8139_map[location]) + cpw16(mii_2_8139_map[location], value); +} + static int cp_ethtool_ioctl (struct cp_private *cp, void *useraddr) { u32 ethcmd; @@ -992,21 +1033,71 @@ static int cp_ethtool_ioctl (struct cp_private *cp, void *useraddr) /* dev_ioctl() in ../../net/core/dev.c has already checked capable(CAP_NET_ADMIN), so don't bother with that here. */ - if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) + if (get_user(ethcmd, (u32 *)useraddr)) return -EFAULT; switch (ethcmd) { - case ETHTOOL_GDRVINFO: - { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, cp->pdev->slot_name); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + strcpy (info.bus_info, cp->pdev->slot_name); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get settings */ + case ETHTOOL_GSET: { + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + spin_lock_irq(&cp->lock); + mii_ethtool_gset(&cp->mii_if, &ecmd); + spin_unlock_irq(&cp->lock); + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) + return -EFAULT; + return 0; + } + /* set settings */ + case ETHTOOL_SSET: { + int r; + struct ethtool_cmd ecmd; + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) + return -EFAULT; + spin_lock_irq(&cp->lock); + r = mii_ethtool_sset(&cp->mii_if, &ecmd); + spin_unlock_irq(&cp->lock); + return r; + } + /* restart autonegotiation */ + case ETHTOOL_NWAY_RST: { + return mii_nway_restart(&cp->mii_if); + } + /* get link status */ + case ETHTOOL_GLINK: { + struct ethtool_value edata = {ETHTOOL_GLINK}; + edata.data = mii_link_ok(&cp->mii_if); + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = cp->msg_enable; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + cp->msg_enable = edata.data; + return 0; + } default: break; @@ -1136,6 +1227,10 @@ static int __devinit cp_init_one (struct pci_dev *pdev, cp->dev = dev; cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug); spin_lock_init (&cp->lock); + cp->mii_if.dev = dev; + cp->mii_if.mdio_read = mdio_read; + cp->mii_if.mdio_write = mdio_write; + cp->mii_if.phy_id = CP_INTERNAL_PHY; rc = pci_enable_device(pdev); if (rc) diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 5d2e80dd6..91ee34ccb 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -92,7 +92,7 @@ */ #define DRV_NAME "8139too" -#define DRV_VERSION "0.9.22" +#define DRV_VERSION "0.9.24" #include <linux/config.h> @@ -160,6 +160,9 @@ static int max_interrupt_work = 20; The RTL chips use a 64 element hash table based on the Ethernet CRC. */ static int multicast_filter_limit = 32; +/* bitmapped message enable number */ +static int debug = -1; + /* Size of the in-memory receive ring. */ #define RX_BUF_LEN_IDX 2 /* 0==8K, 1==16K, 2==32K, 3==64K */ #define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX) @@ -213,6 +216,7 @@ typedef enum { ADDTRON8139, DFE538TX, DFE690TXD, + FE2000VX, RTL8129, } board_t; @@ -230,6 +234,7 @@ static struct { { "Addtron Technolgy 8139 10/100BaseTX", RTL8139_CAPS }, { "D-Link DFE-538TX (RealTek RTL8139)", RTL8139_CAPS }, { "D-Link DFE-690TXD (RealTek RTL8139)", RTL8139_CAPS }, + { "AboCom FE2000VX (RealTek RTL8139)", RTL8139_CAPS }, { "RealTek RTL8129", RTL8129_CAPS }, }; @@ -243,6 +248,7 @@ static struct pci_device_id rtl8139_pci_tbl[] __devinitdata = { {0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADDTRON8139 }, {0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE538TX }, {0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE690TXD }, + {0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FE2000VX }, #ifdef CONFIG_8139TOO_8129 {0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 }, @@ -254,6 +260,7 @@ static struct pci_device_id rtl8139_pci_tbl[] __devinitdata = { */ {PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0, RTL8139 }, {PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, DFE538TX }, + {PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, FE2000VX }, {0,} }; @@ -526,6 +533,7 @@ struct rtl_extra_stats { unsigned long early_rx; unsigned long tx_buf_mapped; unsigned long tx_timeouts; + unsigned long rx_lost_in_ring; }; struct rtl8139_private { @@ -544,12 +552,8 @@ struct rtl8139_private { dma_addr_t tx_bufs_dma; signed char phys[4]; /* MII device addresses. */ char twistie, twist_row, twist_col; /* Twister tune state. */ - unsigned int full_duplex:1; /* Full-duplex operation requested. */ - unsigned int duplex_lock:1; unsigned int default_port:4; /* Last dev->if_port value. */ - unsigned int media2:4; /* Secondary monitored media port. */ unsigned int medialock:1; /* Don't sense media type. */ - unsigned int mediasense:1; /* Media sensing in progress. */ spinlock_t lock; chip_t chipset; pid_t thr_pid; @@ -558,6 +562,7 @@ struct rtl8139_private { u32 rx_config; struct rtl_extra_stats xstats; int time_to_die; + struct mii_if_info mii; }; MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>"); @@ -568,6 +573,8 @@ MODULE_PARM (multicast_filter_limit, "i"); MODULE_PARM (max_interrupt_work, "i"); MODULE_PARM (media, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_PARM (full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); +MODULE_PARM (debug, "i"); +MODULE_PARM_DESC (debug, "8139too bitmapped message enable number"); MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered multicast addresses"); MODULE_PARM_DESC (max_interrupt_work, "8139too maximum events handled per interrupt"); MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps"); @@ -948,6 +955,9 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, spin_lock_init (&tp->lock); init_waitqueue_head (&tp->thr_wait); init_completion (&tp->thr_exited); + tp->mii.dev = dev; + tp->mii.mdio_read = mdio_read; + tp->mii.mdio_write = mdio_write; /* dev is fully set up and ready to use now */ DPRINTK("about to register device named %s (%p)...\n", dev->name, dev); @@ -999,18 +1009,18 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, /* The lower four bits are the media type. */ option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx]; if (option > 0) { - tp->full_duplex = (option & 0x210) ? 1 : 0; + tp->mii.full_duplex = (option & 0x210) ? 1 : 0; tp->default_port = option & 0xFF; if (tp->default_port) tp->medialock = 1; } if (board_idx < MAX_UNITS && full_duplex[board_idx] > 0) - tp->full_duplex = full_duplex[board_idx]; - if (tp->full_duplex) { + tp->mii.full_duplex = full_duplex[board_idx]; + if (tp->mii.full_duplex) { printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name); /* Changing the MII-advertised media because might prevent re-connection. */ - tp->duplex_lock = 1; + tp->mii.duplex_lock = 1; } if (tp->default_port) { printk(KERN_INFO " Forcing %dMbps %s-duplex operation.\n", @@ -1267,7 +1277,7 @@ static int rtl8139_open (struct net_device *dev) } - tp->full_duplex = tp->duplex_lock; + tp->mii.full_duplex = tp->mii.duplex_lock; tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000; tp->twistie = 1; tp->time_to_die = 0; @@ -1279,7 +1289,7 @@ static int rtl8139_open (struct net_device *dev) " GP Pins %2.2x %s-duplex.\n", dev->name, pci_resource_start (tp->pci_dev, 1), dev->irq, RTL_R8 (MediaStatus), - tp->full_duplex ? "full" : "half"); + tp->mii.full_duplex ? "full" : "half"); tp->thr_pid = kernel_thread (rtl8139_thread, dev, CLONE_FS | CLONE_FILES); if (tp->thr_pid < 0) @@ -1295,18 +1305,18 @@ static void rtl_check_media (struct net_device *dev) struct rtl8139_private *tp = dev->priv; if (tp->phys[0] >= 0) { - u16 mii_reg5 = mdio_read(dev, tp->phys[0], 5); - if (mii_reg5 == 0xffff) + u16 mii_lpa = mdio_read(dev, tp->phys[0], MII_LPA); + if (mii_lpa == 0xffff) ; /* Not there */ - else if ((mii_reg5 & 0x0100) == 0x0100 - || (mii_reg5 & 0x00C0) == 0x0040) - tp->full_duplex = 1; + else if ((mii_lpa & LPA_100FULL) == LPA_100FULL + || (mii_lpa & 0x00C0) == LPA_10FULL) + tp->mii.full_duplex = 1; printk (KERN_INFO"%s: Setting %s%s-duplex based on" " auto-negotiated partner ability %4.4x.\n", - dev->name, mii_reg5 == 0 ? "" : - (mii_reg5 & 0x0180) ? "100mbps " : "10mbps ", - tp->full_duplex ? "full" : "half", mii_reg5); + dev->name, mii_lpa == 0 ? "" : + (mii_lpa & 0x0180) ? "100mbps " : "10mbps ", + tp->mii.full_duplex ? "full" : "half", mii_lpa); } } @@ -1494,30 +1504,30 @@ static inline void rtl8139_thread_iter (struct net_device *dev, struct rtl8139_private *tp, void *ioaddr) { - int mii_reg5; + int mii_lpa; - mii_reg5 = mdio_read (dev, tp->phys[0], 5); + mii_lpa = mdio_read (dev, tp->phys[0], MII_LPA); - if (!tp->duplex_lock && mii_reg5 != 0xffff) { - int duplex = (mii_reg5 & 0x0100) - || (mii_reg5 & 0x01C0) == 0x0040; - if (tp->full_duplex != duplex) { - tp->full_duplex = duplex; + if (!tp->mii.duplex_lock && mii_lpa != 0xffff) { + int duplex = (mii_lpa & LPA_100FULL) + || (mii_lpa & 0x01C0) == 0x0040; + if (tp->mii.full_duplex != duplex) { + tp->mii.full_duplex = duplex; - if (mii_reg5) { + if (mii_lpa) { printk (KERN_INFO "%s: Setting %s-duplex based on MII #%d link" " partner ability of %4.4x.\n", dev->name, - tp->full_duplex ? "full" : "half", - tp->phys[0], mii_reg5); + tp->mii.full_duplex ? "full" : "half", + tp->phys[0], mii_lpa); } else { printk(KERN_INFO"%s: media is unconnected, link down, or incompatible connection\n", dev->name); } #if 0 RTL_W8 (Cfg9346, Cfg9346_Unlock); - RTL_W8 (Config1, tp->full_duplex ? 0x60 : 0x20); + RTL_W8 (Config1, tp->mii.full_duplex ? 0x60 : 0x20); RTL_W8 (Cfg9346, Cfg9346_Lock); #endif } @@ -1750,23 +1760,36 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev, struct rtl8139_private *tp, void *ioaddr) { u8 tmp8; +#ifndef CONFIG_8139_NEW_RX_RESET int tmp_work; +#endif DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n", dev->name, rx_status); - if (rx_status & RxTooLong) { - DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n", - dev->name, rx_status); - /* A.C.: The chip hangs here. */ - } tp->stats.rx_errors++; - if (rx_status & (RxBadSymbol | RxBadAlign)) - tp->stats.rx_frame_errors++; - if (rx_status & (RxRunt | RxTooLong)) - tp->stats.rx_length_errors++; - if (rx_status & RxCRCErr) - tp->stats.rx_crc_errors++; + if (!(rx_status & RxStatusOK)) { + if (rx_status & RxTooLong) { + DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n", + dev->name, rx_status); + /* A.C.: The chip hangs here. */ + } + if (rx_status & (RxBadSymbol | RxBadAlign)) + tp->stats.rx_frame_errors++; + if (rx_status & (RxRunt | RxTooLong)) + tp->stats.rx_length_errors++; + if (rx_status & RxCRCErr) + tp->stats.rx_crc_errors++; + } else { + tp->xstats.rx_lost_in_ring++; + } +#ifdef CONFIG_8139_NEW_RX_RESET + tmp8 = RTL_R8 (ChipCmd); + RTL_W8 (ChipCmd, tmp8 & ~CmdRxEnb); + RTL_W8 (ChipCmd, tmp8); + RTL_W32 (RxConfig, tp->rx_config); + tp->cur_rx = 0; +#else /* Reset the receiver, based on RealTek recommendation. (Bug?) */ /* disable receive */ @@ -1811,6 +1834,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev, /* A.C.: Reset the multicast list. */ __set_rx_mode (dev); +#endif } static void rtl8139_rx_interrupt (struct net_device *dev, @@ -1945,13 +1969,13 @@ static void rtl8139_weird_interrupt (struct net_device *dev, (tp->drv_flags & HAS_LNK_CHNG)) { /* Really link-change on new chips. */ int lpar = RTL_R16 (NWayLPAR); - int duplex = (lpar & 0x0100) || (lpar & 0x01C0) == 0x0040 - || tp->duplex_lock; - if (tp->full_duplex != duplex) { - tp->full_duplex = duplex; + int duplex = (lpar & LPA_100FULL) || (lpar & 0x01C0) == 0x0040 + || tp->mii.duplex_lock; + if (tp->mii.full_duplex != duplex) { + tp->mii.full_duplex = duplex; #if 0 RTL_W8 (Cfg9346, Cfg9346_Unlock); - RTL_W8 (Config1, tp->full_duplex ? 0x60 : 0x20); + RTL_W8 (Config1, tp->mii.full_duplex ? 0x60 : 0x20); RTL_W8 (Cfg9346, Cfg9346_Lock); #endif } @@ -2110,48 +2134,6 @@ static int rtl8139_close (struct net_device *dev) } -/* Get the ethtool settings. Assumes that eset points to kernel - memory, *eset has been initialized as {ETHTOOL_GSET}, and other - threads or interrupts aren't messing with the 8139. */ -static void netdev_get_eset (struct net_device *dev, struct ethtool_cmd *eset) -{ - struct rtl8139_private *np = dev->priv; - void *ioaddr = np->mmio_addr; - u16 advert; - - eset->supported = SUPPORTED_10baseT_Half - | SUPPORTED_10baseT_Full - | SUPPORTED_100baseT_Half - | SUPPORTED_100baseT_Full - | SUPPORTED_Autoneg - | SUPPORTED_TP; - - eset->advertising = ADVERTISED_TP | ADVERTISED_Autoneg; - advert = mdio_read (dev, np->phys[0], 4); - if (advert & 0x0020) - eset->advertising |= ADVERTISED_10baseT_Half; - if (advert & 0x0040) - eset->advertising |= ADVERTISED_10baseT_Full; - if (advert & 0x0080) - eset->advertising |= ADVERTISED_100baseT_Half; - if (advert & 0x0100) - eset->advertising |= ADVERTISED_100baseT_Full; - - eset->speed = (RTL_R8 (MediaStatus) & 0x08) ? 10 : 100; - /* (KON)FIXME: np->full_duplex is set or reset by the thread, - which means this always shows half duplex if the interface - isn't up yet, even if it has already autonegotiated. */ - eset->duplex = np->full_duplex ? DUPLEX_FULL : DUPLEX_HALF; - eset->port = PORT_TP; - /* (KON)FIXME: Is np->phys[0] correct? starfire.c uses that. */ - eset->phy_address = np->phys[0]; - eset->transceiver = XCVR_INTERNAL; - eset->autoneg = (mdio_read (dev, np->phys[0], 0) & 0x1000) != 0; - eset->maxtxpkt = 1; - eset->maxrxpkt = 1; -} - - /* Get the ethtool Wake-on-LAN settings. Assumes that wol points to kernel memory, *wol has been initialized as {ETHTOOL_GWOL}, and other threads or interrupts aren't messing with the 8139. */ @@ -2226,7 +2208,6 @@ static int netdev_set_wol (struct net_device *dev, return 0; } - static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) { struct rtl8139_private *np = dev->priv; @@ -2235,33 +2216,71 @@ static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) /* dev_ioctl() in ../../net/core/dev.c has already checked capable(CAP_NET_ADMIN), so don't bother with that here. */ - if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) + if (get_user(ethcmd, (u32 *)useraddr)) return -EFAULT; switch (ethcmd) { - case ETHTOOL_GSET: - { - struct ethtool_cmd eset = { ETHTOOL_GSET }; - spin_lock_irq (&np->lock); - netdev_get_eset (dev, &eset); - spin_unlock_irq (&np->lock); - if (copy_to_user (useraddr, &eset, sizeof (eset))) - return -EFAULT; - return 0; - } - /* TODO: ETHTOOL_SSET */ + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + strcpy (info.bus_info, np->pci_dev->slot_name); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } - case ETHTOOL_GDRVINFO: - { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, np->pci_dev->slot_name); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } + /* get settings */ + case ETHTOOL_GSET: { + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + spin_lock_irq(&np->lock); + mii_ethtool_gset(&np->mii, &ecmd); + spin_unlock_irq(&np->lock); + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) + return -EFAULT; + return 0; + } + /* set settings */ + case ETHTOOL_SSET: { + int r; + struct ethtool_cmd ecmd; + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) + return -EFAULT; + spin_lock_irq(&np->lock); + r = mii_ethtool_sset(&np->mii, &ecmd); + spin_unlock_irq(&np->lock); + return r; + } + /* restart autonegotiation */ + case ETHTOOL_NWAY_RST: { + return mii_nway_restart(&np->mii); + } + /* get link status */ + case ETHTOOL_GLINK: { + struct ethtool_value edata = {ETHTOOL_GLINK}; + edata.data = mii_link_ok(&np->mii); + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + debug = edata.data; + return 0; + } case ETHTOOL_GWOL: { @@ -2315,17 +2334,14 @@ static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); case SIOCGMIIPHY: /* Get the address of the PHY in use. */ - case SIOCDEVPRIVATE: /* binary compat, remove in 2.5 */ data->phy_id = phy; /* Fall Through */ case SIOCGMIIREG: /* Read the specified MII register. */ - case SIOCDEVPRIVATE+1: /* binary compat, remove in 2.5 */ data->val_out = mdio_read (dev, data->phy_id, data->reg_num); break; case SIOCSMIIREG: /* Write the specified MII register */ - case SIOCDEVPRIVATE+2: /* binary compat, remove in 2.5 */ if (!capable (CAP_NET_ADMIN)) { rc = -EPERM; break; @@ -2338,9 +2354,9 @@ static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) /* Check for autonegotiation on or reset. */ tp->medialock = (value & 0x9000) ? 0 : 1; if (tp->medialock) - tp->full_duplex = (value & 0x0100) ? 1 : 0; + tp->mii.full_duplex = (value & 0x0100) ? 1 : 0; break; - case 4: /* tp->advertising = value; */ break; + case 4: tp->mii.advertising = value; break; } } mdio_write(dev, data->phy_id, data->reg_num, data->val_in); diff --git a/drivers/net/Config.in b/drivers/net/Config.in index 100710061..eee781f4f 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -179,6 +179,7 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then dep_mbool ' Use PIO instead of MMIO' CONFIG_8139TOO_PIO $CONFIG_8139TOO dep_mbool ' Support for automatic channel equalization (EXPERIMENTAL)' CONFIG_8139TOO_TUNE_TWISTER $CONFIG_8139TOO $CONFIG_EXPERIMENTAL dep_mbool ' Support for older RTL-8129/8130 boards' CONFIG_8139TOO_8129 $CONFIG_8139TOO + dep_mbool ' Experiment for better RX reset (EXPERIMENTAL)' CONFIG_8139_NEW_RX_RESET $CONFIG_8139TOO $CONFIG_EXPERIMENTAL dep_tristate ' SiS 900/7016 PCI Fast Ethernet Adapter support' CONFIG_SIS900 $CONFIG_PCI dep_tristate ' SMC EtherPower II' CONFIG_EPIC100 $CONFIG_PCI dep_tristate ' Sundance Alta support' CONFIG_SUNDANCE $CONFIG_PCI diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 282671455..92693433d 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -68,7 +68,7 @@ obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o obj-$(CONFIG_PCNET32) += pcnet32.o obj-$(CONFIG_EEPRO100) += eepro100.o obj-$(CONFIG_TLAN) += tlan.o -obj-$(CONFIG_EPIC100) += epic100.o +obj-$(CONFIG_EPIC100) += epic100.o mii.o obj-$(CONFIG_SIS900) += sis900.o obj-$(CONFIG_DM9102) += dmfe.o obj-$(CONFIG_YELLOWFIN) += yellowfin.o @@ -77,7 +77,7 @@ obj-$(CONFIG_VETH) += veth.o obj-$(CONFIG_NATSEMI) += natsemi.o obj-$(CONFIG_NS83820) += ns83820.o obj-$(CONFIG_STNIC) += stnic.o 8390.o -obj-$(CONFIG_FEALNX) += fealnx.o +obj-$(CONFIG_FEALNX) += fealnx.o mii.o obj-$(CONFIG_TIGON3) += tg3.o ifeq ($(CONFIG_SK98LIN),y) @@ -88,7 +88,7 @@ ifeq ($(CONFIG_SKFP),y) obj-y += skfp/skfp.o endif -obj-$(CONFIG_VIA_RHINE) += via-rhine.o +obj-$(CONFIG_VIA_RHINE) += via-rhine.o mii.o obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o # @@ -101,7 +101,7 @@ obj-$(CONFIG_AIRONET4500_NONCS) += aironet4500_card.o obj-$(CONFIG_AIRONET4500_PROC) += aironet4500_proc.o obj-$(CONFIG_AIRONET4500_CS) += aironet4500_proc.o -obj-$(CONFIG_WINBOND_840) += winbond-840.o +obj-$(CONFIG_WINBOND_840) += winbond-840.o mii.o obj-$(CONFIG_SUNDANCE) += sundance.o obj-$(CONFIG_HAMACHI) += hamachi.o obj-$(CONFIG_NET) += Space.o setup.o net_init.o loopback.o @@ -165,8 +165,8 @@ obj-$(CONFIG_EL3) += 3c509.o obj-$(CONFIG_3C515) += 3c515.o obj-$(CONFIG_EEXPRESS) += eexpress.o obj-$(CONFIG_EEXPRESS_PRO) += eepro.o -obj-$(CONFIG_8139CP) += 8139cp.o -obj-$(CONFIG_8139TOO) += 8139too.o +obj-$(CONFIG_8139CP) += 8139cp.o mii.o +obj-$(CONFIG_8139TOO) += 8139too.o mii.o obj-$(CONFIG_ARLAN) += arlan.o arlan-proc.o obj-$(CONFIG_ZNET) += znet.o obj-$(CONFIG_LAN_SAA9730) += saa9730.o diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 894e65f71..e40731714 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -1135,12 +1135,14 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) /* fixme */ switch(cmd) { - case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + case SIOCGMIIPHY: /* Get the address of the PHY in use. */ data[0] = PHY_ADDRESS; - case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ + + case SIOCGMIIREG: /* Read the specified MII register. */ //data[3] = mdio_read(ioaddr, data[0], data[1]); return 0; - case SIOCDEVPRIVATE+2: /* Write the specified MII register */ + + case SIOCSMIIREG: /* Write the specified MII register */ if (!capable(CAP_NET_ADMIN)) return -EPERM; //mdio_write(ioaddr, data[0], data[1], data[2]); diff --git a/drivers/net/de4x5.c b/drivers/net/de4x5.c index 3af726812..4d79396ec 100644 --- a/drivers/net/de4x5.c +++ b/drivers/net/de4x5.c @@ -3645,7 +3645,7 @@ de4x5_alloc_rx_buff(struct net_device *dev, int index, int len) tmp = virt_to_bus(p->data); i = ((tmp + ALIGN) & ~ALIGN) - tmp; skb_reserve(p, i); - lp->rx_ring[index].buf = tmp + i; + lp->rx_ring[index].buf = cpu_to_le32(tmp + i); ret = lp->rx_skb[index]; lp->rx_skb[index] = p; @@ -5616,7 +5616,7 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (!capable(CAP_NET_ADMIN)) return -EPERM; omr = inl(DE4X5_OMR); omr &= ~OMR_PR; - outb(omr, DE4X5_OMR); + outl(omr, DE4X5_OMR); dev->flags &= ~IFF_PROMISC; break; diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 707adf273..efdffd676 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -15,18 +15,24 @@ 0.01 2001/05/03 Created DL2000-based linux driver 0.02 2001/05/21 Added VLAN and hardware checksum support. 1.00 2001/06/26 Added jumbo frame support. - 1.01 2001/08/21 Added two parameters, int_count and int_timeout. + 1.01 2001/08/21 Added two parameters, rx_coalesce and rx_timeout. 1.02 2001/10/08 Supported fiber media. Added flow control parameters. - 1.03 2001/10/12 Changed the default media to 1000mbps_fd for the - fiber devices. - 1.04 2001/11/08 Fixed a bug which Tx stop when a very busy case. -*/ + 1.03 2001/10/12 Changed the default media to 1000mbps_fd for + the fiber devices. + 1.04 2001/11/08 Fixed Tx stopped when tx very busy. + 1.05 2001/11/22 Fixed Tx stopped when unidirectional tx busy. + 1.06 2001/12/13 Fixed disconnect bug at 10Mbps mode. + Fixed tx_full flag incorrect. + Added tx_coalesce paramter. + 1.07 2002/01/03 Fixed miscount of RX frame error. + 1.08 2002/01/17 Fixed the multicast bug. + */ #include "dl2k.h" static char version[] __devinitdata = - KERN_INFO "D-Link DL2000-based linux driver v1.04 2001/11/08\n"; + KERN_INFO "D-Link DL2000-based linux driver v1.08 2002/01/17\n"; #define MAX_UNITS 8 static int mtu[MAX_UNITS]; @@ -36,11 +42,13 @@ static char *media[MAX_UNITS]; static int tx_flow[MAX_UNITS]; static int rx_flow[MAX_UNITS]; static int copy_thresh; -static int int_count; /* Rx frame count each interrupt */ -static int int_timeout; /* Rx DMA wait time in 64ns increments */ +static int rx_coalesce = DEFAULT_RXC; +static int rx_timeout = DEFAULT_RXT; +static int tx_coalesce = DEFAULT_TXC; MODULE_AUTHOR ("Edward Peng"); MODULE_DESCRIPTION ("D-Link DL2000-based Gigabit Ethernet Adapter"); +MODULE_LICENSE("GPL"); MODULE_PARM (mtu, "1-" __MODULE_STRING (MAX_UNITS) "i"); MODULE_PARM (media, "1-" __MODULE_STRING (MAX_UNITS) "s"); MODULE_PARM (vlan, "1-" __MODULE_STRING (MAX_UNITS) "i"); @@ -48,13 +56,16 @@ MODULE_PARM (jumbo, "1-" __MODULE_STRING (MAX_UNITS) "i"); MODULE_PARM (tx_flow, "1-" __MODULE_STRING (MAX_UNITS) "i"); MODULE_PARM (rx_flow, "1-" __MODULE_STRING (MAX_UNITS) "i"); MODULE_PARM (copy_thresh, "i"); -MODULE_PARM (int_count, "i"); -MODULE_PARM (int_timeout, "i"); +MODULE_PARM (rx_coalesce, "i"); /* Rx frame count each interrupt */ +MODULE_PARM (rx_timeout, "i"); /* Rx DMA wait time in 64ns increments */ +MODULE_PARM (tx_coalesce, "i"); /* HW xmit count each TxComplete [1-8] */ + /* Enable the default interrupts */ +#define DEFAULT_INTR (RxDMAComplete | HostError | IntRequested | TxComplete| \ + UpdateStats | LinkEvent) #define EnableInt() \ -writew(RxDMAComplete | HostError | IntRequested | TxComplete| \ - UpdateStats | LinkEvent, ioaddr + IntEnable) +writew(DEFAULT_INTR, ioaddr + IntEnable) static int max_intrloop = 50; static int multicast_filter_limit = 0x40; @@ -162,11 +173,11 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) np->speed = 10; np->full_duplex = 0; } else if (strcmp (media[card_idx], "1000mbps_fd") == 0 || - strcmp (media[card_idx], "5") == 0) { + strcmp (media[card_idx], "6") == 0) { np->speed=1000; np->full_duplex=1; } else if (strcmp (media[card_idx], "1000mbps_hd") == 0 || - strcmp (media[card_idx], "6") == 0) { + strcmp (media[card_idx], "5") == 0) { np->speed = 1000; np->full_duplex = 0; } else { @@ -175,7 +186,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) } if (jumbo[card_idx] != 0) { np->jumbo = 1; - dev->mtu = 9000; + dev->mtu = MAX_JUMBO; } else { np->jumbo = 0; if (mtu[card_idx] > 0 && mtu[card_idx] < PACKET_SIZE) @@ -183,14 +194,17 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) } np->vlan = (vlan[card_idx] > 0 && vlan[card_idx] < 4096) ? vlan[card_idx] : 0; - if (int_count != 0 && int_timeout != 0) { - np->int_count = int_count; - np->int_timeout = int_timeout; + if (rx_coalesce != 0 && rx_timeout != 0) { + np->rx_coalesce = rx_coalesce; + np->rx_timeout = rx_timeout; np->coalesce = 1; } np->tx_flow = (tx_flow[card_idx]) ? 1 : 0; np->rx_flow = (rx_flow[card_idx]) ? 1 : 0; - + if (tx_coalesce < 1) + tx_coalesce = 1; + if (tx_coalesce > 8) + tx_coalesce = 8; } dev->open = &rio_open; dev->hard_start_xmit = &start_xmit; @@ -201,8 +215,8 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) dev->tx_timeout = &tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; dev->change_mtu = &change_mtu; -#ifdef TX_HW_CHECKSUM - dev->features = NETIF_F_SG | NETIF_F_HW_CSUM; +#if 0 + dev->features = NETIF_F_IP_CSUM; #endif pci_set_drvdata (pdev, dev); @@ -326,7 +340,7 @@ parse_eeprom (struct net_device *dev) } /* Check CRC */ - crc = ~ether_crc_le(256-4, sromdata); + crc = ~ether_crc_le(256 - 4, sromdata); if (psrom->crc != crc) { printk (KERN_ERR "%s: EEPROM data CRC error.\n", dev->name); return -1; @@ -388,13 +402,12 @@ rio_open (struct net_device *dev) i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev); if (i) return i; - /* DebugCtrl bit 4, 5, 9 must set */ writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl); /* Jumbo frame */ if (np->jumbo != 0) - writew (9014, ioaddr + MaxFrameSize); + writew (MAX_JUMBO+14, ioaddr + MaxFrameSize); alloc_list (dev); @@ -404,7 +417,7 @@ rio_open (struct net_device *dev) set_multicast (dev); if (np->coalesce) { - writel (np->int_count | np->int_timeout << 16, + writel (np->rx_coalesce | np->rx_timeout << 16, ioaddr + RxDMAIntCtrl); } /* Set RIO to poll every N*320nsec. */ @@ -441,13 +454,31 @@ tx_timeout (struct net_device *dev) struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; - printk (KERN_WARNING "%s: Transmit timed out, TxStatus %4.4x.\n", + printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n", dev->name, readl (ioaddr + TxStatus)); + /* Free used tx skbuffs */ + for (; np->cur_tx - np->old_tx > 0; np->old_tx++) { + int entry = np->old_tx % TX_RING_SIZE; + struct sk_buff *skb; + + if (!(np->tx_ring[entry].status & TFDDone)) + break; + skb = np->tx_skbuff[entry]; + pci_unmap_single (np->pdev, + np->tx_ring[entry].fraginfo, + skb->len, PCI_DMA_TODEVICE); + dev_kfree_skb_irq (skb); + np->tx_skbuff[entry] = 0; + } dev->if_port = 0; dev->trans_start = jiffies; np->stats.tx_errors++; - if (!np->tx_full) + /* If the ring is no longer full, clear tx_full and + call netif_wake_queue() */ + if (np->tx_full && np->cur_tx - np->old_tx < TX_QUEUE_LEN - 1) { + np->tx_full = 0; netif_wake_queue (dev); + } } /* allocate and initialize Tx and Rx descriptors */ @@ -465,16 +496,19 @@ alloc_list (struct net_device *dev) /* Initialize Tx descriptors, TFDListPtr leaves in start_xmit(). */ for (i = 0; i < TX_RING_SIZE; i++) { np->tx_skbuff[i] = 0; - np->tx_ring[i].status = 0; + np->tx_ring[i].status = cpu_to_le64 (TFDDone); + np->tx_ring[i].next_desc = cpu_to_le64 (np->tx_ring_dma + + ((i+1)%TX_RING_SIZE) * + sizeof (struct + netdev_desc)); } /* Initialize Rx descriptors */ for (i = 0; i < RX_RING_SIZE; i++) { np->rx_ring[i].next_desc = cpu_to_le64 (np->rx_ring_dma + - ((i + - 1) % RX_RING_SIZE) * - sizeof (struct - netdev_desc)); + ((i + 1) % RX_RING_SIZE) * + sizeof (struct + netdev_desc)); np->rx_ring[i].status = 0; np->rx_ring[i].fraginfo = 0; np->rx_skbuff[i] = 0; @@ -522,13 +556,12 @@ start_xmit (struct sk_buff *skb, struct net_device *dev) entry = np->cur_tx % TX_RING_SIZE; np->tx_skbuff[entry] = skb; txdesc = &np->tx_ring[entry]; - txdesc->next_desc = 0; /* Set TFDDone to avoid TxDMA gather this descriptor */ txdesc->status = cpu_to_le64 (TFDDone); txdesc->status |= cpu_to_le64 (entry | WordAlignDisable | (1 << FragCountShift)); -#ifdef TX_HW_CHECKSUM +#if 0 if (skb->ip_summed == CHECKSUM_HW) { txdesc->status |= cpu_to_le64 (TCPChecksumEnable | UDPChecksumEnable | @@ -544,21 +577,13 @@ start_xmit (struct sk_buff *skb, struct net_device *dev) /* Send one packet each time at 10Mbps mode */ /* Tx coalescing loop do not exceed 8 */ - if (entry % 0x08 == 0 || np->speed == 10) + if (entry % tx_coalesce == 0 || np->speed == 10) txdesc->status |= cpu_to_le64 (TxIndicate); txdesc->fraginfo = cpu_to_le64 (pci_map_single (np->pdev, skb->data, skb->len, PCI_DMA_TODEVICE)); txdesc->fraginfo |= cpu_to_le64 (skb->len) << 48; - /* Chain the last descriptor's pointer to this one */ - if (np->last_tx) - np->last_tx->next_desc = cpu_to_le64 (np->tx_ring_dma + - entry * - sizeof (struct - netdev_desc)); - np->last_tx = txdesc; - /* Clear TFDDone, then TxDMA start to send this descriptor */ txdesc->status &= ~cpu_to_le64 (TFDDone); @@ -570,8 +595,10 @@ start_xmit (struct sk_buff *skb, struct net_device *dev) if (np->cur_tx - np->old_tx < TX_QUEUE_LEN - 1 && np->speed != 10) { /* do nothing */ } else { + spin_lock_irqsave(&np->lock, flags); np->tx_full = 1; netif_stop_queue (dev); + spin_unlock_irqrestore (&np->lock, flags); } /* The first TFDListPtr */ @@ -580,15 +607,15 @@ start_xmit (struct sk_buff *skb, struct net_device *dev) dev->base_addr + TFDListPtr0); writel (0, dev->base_addr + TFDListPtr1); } - - spin_lock_irqsave (&np->lock, flags); + if (np->old_tx > TX_RING_SIZE) { + spin_lock_irqsave (&np->lock, flags); tx_shift = TX_RING_SIZE; np->old_tx -= tx_shift; np->cur_tx -= tx_shift; + spin_unlock_irqrestore (&np->lock, flags); } - spin_unlock_irqrestore (&np->lock, flags); - + /* NETDEV WATCHDOG timer */ dev->trans_start = jiffies; return 0; @@ -605,33 +632,24 @@ rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs) ioaddr = dev->base_addr; np = dev->priv; - spin_lock (&np->lock); + spin_lock(&np->lock); while (1) { - int_status = readw (ioaddr + IntStatus) & - (HostError | TxComplete | IntRequested | - UpdateStats | LinkEvent | RxDMAComplete); - writew (int_status & (HostError | TxComplete | RxComplete | - IntRequested | UpdateStats | LinkEvent | - TxDMAComplete | RxDMAComplete | RFDListEnd - | RxDMAPriority), ioaddr + IntStatus); + int_status = readw (ioaddr + IntStatus); + writew (int_status, ioaddr + IntStatus); + int_status &= DEFAULT_INTR; if (int_status == 0) break; /* Processing received packets */ if (int_status & RxDMAComplete) receive_packet (dev); /* TxComplete interrupt */ - if (int_status & TxComplete || np->tx_full) { - int tx_status = readl (ioaddr + TxStatus); + if ((int_status & TxComplete) || np->tx_full) { + int tx_status; + tx_status = readl (ioaddr + TxStatus); if (tx_status & 0x01) tx_error (dev, tx_status); - /* Send one packet each time at 10Mbps mode */ - if (np->speed == 10) { - np->tx_full = 0; - netif_wake_queue (dev); - } - /* Free used tx skbuffs */ - for (; np->cur_tx - np->old_tx > 0; np->old_tx++) { + for (;np->cur_tx - np->old_tx > 0; np->old_tx++) { int entry = np->old_tx % TX_RING_SIZE; struct sk_buff *skb; @@ -648,9 +666,12 @@ rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs) /* If the ring is no longer full, clear tx_full and call netif_wake_queue() */ if (np->tx_full && np->cur_tx - np->old_tx < TX_QUEUE_LEN - 1) { - np->tx_full = 0; - netif_wake_queue (dev); + if (np->speed != 10 || int_status & TxComplete) { + np->tx_full = 0; + netif_wake_queue (dev); + } } + /* Handle uncommon events */ if (int_status & (IntRequested | HostError | LinkEvent | UpdateStats)) @@ -665,7 +686,7 @@ rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs) break; } } - spin_unlock (&np->lock); + spin_unlock(&np->lock); } static void @@ -741,7 +762,7 @@ tx_error (struct net_device *dev, int tx_status) np->stats.collisions++; #endif - /* Restart the Tx. */ + /* Restart the Tx */ writel (readw (dev->base_addr + MACCtrl) | TxEnable, ioaddr + MACCtrl); } @@ -782,7 +803,7 @@ receive_packet (struct net_device *dev) if (frame_status & 0x00300000) np->stats.rx_length_errors++; if (frame_status & 0x00010000) - np->stats.rx_fifo_errors++; + np->stats.rx_fifo_errors++; if (frame_status & 0x00060000) np->stats.rx_frame_errors++; if (frame_status & 0x00080000) @@ -807,7 +828,7 @@ receive_packet (struct net_device *dev) skb_put (skb, pkt_len); } skb->protocol = eth_type_trans (skb, dev); -#ifdef RX_HW_CHECKSUM +#if 0 /* Checksum done by hw, but csum value unavailable. */ if (!(frame_status & (TCPError | UDPError | IPError))) { skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -898,7 +919,7 @@ rio_error (struct net_device *dev, int int_status) /* PCI Error, a catastronphic error related to the bus interface occurs, set GlobalReset and HostReset to reset. */ if (int_status & HostError) { - printk (KERN_ERR "%s: PCI Error! IntStatus %4.4x.\n", + printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n", dev->name, int_status); writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2); mdelay (500); @@ -913,8 +934,8 @@ get_stats (struct net_device *dev) u16 temp1; u16 temp2; int i; - /* All statistics registers need to acknowledge, - else overflow could cause some problem */ + /* All statistics registers need to be acknowledged, + else statistic overflow could cause problems */ np->stats.rx_packets += readl (ioaddr + FramesRcvOk); np->stats.tx_packets += readl (ioaddr + FramesXmtOk); np->stats.rx_bytes += readl (ioaddr + OctetRcvOk); @@ -931,11 +952,11 @@ get_stats (struct net_device *dev) readl (ioaddr + FramesWDeferredXmt) + temp2; /* detailed rx_error */ - np->stats.rx_length_errors += readw (ioaddr + InRangeLengthErrors) + - readw (ioaddr + FrameTooLongErrors); + np->stats.rx_length_errors += readw (ioaddr + FrameTooLongErrors); np->stats.rx_crc_errors += readw (ioaddr + FrameCheckSeqError); /* Clear all other statistic register. */ + readw (ioaddr + InRangeLengthErrors); readw (ioaddr + MacControlFramesXmtd); readw (ioaddr + BcstFramesXmtdOk); readl (ioaddr + McstFramesXmtdOk); @@ -960,7 +981,7 @@ int change_mtu (struct net_device *dev, int new_mtu) { struct netdev_private *np = dev->priv; - int max = (np->jumbo) ? 9000 : 1536; + int max = (np->jumbo) ? MAX_JUMBO : 1536; if ((new_mtu < 68) || (new_mtu > max)) { return -EINVAL; @@ -978,36 +999,42 @@ set_multicast (struct net_device *dev) u32 hash_table[2]; u16 rx_mode = 0; int i; + int bit; + int index, crc; struct dev_mc_list *mclist; struct netdev_private *np = dev->priv; - - /* Default: receive broadcast and unicast */ - rx_mode = ReceiveBroadcast | ReceiveUnicast; + + hash_table[0] = hash_table[1] = 0; + /* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */ + hash_table[1] |= 0x02000000; if (dev->flags & IFF_PROMISC) { /* Receive all frames promiscuously. */ - rx_mode |= ReceiveAllFrames; - } else if (((dev->flags & IFF_MULTICAST) - && (dev->mc_count > multicast_filter_limit)) - || (dev->flags & IFF_ALLMULTI)) { + rx_mode = ReceiveAllFrames; + } else if ((dev->flags & IFF_ALLMULTI) || + (dev->mc_count > multicast_filter_limit)) { /* Receive broadcast and multicast frames */ - rx_mode |= ReceiveBroadcast | ReceiveMulticast | ReceiveUnicast; - } else if ((dev->flags & IFF_MULTICAST) & (dev->mc_count > 0)) { - /* Receive broadcast frames and multicast frames filtering by Hashtable */ - rx_mode |= + rx_mode = ReceiveBroadcast | ReceiveMulticast | ReceiveUnicast; + } else if (dev->mc_count > 0) { + /* Receive broadcast frames and multicast frames filtering + by Hashtable */ + rx_mode = ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast; + for (i=0, mclist = dev->mc_list; mclist && i < dev->mc_count; + i++, mclist=mclist->next) { + crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr); + for (index=0, bit=0; bit<6; bit++, crc<<=1) { + if (crc & 0x80000000) index |= 1 << bit; + } + hash_table[index / 32] |= (1 << (index % 32)); + } + } else { + rx_mode = ReceiveBroadcast | ReceiveUnicast; } if (np->vlan) { /* ReceiveVLANMatch field in ReceiveMode */ rx_mode |= ReceiveVLANMatch; } - hash_table[0] = 0x00000000; - hash_table[1] = 0x00000000; - for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; - i++, mclist = mclist->next) { - set_bit (ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f, - hash_table); - } writel (hash_table[0], ioaddr + HashTable0); writel (hash_table[1], ioaddr + HashTable1); writew (rx_mode, ioaddr + ReceiveMode); @@ -1677,8 +1704,9 @@ module_exit (rio_exit); Compile command: -gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -c dl2x.c +gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -c dl2k.c Read Documentation/networking/dl2k.txt for details. */ + diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h index 62559339f..0ee3bbb81 100644 --- a/drivers/net/dl2k.h +++ b/drivers/net/dl2k.h @@ -34,7 +34,7 @@ #include <linux/spinlock.h> #include <linux/time.h> #define TX_RING_SIZE 128 -#define TX_QUEUE_LEN 96 /* Limit ring entries actually used. */ +#define TX_QUEUE_LEN 120 /* Limit ring entries actually used. */ #define RX_RING_SIZE 128 #define TX_TOTAL_SIZE TX_RING_SIZE*sizeof(struct netdev_desc) #define RX_TOTAL_SIZE RX_RING_SIZE*sizeof(struct netdev_desc) @@ -183,12 +183,12 @@ enum IntStatus_bits { /* Bits in the ReceiveMode register. */ enum ReceiveMode_bits { - ReceiveIPMulticast = 0x0020, - ReceiveMulticastHash = 0x0010, - ReceiveAllFrames = 0x0008, - ReceiveBroadcast = 0x0004, - ReceiveMulticast = 0x0002, ReceiveUnicast = 0x0001, + ReceiveMulticast = 0x0002, + ReceiveBroadcast = 0x0004, + ReceiveAllFrames = 0x0008, + ReceiveMulticastHash = 0x0010, + ReceiveIPMulticast = 0x0020, ReceiveVLANMatch = 0x0100, ReceiveVLANHash = 0x0200, }; @@ -650,20 +650,20 @@ struct netdev_private { struct pci_dev *pdev; spinlock_t lock; struct net_device_stats stats; - unsigned int rx_buf_sz; /* Based on MTU+slack. */ - unsigned int speed; /* Operating speed */ - unsigned int vlan; /* VLAN Id */ - unsigned int chip_id; /* PCI table chip id */ - unsigned int int_count; /* Maximum frames each RxDMAComplete intr */ - unsigned int int_timeout; /* Wait time between RxDMAComplete intr */ - unsigned int tx_full:1; /* The Tx queue is full. */ + unsigned int rx_buf_sz; /* Based on MTU+slack. */ + unsigned int speed; /* Operating speed */ + unsigned int vlan; /* VLAN Id */ + unsigned int chip_id; /* PCI table chip id */ + unsigned int rx_coalesce; /* Maximum frames each RxDMAComplete intr */ + unsigned int rx_timeout; /* Wait time between RxDMAComplete intr */ + unsigned int tx_full:1; /* The Tx queue is full. */ unsigned int full_duplex:1; /* Full-duplex operation requested. */ unsigned int an_enable:2; /* Auto-Negotiated Enable */ unsigned int jumbo:1; /* Jumbo frame enable */ unsigned int coalesce:1; /* Rx coalescing enable */ unsigned int tx_flow:1; /* Tx flow control enable */ unsigned int rx_flow:1; /* Rx flow control enable */ - unsigned int phy_media:1; /* 1: fiber, 0: copper */ + unsigned int phy_media:1; /* 1: fiber, 0: copper */ struct netdev_desc *last_tx; /* Last Tx descriptor used. */ unsigned long cur_rx, old_rx; /* Producer/consumer ring indices */ unsigned long cur_tx, old_tx; @@ -698,7 +698,12 @@ static struct pci_device_id rio_pci_tbl[] __devinitdata = { MODULE_DEVICE_TABLE (pci, rio_pci_tbl); #define TX_TIMEOUT (4*HZ) #define PACKET_SIZE 1536 +#define MAX_JUMBO 8000 #define RIO_IO_SIZE 340 +#define DEFAULT_RXC 5 +#define DEFAULT_RXT 750 +#define DEFAULT_TXC 1 +#define MAX_TXC 8 #ifdef RIO_DEBUG #define DEBUG_TFD_DUMP(x) debug_tfd_dump(x) #define DEBUG_RFD_DUMP(x,flag) debug_rfd_dump(x,flag) diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 7c30e7750..2805d9d42 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -53,11 +53,18 @@ LK1.1.10: * revert MII transceiver init change (jgarzik) + LK1.1.11: + * implement ETHTOOL_[GS]SET, _NWAY_RST, _[GS]MSGLVL, _GLINK (jgarzik) + * replace some MII-related magic numbers with constants + + LK1.1.12: + * fix power-up sequence + */ #define DRV_NAME "epic100" -#define DRV_VERSION "1.11+LK1.1.10" -#define DRV_RELDATE "July 6, 2001" +#define DRV_VERSION "1.11+LK1.1.12" +#define DRV_RELDATE "Jan 18, 2002" /* The user-configurable values. @@ -318,12 +325,9 @@ struct epic_private { /* Ring pointers. */ spinlock_t lock; /* Group with Tx control cache line. */ unsigned int cur_tx, dirty_tx; - struct descriptor *last_tx_desc; unsigned int cur_rx, dirty_rx; unsigned int rx_buf_sz; /* Based on MTU+slack. */ - struct descriptor *last_rx_desc; - long last_rx_time; /* Last Rx, in jiffies. */ struct pci_dev *pci_dev; /* PCI bus location. */ int chip_id, chip_flags; @@ -335,13 +339,9 @@ struct epic_private { signed char phys[4]; /* MII device addresses. */ u16 advertising; /* NWay media advertisement */ int mii_phy_cnt; + struct mii_if_info mii; unsigned int tx_full:1; /* The Tx queue is full. */ - unsigned int full_duplex:1; /* Current duplex setting. */ - unsigned int duplex_lock:1; /* Duplex forced by the user. */ unsigned int default_port:4; /* Last dev->if_port value. */ - unsigned int media2:4; /* Secondary monitored media port. */ - unsigned int medialock:1; /* Don't sense media type. */ - unsigned int mediasense:1; /* Media sensing in progress. */ }; static int epic_open(struct net_device *dev); @@ -420,6 +420,9 @@ static int __devinit epic_init_one (struct pci_dev *pdev, pci_set_drvdata(pdev, dev); ep = dev->priv; + ep->mii.dev = dev; + ep->mii.mdio_read = mdio_read; + ep->mii.mdio_write = mdio_write; ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma); if (!ring_space) @@ -481,7 +484,7 @@ static int __devinit epic_init_one (struct pci_dev *pdev, { int phy, phy_idx = 0; for (phy = 1; phy < 32 && phy_idx < sizeof(ep->phys); phy++) { - int mii_status = mdio_read(dev, phy, 1); + int mii_status = mdio_read(dev, phy, MII_BMSR); if (mii_status != 0xffff && mii_status != 0x0000) { ep->phys[phy_idx++] = phy; printk(KERN_INFO DRV_NAME "(%s): MII transceiver #%d control " @@ -492,16 +495,17 @@ static int __devinit epic_init_one (struct pci_dev *pdev, ep->mii_phy_cnt = phy_idx; if (phy_idx != 0) { phy = ep->phys[0]; - ep->advertising = mdio_read(dev, phy, 4); + ep->mii.advertising = mdio_read(dev, phy, MII_ADVERTISE); printk(KERN_INFO DRV_NAME "(%s): Autonegotiation advertising %4.4x link " "partner %4.4x.\n", - pdev->slot_name, ep->advertising, mdio_read(dev, phy, 5)); + pdev->slot_name, ep->mii.advertising, mdio_read(dev, phy, 5)); } else if ( ! (ep->chip_flags & NO_MII)) { printk(KERN_WARNING DRV_NAME "(%s): ***WARNING***: No MII transceiver found!\n", pdev->slot_name); /* Use the known PHY address of the EPII. */ ep->phys[0] = 3; } + ep->mii.phy_id = ep->phys[0]; } /* Turn off the MII xcvr (175 only!), leave the chip in low-power mode. */ @@ -511,13 +515,11 @@ static int __devinit epic_init_one (struct pci_dev *pdev, /* The lower four bits are the media type. */ if (duplex) { - ep->duplex_lock = ep->full_duplex = 1; + ep->mii.duplex_lock = ep->mii.full_duplex = 1; printk(KERN_INFO DRV_NAME "(%s): Forced full duplex operation requested.\n", pdev->slot_name); } dev->if_port = ep->default_port = option; - if (ep->default_port) - ep->medialock = 1; /* The Epic-specific entries in the device structure. */ dev->open = &epic_open; @@ -676,9 +678,8 @@ static int epic_open(struct net_device *dev) required by the details of which bits are reset and the transceiver wiring on the Ositech CardBus card. */ -#if 0 - outl(dev->if_port == 1 ? 0x13 : 0x12, ioaddr + MIICfg); -#endif + + outl(0x12, ioaddr + MIICfg); if (ep->chip_flags & MII_PWRDWN) outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); @@ -700,29 +701,29 @@ static int epic_open(struct net_device *dev) if (media2miictl[dev->if_port & 15]) { if (ep->mii_phy_cnt) - mdio_write(dev, ep->phys[0], 0, media2miictl[dev->if_port&15]); + mdio_write(dev, ep->phys[0], MII_BMCR, media2miictl[dev->if_port&15]); if (dev->if_port == 1) { if (debug > 1) printk(KERN_INFO "%s: Using the 10base2 transceiver, MII " "status %4.4x.\n", - dev->name, mdio_read(dev, ep->phys[0], 1)); + dev->name, mdio_read(dev, ep->phys[0], MII_BMSR)); } } else { - int mii_reg5 = mdio_read(dev, ep->phys[0], 5); - if (mii_reg5 != 0xffff) { - if ((mii_reg5 & 0x0100) || (mii_reg5 & 0x01C0) == 0x0040) - ep->full_duplex = 1; - else if (! (mii_reg5 & 0x4000)) - mdio_write(dev, ep->phys[0], 0, 0x1200); + int mii_lpa = mdio_read(dev, ep->phys[0], MII_LPA); + if (mii_lpa != 0xffff) { + if ((mii_lpa & LPA_100FULL) || (mii_lpa & 0x01C0) == LPA_10FULL) + ep->mii.full_duplex = 1; + else if (! (mii_lpa & LPA_LPACK)) + mdio_write(dev, ep->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART); if (debug > 1) printk(KERN_INFO "%s: Setting %s-duplex based on MII xcvr %d" " register read of %4.4x.\n", dev->name, - ep->full_duplex ? "full" : "half", - ep->phys[0], mii_reg5); + ep->mii.full_duplex ? "full" : "half", + ep->phys[0], mii_lpa); } } - outl(ep->full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl); + outl(ep->mii.full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl); outl(ep->rx_ring_dma, ioaddr + PRxCDAR); outl(ep->tx_ring_dma, ioaddr + PTxCDAR); @@ -742,7 +743,7 @@ static int epic_open(struct net_device *dev) printk(KERN_DEBUG "%s: epic_open() ioaddr %lx IRQ %d status %4.4x " "%s-duplex.\n", dev->name, ioaddr, dev->irq, (int)inl(ioaddr + GENCTL), - ep->full_duplex ? "full" : "half"); + ep->mii.full_duplex ? "full" : "half"); /* Set the timer to switch to check for link beat and perhaps switch to an alternate media type. */ @@ -811,7 +812,7 @@ static void epic_restart(struct net_device *dev) ep->tx_threshold = TX_FIFO_THRESH; outl(ep->tx_threshold, ioaddr + TxThresh); - outl(ep->full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl); + outl(ep->mii.full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl); outl(ep->rx_ring_dma + (ep->cur_rx%RX_RING_SIZE)* sizeof(struct epic_rx_desc), ioaddr + PRxCDAR); outl(ep->tx_ring_dma + (ep->dirty_tx%TX_RING_SIZE)* @@ -837,20 +838,20 @@ static void check_media(struct net_device *dev) { struct epic_private *ep = dev->priv; long ioaddr = dev->base_addr; - int mii_reg5 = ep->mii_phy_cnt ? mdio_read(dev, ep->phys[0], 5) : 0; - int negotiated = mii_reg5 & ep->advertising; + int mii_lpa = ep->mii_phy_cnt ? mdio_read(dev, ep->phys[0], MII_LPA) : 0; + int negotiated = mii_lpa & ep->mii.advertising; int duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040; - if (ep->duplex_lock) + if (ep->mii.duplex_lock) return; - if (mii_reg5 == 0xffff) /* Bogus read */ + if (mii_lpa == 0xffff) /* Bogus read */ return; - if (ep->full_duplex != duplex) { - ep->full_duplex = duplex; + if (ep->mii.full_duplex != duplex) { + ep->mii.full_duplex = duplex; printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d link" " partner capability of %4.4x.\n", dev->name, - ep->full_duplex ? "full" : "half", ep->phys[0], mii_reg5); - outl(ep->full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl); + ep->mii.full_duplex ? "full" : "half", ep->phys[0], mii_lpa); + outl(ep->mii.full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl); } } @@ -914,7 +915,6 @@ static void epic_init_ring(struct net_device *dev) ep->lock = (spinlock_t) SPIN_LOCK_UNLOCKED; ep->dirty_tx = ep->cur_tx = 0; ep->cur_rx = ep->dirty_rx = 0; - ep->last_rx_time = jiffies; ep->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32); /* Initialize all Rx descriptors. */ @@ -1351,17 +1351,66 @@ static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) return -EFAULT; switch (ethcmd) { - case ETHTOOL_GDRVINFO: - { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, np->pci_dev->slot_name); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + strcpy (info.bus_info, np->pci_dev->slot_name); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get settings */ + case ETHTOOL_GSET: { + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + spin_lock_irq(&np->lock); + mii_ethtool_gset(&np->mii, &ecmd); + spin_unlock_irq(&np->lock); + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) + return -EFAULT; + return 0; + } + /* set settings */ + case ETHTOOL_SSET: { + int r; + struct ethtool_cmd ecmd; + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) + return -EFAULT; + spin_lock_irq(&np->lock); + r = mii_ethtool_sset(&np->mii, &ecmd); + spin_unlock_irq(&np->lock); + return r; + } + /* restart autonegotiation */ + case ETHTOOL_NWAY_RST: { + return mii_nway_restart(&np->mii); + } + /* get link status */ + case ETHTOOL_GLINK: { + struct ethtool_value edata = {ETHTOOL_GLINK}; + edata.data = mii_link_ok(&np->mii); + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + debug = edata.data; + return 0; + } default: break; } @@ -1380,12 +1429,10 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = ep->phys[0] & 0x1f; /* Fall Through */ case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ if (! netif_running(dev)) { outl(0x0200, ioaddr + GENCTL); outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); @@ -1400,7 +1447,6 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return 0; case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ if (!capable(CAP_NET_ADMIN)) return -EPERM; if (! netif_running(dev)) { @@ -1412,11 +1458,11 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) switch (data->reg_num) { case 0: /* Check for autonegotiation on or reset. */ - ep->duplex_lock = (value & 0x9000) ? 0 : 1; - if (ep->duplex_lock) - ep->full_duplex = (value & 0x0100) ? 1 : 0; + ep->mii.duplex_lock = (value & 0x9000) ? 0 : 1; + if (ep->mii.duplex_lock) + ep->mii.full_duplex = (value & 0x0100) ? 1 : 0; break; - case 4: ep->advertising = value; break; + case 4: ep->mii.advertising = value; break; } /* Perhaps check_duplex(dev), depending on chip semantics. */ } diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index 66bde2a1c..473e59d9b 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -15,8 +15,19 @@ Support information and updates available at http://www.scyld.com/network/pci-skeleton.html + + Linux kernel updates: + + Version 2.51, Nov 17, 2001 (jgarzik): + - Add ethtool support + - Replace some MII-related magic numbers with constants + */ +#define DRV_NAME "fealnx" +#define DRV_VERSION "2.51" +#define DRV_RELDATE "Nov-17-2001" + static int debug; /* 1-> print debug message */ static int max_interrupt_work = 20; @@ -72,14 +83,16 @@ static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; #include <linux/skbuff.h> #include <linux/init.h> #include <linux/mii.h> +#include <linux/ethtool.h> #include <linux/crc32.h> #include <asm/processor.h> /* Processor type for cache alignment. */ #include <asm/bitops.h> #include <asm/io.h> +#include <asm/uaccess.h> /* These identify the driver base version and may not be removed. */ static char version[] __devinitdata = -KERN_INFO "fealnx.c:v2.50 1/17/2001\n"; +KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "\n"; /* This driver was written to use PCI memory space, however some x86 systems @@ -380,6 +393,8 @@ struct netdev_private { dma_addr_t rx_ring_dma; dma_addr_t tx_ring_dma; + spinlock_t lock; + struct net_device_stats stats; /* Media monitoring timer. */ @@ -404,19 +419,17 @@ struct netdev_private { unsigned int linkok; unsigned int line_speed; unsigned int duplexmode; - unsigned int full_duplex:1; /* Full-duplex operation requested. */ - unsigned int duplex_lock:1; - unsigned int medialock:1; /* Do not sense media. */ unsigned int default_port:4; /* Last dev->if_port value. */ unsigned int PHYType; /* MII transceiver section. */ int mii_cnt; /* MII device addresses. */ unsigned char phys[2]; /* MII device addresses. */ + struct mii_if_info mii; }; -static unsigned int mdio_read(struct net_device *dev, int phy_id, int location); +static int mdio_read(struct net_device *dev, int phy_id, int location); static void mdio_write(struct net_device *dev, int phy_id, int location, int value); static int netdev_open(struct net_device *dev); static void getlinktype(struct net_device *dev); @@ -539,9 +552,13 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, /* Make certain the descriptor lists are aligned. */ np = dev->priv; + spin_lock_init(&np->lock); np->pci_dev = pdev; np->flags = skel_netdrv_tbl[chip_id].flags; pci_set_drvdata(pdev, dev); + np->mii.dev = dev; + np->mii.mdio_read = mdio_read; + np->mii.mdio_write = mdio_write; ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma); if (!ring_space) { @@ -606,6 +623,7 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, else np->PHYType = OtherPHY; } + np->mii.phy_id = np->phys[0]; if (dev->mem_start) option = dev->mem_start; @@ -613,17 +631,14 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, /* The lower four bits are the media type. */ if (option > 0) { if (option & 0x200) - np->full_duplex = 1; + np->mii.full_duplex = 1; np->default_port = option & 15; - - if (np->default_port) - np->medialock = 1; } if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0) - np->full_duplex = full_duplex[card_idx]; + np->mii.full_duplex = full_duplex[card_idx]; - if (np->full_duplex) { + if (np->mii.full_duplex) { printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name); /* 89/6/13 add, (begin) */ // if (np->PHYType==MarvellPHY) @@ -636,10 +651,10 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, } /* 89/6/13 add, (end) */ if (np->flags == HAS_MII_XCVR) - mdio_write(dev, np->phys[0], 4, 0x141); + mdio_write(dev, np->phys[0], MII_ADVERTISE, ADVERTISE_FULL); else - writel(0x141, dev->base_addr + ANARANLPAR); - np->duplex_lock = 1; + writel(ADVERTISE_FULL, dev->base_addr + ANARANLPAR); + np->mii.duplex_lock = 1; } /* The chip-specific entries in the device structure. */ @@ -787,7 +802,7 @@ static ulong m80x_send_cmd_to_phy(long miiport, int opcode, int phyad, int regad } -static unsigned int mdio_read(struct net_device *dev, int phyad, int regad) +static int mdio_read(struct net_device *dev, int phyad, int regad) { long miiport = dev->base_addr + MANAGEMENT; ulong miir; @@ -821,7 +836,7 @@ static unsigned int mdio_read(struct net_device *dev, int phyad, int regad) miir &= ~MASK_MIIR_MII_MDC; writel(miir, miiport); - return data; + return data & 0xffff; } @@ -941,7 +956,7 @@ static int netdev_open(struct net_device *dev) // 89/9/1 modify, // np->crvalue = 0x00e40001; /* tx store and forward, tx/rx enable */ np->crvalue |= 0x00e40001; /* tx store and forward, tx/rx enable */ - np->full_duplex = np->duplex_lock; + np->mii.full_duplex = np->mii.duplex_lock; getlinkstatus(dev); if (np->linkok) getlinktype(dev); @@ -990,7 +1005,7 @@ static void getlinkstatus(struct net_device *dev) } } else { for (i = 0; i < DelayTime; ++i) { - if (mdio_read(dev, np->phys[0], 1) & 0x4) { + if (mdio_read(dev, np->phys[0], MII_BMSR) & BMSR_LSTATUS) { np->linkok = 1; return; } @@ -1475,7 +1490,7 @@ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) np->stats.tx_window_errors++; if (tx_status & UDF) np->stats.tx_fifo_errors++; - if ((tx_status & HF) && np->full_duplex == 0) + if ((tx_status & HF) && np->mii.full_duplex == 0) np->stats.tx_heartbeat_errors++; #ifdef ETHER_STATS @@ -1751,24 +1766,100 @@ static void set_rx_mode(struct net_device *dev) writel(np->crvalue, ioaddr + TCRRCR); } +static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + struct netdev_private *np = dev->priv; + u32 ethcmd; + + if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + strcpy (info.bus_info, np->pci_dev->slot_name); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get settings */ + case ETHTOOL_GSET: { + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + spin_lock_irq(&np->lock); + mii_ethtool_gset(&np->mii, &ecmd); + spin_unlock_irq(&np->lock); + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) + return -EFAULT; + return 0; + } + /* set settings */ + case ETHTOOL_SSET: { + int r; + struct ethtool_cmd ecmd; + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) + return -EFAULT; + spin_lock_irq(&np->lock); + r = mii_ethtool_sset(&np->mii, &ecmd); + spin_unlock_irq(&np->lock); + return r; + } + /* restart autonegotiation */ + case ETHTOOL_NWAY_RST: { + return mii_nway_restart(&np->mii); + } + /* get link status */ + case ETHTOOL_GLINK: { + struct ethtool_value edata = {ETHTOOL_GLINK}; + edata.data = mii_link_ok(&np->mii); + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + debug = edata.data; + return 0; + } + default: + break; + } + + return -EOPNOTSUPP; +} + static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data; switch (cmd) { + case SIOCETHTOOL: + return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = ((struct netdev_private *) dev->priv)->phys[0] & 0x1f; /* Fall Through */ case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f); return 0; case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ if (!capable(CAP_NET_ADMIN)) return -EPERM; mdio_write(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in); diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 0b3b5e23c..45c3021f8 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -1941,17 +1941,14 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case SIOCETHTOOL: return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = ((struct hamachi_private *)dev->priv)->phys[0] & 0x1f; /* Fall Through */ case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ data->val_out = mdio_read(ioaddr, data->phy_id & 0x1f, data->reg_num & 0x1f); return 0; case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ /* TODO: Check the sequencing of this. Might need to stop and * restart Rx and Tx engines. -KDU */ diff --git a/drivers/net/mii.c b/drivers/net/mii.c index 78afc6aa5..bfed2a70a 100644 --- a/drivers/net/mii.c +++ b/drivers/net/mii.c @@ -168,6 +168,10 @@ int mii_nway_restart (struct mii_if_info *mii) return r; } +MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>"); +MODULE_DESCRIPTION ("MII hardware support library"); +MODULE_LICENSE("GPL"); + EXPORT_SYMBOL(mii_link_ok); EXPORT_SYMBOL(mii_nway_restart); EXPORT_SYMBOL(mii_ethtool_gset); diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 8a1187855..1016a2110 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -1,4 +1,4 @@ -#define VERSION "0.13" +#define VERSION "0.14" /* ns83820.c by Benjamin LaHaise <bcrl@redhat.com> * * $Revision: 1.34.2.8 $ @@ -45,6 +45,7 @@ * 0.12 - add statistics counters * - add allmulti/promisc support * 20011009 0.13 - hotplug support, other smaller pci api cleanups + * 20011117 0.14 - ethtool GDRVINFO, GLINK support * * Driver Overview * =============== @@ -86,9 +87,11 @@ #include <linux/in.h> /* for IPPROTO_... */ #include <linux/eeprom.h> #include <linux/compiler.h> +#include <linux/ethtool.h> //#include <linux/skbrefill.h> #include <asm/io.h> +#include <asm/uaccess.h> /* Dprintk is used for more interesting debug events */ #undef Dprintk @@ -1007,6 +1010,59 @@ static struct net_device_stats *ns83820_get_stats(struct net_device *_dev) return &dev->stats; } +static int ns83820_ethtool_ioctl (struct ns83820 *dev, void *useraddr) +{ + u32 ethcmd; + + if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GDRVINFO: + { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, "ns83820"); + strcpy (info.version, VERSION); + strcpy (info.bus_info, dev->pci_dev->slot_name); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get link status */ + case ETHTOOL_GLINK: { + struct ethtool_value edata = {ETHTOOL_GLINK}; + u32 cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY; + + if (cfg & CFG_LNKSTS) + edata.data = 1; + else + edata.data = 0; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + + default: + break; + } + + return -EOPNOTSUPP; +} + +static int ns83820_ioctl(struct net_device *_dev, struct ifreq *rq, int cmd) +{ + struct ns83820 *dev = _dev->priv; + + switch(cmd) { + case SIOCETHTOOL: + return ns83820_ethtool_ioctl(dev, (void *) rq->ifr_data); + + default: + return -EOPNOTSUPP; + } +} + static void ns83820_irq(int foo, void *data, struct pt_regs *regs) { struct ns83820 *dev = data; @@ -1294,6 +1350,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ dev->net_dev.get_stats = ns83820_get_stats; dev->net_dev.change_mtu = ns83820_change_mtu; dev->net_dev.set_multicast_list = ns83820_set_multicast; + dev->net_dev.do_ioctl = ns83820_ioctl; //FIXME: dev->net_dev.tx_timeout = ns83820_tx_timeout; pci_set_drvdata(pci_dev, dev); diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index 6743227a3..957b71b82 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c @@ -834,7 +834,7 @@ static int __devinit netdrv_init_one (struct pci_dev *pdev, printk (KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name); - mdio_write (dev, tp->phys[0], 4, 0x141); + mdio_write (dev, tp->phys[0], MII_ADVERTISE, ADVERTISE_FULL); tp->duplex_lock = 1; } @@ -1235,20 +1235,20 @@ static void netdrv_timer (unsigned long data) struct netdrv_private *tp = dev->priv; void *ioaddr = tp->mmio_addr; int next_tick = 60 * HZ; - int mii_reg5; + int mii_lpa; - mii_reg5 = mdio_read (dev, tp->phys[0], 5); + mii_lpa = mdio_read (dev, tp->phys[0], MII_LPA); - if (!tp->duplex_lock && mii_reg5 != 0xffff) { - int duplex = (mii_reg5 & 0x0100) - || (mii_reg5 & 0x01C0) == 0x0040; + if (!tp->duplex_lock && mii_lpa != 0xffff) { + int duplex = (mii_lpa & LPA_100FULL) + || (mii_lpa & 0x01C0) == 0x0040; if (tp->full_duplex != duplex) { tp->full_duplex = duplex; printk (KERN_INFO "%s: Setting %s-duplex based on MII #%d link" " partner ability of %4.4x.\n", dev->name, tp->full_duplex ? "full" : "half", - tp->phys[0], mii_reg5); + tp->phys[0], mii_lpa); NETDRV_W8 (Cfg9346, Cfg9346_Unlock); NETDRV_W8 (Config1, tp->full_duplex ? 0x60 : 0x20); NETDRV_W8 (Cfg9346, Cfg9346_Lock); @@ -1793,19 +1793,16 @@ static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) switch (cmd) { case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = tp->phys[0] & 0x3f; /* Fall Through */ case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ spin_lock_irqsave (&tp->lock, flags); data->val_out = mdio_read (dev, data->phy_id & 0x1f, data->reg_num & 0x1f); spin_unlock_irqrestore (&tp->lock, flags); break; case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ if (!capable (CAP_NET_ADMIN)) { rc = -EPERM; break; diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 2098eab9c..a782e5d0d 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -17,6 +17,9 @@ ======================================================================*/ +#define DRV_NAME "3c589_cs" +#define DRV_VERSION "1.162" + #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> @@ -28,6 +31,9 @@ #include <linux/interrupt.h> #include <linux/in.h> #include <linux/delay.h> +#include <linux/ethtool.h> + +#include <asm/uaccess.h> #include <asm/io.h> #include <asm/system.h> #include <asm/bitops.h> @@ -134,7 +140,7 @@ MODULE_PARM(irq_list, "1-4i"); INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = -"3c589_cs.c 1.162 2001/10/13 00:08:50 (David Hinds)"; +DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -159,6 +165,7 @@ static int el3_rx(struct net_device *dev); static int el3_close(struct net_device *dev); static void el3_tx_timeout(struct net_device *dev); static void set_multicast_list(struct net_device *dev); +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); static dev_info_t dev_info = "3c589_cs"; @@ -249,7 +256,8 @@ static dev_link_t *tc589_attach(void) dev->tx_timeout = el3_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; #endif - + dev->do_ioctl = netdev_ioctl; + /* Register with Card Services */ link->next = dev_list; dev_list = link; @@ -640,6 +648,71 @@ static void tc589_reset(struct net_device *dev) | AdapterFailure, ioaddr + EL3_CMD); } +static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + /* dev_ioctl() in ../../net/core/dev.c has already checked + capable(CAP_NET_ADMIN), so don't bother with that here. */ + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + +#ifdef PCMCIA_DEBUG + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = pc_debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + pc_debug = edata.data; + return 0; + } +#endif + + default: + break; + } + + return -EOPNOTSUPP; +} + +static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) +{ + int rc; + + switch (cmd) { + case SIOCETHTOOL: + rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + break; + + default: + rc = -EOPNOTSUPP; + break; + } + + return rc; +} + static int el3_config(struct net_device *dev, struct ifmap *map) { if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { diff --git a/drivers/net/pcmcia/aironet4500_cs.c b/drivers/net/pcmcia/aironet4500_cs.c index 4c26b7f48..3b0195a90 100644 --- a/drivers/net/pcmcia/aironet4500_cs.c +++ b/drivers/net/pcmcia/aironet4500_cs.c @@ -10,8 +10,11 @@ * */ +#define DRV_NAME "aironet4500_cs" +#define DRV_VERSION "0.1" + static const char *awc_version = -"aironet4500_cs.c v0.1 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n"; +DRV_NAME ".c v" DRV_VERSION " 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n"; #include <linux/module.h> @@ -24,6 +27,9 @@ static const char *awc_version = #include <linux/timer.h> #include <linux/interrupt.h> #include <linux/in.h> +#include <linux/ethtool.h> + +#include <asm/uaccess.h> #include <asm/io.h> #include <asm/system.h> #include <asm/bitops.h> @@ -159,6 +165,66 @@ static int awc_pcmcia_close(struct net_device *dev) return ret; } +static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + /* dev_ioctl() in ../../net/core/dev.c has already checked + capable(CAP_NET_ADMIN), so don't bother with that here. */ + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + +#ifdef PCMCIA_DEBUG + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = pc_debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + pc_debug = edata.data; + return 0; + } +#endif + + default: + break; + } + + return -EOPNOTSUPP; +} + +static int awc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + switch (cmd) { + case SIOCETHTOOL: + return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + + default: + return -EOPNOTSUPP; + } + return 0; +} + /* awc_attach() creates an "instance" of the driver, allocating local data structures for one device. The device is registered @@ -230,7 +296,8 @@ static dev_link_t *awc_attach(void) // dev->set_config = &awc_config_misiganes,aga mitte awc_config; dev->get_stats = &awc_get_stats; // dev->set_multicast_list = &awc_set_multicast_list; - + dev->do_ioctl = &awc_ioctl; + strcpy(dev->name, ((struct awc_private *)dev->priv)->node.dev_name); ether_setup(dev); diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 6c47c37a0..95bc34369 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -28,6 +28,9 @@ ======================================================================*/ +#define DRV_NAME "fmvj18x_cs" +#define DRV_VERSION "2.6" + #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> @@ -39,6 +42,9 @@ #include <linux/interrupt.h> #include <linux/in.h> #include <linux/delay.h> +#include <linux/ethtool.h> + +#include <asm/uaccess.h> #include <asm/io.h> #include <asm/system.h> @@ -74,7 +80,7 @@ INT_MODULE_PARM(sram_config, 0); #ifdef PCMCIA_DEBUG INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) -static char *version = "fmvj18x_cs.c 2.6 2001/09/17"; +static char *version = DRV_NAME ".c " DRV_VERSION " 2001/09/17"; #else #define DEBUG(n, args...) #endif @@ -104,6 +110,7 @@ static void fjn_reset(struct net_device *dev); static struct net_device_stats *fjn_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); static void fjn_tx_timeout(struct net_device *dev); +static int fjn_ioctl(struct net_device *, struct ifreq *, int); static dev_info_t dev_info = "fmvj18x_cs"; static dev_link_t *dev_list; @@ -316,6 +323,7 @@ static dev_link_t *fmvj18x_attach(void) dev->tx_timeout = fjn_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; #endif + dev->do_ioctl = fjn_ioctl; /* Register with Card Services */ link->next = dev_list; @@ -1103,6 +1111,65 @@ static void fjn_rx(struct net_device *dev) /*====================================================================*/ +static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + /* dev_ioctl() in ../../net/core/dev.c has already checked + capable(CAP_NET_ADMIN), so don't bother with that here. */ + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + +#ifdef PCMCIA_DEBUG + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = pc_debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + pc_debug = edata.data; + return 0; + } +#endif + + default: + break; + } + + return -EOPNOTSUPP; +} + +static int fjn_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + switch (cmd) { + case SIOCETHTOOL: + return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); + + default: + return -EOPNOTSUPP; + } +} + static int fjn_config(struct net_device *dev, struct ifmap *map){ return 0; } diff --git a/drivers/net/pcmcia/xircom_tulip_cb.c b/drivers/net/pcmcia/xircom_tulip_cb.c index 578af8d57..81b91524d 100644 --- a/drivers/net/pcmcia/xircom_tulip_cb.c +++ b/drivers/net/pcmcia/xircom_tulip_cb.c @@ -1472,21 +1472,18 @@ static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) /* Legacy mii-diag interface */ case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ if (tp->mii_cnt) data[0] = phy; else return -ENODEV; return 0; case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ save_flags(flags); cli(); data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f); restore_flags(flags); return 0; case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ if (!capable(CAP_NET_ADMIN)) return -EPERM; save_flags(flags); diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 7b6186fc8..4bf23c2f8 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -483,7 +483,7 @@ static void sl_tx_timeout(struct net_device *dev) * 14 Oct 1994 Dmitry Gorodchanin. */ #ifdef SL_CHECK_TRANSMIT - if (jiffies - dev->trans_start < 20 * HZ) { + if (time_before(jiffies, dev->trans_start + 20 * HZ)) { /* 20 sec timeout not reached */ goto out; } @@ -1387,7 +1387,7 @@ cleanup_module(void) int i; if (slip_ctrls != NULL) { - unsigned long start = jiffies; + unsigned long timeout = jiffies + HZ; int busy = 0; /* First of all: check for active disciplines and hangup them. @@ -1410,7 +1410,7 @@ cleanup_module(void) spin_unlock(&slc->ctrl.lock); } local_bh_enable(); - } while (busy && jiffies - start < 1*HZ); + } while (busy && time_before(jiffies, timeout)); busy = 0; for (i = 0; i < slip_maxdev; i++) { diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 3d17fd6c2..57920334c 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -93,13 +93,16 @@ - Fixed initialization timing problems - Fixed interrupt mask definitions + LK1.3.5 (jgarzik) + - ethtool NWAY_RST, GLINK, [GS]MSGLVL support + TODO: - implement tx_timeout() properly */ #define DRV_NAME "starfire" -#define DRV_VERSION "1.03+LK1.3.4" -#define DRV_RELDATE "August 14, 2001" +#define DRV_VERSION "1.03+LK1.3.5" +#define DRV_RELDATE "November 17, 2001" #include <linux/version.h> #include <linux/module.h> @@ -1767,6 +1770,47 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) return 0; } + /* restart autonegotiation */ + case ETHTOOL_NWAY_RST: { + int tmp; + int r = -EINVAL; + /* if autoneg is off, it's an error */ + tmp = mdio_read(dev, np->phys[0], MII_BMCR); + if (tmp & BMCR_ANENABLE) { + tmp |= (BMCR_ANRESTART); + mdio_write(dev, np->phys[0], MII_BMCR, tmp); + r = 0; + } + return r; + } + /* get link status */ + case ETHTOOL_GLINK: { + struct ethtool_value edata = {ETHTOOL_GLINK}; + if (mdio_read(dev, np->phys[0], MII_BMSR) & BMSR_LSTATUS) + edata.data = 1; + else + edata.data = 0; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + debug = edata.data; + return 0; + } default: return -EOPNOTSUPP; } @@ -1784,17 +1828,14 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) /* Legacy mii-diag interface */ case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = np->phys[0] & 0x1f; /* Fall Through */ case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f); return 0; case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ if (!capable(CAP_NET_ADMIN)) return -EPERM; if (data->phy_id == np->phys[0]) { diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 7321b3424..510573b72 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -21,11 +21,15 @@ Version 1.01a (jgarzik): - Replace some MII-related magic numbers with constants + Version 1.02 (D-Link): + - Add new board to PCI ID list + - Fix multicast bug + */ #define DRV_NAME "sundance" -#define DRV_VERSION "1.01a" -#define DRV_RELDATE "11-Nov-2001" +#define DRV_VERSION "1.02" +#define DRV_RELDATE "17-Jan-2002" /* The user-configurable values. @@ -223,8 +227,9 @@ static struct pci_device_id sundance_pci_tbl[] __devinitdata = { {0x1186, 0x1002, 0x1186, 0x1002, 0, 0, 0}, {0x1186, 0x1002, 0x1186, 0x1003, 0, 0, 1}, {0x1186, 0x1002, 0x1186, 0x1012, 0, 0, 2}, - {0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, - {0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, + {0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3}, + {0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, + {0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, {0,} }; MODULE_DEVICE_TABLE(pci, sundance_pci_tbl); @@ -247,6 +252,8 @@ static struct pci_id_info pci_id_tbl[] = { PCI_IOTYPE, 128, CanHaveMII}, {"D-Link DFE-580TX 4 port Server Adapter", {0x10121186, 0xffffffff,}, PCI_IOTYPE, 128, CanHaveMII}, + {"D-Link DFE-530TXS FAST Ethernet Adapter", {0x10021186, 0xffffffff,}, + PCI_IOTYPE, 128, CanHaveMII}, {"D-Link DL10050-based FAST Ethernet Adapter", {0x10021186, 0xffffffff,}, PCI_IOTYPE, 128, CanHaveMII}, @@ -1287,11 +1294,16 @@ static void set_rx_mode(struct net_device *dev) rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; } else if (dev->mc_count) { struct dev_mc_list *mclist; - memset(mc_filter, 0, sizeof(mc_filter)); + int bit; + int index; + int crc; + memset (mc_filter, 0, sizeof (mc_filter)); for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; - i++, mclist = mclist->next) { - set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f, - mc_filter); + i++, mclist = mclist->next) { + crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr); + for (index=0, bit=0; bit < 6; bit++, crc <<= 1) + if (crc & 0x80000000) index |= 1 << bit; + mc_filter[index/16] |= (1 << (index % 16)); } rx_mode = AcceptBroadcast | AcceptMultiHash | AcceptMyPhys; } else { @@ -1335,17 +1347,14 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case SIOCETHTOOL: return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f; /* Fall Through */ case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f); return 0; case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ if (!capable(CAP_NET_ADMIN)) return -EPERM; mdio_write(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in); diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 1246f4308..59a9f0cd1 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -923,18 +923,15 @@ static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) switch(cmd) { case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = phy; case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ TLan_MiiReadReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, &data->val_out); return 0; case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ if (!capable(CAP_NET_ADMIN)) return -EPERM; TLan_MiiWriteReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in); diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 0aed62e90..3e7634e79 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -76,8 +76,17 @@ LK1.1.12: - Martin Eriksson: Allow Memory-Mapped IO to be enabled. + + LK1.1.13 (jgarzik): + - Add ethtool support + - Replace some MII-related magic numbers with constants + */ +#define DRV_NAME "via-rhine" +#define DRV_VERSION "1.1.13" +#define DRV_RELDATE "Nov-17-2001" + /* A few user-configurable values. These may be modified when a driver module is loaded. */ @@ -151,18 +160,20 @@ static const int multicast_filter_limit = 32; #include <linux/init.h> #include <linux/delay.h> #include <linux/mii.h> +#include <linux/ethtool.h> #include <linux/crc32.h> #include <asm/processor.h> /* Processor type for cache alignment. */ #include <asm/bitops.h> #include <asm/io.h> #include <asm/irq.h> +#include <asm/uaccess.h> /* These identify the driver base version and may not be removed. */ static char version[] __devinitdata = -KERN_INFO "via-rhine.c:v1.10-LK1.1.12 03/11/2001 Written by Donald Becker\n" +KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n" KERN_INFO " http://www.scyld.com/network/via-rhine.html\n"; -static char shortname[] __devinitdata = "via-rhine"; +static char shortname[] __devinitdata = DRV_NAME; /* This driver was written to use PCI memory space, however most versions @@ -471,6 +482,7 @@ struct netdev_private { unsigned char phys[MAX_MII_CNT]; /* MII device addresses. */ unsigned int mii_cnt; /* number of MIIs found, but only the first one is used */ u16 mii_status; /* last read MII status */ + struct mii_if_info mii_if; }; static int mdio_read(struct net_device *dev, int phy_id, int location); @@ -486,7 +498,7 @@ static void via_rhine_rx(struct net_device *dev); static void via_rhine_error(struct net_device *dev, int intr_status); static void via_rhine_set_rx_mode(struct net_device *dev); static struct net_device_stats *via_rhine_get_stats(struct net_device *dev); -static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static int via_rhine_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int via_rhine_close(struct net_device *dev); static inline void clear_tally_counters(long ioaddr); @@ -684,6 +696,9 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev, np->chip_id = chip_id; np->drv_flags = via_rhine_chip_info[chip_id].drv_flags; np->pdev = pdev; + np->mii_if.dev = dev; + np->mii_if.mdio_read = mdio_read; + np->mii_if.mdio_write = mdio_write; if (dev->mem_start) option = dev->mem_start; @@ -691,16 +706,16 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev, /* The lower four bits are the media type. */ if (option > 0) { if (option & 0x200) - np->full_duplex = 1; + np->mii_if.full_duplex = 1; np->default_port = option & 15; } if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0) - np->full_duplex = 1; + np->mii_if.full_duplex = 1; - if (np->full_duplex) { + if (np->mii_if.full_duplex) { printk(KERN_INFO "%s: Set to forced full duplex, autonegotiation" " disabled.\n", dev->name); - np->duplex_lock = 1; + np->mii_if.duplex_lock = 1; } /* The chip-specific entries in the device structure. */ @@ -709,7 +724,7 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev, dev->stop = via_rhine_close; dev->get_stats = via_rhine_get_stats; dev->set_multicast_list = via_rhine_set_rx_mode; - dev->do_ioctl = mii_ioctl; + dev->do_ioctl = via_rhine_ioctl; dev->tx_timeout = via_rhine_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; if (np->drv_flags & ReqTxAlign) @@ -736,10 +751,10 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev, int mii_status = mdio_read(dev, phy, 1); if (mii_status != 0xffff && mii_status != 0x0000) { np->phys[phy_idx++] = phy; - np->advertising = mdio_read(dev, phy, 4); + np->mii_if.advertising = mdio_read(dev, phy, 4); printk(KERN_INFO "%s: MII PHY found at address %d, status " "0x%4.4x advertising %4.4x Link %4.4x.\n", - dev->name, phy, mii_status, np->advertising, + dev->name, phy, mii_status, np->mii_if.advertising, mdio_read(dev, phy, 5)); /* set IFF_RUNNING */ @@ -750,12 +765,13 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev, } } np->mii_cnt = phy_idx; + np->mii_if.phy_id = np->phys[0]; } /* Allow forcing the media type. */ if (option > 0) { if (option & 0x220) - np->full_duplex = 1; + np->mii_if.full_duplex = 1; np->default_port = option & 0x3ff; if (np->default_port & 0x330) { /* FIXME: shouldn't someone check this variable? */ @@ -969,7 +985,7 @@ static void init_registers(struct net_device *dev) ioaddr + IntrEnable); np->chip_cmd = CmdStart|CmdTxOn|CmdRxOn|CmdNoTxPoll; - if (np->duplex_lock) + if (np->mii_if.duplex_lock) np->chip_cmd |= CmdFDuplex; writew(np->chip_cmd, ioaddr + ChipCmd); @@ -1011,12 +1027,12 @@ static void mdio_write(struct net_device *dev, int phy_id, int regnum, int value switch (regnum) { case 0: /* Is user forcing speed/duplex? */ if (value & 0x9000) /* Autonegotiation. */ - np->duplex_lock = 0; + np->mii_if.duplex_lock = 0; else - np->full_duplex = (value & 0x0100) ? 1 : 0; + np->mii_if.full_duplex = (value & 0x0100) ? 1 : 0; break; case 4: - np->advertising = value; + np->mii_if.advertising = value; break; } } @@ -1060,7 +1076,7 @@ static int via_rhine_open(struct net_device *dev) printk(KERN_DEBUG "%s: Done via_rhine_open(), status %4.4x " "MII status: %4.4x.\n", dev->name, readw(ioaddr + ChipCmd), - mdio_read(dev, np->phys[0], 1)); + mdio_read(dev, np->phys[0], MII_BMSR)); netif_start_queue(dev); @@ -1078,19 +1094,19 @@ static void via_rhine_check_duplex(struct net_device *dev) { struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; - int mii_reg5 = mdio_read(dev, np->phys[0], 5); - int negotiated = mii_reg5 & np->advertising; + int mii_lpa = mdio_read(dev, np->phys[0], MII_LPA); + int negotiated = mii_lpa & np->mii_if.advertising; int duplex; - if (np->duplex_lock || mii_reg5 == 0xffff) + if (np->mii_if.duplex_lock || mii_lpa == 0xffff) return; duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040; - if (np->full_duplex != duplex) { - np->full_duplex = duplex; + if (np->mii_if.full_duplex != duplex) { + np->mii_if.full_duplex = duplex; if (debug) printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d link" " partner capability of %4.4x.\n", dev->name, - duplex ? "full" : "half", np->phys[0], mii_reg5); + duplex ? "full" : "half", np->phys[0], mii_lpa); if (duplex) np->chip_cmd |= CmdFDuplex; else @@ -1118,7 +1134,7 @@ static void via_rhine_timer(unsigned long data) via_rhine_check_duplex(dev); /* make IFF_RUNNING follow the MII status bit "Link established" */ - mii_status = mdio_read(dev, np->phys[0], 1); + mii_status = mdio_read(dev, np->phys[0], MII_BMSR); if ( (mii_status & MIILink) != (np->mii_status & MIILink) ) { if (mii_status & MIILink) netif_carrier_on(dev); @@ -1142,7 +1158,7 @@ static void via_rhine_tx_timeout (struct net_device *dev) printk (KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status " "%4.4x, resetting...\n", dev->name, readw (ioaddr + IntrStatus), - mdio_read (dev, np->phys[0], 1)); + mdio_read (dev, np->phys[0], MII_BMSR)); dev->if_port = 0; @@ -1457,14 +1473,14 @@ static void via_rhine_error(struct net_device *dev, int intr_status) if (readb(ioaddr + MIIStatus) & 0x02) { /* Link failed, restart autonegotiation. */ if (np->drv_flags & HasDavicomPhy) - mdio_write(dev, np->phys[0], 0, 0x3300); + mdio_write(dev, np->phys[0], MII_BMCR, 0x3300); } else via_rhine_check_duplex(dev); if (debug) printk(KERN_ERR "%s: MII status changed: Autonegotiation " "advertising %4.4x partner %4.4x.\n", dev->name, - mdio_read(dev, np->phys[0], 4), - mdio_read(dev, np->phys[0], 5)); + mdio_read(dev, np->phys[0], MII_ADVERTISE), + mdio_read(dev, np->phys[0], MII_LPA)); } if (intr_status & IntrStatsMax) { np->stats.rx_crc_errors += readw(ioaddr + RxCRCErrs); @@ -1554,29 +1570,112 @@ static void via_rhine_set_rx_mode(struct net_device *dev) writeb(np->rx_thresh | rx_mode, ioaddr + RxConfig); } -static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static int via_rhine_ethtool_ioctl (struct net_device *dev, void *useraddr) +{ + struct netdev_private *np = dev->priv; + u32 ethcmd; + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, DRV_NAME); + strcpy (info.version, DRV_VERSION); + strcpy (info.bus_info, np->pdev->slot_name); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get settings */ + case ETHTOOL_GSET: { + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + if (!(np->drv_flags & CanHaveMII)) + break; + spin_lock_irq(&np->lock); + mii_ethtool_gset(&np->mii_if, &ecmd); + spin_unlock_irq(&np->lock); + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) + return -EFAULT; + return 0; + } + /* set settings */ + case ETHTOOL_SSET: { + int r; + struct ethtool_cmd ecmd; + if (!(np->drv_flags & CanHaveMII)) + break; + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) + return -EFAULT; + spin_lock_irq(&np->lock); + r = mii_ethtool_sset(&np->mii_if, &ecmd); + spin_unlock_irq(&np->lock); + return r; + } + /* restart autonegotiation */ + case ETHTOOL_NWAY_RST: { + if (!(np->drv_flags & CanHaveMII)) + break; + return mii_nway_restart(&np->mii_if); + } + /* get link status */ + case ETHTOOL_GLINK: { + struct ethtool_value edata = {ETHTOOL_GLINK}; + if (!(np->drv_flags & CanHaveMII)) + break; + edata.data = mii_link_ok(&np->mii_if); + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + debug = edata.data; + return 0; + } + default: + break; + } + + return -EOPNOTSUPP; +} +static int via_rhine_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct netdev_private *np = dev->priv; struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; unsigned long flags; int retval; + if (cmd == SIOCETHTOOL) + return via_rhine_ethtool_ioctl(dev, (void *) rq->ifr_data); + spin_lock_irqsave(&np->lock, flags); retval = 0; switch(cmd) { case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = np->phys[0] & 0x1f; /* Fall Through */ case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f); break; case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ if (!capable(CAP_NET_ADMIN)) { retval = -EPERM; break; diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index 405d218ea..4812d8400 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c @@ -175,7 +175,7 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ case LMCIOCSINFO: /*fold01*/ sp = &((struct ppp_device *) dev)->sppp; - if (!suser ()) { + if (!capable(CAP_NET_ADMIN)) { ret = -EPERM; break; } @@ -210,7 +210,7 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ u_int16_t old_type = sc->if_type; u_int16_t new_type; - if (!suser ()) { + if (!capable(CAP_NET_ADMIN)) { ret = -EPERM; break; } @@ -290,7 +290,7 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ break; case LMCIOCCLEARLMCSTATS: /*fold01*/ - if (!suser ()){ + if (!capable(CAP_NET_ADMIN)){ ret = -EPERM; break; } @@ -304,7 +304,7 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ break; case LMCIOCSETCIRCUIT: /*fold01*/ - if (!suser ()){ + if (!capable(CAP_NET_ADMIN)){ ret = -EPERM; break; } @@ -322,7 +322,7 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ break; case LMCIOCRESET: /*fold01*/ - if (!suser ()){ + if (!capable(CAP_NET_ADMIN)){ ret = -EPERM; break; } @@ -355,7 +355,7 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ { struct lmc_xilinx_control xc; /*fold02*/ - if (!suser ()){ + if (!capable(CAP_NET_ADMIN)){ ret = -EPERM; break; } diff --git a/drivers/net/winbond-840.c b/drivers/net/winbond-840.c index 92e188068..514b57d19 100644 --- a/drivers/net/winbond-840.c +++ b/drivers/net/winbond-840.c @@ -36,6 +36,8 @@ power management. support for big endian descriptors Copyright (C) 2001 Manfred Spraul + * ethtool support (jgarzik) + * Replace some MII-related magic numbers with constants (jgarzik) TODO: * enable pci_power_off @@ -43,8 +45,8 @@ */ #define DRV_NAME "winbond-840" -#define DRV_VERSION "1.01-c" -#define DRV_RELDATE "6/30/2000" +#define DRV_VERSION "1.01-d" +#define DRV_RELDATE "Nov-17-2001" /* Automatically extracted configuration info: @@ -364,14 +366,11 @@ struct netdev_private { unsigned int cur_tx, dirty_tx; unsigned int tx_q_bytes; unsigned int tx_full; /* The Tx queue is full. */ - /* These values are keep track of the transceiver/media in use. */ - unsigned int full_duplex:1; /* Full-duplex operation requested. */ - unsigned int duplex_lock:1; /* MII transceiver section. */ int mii_cnt; /* MII device addresses. */ - u16 advertising; /* NWay media advertisement */ unsigned char phys[MII_CNT]; /* MII device addresses, but only the first is used */ u32 mii; + struct mii_if_info mii_if; }; static int eeprom_read(long ioaddr, int location); @@ -453,6 +452,9 @@ static int __devinit w840_probe1 (struct pci_dev *pdev, np->chip_id = chip_idx; np->drv_flags = pci_id_tbl[chip_idx].drv_flags; spin_lock_init(&np->lock); + np->mii_if.dev = dev; + np->mii_if.mdio_read = mdio_read; + np->mii_if.mdio_write = mdio_write; pci_set_drvdata(pdev, dev); @@ -462,16 +464,16 @@ static int __devinit w840_probe1 (struct pci_dev *pdev, /* The lower four bits are the media type. */ if (option > 0) { if (option & 0x200) - np->full_duplex = 1; + np->mii_if.full_duplex = 1; if (option & 15) printk(KERN_INFO "%s: ignoring user supplied media type %d", dev->name, option & 15); } if (find_cnt < MAX_UNITS && full_duplex[find_cnt] > 0) - np->full_duplex = 1; + np->mii_if.full_duplex = 1; - if (np->full_duplex) - np->duplex_lock = 1; + if (np->mii_if.full_duplex) + np->mii_if.duplex_lock = 1; /* The chip-specific entries in the device structure. */ dev->open = &netdev_open; @@ -496,18 +498,19 @@ static int __devinit w840_probe1 (struct pci_dev *pdev, if (np->drv_flags & CanHaveMII) { int phy, phy_idx = 0; for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) { - int mii_status = mdio_read(dev, phy, 1); + int mii_status = mdio_read(dev, phy, MII_BMSR); if (mii_status != 0xffff && mii_status != 0x0000) { np->phys[phy_idx++] = phy; - np->advertising = mdio_read(dev, phy, 4); - np->mii = (mdio_read(dev, phy, 2) << 16)+ - mdio_read(dev, phy, 3); + np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE); + np->mii = (mdio_read(dev, phy, MII_PHYSID1) << 16)+ + mdio_read(dev, phy, MII_PHYSID2); printk(KERN_INFO "%s: MII PHY %8.8xh found at address %d, status " "0x%4.4x advertising %4.4x.\n", - dev->name, np->mii, phy, mii_status, np->advertising); + dev->name, np->mii, phy, mii_status, np->mii_if.advertising); } } np->mii_cnt = phy_idx; + np->mii_if.phy_id = np->phys[0]; if (phy_idx == 0) { printk(KERN_WARNING "%s: MII PHY not found -- this device may " "not operate correctly.\n", dev->name); @@ -654,7 +657,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val int i; if (location == 4 && phy_id == np->phys[0]) - np->advertising = value; + np->mii_if.advertising = value; if (mii_preamble_required) mdio_sync(mdio_addr); @@ -728,12 +731,12 @@ static int update_link(struct net_device *dev) int duplex, fasteth, result, mii_reg; /* BSMR */ - mii_reg = mdio_read(dev, np->phys[0], 1); + mii_reg = mdio_read(dev, np->phys[0], MII_BMSR); if (mii_reg == 0xffff) return np->csr6; /* reread: the link status bit is sticky */ - mii_reg = mdio_read(dev, np->phys[0], 1); + mii_reg = mdio_read(dev, np->phys[0], MII_BMSR); if (!(mii_reg & 0x4)) { if (netif_carrier_ok(dev)) { if (debug) @@ -759,18 +762,18 @@ static int update_link(struct net_device *dev) * Instead bit 9 and 13 of the BMCR are updated to the result * of the negotiation.. */ - mii_reg = mdio_read(dev, np->phys[0], 0); - duplex = mii_reg & 0x100; - fasteth = mii_reg & 0x2000; + mii_reg = mdio_read(dev, np->phys[0], MII_BMCR); + duplex = mii_reg & BMCR_FULLDPLX; + fasteth = mii_reg & BMCR_SPEED100; } else { int negotiated; - mii_reg = mdio_read(dev, np->phys[0], 5); - negotiated = mii_reg & np->advertising; + mii_reg = mdio_read(dev, np->phys[0], MII_LPA); + negotiated = mii_reg & np->mii_if.advertising; - duplex = (negotiated & 0x0100) || ((negotiated & 0x02C0) == 0x0040); + duplex = (negotiated & LPA_100FULL) || ((negotiated & 0x02C0) == LPA_10FULL); fasteth = negotiated & 0x380; } - duplex |= np->duplex_lock; + duplex |= np->mii_if.duplex_lock; /* remove fastether and fullduplex */ result = np->csr6 & ~0x20000200; if (duplex) @@ -822,7 +825,7 @@ static inline void update_csr6(struct net_device *dev, int new) /* and restart them with the new configuration */ writel(np->csr6, ioaddr + NetworkConfig); if (new & 0x200) - np->full_duplex = 1; + np->mii_if.full_duplex = 1; } static void netdev_timer(unsigned long data) @@ -1131,7 +1134,7 @@ static void netdev_tx_done(struct net_device *dev) if (tx_status & 0x0C80) np->stats.tx_carrier_errors++; if (tx_status & 0x0200) np->stats.tx_window_errors++; if (tx_status & 0x0002) np->stats.tx_fifo_errors++; - if ((tx_status & 0x0080) && np->full_duplex == 0) + if ((tx_status & 0x0080) && np->mii_if.full_duplex == 0) np->stats.tx_heartbeat_errors++; #ifdef ETHER_STATS if (tx_status & 0x0100) np->stats.collisions16++; @@ -1469,6 +1472,56 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) return 0; } + /* get settings */ + case ETHTOOL_GSET: { + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + spin_lock_irq(&np->lock); + mii_ethtool_gset(&np->mii_if, &ecmd); + spin_unlock_irq(&np->lock); + if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) + return -EFAULT; + return 0; + } + /* set settings */ + case ETHTOOL_SSET: { + int r; + struct ethtool_cmd ecmd; + if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) + return -EFAULT; + spin_lock_irq(&np->lock); + r = mii_ethtool_sset(&np->mii_if, &ecmd); + spin_unlock_irq(&np->lock); + return r; + } + /* restart autonegotiation */ + case ETHTOOL_NWAY_RST: { + return mii_nway_restart(&np->mii_if); + } + /* get link status */ + case ETHTOOL_GLINK: { + struct ethtool_value edata = {ETHTOOL_GLINK}; + edata.data = mii_link_ok(&np->mii_if); + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + + /* get message-level */ + case ETHTOOL_GMSGLVL: { + struct ethtool_value edata = {ETHTOOL_GMSGLVL}; + edata.data = debug; + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL: { + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + debug = edata.data; + return 0; + } } return -EOPNOTSUPP; @@ -1483,19 +1536,16 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case SIOCETHTOOL: return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f; /* Fall Through */ case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ spin_lock_irq(&np->lock); data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f); spin_unlock_irq(&np->lock); return 0; case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ if (!capable(CAP_NET_ADMIN)) return -EPERM; spin_lock_irq(&np->lock); diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index e56ab051d..be17f0bbf 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -1420,17 +1420,14 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case SIOCETHTOOL: return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */ data->phy_id = np->phys[0] & 0x1f; /* Fall Through */ case SIOCGMIIREG: /* Read MII PHY register. */ - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */ data->val_out = mdio_read(ioaddr, data->phy_id & 0x1f, data->reg_num & 0x1f); return 0; case SIOCSMIIREG: /* Write MII PHY register. */ - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */ if (!capable(CAP_NET_ADMIN)) return -EPERM; if (data->phy_id == np->phys[0]) { diff --git a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c index 82ed6335b..6d150d928 100644 --- a/drivers/sbus/char/sunkbd.c +++ b/drivers/sbus/char/sunkbd.c @@ -1338,7 +1338,7 @@ repeat: spin_unlock_irqrestore(&kbd_queue_lock, flags); #ifdef CONFIG_SPARC32_COMPAT - if (current->thread.flags & SPARC_FLAG_32BIT) { + if (test_thread_flag(TIF_32BIT)) { if (copy_to_user((Firm_event *)p, &this_event, sizeof(Firm_event)-sizeof(struct timeval))) return -EFAULT; diff --git a/drivers/sbus/char/sunmouse.c b/drivers/sbus/char/sunmouse.c index 8bb45cbde..c006a52b2 100644 --- a/drivers/sbus/char/sunmouse.c +++ b/drivers/sbus/char/sunmouse.c @@ -462,7 +462,7 @@ repeat: spin_unlock_irqrestore(&sunmouse.lock, flags); #ifdef CONFIG_SPARC32_COMPAT - if (current->thread.flags & SPARC_FLAG_32BIT) { + if (test_thread_flag(TIF_32BIT)) { if ((end - p) < ((sizeof(Firm_event) - sizeof(struct timeval) + (sizeof(u32) * 2)))) diff --git a/drivers/usb/hcd/ehci-hcd.c b/drivers/usb/hcd/ehci-hcd.c index 6ee303aa0..e66182530 100644 --- a/drivers/usb/hcd/ehci-hcd.c +++ b/drivers/usb/hcd/ehci-hcd.c @@ -277,7 +277,7 @@ done2: */ usb_connect (udev); udev->speed = USB_SPEED_HIGH; - if (usb_new_device (udev) != 0) { + if (usb_register_root_hub (udev, &ehci->hcd.pdev->dev) != 0) { if (hcd->state == USB_STATE_RUNNING) ehci_ready (ehci); while (readl (&ehci->regs->status) & (STS_ASS | STS_PSS)) diff --git a/drivers/usb/hcd/ohci-hcd.c b/drivers/usb/hcd/ohci-hcd.c index 48576302f..9dbceb3aa 100644 --- a/drivers/usb/hcd/ohci-hcd.c +++ b/drivers/usb/hcd/ohci-hcd.c @@ -469,7 +469,7 @@ static int hc_start (struct ohci_hcd *ohci) usb_connect (udev); udev->speed = USB_SPEED_FULL; - if (usb_new_device (udev) != 0) { + if (usb_register_root_hub (udev, &ohci->hcd.pdev->dev) != 0) { usb_free_dev (udev); ohci->disabled = 1; // FIXME cleanup diff --git a/drivers/usb/hub.c b/drivers/usb/hub.c index 23eb747a7..c545bd8ea 100644 --- a/drivers/usb/hub.c +++ b/drivers/usb/hub.c @@ -721,6 +721,20 @@ static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port, info("new USB device on bus %d path %s, assigned address %d", dev->bus->busnum, dev->devpath, dev->devnum); + /* put the device in the global device tree */ + dev->dev.parent = &dev->parent->dev; + sprintf (&dev->dev.name[0], "USB device %04x:%04x", + dev->descriptor.idVendor, + dev->descriptor.idProduct); + /* find the number of the port this device is connected to */ + sprintf (&dev->dev.bus_id[0], "unknown_port_%03d", dev->devnum); + for (i = 0; i < USB_MAXCHILDREN; ++i) { + if (dev->parent->children[i] == dev) { + sprintf (&dev->dev.bus_id[0], "%02d", i); + break; + } + } + /* Run it through the hoops (find a driver, etc) */ if (!usb_new_device(dev)) goto done; diff --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c index de765d9dc..e668cf3f1 100644 --- a/drivers/usb/uhci.c +++ b/drivers/usb/uhci.c @@ -2842,7 +2842,7 @@ static int alloc_uhci(struct pci_dev *dev, unsigned int io_addr, unsigned int io usb_connect(uhci->rh.dev); - if (usb_new_device(uhci->rh.dev) != 0) { + if (usb_register_root_hub(uhci->rh.dev, &dev->dev) != 0) { err("unable to start root hub"); retval = -ENOMEM; goto err_start_root_hub; diff --git a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c index 94f84edfc..29384b449 100644 --- a/drivers/usb/usb-ohci.c +++ b/drivers/usb/usb-ohci.c @@ -2231,7 +2231,7 @@ static int hc_start (ohci_t * ohci) dev = usb_to_ohci (usb_dev); ohci->bus->root_hub = usb_dev; usb_connect (usb_dev); - if (usb_new_device (usb_dev) != 0) { + if (usb_register_root_hub (usb_dev, &ohci->ohci_dev->dev) != 0) { usb_free_dev (usb_dev); ohci->disabled = 1; return -ENODEV; diff --git a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c index 83d38a9ec..6d332d305 100644 --- a/drivers/usb/usb-uhci.c +++ b/drivers/usb/usb-uhci.c @@ -2904,7 +2904,7 @@ _static int __init uhci_start_usb (uhci_t *s) s->bus->root_hub = usb_dev; usb_connect (usb_dev); - if (usb_new_device (usb_dev) != 0) { + if (usb_register_root_hub (usb_dev, &s->uhci_pci->dev) != 0) { usb_free_dev (usb_dev); return -1; } diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c index e94daf9e1..be9fa8a78 100644 --- a/drivers/usb/usb.c +++ b/drivers/usb/usb.c @@ -980,8 +980,16 @@ static void usb_find_drivers(struct usb_device *dev) unsigned claimed = 0; for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) { + struct usb_interface *interface = &dev->actconfig->interface[ifnum]; + + /* register this interface with driverfs */ + interface->dev.parent = &dev->dev; + sprintf (&interface->dev.bus_id[0], "%03d", ifnum); + sprintf (&interface->dev.name[0], "figure out some name..."); + device_register (&interface->dev); + /* if this interface hasn't already been claimed */ - if (!usb_interface_claimed(dev->actconfig->interface + ifnum)) { + if (!usb_interface_claimed(interface)) { if (usb_find_interface_driver(dev, ifnum)) rejected++; else @@ -1969,8 +1977,10 @@ void usb_disconnect(struct usb_device **pdev) if (driver->owner) __MOD_DEC_USE_COUNT(driver->owner); /* if driver->disconnect didn't release the interface */ - if (interface->driver) + if (interface->driver) { + put_device (&interface->dev); usb_driver_release_interface(driver, interface); + } } } } @@ -1989,6 +1999,7 @@ void usb_disconnect(struct usb_device **pdev) if (dev->devnum > 0) { clear_bit(dev->devnum, &dev->bus->devmap.devicemap); usbfs_remove_device(dev); + put_device(&dev->dev); } /* Free up the device itself */ @@ -2715,6 +2726,11 @@ int usb_new_device(struct usb_device *dev) usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber); #endif + /* register this device in the driverfs tree */ + err = device_register (&dev->dev); + if (err) + return err; + /* now that the basic setup is over, add a /proc/bus/usb entry */ usbfs_add_device(dev); @@ -2727,6 +2743,29 @@ int usb_new_device(struct usb_device *dev) return 0; } +/** + * usb_register_root_hub - called by a usb host controller to register the root hub device in the system + * @usb_dev: the usb root hub device to be registered. + * @parent_dev: the parent device of this root hub. + * + * The USB host controller calls this function to register the root hub + * properly with the USB subsystem. It sets up the device properly in + * the driverfs tree, and then calls usb_new_device() to register the + * usb device. + */ +int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev) +{ + int retval; + + usb_dev->dev.parent = parent_dev; + strcpy (&usb_dev->dev.name[0], "usb_name"); + strcpy (&usb_dev->dev.bus_id[0], "usb_bus"); + retval = usb_new_device (usb_dev); + if (retval) + put_device (&usb_dev->dev); + return retval; +} + static int usb_open(struct inode * inode, struct file * file) { int minor = minor(inode->i_rdev); @@ -2832,6 +2871,7 @@ EXPORT_SYMBOL(usb_alloc_bus); EXPORT_SYMBOL(usb_free_bus); EXPORT_SYMBOL(usb_register_bus); EXPORT_SYMBOL(usb_deregister_bus); +EXPORT_SYMBOL(usb_register_root_hub); EXPORT_SYMBOL(usb_alloc_dev); EXPORT_SYMBOL(usb_free_dev); EXPORT_SYMBOL(usb_inc_dev_use); diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 350a648ee..256a285fd 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -33,7 +33,6 @@ #include <linux/coda_cache.h> /* VFS super_block ops */ -static struct super_block *coda_read_super(struct super_block *, void *, int); static void coda_read_inode(struct inode *); static void coda_clear_inode(struct inode *); static void coda_put_super(struct super_block *); @@ -140,8 +139,7 @@ static int get_device_index(struct coda_mount_data *data) return idx; } -static struct super_block * coda_read_super(struct super_block *sb, - void *data, int silent) +static int coda_fill_super(struct super_block *sb, void *data, int silent) { struct inode *root = 0; struct coda_sb_info *sbi = NULL; @@ -161,17 +159,17 @@ static struct super_block * coda_read_super(struct super_block *sb, vc = &coda_comms[idx]; if (!vc->vc_inuse) { printk("coda_read_super: No pseudo device\n"); - return NULL; + return -EINVAL; } if ( vc->vc_sb ) { printk("coda_read_super: Device already mounted\n"); - return NULL; + return -EBUSY; } sbi = kmalloc(sizeof(struct coda_sb_info), GFP_KERNEL); if(!sbi) { - return NULL; + return -ENOMEM; } vc->vc_sb = sb; @@ -192,7 +190,7 @@ static struct super_block * coda_read_super(struct super_block *sb, printk("coda_read_super: coda_get_rootfid failed with %d\n", error); goto error; - } + } printk("coda_read_super: rootfid is %s\n", coda_f2s(&fid)); /* make root inode */ @@ -205,7 +203,7 @@ static struct super_block * coda_read_super(struct super_block *sb, printk("coda_read_super: rootinode is %ld dev %x\n", root->i_ino, kdev_val(root->i_dev)); sb->s_root = d_alloc_root(root); - return sb; + return 0; error: if (sbi) { @@ -216,7 +214,7 @@ static struct super_block * coda_read_super(struct super_block *sb, if (root) iput(root); - return NULL; + return -EINVAL; } static void coda_put_super(struct super_block *sb) @@ -313,5 +311,14 @@ static int coda_statfs(struct super_block *sb, struct statfs *buf) /* init_coda: used by filesystems.c to register coda */ -DECLARE_FSTYPE( coda_fs_type, "coda", coda_read_super, 0); +static struct super_block *coda_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_nodev(fs_type, flags, data, coda_fill_super); +} +struct file_system_type coda_fs_type = { + owner: THIS_MODULE, + name: "coda", + get_sb: coda_get_sb, +}; diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 3b7e37e96..dd3eef4dc 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -304,7 +304,7 @@ lockd_down(void) * Wait for the lockd process to exit, but since we're holding * the lockd semaphore, we can't wait around forever ... */ - current->work.sigpending = 0; + clear_thread_flag(TIF_SIGPENDING); interruptible_sleep_on_timeout(&lockd_exit, HZ); if (nlmsvc_pid) { printk(KERN_WARNING diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 1b4886e41..be821723b 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -163,8 +163,7 @@ static int minix_remount (struct super_block * sb, int * flags, char * data) return 0; } -static struct super_block *minix_read_super(struct super_block *s, void *data, - int silent) +static int minix_fill_super(struct super_block *s, void *data, int silent) { struct buffer_head *bh; struct buffer_head **map; @@ -273,7 +272,7 @@ static struct super_block *minix_read_super(struct super_block *s, void *data, else if (sbi->s_mount_state & MINIX_ERROR_FS) printk ("MINIX-fs: mounting file system with errors, " "running fsck is recommended.\n"); - return s; + return 0; out_iput: iput(root_inode); @@ -314,7 +313,7 @@ out_bad_hblock: out_bad_sb: printk("MINIX-fs: unable to read superblock\n"); out: - return NULL; + return -EINVAL; } static int minix_statfs(struct super_block *sb, struct statfs *buf) @@ -558,7 +557,18 @@ void minix_truncate(struct inode * inode) V2_minix_truncate(inode); } -static DECLARE_FSTYPE_DEV(minix_fs_type,"minix",minix_read_super); +static struct super_block *minix_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, minix_fill_super); +} + +static struct file_system_type minix_fs_type = { + owner: THIS_MODULE, + name: "minix", + get_sb: minix_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_minix_fs(void) { diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index e4ed0426d..4e79dcb47 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -300,8 +300,7 @@ ncp_delete_inode(struct inode *inode) clear_inode(inode); } -struct super_block * -ncp_read_super(struct super_block *sb, void *raw_data, int silent) +static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) { struct ncp_mount_data_kernel data; struct ncp_server *server; @@ -434,7 +433,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) ncp_unlock_server(server); if (error < 0) goto out_no_connect; - DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb)); + DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb)); #ifdef CONFIG_NCPFS_PACKET_SIGNING if (ncp_negotiate_size_and_options(server, default_bufsize, @@ -486,31 +485,31 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) root_inode = ncp_iget(sb, &finfo); if (!root_inode) goto out_no_root; - DPRINTK("ncp_read_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber); + DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber); sb->s_root = d_alloc_root(root_inode); if (!sb->s_root) goto out_no_root; sb->s_root->d_op = &ncp_dentry_operations; - return sb; + return 0; out_no_root: - printk(KERN_ERR "ncp_read_super: get root inode failed\n"); + printk(KERN_ERR "ncp_fill_super: get root inode failed\n"); iput(root_inode); goto out_disconnect; out_no_bufsize: - printk(KERN_ERR "ncp_read_super: could not get bufsize\n"); + printk(KERN_ERR "ncp_fill_super: could not get bufsize\n"); out_disconnect: ncp_lock_server(server); ncp_disconnect(server); ncp_unlock_server(server); goto out_free_packet; out_no_connect: - printk(KERN_ERR "ncp_read_super: Failed connection, error=%d\n", error); + printk(KERN_ERR "ncp_fill_super: Failed connection, error=%d\n", error); out_free_packet: vfree(server->packet); goto out_free_server; out_no_packet: - printk(KERN_ERR "ncp_read_super: could not alloc packet\n"); + printk(KERN_ERR "ncp_fill_super: could not alloc packet\n"); out_free_server: #ifdef CONFIG_NCPFS_NLS unload_nls(server->nls_io); @@ -527,16 +526,16 @@ out_free_server: out_bad_file2: fput(ncp_filp); out_bad_file: - printk(KERN_ERR "ncp_read_super: invalid ncp socket\n"); + printk(KERN_ERR "ncp_fill_super: invalid ncp socket\n"); goto out; out_bad_mount: - printk(KERN_INFO "ncp_read_super: kernel requires mount version %d\n", + printk(KERN_INFO "ncp_fill_super: kernel requires mount version %d\n", NCP_MOUNT_VERSION); goto out; out_no_data: - printk(KERN_ERR "ncp_read_super: missing data argument\n"); + printk(KERN_ERR "ncp_fill_super: missing data argument\n"); out: - return NULL; + return -EINVAL; } static void ncp_put_super(struct super_block *sb) @@ -750,7 +749,17 @@ int ncp_malloced; int ncp_current_malloced; #endif -static DECLARE_FSTYPE(ncp_fs_type, "ncpfs", ncp_read_super, 0); +static struct super_block *ncp_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_nodev(fs_type, flags, data, ncp_fill_super); +} + +static struct file_system_type ncp_fs_type = { + owner: THIS_MODULE, + name: "ncpfs", + get_sb: ncp_get_sb, +}; static int __init init_ncp_fs(void) { diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 7bb3338e2..a4a6d4ceb 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -468,7 +468,7 @@ exp_writelock(void) return 0; } - current->work.sigpending = 0; + clear_thread_flag(TIF_SIGPENDING); want_lock++; while (hash_count || hash_lock) { interruptible_sleep_on(&hash_wait); diff --git a/fs/proc/array.c b/fs/proc/array.c index d0fbb66a1..08993e30d 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -391,7 +391,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer) task->nswap, task->cnswap, task->exit_signal, - task->cpu); + task->thread_info->cpu); if(mm) mmput(mm); return res; diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 61727bc89..688ba2df2 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -460,8 +460,7 @@ smb_put_super(struct super_block *sb) } } -struct super_block * -smb_read_super(struct super_block *sb, void *raw_data, int silent) +int smb_fill_super(struct super_block *sb, void *raw_data, int silent) { struct smb_sb_info *server = &sb->u.smbfs_sb; struct smb_mount_data_kernel *mnt; @@ -561,7 +560,7 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) goto out_no_root; smb_new_dentry(sb->s_root); - return sb; + return 0; out_no_root: iput(root_inode); @@ -573,15 +572,15 @@ out_no_temp: smb_vfree(server->packet); out_no_mem: if (!server->mnt) - printk(KERN_ERR "smb_read_super: allocation failure\n"); + printk(KERN_ERR "smb_fill_super: allocation failure\n"); goto out_fail; out_wrong_data: printk(KERN_ERR "smbfs: mount_data version %d is not supported\n", ver); goto out_fail; out_no_data: - printk(KERN_ERR "smb_read_super: missing data argument\n"); + printk(KERN_ERR "smb_fill_super: missing data argument\n"); out_fail: - return NULL; + return -EINVAL; } static int @@ -706,7 +705,17 @@ int smb_current_kmalloced; int smb_current_vmalloced; #endif -static DECLARE_FSTYPE( smb_fs_type, "smbfs", smb_read_super, 0); +static struct super_block *smb_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_nodev(fs_type, flags, data, smb_fill_super); +} + +static struct file_system_type smb_fs_type = { + owner: THIS_MODULE, + name: "smbfs", + get_sb: smb_get_sb, +}; static int __init init_smb_fs(void) { diff --git a/fs/smbfs/proto.h b/fs/smbfs/proto.h index 65b18719d..1f240422b 100644 --- a/fs/smbfs/proto.h +++ b/fs/smbfs/proto.h @@ -53,7 +53,6 @@ extern void smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr); extern void smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr); extern void smb_invalidate_inodes(struct smb_sb_info *server); extern int smb_revalidate_inode(struct dentry *dentry); -extern struct super_block *smb_read_super(struct super_block *sb, void *raw_data, int silent); extern int smb_notify_change(struct dentry *dentry, struct iattr *attr); /* file.c */ extern struct address_space_operations smb_file_aops; diff --git a/fs/super.c b/fs/super.c index f9f6a9802..2a4cb3259 100644 --- a/fs/super.c +++ b/fs/super.c @@ -797,11 +797,6 @@ static struct super_block *__get_sb_bdev(struct file_system_type *fs_type, { return get_sb_bdev(fs_type, flags, dev_name, data, fill_super); } -static struct super_block *__get_sb_nodev(struct file_system_type *fs_type, - int flags, char *dev_name, void * data) -{ - return get_sb_nodev(fs_type, flags, data, fill_super); -} struct vfsmount * do_kern_mount(const char *fstype, int flags, char *name, void *data) @@ -820,8 +815,6 @@ do_kern_mount(const char *fstype, int flags, char *name, void *data) sb = type->get_sb(type, flags, name, data); else if (type->fs_flags & FS_REQUIRES_DEV) sb = __get_sb_bdev(type, flags, name, data); - else - sb = __get_sb_nodev(type, flags, name, data); if (IS_ERR(sb)) goto out_mnt; if (type->fs_flags & FS_NOMOUNT) diff --git a/fs/sysv/ChangeLog b/fs/sysv/ChangeLog index 5e13c96e2..adda37067 100644 --- a/fs/sysv/ChangeLog +++ b/fs/sysv/ChangeLog @@ -1,13 +1,18 @@ +Thu Feb 7 2002 Alexander Viro <viro@math.psu.edu> + + * super.c: switched to ->get_sb() + * ChangeLog: fixed dates ;-) + 2002-01-24 David S. Miller <davem@redhat.com> * inode.c: Include linux/init.h -Mon Jan 21 2001 Alexander Viro <viro@math.psu.edu> +Mon Jan 21 2002 Alexander Viro <viro@math.psu.edu> * ialloc.c (sysv_new_inode): zero SYSV_I(inode)->i_data out. * i_vnode renamed to vfs_inode. Sorry, but let's keep that consistent. -Sat Jan 19 2001 Christoph Hellwig <hch@infradead.org> +Sat Jan 19 2002 Christoph Hellwig <hch@infradead.org> * include/linux/sysv_fs.h (SYSV_I): Get fs-private inode data using list_entry() instead of inode->u. @@ -19,7 +24,7 @@ Sat Jan 19 2001 Christoph Hellwig <hch@infradead.org> in the case of failed register_filesystem for V7. (exit_sysv_fs): Destroy inode cache. -Sat Jan 19 2001 Christoph Hellwig <hch@infradead.org> +Sat Jan 19 2002 Christoph Hellwig <hch@infradead.org> * include/linux/sysv_fs.h: Include <linux/sysv_fs_i.h>, declare SYSV_I(). * dir.c (sysv_find_entry): Use SYSV_I() instead of ->u.sysv_i to @@ -32,7 +37,7 @@ Sat Jan 19 2001 Christoph Hellwig <hch@infradead.org> * symlink.c (sysv_readlink): Likewise. (sysv_follow_link): Likewise. -Fri Jan 4 2001 Alexander Viro <viro@math.psu.edu> +Fri Jan 4 2002 Alexander Viro <viro@math.psu.edu> * ialloc.c (sysv_free_inode): Use sb->s_id instead of bdevname(). * inode.c (sysv_read_inode): Likewise. diff --git a/fs/sysv/super.c b/fs/sysv/super.c index 1e853dd27..793578ec0 100644 --- a/fs/sysv/super.c +++ b/fs/sysv/super.c @@ -340,8 +340,7 @@ static int complete_read_super(struct super_block *sb, int silent, int size) return 1; } -static struct super_block *sysv_read_super(struct super_block *sb, - void *data, int silent) +static int sysv_fill_super(struct super_block *sb, void *data, int silent) { struct buffer_head *bh1; struct buffer_head *bh = NULL; @@ -397,7 +396,7 @@ static struct super_block *sysv_read_super(struct super_block *sb, sb->sv_bh1 = bh1; sb->sv_bh2 = bh; if (complete_read_super(sb, silent, size)) - return sb; + return 0; } brelse(bh1); @@ -405,7 +404,7 @@ static struct super_block *sysv_read_super(struct super_block *sb, sb_set_blocksize(sb, BLOCK_SIZE); printk("oldfs: cannot read superblock\n"); failed: - return NULL; + return -EINVAL; Eunknown: brelse(bh); @@ -421,8 +420,7 @@ Ebadsize: goto failed; } -static struct super_block *v7_read_super(struct super_block *sb,void *data, - int silent) +static int v7_fill_super(struct super_block *sb, void *data, int silent) { struct buffer_head *bh, *bh2 = NULL; struct v7_super_block *v7sb; @@ -466,18 +464,41 @@ static struct super_block *v7_read_super(struct super_block *sb,void *data, sb->sv_bh1 = bh; sb->sv_bh2 = bh; if (complete_read_super(sb, silent, 1)) - return sb; + return 0; failed: brelse(bh2); brelse(bh); - return NULL; + return -EINVAL; } /* Every kernel module contains stuff like this. */ -static DECLARE_FSTYPE_DEV(sysv_fs_type, "sysv", sysv_read_super); -static DECLARE_FSTYPE_DEV(v7_fs_type, "v7", v7_read_super); +static struct super_block *sysv_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, sysv_fill_super); +} + +static struct super_block *v7_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, v7_fill_super); +} + +static struct file_system_type sysv_fs_type = { + owner: THIS_MODULE, + name: "sysv", + get_sb: sysv_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; + +static struct file_system_type v7_fs_type = { + owner: THIS_MODULE, + name: "v7", + get_sb: v7_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; extern int sysv_init_icache(void) __init; extern void sysv_destroy_icache(void); diff --git a/include/asm-i386/current.h b/include/asm-i386/current.h index bc1496a2c..4385a95ce 100644 --- a/include/asm-i386/current.h +++ b/include/asm-i386/current.h @@ -1,14 +1,14 @@ #ifndef _I386_CURRENT_H #define _I386_CURRENT_H +#include <asm/thread_info.h> + struct task_struct; static inline struct task_struct * get_current(void) { - struct task_struct *current; - __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL)); - return current; - } + return current_thread_info()->task; +} #define current get_current() diff --git a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h index b321dd098..5b43b7c41 100644 --- a/include/asm-i386/hw_irq.h +++ b/include/asm-i386/hw_irq.h @@ -116,7 +116,8 @@ extern char _stext, _etext; #define GET_CURRENT \ "movl %esp, %ebx\n\t" \ - "andl $-8192, %ebx\n\t" + "andl $-8192, %ebx\n\t" \ + "movl (%ebx),%ebx\n\t" /* * SMP has a few special interrupts for IPI messages diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h index 1cf8dc2ab..3463340e4 100644 --- a/include/asm-i386/i387.h +++ b/include/asm-i386/i387.h @@ -28,16 +28,17 @@ extern void kernel_fpu_begin(void); #define unlazy_fpu( tsk ) do { \ - if ( tsk->flags & PF_USEDFPU ) \ + if (test_thread_flag(TIF_USEDFPU)) \ save_init_fpu( tsk ); \ } while (0) -#define clear_fpu( tsk ) do { \ - if ( tsk->flags & PF_USEDFPU ) { \ - asm volatile("fwait"); \ - tsk->flags &= ~PF_USEDFPU; \ - stts(); \ - } \ +#define clear_fpu( tsk ) \ +do { \ + if (test_thread_flag(TIF_USEDFPU)) { \ + asm volatile("fwait"); \ + clear_thread_flag(TIF_USEDFPU); \ + stts(); \ + } \ } while (0) /* diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index 34820d600..c457c7a7b 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h @@ -105,7 +105,7 @@ extern void smp_store_cpu_info(int id); /* Store per CPU info (like the initial * so this is correct in the x86 case. */ -#define smp_processor_id() (current->cpu) +#define smp_processor_id() (current_thread_info()->cpu) static __inline int hard_smp_processor_id(void) { diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h new file mode 100644 index 000000000..e8515e012 --- /dev/null +++ b/include/asm-i386/thread_info.h @@ -0,0 +1,113 @@ +/* thread_info.h: i386 low-level thread information + * + * Copyright (C) 2002 David Howells (dhowells@redhat.com) + * - Incorporating suggestions made by Linus Torvalds and Dave Miller + */ + +#ifndef _ASM_THREAD_INFO_H +#define _ASM_THREAD_INFO_H + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ +#include <asm/processor.h> +#endif + +/* + * low level task data that entry.S needs immediate access to + * - this struct should fit entirely inside of one cache line + * - this struct shares the supervisor stack pages + * - if the contents of this structure are changed, the assembly constants must also be changed + */ +#ifndef __ASSEMBLY__ +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + unsigned long flags; /* low level flags */ + __u32 cpu; /* current CPU */ + + mm_segment_t addr_limit; /* thread address space: + 0-0xBFFFFFFF for user-thead + 0-0xFFFFFFFF for kernel-thread + */ + + __u8 supervisor_stack[0]; +}; + +#else /* !__ASSEMBLY__ */ + +/* offsets into the thread_info struct for assembly code access */ +#define TI_TASK 0x00000000 +#define TI_EXEC_DOMAIN 0x00000004 +#define TI_FLAGS 0x00000008 +#define TI_CPU 0x0000000C +#define TI_ADDR_LIMIT 0x00000010 + +#endif + +/* + * macros/functions for gaining access to the thread information structure + */ +#ifndef __ASSEMBLY__ +#define INIT_THREAD_INFO(tsk) \ +{ \ + task: &tsk, \ + exec_domain: &default_exec_domain, \ + flags: 0, \ + cpu: 0, \ + addr_limit: KERNEL_DS, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + +/* how to get the thread information struct from C */ +static inline struct thread_info *current_thread_info(void) +{ + struct thread_info *ti; + __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~8191UL)); + return ti; +} + +/* thread information allocation */ +#define THREAD_SIZE (2*PAGE_SIZE) +#define alloc_thread_info() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) +#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) +#define get_thread_info(ti) get_task_struct((ti)->l_task) +#define put_thread_info(ti) put_task_struct((ti)->l_task) + +#else /* !__ASSEMBLY__ */ + +/* how to get the thread information struct from ASM */ +#define GET_THREAD_INFO(reg) \ + movl $-8192, reg; \ + andl %esp, reg + +#endif + +/* + * thread information flags + * - these are process state flags that various assembly files may need to access + * - pending work-to-be-done flags are in LSW + * - other flags in MSW + */ +#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ +#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ +#define TIF_SIGPENDING 2 /* signal pending */ +#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ +#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ + +#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) +#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) +#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) +#define _TIF_USEDFPU (1<<TIF_USEDFPU) +#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) + +#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ +#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_THREAD_INFO_H */ diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h index ecc669335..c932a6980 100644 --- a/include/asm-i386/uaccess.h +++ b/include/asm-i386/uaccess.h @@ -27,14 +27,14 @@ #define USER_DS MAKE_MM_SEG(PAGE_OFFSET) #define get_ds() (KERNEL_DS) -#define get_fs() (current->addr_limit) -#define set_fs(x) (current->addr_limit = (x)) +#define get_fs() (current_thread_info()->addr_limit) +#define set_fs(x) (current_thread_info()->addr_limit = (x)) #define segment_eq(a,b) ((a).seg == (b).seg) extern int __verify_write(const void *, unsigned long); -#define __addr_ok(addr) ((unsigned long)(addr) < (current->addr_limit.seg)) +#define __addr_ok(addr) ((unsigned long)(addr) < (current_thread_info()->addr_limit.seg)) /* * Uhhuh, this needs 33-bit arithmetic. We have a carry.. @@ -43,7 +43,7 @@ extern int __verify_write(const void *, unsigned long); unsigned long flag,sum; \ asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \ :"=&r" (flag), "=r" (sum) \ - :"1" (addr),"g" ((int)(size)),"g" (current->addr_limit.seg)); \ + :"1" (addr),"g" ((int)(size)),"g" (current_thread_info()->addr_limit.seg)); \ flag; }) #ifdef CONFIG_X86_WP_WORKS_OK diff --git a/include/asm-i386/xor.h b/include/asm-i386/xor.h index 5a99f5455..3130e8212 100644 --- a/include/asm-i386/xor.h +++ b/include/asm-i386/xor.h @@ -20,7 +20,7 @@ #define FPU_SAVE \ do { \ - if (!(current->flags & PF_USEDFPU)) \ + if (!test_thread_flag(TIF_USEDFPU)) \ __asm__ __volatile__ (" clts;\n"); \ __asm__ __volatile__ ("fsave %0; fwait": "=m"(fpu_save[0])); \ } while (0) @@ -28,7 +28,7 @@ #define FPU_RESTORE \ do { \ __asm__ __volatile__ ("frstor %0": : "m"(fpu_save[0])); \ - if (!(current->flags & PF_USEDFPU)) \ + if (!test_thread_flag(TIF_USEDFPU)) \ stts(); \ } while (0) diff --git a/include/asm-sparc64/a.out.h b/include/asm-sparc64/a.out.h index 12f58b4ea..7ebbfcd25 100644 --- a/include/asm-sparc64/a.out.h +++ b/include/asm-sparc64/a.out.h @@ -1,4 +1,4 @@ -/* $Id: a.out.h,v 1.7 2001-04-24 01:09:12 davem Exp $ */ +/* $Id: a.out.h,v 1.8 2002-02-09 19:49:31 davem Exp $ */ #ifndef __SPARC64_A_OUT_H__ #define __SPARC64_A_OUT_H__ @@ -95,7 +95,7 @@ struct relocation_info /* used when header.a_machtype == M_SPARC */ #ifdef __KERNEL__ -#define STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L) +#define STACK_TOP (test_thread_flag(TIF_32BIT) ? 0xf0000000 : 0x80000000000L) #endif diff --git a/include/asm-sparc64/checksum.h b/include/asm-sparc64/checksum.h index 2ee3622e3..81cc7570c 100644 --- a/include/asm-sparc64/checksum.h +++ b/include/asm-sparc64/checksum.h @@ -1,4 +1,4 @@ -/* $Id: checksum.h,v 1.18 2002-02-01 22:01:05 davem Exp $ */ +/* $Id: checksum.h,v 1.19 2002-02-09 19:49:31 davem Exp $ */ #ifndef __SPARC64_CHECKSUM_H #define __SPARC64_CHECKSUM_H @@ -45,7 +45,7 @@ csum_partial_copy_nocheck (const char *src, char *dst, int len, unsigned int sum) { int ret; - unsigned char cur_ds = current->thread.current_ds.seg; + unsigned char cur_ds = get_thread_current_ds(); __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "i" (ASI_P)); ret = csum_partial_copy_sparc64(src, dst, len, sum); __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" (cur_ds)); diff --git a/include/asm-sparc64/current.h b/include/asm-sparc64/current.h index 80652fb35..7683c6bdc 100644 --- a/include/asm-sparc64/current.h +++ b/include/asm-sparc64/current.h @@ -1,7 +1,8 @@ #ifndef _SPARC64_CURRENT_H #define _SPARC64_CURRENT_H -/* Sparc rules... */ -register struct task_struct *current asm("g6"); +#include <asm/thread_info.h> + +#define current (current_thread_info()->task) #endif /* !(_SPARC64_CURRENT_H) */ diff --git a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h index 69c60a722..dceb5dd89 100644 --- a/include/asm-sparc64/elf.h +++ b/include/asm-sparc64/elf.h @@ -1,4 +1,4 @@ -/* $Id: elf.h,v 1.31 2002-01-08 16:00:20 davem Exp $ */ +/* $Id: elf.h,v 1.32 2002-02-09 19:49:31 davem Exp $ */ #ifndef __ASM_SPARC64_ELF_H #define __ASM_SPARC64_ELF_H @@ -69,16 +69,11 @@ typedef struct { #ifdef __KERNEL__ #define SET_PERSONALITY(ex, ibcs2) \ -do { unsigned char flags = current->thread.flags; \ - if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ - flags |= SPARC_FLAG_32BIT; \ +do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ + set_thread_flag(TIF_32BIT); \ else \ - flags &= ~SPARC_FLAG_32BIT; \ - if (flags != current->thread.flags) { \ - /* flush_thread will update pgd cache */\ - current->thread.flags = flags; \ - } \ - \ + clear_thread_flag(TIF_32BIT); \ + /* flush_thread will update pgd cache */ \ if (ibcs2) \ set_personality(PER_SVR4); \ else if (current->personality != PER_LINUX32) \ diff --git a/include/asm-sparc64/fpumacro.h b/include/asm-sparc64/fpumacro.h index 3fd5cab0c..21d2740a8 100644 --- a/include/asm-sparc64/fpumacro.h +++ b/include/asm-sparc64/fpumacro.h @@ -14,7 +14,7 @@ struct fpustate { u32 regs[64]; }; -#define FPUSTATE (struct fpustate *)(((unsigned long)current) + AOFF_task_fpregs) +#define FPUSTATE (struct fpustate *)(current_thread_info()->fpregs) extern __inline__ unsigned long fprs_read(void) { diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index e8103b759..46ecb863e 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h @@ -1,4 +1,4 @@ -/* $Id: mmu_context.h,v 1.53 2002-01-30 01:40:00 davem Exp $ */ +/* $Id: mmu_context.h,v 1.54 2002-02-09 19:49:31 davem Exp $ */ #ifndef __SPARC64_MMU_CONTEXT_H #define __SPARC64_MMU_CONTEXT_H @@ -101,7 +101,7 @@ do { \ register unsigned long pgd_cache asm("o4"); \ paddr = __pa((__mm)->pgd); \ pgd_cache = 0UL; \ - if ((__tsk)->thread.flags & SPARC_FLAG_32BIT) \ + if ((__tsk)->thread_info->flags & _TIF_32BIT) \ pgd_cache = pgd_val((__mm)->pgd[0]) << 11UL; \ __asm__ __volatile__("wrpr %%g0, 0x494, %%pstate\n\t" \ "mov %3, %%g4\n\t" \ diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h index 86662d26a..68fe493d2 100644 --- a/include/asm-sparc64/page.h +++ b/include/asm-sparc64/page.h @@ -1,4 +1,4 @@ -/* $Id: page.h,v 1.38 2001-11-30 01:04:10 davem Exp $ */ +/* $Id: page.h,v 1.39 2002-02-09 19:49:31 davem Exp $ */ #ifndef _SPARC64_PAGE_H #define _SPARC64_PAGE_H @@ -95,7 +95,7 @@ typedef unsigned long iopgprot_t; #endif /* (STRICT_MM_TYPECHECKS) */ -#define TASK_UNMAPPED_BASE ((current->thread.flags & SPARC_FLAG_32BIT) ? \ +#define TASK_UNMAPPED_BASE (test_thread_flag(TIF_32BIT) ? \ (0x0000000070000000UL) : (PAGE_OFFSET)) #endif /* !(__ASSEMBLY__) */ diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index e013039e8..61615d5fc 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -1,4 +1,4 @@ -/* $Id: pgtable.h,v 1.155 2001-12-21 04:56:17 davem Exp $ +/* $Id: pgtable.h,v 1.156 2002-02-09 19:49:31 davem Exp $ * pgtable.h: SpitFire page table operations. * * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu) @@ -76,7 +76,7 @@ * is different so we can optimize correctly for 32-bit tasks. */ #define REAL_PTRS_PER_PMD (1UL << PMD_BITS) -#define PTRS_PER_PMD ((const int)((current->thread.flags & SPARC_FLAG_32BIT) ? \ +#define PTRS_PER_PMD ((const int)(test_thread_flag(TIF_32BIT) ? \ (1UL << (32 - (PAGE_SHIFT-3) - PAGE_SHIFT)) : (REAL_PTRS_PER_PMD))) /* @@ -90,8 +90,8 @@ (PAGE_SHIFT-3) + PMD_BITS))) /* Kernel has a separate 44bit address space. */ -#define USER_PTRS_PER_PGD ((const int)((current->thread.flags & SPARC_FLAG_32BIT) ? \ - (1) : (PTRS_PER_PGD))) +#define USER_PTRS_PER_PGD ((const int)(test_thread_flag(TIF_32BIT)) ? \ + (1) : (PTRS_PER_PGD)) #define FIRST_USER_PGD_NR 0 #define pte_ERROR(e) __builtin_trap() diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h index 8d6fdbe63..dbeacf216 100644 --- a/include/asm-sparc64/processor.h +++ b/include/asm-sparc64/processor.h @@ -1,4 +1,4 @@ -/* $Id: processor.h,v 1.81 2002-02-02 03:33:48 kanoj Exp $ +/* $Id: processor.h,v 1.82 2002-02-09 19:49:31 davem Exp $ * include/asm-sparc64/processor.h * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -44,29 +44,13 @@ #ifndef __ASSEMBLY__ -#define NSWINS 7 - typedef struct { unsigned char seg; } mm_segment_t; /* The Sparc processor specific thread struct. */ +/* XXX This should die, everything can go into thread_info now. */ struct thread_struct { - /* D$ line 1 */ - unsigned long ksp __attribute__ ((aligned(16))); - unsigned char wstate, cwp, flags; - mm_segment_t current_ds; - unsigned char w_saved, fpdepth, fault_code, use_blkcommit; - unsigned long fault_address; - unsigned char fpsaved[7]; - unsigned char __pad2; - - /* D$ line 2, 3, 4 */ - struct pt_regs *kregs; - unsigned long *utraps; - unsigned long gsr[7]; - unsigned long xfsr[7]; - #ifdef CONFIG_DEBUG_SPINLOCK /* How many spinlocks held by this thread. * Used with spin lock debugging to catch tasks @@ -74,96 +58,29 @@ struct thread_struct { */ int smp_lock_count; unsigned int smp_lock_pc; +#else + int dummy; /* f'in gcc bug... */ #endif - - struct reg_window reg_window[NSWINS]; - unsigned long rwbuf_stkptrs[NSWINS]; - - /* Performance counter state */ - u64 *user_cntd0, *user_cntd1; - u64 kernel_cntd0, kernel_cntd1; - u64 pcr_reg; }; #endif /* !(__ASSEMBLY__) */ -#define SPARC_FLAG_UNALIGNED 0x01 /* is allowed to do unaligned accesses */ -#define SPARC_FLAG_NEWSIGNALS 0x02 /* task wants new-style signals */ -#define SPARC_FLAG_32BIT 0x04 /* task is older 32-bit binary */ -#define SPARC_FLAG_NEWCHILD 0x08 /* task is just-spawned child process */ -#define SPARC_FLAG_PERFCTR 0x10 /* task has performance counters active */ - -#define FAULT_CODE_WRITE 0x01 /* Write access, implies D-TLB */ -#define FAULT_CODE_DTLB 0x02 /* Miss happened in D-TLB */ -#define FAULT_CODE_ITLB 0x04 /* Miss happened in I-TLB */ -#define FAULT_CODE_WINFIXUP 0x08 /* Miss happened during spill/fill */ - #ifndef CONFIG_DEBUG_SPINLOCK -#define INIT_THREAD { \ -/* ksp, wstate, cwp, flags, current_ds, */ \ - 0, 0, 0, 0, KERNEL_DS, \ -/* w_saved, fpdepth, fault_code, use_blkcommit, */ \ - 0, 0, 0, 0, \ -/* fault_address, fpsaved, __pad2, kregs, */ \ - 0, { 0 }, 0, 0, \ -/* utraps, gsr, xfsr, */ \ - 0, { 0 }, { 0 }, \ -/* reg_window */ \ - { { { 0, }, { 0, } }, }, \ -/* rwbuf_stkptrs */ \ - { 0, 0, 0, 0, 0, 0, 0, }, \ -/* user_cntd0, user_cndd1, kernel_cntd0, kernel_cntd0, pcr_reg */ \ - 0, 0, 0, 0, 0, \ +#define INIT_THREAD { \ + 0, \ } #else /* CONFIG_DEBUG_SPINLOCK */ #define INIT_THREAD { \ -/* ksp, wstate, cwp, flags, current_ds, */ \ - 0, 0, 0, 0, KERNEL_DS, \ -/* w_saved, fpdepth, fault_code, use_blkcommit, */ \ - 0, 0, 0, 0, \ -/* fault_address, fpsaved, __pad2, kregs, */ \ - 0, { 0 }, 0, 0, \ -/* utraps, gsr, xfsr, smp_lock_count, smp_lock_pc, */\ - 0, { 0 }, { 0 }, 0, 0, \ -/* reg_window */ \ - { { { 0, }, { 0, } }, }, \ -/* rwbuf_stkptrs */ \ - { 0, 0, 0, 0, 0, 0, 0, }, \ -/* user_cntd0, user_cndd1, kernel_cntd0, kernel_cntd0, pcr_reg */ \ - 0, 0, 0, 0, 0, \ +/* smp_lock_count, smp_lock_pc, */ \ + 0, 0, \ } #endif /* !(CONFIG_DEBUG_SPINLOCK) */ -#ifdef __KERNEL__ -#if PAGE_SHIFT == 13 -#define THREAD_SIZE (2*PAGE_SIZE) -#define THREAD_SHIFT (PAGE_SHIFT + 1) -#else /* PAGE_SHIFT == 13 */ -#define THREAD_SIZE PAGE_SIZE -#define THREAD_SHIFT PAGE_SHIFT -#endif /* PAGE_SHIFT == 13 */ -#endif /* __KERNEL__ */ - #ifndef __ASSEMBLY__ /* Return saved PC of a blocked thread. */ -extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t) -{ - unsigned long ret = 0xdeadbeefUL; - - if (t->ksp) { - unsigned long *sp; - sp = (unsigned long *)(t->ksp + STACK_BIAS); - if (((unsigned long)sp & (sizeof(long) - 1)) == 0UL && - sp[14]) { - unsigned long *fp; - fp = (unsigned long *)(sp[14] + STACK_BIAS); - if (((unsigned long)fp & (sizeof(long) - 1)) == 0UL) - ret = fp[15]; - } - } - return ret; -} +struct thread_info; +extern unsigned long thread_saved_pc(struct thread_info *); /* On Uniprocessor, even in RMO processes see TSO semantics */ #ifdef CONFIG_SMP @@ -179,13 +96,13 @@ do { \ regs->tpc = ((pc & (~3)) - 4); \ regs->tnpc = regs->tpc + 4; \ regs->y = 0; \ - current->thread.wstate = (1 << 3); \ - if (current->thread.utraps) { \ - if (*(current->thread.utraps) < 2) \ - kfree (current->thread.utraps); \ + set_thread_wstate(1 << 3); \ + if (current_thread_info()->utraps) { \ + if (*(current_thread_info()->utraps) < 2) \ + kfree(current_thread_info()->utraps); \ else \ - (*(current->thread.utraps))--; \ - current->thread.utraps = NULL; \ + (*(current_thread_info()->utraps))--; \ + current_thread_info()->utraps = NULL; \ } \ __asm__ __volatile__( \ "stx %%g0, [%0 + %2 + 0x00]\n\t" \ @@ -208,7 +125,7 @@ do { \ : \ : "r" (regs), "r" (sp - REGWIN_SZ - STACK_BIAS), \ "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ -} while(0) +} while (0) #define start_thread32(regs, pc, sp) \ do { \ @@ -219,13 +136,13 @@ do { \ regs->tpc = ((pc & (~3)) - 4); \ regs->tnpc = regs->tpc + 4; \ regs->y = 0; \ - current->thread.wstate = (2 << 3); \ - if (current->thread.utraps) { \ - if (*(current->thread.utraps) < 2) \ - kfree (current->thread.utraps); \ + set_thread_wstate(2 << 3); \ + if (current_thread_info()->utraps) { \ + if (*(current_thread_info()->utraps) < 2) \ + kfree(current_thread_info()->utraps); \ else \ - (*(current->thread.utraps))--; \ - current->thread.utraps = NULL; \ + (*(current_thread_info()->utraps))--; \ + current_thread_info()->utraps = NULL; \ } \ __asm__ __volatile__( \ "stx %%g0, [%0 + %2 + 0x00]\n\t" \ @@ -248,10 +165,10 @@ do { \ : \ : "r" (regs), "r" (sp - REGWIN32_SZ), \ "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \ -} while(0) +} while (0) /* Free all resources held by a thread. */ -#define release_thread(tsk) do { } while(0) +#define release_thread(tsk) do { } while (0) extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); @@ -262,19 +179,20 @@ extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); ({ extern void scheduling_functions_start_here(void); \ extern void scheduling_functions_end_here(void); \ unsigned long pc, fp, bias = 0; \ - unsigned long task_base = (unsigned long) (__TSK); \ + unsigned long thread_info_base; \ struct reg_window *rw; \ unsigned long __ret = 0; \ int count = 0; \ if (!(__TSK) || (__TSK) == current || \ (__TSK)->state == TASK_RUNNING) \ goto __out; \ + thread_info_base = (unsigned long) ((__TSK)->thread_info); \ bias = STACK_BIAS; \ - fp = (__TSK)->thread.ksp + bias; \ + fp = (__TSK)->thread_info->ksp + bias; \ do { \ /* Bogus frame pointer? */ \ - if (fp < (task_base + sizeof(struct task_struct)) || \ - fp >= (task_base + THREAD_SIZE)) \ + if (fp < (thread_info_base + sizeof(struct thread_info)) || \ + fp >= (thread_info_base + THREAD_SIZE)) \ break; \ rw = (struct reg_window *) fp; \ pc = rw->ins[7]; \ @@ -288,27 +206,11 @@ extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); __out: __ret; \ }) -#define KSTK_EIP(tsk) ((tsk)->thread.kregs->tpc) -#define KSTK_ESP(tsk) ((tsk)->thread.kregs->u_regs[UREG_FP]) - -#ifdef __KERNEL__ -/* Allocation and freeing of task_struct and kernel stack. */ -#if PAGE_SHIFT == 13 -#define alloc_task_struct() ((struct task_struct *)__get_free_pages(GFP_KERNEL, 1)) -#define free_task_struct(tsk) free_pages((unsigned long)(tsk),1) -#else /* PAGE_SHIFT == 13 */ -#define alloc_task_struct() ((struct task_struct *)__get_free_pages(GFP_KERNEL, 0)) -#define free_task_struct(tsk) free_pages((unsigned long)(tsk),0) -#endif /* PAGE_SHIFT == 13 */ -#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count) - -#define init_task (init_task_union.task) -#define init_stack (init_task_union.stack) +#define KSTK_EIP(tsk) ((tsk)->thread_info->kregs->tpc) +#define KSTK_ESP(tsk) ((tsk)->thread_info->kregs->u_regs[UREG_FP]) #define cpu_relax() udelay(1 + smp_processor_id()) -#endif /* __KERNEL__ */ - #endif /* !(__ASSEMBLY__) */ #endif /* !(__ASM_SPARC64_PROCESSOR_H) */ diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h index 386f474fa..b2e191da8 100644 --- a/include/asm-sparc64/ptrace.h +++ b/include/asm-sparc64/ptrace.h @@ -1,4 +1,4 @@ -/* $Id: ptrace.h,v 1.13 1997-09-17 17:27:51 davem Exp $ */ +/* $Id: ptrace.h,v 1.14 2002-02-09 19:49:32 davem Exp $ */ #ifndef _SPARC64_PTRACE_H #define _SPARC64_PTRACE_H @@ -110,8 +110,6 @@ extern void show_regs(struct pt_regs *); #define TRACEREG32_SZ 0x50 #define STACKFRAME32_SZ 0x60 #define REGWIN32_SZ 0x40 - -#include <asm/asm_offsets.h> #endif #ifdef __KERNEL__ diff --git a/include/asm-sparc64/sfp-machine.h b/include/asm-sparc64/sfp-machine.h index 49c77bd81..5015bb8d6 100644 --- a/include/asm-sparc64/sfp-machine.h +++ b/include/asm-sparc64/sfp-machine.h @@ -74,7 +74,7 @@ /* Obtain the current rounding mode. */ #ifndef FP_ROUNDMODE -#define FP_ROUNDMODE ((current->thread.xfsr[0] >> 30) & 0x3) +#define FP_ROUNDMODE ((current_thread_info()->xfsr[0] >> 30) & 0x3) #endif /* Exception flags. */ @@ -86,6 +86,6 @@ #define FP_HANDLE_EXCEPTIONS return _fex -#define FP_INHIBIT_RESULTS ((current->thread.xfsr[0] >> 23) & _fex) +#define FP_INHIBIT_RESULTS ((current_thread_info()->xfsr[0] >> 23) & _fex) #endif diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h index d73d3e657..ae5307391 100644 --- a/include/asm-sparc64/smp.h +++ b/include/asm-sparc64/smp.h @@ -103,7 +103,7 @@ extern __inline__ int hard_smp_processor_id(void) } } -#define smp_processor_id() (current->cpu) +#define smp_processor_id() (current_thread_info()->cpu) /* This needn't do anything as we do not sleep the cpu * inside of the idler task, so an interrupt is not needed diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h index 58976a090..f87be0c92 100644 --- a/include/asm-sparc64/system.h +++ b/include/asm-sparc64/system.h @@ -1,12 +1,12 @@ -/* $Id: system.h,v 1.68 2001-11-18 00:12:56 davem Exp $ */ +/* $Id: system.h,v 1.69 2002-02-09 19:49:31 davem Exp $ */ #ifndef __SPARC64_SYSTEM_H #define __SPARC64_SYSTEM_H #include <linux/config.h> #include <asm/ptrace.h> #include <asm/processor.h> -#include <asm/asm_offsets.h> #include <asm/visasm.h> +#include <asm/thread_info.h> #ifndef __ASSEMBLY__ /* @@ -174,19 +174,19 @@ if ((PREV)->thread.smp_lock_count) { \ */ #define switch_to(prev, next, last) \ do { CHECK_LOCKS(prev); \ - if (current->thread.flags & SPARC_FLAG_PERFCTR) { \ + if (test_thread_flag(TIF_PERFCTR)) { \ unsigned long __tmp; \ read_pcr(__tmp); \ - current->thread.pcr_reg = __tmp; \ + current_thread_info()->pcr_reg = __tmp; \ read_pic(__tmp); \ - current->thread.kernel_cntd0 += (unsigned int)(__tmp); \ - current->thread.kernel_cntd1 += ((__tmp) >> 32); \ + current_thread_info()->kernel_cntd0 += (unsigned int)(__tmp); \ + current_thread_info()->kernel_cntd1 += ((__tmp) >> 32); \ } \ save_and_clear_fpu(); \ /* If you are tempted to conditionalize the following */ \ /* so that ASI is only written if it changes, think again. */ \ __asm__ __volatile__("wr %%g0, %0, %%asi" \ - : : "r" (next->thread.current_ds.seg)); \ + : : "r" (__thread_flag_byte_ptr(next->thread_info)[TI_FLAG_BYTE_CURRENT_DS])); \ __asm__ __volatile__( \ "mov %%g6, %%g5\n\t" \ "wrpr %%g0, 0x95, %%pstate\n\t" \ @@ -202,7 +202,7 @@ do { CHECK_LOCKS(prev); \ "wrpr %%g1, %%cwp\n\t" \ "ldx [%%g6 + %3], %%o6\n\t" \ "ldub [%%g6 + %2], %%o5\n\t" \ - "ldub [%%g6 + %4], %%o7\n\t" \ + "ldx [%%g6 + %4], %%o7\n\t" \ "mov %%g6, %%l2\n\t" \ "wrpr %%o5, 0x0, %%wstate\n\t" \ "ldx [%%sp + 2047 + 0x70], %%i6\n\t" \ @@ -212,21 +212,18 @@ do { CHECK_LOCKS(prev); \ "wrpr %%g0, 0x96, %%pstate\n\t" \ "andcc %%o7, %6, %%g0\n\t" \ "bne,pn %%icc, ret_from_syscall\n\t" \ - " mov %%g5, %0\n\t" \ + " ldx [%%g5 + %7], %0\n\t" \ : "=&r" (last) \ - : "r" (next), \ - "i" ((const unsigned long)(&((struct task_struct *)0)->thread.wstate)),\ - "i" ((const unsigned long)(&((struct task_struct *)0)->thread.ksp)), \ - "i" ((const unsigned long)(&((struct task_struct *)0)->thread.flags)),\ - "i" ((const unsigned long)(&((struct task_struct *)0)->thread.cwp)), \ - "i" (SPARC_FLAG_NEWCHILD) \ + : "r" (next->thread_info), \ + "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_FLAGS), "i" (TI_CWP), \ + "i" (_TIF_NEWCHILD), "i" (TI_TASK) \ : "cc", "g1", "g2", "g3", "g5", "g7", \ "l2", "l3", "l4", "l5", "l6", "l7", \ "i0", "i1", "i2", "i3", "i4", "i5", \ "o0", "o1", "o2", "o3", "o4", "o5", "o7"); \ /* If you fuck with this, update ret_from_syscall code too. */ \ - if (current->thread.flags & SPARC_FLAG_PERFCTR) { \ - write_pcr(current->thread.pcr_reg); \ + if (test_thread_flag(TIF_PERFCTR)) { \ + write_pcr(current_thread_info()->pcr_reg); \ reset_pic(); \ } \ } while(0) diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h index 33d336309..a3025150d 100644 --- a/include/asm-sparc64/ttable.h +++ b/include/asm-sparc64/ttable.h @@ -1,9 +1,9 @@ -/* $Id: ttable.h,v 1.17 2001-11-28 23:32:16 davem Exp $ */ +/* $Id: ttable.h,v 1.18 2002-02-09 19:49:32 davem Exp $ */ #ifndef _SPARC64_TTABLE_H #define _SPARC64_TTABLE_H #include <linux/config.h> -#include <asm/asm_offsets.h> +#include <asm/thread_info.h> #include <asm/utrap.h> #define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop; @@ -104,14 +104,14 @@ mov num, %g1; \ nop;nop;nop; -#define TRAP_UTRAP(handler,lvl) \ - ldx [%g6 + AOFF_task_thread + AOFF_thread_utraps], %g1; \ - sethi %hi(109f), %g7; \ - brz,pn %g1, utrap; \ - or %g7, %lo(109f), %g7; \ - ba,pt %xcc, utrap; \ -109: ldx [%g1 + handler*8], %g1; \ - ba,pt %xcc, utrap_ill; \ +#define TRAP_UTRAP(handler,lvl) \ + ldx [%g6 + TI_UTRAPS], %g1; \ + sethi %hi(109f), %g7; \ + brz,pn %g1, utrap; \ + or %g7, %lo(109f), %g7; \ + ba,pt %xcc, utrap; \ +109: ldx [%g1 + handler*8], %g1; \ + ba,pt %xcc, utrap_ill; \ mov lvl, %o1; #ifdef CONFIG_SUNOS_EMUL diff --git a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h index 7c4bfd907..f1f87992f 100644 --- a/include/asm-sparc64/uaccess.h +++ b/include/asm-sparc64/uaccess.h @@ -1,4 +1,4 @@ -/* $Id: uaccess.h,v 1.34 2001-09-27 04:36:24 kanoj Exp $ */ +/* $Id: uaccess.h,v 1.35 2002-02-09 19:49:31 davem Exp $ */ #ifndef _ASM_UACCESS_H #define _ASM_UACCESS_H @@ -36,14 +36,14 @@ #define VERIFY_READ 0 #define VERIFY_WRITE 1 -#define get_fs() (current->thread.current_ds) +#define get_fs() ((mm_segment_t) { get_thread_current_ds() }) #define get_ds() (KERNEL_DS) #define segment_eq(a,b) ((a).seg == (b).seg) #define set_fs(val) \ do { \ - current->thread.current_ds = (val); \ + set_thread_current_ds((val).seg); \ __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg)); \ } while(0) diff --git a/include/linux/fs.h b/include/linux/fs.h index 8e3ce34f3..68902b1c4 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -964,17 +964,14 @@ struct super_block *get_sb_nodev(struct file_system_type *fs_type, int flags, void *data, int (*fill_super)(struct super_block *, void *, int)); -#define DECLARE_FSTYPE(var,type,read,flags) \ +#define DECLARE_FSTYPE_DEV(var,type,read) \ struct file_system_type var = { \ name: type, \ read_super: read, \ - fs_flags: flags, \ + fs_flags: FS_REQUIRES_DEV, \ owner: THIS_MODULE, \ } -#define DECLARE_FSTYPE_DEV(var,type,read) \ - DECLARE_FSTYPE(var,type,read,FS_REQUIRES_DEV) - /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ #define fops_get(fops) \ (((fops) && (fops)->owner) \ diff --git a/include/linux/gameport.h b/include/linux/gameport.h index 5e741a18c..4077fd8e1 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h @@ -2,11 +2,9 @@ #define _GAMEPORT_H /* - * $Id: gameport.h,v 1.11 2001/04/26 10:24:46 vojtech Exp $ + * $Id: gameport.h,v 1.20 2002/01/03 08:55:05 vojtech Exp $ * - * Copyright (c) 1999-2000 Vojtech Pavlik - * - * Sponsored by SuSE + * Copyright (c) 1999-2001 Vojtech Pavlik */ /* @@ -26,21 +24,27 @@ * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ -#include <linux/sched.h> -#include <linux/delay.h> #include <asm/io.h> +#include <linux/input.h> struct gameport; struct gameport { - void *private; - + void *private; /* Private pointer for joystick drivers */ + void *driver; /* Private pointer for gameport drivers */ + char *name; + char *phys; int number; + unsigned short idbus; + unsigned short idvendor; + unsigned short idproduct; + unsigned short idversion; + int io; int speed; int fuzz; @@ -59,6 +63,7 @@ struct gameport { struct gameport_dev { void *private; + char *name; void (*connect)(struct gameport *, struct gameport_dev *dev); void (*disconnect)(struct gameport *); @@ -74,8 +79,8 @@ void gameport_rescan(struct gameport *gameport); void gameport_register_port(struct gameport *gameport); void gameport_unregister_port(struct gameport *gameport); #else -static void __inline__ gameport_register_port(struct gameport *gameport) { return; } -static void __inline__ gameport_unregister_port(struct gameport *gameport) { return; } +void __inline__ gameport_register_port(struct gameport *gameport) { return; } +void __inline__ gameport_unregister_port(struct gameport *gameport) { return; } #endif void gameport_register_device(struct gameport_dev *dev); @@ -94,6 +99,7 @@ void gameport_unregister_device(struct gameport_dev *dev); #define GAMEPORT_ID_VENDOR_MICROSOFT 0x0007 #define GAMEPORT_ID_VENDOR_THRUSTMASTER 0x0008 #define GAMEPORT_ID_VENDOR_GRAVIS 0x0009 +#define GAMEPORT_ID_VENDOR_GUILLEMOT 0x000a static __inline__ void gameport_trigger(struct gameport *gameport) { @@ -134,7 +140,7 @@ static __inline__ int gameport_time(struct gameport *gameport, int time) static __inline__ void wait_ms(unsigned int ms) { - current->state = TASK_UNINTERRUPTIBLE; + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1 + ms * HZ / 1000); } diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 4da338417..9007fe56c 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -35,14 +35,6 @@ siglock: SPIN_LOCK_UNLOCKED \ } -#define INIT_TASK_WORK \ -{ \ - need_resched: 0, \ - syscall_trace: 0, \ - sigpending: 0, \ - notify_resume: 0, \ -} - /* * INIT_TASK is used to set up the first task table, touch at * your own risk!. Base=0, limit=0x1fffff (=2MB) @@ -50,10 +42,8 @@ #define INIT_TASK(tsk) \ { \ state: 0, \ + thread_info: &init_thread_info, \ flags: 0, \ - work: INIT_TASK_WORK, \ - addr_limit: KERNEL_DS, \ - exec_domain: &default_exec_domain, \ lock_depth: -1, \ __nice: DEF_USER_NICE, \ policy: SCHED_OTHER, \ diff --git a/include/linux/input.h b/include/linux/input.h index 3f961ae82..7ebdaaa7a 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -2,11 +2,9 @@ #define _INPUT_H /* - * $Id: input.h,v 1.34 2001/05/28 09:06:44 vojtech Exp $ + * $Id: input.h,v 1.57 2002/01/02 11:59:56 vojtech Exp $ * - * Copyright (c) 1999-2000 Vojtech Pavlik - * - * Sponsored by SuSE + * Copyright (c) 1999-2001 Vojtech Pavlik */ /* @@ -17,7 +15,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -25,8 +23,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by - * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic + * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ #ifdef __KERNEL__ @@ -64,17 +62,20 @@ struct input_event { #define EVIOCSREP _IOW('E', 0x03, int[2]) /* get repeat settings */ #define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */ #define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */ -#define EVIOCGKEY _IOR('E', 0x05, int[2]) /* get key value */ + #define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */ -#define EVIOCGBUS _IOR('E', 0x07, short[4]) /* get bus address */ +#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */ +#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */ + +#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global keystate */ +#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */ +#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */ #define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len) /* get event bits */ #define EVIOCGABS(abs) _IOR('E', 0x40 + abs, int[5]) /* get abs value/limits */ #define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */ #define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */ -#define EVIOCSGAIN _IOW('E', 0x82, unsigned short) /* Set overall gain */ -#define EVIOCSAUTOCENTER _IOW('E', 0x83, unsigned short) /* Enable or disable auto-centering */ #define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */ /* @@ -90,6 +91,8 @@ struct input_event { #define EV_SND 0x12 #define EV_REP 0x14 #define EV_FF 0x15 +#define EV_PWR 0x16 +#define EV_FF_STATUS 0x17 #define EV_MAX 0x1f /* @@ -304,8 +307,23 @@ struct input_event { #define KEY_PROG4 203 #define KEY_SUSPEND 205 #define KEY_CLOSE 206 - -#define KEY_UNKNOWN 220 +#define KEY_PLAY 207 +#define KEY_FASTFORWARD 208 +#define KEY_BASSBOOST 209 +#define KEY_PRINT 210 +#define KEY_HP 211 +#define KEY_CAMERA 212 +#define KEY_SOUND 213 +#define KEY_QUESTION 214 +#define KEY_EMAIL 215 +#define KEY_CHAT 216 +#define KEY_SEARCH 217 +#define KEY_CONNECT 218 +#define KEY_FINANCE 219 +#define KEY_SPORT 220 +#define KEY_SHOP 221 + +#define KEY_UNKNOWN 240 #define BTN_MISC 0x100 #define BTN_0 0x100 @@ -415,14 +433,16 @@ struct input_event { #define ABS_DISTANCE 0x19 #define ABS_TILT_X 0x1a #define ABS_TILT_Y 0x1b -#define ABS_MISC 0x1c -#define ABS_MAX 0x1f +#define ABS_VOLUME 0x20 +#define ABS_MISC 0x28 +#define ABS_MAX 0x3f /* * Misc events */ #define MSC_SERIAL 0x00 +#define MSC_PULSELED 0x01 #define MSC_MAX 0x07 /* @@ -468,6 +488,7 @@ struct input_event { #define BUS_PCI 0x01 #define BUS_ISAPNP 0x02 #define BUS_USB 0x03 +#define BUS_HIL 0x04 #define BUS_ISA 0x10 #define BUS_I8042 0x11 @@ -480,32 +501,42 @@ struct input_event { #define BUS_I2C 0x18 /* + * Values describing the status of an effect + */ +#define FF_STATUS_STOPPED 0x00 +#define FF_STATUS_PLAYING 0x01 +#define FF_STATUS_MAX 0x01 + +/* * Structures used in ioctls to upload effects to a device * The first structures are not passed directly by using ioctls. * They are sub-structures of the actually sent structure (called ff_effect) + * + * Ranges: + * 0 <= __u16 <= 65535 + * -32767 <= __s16 <= +32767 ! Not -32768 for lower bound ! */ struct ff_replay { - __u16 length; /* Duration of an effect */ + __u16 length; /* Duration of an effect in ms. All other times are also expressed in ms */ __u16 delay; /* Time to wait before to start playing an effect */ }; struct ff_trigger { __u16 button; /* Number of button triggering an effect */ - __u16 interval; /* Time to wait before an effect can be re-triggered */ + __u16 interval; /* Time to wait before an effect can be re-triggered (ms) */ }; struct ff_shape { - __u16 attack_length; /* Duration of attack */ - __s16 attack_level; /* Level at beginning of attack */ - __u16 fade_length; /* Duration of fade */ - __s16 fade_level; /* Level at end of fade */ + __u16 attack_length; /* Duration of attack (ms) */ + __u16 attack_level; /* Level at beginning of attack */ + __u16 fade_length; /* Duration of fade (ms) */ + __u16 fade_level; /* Level at end of fade */ }; /* FF_CONSTANT */ struct ff_constant_effect { - __s16 level; /* Strength of effect */ - __u16 direction; /* Direction of effect (see periodic effects) */ + __s16 level; /* Strength of effect. Negative values are OK */ struct ff_shape shape; }; @@ -514,12 +545,13 @@ struct ff_interactive_effect { /* Axis along which effect must be created. If null, the field named direction * is used * It is a bit array (ie to enable axes X and Y, use BIT(ABS_X) | BIT(ABS_Y) + * It overrides the value of ff_effect::direction, which is used only if + * axis == 0 */ __u16 axis; - __u16 direction; - __s16 right_saturation; /* Max level when joystick is on the right */ - __s16 left_saturation; /* Max level when joystick in on the left */ + __u16 right_saturation; /* Max level when joystick is on the right */ + __u16 left_saturation; /* Max level when joystick in on the left */ __s16 right_coeff; /* Indicates how fast the force grows when the joystick moves to the right */ @@ -533,12 +565,10 @@ struct ff_interactive_effect { /* FF_PERIODIC */ struct ff_periodic_effect { __u16 waveform; /* Kind of wave (sine, square...) */ - __u16 period; + __u16 period; /* in ms */ __s16 magnitude; /* Peak value */ __s16 offset; /* Mean value of wave (roughly) */ __u16 phase; /* 'Horizontal' shift */ - __u16 direction; /* Direction. 0 deg -> 0x0000 - 90 deg -> 0x4000 */ struct ff_shape shape; }; @@ -549,10 +579,17 @@ struct ff_periodic_effect { struct ff_effect { __u16 type; /* Following field denotes the unique id assigned to an effect. - * It is set by the driver. + * If user sets if to -1, a new effect is created, and its id is returned in the same field + * Else, the user sets it to the effect id it wants to update. */ __s16 id; + __u16 direction; /* Direction. 0 deg -> 0x0000 (down) + 90 deg -> 0x4000 (left) + 180 deg -> 0x8000 (up) + 270 deg -> 0xC000 (right) + */ + struct ff_trigger trigger; struct ff_replay replay; @@ -564,7 +601,7 @@ struct ff_effect { }; /* - * Buttons that can trigger effects. Use for example FF_BTN(BTN_TRIGGER) to + * Buttons that can trigger effects. Use for example FF_BTN(BTN_TRIGGER) to * access the bitmap. */ @@ -625,8 +662,11 @@ struct input_dev { void *private; - int number; char *name; + char *phys; + char *uniq; + int number; + unsigned short idbus; unsigned short idvendor; unsigned short idproduct; @@ -649,6 +689,9 @@ struct input_dev { unsigned int repeat_key; struct timer_list timer; + struct pm_dev *pm_dev; + int state; + int abs[ABS_MAX + 1]; int rep[REP_MAX + 1]; @@ -661,8 +704,12 @@ struct input_dev { int absfuzz[ABS_MAX + 1]; int absflat[ABS_MAX + 1]; + int only_one_writer; + int (*open)(struct input_dev *dev); void (*close)(struct input_dev *dev); + int (*accept)(struct input_dev *dev, struct file *file); + int (*flush)(struct input_dev *dev, struct file *file); int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect); int (*erase_effect)(struct input_dev *dev, int effect_id); @@ -671,16 +718,63 @@ struct input_dev { struct input_dev *next; }; +/* + * Structure for hotplug & device<->driver matching. + */ + +#define INPUT_DEVICE_ID_MATCH_BUS 1 +#define INPUT_DEVICE_ID_MATCH_VENDOR 2 +#define INPUT_DEVICE_ID_MATCH_PRODUCT 4 +#define INPUT_DEVICE_ID_MATCH_VERSION 8 + +#define INPUT_DEVICE_ID_MATCH_EVBIT 0x010 +#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x020 +#define INPUT_DEVICE_ID_MATCH_RELBIT 0x040 +#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x080 +#define INPUT_DEVICE_ID_MATCH_MSCIT 0x100 +#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x200 +#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x400 +#define INPUT_DEVICE_ID_MATCH_FFBIT 0x800 + +#define INPUT_DEVICE_ID_MATCH_DEVICE\ + (INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT) +#define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION\ + (INPUT_DEVICE_ID_MATCH_DEVICE | INPUT_DEVICE_ID_MATCH_VERSION) + +struct input_device_id { + + unsigned long flags; + + unsigned short idbus; + unsigned short idvendor; + unsigned short idproduct; + unsigned short idversion; + + unsigned long evbit[NBITS(EV_MAX)]; + unsigned long keybit[NBITS(KEY_MAX)]; + unsigned long relbit[NBITS(REL_MAX)]; + unsigned long absbit[NBITS(ABS_MAX)]; + unsigned long mscbit[NBITS(MSC_MAX)]; + unsigned long ledbit[NBITS(LED_MAX)]; + unsigned long sndbit[NBITS(SND_MAX)]; + unsigned long ffbit[NBITS(FF_MAX)]; + + unsigned long driver_info; +}; + struct input_handler { void *private; void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); - struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev); + struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id); void (*disconnect)(struct input_handle *handle); struct file_operations *fops; int minor; + char *name; + + struct input_device_id *id_table; struct input_handle *handle; struct input_handler *next; @@ -691,6 +785,7 @@ struct input_handle { void *private; int open; + char *name; struct input_dev *dev; struct input_handler *handler; @@ -708,6 +803,9 @@ void input_unregister_handler(struct input_handler *); int input_open_device(struct input_handle *); void input_close_device(struct input_handle *); +int input_accept_process(struct input_handle *handle, struct file *file); +int input_flush_device(struct input_handle* handle, struct file* file); + devfs_handle_t input_register_minor(char *name, int minor, int minor_base); void input_unregister_minor(devfs_handle_t handle); @@ -716,6 +814,8 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in #define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c)) #define input_report_rel(a,b,c) input_event(a, EV_REL, b, c) #define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c) +#define input_report_ff(a,b,c) input_event(a, EV_FF, b, c) +#define input_report_ff_status(a,b,c) input_event(a, EV_FF_STATUS, b, c) #endif #endif diff --git a/include/linux/ncp_fs.h b/include/linux/ncp_fs.h index 0f285d517..0dd1c21dc 100644 --- a/include/linux/ncp_fs.h +++ b/include/linux/ncp_fs.h @@ -228,7 +228,6 @@ static inline void ncp_kfree_s(void *obj, int size) /* linux/fs/ncpfs/inode.c */ int ncp_notify_change(struct dentry *, struct iattr *); -struct super_block *ncp_read_super(struct super_block *, void *, int); struct inode *ncp_iget(struct super_block *, struct ncp_entry_info *); void ncp_update_inode(struct inode *, struct ncp_entry_info *); void ncp_update_inode2(struct inode *, struct ncp_entry_info *); diff --git a/include/linux/pm.h b/include/linux/pm.h index 8cefa88e6..ab9305b09 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -103,8 +103,8 @@ struct pm_dev void *data; unsigned long flags; - int state; - int prev_state; + unsigned long state; + unsigned long prev_state; struct list_head entry; }; diff --git a/include/linux/sched.h b/include/linux/sched.h index 5d3f7b02c..78a5834f8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -13,6 +13,7 @@ extern unsigned long event; #include <linux/times.h> #include <linux/timex.h> #include <linux/rbtree.h> +#include <linux/thread_info.h> #include <asm/system.h> #include <asm/semaphore.h> @@ -229,37 +230,15 @@ extern struct user_struct root_user; typedef struct prio_array prio_array_t; -/* this struct must occupy one 32-bit chunk so that is can be read in one go */ -struct task_work { - __s8 need_resched; - __u8 syscall_trace; /* count of syscall interceptors */ - __u8 sigpending; - __u8 notify_resume; /* request for notification on - userspace execution resumption */ -} __attribute__((packed)); - struct task_struct { - /* - * offsets of these are hardcoded elsewhere - touch with care - */ volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ + struct thread_info *thread_info; + atomic_t usage; unsigned long flags; /* per process flags, defined below */ - volatile struct task_work work; - - mm_segment_t addr_limit; /* thread address space: - 0-0xBFFFFFFF for user-thead - 0-0xFFFFFFFF for kernel-thread - */ - struct exec_domain *exec_domain; - long __pad; unsigned long ptrace; int lock_depth; /* Lock depth */ - /* - * offset 32 begins here on 32-bit platforms. - */ - unsigned int cpu; int prio; long __nice; list_t run_list; @@ -368,6 +347,11 @@ struct task_struct { void *journal_info; }; +extern void __put_task_struct(struct task_struct *tsk); +#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) +#define put_task_struct(tsk) \ +do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0) + /* * Per process flags */ @@ -384,17 +368,14 @@ struct task_struct { #define PF_FREE_PAGES 0x00002000 /* per process page freeing */ #define PF_NOIO 0x00004000 /* avoid generating further I/O */ -#define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */ - /* * Ptrace flags */ #define PT_PTRACED 0x00000001 -#define PT_SYSCALLTRACE 0x00000002 /* T if syscall_trace is +1 for ptrace() */ -#define PT_DTRACE 0x00000004 /* delayed trace (used on m68k, i386) */ -#define PT_TRACESYSGOOD 0x00000008 -#define PT_PTRACE_CAP 0x00000010 /* ptracer can follow suid-exec */ +#define PT_DTRACE 0x00000002 /* delayed trace (used on m68k, i386) */ +#define PT_TRACESYSGOOD 0x00000004 +#define PT_PTRACE_CAP 0x00000008 /* ptracer can follow suid-exec */ /* * Limit the stack by to some sane default: root can always @@ -470,16 +451,17 @@ asmlinkage long sys_sched_yield(void); */ extern struct exec_domain default_exec_domain; -#ifndef INIT_TASK_SIZE -# define INIT_TASK_SIZE 2048*sizeof(long) +#ifndef INIT_THREAD_SIZE +# define INIT_THREAD_SIZE 2048*sizeof(long) #endif -union task_union { - struct task_struct task; - unsigned long stack[INIT_TASK_SIZE/sizeof(long)]; +union thread_union { + struct thread_info thread_info; + unsigned long stack[INIT_THREAD_SIZE/sizeof(long)]; }; -extern union task_union init_task_union; +extern union thread_union init_thread_union; +extern struct task_struct init_task; extern struct mm_struct init_mm; extern struct task_struct *init_tasks[NR_CPUS]; @@ -584,22 +566,6 @@ extern int kill_proc(pid_t, int, int); extern int do_sigaction(int, const struct k_sigaction *, struct k_sigaction *); extern int do_sigaltstack(const stack_t *, stack_t *, unsigned long); -static inline int signal_pending(struct task_struct *p) -{ - return (p->work.sigpending != 0); -} - -static inline int need_resched(void) -{ - return unlikely(current->work.need_resched != 0); -} - -static inline void cond_resched(void) -{ - if (need_resched()) - schedule(); -} - /* * Re-calculate pending state from the set of locally pending * signals, globally pending signals, and blocked signals. @@ -630,15 +596,6 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked) return ready != 0; } -/* Reevaluate whether the task has signals pending delivery. - This is required every time the blocked sigset_t changes. - All callers should have t->sigmask_lock. */ - -static inline void recalc_sigpending(struct task_struct *t) -{ - t->work.sigpending = has_pending_signals(&t->pending.signal, &t->blocked); -} - /* True if we are on the alternate signal stack. */ static inline int on_sig_stack(unsigned long sp) @@ -888,6 +845,72 @@ static inline char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, return res; } +/* set thread flags in other task's structures + * - see asm/thread_info.h for TIF_xxxx flags available + */ +static inline void set_tsk_thread_flag(struct task_struct *tsk, int flag) +{ + set_ti_thread_flag(tsk->thread_info,flag); +} + +static inline void clear_tsk_thread_flag(struct task_struct *tsk, int flag) +{ + clear_ti_thread_flag(tsk->thread_info,flag); +} + +static inline int test_and_set_tsk_thread_flag(struct task_struct *tsk, int flag) +{ + return test_and_set_ti_thread_flag(tsk->thread_info,flag); +} + +static inline int test_and_clear_tsk_thread_flag(struct task_struct *tsk, int flag) +{ + return test_and_clear_ti_thread_flag(tsk->thread_info,flag); +} + +static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag) +{ + return test_ti_thread_flag(tsk->thread_info,flag); +} + +static inline void set_tsk_need_resched(struct task_struct *tsk) +{ + set_tsk_thread_flag(tsk,TIF_NEED_RESCHED); +} + +static inline void clear_tsk_need_resched(struct task_struct *tsk) +{ + clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED); +} + +static inline int signal_pending(struct task_struct *p) +{ + return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING)); +} + +static inline int need_resched(void) +{ + return unlikely(test_thread_flag(TIF_NEED_RESCHED)); +} + +static inline void cond_resched(void) +{ + if (need_resched()) + schedule(); +} + +/* Reevaluate whether the task has signals pending delivery. + This is required every time the blocked sigset_t changes. + Athread cathreaders should have t->sigmask_lock. */ + +static inline void recalc_sigpending(struct task_struct *t) +{ + if (has_pending_signals(&t->pending.signal, &t->blocked)) + set_thread_flag(TIF_SIGPENDING); + else + clear_thread_flag(TIF_SIGPENDING); +} + #endif /* __KERNEL__ */ #endif diff --git a/include/linux/serio.h b/include/linux/serio.h index 3619a866e..fae360265 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h @@ -2,31 +2,29 @@ #define _SERIO_H /* - * $Id: serio.h,v 1.11 2001/05/29 02:58:50 jsimmons Exp $ + * $Id: serio.h,v 1.21 2001/12/19 05:15:21 skids Exp $ * - * Copyright (C) 1999 Vojtech Pavlik - * - * Sponsored by SuSE + * Copyright (C) 1999-2001 Vojtech Pavlik */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ /* @@ -42,23 +40,31 @@ struct serio { void *private; void *driver; + char *name; + char *phys; + int number; + + unsigned short idbus; + unsigned short idvendor; + unsigned short idproduct; + unsigned short idversion; unsigned long type; - int number; int (*write)(struct serio *, unsigned char); int (*open)(struct serio *); void (*close)(struct serio *); struct serio_dev *dev; - struct serio *next; }; struct serio_dev { void *private; + char *name; + void (*write_wakeup)(struct serio *); void (*interrupt)(struct serio *, unsigned char, unsigned int); void (*connect)(struct serio *, struct serio_dev *dev); void (*disconnect)(struct serio *); @@ -80,6 +86,13 @@ static __inline__ int serio_write(struct serio *serio, unsigned char data) return serio->write(serio, data); } +static __inline__ void serio_dev_write_wakeup(struct serio *serio) +{ + if (serio->dev && serio->dev->write_wakeup) { + serio->dev->write_wakeup(serio); + } +} + #define SERIO_TIMEOUT 1 #define SERIO_PARITY 2 @@ -87,6 +100,7 @@ static __inline__ int serio_write(struct serio *serio, unsigned char data) #define SERIO_XT 0x00000000UL #define SERIO_8042 0x01000000UL #define SERIO_RS232 0x02000000UL +#define SERIO_HIL_MLC 0x03000000UL #define SERIO_PROTO 0xFFUL #define SERIO_MSC 0x01 @@ -108,6 +122,9 @@ static __inline__ int serio_write(struct serio *serio, unsigned char data) #define SERIO_STOWAWAY 0x20 #define SERIO_H3600 0x21 #define SERIO_PS2SER 0x22 +#define SERIO_TWIDKBD 0x23 +#define SERIO_TWIDJOY 0x24 +#define SERIO_HIL 0x25 #define SERIO_ID 0xff00UL #define SERIO_EXTRA 0xff0000UL diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h new file mode 100644 index 000000000..926186379 --- /dev/null +++ b/include/linux/thread_info.h @@ -0,0 +1,82 @@ +/* thread_info.h: common low-level thread information accessors + * + * Copyright (C) 2002 David Howells (dhowells@redhat.com) + * - Incorporating suggestions made by Linus Torvalds + */ + +#ifndef _LINUX_THREAD_INFO_H +#define _LINUX_THREAD_INFO_H + +#include <asm/thread_info.h> +#include <asm/bitops.h> + +#ifdef __KERNEL__ + +/* + * flag set/clear/test wrappers + * - pass TIF_xxxx constants to these functions + */ + +static inline void set_thread_flag(int flag) +{ + set_bit(flag,¤t_thread_info()->flags); +} + +static inline void clear_thread_flag(int flag) +{ + clear_bit(flag,¤t_thread_info()->flags); +} + +static inline int test_and_set_thread_flag(int flag) +{ + return test_and_set_bit(flag,¤t_thread_info()->flags); +} + +static inline int test_and_clear_thread_flag(int flag) +{ + return test_and_clear_bit(flag,¤t_thread_info()->flags); +} + +static inline int test_thread_flag(int flag) +{ + return test_bit(flag,¤t_thread_info()->flags); +} + +static inline void set_ti_thread_flag(struct thread_info *ti, int flag) +{ + set_bit(flag,&ti->flags); +} + +static inline void clear_ti_thread_flag(struct thread_info *ti, int flag) +{ + clear_bit(flag,&ti->flags); +} + +static inline int test_and_set_ti_thread_flag(struct thread_info *ti, int flag) +{ + return test_and_set_bit(flag,&ti->flags); +} + +static inline int test_and_clear_ti_thread_flag(struct thread_info *ti, int flag) +{ + return test_and_clear_bit(flag,&ti->flags); +} + +static inline int test_ti_thread_flag(struct thread_info *ti, int flag) +{ + return test_bit(flag,&ti->flags); +} + +static inline void set_need_resched(void) +{ + set_thread_flag(TIF_NEED_RESCHED); +} + +static inline void clear_need_resched(void) +{ + clear_thread_flag(TIF_NEED_RESCHED); +} + +#endif + +#endif /* _LINUX_THREAD_INFO_H */ diff --git a/include/linux/usb.h b/include/linux/usb.h index d598c720a..b577fce7d 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1,6 +1,8 @@ #ifndef __LINUX_USB_H #define __LINUX_USB_H +#include <linux/device.h> + /* USB constants */ /* @@ -260,6 +262,7 @@ struct usb_interface { int max_altsetting; /* total memory allocated */ struct usb_driver *driver; /* driver */ + struct device dev; /* interface specific device info */ void *private_data; }; @@ -945,6 +948,7 @@ extern struct usb_bus *usb_alloc_bus(struct usb_operations *); extern void usb_free_bus(struct usb_bus *); extern void usb_register_bus(struct usb_bus *); extern void usb_deregister_bus(struct usb_bus *); +extern int usb_register_root_hub(struct usb_device *usb_dev, struct device *parent_dev); extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb); extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, @@ -1041,6 +1045,8 @@ struct usb_device { struct usb_device *parent; struct usb_bus *bus; /* Bus we're part of */ + struct device dev; /* Generic device interface */ + struct usb_device_descriptor descriptor;/* Descriptor */ struct usb_config_descriptor *config; /* All of the configs */ struct usb_config_descriptor *actconfig;/* the active configuration */ diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c index fc2c88549..7d5ea3598 100644 --- a/kernel/exec_domain.c +++ b/kernel/exec_domain.c @@ -67,8 +67,8 @@ default_handler(int segment, struct pt_regs *regp) } set_personality(pers); - if (current->exec_domain->handler != default_handler) - current->exec_domain->handler(segment, regp); + if (current_thread_info()->exec_domain->handler != default_handler) + current_thread_info()->exec_domain->handler(segment, regp); else send_sig(SIGSEGV, current, 1); } @@ -162,7 +162,7 @@ __set_personality(u_long personality) struct exec_domain *ep, *oep; ep = lookup_exec_domain(personality); - if (ep == current->exec_domain) { + if (ep == current_thread_info()->exec_domain) { current->personality = personality; return 0; } @@ -190,8 +190,8 @@ __set_personality(u_long personality) */ current->personality = personality; - oep = current->exec_domain; - current->exec_domain = ep; + oep = current_thread_info()->exec_domain; + current_thread_info()->exec_domain = ep; set_fs_altroot(); put_exec_domain(oep); diff --git a/kernel/exit.c b/kernel/exit.c index 429fd2908..6b5a7cba0 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -65,7 +65,7 @@ static void release_task(struct task_struct * p) __restore_flags(flags); p->pid = 0; - free_task_struct(p); + put_task_struct(p); } /* @@ -529,7 +529,7 @@ fake_volatile: if (current->leader) disassociate_ctty(1); - put_exec_domain(tsk->exec_domain); + put_exec_domain(tsk->thread_info->exec_domain); if (tsk->binfmt && tsk->binfmt->module) __MOD_DEC_USE_COUNT(tsk->binfmt->module); diff --git a/kernel/fork.c b/kernel/fork.c index bfbae1b15..3e49ad5c1 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -28,6 +28,8 @@ #include <asm/uaccess.h> #include <asm/mmu_context.h> +static kmem_cache_t *task_struct_cachep; + /* The idle threads do not count.. */ int nr_threads; @@ -70,6 +72,14 @@ void remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait) void __init fork_init(unsigned long mempages) { + /* create a slab on which task_structs can be allocated */ + task_struct_cachep = + kmem_cache_create("task_struct", + sizeof(struct task_struct),0, + SLAB_HWCACHE_ALIGN, NULL, NULL); + if (!task_struct_cachep) + panic("fork_init(): cannot create task_struct SLAB cache"); + /* * The default maximum number of threads is set to a safe * value: the thread structures can take up at most half @@ -81,6 +91,35 @@ void __init fork_init(unsigned long mempages) init_task.rlim[RLIMIT_NPROC].rlim_max = max_threads/2; } +struct task_struct *dup_task_struct(struct task_struct *orig) +{ + struct task_struct *tsk; + struct thread_info *ti; + + ti = alloc_thread_info(); + if (!ti) return NULL; + + tsk = kmem_cache_alloc(task_struct_cachep,GFP_ATOMIC); + if (!tsk) { + free_thread_info(ti); + return NULL; + } + + *ti = *orig->thread_info; + *tsk = *orig; + tsk->thread_info = ti; + ti->task = tsk; + atomic_set(&tsk->usage,1); + + return tsk; +} + +void __put_task_struct(struct task_struct *tsk) +{ + free_thread_info(tsk->thread_info); + kmem_cache_free(task_struct_cachep,tsk); +} + /* Protects next_safe and last_pid. */ spinlock_t lastpid_lock = SPIN_LOCK_UNLOCKED; @@ -546,7 +585,7 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p) { unsigned long new_flags = p->flags; - new_flags &= ~(PF_SUPERPRIV | PF_USEDFPU); + new_flags &= ~PF_SUPERPRIV; new_flags |= PF_FORKNOEXEC; if (!(clone_flags & CLONE_PTRACE)) p->ptrace = 0; @@ -585,12 +624,10 @@ int do_fork(unsigned long clone_flags, unsigned long stack_start, } retval = -ENOMEM; - p = alloc_task_struct(); + p = dup_task_struct(current); if (!p) goto fork_out; - *p = *current; - retval = -EAGAIN; if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur) { if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) @@ -608,7 +645,7 @@ int do_fork(unsigned long clone_flags, unsigned long stack_start, if (nr_threads >= max_threads) goto bad_fork_cleanup_count; - get_exec_domain(p->exec_domain); + get_exec_domain(p->thread_info->exec_domain); if (p->binfmt && p->binfmt->module) __MOD_INC_USE_COUNT(p->binfmt->module); @@ -631,7 +668,7 @@ int do_fork(unsigned long clone_flags, unsigned long stack_start, } spin_lock_init(&p->alloc_lock); - p->work.sigpending = 0; + clear_tsk_thread_flag(p,TIF_SIGPENDING); init_sigpending(&p->pending); p->it_real_value = p->it_virt_value = p->it_prof_value = 0; @@ -755,7 +792,7 @@ int do_fork(unsigned long clone_flags, unsigned long stack_start, * Let the child process run first, to avoid most of the * COW overhead when the child exec()s afterwards. */ - current->work.need_resched = 1; + set_need_resched(); fork_out: return retval; @@ -771,14 +808,14 @@ bad_fork_cleanup_fs: bad_fork_cleanup_files: exit_files(p); /* blocking */ bad_fork_cleanup: - put_exec_domain(p->exec_domain); + put_exec_domain(p->thread_info->exec_domain); if (p->binfmt && p->binfmt->module) __MOD_DEC_USE_COUNT(p->binfmt->module); bad_fork_cleanup_count: atomic_dec(&p->user->processes); free_uid(p->user); bad_fork_free: - free_task_struct(p); + put_task_struct(p); goto fork_out; } diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 4ff3e77b7..57e60f019 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -566,7 +566,8 @@ EXPORT_SYMBOL(__tasklet_hi_schedule); /* init task, for moving kthread roots - ought to export a function ?? */ -EXPORT_SYMBOL(init_task_union); +EXPORT_SYMBOL(init_task); +EXPORT_SYMBOL(init_thread_union); EXPORT_SYMBOL(tasklist_lock); EXPORT_SYMBOL(pidhash); diff --git a/kernel/pm.c b/kernel/pm.c index a33e7b26e..0992b66f0 100644 --- a/kernel/pm.c +++ b/kernel/pm.c @@ -154,7 +154,7 @@ void pm_unregister_all(pm_callback callback) int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data) { int status = 0; - int prev_state, next_state; + unsigned long prev_state, next_state; if (in_interrupt()) BUG(); @@ -163,7 +163,7 @@ int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data) case PM_SUSPEND: case PM_RESUME: prev_state = dev->state; - next_state = (int) data; + next_state = (unsigned long) data; if (prev_state != next_state) { if (dev->callback) status = (*dev->callback)(dev, rqst, data); diff --git a/kernel/signal.c b/kernel/signal.c index d648cff08..74d783557 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -23,7 +23,7 @@ #define DEBUG_SIG 0 #if DEBUG_SIG -#define SIG_SLAB_DEBUG (SLAB_DEBUG_FREE | SLAB_RED_ZONE /* | SLAB_POISON */) +#define SIG_SLAB_DEBUG (SLAB_RED_ZONE /* | SLAB_POISON */) #else #define SIG_SLAB_DEBUG 0 #endif @@ -105,7 +105,7 @@ static void flush_sigqueue(struct sigpending *queue) void flush_signals(struct task_struct *t) { - t->work.sigpending = 0; + clear_tsk_thread_flag(t,TIF_SIGPENDING); flush_sigqueue(&t->pending); } @@ -119,7 +119,7 @@ void exit_sighand(struct task_struct *tsk) if (atomic_dec_and_test(&sig->count)) kmem_cache_free(sigact_cachep, sig); } - tsk->work.sigpending = 0; + clear_tsk_thread_flag(tsk,TIF_SIGPENDING); flush_sigqueue(&tsk->pending); spin_unlock_irq(&tsk->sigmask_lock); } @@ -275,7 +275,7 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid, if (current->notifier) { if (sigismember(current->notifier_mask, sig)) { if (!(current->notifier)(current->notifier_data)) { - current->work.sigpending = 0; + clear_thread_flag(TIF_SIGPENDING); return 0; } } @@ -494,7 +494,7 @@ static int send_signal(int sig, struct siginfo *info, struct sigpending *signals */ static inline void signal_wake_up(struct task_struct *t) { - t->work.sigpending = 1; + set_tsk_thread_flag(t,TIF_SIGPENDING); #ifdef CONFIG_SMP /* @@ -507,7 +507,7 @@ static inline void signal_wake_up(struct task_struct *t) * process of changing - but no harm is done by that * other than doing an extra (lightweight) IPI interrupt. */ - if ((t->state == TASK_RUNNING) && (t->cpu != smp_processor_id())) + if ((t->state == TASK_RUNNING) && (t->thread_info->cpu != smp_processor_id())) kick_if_running(t); #endif if (t->state & TASK_INTERRUPTIBLE) { diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 6e3215867..fb480e53c 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -1109,7 +1109,7 @@ rpciod_killall(void) unsigned long flags; while (all_tasks) { - current->work.sigpending = 0; + clear_thread_flag(TIF_SIGPENDING); rpc_killall_tasks(NULL); __rpc_schedule(); if (all_tasks) { @@ -1183,7 +1183,7 @@ rpciod_down(void) * Usually rpciod will exit very quickly, so we * wait briefly before checking the process id. */ - current->work.sigpending = 0; + clear_thread_flag(TIF_SIGPENDING); yield(); /* * Display a message if we're going to wait longer. diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 3a65741e6..c7793beee 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -185,7 +185,7 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port) progp->pg_name, proto == IPPROTO_UDP? "udp" : "tcp", port); if (!port) - current->work.sigpending = 0; + clear_thread_flag(TIF_SIGPENDING); for (i = 0; i < progp->pg_nvers; i++) { if (progp->pg_vers[i] == NULL) |