linux/debian/patches-arch/m68k.diff

5187 lines
153 KiB
Diff
Raw Normal View History

diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/Makefile linux-2.6.12/Makefile
--- linux-2.6.12-i386/Makefile 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/Makefile 2005-06-19 16:31:23.000000000 +0200
@@ -190,7 +190,7 @@
# Default value for CROSS_COMPILE is not to prefix executables
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
-ARCH ?= $(SUBARCH)
+ARCH ?= m68k
CROSS_COMPILE ?=
# Architecture as present in compile.h
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/arch/m68k/fpsp040/skeleton.S linux-2.6.12/arch/m68k/fpsp040/skeleton.S
--- linux-2.6.12-i386/arch/m68k/fpsp040/skeleton.S 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/arch/m68k/fpsp040/skeleton.S 2005-05-30 16:31:21.000000000 +0200
@@ -381,10 +381,8 @@
.Lnotkern:
SAVE_ALL_INT
GET_CURRENT(%d0)
- tstb %curptr@(TASK_NEEDRESCHED)
- jne ret_from_exception | deliver signals,
- | reschedule etc..
- RESTORE_ALL
+ | deliver signals, reschedule etc..
+ jra ret_from_exception
|
| mem_write --- write to user or supervisor address space
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/arch/m68k/ifpsp060/iskeleton.S linux-2.6.12/arch/m68k/ifpsp060/iskeleton.S
--- linux-2.6.12-i386/arch/m68k/ifpsp060/iskeleton.S 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/arch/m68k/ifpsp060/iskeleton.S 2005-05-30 16:31:22.000000000 +0200
@@ -75,10 +75,8 @@
.Lnotkern:
SAVE_ALL_INT
GET_CURRENT(%d0)
- tstb %curptr@(TASK_NEEDRESCHED)
- jne ret_from_exception | deliver signals,
- | reschedule etc..
- RESTORE_ALL
+ | deliver signals, reschedule etc..
+ jra ret_from_exception
|
| _060_real_chk():
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/arch/m68k/kernel/asm-offsets.c linux-2.6.12/arch/m68k/kernel/asm-offsets.c
--- linux-2.6.12-i386/arch/m68k/kernel/asm-offsets.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/arch/m68k/kernel/asm-offsets.c 2005-05-30 16:31:22.000000000 +0200
@@ -25,12 +25,8 @@
DEFINE(TASK_STATE, offsetof(struct task_struct, state));
DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
- DEFINE(TASK_WORK, offsetof(struct task_struct, thread.work));
- DEFINE(TASK_NEEDRESCHED, offsetof(struct task_struct, thread.work.need_resched));
- DEFINE(TASK_SYSCALL_TRACE, offsetof(struct task_struct, thread.work.syscall_trace));
- DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, thread.work.sigpending));
- DEFINE(TASK_NOTIFY_RESUME, offsetof(struct task_struct, thread.work.notify_resume));
DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+ DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
@@ -45,6 +41,10 @@
DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
+ /* offsets into the thread_info struct */
+ DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
+ DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
+
/* offsets into the pt_regs */
DEFINE(PT_D0, offsetof(struct pt_regs, d0));
DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0));
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/arch/m68k/kernel/bios32.c linux-2.6.12/arch/m68k/kernel/bios32.c
--- linux-2.6.12-i386/arch/m68k/kernel/bios32.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/arch/m68k/kernel/bios32.c 2004-10-20 16:38:00.000000000 +0200
@@ -285,7 +285,7 @@
DBG_DEVS(("layout_bus: starting bus %d\n", bus->number));
- if (!bus->devices && !bus->children)
+ if (list_empty(&bus->devices) && list_empty(&bus->children))
return;
/*
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/arch/m68k/kernel/entry.S linux-2.6.12/arch/m68k/kernel/entry.S
--- linux-2.6.12-i386/arch/m68k/kernel/entry.S 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/arch/m68k/kernel/entry.S 2005-05-30 16:31:22.000000000 +0200
@@ -44,9 +44,7 @@
#include <asm/offsets.h>
-.globl system_call, buserr, trap
-.globl resume, ret_from_exception
-.globl ret_from_signal
+.globl system_call, buserr, trap, resume
.globl inthandler, sys_call_table
.globl sys_fork, sys_clone, sys_vfork
.globl ret_from_interrupt, bad_interrupt
@@ -58,7 +56,7 @@
movel %sp,%sp@- | stack frame pointer argument
bsrl buserr_c
addql #4,%sp
- jra ret_from_exception
+ jra .Lret_from_exception
ENTRY(trap)
SAVE_ALL_INT
@@ -66,7 +64,7 @@
movel %sp,%sp@- | stack frame pointer argument
bsrl trap_c
addql #4,%sp
- jra ret_from_exception
+ jra .Lret_from_exception
| After a fork we jump here directly from resume,
| so that %d1 contains the previous task
@@ -75,30 +73,31 @@
movel %d1,%sp@-
jsr schedule_tail
addql #4,%sp
- jra ret_from_exception
+ jra .Lret_from_exception
-badsys:
- movel #-ENOSYS,%sp@(PT_D0)
- jra ret_from_exception
-
-do_trace:
+do_trace_entry:
movel #-ENOSYS,%sp@(PT_D0) | needed for strace
subql #4,%sp
SAVE_SWITCH_STACK
jbsr syscall_trace
RESTORE_SWITCH_STACK
addql #4,%sp
- movel %sp@(PT_ORIG_D0),%d1
- movel #-ENOSYS,%d0
- cmpl #NR_syscalls,%d1
- jcc 1f
- jbsr @(sys_call_table,%d1:l:4)@(0)
-1: movel %d0,%sp@(PT_D0) | save the return value
- subql #4,%sp | dummy return address
+ movel %sp@(PT_ORIG_D0),%d0
+ cmpl #NR_syscalls,%d0
+ jcs syscall
+badsys:
+ movel #-ENOSYS,%sp@(PT_D0)
+ jra ret_from_syscall
+
+do_trace_exit:
+ subql #4,%sp
SAVE_SWITCH_STACK
jbsr syscall_trace
+ RESTORE_SWITCH_STACK
+ addql #4,%sp
+ jra .Lret_from_exception
-ret_from_signal:
+ENTRY(ret_from_signal)
RESTORE_SWITCH_STACK
addql #4,%sp
/* on 68040 complete pending writebacks if any */
@@ -111,7 +110,7 @@
addql #4,%sp
1:
#endif
- jra ret_from_exception
+ jra .Lret_from_exception
ENTRY(system_call)
SAVE_ALL_SYS
@@ -120,30 +119,34 @@
| save top of frame
movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
- tstb %curptr@(TASK_SYSCALL_TRACE)
- jne do_trace
+ | syscall trace?
+ tstb %curptr@(TASK_INFO+TINFO_FLAGS+2)
+ jmi do_trace_entry
cmpl #NR_syscalls,%d0
jcc badsys
+syscall:
jbsr @(sys_call_table,%d0:l:4)@(0)
movel %d0,%sp@(PT_D0) | save the return value
-
+ret_from_syscall:
|oriw #0x0700,%sr
- movel %curptr@(TASK_WORK),%d0
+ movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0
jne syscall_exit_work
1: RESTORE_ALL
syscall_exit_work:
btst #5,%sp@(PT_SR) | check if returning to kernel
bnes 1b | if so, skip resched, signals
- tstw %d0
- jeq do_signal_return
- tstb %d0
- jne do_delayed_trace
-
+ lslw #1,%d0
+ jcs do_trace_exit
+ jmi do_delayed_trace
+ lslw #8,%d0
+ jmi do_signal_return
pea resume_userspace
- jmp schedule
+ jra schedule
+
-ret_from_exception:
+ENTRY(ret_from_exception)
+.Lret_from_exception:
btst #5,%sp@(PT_SR) | check if returning to kernel
bnes 1f | if so, skip resched, signals
| only allow interrupts when we are really the last one on the
@@ -152,19 +155,18 @@
andw #ALLOWINT,%sr
resume_userspace:
- movel %curptr@(TASK_WORK),%d0
- lsrl #8,%d0
+ moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0
jne exit_work
1: RESTORE_ALL
exit_work:
| save top of frame
movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
- tstb %d0
- jeq do_signal_return
-
+ lslb #1,%d0
+ jmi do_signal_return
pea resume_userspace
- jmp schedule
+ jra schedule
+
do_signal_return:
|andw #ALLOWINT,%sr
@@ -254,7 +256,7 @@
/* check if we need to do software interrupts */
tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING
- jeq ret_from_exception
+ jeq .Lret_from_exception
pea ret_from_exception
jra do_softirq
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/arch/m68k/kernel/m68k_ksyms.c linux-2.6.12/arch/m68k/kernel/m68k_ksyms.c
--- linux-2.6.12-i386/arch/m68k/kernel/m68k_ksyms.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/arch/m68k/kernel/m68k_ksyms.c 2004-10-20 16:38:00.000000000 +0200
@@ -46,6 +46,7 @@
EXPORT_SYMBOL(iounmap);
EXPORT_SYMBOL(kernel_set_cachemode);
#endif /* !CONFIG_SUN3 */
+EXPORT_SYMBOL(flush_icache_user_range);
EXPORT_SYMBOL(m68k_debug_device);
EXPORT_SYMBOL(mach_hwclk);
EXPORT_SYMBOL(mach_get_ss);
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/arch/m68k/kernel/process.c linux-2.6.12/arch/m68k/kernel/process.c
--- linux-2.6.12-i386/arch/m68k/kernel/process.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/arch/m68k/kernel/process.c 2004-10-20 16:38:00.000000000 +0200
@@ -245,7 +245,7 @@
unsigned long stack_offset, *retp;
stack_offset = THREAD_SIZE - sizeof(struct pt_regs);
- childregs = (struct pt_regs *) ((unsigned long) (p->thread_info) + stack_offset);
+ childregs = (struct pt_regs *) ((unsigned long) (p->stack) + stack_offset);
*childregs = *regs;
childregs->d0 = 0;
@@ -390,7 +390,7 @@
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
- stack_page = (unsigned long)(p->thread_info);
+ stack_page = (unsigned long)(p->stack);
fp = ((struct switch_stack *)p->thread.ksp)->a6;
do {
if (fp < stack_page+sizeof(struct thread_info) ||
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/arch/m68k/kernel/ptrace.c linux-2.6.12/arch/m68k/kernel/ptrace.c
--- linux-2.6.12-i386/arch/m68k/kernel/ptrace.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/arch/m68k/kernel/ptrace.c 2005-06-19 16:32:04.000000000 +0200
@@ -95,7 +95,7 @@
if (regno == PT_USP)
addr = &task->thread.usp;
else if (regno < sizeof(regoff)/sizeof(regoff[0]))
- addr = (unsigned long *) (task->thread.esp0 + regoff[regno]);
+ addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
else
return -1;
*addr = data;
@@ -103,48 +103,56 @@
}
/*
- * Called by kernel/ptrace.c when detaching..
- *
* Make sure the single step bit is not set.
*/
-void ptrace_disable(struct task_struct *child)
+static inline void singlestep_disable(struct task_struct *child)
{
- unsigned long tmp;
- /* make sure the single step bit is not set. */
- tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+ unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
put_reg(child, PT_SR, tmp);
- child->thread.work.delayed_trace = 0;
- child->thread.work.syscall_trace = 0;
+ clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ */
+void ptrace_disable(struct task_struct *child)
+{
+ singlestep_disable(child);
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
}
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
- int ret;
+ unsigned long tmp;
+ int i, ret = 0;
lock_kernel();
- ret = -EPERM;
if (request == PTRACE_TRACEME) {
/* are we already being traced? */
- if (current->ptrace & PT_PTRACED)
+ if (current->ptrace & PT_PTRACED) {
+ ret = -EPERM;
goto out;
+ }
/* set the ptrace bit in the process flags. */
current->ptrace |= PT_PTRACED;
- ret = 0;
goto out;
}
- ret = -ESRCH;
read_lock(&tasklist_lock);
child = find_task_by_pid(pid);
if (child)
get_task_struct(child);
read_unlock(&tasklist_lock);
- if (!child)
+ if (unlikely(!child)) {
+ ret = -ESRCH;
goto out;
+ }
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
+ /* you may not mess with init */
+ if (unlikely(pid == 1)) {
+ ret = -EPERM;
goto out_tsk;
+ }
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
@@ -152,234 +160,175 @@
}
ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
+ if (ret)
goto out_tsk;
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
- case PTRACE_PEEKTEXT: /* read word at location addr. */
- case PTRACE_PEEKDATA: {
- unsigned long tmp;
- int copied;
-
- copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
- ret = -EIO;
- if (copied != sizeof(tmp))
- break;
- ret = put_user(tmp,(unsigned long *) data);
- break;
- }
+ case PTRACE_PEEKTEXT: /* read word at location addr. */
+ case PTRACE_PEEKDATA:
+ i = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+ if (i != sizeof(tmp))
+ goto out_eio;
+ ret = put_user(tmp, (unsigned long *)data);
+ break;
/* read the word at location addr in the USER area. */
- case PTRACE_PEEKUSR: {
- unsigned long tmp;
-
- ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
- break;
-
- tmp = 0; /* Default return condition */
- addr = addr >> 2; /* temporary hack. */
- ret = -EIO;
- if (addr < 19) {
- tmp = get_reg(child, addr);
- if (addr == PT_SR)
- tmp >>= 16;
- } else if (addr >= 21 && addr < 49) {
- tmp = child->thread.fp[addr - 21];
-#ifdef CONFIG_M68KFPU_EMU
- /* Convert internal fpu reg representation
- * into long double format
- */
- if (FPU_IS_EMU && (addr < 45) && !(addr % 3))
- tmp = ((tmp & 0xffff0000) << 15) |
- ((tmp & 0x0000ffff) << 16);
-#endif
- } else
- break;
- ret = put_user(tmp,(unsigned long *) data);
- break;
- }
-
- /* when I and D space are separate, this will have to be fixed. */
- case PTRACE_POKETEXT: /* write the word at location addr. */
- case PTRACE_POKEDATA:
- ret = 0;
- if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
- break;
- ret = -EIO;
- break;
-
- case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
- ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
- break;
-
- addr = addr >> 2; /* temporary hack. */
-
- if (addr == PT_SR) {
- data &= SR_MASK;
- data <<= 16;
- data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
- }
- if (addr < 19) {
- if (put_reg(child, addr, data))
- break;
- ret = 0;
- break;
- }
- if (addr >= 21 && addr < 48)
- {
-#ifdef CONFIG_M68KFPU_EMU
- /* Convert long double format
- * into internal fpu reg representation
- */
- if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) {
- data = (unsigned long)data << 15;
- data = (data & 0xffff0000) |
- ((data & 0x0000ffff) >> 1);
- }
-#endif
- child->thread.fp[addr - 21] = data;
- ret = 0;
- }
- break;
-
- case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- case PTRACE_CONT: { /* restart after signal. */
- long tmp;
-
- ret = -EIO;
- if (!valid_signal(data))
- break;
- if (request == PTRACE_SYSCALL) {
- child->thread.work.syscall_trace = ~0;
- } else {
- child->thread.work.syscall_trace = 0;
- }
- child->exit_code = data;
- /* make sure the single step bit is not set. */
- tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
- put_reg(child, PT_SR, tmp);
- child->thread.work.delayed_trace = 0;
- wake_up_process(child);
- ret = 0;
- break;
- }
-
-/*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL: {
- long tmp;
-
- ret = 0;
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
- break;
- child->exit_code = SIGKILL;
- /* make sure the single step bit is not set. */
- tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
- put_reg(child, PT_SR, tmp);
- child->thread.work.delayed_trace = 0;
- wake_up_process(child);
- break;
- }
-
- case PTRACE_SINGLESTEP: { /* set the trap flag. */
- long tmp;
-
- ret = -EIO;
- if (!valid_signal(data))
- break;
- child->thread.work.syscall_trace = 0;
- tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
- put_reg(child, PT_SR, tmp);
- child->thread.work.delayed_trace = 1;
-
- child->exit_code = data;
- /* give it a chance to run. */
- wake_up_process(child);
- ret = 0;
- break;
- }
+ case PTRACE_PEEKUSR:
+ if (addr & 3)
+ goto out_eio;
+ addr >>= 2; /* temporary hack. */
+
+ if (addr >= 0 && addr < 19) {
+ tmp = get_reg(child, addr);
+ if (addr == PT_SR)
+ tmp >>= 16;
+ } else if (addr >= 21 && addr < 49) {
+ tmp = child->thread.fp[addr - 21];
+ /* Convert internal fpu reg representation
+ * into long double format
+ */
+ if (FPU_IS_EMU && (addr < 45) && !(addr % 3))
+ tmp = ((tmp & 0xffff0000) << 15) |
+ ((tmp & 0x0000ffff) << 16);
+ } else
+ break;
+ ret = put_user(tmp, (unsigned long *)data);
+ break;
+
+ /* when I and D space are separate, this will have to be fixed. */
+ case PTRACE_POKETEXT: /* write the word at location addr. */
+ case PTRACE_POKEDATA:
+ if (access_process_vm(child, addr, &data, sizeof(data), 1) != sizeof(data))
+ goto out_eio;
+ break;
+
+ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+ if (addr & 3)
+ goto out_eio;
+ addr >>= 2; /* temporary hack. */
+
+ if (addr == PT_SR) {
+ data &= SR_MASK;
+ data <<= 16;
+ data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
+ } else if (addr >= 0 && addr < 19) {
+ if (put_reg(child, addr, data))
+ goto out_eio;
+ } else if (addr >= 21 && addr < 48) {
+ /* Convert long double format
+ * into internal fpu reg representation
+ */
+ if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) {
+ data = (unsigned long)data << 15;
+ data = (data & 0xffff0000) |
+ ((data & 0x0000ffff) >> 1);
+ }
+ child->thread.fp[addr - 21] = data;
+ } else
+ goto out_eio;
+ break;
+
+ case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+ case PTRACE_CONT: /* restart after signal. */
+ if (!valid_signal(data))
+ goto out_eio;
+
+ if (request == PTRACE_SYSCALL)
+ set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ else
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ child->exit_code = data;
+ singlestep_disable(child);
+ wake_up_process(child);
+ break;
- case PTRACE_DETACH: /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
+ /*
+ * make the child exit. Best I can do is send it a sigkill.
+ * perhaps it should be put in the status that it wants to
+ * exit.
+ */
+ case PTRACE_KILL:
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
-
- case PTRACE_GETREGS: { /* Get all gp regs from the child. */
- int i;
- unsigned long tmp;
- for (i = 0; i < 19; i++) {
- tmp = get_reg(child, i);
- if (i == PT_SR)
+ child->exit_code = SIGKILL;
+ singlestep_disable(child);
+ wake_up_process(child);
+ break;
+
+ case PTRACE_SINGLESTEP: /* set the trap flag. */
+ if (!valid_signal(data))
+ goto out_eio;
+
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
+ put_reg(child, PT_SR, tmp);
+ set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
+
+ child->exit_code = data;
+ /* give it a chance to run. */
+ wake_up_process(child);
+ break;
+
+ case PTRACE_DETACH: /* detach a process that was attached. */
+ ret = ptrace_detach(child, data);
+ break;
+
+ case PTRACE_GETREGS: /* Get all gp regs from the child. */
+ for (i = 0; i < 19; i++) {
+ tmp = get_reg(child, i);
+ if (i == PT_SR)
tmp >>= 16;
- if (put_user(tmp, (unsigned long *) data)) {
- ret = -EFAULT;
+ ret = put_user(tmp, (unsigned long *)data);
+ if (ret)
break;
- }
- data += sizeof(long);
- }
- ret = 0;
- break;
+ data += sizeof(long);
}
+ break;
- case PTRACE_SETREGS: { /* Set all gp regs in the child. */
- int i;
- unsigned long tmp;
- for (i = 0; i < 19; i++) {
- if (get_user(tmp, (unsigned long *) data)) {
- ret = -EFAULT;
+ case PTRACE_SETREGS: /* Set all gp regs in the child. */
+ for (i = 0; i < 19; i++) {
+ ret = get_user(tmp, (unsigned long *)data);
+ if (ret)
break;
- }
- if (i == PT_SR) {
+ if (i == PT_SR) {
tmp &= SR_MASK;
tmp <<= 16;
tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
- }
- put_reg(child, i, tmp);
- data += sizeof(long);
}
- ret = 0;
- break;
- }
-
- case PTRACE_GETFPREGS: { /* Get the child FPU state. */
- ret = 0;
- if (copy_to_user((void *)data, &child->thread.fp,
- sizeof(struct user_m68kfp_struct)))
- ret = -EFAULT;
- break;
+ put_reg(child, i, tmp);
+ data += sizeof(long);
}
+ break;
- case PTRACE_SETFPREGS: { /* Set the child FPU state. */
- ret = 0;
- if (copy_from_user(&child->thread.fp, (void *)data,
- sizeof(struct user_m68kfp_struct)))
- ret = -EFAULT;
- break;
- }
-
- default:
- ret = ptrace_request(child, request, addr, data);
- break;
+ case PTRACE_GETFPREGS: /* Get the child FPU state. */
+ if (copy_to_user((void *)data, &child->thread.fp,
+ sizeof(struct user_m68kfp_struct)))
+ ret = -EFAULT;
+ break;
+
+ case PTRACE_SETFPREGS: /* Set the child FPU state. */
+ if (copy_from_user(&child->thread.fp, (void *)data,
+ sizeof(struct user_m68kfp_struct)))
+ ret = -EFAULT;
+ break;
+
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
}
out_tsk:
put_task_struct(child);
out:
unlock_kernel();
return ret;
+out_eio:
+ ret = -EIO;
+ goto out_tsk;
}
asmlinkage void syscall_trace(void)
{
- if (!current->thread.work.delayed_trace &&
- !current->thread.work.syscall_trace)
- return;
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
/*
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/arch/m68k/mm/Makefile linux-2.6.12/arch/m68k/mm/Makefile
--- linux-2.6.12-i386/arch/m68k/mm/Makefile 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/arch/m68k/mm/Makefile 2004-02-06 14:59:40.000000000 +0100
@@ -2,7 +2,7 @@
# Makefile for the linux m68k-specific parts of the memory manager.
#
-obj-y := init.o fault.o hwtest.o
+obj-y := cache.o init.o fault.o hwtest.o
obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o
obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/arch/m68k/mm/cache.c linux-2.6.12/arch/m68k/mm/cache.c
--- linux-2.6.12-i386/arch/m68k/mm/cache.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.12/arch/m68k/mm/cache.c 2004-04-05 16:34:15.000000000 +0200
@@ -0,0 +1,160 @@
+/*
+ * linux/arch/m68k/mm/cache.c
+ *
+ * Instruction cache handling
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ */
+
+#include <asm/pgalloc.h>
+#include <asm/traps.h>
+
+
+static unsigned long virt_to_phys_slow(unsigned long vaddr, mm_segment_t fs)
+{
+ if (CPU_IS_060) {
+ mm_segment_t old_fs = get_fs();
+ unsigned long paddr;
+
+ set_fs(fs);
+
+ /* The PLPAR instruction causes an access error if the translation
+ * is not possible. To catch this we use the same exception mechanism
+ * as for user space accesses in <asm/uaccess.h>. */
+ asm volatile (".chip 68060\n"
+ "1: plpar (%0)\n"
+ ".chip 68k\n"
+ "2:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "3: sub.l %0,%0\n"
+ " jra 2b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,3b\n"
+ ".previous"
+ : "=a" (paddr)
+ : "0" (vaddr));
+ set_fs(old_fs);
+ return paddr;
+ } else if (CPU_IS_040) {
+ mm_segment_t old_fs = get_fs();
+ unsigned long mmusr;
+
+ set_fs(fs);
+
+ asm volatile (".chip 68040\n\t"
+ "ptestr (%1)\n\t"
+ "movec %%mmusr, %0\n\t"
+ ".chip 68k"
+ : "=r" (mmusr)
+ : "a" (vaddr));
+ set_fs(old_fs);
+
+ if (mmusr & MMU_R_040)
+ return (mmusr & PAGE_MASK) | (vaddr & ~PAGE_MASK);
+ } else {
+ unsigned short mmusr;
+ unsigned long *descaddr;
+
+ asm volatile ("ptestr %3,%2@,#7,%0\n\t"
+ "pmove %%psr,%1@"
+ : "=a&" (descaddr)
+ : "a" (&mmusr), "a" (vaddr), "d" (fs.seg));
+ if (mmusr & (MMU_I|MMU_B|MMU_L))
+ return 0;
+ descaddr = phys_to_virt((unsigned long)descaddr);
+ switch (mmusr & MMU_NUM) {
+ case 1:
+ return (*descaddr & 0xfe000000) | (vaddr & 0x01ffffff);
+ case 2:
+ return (*descaddr & 0xfffc0000) | (vaddr & 0x0003ffff);
+ case 3:
+ return (*descaddr & PAGE_MASK) | (vaddr & ~PAGE_MASK);
+ }
+ }
+ return 0;
+}
+
+/* Push n pages at kernel virtual address and clear the icache */
+/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
+void flush_icache_range(unsigned long address, unsigned long endaddr)
+{
+ if (CPU_IS_040_OR_060) {
+ address &= PAGE_MASK;
+
+ if (address >= PAGE_OFFSET && address < (unsigned long)high_memory) {
+ do {
+ asm volatile ("nop\n\t"
+ ".chip 68040\n\t"
+ "cpushp %%bc,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (virt_to_phys((void *)address)));
+ address += PAGE_SIZE;
+ } while (address < endaddr);
+ } else {
+ do {
+ asm volatile ("nop\n\t"
+ ".chip 68040\n\t"
+ "cpushp %%bc,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (virt_to_phys_slow(address, KERNEL_DS)));
+ address += PAGE_SIZE;
+ } while (address < endaddr);
+ }
+ } else {
+ unsigned long tmp;
+ asm volatile ("movec %%cacr,%0\n\t"
+ "orw %1,%0\n\t"
+ "movec %0,%%cacr"
+ : "=&d" (tmp)
+ : "di" (FLUSH_I));
+ }
+}
+
+void flush_icache_user_range(void *addr, unsigned long size)
+{
+ unsigned long address = (unsigned long)addr;
+ unsigned long endaddr = address + size;
+
+ if (CPU_IS_040_OR_060) {
+ address &= PAGE_MASK;
+
+ do {
+ asm volatile ("nop\n\t"
+ ".chip 68040\n\t"
+ "cpushp %%bc,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (virt_to_phys_slow(address, get_fs())));
+ address += PAGE_SIZE;
+ } while (address < endaddr);
+ } else {
+ unsigned long tmp;
+ asm volatile ("movec %%cacr,%0\n\t"
+ "orw %1,%0\n\t"
+ "movec %0,%%cacr"
+ : "=&d" (tmp)
+ : "di" (FLUSH_I));
+ }
+}
+
+void flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
+ unsigned long addr, int len)
+{
+ if (CPU_IS_040_OR_060) {
+ asm volatile ("nop\n\t"
+ ".chip 68040\n\t"
+ "cpushp %%bc,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (page_to_phys(page)));
+ } else {
+ unsigned long tmp;
+ asm volatile ("movec %%cacr,%0\n\t"
+ "orw %1,%0\n\t"
+ "movec %0,%%cacr"
+ : "=&d" (tmp)
+ : "di" (FLUSH_I));
+ }
+}
+
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/arch/m68k/mm/memory.c linux-2.6.12/arch/m68k/mm/memory.c
--- linux-2.6.12-i386/arch/m68k/mm/memory.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/arch/m68k/mm/memory.c 2004-10-03 16:35:42.000000000 +0200
@@ -354,110 +354,6 @@
#endif
}
-static unsigned long virt_to_phys_slow(unsigned long vaddr)
-{
- if (CPU_IS_060) {
- mm_segment_t fs = get_fs();
- unsigned long paddr;
-
- set_fs(get_ds());
-
- /* The PLPAR instruction causes an access error if the translation
- * is not possible. To catch this we use the same exception mechanism
- * as for user space accesses in <asm/uaccess.h>. */
- asm volatile (".chip 68060\n"
- "1: plpar (%0)\n"
- ".chip 68k\n"
- "2:\n"
- ".section .fixup,\"ax\"\n"
- " .even\n"
- "3: sub.l %0,%0\n"
- " jra 2b\n"
- ".previous\n"
- ".section __ex_table,\"a\"\n"
- " .align 4\n"
- " .long 1b,3b\n"
- ".previous"
- : "=a" (paddr)
- : "0" (vaddr));
- set_fs(fs);
- return paddr;
- } else if (CPU_IS_040) {
- mm_segment_t fs = get_fs();
- unsigned long mmusr;
-
- set_fs(get_ds());
-
- asm volatile (".chip 68040\n\t"
- "ptestr (%1)\n\t"
- "movec %%mmusr, %0\n\t"
- ".chip 68k"
- : "=r" (mmusr)
- : "a" (vaddr));
- set_fs(fs);
-
- if (mmusr & MMU_R_040)
- return (mmusr & PAGE_MASK) | (vaddr & ~PAGE_MASK);
- } else {
- unsigned short mmusr;
- unsigned long *descaddr;
-
- asm volatile ("ptestr #5,%2@,#7,%0\n\t"
- "pmove %%psr,%1@"
- : "=a&" (descaddr)
- : "a" (&mmusr), "a" (vaddr));
- if (mmusr & (MMU_I|MMU_B|MMU_L))
- return 0;
- descaddr = phys_to_virt((unsigned long)descaddr);
- switch (mmusr & MMU_NUM) {
- case 1:
- return (*descaddr & 0xfe000000) | (vaddr & 0x01ffffff);
- case 2:
- return (*descaddr & 0xfffc0000) | (vaddr & 0x0003ffff);
- case 3:
- return (*descaddr & PAGE_MASK) | (vaddr & ~PAGE_MASK);
- }
- }
- return 0;
-}
-
-/* Push n pages at kernel virtual address and clear the icache */
-/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
-void flush_icache_range(unsigned long address, unsigned long endaddr)
-{
- if (CPU_IS_040_OR_060) {
- address &= PAGE_MASK;
-
- if (address >= PAGE_OFFSET && address < (unsigned long)high_memory) {
- do {
- asm volatile ("nop\n\t"
- ".chip 68040\n\t"
- "cpushp %%bc,(%0)\n\t"
- ".chip 68k"
- : : "a" (virt_to_phys((void *)address)));
- address += PAGE_SIZE;
- } while (address < endaddr);
- } else {
- do {
- asm volatile ("nop\n\t"
- ".chip 68040\n\t"
- "cpushp %%bc,(%0)\n\t"
- ".chip 68k"
- : : "a" (virt_to_phys_slow(address)));
- address += PAGE_SIZE;
- } while (address < endaddr);
- }
- } else {
- unsigned long tmp;
- asm volatile ("movec %%cacr,%0\n\t"
- "orw %1,%0\n\t"
- "movec %0,%%cacr"
- : "=&d" (tmp)
- : "di" (FLUSH_I));
- }
-}
-
-
#ifndef CONFIG_SINGLE_MEMORY_CHUNK
int mm_end_of_chunk (unsigned long addr, int len)
{
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/block/swim3.c linux-2.6.12/drivers/block/swim3.c
--- linux-2.6.12-i386/drivers/block/swim3.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/block/swim3.c 2005-04-25 23:08:32.000000000 +0200
@@ -302,7 +302,7 @@
continue;
start_request(&floppy_states[i]);
}
- sti();
+ local_irq_enable();
}
static void start_request(struct floppy_state *fs)
@@ -368,7 +368,7 @@
{
unsigned long flags;
- save_flags(flags); cli();
+ local_irq_save(flags);
if (fs->timeout_pending)
del_timer(&fs->timeout);
fs->timeout.expires = jiffies + nticks;
@@ -376,7 +376,7 @@
fs->timeout.data = (unsigned long) fs;
add_timer(&fs->timeout);
fs->timeout_pending = 1;
- restore_flags(flags);
+ local_irq_restore(flags);
}
static inline void scan_track(struct floppy_state *fs)
@@ -788,14 +788,13 @@
{
unsigned long flags;
- save_flags(flags);
- cli();
+ local_irq_save(flags);
if (fs->state != idle) {
++fs->wanted;
while (fs->state != available) {
if (interruptible && signal_pending(current)) {
--fs->wanted;
- restore_flags(flags);
+ local_irq_restore(flags);
return -EINTR;
}
interruptible_sleep_on(&fs->wait);
@@ -803,7 +802,7 @@
--fs->wanted;
}
fs->state = state;
- restore_flags(flags);
+ local_irq_restore(flags);
return 0;
}
@@ -811,11 +810,10 @@
{
unsigned long flags;
- save_flags(flags);
- cli();
+ local_irq_save(flags);
fs->state = idle;
start_request(fs);
- restore_flags(flags);
+ local_irq_restore(flags);
}
static int fd_eject(struct floppy_state *fs)
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/char/16c552.h linux-2.6.12/drivers/char/16c552.h
--- linux-2.6.12-i386/drivers/char/16c552.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.12/drivers/char/16c552.h 2001-10-22 11:34:32.000000000 +0200
@@ -0,0 +1,165 @@
+/*
+ * Definitions for the 16c552 DACE
+ * (dual-asynchronous-communications-element) used on the GVP
+ * IO-Extender.
+ *
+ * Basically this is two 16c550 uarts's and a parallel port, which is
+ * why the serial definitions should be valid for the 16c550 uart
+ * aswell.
+ *
+ * Data was taken from National Semiconductors duart 16c552
+ * data-sheets and the Texas Instruments DACE 16c552 data-sheets (the
+ * NS version of the chip is _non_ standard and their data-sheets did
+ * cost me several wasted hours of work).
+ *
+ * This file is (C) 1995 Jes Sorensen (jds@kom.auc.dk)
+ *
+ * Moved from drivers/char/ to include/linux/, because it's useful
+ * on more than just the one card. I'm using it on the hp300 DCA
+ * serial driver, for example.
+ * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 05/1998
+ */
+
+#ifndef _16C552_H_
+#define _16C552_H_
+
+/* Serial stuff */
+
+struct uart_16c550 {
+ volatile u_char skip0;
+ volatile u_char RBR;
+ volatile u_char skip1;
+ volatile u_char IER;
+ volatile u_char skip2;
+ volatile u_char IIR;
+ volatile u_char skip3;
+ volatile u_char LCR;
+ volatile u_char skip4;
+ volatile u_char MCR;
+ volatile u_char skip5;
+ volatile u_char LSR;
+ volatile u_char skip6;
+ volatile u_char MSR;
+ volatile u_char skip7;
+ volatile u_char SCR;
+};
+
+#define THR RBR
+#define FCR IIR
+#define DLL RBR
+#define DLM IER
+#define AFR IIR
+
+/*
+ * Bit-defines for the various registers.
+ */
+
+
+/* IER */
+
+#define ERDAI (1<<0)
+#define ETHREI (1<<1)
+#define ELSI (1<<2)
+#define EMSI (1<<3)
+
+/* IIR - Interrupt Ident. Register */
+
+#define IRQ_PEND (1<<0) /* NOTE: IRQ_PEND=0 implies irq pending */
+#define IRQ_ID1 (1<<1)
+#define IRQ_ID2 (1<<2)
+#define IRQ_ID3 (1<<3)
+#define FIFO_ENA0 (1<<6) /* Both these are set when FCR(1<<0)=1 */
+#define FIFO_ENA1 (1<<7)
+
+#define IRQ_RLS (IRQ_ID1 | IRQ_ID2)
+#define IRQ_RDA (IRQ_ID2)
+#define IRQ_CTI (IRQ_ID2 | IRQ_ID3)
+#define IRQ_THRE (IRQ_ID1)
+#define IRQ_MS 0
+
+/* FCR - FIFO Control Register */
+
+#define FIFO_ENA (1<<0)
+#define RCVR_FIFO_RES (1<<1)
+#define XMIT_FIFO_RES (1<<2)
+#define DMA_MODE_SEL (1<<3)
+#define RCVR_TRIG_LSB (1<<6)
+#define RCVR_TRIG_MSB (1<<7)
+
+#define FIFO_TRIG_1 0x00
+#define FIFO_TRIG_4 RCVR_TRIG_LSB
+#define FIFO_TRIG_8 RCVR_TRIG_MSB
+#define FIFO_TRIG_14 RCVR_TRIG_LSB|RCVR_TRIG_MSB
+
+/* LCR - Line Control Register */
+
+#define WLS0 (1<<0)
+#define WLS1 (1<<1)
+#define STB (1<<2)
+#define PEN (1<<3)
+#define EPS (1<<4)
+#define STICK_PARITY (1<<5)
+#define SET_BREAK (1<<6)
+#define DLAB (1<<7)
+
+#define data_5bit 0x00
+#define data_6bit 0x01
+#define data_7bit 0x02
+#define data_8bit 0x03
+
+
+/* MCR - Modem Control Register */
+
+#define DTR (1<<0)
+#define RTS (1<<1)
+#define OUT1 (1<<2)
+#define OUT2 (1<<3)
+#define LOOP (1<<4)
+
+/* LSR - Line Status Register */
+
+#define DR (1<<0)
+#define OE (1<<1)
+#define PE (1<<2)
+#define FE (1<<3)
+#define BI (1<<4)
+#define THRE (1<<5)
+#define TEMT (1<<6)
+#define RCVR_FIFO_ERR (1<<7)
+
+/* MSR - Modem Status Register */
+
+#define DCTS (1<<0)
+#define DDSR (1<<1)
+#define TERI (1<<2)
+#define DDCD (1<<3)
+#define CTS (1<<4)
+#define DSR (1<<5)
+#define RING_I (1<<6)
+#define DCD (1<<7)
+
+/* AFR - Alternate Function Register */
+
+#define CONCUR_WRITE (1<<0)
+#define BAUDOUT (1<<1)
+#define RXRDY (1<<2)
+
+/* Parallel stuff */
+
+/*
+ * Unfortunately National Semiconductors did not supply the
+ * specifications for the parallel port in the chip :-(
+ * TI succed though, so here they are :-)
+ *
+ * Defines for the bits can be found by including <linux/lp.h>
+ */
+struct IOEXT_par {
+ volatile u_char skip0;
+ volatile u_char DATA;
+ volatile u_char skip1;
+ volatile u_char STATUS;
+ volatile u_char skip2;
+ volatile u_char CTRL;
+};
+
+#endif
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/char/ioext.h linux-2.6.12/drivers/char/ioext.h
--- linux-2.6.12-i386/drivers/char/ioext.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.12/drivers/char/ioext.h 2001-10-22 11:34:32.000000000 +0200
@@ -0,0 +1,108 @@
+/*
+ * Shared data structure for GVP IO-Extender support.
+ *
+ * Merge of ioext.h and ser_ioext.h
+ */
+#ifndef _IOEXT_H_
+#define _IOEXT_H_
+
+#include <linux/config.h>
+#include <linux/netdevice.h>
+
+#include "16c552.h"
+
+#define MAX_IOEXT 5 /*
+ * The maximum number of io-extenders is 5, as you
+ * can't have more than 5 ZII boards in any Amiga.
+ */
+
+#define UART_CLK 7372800
+
+#define IOEXT_BAUD_BASE (UART_CLK / 16)
+
+#define IOEXT_MAX_LINES 2
+
+#define IOEXT_PAR_PLIP 0x0001
+#define IOEXT_PAR_LP 0x0002
+
+
+/*
+ * Macros for the serial driver.
+ */
+#define curruart(info) ((struct uart_16c550 *)(info->port))
+
+#define ser_DTRon(info) curruart(info)->MCR |= DTR
+#define ser_RTSon(info) curruart(info)->MCR |= RTS
+#define ser_DTRoff(info) curruart(info)->MCR &= ~DTR
+#define ser_RTSoff(info) curruart(info)->MCR &= ~RTS
+
+
+/*
+ * CNTR defines (copied from the GVP SCSI-driver file gvp11.h
+ */
+#define GVP_BUSY (1<<0)
+#define GVP_IRQ_PEND (1<<1)
+#define GVP_IRQ_ENA (1<<3)
+#define GVP_DIR_WRITE (1<<4)
+
+
+/*
+ * CTRL defines
+ */
+#define PORT0_MIDI (1<<0) /* CLR = DRIVERS SET = MIDI */
+#define PORT1_MIDI (1<<1) /* CLR = DRIVERS SET = MIDI */
+#define PORT0_DRIVER (1<<2) /* CLR = RS232, SET = MIDI */
+#define PORT1_DRIVER (1<<3) /* CLR = RS232, SET = MIDI */
+#define IRQ_SEL (1<<4) /* CLR = INT2, SET = INT6 */
+#define ROM_BANK_SEL (1<<5) /* CLR = LOW 32K, SET = HIGH 32K */
+#define PORT0_CTRL (1<<6) /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */
+#define PORT1_CTRL (1<<7) /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */
+
+
+/*
+ * This is the struct describing the registers on the IO-Extender.
+ * NOTE: The board uses a dual uart (16c552), which should be equal to
+ * two 16c550 uarts.
+ */
+typedef struct {
+ char gap0[0x41];
+ volatile unsigned char CNTR; /* GVP DMAC CNTR (status register) */
+ char gap1[0x11e];
+ struct uart_16c550 uart0; /* The first uart */
+ char gap2[0xf0];
+ struct uart_16c550 uart1; /* The second uart */
+ char gap3[0xf0];
+ struct IOEXT_par par; /* The parallel port */
+ char gap4[0xfb];
+ volatile unsigned char CTRL; /* The control-register on the board */
+} IOEXT_struct;
+
+
+typedef struct {
+ int num_uarts;
+ int line[IOEXT_MAX_LINES];
+ volatile struct uart_16c550 *uart[IOEXT_MAX_LINES];
+ IOEXT_struct *board;
+ int spurious_count;
+ unsigned char par_use; /* IOEXT_PAR_xxx */
+#if defined(CONFIG_GVPIOEXT_PLIP) || defined(CONFIG_GVPIOEXT_PLIP_MODULE)
+ struct nt_device *dev;
+#endif
+#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE)
+ struct lp_struct *lp_table;
+ int lp_dev;
+ int lp_interrupt;
+#endif
+} IOExtInfoType;
+
+/* Number of detected boards. */
+extern int ioext_num;
+extern IOExtInfoType ioext_info[MAX_IOEXT];
+
+void ioext_plip_interrupt(struct net_device *dev, int *spurious_count);
+void ioext_lp_interrupt(int dev, int *spurious_count);
+
+extern struct net_device ioext_dev_plip[3];
+extern struct lp_struct ioext_lp_table[1];
+
+#endif
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/char/mc68681.h linux-2.6.12/drivers/char/mc68681.h
--- linux-2.6.12-i386/drivers/char/mc68681.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.12/drivers/char/mc68681.h 2001-10-22 11:34:32.000000000 +0200
@@ -0,0 +1,131 @@
+#ifndef _MC68681_H_
+#define _MC68681_H_
+
+/*
+ * This describes an MC68681 DUART. It has almost only overlayed registers, which
+ * the structure very ugly.
+ * Note that the ri-register isn't really a register of the duart but a kludge of bsc
+ * to make the ring indicator available.
+ *
+ * The data came from the MFC-31-Developer Kit (from Ralph Seidel,
+ * zodiac@darkness.gun.de) and the data sheet of Phillip's clone device (SCN68681)
+ * (from Richard Hirst, srh@gpt.co.uk)
+ *
+ * 11.11.95 copyright Joerg Dorchain (dorchain@mpi-sb.mpg.de)
+ *
+ */
+
+struct duarthalf {
+union {
+volatile u_char mr1; /* rw */
+volatile u_char mr2; /* rw */
+} mr;
+volatile u_char ri; /* special, read */
+union {
+volatile u_char sr; /* read */
+volatile u_char csr; /* write */
+} sr_csr;
+u_char pad1;
+volatile u_char cr; /* write */
+u_char pad2;
+union {
+volatile u_char rhr; /* read */
+volatile u_char thr; /* write */
+} hr;
+u_char pad3;
+};
+
+struct duart {
+struct duarthalf pa;
+union {
+volatile u_char ipcr; /* read */
+volatile u_char acr; /* write */
+} ipcr_acr;
+u_char pad1;
+union {
+volatile u_char isr; /* read */
+volatile u_char imr; /* write */
+} ir;
+u_char pad2;
+volatile u_char ctu;
+u_char pad3;
+volatile u_char ctl;
+u_char pad4;
+struct duarthalf pb;
+volatile u_char ivr;
+u_char pad5;
+union {
+volatile u_char ipr; /* read */
+volatile u_char opcr; /* write */
+} ipr_opcr;
+u_char pad6;
+union {
+volatile u_char start; /* read */
+volatile u_char sopc; /* write */
+} start_sopc;
+u_char pad7;
+union {
+volatile u_char stop; /* read */
+volatile u_char ropc; /* write */
+} stop_ropc;
+u_char pad8;
+};
+
+#define MR1_BITS 3
+#define MR1_5BITS 0
+#define MR1_6BITS 1
+#define MR1_7BITS 2
+#define MR1_8BITS 3
+
+#define MR1_PARITY_ODD 4
+
+#define MR1_PARITY 24
+#define MR1_PARITY_WITH 0
+#define MR1_PARITY_FORCE 8
+#define MR1_PARITY_NO 16
+#define MR1_PARITY_MULTIDROP 24
+
+#define MR1_ERROR_BLOCK 32
+#define MR1_FFULL_IRQ 64
+#define MR1_RxRTS_ON 128
+
+#define MR2_STOPS 15
+#define MR2_1STOP 7
+#define MR2_2STOP 15
+
+#define MR2_CTS_ON 16
+#define MR2_TxRTS_ON 32
+
+#define MR2_MODE 192
+#define MR2_NORMAL 0
+#define MR2_ECHO 64
+#define MR2_LOCALLOOP 128
+#define MR2_REMOTELOOP 192
+
+#define CR_RXCOMMAND 3
+#define CR_NONE 0
+#define CR_RX_ON 1
+#define CR_RX_OFF 2
+#define CR_TXCOMMAND 12
+#define CR_TX_ON 4
+#define CR_TX_OFF 8
+#define CR_MISC 112
+#define CR_RESET_MR 16
+#define CR_RESET_RX 32
+#define CR_RESET_TX 48
+#define CR_RESET_ERR 64
+#define CR_RESET_BREAK 80
+#define CR_START_BREAK 96
+#define CR_STOP_BREAK 112
+
+#define SR_RXRDY 1
+#define SR_FFULL 2
+#define SR_TXRDY 4
+#define SR_TXEMPT 8
+#define SR_OVERRUN 16
+#define SR_PARITY 32
+#define SR_FRAMING 64
+#define SR_BREAK 128
+
+
+#endif
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/char/plip_ioext.c linux-2.6.12/drivers/char/plip_ioext.c
--- linux-2.6.12-i386/drivers/char/plip_ioext.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.12/drivers/char/plip_ioext.c 2004-10-25 16:38:25.000000000 +0200
@@ -0,0 +1,1058 @@
+/*
+ * plip_ioext: A parallel port "network" driver for GVP IO-Extender.
+ *
+ * Authors: See drivers/net/plip.c
+ * IO-Extender version by Steve Bennett, <msteveb@ozemail.com.au>
+ *
+ * This driver is for use with a 5-bit cable (LapLink (R) cable).
+ */
+
+static const char *version = "NET3 PLIP version 2.2/m68k";
+
+#define __NO_VERSION__
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/termios.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/amigahw.h>
+#include <asm/amigaints.h>
+#include <linux/zorro.h>
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/fcntl.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/if_ether.h>
+
+#include <asm/system.h>
+
+#include <linux/in.h>
+#include <linux/delay.h>
+/*#include <linux/lp_m68k.h>*/
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_plip.h>
+
+#include <linux/tqueue.h>
+#include <linux/ioport.h>
+#include <linux/bitops.h>
+#include <asm/byteorder.h>
+
+#include "ioext.h"
+
+#define DEBUG 0
+
+/* Map 'struct device *' to our control structure */
+#define PLIP_DEV(DEV) (&ioext_info[(DEV)->irq])
+
+/************************************************************************
+**
+** PLIP definitions
+**
+*************************************************************************
+*/
+
+/* Use 0 for production, 1 for verification, >2 for debug */
+#ifndef NET_DEBUG
+#define NET_DEBUG 2
+#endif
+static unsigned int net_debug = NET_DEBUG;
+
+/* In micro second */
+#define PLIP_DELAY_UNIT 1
+
+/* Connection time out = PLIP_TRIGGER_WAIT * PLIP_DELAY_UNIT usec */
+#define PLIP_TRIGGER_WAIT 500
+
+/* Nibble time out = PLIP_NIBBLE_WAIT * PLIP_DELAY_UNIT usec */
+#define PLIP_NIBBLE_WAIT 3000
+
+#define PAR_DATA(dev) ((dev)->base_addr+0)
+#define PAR_STATUS(dev) ((dev)->base_addr+2)
+#define PAR_CONTROL(dev) ((dev)->base_addr+4)
+
+static void enable_par_irq(struct device *dev, int on);
+static int plip_init(struct device *dev);
+
+/* Bottom halfs */
+static void plip_kick_bh(struct device *dev);
+static void plip_bh(struct device *dev);
+
+/* Functions for DEV methods */
+static int plip_rebuild_header(struct sk_buff *skb);
+static int plip_tx_packet(struct sk_buff *skb, struct device *dev);
+static int plip_open(struct device *dev);
+static int plip_close(struct device *dev);
+static struct enet_statistics *plip_get_stats(struct device *dev);
+static int plip_config(struct device *dev, struct ifmap *map);
+static int plip_ioctl(struct device *dev, struct ifreq *ifr, int cmd);
+
+enum plip_connection_state {
+ PLIP_CN_NONE=0,
+ PLIP_CN_RECEIVE,
+ PLIP_CN_SEND,
+ PLIP_CN_CLOSING,
+ PLIP_CN_ERROR
+};
+
+enum plip_packet_state {
+ PLIP_PK_DONE=0,
+ PLIP_PK_TRIGGER,
+ PLIP_PK_LENGTH_LSB,
+ PLIP_PK_LENGTH_MSB,
+ PLIP_PK_DATA,
+ PLIP_PK_CHECKSUM
+};
+
+enum plip_nibble_state {
+ PLIP_NB_BEGIN,
+ PLIP_NB_1,
+ PLIP_NB_2,
+};
+
+struct plip_local {
+ enum plip_packet_state state;
+ enum plip_nibble_state nibble;
+ union {
+ struct {
+#if defined(__LITTLE_ENDIAN)
+ unsigned char lsb;
+ unsigned char msb;
+#elif defined(__BIG_ENDIAN)
+ unsigned char msb;
+ unsigned char lsb;
+#else
+#error "Please fix the endianness defines in <asm/byteorder.h>"
+#endif
+ } b;
+ unsigned short h;
+ } length;
+ unsigned short byte;
+ unsigned char checksum;
+ unsigned char data;
+ struct sk_buff *skb;
+};
+
+struct net_local {
+ struct enet_statistics enet_stats;
+ struct tq_struct immediate;
+ struct tq_struct deferred;
+ struct plip_local snd_data;
+ struct plip_local rcv_data;
+ unsigned long trigger;
+ unsigned long nibble;
+ enum plip_connection_state connection;
+ unsigned short timeout_count;
+ char is_deferred;
+ int (*orig_rebuild_header)(struct sk_buff *skb);
+};
+
+struct device ioext_dev_plip[] = {
+ {
+ "plip0",
+ 0, 0, 0, 0, /* memory */
+ 0, 0, /* base, irq */
+ 0, 0, 0, NULL, plip_init
+ },
+ {
+ "plip1",
+ 0, 0, 0, 0, /* memory */
+ 0, 0, /* base, irq */
+ 0, 0, 0, NULL, plip_init
+ },
+ {
+ "plip2",
+ 0, 0, 0, 0, /* memory */
+ 0, 0, /* base, irq */
+ 0, 0, 0, NULL, plip_init
+ }
+};
+
+/*
+ * Check for and handle an interrupt for this PLIP device.
+ *
+ */
+void ioext_plip_interrupt(struct device *dev, int *spurious_count)
+{
+ struct net_local *nl;
+ struct plip_local *rcv;
+ unsigned char c0;
+ unsigned long flags;
+
+ nl = (struct net_local *)dev->priv;
+ rcv = &nl->rcv_data;
+
+ c0 = z_readb(PAR_STATUS(dev));
+
+ if (dev->interrupt) {
+ return;
+ }
+
+ if ((c0 & 0xf8) != 0xc0) {
+ /* Not for us */
+ ++*spurious_count;
+ return;
+ }
+
+ *spurious_count = 0;
+ dev->interrupt = 1;
+
+ local_irq_save(flags);
+
+ switch (nl->connection) {
+ case PLIP_CN_CLOSING:
+ dev->tbusy = 0;
+ case PLIP_CN_NONE:
+ case PLIP_CN_SEND:
+ dev->last_rx = jiffies;
+ rcv->state = PLIP_PK_TRIGGER;
+ nl->connection = PLIP_CN_RECEIVE;
+ nl->timeout_count = 0;
+ queue_task(&nl->immediate, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+ local_irq_restore(flags);
+#if 0
+ printk("%s: receive irq in SEND/NONE/CLOSING (%d) ok\n",
+ dev->name, nl->connection);
+#endif
+ break;
+
+ case PLIP_CN_RECEIVE:
+ local_irq_restore(flags);
+ printk("%s: receive interrupt when receiving packet\n",
+ dev->name);
+ break;
+
+ case PLIP_CN_ERROR:
+ local_irq_restore(flags);
+ printk("%s: receive interrupt in error state\n", dev->name);
+ break;
+ }
+}
+
+
+/* Bottom half handler for the delayed request.
+ This routine is kicked by do_timer().
+ Request `plip_bh' to be invoked. */
+static void
+plip_kick_bh(struct device *dev)
+{
+ struct net_local *nl = (struct net_local *)dev->priv;
+
+ if (nl->is_deferred) {
+ queue_task(&nl->immediate, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+ }
+}
+
+/* Forward declarations of internal routines */
+static int plip_none(struct device *, struct net_local *,
+ struct plip_local *, struct plip_local *);
+static int plip_receive_packet(struct device *, struct net_local *,
+ struct plip_local *, struct plip_local *);
+static int plip_send_packet(struct device *, struct net_local *,
+ struct plip_local *, struct plip_local *);
+static int plip_connection_close(struct device *, struct net_local *,
+ struct plip_local *, struct plip_local *);
+static int plip_error(struct device *, struct net_local *,
+ struct plip_local *, struct plip_local *);
+static int plip_bh_timeout_error(struct device *dev, struct net_local *nl,
+ struct plip_local *snd,
+ struct plip_local *rcv,
+ int error);
+
+#define OK 0
+#define TIMEOUT 1
+#define ERROR 2
+
+typedef int (*plip_func)(struct device *dev, struct net_local *nl,
+ struct plip_local *snd, struct plip_local *rcv);
+
+static plip_func connection_state_table[] =
+{
+ plip_none,
+ plip_receive_packet,
+ plip_send_packet,
+ plip_connection_close,
+ plip_error
+};
+
+/*
+** enable_par_irq()
+**
+** Enable or disable parallel irq for 'dev' according to 'on'.
+**
+** It is NOT possible to disable only the parallel irq.
+** So we disable the board interrupt instead. This means that
+** during reception of a PLIP packet, no serial interrupts can
+** happen. Sorry.
+*/
+static void enable_par_irq(struct device *dev, int on)
+{
+ if (on) {
+ PLIP_DEV(dev)->board->CNTR |= GVP_IRQ_ENA;
+ }
+ else {
+ PLIP_DEV(dev)->board->CNTR &= ~GVP_IRQ_ENA;
+ }
+}
+
+/* Bottom half handler of PLIP. */
+static void
+plip_bh(struct device *dev)
+{
+ struct net_local *nl = (struct net_local *)dev->priv;
+ struct plip_local *snd = &nl->snd_data;
+ struct plip_local *rcv = &nl->rcv_data;
+ plip_func f;
+ int r;
+
+ nl->is_deferred = 0;
+ f = connection_state_table[nl->connection];
+ if ((r = (*f)(dev, nl, snd, rcv)) != OK
+ && (r = plip_bh_timeout_error(dev, nl, snd, rcv, r)) != OK) {
+ nl->is_deferred = 1;
+ queue_task(&nl->deferred, &tq_timer);
+ }
+}
+
+static int
+plip_bh_timeout_error(struct device *dev, struct net_local *nl,
+ struct plip_local *snd, struct plip_local *rcv,
+ int error)
+{
+ unsigned char c0;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (nl->connection == PLIP_CN_SEND) {
+
+ if (error != ERROR) { /* Timeout */
+ nl->timeout_count++;
+ if ((snd->state == PLIP_PK_TRIGGER
+ && nl->timeout_count <= 10)
+ || nl->timeout_count <= 3) {
+ local_irq_restore(flags);
+ /* Try again later */
+ return TIMEOUT;
+ }
+ c0 = z_readb(PAR_STATUS(dev));
+ printk(KERN_INFO "%s: transmit timeout(%d,%02x)\n",
+ dev->name, snd->state, c0);
+ }
+ nl->enet_stats.tx_errors++;
+ nl->enet_stats.tx_aborted_errors++;
+ } else if (nl->connection == PLIP_CN_RECEIVE) {
+ if (rcv->state == PLIP_PK_TRIGGER) {
+ /* Transmission was interrupted. */
+ local_irq_restore(flags);
+ return OK;
+ }
+ if (error != ERROR) { /* Timeout */
+ if (++nl->timeout_count <= 3) {
+ local_irq_restore(flags);
+ /* Try again later */
+ return TIMEOUT;
+ }
+ c0 = z_readb(PAR_STATUS(dev));
+ printk(KERN_INFO "%s: receive timeout(%d,%02x)\n",
+ dev->name, rcv->state, c0);
+ }
+ nl->enet_stats.rx_dropped++;
+ }
+ rcv->state = PLIP_PK_DONE;
+ if (rcv->skb) {
+ kfree_skb(rcv->skb);
+ rcv->skb = NULL;
+ }
+ snd->state = PLIP_PK_DONE;
+ if (snd->skb) {
+ dev_kfree_skb(snd->skb);
+ snd->skb = NULL;
+ }
+ enable_par_irq(dev, 0);
+ dev->tbusy = 1;
+ nl->connection = PLIP_CN_ERROR;
+ z_writeb(0x00, PAR_DATA(dev));
+ local_irq_restore(flags);
+
+ return TIMEOUT;
+}
+
+static int
+plip_none(struct device *dev, struct net_local *nl,
+ struct plip_local *snd, struct plip_local *rcv)
+{
+ return OK;
+}
+
+/* PLIP_RECEIVE --- receive a byte(two nibbles)
+ Returns OK on success, TIMEOUT on timeout */
+inline static int
+plip_receive(struct device *dev, unsigned short nibble_timeout,
+ enum plip_nibble_state *ns_p, unsigned char *data_p)
+{
+ unsigned char c0, c1;
+ unsigned int cx;
+
+ switch (*ns_p) {
+ case PLIP_NB_BEGIN:
+ cx = nibble_timeout;
+ while (1) {
+ c0 = z_readb(PAR_STATUS(dev));
+ udelay(PLIP_DELAY_UNIT);
+ if ((c0 & 0x80) == 0) {
+ c1 = z_readb(PAR_STATUS(dev));
+ if (c0 == c1)
+ break;
+ }
+ if (--cx == 0)
+ return TIMEOUT;
+ }
+#if 0
+ printk("received first nybble: %02X -> %02X\n",
+ c0, (c0 >> 3) & 0x0F);
+#endif
+ *data_p = (c0 >> 3) & 0x0f;
+ z_writeb(0x10, PAR_DATA(dev)); /* send ACK */
+ *ns_p = PLIP_NB_1;
+
+ case PLIP_NB_1:
+ cx = nibble_timeout;
+ while (1) {
+ c0 = z_readb(PAR_STATUS(dev));
+ udelay(PLIP_DELAY_UNIT);
+ if (c0 & 0x80) {
+ c1 = z_readb(PAR_STATUS(dev));
+ if (c0 == c1)
+ break;
+ }
+ if (--cx == 0)
+ return TIMEOUT;
+ }
+#if 0
+ printk("received second nybble: %02X -> %02X\n",
+ c0, (c0 << 1) & 0xF0);
+#endif
+ *data_p |= (c0 << 1) & 0xf0;
+ z_writeb(0x00, PAR_DATA(dev)); /* send ACK */
+ *ns_p = PLIP_NB_BEGIN;
+ case PLIP_NB_2:
+ break;
+ }
+ return OK;
+}
+
+/* PLIP_RECEIVE_PACKET --- receive a packet */
+static int
+plip_receive_packet(struct device *dev, struct net_local *nl,
+ struct plip_local *snd, struct plip_local *rcv)
+{
+ unsigned short nibble_timeout = nl->nibble;
+ unsigned char *lbuf;
+ unsigned long flags;
+
+ switch (rcv->state) {
+ case PLIP_PK_TRIGGER:
+ enable_par_irq(dev, 0);
+ dev->interrupt = 0;
+ z_writeb(0x01, PAR_DATA(dev)); /* send ACK */
+ if (net_debug > 2)
+ printk(KERN_DEBUG "%s: receive start\n", dev->name);
+ rcv->state = PLIP_PK_LENGTH_LSB;
+ rcv->nibble = PLIP_NB_BEGIN;
+
+ case PLIP_PK_LENGTH_LSB:
+ if (snd->state != PLIP_PK_DONE) {
+ if (plip_receive(dev, nl->trigger,
+ &rcv->nibble, &rcv->length.b.lsb)) {
+ /* collision, here dev->tbusy == 1 */
+ rcv->state = PLIP_PK_DONE;
+ nl->is_deferred = 1;
+ nl->connection = PLIP_CN_SEND;
+ queue_task(&nl->deferred, &tq_timer);
+ enable_par_irq(dev, 1);
+ return OK;
+ }
+ } else {
+ if (plip_receive(dev, nibble_timeout,
+ &rcv->nibble, &rcv->length.b.lsb))
+ return TIMEOUT;
+ }
+ rcv->state = PLIP_PK_LENGTH_MSB;
+
+ case PLIP_PK_LENGTH_MSB:
+ if (plip_receive(dev, nibble_timeout,
+ &rcv->nibble, &rcv->length.b.msb))
+ return TIMEOUT;
+ if (rcv->length.h > dev->mtu + dev->hard_header_len
+ || rcv->length.h < 8) {
+ printk(KERN_INFO "%s: bogus packet size %d.\n",
+ dev->name, rcv->length.h);
+ return ERROR;
+ }
+ /* Malloc up new buffer. */
+ rcv->skb = dev_alloc_skb(rcv->length.h);
+ if (rcv->skb == NULL) {
+ printk(KERN_INFO "%s: Memory squeeze.\n", dev->name);
+ return ERROR;
+ }
+ skb_put(rcv->skb,rcv->length.h);
+ rcv->skb->dev = dev;
+ rcv->state = PLIP_PK_DATA;
+ rcv->byte = 0;
+ rcv->checksum = 0;
+
+ case PLIP_PK_DATA:
+ lbuf = rcv->skb->data;
+ do
+ if (plip_receive(dev, nibble_timeout,
+ &rcv->nibble, &lbuf[rcv->byte]))
+ return TIMEOUT;
+ while (++rcv->byte < rcv->length.h);
+ do
+ rcv->checksum += lbuf[--rcv->byte];
+ while (rcv->byte);
+ rcv->state = PLIP_PK_CHECKSUM;
+
+ case PLIP_PK_CHECKSUM:
+ if (plip_receive(dev, nibble_timeout,
+ &rcv->nibble, &rcv->data))
+ return TIMEOUT;
+ if (rcv->data != rcv->checksum) {
+ nl->enet_stats.rx_crc_errors++;
+ if (net_debug)
+ printk(KERN_INFO "%s: checksum error\n",
+ dev->name);
+ return ERROR;
+ }
+ rcv->state = PLIP_PK_DONE;
+
+ case PLIP_PK_DONE:
+ /* Inform the upper layer for the arrival of a packet. */
+ rcv->skb->protocol=eth_type_trans(rcv->skb, dev);
+ netif_rx(rcv->skb);
+ nl->enet_stats.rx_packets++;
+ rcv->skb = NULL;
+ if (net_debug > 2)
+ printk(KERN_DEBUG "%s: receive end\n", dev->name);
+
+ /* Close the connection. */
+ z_writeb (0x00, PAR_DATA(dev));
+
+ local_irq_save(flags);
+ if (snd->state != PLIP_PK_DONE) {
+ nl->connection = PLIP_CN_SEND;
+ local_irq_restore(flags);
+ queue_task(&nl->immediate, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+ enable_par_irq(dev, 1);
+ return OK;
+ } else {
+ nl->connection = PLIP_CN_NONE;
+ local_irq_restore(flags);
+ enable_par_irq(dev, 1);
+ return OK;
+ }
+ }
+ return OK;
+}
+
+/* PLIP_SEND --- send a byte (two nibbles)
+ Returns OK on success, TIMEOUT when timeout */
+inline static int
+plip_send(struct device *dev, unsigned short nibble_timeout,
+ enum plip_nibble_state *ns_p, unsigned char data)
+{
+ unsigned char c0;
+ unsigned int cx;
+
+ switch (*ns_p) {
+ case PLIP_NB_BEGIN:
+ z_writeb((data & 0x0f), PAR_DATA(dev));
+ *ns_p = PLIP_NB_1;
+
+ case PLIP_NB_1:
+ z_writeb(0x10 | (data & 0x0f), PAR_DATA(dev));
+ cx = nibble_timeout;
+ while (1) {
+ c0 = z_readb(PAR_STATUS(dev));
+ if ((c0 & 0x80) == 0)
+ break;
+ if (--cx == 0)
+ return TIMEOUT;
+ udelay(PLIP_DELAY_UNIT);
+ }
+ z_writeb(0x10 | (data >> 4), PAR_DATA(dev));
+ *ns_p = PLIP_NB_2;
+
+ case PLIP_NB_2:
+ z_writeb((data >> 4), PAR_DATA(dev));
+ cx = nibble_timeout;
+ while (1) {
+ c0 = z_readb(PAR_STATUS(dev));
+ if (c0 & 0x80)
+ break;
+ if (--cx == 0)
+ return TIMEOUT;
+ udelay(PLIP_DELAY_UNIT);
+ }
+ *ns_p = PLIP_NB_BEGIN;
+ return OK;
+ }
+ return OK;
+}
+
+/* PLIP_SEND_PACKET --- send a packet */
+static int
+plip_send_packet(struct device *dev, struct net_local *nl,
+ struct plip_local *snd, struct plip_local *rcv)
+{
+ unsigned short nibble_timeout = nl->nibble;
+ unsigned char *lbuf;
+ unsigned char c0;
+ unsigned int cx;
+ unsigned long flags;
+
+ if (snd->skb == NULL || (lbuf = snd->skb->data) == NULL) {
+ printk(KERN_INFO "%s: send skb lost\n", dev->name);
+ snd->state = PLIP_PK_DONE;
+ snd->skb = NULL;
+ return ERROR;
+ }
+
+ if (snd->length.h == 0) {
+ return OK;
+ }
+
+ switch (snd->state) {
+ case PLIP_PK_TRIGGER:
+ if ((z_readb(PAR_STATUS(dev)) & 0xf8) != 0x80)
+ return TIMEOUT;
+
+ /* Trigger remote rx interrupt. */
+ z_writeb(0x08, PAR_DATA(dev));
+ cx = nl->trigger;
+ while (1) {
+ udelay(PLIP_DELAY_UNIT);
+ local_irq_save(flags);
+ if (nl->connection == PLIP_CN_RECEIVE) {
+ local_irq_restore(flags);
+ /* interrupted */
+ nl->enet_stats.collisions++;
+ if (net_debug > 1)
+ printk(KERN_INFO "%s: collision.\n",
+ dev->name);
+ return OK;
+ }
+ c0 = z_readb(PAR_STATUS(dev));
+ if (c0 & 0x08) {
+ enable_par_irq(dev, 0);
+ if (net_debug > 2)
+ printk(KERN_DEBUG "%s: send start\n",
+ dev->name);
+ snd->state = PLIP_PK_LENGTH_LSB;
+ snd->nibble = PLIP_NB_BEGIN;
+ nl->timeout_count = 0;
+ local_irq_restore(flags);
+ break;
+ }
+ local_irq_restore(flags);
+ if (--cx == 0) {
+ z_writeb(0x00, PAR_DATA(dev));
+ return TIMEOUT;
+ }
+ }
+
+ case PLIP_PK_LENGTH_LSB:
+ if (plip_send(dev, nibble_timeout,
+ &snd->nibble, snd->length.b.lsb))
+ return TIMEOUT;
+ snd->state = PLIP_PK_LENGTH_MSB;
+
+ case PLIP_PK_LENGTH_MSB:
+ if (plip_send(dev, nibble_timeout,
+ &snd->nibble, snd->length.b.msb))
+ return TIMEOUT;
+ snd->state = PLIP_PK_DATA;
+ snd->byte = 0;
+ snd->checksum = 0;
+
+ case PLIP_PK_DATA:
+ do
+ if (plip_send(dev, nibble_timeout,
+ &snd->nibble, lbuf[snd->byte]))
+ return TIMEOUT;
+ while (++snd->byte < snd->length.h);
+ do
+ snd->checksum += lbuf[--snd->byte];
+ while (snd->byte);
+ snd->state = PLIP_PK_CHECKSUM;
+
+ case PLIP_PK_CHECKSUM:
+ if (plip_send(dev, nibble_timeout,
+ &snd->nibble, snd->checksum))
+ return TIMEOUT;
+
+ dev_kfree_skb(snd->skb);
+ nl->enet_stats.tx_packets++;
+ snd->state = PLIP_PK_DONE;
+
+ case PLIP_PK_DONE:
+ /* Close the connection */
+ z_writeb (0x00, PAR_DATA(dev));
+ snd->skb = NULL;
+ if (net_debug > 2)
+ printk(KERN_DEBUG "%s: send end\n", dev->name);
+ nl->connection = PLIP_CN_CLOSING;
+ nl->is_deferred = 1;
+ queue_task(&nl->deferred, &tq_timer);
+ enable_par_irq(dev, 1);
+ return OK;
+ }
+ return OK;
+}
+
+static int
+plip_connection_close(struct device *dev, struct net_local *nl,
+ struct plip_local *snd, struct plip_local *rcv)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (nl->connection == PLIP_CN_CLOSING) {
+ nl->connection = PLIP_CN_NONE;
+ dev->tbusy = 0;
+ mark_bh(NET_BH);
+ }
+ local_irq_restore(flags);
+ return OK;
+}
+
+/* PLIP_ERROR --- wait till other end settled */
+static int
+plip_error(struct device *dev, struct net_local *nl,
+ struct plip_local *snd, struct plip_local *rcv)
+{
+ unsigned char status;
+
+ status = z_readb(PAR_STATUS(dev));
+ if ((status & 0xf8) == 0x80) {
+ if (net_debug > 2)
+ printk(KERN_DEBUG "%s: reset interface.\n", dev->name);
+ nl->connection = PLIP_CN_NONE;
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ enable_par_irq(dev, 1);
+ mark_bh(NET_BH);
+ } else {
+ nl->is_deferred = 1;
+ queue_task(&nl->deferred, &tq_timer);
+ }
+
+ return OK;
+}
+
+/* We don't need to send arp, for plip is point-to-point. */
+static int
+plip_rebuild_header(struct sk_buff *skb)
+{
+ struct device *dev = skb->dev;
+ struct net_local *nl = (struct net_local *)dev->priv;
+ struct ethhdr *eth = (struct ethhdr *)skb->data;
+ int i;
+
+ if ((dev->flags & IFF_NOARP)==0)
+ return nl->orig_rebuild_header(skb);
+
+ if (eth->h_proto != __constant_htons(ETH_P_IP)
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ && eth->h_proto != __constant_htons(ETH_P_IPV6)
+#endif
+ ) {
+ printk(KERN_ERR "plip_rebuild_header: Don't know how to resolve type %d addresses?\n", (int)eth->h_proto);
+ memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
+ return 0;
+ }
+
+ for (i=0; i < ETH_ALEN - sizeof(u32); i++)
+ eth->h_dest[i] = 0xfc;
+#if 0
+ *(u32 *)(eth->h_dest+i) = dst;
+#else
+ /* Do not want to include net/route.h here.
+ * In any case, it is TOP of silliness to emulate
+ * hardware addresses on PtP link. --ANK
+ */
+ *(u32 *)(eth->h_dest+i) = 0;
+#endif
+ return 0;
+}
+
+static int
+plip_tx_packet(struct sk_buff *skb, struct device *dev)
+{
+ struct net_local *nl = (struct net_local *)dev->priv;
+ struct plip_local *snd = &nl->snd_data;
+ unsigned long flags;
+
+ if (dev->tbusy)
+ return 1;
+
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
+ printk(KERN_ERR "%s: Transmitter access conflict.\n",
+ dev->name);
+ return 1;
+ }
+
+ if (skb->len > dev->mtu + dev->hard_header_len) {
+ printk(KERN_ERR "%s: packet too big, %d.\n",
+ dev->name, (int)skb->len);
+ dev->tbusy = 0;
+ return 0;
+ }
+
+ if (net_debug > 2)
+ printk(KERN_DEBUG "%s: send request\n", dev->name);
+
+ local_irq_save(flags);
+ dev->trans_start = jiffies;
+ snd->skb = skb;
+ snd->length.h = skb->len;
+ snd->state = PLIP_PK_TRIGGER;
+ if (nl->connection == PLIP_CN_NONE) {
+ nl->connection = PLIP_CN_SEND;
+ nl->timeout_count = 0;
+ }
+ queue_task(&nl->immediate, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+/* Open/initialize the board. This is called (in the current kernel)
+ sometime after booting when the 'ifconfig' program is run.
+
+ */
+static int
+plip_open(struct device *dev)
+{
+ struct net_local *nl = (struct net_local *)dev->priv;
+ struct in_device *in_dev;
+
+#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE)
+ /* Yes, there is a race condition here. Fix it later */
+ if (PLIP_DEV(dev)->par_use & IOEXT_PAR_LP) {
+ /* Can't open if lp is in use */
+#if DEBUG
+ printk("par is in use by lp\n");
+#endif
+ return(-EBUSY);
+ }
+#endif
+ PLIP_DEV(dev)->par_use |= IOEXT_PAR_PLIP;
+
+#if DEBUG
+ printk("plip_open(): sending 00 to data port\n");
+#endif
+
+ /* Clear the data port. */
+ z_writeb (0x00, PAR_DATA(dev));
+
+#if DEBUG
+ printk("plip_open(): sent\n");
+#endif
+
+ /* Initialize the state machine. */
+ nl->rcv_data.state = nl->snd_data.state = PLIP_PK_DONE;
+ nl->rcv_data.skb = nl->snd_data.skb = NULL;
+ nl->connection = PLIP_CN_NONE;
+ nl->is_deferred = 0;
+
+ /* Fill in the MAC-level header.
+ (ab)Use "dev->broadcast" to store point-to-point MAC address.
+
+ PLIP doesn't have a real mac address, but we need to create one
+ to be DOS compatible. */
+ memset(dev->dev_addr, 0xfc, ETH_ALEN);
+ memset(dev->broadcast, 0xfc, ETH_ALEN);
+
+ if ((in_dev=dev->ip_ptr) != NULL) {
+ /*
+ * Any address will do - we take the first
+ */
+ struct in_ifaddr *ifa=in_dev->ifa_list;
+ if (ifa != NULL) {
+ memcpy(dev->dev_addr+2, &ifa->ifa_local, 4);
+ memcpy(dev->broadcast+2, &ifa->ifa_address, 4);
+ }
+ }
+
+ dev->interrupt = 0;
+ dev->start = 1;
+ dev->tbusy = 0;
+
+ MOD_INC_USE_COUNT;
+
+ /* Enable rx interrupt. */
+ enable_par_irq(dev, 1);
+
+ return 0;
+}
+
+/* The inverse routine to plip_open (). */
+static int
+plip_close(struct device *dev)
+{
+ struct net_local *nl = (struct net_local *)dev->priv;
+ struct plip_local *snd = &nl->snd_data;
+ struct plip_local *rcv = &nl->rcv_data;
+ unsigned long flags;
+
+ dev->tbusy = 1;
+ dev->start = 0;
+ local_irq_save(flags);
+ nl->is_deferred = 0;
+ nl->connection = PLIP_CN_NONE;
+ local_irq_restore(flags);
+ z_writeb(0x00, PAR_DATA(dev));
+
+ snd->state = PLIP_PK_DONE;
+ if (snd->skb) {
+ dev_kfree_skb(snd->skb);
+ snd->skb = NULL;
+ }
+ rcv->state = PLIP_PK_DONE;
+ if (rcv->skb) {
+ kfree_skb(rcv->skb);
+ rcv->skb = NULL;
+ }
+
+ PLIP_DEV(dev)->par_use &= ~IOEXT_PAR_PLIP;
+
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+static struct enet_statistics *
+plip_get_stats(struct device *dev)
+{
+ struct net_local *nl = (struct net_local *)dev->priv;
+ struct enet_statistics *r = &nl->enet_stats;
+
+ return r;
+}
+
+static int
+plip_config(struct device *dev, struct ifmap *map)
+{
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+
+ printk(KERN_INFO "%s: This interface is autodetected (ignored).\n",
+ dev->name);
+
+ return 0;
+}
+
+static int
+plip_ioctl(struct device *dev, struct ifreq *rq, int cmd)
+{
+ struct net_local *nl = (struct net_local *) dev->priv;
+ struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
+
+ switch(pc->pcmd) {
+ case PLIP_GET_TIMEOUT:
+ pc->trigger = nl->trigger;
+ pc->nibble = nl->nibble;
+ break;
+ case PLIP_SET_TIMEOUT:
+ nl->trigger = pc->trigger;
+ nl->nibble = pc->nibble;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+/*
+ * Detect and initialize all IO-Extenders in this system.
+ *
+ * Both PLIP and serial devices are configured.
+ */
+int plip_init(struct device *dev)
+{
+ IOEXT_struct *board;
+ struct net_local *nl;
+
+ if (ioext_num == 0) {
+ printk(KERN_INFO "%s\n", version);
+ }
+
+ board = PLIP_DEV(dev)->board;
+ dev->base_addr = (unsigned long)&board->par.DATA;
+
+ /* Cheat and use irq to index into our table */
+ dev->irq = ioext_num;
+
+ printk(KERN_INFO "%s: IO-Extender parallel port at 0x%08lX\n", dev->name, dev->base_addr);
+
+ /* Fill in the generic fields of the device structure. */
+ ether_setup(dev);
+
+ /* Then, override parts of it */
+ dev->hard_start_xmit = plip_tx_packet;
+ dev->open = plip_open;
+ dev->stop = plip_close;
+ dev->get_stats = plip_get_stats;
+ dev->set_config = plip_config;
+ dev->do_ioctl = plip_ioctl;
+ dev->tx_queue_len = 10;
+ dev->flags = IFF_POINTOPOINT|IFF_NOARP;
+
+ /* Set the private structure */
+ dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL);
+ if (dev->priv == NULL) {
+ printk(KERN_ERR "%s: out of memory\n", dev->name);
+ return -ENOMEM;
+ }
+ memset(dev->priv, 0, sizeof(struct net_local));
+ nl = (struct net_local *) dev->priv;
+
+ nl->orig_rebuild_header = dev->rebuild_header;
+ dev->rebuild_header = plip_rebuild_header;
+
+ /* Initialize constants */
+ nl->trigger = PLIP_TRIGGER_WAIT;
+ nl->nibble = PLIP_NIBBLE_WAIT;
+
+ /* Initialize task queue structures */
+ nl->immediate.next = NULL;
+ nl->immediate.sync = 0;
+ nl->immediate.routine = (void *)(void *)plip_bh;
+ nl->immediate.data = dev;
+
+ nl->deferred.next = NULL;
+ nl->deferred.sync = 0;
+ nl->deferred.routine = (void *)(void *)plip_kick_bh;
+ nl->deferred.data = dev;
+
+ /* Don't enable interrupts yet */
+
+ return 0;
+}
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/ide/ide-iops.c linux-2.6.12/drivers/ide/ide-iops.c
--- linux-2.6.12-i386/drivers/ide/ide-iops.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/ide/ide-iops.c 2005-06-19 16:33:16.000000000 +0200
@@ -341,6 +341,23 @@
int i;
u16 *stringcast;
+#ifdef __mc68000__
+ if (!MACH_IS_AMIGA && !MACH_IS_MAC && !MACH_IS_Q40 && !MACH_IS_ATARI)
+ return;
+
+#ifdef M68K_IDE_SWAPW
+ if (M68K_IDE_SWAPW) { /* fix bus byteorder first */
+ u_char *p = (u_char *)id;
+ u_char t;
+ for (i = 0; i < 512; i += 2) {
+ t = p[i];
+ p[i] = p[i+1];
+ p[i+1] = t;
+ }
+ }
+#endif
+#endif /* __mc68000__ */
+
id->config = __le16_to_cpu(id->config);
id->cyls = __le16_to_cpu(id->cyls);
id->reserved2 = __le16_to_cpu(id->reserved2);
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/macintosh/adb.c linux-2.6.12/drivers/macintosh/adb.c
--- linux-2.6.12-i386/drivers/macintosh/adb.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/macintosh/adb.c 2005-06-19 16:33:31.000000000 +0200
@@ -476,13 +476,15 @@
use_sreq = 1;
} else
use_sreq = 0;
- req->nbytes = nbytes+1;
+ i = (flags & ADBREQ_RAW) ? 0 : 1;
+ req->nbytes = nbytes+i;
req->done = done;
req->reply_expected = flags & ADBREQ_REPLY;
req->data[0] = ADB_PACKET;
va_start(list, nbytes);
- for (i = 0; i < nbytes; ++i)
- req->data[i+1] = va_arg(list, int);
+ while (i < req->nbytes) {
+ req->data[i++] = va_arg(list, int);
+ }
va_end(list);
if (flags & ADBREQ_NOSEND)
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/net/Kconfig linux-2.6.12/drivers/net/Kconfig
--- linux-2.6.12-i386/drivers/net/Kconfig 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/net/Kconfig 2005-06-19 16:33:45.000000000 +0200
@@ -294,7 +294,7 @@
config MAC89x0
tristate "Macintosh CS89x0 based ethernet cards"
- depends on NET_ETHERNET && MAC && BROKEN
+ depends on NET_ETHERNET && MAC
---help---
Support for CS89x0 chipset based Ethernet cards. If you have a
Nubus or LC-PDS network (Ethernet) card of this type, say Y and
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/net/mac89x0.c linux-2.6.12/drivers/net/mac89x0.c
--- linux-2.6.12-i386/drivers/net/mac89x0.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/net/mac89x0.c 2004-12-30 16:38:24.000000000 +0100
@@ -128,7 +128,7 @@
extern void reset_chip(struct net_device *dev);
#endif
static int net_open(struct net_device *dev);
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
+static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static void set_multicast_list(struct net_device *dev);
static void net_rx(struct net_device *dev);
@@ -374,56 +374,37 @@
static int
net_send_packet(struct sk_buff *skb, struct net_device *dev)
{
- if (dev->tbusy) {
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5)
- return 1;
- if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name,
- tx_done(dev) ? "IRQ conflict" : "network cable problem");
- /* Try to restart the adaptor. */
- dev->tbusy=0;
- dev->trans_start = jiffies;
- }
-
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
- else {
- struct net_local *lp = netdev_priv(dev);
- unsigned long flags;
-
- if (net_debug > 3)
- printk("%s: sent %d byte packet of type %x\n",
- dev->name, skb->len,
- (skb->data[ETH_ALEN+ETH_ALEN] << 8)
- | skb->data[ETH_ALEN+ETH_ALEN+1]);
-
- /* keep the upload from being interrupted, since we
- ask the chip to start transmitting before the
- whole packet has been completely uploaded. */
- local_irq_save(flags);
-
- /* initiate a transmit sequence */
- writereg(dev, PP_TxCMD, lp->send_cmd);
- writereg(dev, PP_TxLength, skb->len);
-
- /* Test to see if the chip has allocated memory for the packet */
- if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
- /* Gasp! It hasn't. But that shouldn't happen since
- we're waiting for TxOk, so return 1 and requeue this packet. */
- local_irq_restore(flags);
- return 1;
- }
+ struct net_local *lp = netdev_priv(dev);
+ unsigned long flags;
- /* Write the contents of the packet */
- memcpy_toio(dev->mem_start + PP_TxFrame, skb->data, skb->len+1);
+ if (net_debug > 3)
+ printk("%s: sent %d byte packet of type %x\n",
+ dev->name, skb->len,
+ (skb->data[ETH_ALEN+ETH_ALEN] << 8)
+ | skb->data[ETH_ALEN+ETH_ALEN+1]);
+
+ /* keep the upload from being interrupted, since we
+ ask the chip to start transmitting before the
+ whole packet has been completely uploaded. */
+ local_irq_save(flags);
+ /* initiate a transmit sequence */
+ writereg(dev, PP_TxCMD, lp->send_cmd);
+ writereg(dev, PP_TxLength, skb->len);
+
+ /* Test to see if the chip has allocated memory for the packet */
+ if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
+ /* Gasp! It hasn't. But that shouldn't happen since
+ we're waiting for TxOk, so return 1 and requeue this packet. */
local_irq_restore(flags);
- dev->trans_start = jiffies;
+ return 1;
}
+
+ /* Write the contents of the packet */
+ memcpy((void *)(dev->mem_start + PP_TxFrame), skb->data, skb->len+1);
+
+ local_irq_restore(flags);
+ dev->trans_start = jiffies;
dev_kfree_skb (skb);
return 0;
@@ -441,9 +422,6 @@
printk ("net_interrupt(): irq %d for unknown device.\n", irq);
return IRQ_NONE;
}
- if (dev->interrupt)
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
- dev->interrupt = 1;
ioaddr = dev->base_addr;
lp = netdev_priv(dev);
@@ -464,8 +442,7 @@
break;
case ISQ_TRANSMITTER_EVENT:
lp->stats.tx_packets++;
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
+ netif_wake_queue(dev);
if ((status & TX_OK) == 0) lp->stats.tx_errors++;
if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++;
if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++;
@@ -479,8 +456,7 @@
That shouldn't happen since we only ever
load one packet. Shrug. Do the right
thing anyway. */
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
+ netif_wake_queue(dev);
}
if (status & TX_UNDERRUN) {
if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
@@ -497,7 +473,6 @@
break;
}
}
- dev->interrupt = 0;
return IRQ_HANDLED;
}
@@ -532,7 +507,7 @@
skb_put(skb, length);
skb->dev = dev;
- memcpy_fromio(skb->data, dev->mem_start + PP_RxFrame, length);
+ memcpy(skb->data, (void *)(dev->mem_start + PP_RxFrame), length);
if (net_debug > 3)printk("%s: received %d byte packet of type %x\n",
dev->name, length,
@@ -611,8 +586,6 @@
static int set_mac_address(struct net_device *dev, void *addr)
{
int i;
- if (dev->start)
- return -EBUSY;
printk("%s: Setting MAC address to ", dev->name);
for (i = 0; i < 6; i++)
printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]);
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/scsi/53c7xx.c linux-2.6.12/drivers/scsi/53c7xx.c
--- linux-2.6.12-i386/drivers/scsi/53c7xx.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/scsi/53c7xx.c 2005-06-19 16:34:18.000000000 +0200
@@ -307,7 +307,7 @@
static int check_address (unsigned long addr, int size);
static void dump_events (struct Scsi_Host *host, int count);
-static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host,
+static struct scsi_cmnd * return_outstanding_commands (struct Scsi_Host *host,
int free, int issue);
static void hard_reset (struct Scsi_Host *host);
static void ncr_scsi_reset (struct Scsi_Host *host);
@@ -316,7 +316,7 @@
int scntl3, int now_connected);
static int datapath_residual (struct Scsi_Host *host);
static const char * sbcl_to_phase (int sbcl);
-static void print_progress (Scsi_Cmnd *cmd);
+static void print_progress (struct scsi_cmnd *cmd);
static void print_queues (struct Scsi_Host *host);
static void process_issue_queue (unsigned long flags);
static int shutdown (struct Scsi_Host *host);
@@ -341,9 +341,8 @@
static void NCR53c7x0_soft_reset (struct Scsi_Host *host);
/* Size of event list (per host adapter) */
-static int track_events = 0;
-static struct Scsi_Host *first_host = NULL; /* Head of list of NCR boards */
-static Scsi_Host_Template *the_template = NULL;
+static int track_events;
+static Scsi_Host_Template *the_template;
/* NCR53c710 script handling code */
@@ -666,8 +665,11 @@
static struct Scsi_Host *
find_host (int host) {
- struct Scsi_Host *h;
- for (h = first_host; h && h->host_no != host; h = h->next);
+ struct Scsi_Host *h, *s;
+ list_for_each_entry_safe(h, s, &the_template->legacy_hosts, sht_legacy_list) {
+ if (h->host_no == host)
+ break;
+ }
if (!h) {
printk (KERN_ALERT "scsi%d not found\n", host);
return NULL;
@@ -715,14 +717,14 @@
}
hostdata = (struct NCR53c7x0_hostdata *)h->hostdata[0];
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
if (hostdata->initiate_sdtr & (1 << target)) {
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
printk (KERN_ALERT "target %d already doing SDTR\n", target);
return -1;
}
hostdata->initiate_sdtr |= (1 << target);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return 0;
}
#endif
@@ -1033,9 +1035,6 @@
ccf = clock_to_ccf_710 (expected_clock);
- for (i = 0; i < 16; ++i)
- hostdata->cmd_allocated[i] = 0;
-
if (hostdata->init_save_regs)
hostdata->init_save_regs (host);
if (hostdata->init_fixup)
@@ -1043,7 +1042,6 @@
if (!the_template) {
the_template = host->hostt;
- first_host = host;
}
/*
@@ -1306,7 +1304,6 @@
hostdata->free->size = max_cmd_size;
hostdata->free->free = NULL;
hostdata->free->next = NULL;
- hostdata->extra_allocate = 0;
/* Allocate command start code space */
hostdata->schedule = (chip == 700 || chip == 70066) ?
@@ -1589,10 +1586,10 @@
/* The NCR chip _must_ be idle to run the test scripts */
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
if (!hostdata->idle) {
printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return -1;
}
@@ -1616,7 +1613,7 @@
NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl | DCNTL_SSM |
DCNTL_STD);
printk (" started\n");
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
/*
* This is currently a .5 second timeout, since (in theory) no slow
@@ -1655,7 +1652,7 @@
hostdata->script, start);
printk ("scsi%d : DSPS = 0x%x\n", host->host_no,
NCR53c7x0_read32(DSPS_REG));
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return -1;
}
hostdata->test_running = 0;
@@ -1693,7 +1690,7 @@
local_irq_disable();
if (!hostdata->idle) {
printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return -1;
}
@@ -1709,7 +1706,7 @@
if (hostdata->options & OPTION_DEBUG_TRACE)
NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl |
DCNTL_SSM | DCNTL_STD);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
timeout = jiffies + 5 * HZ; /* arbitrary */
while ((hostdata->test_completed == -1) && time_before(jiffies, timeout))
@@ -1731,19 +1728,19 @@
host->host_no, i);
if (!hostdata->idle) {
printk("scsi%d : not idle\n", host->host_no);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return -1;
}
} else if (hostdata->test_completed == -1) {
printk ("scsi%d : test 2 timed out\n", host->host_no);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return -1;
}
hostdata->test_running = 0;
}
}
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return 0;
}
@@ -1759,7 +1756,7 @@
static void
NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
- Scsi_Cmnd *c = cmd->cmd;
+ struct scsi_cmnd *c = cmd->cmd;
struct Scsi_Host *host = c->device->host;
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata[0];
@@ -1845,7 +1842,7 @@
*
* Purpose : mark SCSI command as finished, OR'ing the host portion
* of the result word into the result field of the corresponding
- * Scsi_Cmnd structure, and removing it from the internal queues.
+ * scsi_cmnd structure, and removing it from the internal queues.
*
* Inputs : cmd - command, result - entire result field
*
@@ -1856,7 +1853,7 @@
static void
abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
- Scsi_Cmnd *c = cmd->cmd;
+ struct scsi_cmnd *c = cmd->cmd;
struct Scsi_Host *host = c->device->host;
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata[0];
@@ -1870,7 +1867,7 @@
printk ("scsi%d: abnormal finished\n", host->host_no);
#endif
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
found = 0;
/*
* Traverse the NCR issue array until we find a match or run out
@@ -1953,7 +1950,7 @@
c->result = result;
c->scsi_done(c);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
run_process_issue_queue();
}
@@ -1975,7 +1972,7 @@
NCR53c7x0_local_declare();
struct NCR53c7x0_break *bp;
#if 0
- Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
+ struct scsi_cmnd *c = cmd ? cmd->cmd : NULL;
#endif
u32 *dsp;
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
@@ -1988,7 +1985,7 @@
* dump the appropriate debugging information to standard
* output.
*/
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
for (bp = hostdata->breakpoints; bp && bp->address != dsp;
bp = bp->next);
@@ -2010,7 +2007,7 @@
* instruction in bytes.
*/
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
}
/*
* Function : static void print_synchronous (const char *prefix,
@@ -2252,7 +2249,7 @@
NCR53c7x0_cmd *cmd) {
NCR53c7x0_local_declare();
int print;
- Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
+ struct scsi_cmnd *c = cmd ? cmd->cmd : NULL;
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata[0];
u32 dsps,*dsp; /* Argument of the INT instruction */
@@ -2916,7 +2913,7 @@
host->hostdata[0];
NCR53c7x0_local_setup(host);
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
/* Disable scsi chip and s/w level 7 ints */
@@ -3017,12 +3014,12 @@
}
#endif
/* Anything needed for your hardware? */
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
}
/*
- * Function static struct NCR53c7x0_cmd *allocate_cmd (Scsi_Cmnd *cmd)
+ * Function static struct NCR53c7x0_cmd *allocate_cmd (struct scsi_cmnd *cmd)
*
* Purpose : Return the first free NCR53c7x0_cmd structure (which are
* reused in a LIFO manner to minimize cache thrashing).
@@ -3049,86 +3046,25 @@
}
static struct NCR53c7x0_cmd *
-allocate_cmd (Scsi_Cmnd *cmd) {
+allocate_cmd (struct scsi_cmnd *cmd) {
struct Scsi_Host *host = cmd->device->host;
struct NCR53c7x0_hostdata *hostdata =
(struct NCR53c7x0_hostdata *) host->hostdata[0];
- u32 real; /* Real address */
- int size; /* Size of *tmp */
struct NCR53c7x0_cmd *tmp;
unsigned long flags;
if (hostdata->options & OPTION_DEBUG_ALLOCATION)
printk ("scsi%d : num_cmds = %d, can_queue = %d\n"
- " target = %d, lun = %d, %s\n",
+ " target = %d, lun = %d\n",
host->host_no, hostdata->num_cmds, host->can_queue,
- cmd->device->id, cmd->device->lun, (hostdata->cmd_allocated[cmd->device->id] &
- (1 << cmd->device->lun)) ? "already allocated" : "not allocated");
-
-/*
- * If we have not yet reserved commands for this I_T_L nexus, and
- * the device exists (as indicated by permanent Scsi_Cmnd structures
- * being allocated under 1.3.x, or being outside of scan_scsis in
- * 1.2.x), do so now.
- */
- if (!(hostdata->cmd_allocated[cmd->device->id] & (1 << cmd->device->lun)) &&
- cmd->device && cmd->device->has_cmdblocks) {
- if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue)
- hostdata->extra_allocate += host->cmd_per_lun;
- hostdata->cmd_allocated[cmd->device->id] |= (1 << cmd->device->lun);
- }
-
- for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate,
- ++hostdata->num_cmds) {
- /* historically, kmalloc has returned unaligned addresses; pad so we
- have enough room to ROUNDUP */
- size = hostdata->max_cmd_size + sizeof (void *);
-#ifdef FORCE_DSA_ALIGNMENT
- /*
- * 53c710 rev.0 doesn't have an add-with-carry instruction.
- * Ensure we allocate enough memory to force alignment.
- */
- size += 256;
-#endif
-/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
+ cmd->device->id, cmd->device->lun);
- if (size > 4096) {
- printk (KERN_ERR "53c7xx: allocate_cmd size > 4K\n");
- return NULL;
- }
- real = get_zeroed_page(GFP_ATOMIC);
- if (real == 0)
- return NULL;
- memset((void *)real, 0, 4096);
- cache_push(virt_to_phys((void *)real), 4096);
- cache_clear(virt_to_phys((void *)real), 4096);
- kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER);
- tmp = ROUNDUP(real, void *);
-#ifdef FORCE_DSA_ALIGNMENT
- {
- if (((u32)tmp & 0xff) > CmdPageStart)
- tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255);
- tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart);
-#if 0
- printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n",
- size, real, (u32)tmp);
-#endif
- }
-#endif
- tmp->real = (void *)real;
- tmp->size = size;
- tmp->free = ((void (*)(void *, int)) my_free_page);
- local_irq_save(flags);
- tmp->next = hostdata->free;
- hostdata->free = tmp;
- local_irq_restore(flags);
- }
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
tmp = (struct NCR53c7x0_cmd *) hostdata->free;
if (tmp) {
hostdata->free = tmp->next;
}
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
if (!tmp)
printk ("scsi%d : can't allocate command for target %d lun %d\n",
host->host_no, cmd->device->id, cmd->device->lun);
@@ -3136,11 +3072,11 @@
}
/*
- * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd)
+ * Function static struct NCR53c7x0_cmd *create_cmd (struct scsi_cmnd *cmd)
*
*
* Purpose : allocate a NCR53c7x0_cmd structure, initialize it based on the
- * Scsi_Cmnd structure passed in cmd, including dsa and Linux field
+ * scsi_cmnd structure passed in cmd, including dsa and Linux field
* initialization, and dsa code relocation.
*
* Inputs : cmd - SCSI command
@@ -3149,7 +3085,7 @@
* NULL on failure.
*/
static struct NCR53c7x0_cmd *
-create_cmd (Scsi_Cmnd *cmd) {
+create_cmd (struct scsi_cmnd *cmd) {
NCR53c7x0_local_declare();
struct Scsi_Host *host = cmd->device->host;
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
@@ -3173,7 +3109,7 @@
return NULL;
/*
- * Copy CDB and initialised result fields from Scsi_Cmnd to NCR53c7x0_cmd.
+ * Copy CDB and initialised result fields from scsi_cmnd to NCR53c7x0_cmd.
* We do this because NCR53c7x0_cmd may have a special cache mode
* selected to cope with lack of bus snooping, etc.
*/
@@ -3316,7 +3252,7 @@
patch_dsa_32(tmp->dsa, dsa_next, 0, 0);
/*
- * XXX is this giving 53c710 access to the Scsi_Cmnd in some way?
+ * XXX is this giving 53c710 access to the scsi_cmnd in some way?
* Do we need to change it for caching reasons?
*/
patch_dsa_32(tmp->dsa, dsa_cmnd, 0, virt_to_bus(cmd));
@@ -3347,17 +3283,17 @@
memcpy ((void *) (tmp->select + 1), (void *) wdtr_message,
sizeof(wdtr_message));
patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(wdtr_message));
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
hostdata->initiate_wdtr &= ~(1 << cmd->device->id);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
} else if (hostdata->initiate_sdtr & (1 << cmd->device->id)) {
memcpy ((void *) (tmp->select + 1), (void *) sdtr_message,
sizeof(sdtr_message));
patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(sdtr_message));
tmp->flags |= CMD_FLAG_SDTR;
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
hostdata->initiate_sdtr &= ~(1 << cmd->device->id);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
}
#if 1
@@ -3570,8 +3506,8 @@
}
/*
- * Function : int NCR53c7xx_queue_command (Scsi_Cmnd *cmd,
- * void (*done)(Scsi_Cmnd *))
+ * Function : int NCR53c7xx_queue_command (struct scsi_cmnd *cmd,
+ * void (*done)(struct scsi_cmnd *))
*
* Purpose : enqueues a SCSI command
*
@@ -3585,18 +3521,18 @@
* twiddling done to the host specific fields of cmd. If the
* process_issue_queue coroutine isn't running, it is restarted.
*
- * NOTE : we use the host_scribble field of the Scsi_Cmnd structure to
+ * NOTE : we use the host_scribble field of the scsi_cmnd structure to
* hold our own data, and pervert the ptr field of the SCp field
* to create a linked list.
*/
int
-NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
+NCR53c7xx_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) {
struct Scsi_Host *host = cmd->device->host;
struct NCR53c7x0_hostdata *hostdata =
(struct NCR53c7x0_hostdata *) host->hostdata[0];
unsigned long flags;
- Scsi_Cmnd *tmp;
+ struct scsi_cmnd *tmp;
cmd->scsi_done = done;
cmd->host_scribble = NULL;
@@ -3614,7 +3550,7 @@
}
#endif
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY))
|| ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
!(hostdata->debug_lun_limit[cmd->device->id] & (1 << cmd->device->lun)))
@@ -3629,7 +3565,7 @@
cmd->device->id, cmd->device->lun);
cmd->result = (DID_BAD_TARGET << 16);
done(cmd);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return 0;
}
@@ -3638,7 +3574,7 @@
printk("scsi%d : maximum commands exceeded\n", host->host_no);
cmd->result = (DID_BAD_TARGET << 16);
done(cmd);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return 0;
}
@@ -3650,7 +3586,7 @@
host->host_no);
cmd->result = (DID_BAD_TARGET << 16);
done(cmd);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return 0;
}
}
@@ -3673,18 +3609,18 @@
cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
hostdata->issue_queue = cmd;
} else {
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->SCp.ptr;
- tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
+ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->SCp.ptr;
+ tmp = (struct scsi_cmnd *) tmp->SCp.ptr);
tmp->SCp.ptr = (unsigned char *) cmd;
}
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
run_process_issue_queue();
return 0;
}
/*
* Function : void to_schedule_list (struct Scsi_Host *host,
- * struct NCR53c7x0_hostdata * hostdata, Scsi_Cmnd *cmd)
+ * struct NCR53c7x0_hostdata * hostdata, struct scsi_cmnd *cmd)
*
* Purpose : takes a SCSI command which was just removed from the
* issue queue, and deals with it by inserting it in the first
@@ -3705,7 +3641,7 @@
to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
struct NCR53c7x0_cmd *cmd) {
NCR53c7x0_local_declare();
- Scsi_Cmnd *tmp = cmd->cmd;
+ struct scsi_cmnd *tmp = cmd->cmd;
unsigned long flags;
/* dsa start is negative, so subtraction is used */
volatile u32 *ncrcurrent;
@@ -3717,7 +3653,7 @@
virt_to_bus(hostdata->dsa), hostdata->dsa);
#endif
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
/*
* Work around race condition : if an interrupt fired and we
@@ -3730,7 +3666,7 @@
cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
hostdata->free = cmd;
tmp->scsi_done(tmp);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return;
}
@@ -3760,7 +3696,7 @@
cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
hostdata->free = cmd;
tmp->scsi_done(tmp);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return;
}
@@ -3781,12 +3717,12 @@
NCR53c7x0_write8(hostdata->istat, ISTAT_10_SIGP);
}
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
}
/*
* Function : busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata
- * *hostdata, Scsi_Cmnd *cmd)
+ * *hostdata, struct scsi_cmnd *cmd)
*
* Purpose : decide if we can pass the given SCSI command on to the
* device in question or not.
@@ -3796,7 +3732,7 @@
static __inline__ int
busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
- Scsi_Cmnd *cmd) {
+ struct scsi_cmnd *cmd) {
/* FIXME : in the future, this needs to accommodate SCSI-II tagged
queuing, and we may be able to play with fairness here a bit.
*/
@@ -3822,8 +3758,8 @@
static void
process_issue_queue (unsigned long flags) {
- Scsi_Cmnd *tmp, *prev;
- struct Scsi_Host *host;
+ struct scsi_cmnd *tmp, *prev;
+ struct Scsi_Host *host, *s;
struct NCR53c7x0_hostdata *hostdata;
int done;
@@ -3841,14 +3777,13 @@
do {
local_irq_disable(); /* Freeze request queues */
done = 1;
- for (host = first_host; host && host->hostt == the_template;
- host = host->next) {
+ list_for_each_entry_safe(host, s, &the_template->legacy_hosts, sht_legacy_list) {
hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
- local_irq_disable();
+ spin_lock_irq(host->host_lock);
if (hostdata->issue_queue) {
if (hostdata->state == STATE_DISABLED) {
- tmp = (Scsi_Cmnd *) hostdata->issue_queue;
- hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
+ tmp = (struct scsi_cmnd *) hostdata->issue_queue;
+ hostdata->issue_queue = (struct scsi_cmnd *) tmp->SCp.ptr;
tmp->result = (DID_BAD_TARGET << 16);
if (tmp->host_scribble) {
((struct NCR53c7x0_cmd *)tmp->host_scribble)->next =
@@ -3860,15 +3795,15 @@
tmp->scsi_done (tmp);
done = 0;
} else
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue,
- prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *)
+ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue,
+ prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *)
tmp->SCp.ptr)
if (!tmp->host_scribble ||
!busyp (host, hostdata, tmp)) {
if (prev)
prev->SCp.ptr = tmp->SCp.ptr;
else
- hostdata->issue_queue = (Scsi_Cmnd *)
+ hostdata->issue_queue = (struct scsi_cmnd *)
tmp->SCp.ptr;
tmp->SCp.ptr = NULL;
if (tmp->host_scribble) {
@@ -3893,6 +3828,7 @@
done = 0;
} /* if target/lun is not busy */
} /* if hostdata->issue_queue */
+ spin_unlock(host->host_lock);
if (!done)
local_irq_restore(flags);
} /* for host */
@@ -4103,7 +4039,7 @@
int cnt = 0;
int i = insn_log_index;
int size;
- struct Scsi_Host *host = first_host;
+ struct Scsi_Host *host = (struct Scsi_Host *)the_template->legacy_hosts->next;
while (cnt < 4096) {
printk ("%08x (+%6x): ", insn_log[i], (insn_log[i] - (u32)&(((struct NCR53c7x0_hostdata *)host->hostdata[0])->script))/4);
@@ -4161,14 +4097,14 @@
* completion.
*/
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
restart:
for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)&(hostdata->running_list),
cmd = (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next),
cmd = (struct NCR53c7x0_cmd *) cmd->next)
{
- Scsi_Cmnd *tmp;
+ struct scsi_cmnd *tmp;
if (!cmd) {
printk("scsi%d : very weird.\n", host->host_no);
@@ -4176,7 +4112,7 @@
}
if (!(tmp = cmd->cmd)) {
- printk("scsi%d : weird. NCR53c7x0_cmd has no Scsi_Cmnd\n",
+ printk("scsi%d : weird. NCR53c7x0_cmd has no scsi_cmnd\n",
host->host_no);
continue;
}
@@ -4215,7 +4151,7 @@
tmp->scsi_done(tmp);
goto restart;
}
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
if (!search_found) {
printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
@@ -4250,7 +4186,7 @@
struct NCR53c7x0_cmd *cmd; /* command which halted */
u32 *dsa; /* DSA */
int handled = 0;
-
+ unsigned long flags;
#ifdef NCR_DEBUG
char buf[80]; /* Debugging sprintf buffer */
size_t buflen; /* Length of same */
@@ -4259,6 +4195,7 @@
host = (struct Scsi_Host *)dev_id;
hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
NCR53c7x0_local_setup(host);
+ spin_lock_irqsave(host->host_lock, flags);
/*
* Only read istat once per loop, since reading it again will unstack
@@ -4351,7 +4288,8 @@
}
}
}
- return IRQ_HANDLED;
+ spin_unlock_irqrestore(host->host_lock, flags);
+ return IRQ_RETVAL(handled);
}
@@ -4360,7 +4298,7 @@
*
* Purpose : Assuming that the NCR SCSI processor is currently
* halted, break the currently established nexus. Clean
- * up of the NCR53c7x0_cmd and Scsi_Cmnd structures should
+ * up of the NCR53c7x0_cmd and scsi_cmnd structures should
* be done on receipt of the abort interrupt.
*
* Inputs : host - SCSI host
@@ -4899,12 +4837,12 @@
/* Don't print instr. until we write DSP at end of intr function */
} else if (hostdata->options & OPTION_DEBUG_SINGLE) {
print_insn (host, dsp, "s ", 0);
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
/* XXX - should we do this, or can we get away with writing dsp? */
NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) &
~DCNTL_SSM) | DCNTL_STD);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
} else {
printk(KERN_ALERT "scsi%d : unexpected single step interrupt at\n"
" ", host->host_no);
@@ -5127,7 +5065,7 @@
}
/*
- * Function : int NCR53c7xx_abort (Scsi_Cmnd *cmd)
+ * Function : int NCR53c7xx_abort (struct scsi_cmnd *cmd)
*
* Purpose : Abort an errant SCSI command, doing all necessary
* cleanup of the issue_queue, running_list, shared Linux/NCR
@@ -5139,14 +5077,14 @@
*/
int
-NCR53c7xx_abort (Scsi_Cmnd *cmd) {
+NCR53c7xx_abort (struct scsi_cmnd *cmd) {
NCR53c7x0_local_declare();
struct Scsi_Host *host = cmd->device->host;
struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *)
host->hostdata[0] : NULL;
unsigned long flags;
struct NCR53c7x0_cmd *curr, **prev;
- Scsi_Cmnd *me, **last;
+ struct scsi_cmnd *me, **last;
#if 0
static long cache_pid = -1;
#endif
@@ -5155,10 +5093,10 @@
if (!host) {
printk ("Bogus SCSI command pid %ld; no host structure\n",
cmd->pid);
- return SCSI_ABORT_ERROR;
+ return FAILED;
} else if (!hostdata) {
printk ("Bogus SCSI host %d; no hostdata\n", host->host_no);
- return SCSI_ABORT_ERROR;
+ return FAILED;
}
NCR53c7x0_local_setup(host);
@@ -5179,10 +5117,10 @@
printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no,
cmd->pid);
NCR53c7x0_intr (host->irq, NULL, NULL);
- return SCSI_ABORT_BUSY;
+ return FAILED;
}
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
#if 0
if (cache_pid == cmd->pid)
panic ("scsi%d : bloody fetus %d\n", host->host_no, cmd->pid);
@@ -5201,13 +5139,13 @@
* pull the command out of the old queue, and call it aborted.
*/
- for (me = (Scsi_Cmnd *) hostdata->issue_queue,
- last = (Scsi_Cmnd **) &(hostdata->issue_queue);
- me && me != cmd; last = (Scsi_Cmnd **)&(me->SCp.ptr),
- me = (Scsi_Cmnd *)me->SCp.ptr);
+ for (me = (struct scsi_cmnd *) hostdata->issue_queue,
+ last = (struct scsi_cmnd **) &(hostdata->issue_queue);
+ me && me != cmd; last = (struct scsi_cmnd **)&(me->SCp.ptr),
+ me = (struct scsi_cmnd *)me->SCp.ptr);
if (me) {
- *last = (Scsi_Cmnd *) me->SCp.ptr;
+ *last = (struct scsi_cmnd *) me->SCp.ptr;
if (me->host_scribble) {
((struct NCR53c7x0_cmd *)me->host_scribble)->next = hostdata->free;
hostdata->free = (struct NCR53c7x0_cmd *) me->host_scribble;
@@ -5217,9 +5155,9 @@
cmd->scsi_done(cmd);
printk ("scsi%d : found command %ld in Linux issue queue\n",
host->host_no, me->pid);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
run_process_issue_queue();
- return SCSI_ABORT_SUCCESS;
+ return SUCCESS;
}
/*
@@ -5243,13 +5181,13 @@
cmd->scsi_done(cmd);
printk ("scsi%d : found finished command %ld in running list\n",
host->host_no, cmd->pid);
- local_irq_restore(flags);
- return SCSI_ABORT_NOT_RUNNING;
+ spin_unlock_irqrestore(host->host_lock, flags);
+ return SUCCESS;
} else {
printk ("scsi%d : DANGER : command running, can not abort.\n",
cmd->device->host->host_no);
- local_irq_restore(flags);
- return SCSI_ABORT_BUSY;
+ spin_unlock_irqrestore(host->host_lock, flags);
+ return FAILED;
}
}
@@ -5280,21 +5218,20 @@
*/
--hostdata->busy[cmd->device->id][cmd->device->lun];
}
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
cmd->scsi_done(cmd);
/*
* We need to run process_issue_queue since termination of this command
* may allow another queued command to execute first?
*/
- return SCSI_ABORT_NOT_RUNNING;
+ return SUCCESS;
}
/*
- * Function : int NCR53c7xx_reset (Scsi_Cmnd *cmd)
+ * Function : int NCR53c7xx_reset (struct scsi_cmnd *cmd)
*
- * Purpose : perform a hard reset of the SCSI bus and NCR
- * chip.
+ * Purpose : perform a hard reset of the SCSI bus.
*
* Inputs : cmd - command which caused the SCSI RESET
*
@@ -5302,12 +5239,12 @@
*/
int
-NCR53c7xx_reset (Scsi_Cmnd *cmd, unsigned int reset_flags) {
+NCR53c7xx_reset (struct scsi_cmnd *cmd) {
NCR53c7x0_local_declare();
unsigned long flags;
int found = 0;
struct NCR53c7x0_cmd * c;
- Scsi_Cmnd *tmp;
+ struct scsi_cmnd *tmp;
/*
* When we call scsi_done(), it's going to wake up anything sleeping on the
* resources which were in use by the aborted commands, and we'll start to
@@ -5322,19 +5259,19 @@
* pointer), do our reinitialization, and then call the done function for
* each command.
*/
- Scsi_Cmnd *nuke_list = NULL;
+ struct scsi_cmnd *nuke_list = NULL;
struct Scsi_Host *host = cmd->device->host;
struct NCR53c7x0_hostdata *hostdata =
(struct NCR53c7x0_hostdata *) host->hostdata[0];
NCR53c7x0_local_setup(host);
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
ncr_halt (host);
print_lots (host);
dump_events (host, 30);
ncr_scsi_reset (host);
for (tmp = nuke_list = return_outstanding_commands (host, 1 /* free */,
- 0 /* issue */ ); tmp; tmp = (Scsi_Cmnd *) tmp->SCp.buffer)
+ 0 /* issue */ ); tmp; tmp = (struct scsi_cmnd *) tmp->SCp.buffer)
if (tmp == cmd) {
found = 1;
break;
@@ -5357,19 +5294,21 @@
}
NCR53c7x0_driver_init (host);
+#if 0
hostdata->soft_reset (host);
+#endif
if (hostdata->resets == 0)
disable(host);
else if (hostdata->resets != -1)
--hostdata->resets;
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
for (; nuke_list; nuke_list = tmp) {
- tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
+ tmp = (struct scsi_cmnd *) nuke_list->SCp.buffer;
nuke_list->result = DID_RESET << 16;
nuke_list->scsi_done (nuke_list);
}
- local_irq_restore(flags);
- return SCSI_RESET_SUCCESS;
+ spin_unlock_irqrestore(host->host_lock, flags);
+ return SUCCESS;
}
/*
@@ -5378,7 +5317,7 @@
*/
/*
- * Function : int insn_to_offset (Scsi_Cmnd *cmd, u32 *insn)
+ * Function : int insn_to_offset (struct scsi_cmnd *cmd, u32 *insn)
*
* Purpose : convert instructions stored at NCR pointer into data
* pointer offset.
@@ -5391,7 +5330,7 @@
static int
-insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
+insn_to_offset (struct scsi_cmnd *cmd, u32 *insn) {
struct NCR53c7x0_hostdata *hostdata =
(struct NCR53c7x0_hostdata *) cmd->device->host->hostdata[0];
struct NCR53c7x0_cmd *ncmd =
@@ -5445,7 +5384,7 @@
/*
- * Function : void print_progress (Scsi_Cmnd *cmd)
+ * Function : void print_progress (struct scsi_cmnd *cmd)
*
* Purpose : print the current location of the saved data pointer
*
@@ -5454,7 +5393,7 @@
*/
static void
-print_progress (Scsi_Cmnd *cmd) {
+print_progress (struct scsi_cmnd *cmd) {
NCR53c7x0_local_declare();
struct NCR53c7x0_cmd *ncmd =
(struct NCR53c7x0_cmd *) cmd->host_scribble;
@@ -5512,7 +5451,7 @@
host->hostdata[0];
int i, len;
char *ptr;
- Scsi_Cmnd *cmd;
+ struct scsi_cmnd *cmd;
if (check_address ((unsigned long) dsa, hostdata->dsa_end -
hostdata->dsa_start) == -1) {
@@ -5548,7 +5487,7 @@
printk(" + %d : select_indirect = 0x%x\n",
hostdata->dsa_select, dsa[hostdata->dsa_select / sizeof(u32)]);
- cmd = (Scsi_Cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
+ cmd = (struct scsi_cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
printk(" + %d : dsa_cmnd = 0x%x ", hostdata->dsa_cmnd,
(u32) virt_to_bus(cmd));
/* XXX Maybe we should access cmd->host_scribble->result here. RGH */
@@ -5588,16 +5527,16 @@
u32 *dsa, *next_dsa;
volatile u32 *ncrcurrent;
int left;
- Scsi_Cmnd *cmd, *next_cmd;
+ struct scsi_cmnd *cmd, *next_cmd;
unsigned long flags;
printk ("scsi%d : issue queue\n", host->host_no);
- for (left = host->can_queue, cmd = (Scsi_Cmnd *) hostdata->issue_queue;
+ for (left = host->can_queue, cmd = (struct scsi_cmnd *) hostdata->issue_queue;
left >= 0 && cmd;
cmd = next_cmd) {
- next_cmd = (Scsi_Cmnd *) cmd->SCp.ptr;
- local_irq_save(flags);
+ next_cmd = (struct scsi_cmnd *) cmd->SCp.ptr;
+ spin_lock_irqsave(host->host_lock, flags);
if (cmd->host_scribble) {
if (check_address ((unsigned long) (cmd->host_scribble),
sizeof (cmd->host_scribble)) == -1)
@@ -5610,7 +5549,7 @@
} else
printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n",
host->host_no, cmd->pid, cmd->device->id, cmd->device->lun);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
}
if (left <= 0) {
@@ -5642,7 +5581,7 @@
dsa = bus_to_virt (hostdata->reconnect_dsa_head);
left >= 0 && dsa;
dsa = next_dsa) {
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
if (check_address ((unsigned long) dsa, sizeof(dsa)) == -1) {
printk ("scsi%d: bad DSA pointer 0x%p", host->host_no,
dsa);
@@ -5653,7 +5592,7 @@
next_dsa = bus_to_virt(dsa[hostdata->dsa_next / sizeof(u32)]);
print_dsa (host, dsa, "");
}
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
}
printk ("scsi%d : end reconnect_dsa_head\n", host->host_no);
if (left < 0)
@@ -5743,14 +5682,14 @@
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata[0];
NCR53c7x0_local_setup(host);
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
/* Get in a state where we can reset the SCSI bus */
ncr_halt (host);
ncr_scsi_reset (host);
hostdata->soft_reset(host);
disable (host);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
return 0;
}
@@ -5765,11 +5704,11 @@
NCR53c7x0_local_declare();
unsigned long flags;
NCR53c7x0_local_setup(host);
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
udelay(25); /* Minimum amount of time to assert RST */
NCR53c7x0_write8(SCNTL1_REG, 0);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
}
/*
@@ -5782,26 +5721,26 @@
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata[0];
unsigned long flags;
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
ncr_scsi_reset(host);
NCR53c7x0_driver_init (host);
if (hostdata->soft_reset)
hostdata->soft_reset (host);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
}
/*
- * Function : Scsi_Cmnd *return_outstanding_commands (struct Scsi_Host *host,
+ * Function : struct scsi_cmnd *return_outstanding_commands (struct Scsi_Host *host,
* int free, int issue)
*
* Purpose : return a linked list (using the SCp.buffer field as next,
* so we don't perturb hostdata. We don't use a field of the
* NCR53c7x0_cmd structure since we may not have allocated one
- * for the command causing the reset.) of Scsi_Cmnd structures that
+ * for the command causing the reset.) of scsi_cmnd structures that
* had propagated below the Linux issue queue level. If free is set,
* free the NCR53c7x0_cmd structures which are associated with
- * the Scsi_Cmnd structures, and clean up any internal
+ * the scsi_cmnd structures, and clean up any internal
* NCR lists that the commands were on. If issue is set,
* also return commands in the issue queue.
*
@@ -5811,14 +5750,14 @@
* if the free flag is set.
*/
-static Scsi_Cmnd *
+static struct scsi_cmnd *
return_outstanding_commands (struct Scsi_Host *host, int free, int issue) {
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata[0];
struct NCR53c7x0_cmd *c;
int i;
u32 *ncrcurrent;
- Scsi_Cmnd *list = NULL, *tmp;
+ struct scsi_cmnd *list = NULL, *tmp, *next_cmd;
for (c = (struct NCR53c7x0_cmd *) hostdata->running_list; c;
c = (struct NCR53c7x0_cmd *) c->next) {
if (c->cmd->SCp.buffer) {
@@ -5847,7 +5786,9 @@
}
if (issue) {
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; tmp = tmp->next) {
+ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp; tmp = next_cmd) {
+ next_cmd = (struct scsi_cmnd *) tmp->SCp.ptr;
+
if (tmp->SCp.buffer) {
printk ("scsi%d : loop detected in issue queue!\n",
host->host_no);
@@ -5882,17 +5823,17 @@
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
host->hostdata[0];
unsigned long flags;
- Scsi_Cmnd *nuke_list, *tmp;
- local_irq_save(flags);
+ struct scsi_cmnd *nuke_list, *tmp;
+ spin_lock_irqsave(host->host_lock, flags);
if (hostdata->state != STATE_HALTED)
ncr_halt (host);
nuke_list = return_outstanding_commands (host, 1 /* free */, 1 /* issue */);
hard_reset (host);
hostdata->state = STATE_DISABLED;
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
printk ("scsi%d : nuking commands\n", host->host_no);
for (; nuke_list; nuke_list = tmp) {
- tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
+ tmp = (struct scsi_cmnd *) nuke_list->SCp.buffer;
nuke_list->result = DID_ERROR << 16;
nuke_list->scsi_done(nuke_list);
}
@@ -5922,7 +5863,7 @@
int stage;
NCR53c7x0_local_setup(host);
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
/* Stage 0 : eat all interrupts
Stage 1 : set ABORT
Stage 2 : eat all but abort interrupts
@@ -5957,7 +5898,7 @@
}
}
hostdata->state = STATE_HALTED;
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
#if 0
print_lots (host);
#endif
@@ -6011,7 +5952,7 @@
* still be guaranteed that they're happening on the same
* event structure.
*/
- local_irq_save(flags);
+ spin_lock_irqsave(host->host_lock, flags);
#if 0
event = hostdata->events[i];
#else
@@ -6019,7 +5960,7 @@
sizeof(event));
#endif
- local_irq_restore(flags);
+ spin_unlock_irqrestore(host->host_lock, flags);
printk ("scsi%d : %s event %d at %ld secs %ld usecs target %d lun %d\n",
host->host_no, event_name (event.event), count,
(long) event.time.tv_sec, (long) event.time.tv_usec,
@@ -6054,6 +5995,72 @@
return (virt_to_phys((void *)addr) < PAGE_SIZE || virt_to_phys((void *)(addr + size)) > virt_to_phys(high_memory) ? -1 : 0);
}
+int
+NCR53c7xx_slave_configure(struct scsi_device *sdev) {
+ struct Scsi_Host *host = sdev->host;
+ struct NCR53c7x0_hostdata *hostdata =
+ (struct NCR53c7x0_hostdata *) host->hostdata[0];
+ struct NCR53c7x0_cmd *tmp;
+ u32 real; /* Real address */
+ int size; /* Size of *tmp */
+ unsigned long flags;
+ int extra_allocate = 0;
+
+/*
+ * Reserve commands for this I_T_L nexus.
+ */
+ if (hostdata->num_cmds < host->can_queue)
+ extra_allocate = host->cmd_per_lun;
+
+ for (; extra_allocate > 0 ; --extra_allocate,
+ ++hostdata->num_cmds) {
+ /* historically, kmalloc has returned unaligned addresses; pad so we
+ have enough room to ROUNDUP */
+ size = hostdata->max_cmd_size + sizeof (void *);
+#ifdef FORCE_DSA_ALIGNMENT
+ /*
+ * 53c710 rev.0 doesn't have an add-with-carry instruction.
+ * Ensure we allocate enough memory to force alignment.
+ */
+ size += 256;
+#endif
+/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
+
+ if (size > 4096) {
+ printk (KERN_ERR "53c7xx: slave_configure size > 4K\n");
+ return -ENOMEM;
+ }
+ real = get_zeroed_page(GFP_ATOMIC);
+ if (real == 0)
+ return -ENOMEM;
+ memset((void *)real, 0, 4096);
+ cache_push(virt_to_phys((void *)real), 4096);
+ cache_clear(virt_to_phys((void *)real), 4096);
+ kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER);
+ tmp = ROUNDUP(real, void *);
+#ifdef FORCE_DSA_ALIGNMENT
+ {
+ if (((u32)tmp & 0xff) > CmdPageStart)
+ tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255);
+ tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart);
+#if 0
+ printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n",
+ size, real, (u32)tmp);
+#endif
+ }
+#endif
+ tmp->real = (void *)real;
+ tmp->size = size;
+ tmp->free = ((void (*)(void *, int)) my_free_page);
+ spin_lock_irqsave(host->host_lock, flags);
+ tmp->next = hostdata->free;
+ hostdata->free = tmp;
+ spin_unlock_irqrestore(host->host_lock, flags);
+ }
+
+ return 0;
+}
+
#ifdef MODULE
int
NCR53c7x0_release(struct Scsi_Host *host) {
@@ -6063,19 +6070,22 @@
shutdown (host);
if (host->irq != SCSI_IRQ_NONE)
{
- int irq_count;
- struct Scsi_Host *tmp;
- for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
- if (tmp->hostt == the_template && tmp->irq == host->irq)
+ int irq_count = 0;
+ struct Scsi_Host *tmp, *s;
+ list_for_each_entry_safe(tmp, s, &the_template->legacy_hosts, sht_legacy_list) {
+ if (tmp->irq == host->irq)
++irq_count;
+ }
if (irq_count == 1)
free_irq(host->irq, NULL);
}
+#ifdef CONFIG_ISA
if (host->dma_channel != DMA_NONE)
free_dma(host->dma_channel);
+#endif
if (host->io_port)
release_region(host->io_port, host->n_io_port);
-
+
for (cmd = (struct NCR53c7x0_cmd *) hostdata->free; cmd; cmd = tmp,
--hostdata->num_cmds) {
tmp = (struct NCR53c7x0_cmd *) cmd->next;
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/scsi/53c7xx.h linux-2.6.12/drivers/scsi/53c7xx.h
--- linux-2.6.12-i386/drivers/scsi/53c7xx.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/scsi/53c7xx.h 2004-10-30 16:35:43.000000000 +0200
@@ -997,7 +997,7 @@
u32 *dsa; /* What's in the DSA register now (virt) */
/*
* A few things from that SCSI pid so we know what happened after
- * the Scsi_Cmnd structure in question may have disappeared.
+ * the scsi_cmnd structure in question may have disappeared.
*/
unsigned long pid; /* The SCSI PID which caused this
event */
@@ -1029,8 +1029,8 @@
void (* free)(void *, int); /* Command to deallocate; NULL
for structures allocated with
scsi_register, etc. */
- Scsi_Cmnd *cmd; /* Associated Scsi_Cmnd
- structure, Scsi_Cmnd points
+ struct scsi_cmnd *cmd; /* Associated scsi_cmnd
+ structure, scsi_cmnd points
at NCR53c7x0_cmd using
host_scribble structure */
@@ -1039,8 +1039,8 @@
int flags; /* CMD_* flags */
- unsigned char cmnd[12]; /* CDB, copied from Scsi_Cmnd */
- int result; /* Copy to Scsi_Cmnd when done */
+ unsigned char cmnd[12]; /* CDB, copied from scsi_cmnd */
+ int result; /* Copy to scsi_cmnd when done */
struct { /* Private non-cached bounce buffer */
unsigned char buf[256];
@@ -1339,7 +1339,7 @@
volatile struct NCR53c7x0_synchronous sync[16]
__attribute__ ((aligned (4)));
- volatile Scsi_Cmnd *issue_queue
+ volatile struct scsi_cmnd *issue_queue
__attribute__ ((aligned (4)));
/* waiting to be issued by
Linux driver */
@@ -1363,10 +1363,6 @@
*/
volatile int num_cmds; /* Number of commands
allocated */
- volatile int extra_allocate;
- volatile unsigned char cmd_allocated[16]; /* Have we allocated commands
- for this target yet? If not,
- do so ASAP */
volatile unsigned char busy[16][8]; /* number of commands
executing on each target
*/
@@ -1589,20 +1585,26 @@
/* Patch field in dsa structure (assignment should be +=?) */
#define patch_dsa_32(dsa, symbol, word, value) \
{ \
- (dsa)[(hostdata->##symbol - hostdata->dsa_start) / sizeof(u32) \
+ (dsa)[(hostdata->symbol - hostdata->dsa_start) / sizeof(u32) \
+ (word)] = (value); \
if (hostdata->options & OPTION_DEBUG_DSA) \
printk("scsi : dsa %s symbol %s(%d) word %d now 0x%x\n", \
- #dsa, #symbol, hostdata->##symbol, \
+ #dsa, #symbol, hostdata->symbol, \
(word), (u32) (value)); \
}
/* Paranoid people could use panic() here. */
#define FATAL(host) shutdown((host));
-extern int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip,
+extern int ncr53c7xx_init(struct scsi_host_template *tpnt, int board, int chip,
unsigned long base, int io_port, int irq, int dma,
long long options, int clock);
+extern const char *NCR53c7x0_info(void);
+extern int NCR53c7xx_queue_command(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+extern int NCR53c7xx_abort(struct scsi_cmnd *);
+extern int NCR53c7x0_release (struct Scsi_Host *);
+extern int NCR53c7xx_reset(struct scsi_cmnd *);
+extern int NCR53c7xx_slave_configure(struct scsi_device *);
#endif /* NCR53c710_C */
#endif /* NCR53c710_H */
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/scsi/Kconfig linux-2.6.12/drivers/scsi/Kconfig
--- linux-2.6.12-i386/drivers/scsi/Kconfig 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/scsi/Kconfig 2005-06-19 16:34:18.000000000 +0200
@@ -1631,7 +1631,7 @@
config SCSI_AMIGA7XX
bool "Amiga NCR53c710 SCSI support (EXPERIMENTAL)"
- depends on AMIGA && SCSI && EXPERIMENTAL && BROKEN
+ depends on AMIGA && SCSI && EXPERIMENTAL
help
Support for various NCR53c710-based SCSI controllers on the Amiga.
This includes:
@@ -1728,7 +1728,7 @@
config MVME16x_SCSI
bool "NCR53C710 SCSI driver for MVME16x"
- depends on MVME16x && SCSI && BROKEN
+ depends on MVME16x && SCSI
help
The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
SCSI controller chip. Almost everyone using one of these boards
@@ -1736,7 +1736,7 @@
config BVME6000_SCSI
bool "NCR53C710 SCSI driver for BVME6000"
- depends on BVME6000 && SCSI && BROKEN
+ depends on BVME6000 && SCSI
help
The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
SCSI controller chip. Almost everyone using one of these boards
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/scsi/NCR5380.c linux-2.6.12/drivers/scsi/NCR5380.c
--- linux-2.6.12-i386/drivers/scsi/NCR5380.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/scsi/NCR5380.c 2005-06-19 16:34:18.000000000 +0200
@@ -346,6 +346,7 @@
return -ETIMEDOUT;
}
+#ifdef NDEBUG
static struct {
unsigned char value;
const char *name;
@@ -359,7 +360,6 @@
{PHASE_UNKNOWN, "UNKNOWN"}
};
-#ifdef NDEBUG
static struct {
unsigned char mask;
const char *name;
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/scsi/amiga7xx.c linux-2.6.12/drivers/scsi/amiga7xx.c
--- linux-2.6.12-i386/drivers/scsi/amiga7xx.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/scsi/amiga7xx.c 2004-10-30 16:35:43.000000000 +0200
@@ -27,8 +27,14 @@
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "53c7xx.h"
-#include "amiga7xx.h"
+#ifndef CMD_PER_LUN
+#define CMD_PER_LUN 3
+#endif
+
+#ifndef CAN_QUEUE
+#define CAN_QUEUE 24
+#endif
static int amiga7xx_register_one(Scsi_Host_Template *tpnt,
unsigned long address)
@@ -115,8 +121,10 @@
{
if (shost->irq)
free_irq(shost->irq, NULL);
+#ifdef CONFIG_ISA
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
+#endif
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
@@ -128,8 +136,9 @@
.detect = amiga7xx_detect,
.release = amiga7xx_release,
.queuecommand = NCR53c7xx_queue_command,
- .abort = NCR53c7xx_abort,
- .reset = NCR53c7xx_reset,
+ .eh_abort_handler = NCR53c7xx_abort,
+ .eh_bus_reset_handler = NCR53c7xx_reset,
+ .slave_configure = NCR53c7xx_slave_configure,
.can_queue = 24,
.this_id = 7,
.sg_tablesize = 63,
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/scsi/amiga7xx.h linux-2.6.12/drivers/scsi/amiga7xx.h
--- linux-2.6.12-i386/drivers/scsi/amiga7xx.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/scsi/amiga7xx.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,23 +0,0 @@
-#ifndef AMIGA7XX_H
-
-#include <linux/types.h>
-
-int amiga7xx_detect(Scsi_Host_Template *);
-const char *NCR53c7x0_info(void);
-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int NCR53c7xx_abort(Scsi_Cmnd *);
-int NCR53c7x0_release (struct Scsi_Host *);
-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 3
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 24
-#endif
-
-#include <scsi/scsicam.h>
-
-#endif /* AMIGA7XX_H */
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/scsi/bvme6000.c linux-2.6.12/drivers/scsi/bvme6000.c
--- linux-2.6.12-i386/drivers/scsi/bvme6000.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/scsi/bvme6000.c 2004-10-30 16:35:43.000000000 +0200
@@ -19,10 +19,16 @@
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "53c7xx.h"
-#include "bvme6000.h"
#include<linux/stat.h>
+#ifndef CMD_PER_LUN
+#define CMD_PER_LUN 3
+#endif
+
+#ifndef CAN_QUEUE
+#define CAN_QUEUE 24
+#endif
int bvme6000_scsi_detect(Scsi_Host_Template *tpnt)
{
@@ -52,8 +58,10 @@
{
if (shost->irq)
free_irq(shost->irq, NULL);
+#ifdef CONFIG_ISA
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
+#endif
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
@@ -65,8 +73,9 @@
.detect = bvme6000_scsi_detect,
.release = bvme6000_scsi_release,
.queuecommand = NCR53c7xx_queue_command,
- .abort = NCR53c7xx_abort,
- .reset = NCR53c7xx_reset,
+ .eh_abort_handler = NCR53c7xx_abort,
+ .eh_bus_reset_handler = NCR53c7xx_reset,
+ .slave_configure = NCR53c7xx_slave_configure,
.can_queue = 24,
.this_id = 7,
.sg_tablesize = 63,
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/scsi/bvme6000.h linux-2.6.12/drivers/scsi/bvme6000.h
--- linux-2.6.12-i386/drivers/scsi/bvme6000.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/scsi/bvme6000.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,24 +0,0 @@
-#ifndef BVME6000_SCSI_H
-#define BVME6000_SCSI_H
-
-#include <linux/types.h>
-
-int bvme6000_scsi_detect(Scsi_Host_Template *);
-const char *NCR53c7x0_info(void);
-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int NCR53c7xx_abort(Scsi_Cmnd *);
-int NCR53c7x0_release (struct Scsi_Host *);
-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 3
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 24
-#endif
-
-#include <scsi/scsicam.h>
-
-#endif /* BVME6000_SCSI_H */
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/scsi/mvme16x.c linux-2.6.12/drivers/scsi/mvme16x.c
--- linux-2.6.12-i386/drivers/scsi/mvme16x.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/scsi/mvme16x.c 2004-10-30 16:35:43.000000000 +0200
@@ -17,10 +17,16 @@
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "53c7xx.h"
-#include "mvme16x.h"
#include<linux/stat.h>
+#ifndef CMD_PER_LUN
+#define CMD_PER_LUN 3
+#endif
+
+#ifndef CAN_QUEUE
+#define CAN_QUEUE 24
+#endif
int mvme16x_scsi_detect(Scsi_Host_Template *tpnt)
{
@@ -54,8 +60,10 @@
{
if (shost->irq)
free_irq(shost->irq, NULL);
+#ifdef CONFIG_ISA
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
+#endif
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
@@ -67,8 +75,9 @@
.detect = mvme16x_scsi_detect,
.release = mvme16x_scsi_release,
.queuecommand = NCR53c7xx_queue_command,
- .abort = NCR53c7xx_abort,
- .reset = NCR53c7xx_reset,
+ .eh_abort_handler = NCR53c7xx_abort,
+ .eh_bus_reset_handler = NCR53c7xx_reset,
+ .slave_configure = NCR53c7xx_slave_configure,
.can_queue = 24,
.this_id = 7,
.sg_tablesize = 63,
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/drivers/scsi/mvme16x.h linux-2.6.12/drivers/scsi/mvme16x.h
--- linux-2.6.12-i386/drivers/scsi/mvme16x.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/drivers/scsi/mvme16x.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,24 +0,0 @@
-#ifndef MVME16x_SCSI_H
-#define MVME16x_SCSI_H
-
-#include <linux/types.h>
-
-int mvme16x_scsi_detect(Scsi_Host_Template *);
-const char *NCR53c7x0_info(void);
-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int NCR53c7xx_abort(Scsi_Cmnd *);
-int NCR53c7x0_release (struct Scsi_Host *);
-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 3
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 24
-#endif
-
-#include <scsi/scsicam.h>
-
-#endif /* MVME16x_SCSI_H */
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/fs/binfmt_aout.c linux-2.6.12/fs/binfmt_aout.c
--- linux-2.6.12-i386/fs/binfmt_aout.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/fs/binfmt_aout.c 2005-06-19 16:35:04.000000000 +0200
@@ -368,8 +368,9 @@
send_sig(SIGKILL, current, 0);
return error;
}
-
- flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data);
+
+ flush_icache_user_range((void *)text_addr,
+ ex.a_text + ex.a_data);
} else {
static unsigned long error_time, error_time2;
if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
@@ -396,9 +397,8 @@
bprm->file->f_op->read(bprm->file,
(char __user *)N_TXTADDR(ex),
ex.a_text+ex.a_data, &pos);
- flush_icache_range((unsigned long) N_TXTADDR(ex),
- (unsigned long) N_TXTADDR(ex) +
- ex.a_text+ex.a_data);
+ flush_icache_user_range((void *)N_TXTADDR(ex),
+ ex.a_text + ex.a_data);
goto beyond_if;
}
@@ -503,8 +503,8 @@
file->f_op->read(file, (char __user *)start_addr,
ex.a_text + ex.a_data, &pos);
- flush_icache_range((unsigned long) start_addr,
- (unsigned long) start_addr + ex.a_text + ex.a_data);
+ flush_icache_user_range((void *)start_addr,
+ ex.a_text + ex.a_data);
retval = 0;
goto out;
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/fs/binfmt_elf.c linux-2.6.12/fs/binfmt_elf.c
--- linux-2.6.12-i386/fs/binfmt_elf.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/fs/binfmt_elf.c 2005-06-19 16:35:04.000000000 +0200
@@ -471,8 +471,7 @@
goto out;
if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0)
goto out;
- flush_icache_range((unsigned long)addr,
- (unsigned long)addr + text_data);
+ flush_icache_user_range(addr, text_data);
down_write(&current->mm->mmap_sem);
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/fs/fat/inode.c linux-2.6.12/fs/fat/inode.c
--- linux-2.6.12-i386/fs/fat/inode.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/fs/fat/inode.c 2005-06-19 16:35:11.000000000 +0200
@@ -11,12 +11,14 @@
*/
#include <linux/module.h>
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/seq_file.h>
#include <linux/msdos_fs.h>
+#include <linux/major.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/mount.h>
@@ -751,7 +753,7 @@
Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid,
Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_nocase,
Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable,
- Opt_dots, Opt_nodots,
+ Opt_dots, Opt_nodots, Opt_atari_no, Opt_atari_yes,
Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
@@ -776,6 +778,9 @@
{Opt_showexec, "showexec"},
{Opt_debug, "debug"},
{Opt_immutable, "sys_immutable"},
+ {Opt_atari_yes, "atari=yes"},
+ {Opt_atari_yes, "atari"},
+ {Opt_atari_no, "atari=no"},
{Opt_obsolate, "conv=binary"},
{Opt_obsolate, "conv=text"},
{Opt_obsolate, "conv=auto"},
@@ -850,6 +855,13 @@
opts->utf8 = opts->unicode_xlate = 0;
opts->numtail = 1;
opts->nocase = 0;
+ opts->atari = 0;
+
+#ifdef CONFIG_ATARI
+ if(MACH_IS_ATARI)
+ /* make Atari GEMDOS format the default if machine is an Atari */
+ opts->atari = 1;
+#endif
*debug = 0;
if (!options)
@@ -898,6 +910,12 @@
case Opt_immutable:
opts->sys_immutable = 1;
break;
+ case Opt_atari_yes:
+ opts->atari = 1;
+ break;
+ case Opt_atari_no:
+ opts->atari = 0;
+ break;
case Opt_uid:
if (match_int(&args[0], &option))
return 0;
@@ -1230,8 +1248,31 @@
total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
- if (sbi->fat_bits != 32)
- sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
+ if (!sbi->options.atari) {
+ if (sbi->fat_bits != 32)
+ sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
+ } else {
+ int sectors;
+ /* Atari GEMDOS partitions always have 16-bit fat */
+ if (sbi->fat_bits != 32)
+ sbi->fat_bits = 16;
+ /* If more clusters than fat entries in 16-bit fat, we assume
+ * it's a real MSDOS partition with 12-bit fat.
+ */
+ if (sbi->fat_bits != 32 && total_clusters+2 > sbi->
+ fat_length*SECTOR_SIZE*8/sbi->fat_bits)
+ sbi->fat_bits = 12;
+ /* if it's a floppy disk --> 12bit fat */
+ if (sbi->fat_bits != 32 && MAJOR(sb->s_dev) == FLOPPY_MAJOR)
+ sbi->fat_bits = 12;
+ /* if it's a ramdisk or loopback device and has one of the usual
+ * floppy sizes -> 12bit FAT */
+ sectors = total_sectors + sbi->data_start;
+ if (sbi->fat_bits != 32 && (MAJOR(sb->s_dev) == RAMDISK_MAJOR ||
+ MAJOR(sb->s_dev) == LOOP_MAJOR) &&
+ (sectors == 720 || sectors == 1440 || sectors == 2880))
+ sbi->fat_bits = 12;
+ }
/* check that FAT table does not overflow */
fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/asm-m68k/cacheflush.h linux-2.6.12/include/asm-m68k/cacheflush.h
--- linux-2.6.12-i386/include/asm-m68k/cacheflush.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/asm-m68k/cacheflush.h 2005-06-19 16:35:42.000000000 +0200
@@ -130,20 +130,26 @@
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
#define flush_icache_page(vma, page) __flush_page_to_ram(page_address(page))
-#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
- do { \
- flush_cache_page(vma, vaddr, page_to_pfn(page));\
- memcpy(dst, src, len); \
- } while (0)
-
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
- do { \
- flush_cache_page(vma, vaddr, page_to_pfn(page));\
- memcpy(dst, src, len); \
- } while (0)
+extern void flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
+ unsigned long addr, int len);
extern void flush_icache_range(unsigned long address, unsigned long endaddr);
+extern void flush_icache_user_range(void *address, unsigned long size);
+
+static inline void copy_to_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr,
+ void *dst, void *src, int len)
+{
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
+ memcpy(dst, src, len);
+ flush_icache_user_page(vma, page, vaddr, len);
+}
+static inline void copy_from_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr,
+ void *dst, void *src, int len)
+{
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
+ memcpy(dst, src, len);
+}
#endif /* _M68K_CACHEFLUSH_H */
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/asm-m68k/io.h linux-2.6.12/include/asm-m68k/io.h
--- linux-2.6.12-i386/include/asm-m68k/io.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/asm-m68k/io.h 2005-06-19 16:35:42.000000000 +0200
@@ -324,8 +324,6 @@
#define writel(val,addr) out_le32((addr),(val))
#endif
-#define mmiowb()
-
static inline void *ioremap(unsigned long physaddr, unsigned long size)
{
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/asm-m68k/processor.h linux-2.6.12/include/asm-m68k/processor.h
--- linux-2.6.12-i386/include/asm-m68k/processor.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/asm-m68k/processor.h 2005-05-30 16:33:26.000000000 +0200
@@ -14,6 +14,7 @@
#define current_text_addr() ({ __label__ _l; _l: &&_l;})
#include <linux/config.h>
+#include <linux/thread_info.h>
#include <asm/segment.h>
#include <asm/fpu.h>
#include <asm/ptrace.h>
@@ -55,17 +56,6 @@
#endif
#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
-struct task_work {
- unsigned char sigpending;
- unsigned char notify_resume; /* request for notification on
- userspace execution resumption */
- char need_resched;
- unsigned char delayed_trace; /* single step a syscall */
- unsigned char syscall_trace; /* count of syscall interceptors */
- unsigned char memdie; /* task was selected to be killed */
- unsigned char pad[2];
-};
-
struct thread_struct {
unsigned long ksp; /* kernel stack pointer */
unsigned long usp; /* user stack pointer */
@@ -78,7 +68,7 @@
unsigned long fp[8*3];
unsigned long fpcntl[3]; /* fp control regs */
unsigned char fpstate[FPSTATESIZE]; /* floating point state */
- struct task_work work;
+ struct thread_info info;
};
#define INIT_THREAD { \
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/asm-m68k/serial.h linux-2.6.12/include/asm-m68k/serial.h
--- linux-2.6.12-i386/include/asm-m68k/serial.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/asm-m68k/serial.h 2004-07-12 16:39:26.000000000 +0200
@@ -74,6 +74,8 @@
#define EXTRA_SERIAL_PORT_DEFNS
#endif
+#ifdef CONFIG_ISA
#define SERIAL_PORT_DFNS \
STD_SERIAL_PORT_DEFNS \
EXTRA_SERIAL_PORT_DEFNS
+#endif
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/asm-m68k/thread_info.h linux-2.6.12/include/asm-m68k/thread_info.h
--- linux-2.6.12-i386/include/asm-m68k/thread_info.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/asm-m68k/thread_info.h 2005-05-31 16:33:46.000000000 +0200
@@ -2,17 +2,15 @@
#define _ASM_M68K_THREAD_INFO_H
#include <asm/types.h>
-#include <asm/processor.h>
#include <asm/page.h>
struct thread_info {
struct task_struct *task; /* main task structure */
+ unsigned long flags;
struct exec_domain *exec_domain; /* execution domain */
__s32 preempt_count; /* 0 => preemptable, <0 => BUG */
__u32 cpu; /* should always be 0 on m68k */
struct restart_block restart_block;
-
- __u8 supervisor_stack[0];
};
#define PREEMPT_ACTIVE 0x4000000
@@ -28,91 +26,34 @@
/* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */
#if PAGE_SHIFT == 13 /* 8k machines */
-#define alloc_thread_info(tsk) ((struct thread_info *)__get_free_pages(GFP_KERNEL,0))
-#define free_thread_info(ti) free_pages((unsigned long)(ti),0)
+#define alloc_thread_stack(tsk) ((void *)__get_free_pages(GFP_KERNEL,0))
+#define free_thread_stack(ti) free_pages((unsigned long)(ti),0)
#else /* otherwise assume 4k pages */
-#define alloc_thread_info(tsk) ((struct thread_info *)__get_free_pages(GFP_KERNEL,1))
-#define free_thread_info(ti) free_pages((unsigned long)(ti),1)
+#define alloc_thread_stack(tsk) ((void *)__get_free_pages(GFP_KERNEL,1))
+#define free_thread_stack(ti) free_pages((unsigned long)(ti),1)
#endif /* PAGE_SHIFT == 13 */
//#define init_thread_info (init_task.thread.info)
#define init_stack (init_thread_union.stack)
-#define current_thread_info() (current->thread_info)
+#define task_thread_info(tsk) (&(tsk)->thread.info)
+#define current_thread_info() task_thread_info(current)
+#define setup_thread_stack(p, org) ({ \
+ *(struct task_struct **)(p)->stack = (p); \
+ task_thread_info(p)->task = (p); \
+})
#define __HAVE_THREAD_FUNCTIONS
-#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
-#define TIF_DELAYED_TRACE 1 /* single step a syscall */
-#define TIF_NOTIFY_RESUME 2 /* resumption notification requested */
-#define TIF_SIGPENDING 3 /* signal pending */
-#define TIF_NEED_RESCHED 4 /* rescheduling necessary */
-#define TIF_MEMDIE 5
-
-extern int thread_flag_fixme(void);
-
-/*
- * flag set/clear/test wrappers
- * - pass TIF_xxxx constants to these functions
+/* entry.S relies on these definitions!
+ * bits 0-7 are tested at every exception exit
+ * bits 8-15 are also tested at syscall exit
*/
-
-#define __set_tsk_thread_flag(tsk, flag, val) ({ \
- switch (flag) { \
- case TIF_SIGPENDING: \
- tsk->thread.work.sigpending = val; \
- break; \
- case TIF_NEED_RESCHED: \
- tsk->thread.work.need_resched = val; \
- break; \
- case TIF_SYSCALL_TRACE: \
- tsk->thread.work.syscall_trace = val; \
- break; \
- case TIF_MEMDIE: \
- tsk->thread.work.memdie = val; \
- break; \
- default: \
- thread_flag_fixme(); \
- } \
-})
-
-#define __get_tsk_thread_flag(tsk, flag) ({ \
- int ___res; \
- switch (flag) { \
- case TIF_SIGPENDING: \
- ___res = tsk->thread.work.sigpending; \
- break; \
- case TIF_NEED_RESCHED: \
- ___res = tsk->thread.work.need_resched; \
- break; \
- case TIF_SYSCALL_TRACE: \
- ___res = tsk->thread.work.syscall_trace;\
- break; \
- case TIF_MEMDIE: \
- ___res = tsk->thread.work.memdie;\
- break; \
- default: \
- ___res = thread_flag_fixme(); \
- } \
- ___res; \
-})
-
-#define __get_set_tsk_thread_flag(tsk, flag, val) ({ \
- int __res = __get_tsk_thread_flag(tsk, flag); \
- __set_tsk_thread_flag(tsk, flag, val); \
- __res; \
-})
-
-#define set_tsk_thread_flag(tsk, flag) __set_tsk_thread_flag(tsk, flag, ~0)
-#define clear_tsk_thread_flag(tsk, flag) __set_tsk_thread_flag(tsk, flag, 0)
-#define test_and_set_tsk_thread_flag(tsk, flag) __get_set_tsk_thread_flag(tsk, flag, ~0)
-#define test_tsk_thread_flag(tsk, flag) __get_tsk_thread_flag(tsk, flag)
-
-#define set_thread_flag(flag) set_tsk_thread_flag(current, flag)
-#define clear_thread_flag(flag) clear_tsk_thread_flag(current, flag)
-#define test_thread_flag(flag) test_tsk_thread_flag(current, flag)
-
-#define set_need_resched() set_thread_flag(TIF_NEED_RESCHED)
-#define clear_need_resched() clear_thread_flag(TIF_NEED_RESCHED)
+#define TIF_SIGPENDING 6 /* signal pending */
+#define TIF_NEED_RESCHED 7 /* rescheduling necessary */
+#define TIF_DELAYED_TRACE 14 /* single step a syscall */
+#define TIF_SYSCALL_TRACE 15 /* syscall trace active */
+#define TIF_MEMDIE 16
#endif /* _ASM_M68K_THREAD_INFO_H */
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/linux/adb.h linux-2.6.12/include/linux/adb.h
--- linux-2.6.12-i386/include/linux/adb.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/linux/adb.h 2003-03-25 20:25:16.000000000 +0100
@@ -76,6 +76,7 @@
#define ADBREQ_REPLY 1 /* expect reply */
#define ADBREQ_SYNC 2 /* poll until done */
#define ADBREQ_NOSEND 4 /* build the request, but don't send it */
+#define ADBREQ_RAW 8 /* send raw packet (don't prepend ADB_PACKET) */
/* Messages sent thru the client_list notifier. You should NOT stop
the operation, at least not with this version */
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/linux/bootmem.h linux-2.6.12/include/linux/bootmem.h
--- linux-2.6.12-i386/include/linux/bootmem.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/linux/bootmem.h 2005-04-25 23:13:10.000000000 +0200
@@ -45,11 +45,11 @@
#define alloc_bootmem(x) \
__alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
#define alloc_bootmem_low(x) \
- __alloc_bootmem((x), SMP_CACHE_BYTES, 0)
+ __alloc_bootmem((x), SMP_CACHE_BYTES, __pa(PAGE_OFFSET))
#define alloc_bootmem_pages(x) \
__alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
#define alloc_bootmem_low_pages(x) \
- __alloc_bootmem((x), PAGE_SIZE, 0)
+ __alloc_bootmem((x), PAGE_SIZE, __pa(PAGE_OFFSET))
#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
extern unsigned long __init free_all_bootmem (void);
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/linux/ide.h linux-2.6.12/include/linux/ide.h
--- linux-2.6.12-i386/include/linux/ide.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/linux/ide.h 2005-06-19 16:36:06.000000000 +0200
@@ -592,7 +592,7 @@
* sense_key : Sense key of the last failed packet command
*/
typedef union {
- unsigned all :8;
+ u8 all;
struct {
#if defined(__LITTLE_ENDIAN_BITFIELD)
unsigned ili :1;
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/linux/init_task.h linux-2.6.12/include/linux/init_task.h
--- linux-2.6.12-i386/include/linux/init_task.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/linux/init_task.h 2005-06-19 16:36:06.000000000 +0200
@@ -70,7 +70,7 @@
#define INIT_TASK(tsk) \
{ \
.state = 0, \
- .thread_info = &init_thread_info, \
+ .stack = &init_stack, \
.usage = ATOMIC_INIT(2), \
.flags = 0, \
.lock_depth = -1, \
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/linux/interrupt.h linux-2.6.12/include/linux/interrupt.h
--- linux-2.6.12-i386/include/linux/interrupt.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/linux/interrupt.h 2005-05-30 16:33:46.000000000 +0200
@@ -9,6 +9,7 @@
#include <linux/preempt.h>
#include <linux/cpumask.h>
#include <linux/hardirq.h>
+#include <linux/sched.h>
#include <asm/atomic.h>
#include <asm/ptrace.h>
#include <asm/system.h>
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/linux/sched.h linux-2.6.12/include/linux/sched.h
--- linux-2.6.12-i386/include/linux/sched.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/linux/sched.h 2005-06-19 16:36:08.000000000 +0200
@@ -573,7 +573,8 @@
struct task_struct {
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
- struct thread_info *thread_info;
+ //struct thread_info *thread_info;
+ void *stack;
atomic_t usage;
unsigned long flags; /* per process flags, defined below */
unsigned long ptrace;
@@ -1105,32 +1106,50 @@
spin_unlock(&p->alloc_lock);
}
+#ifndef __HAVE_THREAD_FUNCTIONS
+
+#define task_thread_info(task) ((struct thread_info *)(task)->stack)
+
+static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
+{
+ *task_thread_info(p) = *task_thread_info(org);
+ task_thread_info(p)->task = p;
+}
+
+static inline unsigned long *end_of_stack(struct task_struct *p)
+{
+ return (unsigned long *)(task_thread_info(p)(p) + 1);
+}
+
+#endif
+
/* 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);
+ set_ti_thread_flag(task_thread_info(tsk), flag);
}
static inline void clear_tsk_thread_flag(struct task_struct *tsk, int flag)
{
- clear_ti_thread_flag(tsk->thread_info,flag);
+ clear_ti_thread_flag(task_thread_info(tsk), 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);
+ return test_and_set_ti_thread_flag(task_thread_info(tsk), 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);
+ return test_and_clear_ti_thread_flag(task_thread_info(tsk), flag);
}
static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag)
{
- return test_ti_thread_flag(tsk->thread_info,flag);
+ return test_ti_thread_flag(task_thread_info(tsk), flag);
}
static inline void set_tsk_need_resched(struct task_struct *tsk)
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/linux/smp_lock.h linux-2.6.12/include/linux/smp_lock.h
--- linux-2.6.12-i386/include/linux/smp_lock.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/linux/smp_lock.h 2005-04-25 23:13:18.000000000 +0200
@@ -2,7 +2,6 @@
#define __LINUX_SMPLOCK_H
#include <linux/config.h>
-#include <linux/sched.h>
#include <linux/spinlock.h>
#ifdef CONFIG_LOCK_KERNEL
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/include/linux/thread_info.h linux-2.6.12/include/linux/thread_info.h
--- linux-2.6.12-i386/include/linux/thread_info.h 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/include/linux/thread_info.h 2005-05-30 16:33:47.000000000 +0200
@@ -27,31 +27,6 @@
* - 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);
@@ -77,16 +52,20 @@
return test_bit(flag,&ti->flags);
}
-static inline void set_need_resched(void)
-{
- set_thread_flag(TIF_NEED_RESCHED);
-}
+#define set_thread_flag(flag) \
+ set_ti_thread_flag(current_thread_info(), flag)
+#define clear_thread_flag(flag) \
+ clear_ti_thread_flag(current_thread_info(), flag)
+#define test_and_set_thread_flag(flag) \
+ test_and_set_ti_thread_flag(current_thread_info(), flag)
+#define test_and_clear_thread_flag(flag) \
+ test_and_clear_ti_thread_flag(current_thread_info(), flag)
+#define test_thread_flag(flag) \
+ test_ti_thread_flag(current_thread_info(), flag)
-static inline void clear_need_resched(void)
-{
- clear_thread_flag(TIF_NEED_RESCHED);
-}
+#define set_need_resched() set_thread_flag(TIF_NEED_RESCHED)
+#define clear_need_resched() clear_thread_flag(TIF_NEED_RESCHED)
-#endif
+#endif /* __KERNEL__ */
#endif /* _LINUX_THREAD_INFO_H */
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/kernel/exit.c linux-2.6.12/kernel/exit.c
--- linux-2.6.12-i386/kernel/exit.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/kernel/exit.c 2005-06-19 16:36:18.000000000 +0200
@@ -826,7 +826,7 @@
if (group_dead && tsk->signal->leader)
disassociate_ctty(1);
- module_put(tsk->thread_info->exec_domain->module);
+ module_put(task_thread_info(tsk)->exec_domain->module);
if (tsk->binfmt)
module_put(tsk->binfmt->module);
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/kernel/fork.c linux-2.6.12/kernel/fork.c
--- linux-2.6.12-i386/kernel/fork.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/kernel/fork.c 2005-06-19 16:36:18.000000000 +0200
@@ -100,7 +100,7 @@
void free_task(struct task_struct *tsk)
{
- free_thread_info(tsk->thread_info);
+ free_thread_stack(tsk->stack);
free_task_struct(tsk);
}
EXPORT_SYMBOL(free_task);
@@ -155,7 +155,7 @@
static struct task_struct *dup_task_struct(struct task_struct *orig)
{
struct task_struct *tsk;
- struct thread_info *ti;
+ void *stack;
prepare_to_copy(orig);
@@ -163,16 +163,16 @@
if (!tsk)
return NULL;
- ti = alloc_thread_info(tsk);
- if (!ti) {
+ stack = alloc_thread_stack(tsk);
+ if (!stack) {
free_task_struct(tsk);
return NULL;
}
- *ti = *orig->thread_info;
*tsk = *orig;
- tsk->thread_info = ti;
- ti->task = tsk;
+ tsk->stack = stack;
+ *(struct task_struct **)tsk->stack = tsk;
+ setup_thread_stack(tsk, orig);
/* One for us, one for whoever does the "release_task()" (usually parent) */
atomic_set(&tsk->usage,2);
@@ -893,7 +893,7 @@
if (nr_threads >= max_threads)
goto bad_fork_cleanup_count;
- if (!try_module_get(p->thread_info->exec_domain->module))
+ if (!try_module_get(task_thread_info(p)->exec_domain->module))
goto bad_fork_cleanup_count;
if (p->binfmt && !try_module_get(p->binfmt->module))
@@ -1138,7 +1138,7 @@
if (p->binfmt)
module_put(p->binfmt->module);
bad_fork_cleanup_put_domain:
- module_put(p->thread_info->exec_domain->module);
+ module_put(task_thread_info(p)->exec_domain->module);
bad_fork_cleanup_count:
put_group_info(p->group_info);
atomic_dec(&p->user->processes);
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/kernel/sched.c linux-2.6.12/kernel/sched.c
--- linux-2.6.12-i386/kernel/sched.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/kernel/sched.c 2005-06-19 16:36:19.000000000 +0200
@@ -3962,10 +3962,10 @@
#endif
#ifdef CONFIG_DEBUG_STACK_USAGE
{
- unsigned long * n = (unsigned long *) (p->thread_info+1);
+ unsigned long * n = end_of_stack(p);
while (!*n)
n++;
- free = (unsigned long) n - (unsigned long)(p->thread_info+1);
+ free = (unsigned long) n - (unsigned long) end_of_stack(p);
}
#endif
printk("%5lu %5d %6d ", free, p->pid, p->parent->pid);
@@ -4035,9 +4035,9 @@
/* Set the preempt count _outside_ the spinlocks! */
#if defined(CONFIG_PREEMPT) && !defined(CONFIG_PREEMPT_BKL)
- idle->thread_info->preempt_count = (idle->lock_depth >= 0);
+ task_thread_info(idle)->preempt_count = (idle->lock_depth >= 0);
#else
- idle->thread_info->preempt_count = 0;
+ task_thread_info(idle)->preempt_count = 0;
#endif
}
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/mm/bootmem.c linux-2.6.12/mm/bootmem.c
--- linux-2.6.12-i386/mm/bootmem.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/mm/bootmem.c 2005-04-25 23:13:33.000000000 +0200
@@ -266,7 +266,6 @@
count = 0;
/* first extant page of the node */
- page = virt_to_page(phys_to_virt(bdata->node_boot_start));
idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
map = bdata->node_bootmem_map;
/* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */
@@ -278,6 +277,8 @@
if (gofast && v == ~0UL) {
int j, order;
+ page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) +
+ bdata->node_boot_start));
count += BITS_PER_LONG;
__ClearPageReserved(page);
order = ffs(BITS_PER_LONG) - 1;
@@ -289,21 +290,20 @@
}
__free_pages(page, order);
i += BITS_PER_LONG;
- page += BITS_PER_LONG;
} else if (v) {
unsigned long m;
- for (m = 1; m && i < idx; m<<=1, page++, i++) {
+ for (m = 1; m && i < idx; m<<=1, i++) {
if (v & m) {
+ page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) +
+ bdata->node_boot_start));
count++;
__ClearPageReserved(page);
set_page_refs(page, 0);
__free_page(page);
}
}
- } else {
+ } else
i+=BITS_PER_LONG;
- page += BITS_PER_LONG;
- }
}
total += count;
diff -urN --exclude-from=/usr/src/exclude-file linux-2.6.12-i386/sound/oss/dmasound/dmasound_paula.c linux-2.6.12/sound/oss/dmasound/dmasound_paula.c
--- linux-2.6.12-i386/sound/oss/dmasound/dmasound_paula.c 2005-06-17 21:48:29.000000000 +0200
+++ linux-2.6.12/sound/oss/dmasound/dmasound_paula.c 2005-05-30 16:34:14.000000000 +0200
@@ -244,6 +244,7 @@
u_char frame[], ssize_t *frameUsed, \
ssize_t frameLeft) \
{ \
+ const u_short *ptr = (const u_short *)userPtr; \
ssize_t count, used; \
u_short data; \
\
@@ -253,7 +254,7 @@
count = min_t(size_t, userCount, frameLeft)>>1 & ~1; \
used = count*2; \
while (count > 0) { \
- if (get_user(data, ((u_short *)userPtr)++)) \
+ if (get_user(data, ptr++)) \
return -EFAULT; \
data = convsample(data); \
*high++ = data>>8; \
@@ -268,12 +269,12 @@
count = min_t(size_t, userCount, frameLeft)>>2 & ~1; \
used = count*4; \
while (count > 0) { \
- if (get_user(data, ((u_short *)userPtr)++)) \
+ if (get_user(data, ptr++)) \
return -EFAULT; \
data = convsample(data); \
*lefth++ = data>>8; \
*leftl++ = (data>>2) & 0x3f; \
- if (get_user(data, ((u_short *)userPtr)++)) \
+ if (get_user(data, ptr++)) \
return -EFAULT; \
data = convsample(data); \
*righth++ = data>>8; \