diff -urN --exclude-from=/usr/src/exclude-file linux-i386/Makefile linux-m68k/Makefile --- linux-i386/Makefile 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/Makefile 2005-10-29 10:40:15.000000000 +0200 @@ -189,7 +189,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-i386/arch/m68k/Kconfig linux-m68k/arch/m68k/Kconfig --- linux-i386/arch/m68k/Kconfig 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/Kconfig 2005-10-29 10:40:42.000000000 +0200 @@ -618,7 +618,7 @@ config SERIAL167 bool "CD2401 support for MVME166/7 serial ports" - depends on MVME16x && BROKEN + depends on MVME16x help This is the driver for the serial ports on the Motorola MVME166, 167, and 172 boards. Everyone using one of these boards should say diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/amiga/amiints.c linux-m68k/arch/m68k/amiga/amiints.c --- linux-i386/arch/m68k/amiga/amiints.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/amiga/amiints.c 2005-11-01 16:31:28.000000000 +0100 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/amiga/config.c linux-m68k/arch/m68k/amiga/config.c --- linux-i386/arch/m68k/amiga/config.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/amiga/config.c 2005-10-12 16:31:23.000000000 +0200 @@ -431,9 +431,6 @@ mach_floppy_setup = amiga_floppy_setup; #endif mach_reset = amiga_reset; -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) mach_beep = amiga_mksound; #endif diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/apollo/config.c linux-m68k/arch/m68k/apollo/config.c --- linux-i386/arch/m68k/apollo/config.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/apollo/config.c 2005-10-12 16:31:23.000000000 +0200 @@ -176,9 +176,6 @@ mach_set_clock_mmss = dn_dummy_set_clock_mmss; /* */ mach_process_int = dn_process_int; mach_reset = dn_dummy_reset; /* */ -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif #ifdef CONFIG_HEARTBEAT mach_heartbeat = dn_heartbeat; #endif diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/atari/config.c linux-m68k/arch/m68k/atari/config.c --- linux-i386/arch/m68k/atari/config.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/atari/config.c 2005-10-12 16:31:23.000000000 +0200 @@ -247,9 +247,6 @@ #ifdef CONFIG_ATARI_FLOPPY mach_floppy_setup = atari_floppy_setup; #endif -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif mach_max_dma_address = 0xffffff; #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) mach_beep = atari_mksound; diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/fpsp040/skeleton.S linux-m68k/arch/m68k/fpsp040/skeleton.S --- linux-i386/arch/m68k/fpsp040/skeleton.S 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/fpsp040/skeleton.S 2005-10-29 10:40:44.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-i386/arch/m68k/hp300/config.c linux-m68k/arch/m68k/hp300/config.c --- linux-i386/arch/m68k/hp300/config.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/hp300/config.c 2005-10-12 16:31:23.000000000 +0200 @@ -261,9 +261,6 @@ #ifdef CONFIG_HEARTBEAT mach_heartbeat = hp300_pulse; #endif -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif mach_max_dma_address = 0xffffffff; if (hp300_model >= HP_330 && hp300_model <= HP_433S && hp300_model != HP_350) { diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/ifpsp060/iskeleton.S linux-m68k/arch/m68k/ifpsp060/iskeleton.S --- linux-i386/arch/m68k/ifpsp060/iskeleton.S 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/ifpsp060/iskeleton.S 2005-10-29 10:40:44.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-i386/arch/m68k/kernel/asm-offsets.c linux-m68k/arch/m68k/kernel/asm-offsets.c --- linux-i386/arch/m68k/kernel/asm-offsets.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/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-i386/arch/m68k/kernel/bios32.c linux-m68k/arch/m68k/kernel/bios32.c --- linux-i386/arch/m68k/kernel/bios32.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/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-i386/arch/m68k/kernel/entry.S linux-m68k/arch/m68k/kernel/entry.S --- linux-i386/arch/m68k/kernel/entry.S 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/kernel/entry.S 2005-10-29 10:40:44.000000000 +0200 @@ -44,9 +44,7 @@ #include -.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-i386/arch/m68k/kernel/process.c linux-m68k/arch/m68k/kernel/process.c --- linux-i386/arch/m68k/kernel/process.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/kernel/process.c 2005-08-30 16:31:36.000000000 +0200 @@ -239,7 +239,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; @@ -384,7 +384,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-i386/arch/m68k/kernel/ptrace.c linux-m68k/arch/m68k/kernel/ptrace.c --- linux-i386/arch/m68k/kernel/ptrace.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/kernel/ptrace.c 2005-06-19 16:32:04.000000000 +0200 @@ -109,7 +109,7 @@ { unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); put_reg(child, PT_SR, tmp); - child->thread.work.delayed_trace = 0; + clear_tsk_thread_flag(child, TIF_DELAYED_TRACE); } /* @@ -118,7 +118,7 @@ void ptrace_disable(struct task_struct *child) { singlestep_disable(child); - child->thread.work.syscall_trace = 0; + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); } asmlinkage int sys_ptrace(long request, long pid, long addr, long data) @@ -235,9 +235,9 @@ goto out_eio; if (request == PTRACE_SYSCALL) - child->thread.work.syscall_trace = ~0; + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); else - child->thread.work.syscall_trace = 0; + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->exit_code = data; singlestep_disable(child); wake_up_process(child); @@ -260,10 +260,10 @@ if (!valid_signal(data)) goto out_eio; - child->thread.work.syscall_trace = 0; + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16); put_reg(child, PT_SR, tmp); - child->thread.work.delayed_trace = 1; + set_tsk_thread_flag(child, TIF_DELAYED_TRACE); child->exit_code = data; /* give it a chance to run. */ @@ -329,9 +329,6 @@ 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-i386/arch/m68k/kernel/setup.c linux-m68k/arch/m68k/kernel/setup.c --- linux-i386/arch/m68k/kernel/setup.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/kernel/setup.c 2005-10-12 16:31:24.000000000 +0200 @@ -280,6 +280,10 @@ } } +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + switch (m68k_machtype) { #ifdef CONFIG_AMIGA case MACH_AMIGA: diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mac/config.c linux-m68k/arch/m68k/mac/config.c --- linux-i386/arch/m68k/mac/config.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/mac/config.c 2005-10-12 16:31:24.000000000 +0200 @@ -212,9 +212,6 @@ mach_reset = mac_reset; mach_halt = mac_poweroff; mach_power_off = mac_poweroff; -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif mach_max_dma_address = 0xffffffff; #if 0 mach_debug_init = mac_debug_init; diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/q40/config.c linux-m68k/arch/m68k/q40/config.c --- linux-i386/arch/m68k/q40/config.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/q40/config.c 2005-10-12 16:31:25.000000000 +0200 @@ -194,9 +194,6 @@ mach_heartbeat = q40_heartbeat; #endif mach_halt = q40_halt; -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif /* disable a few things that SMSQ might have left enabled */ q40_disable_irqs(); diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/sun3/config.c linux-m68k/arch/m68k/sun3/config.c --- linux-i386/arch/m68k/sun3/config.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/sun3/config.c 2005-10-12 16:31:25.000000000 +0200 @@ -160,9 +160,6 @@ mach_hwclk = sun3_hwclk; mach_halt = sun3_halt; mach_get_hardware_list = sun3_get_hardware_list; -#if defined(CONFIG_DUMMY_CONSOLE) - conswitchp = &dummy_con; -#endif memory_start = ((((int)&_end) + 0x2000) & ~0x1fff); // PROM seems to want the last couple of physical pages. --m diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/sun3x/config.c linux-m68k/arch/m68k/sun3x/config.c --- linux-i386/arch/m68k/sun3x/config.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/arch/m68k/sun3x/config.c 2005-10-12 16:31:25.000000000 +0200 @@ -71,10 +71,6 @@ mach_get_model = sun3_get_model; mach_get_hardware_list = sun3x_get_hardware_list; -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif - sun3_intreg = (unsigned char *)SUN3X_INTREG; /* only the serial console is known to work anyway... */ diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/block/swim3.c linux-m68k/drivers/block/swim3.c --- linux-i386/drivers/block/swim3.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/block/swim3.c 2005-10-29 10:42:06.000000000 +0200 @@ -304,7 +304,7 @@ #endif /* CONFIG_PMAC_MEDIABAY */ start_request(&floppy_states[i]); } - sti(); + local_irq_enable(); } static void start_request(struct floppy_state *fs) @@ -370,7 +370,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; @@ -378,7 +378,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) @@ -790,14 +790,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); @@ -805,7 +804,7 @@ --fs->wanted; } fs->state = state; - restore_flags(flags); + local_irq_restore(flags); return 0; } @@ -813,11 +812,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-i386/drivers/char/16c552.h linux-m68k/drivers/char/16c552.h --- linux-i386/drivers/char/16c552.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-m68k/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 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 + */ +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-i386/drivers/char/ioext.h linux-m68k/drivers/char/ioext.h --- linux-i386/drivers/char/ioext.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-m68k/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 +#include + +#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-i386/drivers/char/mc68681.h linux-m68k/drivers/char/mc68681.h --- linux-i386/drivers/char/mc68681.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-m68k/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-i386/drivers/char/plip_ioext.c linux-m68k/drivers/char/plip_ioext.c --- linux-i386/drivers/char/plip_ioext.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-m68k/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, + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +/*#include */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#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 " +#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-i386/drivers/char/serial167.c linux-m68k/drivers/char/serial167.c --- linux-i386/drivers/char/serial167.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/char/serial167.c 2005-10-12 16:32:10.000000000 +0200 @@ -1450,7 +1450,6 @@ volatile unsigned char *base_addr = (u_char *)BASE_ADDR; unsigned long flags; unsigned char status; - unsigned int result; channel = info->line; @@ -1474,7 +1473,6 @@ int channel; volatile unsigned char *base_addr = (u_char *)BASE_ADDR; unsigned long flags; - unsigned int arg; channel = info->line; diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/ide/ide-iops.c linux-m68k/drivers/ide/ide-iops.c --- linux-i386/drivers/ide/ide-iops.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/ide/ide-iops.c 2005-10-29 10:42:13.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-i386/drivers/ide/legacy/gayle.c linux-m68k/drivers/ide/legacy/gayle.c --- linux-i386/drivers/ide/legacy/gayle.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/ide/legacy/gayle.c 2005-09-02 16:32:11.000000000 +0200 @@ -161,6 +161,7 @@ base = (unsigned long)ZTWO_VADDR(phys_base); ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; + memset(&hw, 0, sizeof(hw)); ide_setup_ports(&hw, base, gayle_offsets, ctrlport, irqport, ack_intr, // &gayle_iops, diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/keyboard/Kconfig linux-m68k/drivers/input/keyboard/Kconfig --- linux-i386/drivers/input/keyboard/Kconfig 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/input/keyboard/Kconfig 2005-10-29 10:42:17.000000000 +0200 @@ -165,7 +165,7 @@ config KEYBOARD_HIL_OLD tristate "HP HIL keyboard support (simple driver)" - depends on GSC + depends on GSC || HP300 default y help The "Human Interface Loop" is a older, 8-channel USB-like @@ -182,7 +182,7 @@ config KEYBOARD_HIL tristate "HP HIL keyboard support" - depends on GSC + depends on GSC || HP300 default y select HP_SDC select HIL_MLC diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/misc/Kconfig linux-m68k/drivers/input/misc/Kconfig --- linux-i386/drivers/input/misc/Kconfig 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/input/misc/Kconfig 2005-08-30 16:33:05.000000000 +0200 @@ -51,7 +51,7 @@ config HP_SDC_RTC tristate "HP SDC Real Time Clock" - depends on GSC + depends on GSC || HP300 select HP_SDC help Say Y here if you want to support the built-in real time clock diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/mouse/Kconfig linux-m68k/drivers/input/mouse/Kconfig --- linux-i386/drivers/input/mouse/Kconfig 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/input/mouse/Kconfig 2005-08-30 16:33:05.000000000 +0200 @@ -129,7 +129,7 @@ config MOUSE_HIL tristate "HIL pointers (mice etc)." - depends on GSC + depends on GSC || HP300 select HP_SDC select HIL_MLC help diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/serio/Kconfig linux-m68k/drivers/input/serio/Kconfig --- linux-i386/drivers/input/serio/Kconfig 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/input/serio/Kconfig 2005-08-30 16:33:05.000000000 +0200 @@ -112,7 +112,7 @@ config HP_SDC tristate "HP System Device Controller i8042 Support" - depends on GSC && SERIO + depends on (GSC || HP300) && SERIO default y ---help--- This option enables supports for the the "System Device diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/macintosh/adb.c linux-m68k/drivers/macintosh/adb.c --- linux-i386/drivers/macintosh/adb.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/macintosh/adb.c 2005-08-30 16:33:07.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-i386/drivers/net/7990.c linux-m68k/drivers/net/7990.c --- linux-i386/drivers/net/7990.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/net/7990.c 2005-10-12 16:32:42.000000000 +0200 @@ -500,7 +500,7 @@ int res; /* Install the Interrupt handler. Or we could shunt this out to specific drivers? */ - if (request_irq(lp->irq, lance_interrupt, 0, lp->name, dev)) + if (request_irq(lp->irq, lance_interrupt, SA_SHIRQ, lp->name, dev)) return -EAGAIN; res = lance_reset(dev); diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/Kconfig linux-m68k/drivers/net/Kconfig --- linux-i386/drivers/net/Kconfig 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/net/Kconfig 2005-10-29 10:42:30.000000000 +0200 @@ -296,7 +296,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-i386/drivers/net/hplance.c linux-m68k/drivers/net/hplance.c --- linux-i386/drivers/net/hplance.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/net/hplance.c 2005-10-12 16:32:43.000000000 +0200 @@ -77,6 +77,7 @@ { struct net_device *dev; int err = -ENOMEM; + int i; dev = alloc_etherdev(sizeof(struct hplance_private)); if (!dev) @@ -93,6 +94,15 @@ goto out_release_mem_region; dio_set_drvdata(d, dev); + + printk(KERN_INFO "%s: %s; select code %d, addr %2.2x", dev->name, d->name, d->scode, dev->dev_addr[0]); + + for (i=1; i<6; i++) { + printk(":%2.2x", dev->dev_addr[i]); + } + + printk(", irq %d\n", d->ipl); + return 0; out_release_mem_region: @@ -118,9 +128,7 @@ unsigned long va = (d->resource.start + DIO_VIRADDRBASE); struct hplance_private *lp; int i; - - printk(KERN_INFO "%s: %s; select code %d, addr", dev->name, d->name, d->scode); - + /* reset the board */ out_8(va+DIO_IDOFF, 0xff); udelay(100); /* ariba! ariba! udelay! udelay! */ @@ -143,7 +151,6 @@ */ dev->dev_addr[i] = ((in_8(va + HPLANCE_NVRAMOFF + i*4 + 1) & 0xF) << 4) | (in_8(va + HPLANCE_NVRAMOFF + i*4 + 3) & 0xF); - printk("%c%2.2x", i == 0 ? ' ' : ':', dev->dev_addr[i]); } lp = netdev_priv(dev); @@ -160,7 +167,6 @@ lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS; lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK; lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK; - printk(", irq %d\n", lp->lance.irq); } /* This is disgusting. We have to check the DIO status register for ack every diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/mac89x0.c linux-m68k/drivers/net/mac89x0.c --- linux-i386/drivers/net/mac89x0.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/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-i386/drivers/scsi/53c7xx.c linux-m68k/drivers/scsi/53c7xx.c --- linux-i386/drivers/scsi/53c7xx.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/scsi/53c7xx.c 2005-10-29 10:42:44.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-i386/drivers/scsi/53c7xx.h linux-m68k/drivers/scsi/53c7xx.h --- linux-i386/drivers/scsi/53c7xx.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/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-i386/drivers/scsi/Kconfig linux-m68k/drivers/scsi/Kconfig --- linux-i386/drivers/scsi/Kconfig 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/scsi/Kconfig 2005-10-29 10:42:45.000000000 +0200 @@ -1654,7 +1654,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: @@ -1751,7 +1751,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 @@ -1759,7 +1759,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-i386/drivers/scsi/NCR5380.c linux-m68k/drivers/scsi/NCR5380.c --- linux-i386/drivers/scsi/NCR5380.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/scsi/NCR5380.c 2005-10-29 10:42:45.000000000 +0200 @@ -353,6 +353,7 @@ return -ETIMEDOUT; } +#if NDEBUG static struct { unsigned char value; const char *name; @@ -366,7 +367,6 @@ {PHASE_UNKNOWN, "UNKNOWN"} }; -#if NDEBUG static struct { unsigned char mask; const char *name; diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/amiga7xx.c linux-m68k/drivers/scsi/amiga7xx.c --- linux-i386/drivers/scsi/amiga7xx.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/scsi/amiga7xx.c 2004-10-30 16:35:43.000000000 +0200 @@ -27,8 +27,14 @@ #include "scsi.h" #include #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-i386/drivers/scsi/amiga7xx.h linux-m68k/drivers/scsi/amiga7xx.h --- linux-i386/drivers/scsi/amiga7xx.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/scsi/amiga7xx.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,23 +0,0 @@ -#ifndef AMIGA7XX_H - -#include - -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 - -#endif /* AMIGA7XX_H */ diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/bvme6000.c linux-m68k/drivers/scsi/bvme6000.c --- linux-i386/drivers/scsi/bvme6000.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/scsi/bvme6000.c 2004-10-30 16:35:43.000000000 +0200 @@ -19,10 +19,16 @@ #include "scsi.h" #include #include "53c7xx.h" -#include "bvme6000.h" #include +#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-i386/drivers/scsi/bvme6000.h linux-m68k/drivers/scsi/bvme6000.h --- linux-i386/drivers/scsi/bvme6000.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/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 - -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 - -#endif /* BVME6000_SCSI_H */ diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/mvme16x.c linux-m68k/drivers/scsi/mvme16x.c --- linux-i386/drivers/scsi/mvme16x.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/drivers/scsi/mvme16x.c 2004-10-30 16:35:43.000000000 +0200 @@ -17,10 +17,16 @@ #include "scsi.h" #include #include "53c7xx.h" -#include "mvme16x.h" #include +#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-i386/drivers/scsi/mvme16x.h linux-m68k/drivers/scsi/mvme16x.h --- linux-i386/drivers/scsi/mvme16x.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/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 - -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 - -#endif /* MVME16x_SCSI_H */ diff -urN --exclude-from=/usr/src/exclude-file linux-i386/fs/fat/inode.c linux-m68k/fs/fat/inode.c --- linux-i386/fs/fat/inode.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/fs/fat/inode.c 2005-10-29 10:43:07.000000000 +0200 @@ -11,12 +11,14 @@ */ #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -771,7 +773,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, @@ -796,6 +798,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"}, @@ -870,6 +875,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) @@ -918,6 +930,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; @@ -1250,8 +1268,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-i386/include/asm-m68k/hardirq.h linux-m68k/include/asm-m68k/hardirq.h --- linux-i386/include/asm-m68k/hardirq.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/include/asm-m68k/hardirq.h 2005-11-01 16:33:46.000000000 +0100 @@ -4,6 +4,7 @@ #include #include #include +#include /* entry.S is sensitive to the offsets of these fields */ typedef struct { diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/io.h linux-m68k/include/asm-m68k/io.h --- linux-i386/include/asm-m68k/io.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/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-i386/include/asm-m68k/irq.h linux-m68k/include/asm-m68k/irq.h --- linux-i386/include/asm-m68k/irq.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/include/asm-m68k/irq.h 2005-11-01 16:33:46.000000000 +0100 @@ -2,7 +2,6 @@ #define _M68K_IRQ_H_ #include -#include /* * # of m68k interrupts @@ -77,7 +76,7 @@ struct pt_regs; extern int cpu_request_irq(unsigned int, - irqreturn_t (*)(int, void *, struct pt_regs *), + int (*)(int, void *, struct pt_regs *), unsigned long, const char *, void *); extern void cpu_free_irq(unsigned int, void *); @@ -99,7 +98,7 @@ * interrupt source (if it supports chaining). */ typedef struct irq_node { - irqreturn_t (*handler)(int, void *, struct pt_regs *); + int (*handler)(int, void *, struct pt_regs *); unsigned long flags; void *dev_id; const char *devname; @@ -110,7 +109,7 @@ * This structure has only 4 elements for speed reasons */ typedef struct irq_handler { - irqreturn_t (*handler)(int, void *, struct pt_regs *); + int (*handler)(int, void *, struct pt_regs *); unsigned long flags; void *dev_id; const char *devname; diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/processor.h linux-m68k/include/asm-m68k/processor.h --- linux-i386/include/asm-m68k/processor.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/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 +#include #include #include #include @@ -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-i386/include/asm-m68k/serial.h linux-m68k/include/asm-m68k/serial.h --- linux-i386/include/asm-m68k/serial.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/include/asm-m68k/serial.h 2005-08-30 16:36:03.000000000 +0200 @@ -26,9 +26,11 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif +#ifdef CONFIG_ISA #define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ +#endif diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/thread_info.h linux-m68k/include/asm-m68k/thread_info.h --- linux-i386/include/asm-m68k/thread_info.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/include/asm-m68k/thread_info.h 2005-08-30 16:36:04.000000000 +0200 @@ -2,17 +2,15 @@ #define _ASM_M68K_THREAD_INFO_H #include -#include #include struct thread_info { struct task_struct *task; /* main task structure */ + unsigned long flags; struct exec_domain *exec_domain; /* execution domain */ int 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-i386/include/linux/adb.h linux-m68k/include/linux/adb.h --- linux-i386/include/linux/adb.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/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-i386/include/linux/bootmem.h linux-m68k/include/linux/bootmem.h --- linux-i386/include/linux/bootmem.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/include/linux/bootmem.h 2005-10-29 10:43:54.000000000 +0200 @@ -49,11 +49,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)) #define alloc_bootmem_limit(x, limit) \ __alloc_bootmem_limit((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS), (limit)) diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/file.h linux-m68k/include/linux/file.h --- linux-i386/include/linux/file.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/include/linux/file.h 2005-11-01 16:34:09.000000000 +0100 @@ -5,7 +5,6 @@ #ifndef __LINUX_FILE_H #define __LINUX_FILE_H -#include #include #include #include diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/ide.h linux-m68k/include/linux/ide.h --- linux-i386/include/linux/ide.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/include/linux/ide.h 2005-08-30 16:36:33.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-i386/include/linux/init_task.h linux-m68k/include/linux/init_task.h --- linux-i386/include/linux/init_task.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/include/linux/init_task.h 2005-10-29 10:43:55.000000000 +0200 @@ -80,7 +80,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-i386/include/linux/interrupt.h linux-m68k/include/linux/interrupt.h --- linux-i386/include/linux/interrupt.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/include/linux/interrupt.h 2005-10-29 10:43:55.000000000 +0200 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/sched.h linux-m68k/include/linux/sched.h --- linux-i386/include/linux/sched.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/include/linux/sched.h 2005-10-29 10:43:57.000000000 +0200 @@ -641,7 +641,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; @@ -1182,32 +1183,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-i386/include/linux/smp_lock.h linux-m68k/include/linux/smp_lock.h --- linux-i386/include/linux/smp_lock.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/include/linux/smp_lock.h 2005-04-25 23:13:18.000000000 +0200 @@ -2,7 +2,6 @@ #define __LINUX_SMPLOCK_H #include -#include #include #ifdef CONFIG_LOCK_KERNEL diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/thread_info.h linux-m68k/include/linux/thread_info.h --- linux-i386/include/linux/thread_info.h 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/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,¤t_thread_info()->flags); -} - -static inline void clear_thread_flag(int flag) -{ - clear_bit(flag,¤t_thread_info()->flags); -} - -static inline int test_and_set_thread_flag(int flag) -{ - return test_and_set_bit(flag,¤t_thread_info()->flags); -} - -static inline int test_and_clear_thread_flag(int flag) -{ - return test_and_clear_bit(flag,¤t_thread_info()->flags); -} - -static inline int test_thread_flag(int flag) -{ - return test_bit(flag,¤t_thread_info()->flags); -} - static inline void set_ti_thread_flag(struct thread_info *ti, int flag) { set_bit(flag,&ti->flags); @@ -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-i386/kernel/exit.c linux-m68k/kernel/exit.c --- linux-i386/kernel/exit.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/kernel/exit.c 2005-10-29 10:44:04.000000000 +0200 @@ -859,7 +859,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-i386/kernel/fork.c linux-m68k/kernel/fork.c --- linux-i386/kernel/fork.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/kernel/fork.c 2005-10-29 10:44:04.000000000 +0200 @@ -101,7 +101,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); @@ -156,7 +156,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); @@ -164,16 +164,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); @@ -928,7 +928,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)) @@ -1188,7 +1188,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-i386/kernel/sched.c linux-m68k/kernel/sched.c --- linux-i386/kernel/sched.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/kernel/sched.c 2005-10-29 10:44:05.000000000 +0200 @@ -4230,10 +4230,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); @@ -4313,9 +4313,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-i386/lib/kref.c linux-m68k/lib/kref.c --- linux-i386/lib/kref.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/lib/kref.c 2005-11-01 16:34:19.000000000 +0100 @@ -11,8 +11,8 @@ * */ -#include #include +#include /** * kref_init - initialize object. diff -urN --exclude-from=/usr/src/exclude-file linux-i386/mm/bootmem.c linux-m68k/mm/bootmem.c --- linux-i386/mm/bootmem.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/mm/bootmem.c 2005-10-29 10:44:06.000000000 +0200 @@ -283,7 +283,6 @@ count = 0; /* first extant page of the node */ - pfn = bdata->node_boot_start >> PAGE_SHIFT; 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 */ @@ -296,7 +295,8 @@ if (gofast && v == ~0UL) { int j, order; - page = pfn_to_page(pfn); + 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; @@ -308,23 +308,20 @@ } __free_pages(page, order); i += BITS_PER_LONG; - page += BITS_PER_LONG; } else if (v) { unsigned long m; - - page = pfn_to_page(pfn); - 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; - } - pfn += BITS_PER_LONG; } total += count; diff -urN --exclude-from=/usr/src/exclude-file linux-i386/net/ipv4/raw.c linux-m68k/net/ipv4/raw.c --- linux-i386/net/ipv4/raw.c 2005-10-28 02:02:08.000000000 +0200 +++ linux-m68k/net/ipv4/raw.c 2005-11-01 16:34:26.000000000 +0100 @@ -40,7 +40,6 @@ */ #include -#include #include #include #include