aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavem <davem>2002-02-09 19:49:28 +0000
committerdavem <davem>2002-02-09 19:49:28 +0000
commit80048cfb639d5a43a554f7d7aa1be0152ab24d55 (patch)
treefcc74fdf27b55ba3fb5f0cf7464316377bb7c16f
parent35f6bf4a4e288f2ccd8f44cdd1b25384a0ea4f74 (diff)
downloadnetdev-vger-cvs-80048cfb639d5a43a554f7d7aa1be0152ab24d55.tar.gz
Merge mainline to 2.5.4-pre3
-rw-r--r--Documentation/networking/8139too.txt10
-rw-r--r--Documentation/networking/dl2k.txt35
-rw-r--r--Makefile2
-rw-r--r--arch/alpha/kernel/setup.c4
-rw-r--r--arch/alpha/mm/fault.c3
-rw-r--r--arch/i386/kernel/entry.S78
-rw-r--r--arch/i386/kernel/head.S2
-rw-r--r--arch/i386/kernel/i387.c4
-rw-r--r--arch/i386/kernel/init_task.c13
-rw-r--r--arch/i386/kernel/irq.c2
-rw-r--r--arch/i386/kernel/nmi.c5
-rw-r--r--arch/i386/kernel/process.c18
-rw-r--r--arch/i386/kernel/ptrace.c34
-rw-r--r--arch/i386/kernel/setup.c2
-rw-r--r--arch/i386/kernel/signal.c25
-rw-r--r--arch/i386/kernel/smpboot.c4
-rw-r--r--arch/i386/kernel/traps.c8
-rw-r--r--arch/i386/lib/getuser.S19
-rw-r--r--arch/ia64/kernel/entry.S1
-rw-r--r--arch/sparc64/Makefile8
-rw-r--r--arch/sparc64/defconfig1
-rw-r--r--arch/sparc64/kernel/Makefile116
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c4
-rw-r--r--arch/sparc64/kernel/binfmt_elf32.c2
-rw-r--r--arch/sparc64/kernel/entry.S60
-rw-r--r--arch/sparc64/kernel/etrap.S10
-rw-r--r--arch/sparc64/kernel/head.S8
-rw-r--r--arch/sparc64/kernel/init_task.c18
-rw-r--r--arch/sparc64/kernel/itlb_base.S6
-rw-r--r--arch/sparc64/kernel/process.c157
-rw-r--r--arch/sparc64/kernel/ptrace.c82
-rw-r--r--arch/sparc64/kernel/rtrap.S75
-rw-r--r--arch/sparc64/kernel/setup.c4
-rw-r--r--arch/sparc64/kernel/signal.c118
-rw-r--r--arch/sparc64/kernel/signal32.c173
-rw-r--r--arch/sparc64/kernel/smp.c10
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c12
-rw-r--r--arch/sparc64/kernel/sys_sparc.c110
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c12
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c8
-rw-r--r--arch/sparc64/kernel/trampoline.S6
-rw-r--r--arch/sparc64/kernel/traps.c94
-rw-r--r--arch/sparc64/kernel/ttable.S14
-rw-r--r--arch/sparc64/kernel/unaligned.c76
-rw-r--r--arch/sparc64/kernel/winfixup.S222
-rw-r--r--arch/sparc64/lib/VIScopy.S34
-rw-r--r--arch/sparc64/lib/VIScsum.S6
-rw-r--r--arch/sparc64/lib/VISsave.S51
-rw-r--r--arch/sparc64/lib/blockops.S8
-rw-r--r--arch/sparc64/lib/checksum.S4
-rw-r--r--arch/sparc64/math-emu/math.c72
-rw-r--r--arch/sparc64/mm/fault.c16
-rw-r--r--arch/sparc64/mm/init.c12
-rw-r--r--arch/sparc64/mm/ultra.S24
-rw-r--r--arch/sparc64/solaris/entry64.S39
-rw-r--r--arch/sparc64/solaris/misc.c9
-rw-r--r--drivers/block/blkpg.c3
-rw-r--r--drivers/hotplug/pci_hotplug_core.c6
-rw-r--r--drivers/ide/ide-disk.c17
-rw-r--r--drivers/ide/ide-taskfile.c161
-rw-r--r--drivers/input/evdev.c130
-rw-r--r--drivers/input/joydev.c89
-rw-r--r--drivers/input/joystick/iforce.c6
-rw-r--r--drivers/input/keybdev.c85
-rw-r--r--drivers/input/mousedev.c84
-rw-r--r--drivers/net/3c501.c91
-rw-r--r--drivers/net/3c503.c77
-rw-r--r--drivers/net/3c505.c95
-rw-r--r--drivers/net/3c507.c95
-rw-r--r--drivers/net/3c509.c92
-rw-r--r--drivers/net/3c515.c96
-rw-r--r--drivers/net/3c523.c75
-rw-r--r--drivers/net/3c527.c94
-rw-r--r--drivers/net/8139cp.c127
-rw-r--r--drivers/net/8139too.c248
-rw-r--r--drivers/net/Config.in1
-rw-r--r--drivers/net/Makefile12
-rw-r--r--drivers/net/au1000_eth.c8
-rw-r--r--drivers/net/de4x5.c4
-rw-r--r--drivers/net/dl2k.c218
-rw-r--r--drivers/net/dl2k.h33
-rw-r--r--drivers/net/epic100.c162
-rw-r--r--drivers/net/fealnx.c135
-rw-r--r--drivers/net/hamachi.c3
-rw-r--r--drivers/net/mii.c4
-rw-r--r--drivers/net/ns83820.c59
-rw-r--r--drivers/net/pci-skeleton.c17
-rw-r--r--drivers/net/pcmcia/3c589_cs.c77
-rw-r--r--drivers/net/pcmcia/aironet4500_cs.c71
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c69
-rw-r--r--drivers/net/pcmcia/xircom_tulip_cb.c3
-rw-r--r--drivers/net/slip.c6
-rw-r--r--drivers/net/starfire.c51
-rw-r--r--drivers/net/sundance.c31
-rw-r--r--drivers/net/tlan.c3
-rw-r--r--drivers/net/via-rhine.c161
-rw-r--r--drivers/net/wan/lmc/lmc_main.c12
-rw-r--r--drivers/net/winbond-840.c110
-rw-r--r--drivers/net/yellowfin.c3
-rw-r--r--drivers/sbus/char/sunkbd.c2
-rw-r--r--drivers/sbus/char/sunmouse.c2
-rw-r--r--drivers/usb/hcd/ehci-hcd.c2
-rw-r--r--drivers/usb/hcd/ohci-hcd.c2
-rw-r--r--drivers/usb/hub.c14
-rw-r--r--drivers/usb/uhci.c2
-rw-r--r--drivers/usb/usb-ohci.c2
-rw-r--r--drivers/usb/usb-uhci.c2
-rw-r--r--drivers/usb/usb.c44
-rw-r--r--fs/coda/inode.c27
-rw-r--r--fs/lockd/svc.c2
-rw-r--r--fs/minix/inode.c20
-rw-r--r--fs/ncpfs/inode.c37
-rw-r--r--fs/nfsd/export.c2
-rw-r--r--fs/proc/array.c2
-rw-r--r--fs/smbfs/inode.c23
-rw-r--r--fs/smbfs/proto.h1
-rw-r--r--fs/super.c7
-rw-r--r--fs/sysv/ChangeLog13
-rw-r--r--fs/sysv/super.c41
-rw-r--r--include/asm-i386/current.h8
-rw-r--r--include/asm-i386/hw_irq.h3
-rw-r--r--include/asm-i386/i387.h15
-rw-r--r--include/asm-i386/smp.h2
-rw-r--r--include/asm-i386/thread_info.h113
-rw-r--r--include/asm-i386/uaccess.h8
-rw-r--r--include/asm-i386/xor.h4
-rw-r--r--include/asm-sparc64/a.out.h4
-rw-r--r--include/asm-sparc64/checksum.h4
-rw-r--r--include/asm-sparc64/current.h5
-rw-r--r--include/asm-sparc64/elf.h15
-rw-r--r--include/asm-sparc64/fpumacro.h2
-rw-r--r--include/asm-sparc64/mmu_context.h4
-rw-r--r--include/asm-sparc64/page.h4
-rw-r--r--include/asm-sparc64/pgtable.h8
-rw-r--r--include/asm-sparc64/processor.h162
-rw-r--r--include/asm-sparc64/ptrace.h4
-rw-r--r--include/asm-sparc64/sfp-machine.h4
-rw-r--r--include/asm-sparc64/smp.h2
-rw-r--r--include/asm-sparc64/system.h31
-rw-r--r--include/asm-sparc64/ttable.h20
-rw-r--r--include/asm-sparc64/uaccess.h6
-rw-r--r--include/linux/fs.h7
-rw-r--r--include/linux/gameport.h30
-rw-r--r--include/linux/init_task.h12
-rw-r--r--include/linux/input.h166
-rw-r--r--include/linux/ncp_fs.h1
-rw-r--r--include/linux/pm.h4
-rw-r--r--include/linux/sched.h145
-rw-r--r--include/linux/serio.h39
-rw-r--r--include/linux/thread_info.h82
-rw-r--r--include/linux/usb.h6
-rw-r--r--kernel/exec_domain.c10
-rw-r--r--kernel/exit.c4
-rw-r--r--kernel/fork.c55
-rw-r--r--kernel/ksyms.c3
-rw-r--r--kernel/pm.c4
-rw-r--r--kernel/signal.c12
-rw-r--r--net/sunrpc/sched.c4
-rw-r--r--net/sunrpc/svc.c2
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
===========================
diff --git a/Makefile b/Makefile
index cd0b434d2..f1c5436e4 100644
--- a/Makefile
+++ b/Makefile
@@ -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(&current->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 = &current->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 = &current->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 = &current->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 = &current->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], &regs->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], &current->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 = &current->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(&current->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 = &current->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(&current->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(&current->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(&current->sigmask_lock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
sigaddset(&current->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 = &current->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 = &current->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(&current->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],
- &current->thread.reg_window[window],
+ &current_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],
- &current->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],
+ &current_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 = &current->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(&current->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(&current->sigmask_lock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
sigaddset(&current->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 = &current->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 &regs->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 (&ethcmd, 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 (&ethcmd, 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 (&ethcmd, 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 (&ethcmd, 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,&current_thread_info()->flags);
+}
+
+static inline void clear_thread_flag(int flag)
+{
+ clear_bit(flag,&current_thread_info()->flags);
+}
+
+static inline int test_and_set_thread_flag(int flag)
+{
+ return test_and_set_bit(flag,&current_thread_info()->flags);
+}
+
+static inline int test_and_clear_thread_flag(int flag)
+{
+ return test_and_clear_bit(flag,&current_thread_info()->flags);
+}
+
+static inline int test_thread_flag(int flag)
+{
+ return test_bit(flag,&current_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)