diff -Nru a/Documentation/computone.txt b/Documentation/computone.txt
--- a/Documentation/computone.txt	2002-02-04 23:54:04 -08:00
+++ b/Documentation/computone.txt	2004-12-22 19:00:39 -08:00
@@ -6,11 +6,11 @@
 These notes are for the drivers which have already been integrated into the
 kernel and have been tested on Linux kernels 2.0, 2.2, 2.3, and 2.4.
 
-Version: 1.2.14
-Date: 11/01/2001
+Version: 1.2.18
+Date: 12/22/2004
 Historical Author: Andrew Manison <amanison@america.net>
 Primary Author: Doug McNash
-Support: support@computone.com
+Support: mhw@wittsend.com
 Fixes and Updates: Mike Warfield <mhw@wittsend.com>
 
 This file assumes that you are using the Computone drivers which are
@@ -26,7 +26,7 @@
 products previous to the Intelliport II.
 
 This driver was developed on the v2.0.x Linux tree and has been tested up
-to v2.4.14; it will probably not work with earlier v1.X kernels,.
+to v2.4.28; it will probably not work with earlier v1.X kernels,.
 
 
 2. QUICK INSTALLATION
diff -Nru a/Makefile b/Makefile
--- a/Makefile	2004-12-21 10:40:23 -08:00
+++ b/Makefile	2005-01-05 02:49:38 -08:00
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 29
-EXTRAVERSION = -pre3
+EXTRAVERSION = -pre3-bk3
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -Nru a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
--- a/arch/ppc64/kernel/signal.c	2003-12-14 20:00:07 -08:00
+++ b/arch/ppc64/kernel/signal.c	2004-12-22 17:06:00 -08:00
@@ -31,8 +31,8 @@
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
-#include <asm/ppcdebug.h>
 #include <asm/unistd.h>
+#include <asm/processor.h>
 
 #define DEBUG_SIG 0
 
@@ -138,7 +138,7 @@
 	regs->gpr[3] = EINTR;
 	regs->ccr |= 0x10000000;
 	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
+		set_current_state(TASK_INTERRUPTIBLE);
 		schedule();
 		if (do_signal(&saveset, regs))
 			/*
@@ -236,22 +236,16 @@
 
 	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
-
-	current->thread.saved_msr = regs->msr & ~(MSR_FP | MSR_FE0 | MSR_FE1);
-	regs->msr = current->thread.saved_msr | current->thread.fpexc_mode;
-	current->thread.saved_softe = regs->softe;
-
 	err |= __put_user(&sc->gp_regs, &sc->regs);
 	err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE);
 	err |= __copy_to_user(&sc->fp_regs, &current->thread.fpr, FP_REGS_SIZE);
+	current->thread.fpscr = 0;
+
 	err |= __put_user(signr, &sc->signal);
 	err |= __put_user(handler, &sc->handler);
 	if (set != NULL)
 		err |=  __put_user(set->sig[0], &sc->oldmask);
 
-	regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
-	current->thread.fpscr = 0;
-
 	return err;
 }
 
@@ -263,19 +257,32 @@
 restore_sigcontext(struct pt_regs *regs, sigset_t *set, struct sigcontext *sc)
 {
 	unsigned int err = 0;
+	int i;
+	elf_greg_t *gregs = (elf_greg_t *)regs;
+	unsigned long msr;
+
+	/* copy up to but not including MSR */
+	err |= __copy_from_user(regs, &sc->gp_regs,
+				PT_MSR * sizeof(elf_greg_t));
+	/* get the MSR value from the stack but don't put it in regs->msr */
+	err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
+	/* copy from orig_r3 (the word after the MSR) to the end,
+	 * but don't copy softe */
+	for (i = PT_ORIG_R3; err == 0 && i <= PT_RESULT; ++i)
+		if (i != PT_SOFTE)
+			err |= __get_user(gregs[i], &sc->gp_regs[i]);
 
-	if (regs->msr & MSR_FP)
-		giveup_fpu(current);
-
-	err |= __copy_from_user(regs, &sc->gp_regs, GP_REGS_SIZE);
+	/* make the process reload FP regs if it executes an FP instr */
+	regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
+#ifndef CONFIG_SMP
+	if (last_task_used_math == current)
+		last_task_used_math = NULL;
+#endif
 	err |= __copy_from_user(&current->thread.fpr, &sc->fp_regs, FP_REGS_SIZE);
-	current->thread.fpexc_mode = regs->msr & (MSR_FE0 | MSR_FE1);
+
+	/* restore the signal mask */
 	if (set != NULL)
 		err |=  __get_user(set->sig[0], &sc->oldmask);
-
-	/* Don't allow the signal handler to change these modulo FE{0,1} */
-	regs->msr = current->thread.saved_msr & ~(MSR_FP | MSR_FE0 | MSR_FE1);
-	regs->softe = current->thread.saved_softe;
 
 	return err;
 }
diff -Nru a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
--- a/arch/ppc64/kernel/signal32.c	2003-12-14 20:00:07 -08:00
+++ b/arch/ppc64/kernel/signal32.c	2004-12-22 18:20:38 -08:00
@@ -48,7 +48,6 @@
 #include <asm/uaccess.h>
 #include <linux/elf.h>
 #include <asm/ppc32.h>
-#include <asm/ppcdebug.h>
 #include <asm/unistd.h>
 #include <asm/ucontext.h>
 
@@ -141,23 +140,22 @@
 {
 	struct k_sigaction new_ka, old_ka;
 	int ret;
+	u32 handler, restorer;
 	
-	PPCDBG(PPCDBG_SYS32, "sys32_sigaction - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
-
 	if (sig < 0)
 		sig = -sig;
 
 	if (act) {
 		old_sigset_t32 mask;
 
-		ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
-		ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
+		ret = get_user(handler, &act->sa_handler);
+		ret |= __get_user(restorer, &act->sa_restorer);
 		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
 		ret |= __get_user(mask, &act->sa_mask);
 		if (ret)
 			return ret;
-		PPCDBG(PPCDBG_SIGNAL, "sys32_sigaction flags =%lx  \n", new_ka.sa.sa_flags);
-
+		new_ka.sa.sa_handler = (__sighandler_t)(long) handler;
+		new_ka.sa.sa_restorer = (void (*)(void))(long) restorer;
 		siginitset(&new_ka.sa.sa_mask, mask);
 	}
 
@@ -171,9 +169,6 @@
 		ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
 	}
 
-	
-	PPCDBG(PPCDBG_SYS32, "sys32_sigaction - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
-
 	return ret;
 }
 
@@ -188,15 +183,11 @@
 	int ret;
 	mm_segment_t old_fs = get_fs();
 	
-	PPCDBG(PPCDBG_SYS32, "sys32_sigpending - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
-		
 	set_fs (KERNEL_DS);
 	ret = sys_sigpending(&s);
 	set_fs (old_fs);
 	if (put_user (s, set)) return -EFAULT;
 	
-	PPCDBG(PPCDBG_SYS32, "sys32_sigpending - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
-
 	return ret;
 }
 
@@ -216,16 +207,12 @@
 	int ret;
 	mm_segment_t old_fs = get_fs();
 	
-	PPCDBG(PPCDBG_SYS32, "sys32_sigprocmask - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
-	
 	if (set && get_user(s, set))
 		return -EFAULT;
 	set_fs (KERNEL_DS);
 	ret = sys_sigprocmask((int)how, set ? &s : NULL, oset ? &s : NULL);
 	set_fs (old_fs);
 	
-	PPCDBG(PPCDBG_SYS32, "sys32_sigprocmask - exited - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
-
 	if (ret)
 		return ret;
 	if (oset && put_user (s, oset))
@@ -256,14 +243,10 @@
 {
 	struct sigcontext32 *sc, sigctx;
 	struct sigregs32 *sr;
-	int ret;
 	elf_gregset_t32 saved_regs;  /* an array of ELF_NGREG unsigned ints (32 bits) */
 	sigset_t set;
-	unsigned int prevsp;
 	int i;
 
-	PPCDBG(PPCDBG_SIGNAL, "sys32_sigreturn - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
-
 	sc = (struct sigcontext32 *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
 	if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
 		goto badframe;
@@ -279,107 +262,67 @@
 	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
 
-	sc++;			/* Look at next sigcontext */
-	/* If the next sigcontext is actually the sigregs (frame)  */
-	/*   - then no more sigcontexts on the user stack          */  
-	if (sc == (struct sigcontext32*)(u64)sigctx.regs)
-	{
-		/* Last stacked signal - restore registers */
-		sr = (struct sigregs32*)(u64)sigctx.regs;
-		if (regs->msr & MSR_FP )
-			giveup_fpu(current);
-		/* 
-		 * Copy the 32 bit register values off the user stack
-		 * into the 32 bit register area
-		 */
-		if (copy_from_user(saved_regs, &sr->gp_regs,sizeof(sr->gp_regs)))
-			goto badframe;
-		/*
-		 * The saved reg structure in the frame is an elf_grepset_t32,
-		 * it is a 32 bit register save of the registers in the
-		 * pt_regs structure that was stored on the kernel stack
-		 * during the system call when the system call was interrupted
-		 * for the signal. Only 32 bits are saved because the
-		 * sigcontext contains a pointer to the regs and the sig
-		 * context address is passed as a pointer to the signal
-		 * handler.  
-		 *
-		 * The entries in the elf_grepset have the same index as the
-		 * elements in the pt_regs structure.
-		 */
-		saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
-			| (saved_regs[PT_MSR] & MSR_USERCHANGE);
-		/*
-		 * Register 2 is the kernel toc - should be reset on
-		 * any calls into the kernel 
-		 */
-		for (i = 0; i < 32; i++)
-			regs->gpr[i] = (u64)(saved_regs[i]) & 0xFFFFFFFF;
-
-		/*
-		 *  restore the non gpr registers 
-		 */
-		regs->msr = (u64)(saved_regs[PT_MSR]) & 0xFFFFFFFF;
-		/*
-		 * Insure that the interrupt mode is 64 bit, during 32 bit
-		 * execution. (This is necessary because we only saved
-		 * lower 32 bits of msr.)
-		 */
-		regs->msr = regs->msr | MSR_ISF;
-
-		regs->nip = (u64)(saved_regs[PT_NIP]) & 0xFFFFFFFF;
-		regs->orig_gpr3 = (u64)(saved_regs[PT_ORIG_R3]) & 0xFFFFFFFF; 
-		regs->ctr = (u64)(saved_regs[PT_CTR]) & 0xFFFFFFFF; 
-		regs->link = (u64)(saved_regs[PT_LNK]) & 0xFFFFFFFF; 
-		regs->xer = (u64)(saved_regs[PT_XER]) & 0xFFFFFFFF; 
-		regs->ccr = (u64)(saved_regs[PT_CCR]) & 0xFFFFFFFF;
-		/* regs->softe is left unchanged (like the MSR.EE bit) */
-		/******************************************************/
-		/* the DAR and the DSISR are only relevant during a   */
-		/*   data or instruction storage interrupt. The value */
-		/*   will be set to zero.                             */
-		/******************************************************/
-		regs->dar = 0; 
-		regs->dsisr = 0;
-		regs->result = (u64)(saved_regs[PT_RESULT]) & 0xFFFFFFFF;
+	sr = (struct sigregs32*)(u64)sigctx.regs;
+	/*
+	 * Copy the 32 bit register values off the user stack
+	 * into the 32 bit register area
+	 */
+	if (copy_from_user(saved_regs, &sr->gp_regs,sizeof(sr->gp_regs)))
+		goto badframe;
 
-		if (copy_from_user(current->thread.fpr, &sr->fp_regs, sizeof(sr->fp_regs)))
-			goto badframe;
+	/*
+	 * The saved reg structure in the frame is an elf_grepset_t32,
+	 * it is a 32 bit register save of the registers in the
+	 * pt_regs structure that was stored on the kernel stack
+	 * during the system call when the system call was interrupted
+	 * for the signal. Only 32 bits are saved because the
+	 * sigcontext contains a pointer to the regs and the sig
+	 * context address is passed as a pointer to the signal
+	 * handler.  
+	 *
+	 * The entries in the elf_grepset have the same index as the
+	 * elements in the pt_regs structure.
+	 */
+	for (i = 0; i < 32; i++)
+		regs->gpr[i] = (u64)(saved_regs[i]) & 0xFFFFFFFF;
 
-		ret = regs->result;
-	} else {
-		/* More signals to go */
-		regs->gpr[1] = (unsigned long)sc - __SIGNAL_FRAMESIZE32;
-		if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
-			goto badframe;
-		sr = (struct sigregs32*)(u64)sigctx.regs;
-		regs->gpr[3] = ret = sigctx.signal;
-		regs->gpr[4] = (unsigned long) sc;
-		regs->link = (unsigned long) &sr->tramp;
-		regs->nip = sigctx.handler;
+	/*
+	 *  restore the non gpr registers 
+	 */
+	regs->nip = (u64)(saved_regs[PT_NIP]) & 0xFFFFFFFF;
+	regs->orig_gpr3 = (u64)(saved_regs[PT_ORIG_R3]) & 0xFFFFFFFF; 
+	regs->ctr = (u64)(saved_regs[PT_CTR]) & 0xFFFFFFFF; 
+	regs->link = (u64)(saved_regs[PT_LNK]) & 0xFFFFFFFF; 
+	regs->xer = (u64)(saved_regs[PT_XER]) & 0xFFFFFFFF; 
+	regs->ccr = (u64)(saved_regs[PT_CCR]) & 0xFFFFFFFF;
+	/* regs->softe is left unchanged (like the MSR.EE bit) */
+	regs->result = (u64)(saved_regs[PT_RESULT]) & 0xFFFFFFFF;
+
+	/* force the process to reload the FP registers from
+	   current->thread when it next does FP instructions */
+	regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
+#ifndef CONFIG_SMP
+	if (last_task_used_math == current)
+		last_task_used_math = NULL;
+#endif
+	if (copy_from_user(current->thread.fpr, &sr->fp_regs,
+			   sizeof(sr->fp_regs)))
+		goto badframe;
 
-		if (get_user(prevsp, &sr->gp_regs[PT_R1])
-		    || put_user(prevsp, (unsigned int*) regs->gpr[1]))
-			goto badframe;
-		current->thread.fpscr = 0;
-	}
-  
-	PPCDBG(PPCDBG_SIGNAL, "sys32_sigreturn - normal exit returning %ld - pid=%ld current=%lx comm=%s \n", ret, current->pid, current, current->comm);
-	return ret;
+	return regs->result;
 
 badframe:
-	PPCDBG(PPCDBG_SYS32NI, "sys32_sigreturn - badframe - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
-	do_exit(SIGSEGV);
+	force_sig(SIGSEGV, current);
+	return 0;
 }	
 
 /*
  * Set up a signal frame.
  */
 static void
-setup_frame32(struct pt_regs *regs, struct sigregs32 *frame,
-            unsigned int newsp)
+setup_frame32(struct pt_regs *regs, int sig, struct k_sigaction *ka,
+	      struct sigregs32 *frame, unsigned int newsp)
 {
-	struct sigcontext32 *sc = (struct sigcontext32 *)(u64)newsp;
 	int i;
 
 	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
@@ -425,30 +368,32 @@
 			   (unsigned long) &frame->tramp[2]);
 	current->thread.fpscr = 0;      /* turn off all fp exceptions */
 
-	newsp -= __SIGNAL_FRAMESIZE32;
-	if (put_user(regs->gpr[1], (u32*)(u64)newsp)
-	    || get_user(regs->nip, &sc->handler)
-	    || get_user(regs->gpr[3], &sc->signal))
-		goto badframe;
-
-	regs->gpr[1] = newsp & 0xFFFFFFFF;
 	/*
 	 * first parameter to the signal handler is the signal number
 	 *  - the value is in gpr3
 	 * second parameter to the signal handler is the sigcontext
 	 *   - set the value into gpr4
 	 */
-	regs->gpr[4] = (unsigned long) sc;
+	regs->gpr[3] = sig;
+	regs->gpr[4] = newsp;
+	regs->nip = (u64)ka->sa.sa_handler & 0xFFFFFFFF;
 	regs->link = (unsigned long) frame->tramp;
+
+	newsp -= __SIGNAL_FRAMESIZE32;
+	if (put_user(regs->gpr[1], (u32*)(u64)newsp))
+		goto badframe;
+	regs->gpr[1] = newsp;
+
 	return;
 
  badframe:
-	udbg_printf("setup_frame32 - badframe in setup_frame, regs=%p frame=%p newsp=%lx\n", regs, frame, newsp);  PPCDBG_ENTER_DEBUGGER();
 #if DEBUG_SIG
 	printk("badframe in setup_frame32, regs=%p frame=%p newsp=%lx\n",
 	       regs, frame, newsp);
 #endif
-	do_exit(SIGSEGV);
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
 }
 
 
@@ -485,14 +430,12 @@
 	struct sigcontext32 sigctx;
 	struct sigregs32 *signalregs;
  
-	int i, ret;
+	int i;
 	elf_gregset_t32 saved_regs;   /* an array of 32 bit register values */
 	sigset_t signal_set; 
 	stack_t stack;
-	unsigned int previous_stack;
 
-	ret = 0;
-	/* Adjust the inputted reg1 to point to the first rt signal frame */
+	/* Adjust the inputted reg1 to point to the rt signal frame */
 	rt_stack_frame = (struct rt_sigframe_32 *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32);
 	/* Copy the information from the user stack  */
 	if (copy_from_user(&sigctx, &rt_stack_frame->uc.uc_mcontext,sizeof(sigctx))
@@ -514,100 +457,54 @@
 	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
 
-	/* Set to point to the next rt_sigframe - this is used to determine whether this 
-	 *   is the last signal to process
-	 */
-	rt_stack_frame ++;
-
-	if (rt_stack_frame == (struct rt_sigframe_32 *)(u64)(sigctx.regs)) {
-		signalregs = (struct sigregs32 *) (u64)sigctx.regs;
-		/* If currently owning the floating point - give them up */
-		if (regs->msr & MSR_FP)
-			giveup_fpu(current);
+	signalregs = (struct sigregs32 *) (u64)sigctx.regs;
 
-		if (copy_from_user(saved_regs,&signalregs->gp_regs,sizeof(signalregs->gp_regs))) 
-			goto badframe;
-
-		/*
-		 * The saved reg structure in the frame is an elf_grepset_t32,
-		 * it is a 32 bit register save of the registers in the
-		 * pt_regs structure that was stored on the kernel stack
-		 * during the system call when the system call was interrupted
-		 * for the signal. Only 32 bits are saved because the
-		 * sigcontext contains a pointer to the regs and the sig
-		 * context address is passed as a pointer to the signal handler
-		 *
-		 * The entries in the elf_grepset have the same index as
-		 * the elements in the pt_regs structure.
-		 */
-		saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
-			| (saved_regs[PT_MSR] & MSR_USERCHANGE);
-		/*
-		 * Register 2 is the kernel toc - should be reset on any
-		 * calls into the kernel
-		 */
-		for (i = 0; i < 32; i++)
-			regs->gpr[i] = (u64)(saved_regs[i]) & 0xFFFFFFFF;
-		/*
-		 * restore the non gpr registers
-		 */
-		regs->msr = (u64)(saved_regs[PT_MSR]) & 0xFFFFFFFF;
-		regs->nip = (u64)(saved_regs[PT_NIP]) & 0xFFFFFFFF;
-		regs->orig_gpr3 = (u64)(saved_regs[PT_ORIG_R3]) & 0xFFFFFFFF; 
-		regs->ctr = (u64)(saved_regs[PT_CTR]) & 0xFFFFFFFF; 
-		regs->link = (u64)(saved_regs[PT_LNK]) & 0xFFFFFFFF; 
-		regs->xer = (u64)(saved_regs[PT_XER]) & 0xFFFFFFFF; 
-		regs->ccr = (u64)(saved_regs[PT_CCR]) & 0xFFFFFFFF;
-		/* regs->softe is left unchanged (like MSR.EE) */
-		/*
-		 * the DAR and the DSISR are only relevant during a
-		 *   data or instruction storage interrupt. The value
-		 *   will be set to zero.
-		 */
-		regs->dar = 0; 
-		regs->dsisr = 0;
-		regs->result = (u64)(saved_regs[PT_RESULT]) & 0xFFFFFFFF;
-
-		if (copy_from_user(current->thread.fpr, &signalregs->fp_regs, sizeof(signalregs->fp_regs))) 
-			goto badframe;
-
-		ret = regs->result;
-	}
-	else  /* more signals to go  */
-	{
-		regs->gpr[1] = (u64)rt_stack_frame - __SIGNAL_FRAMESIZE32;
-		if (copy_from_user(&sigctx, &rt_stack_frame->uc.uc_mcontext,sizeof(sigctx)))
-		{
-			goto badframe;
-		}
-		signalregs = (struct sigregs32 *) (u64)sigctx.regs;
-		/* first parm to signal handler is the signal number */
-		regs->gpr[3] = ret = sigctx.signal;
-		/* second parm is a pointer to sig info */
-		get_user(regs->gpr[4], &rt_stack_frame->pinfo);
-		/* third parm is a pointer to the ucontext */
-		get_user(regs->gpr[5], &rt_stack_frame->puc);
-		/* fourth parm is the stack frame */
-		regs->gpr[6] = (u64)rt_stack_frame;
-		/* Set up link register to return to sigreturn when the */
-		/*  signal handler completes */
-		regs->link = (u64)&signalregs->tramp;
-		/* Set next instruction to the start fo the signal handler */
-		regs->nip = sigctx.handler;
-		/* Set the reg1 to look like a call to the signal handler */
-		if (get_user(previous_stack,&signalregs->gp_regs[PT_R1])
-		    || put_user(previous_stack, (unsigned long *)regs->gpr[1]))
-		{
-			goto badframe;
-		}
-		current->thread.fpscr = 0;
+	if (copy_from_user(saved_regs, &signalregs->gp_regs,
+			   sizeof(signalregs->gp_regs))) 
+		goto badframe;
 
-	}
+	/*
+	 * The saved reg structure in the frame is an elf_grepset_t32,
+	 * it is a 32 bit register save of the registers in the
+	 * pt_regs structure that was stored on the kernel stack
+	 * during the system call when the system call was interrupted
+	 * for the signal. Only 32 bits are saved because the
+	 * sigcontext contains a pointer to the regs and the sig
+	 * context address is passed as a pointer to the signal handler
+	 *
+	 * The entries in the elf_grepset have the same index as
+	 * the elements in the pt_regs structure.
+	 */
+	for (i = 0; i < 32; i++)
+		regs->gpr[i] = (u64)(saved_regs[i]) & 0xFFFFFFFF;
+	/*
+	 * restore the non gpr registers
+	 */
+	regs->nip = (u64)(saved_regs[PT_NIP]) & 0xFFFFFFFF;
+	regs->orig_gpr3 = (u64)(saved_regs[PT_ORIG_R3]) & 0xFFFFFFFF; 
+	regs->ctr = (u64)(saved_regs[PT_CTR]) & 0xFFFFFFFF; 
+	regs->link = (u64)(saved_regs[PT_LNK]) & 0xFFFFFFFF; 
+	regs->xer = (u64)(saved_regs[PT_XER]) & 0xFFFFFFFF; 
+	regs->ccr = (u64)(saved_regs[PT_CCR]) & 0xFFFFFFFF;
+	/* regs->softe is left unchanged (like MSR.EE) */
+	regs->result = (u64)(saved_regs[PT_RESULT]) & 0xFFFFFFFF;
+
+	/* force the process to reload the FP registers from
+	   current->thread when it next does FP instructions */
+	regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
+#ifndef CONFIG_SMP
+	if (last_task_used_math == current)
+		last_task_used_math = NULL;
+#endif
+	if (copy_from_user(current->thread.fpr, &signalregs->fp_regs,
+			   sizeof(signalregs->fp_regs))) 
+		goto badframe;
 
-	return ret;
+	return regs->result;
 
  badframe:
-	do_exit(SIGSEGV);     
+	force_sig(SIGSEGV, current);
+	return 0;
 }
 
 
@@ -617,15 +514,14 @@
 	struct k_sigaction new_ka, old_ka;
 	int ret;
 	sigset32_t set32;
-
-	PPCDBG(PPCDBG_SIGNAL, "sys32_rt_sigaction - entered - sig=%x \n", sig);
+	u32 handler;
 
 	/* XXX: Don't preclude handling different sized sigset_t's.  */
 	if (sigsetsize != sizeof(sigset32_t))
 		return -EINVAL;
 
 	if (act) {
-		ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
+		ret = get_user(handler, &act->sa_handler);
 		ret |= __copy_from_user(&set32, &act->sa_mask,
 					sizeof(sigset32_t));
 		switch (_NSIG_WORDS) {
@@ -643,6 +539,7 @@
 		
 		if (ret)
 			return -EFAULT;
+		new_ka.sa.sa_handler = (__sighandler_t)(long) handler;
 	}
 
 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
@@ -668,9 +565,7 @@
 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 	}
 
-  
-	PPCDBG(PPCDBG_SIGNAL, "sys32_rt_sigaction - exiting - sig=%x \n", sig);
-	return ret;
+  	return ret;
 }
 
 
@@ -691,8 +586,6 @@
 	int ret;
 	mm_segment_t old_fs = get_fs();
 
-	PPCDBG(PPCDBG_SIGNAL, "sys32_rt_sigprocmask - entered how=%x \n", (int)how);
-	
 	if (set) {
 		if (copy_from_user (&s32, set, sizeof(sigset32_t)))
 			return -EFAULT;
@@ -779,7 +672,7 @@
 	case SIGBUS:
 	case SIGFPE:
 	case SIGILL:
-		d->si_addr = (unsigned int)(s->si_addr);
+		d->si_addr = (unsigned int)(u64)(s->si_addr);
         break;
 	case SIGPOLL:
 		d->si_band = s->si_band;
@@ -943,7 +836,7 @@
 	regs->gpr[3] = EINTR;
 	regs->ccr |= 0x10000000;
 	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
+		set_current_state(TASK_INTERRUPTIBLE);
 		schedule();
 		if (do_signal(&saveset, regs))
 			/*
@@ -963,10 +856,9 @@
  * Set up a rt signal frame.
  */
 static void
-setup_rt_frame32(struct pt_regs *regs, struct sigregs32 *frame,
-            unsigned int newsp)
+setup_rt_frame32(struct pt_regs *regs, int sig, struct k_sigaction *ka,
+		 struct sigregs32 *frame, unsigned int newsp)
 {
-	unsigned int copyreg4,copyreg5;
 	struct rt_sigframe_32 * rt_sf = (struct rt_sigframe_32 *) (u64)newsp;
 	int i;
   
@@ -1013,34 +905,31 @@
 	current->thread.fpscr = 0;	/* turn off all fp exceptions */
   
 	/*
-	 * Retrieve rt_sigframe from stack and
-	 * set up registers for signal handler
-	*/
+	 * Set up registers for signal handler
+	 */
 	newsp -= __SIGNAL_FRAMESIZE32;
-      
-
-	if (put_user((u32)(regs->gpr[1]), (unsigned int *)(u64)newsp)
-	    || get_user(regs->nip, &rt_sf->uc.uc_mcontext.handler)
-	    || get_user(regs->gpr[3], &rt_sf->uc.uc_mcontext.signal)
-	    || get_user(copyreg4, &rt_sf->pinfo)
-	    || get_user(copyreg5, &rt_sf->puc))
-		goto badframe;
 
-	regs->gpr[4] = copyreg4;
-	regs->gpr[5] = copyreg5;
 	regs->gpr[1] = newsp;
+	regs->gpr[3] = sig;
+	regs->gpr[4] = (unsigned long) &rt_sf->info;
+	regs->gpr[5] = (unsigned long) &rt_sf->uc;
 	regs->gpr[6] = (unsigned long) rt_sf;
-	regs->link = (unsigned long) frame->tramp;
+	regs->nip    = (unsigned long) ka->sa.sa_handler;
+	regs->link   = (unsigned long) frame->tramp;
+
+	if (put_user((u32)(regs->gpr[1]), (unsigned int *)(u64)newsp))
+		goto badframe;
 
 	return;
 
  badframe:
-	udbg_printf("setup_frame32 - badframe in setup_frame, regs=%p frame=%p newsp=%lx\n", regs, frame, newsp);  PPCDBG_ENTER_DEBUGGER();
 #if DEBUG_SIG
-	printk("badframe in setup_frame32, regs=%p frame=%p newsp=%lx\n",
+	printk("badframe in setup_rt_frame32, regs=%p frame=%p newsp=%lx\n",
 	       regs, frame, newsp);
 #endif
-	do_exit(SIGSEGV);
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
 }
 
 
@@ -1131,7 +1020,9 @@
 	       regs, frame, *newspp);
 	printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset);
 #endif
-	do_exit(SIGSEGV);
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
 }
 
 
@@ -1150,6 +1041,8 @@
 	int ret;
 	mm_segment_t old_fs;
 	unsigned long sp;
+	u32 sssp;
+	stack_32_t *ustack;
 
 	/*
 	 * set sp to the user stack on entry to the system call
@@ -1157,21 +1050,26 @@
 	 */
 	sp = regs->gpr[1];
 
-	/*  Put new stack info in local 64 bit stack struct                      */ 
-	if (newstack && (get_user((long)uss.ss_sp, &((stack_32_t *)(long)newstack)->ss_sp) ||
-			 __get_user(uss.ss_flags, &((stack_32_t *)(long)newstack)->ss_flags) ||
-			 __get_user(uss.ss_size, &((stack_32_t *)(long)newstack)->ss_size)))
+	/*  Put new stack info in local 64 bit stack struct */ 
+	ustack = (stack_32_t *)(long) newstack;
+	if (newstack && (get_user(sssp, &ustack->ss_sp) ||
+			 __get_user(uss.ss_flags, &ustack->ss_flags) ||
+			 __get_user(uss.ss_size, &ustack->ss_size)))
 		return -EFAULT; 
-
+	uss.ss_sp = (void *)(long) sssp;
    
 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
 	ret = do_sigaltstack(newstack ? &uss : NULL, oldstack ? &uoss : NULL, sp);
 	set_fs(old_fs);
-	/* Copy the stack information to the user output buffer                  */
-	if (!ret && oldstack  && (put_user((long)uoss.ss_sp, &((stack_32_t *)(long)oldstack)->ss_sp) ||
-				  __put_user(uoss.ss_flags, &((stack_32_t *)(long)oldstack)->ss_flags) ||
-				  __put_user(uoss.ss_size, &((stack_32_t *)(long)oldstack)->ss_size)))
+	if (ret)
+		return ret;
+
+	/* Copy the stack information to the user output buffer */
+	ustack = (stack_32_t *)(long) oldstack;
+	if (oldstack && (put_user((long)uoss.ss_sp, &ustack->ss_sp) ||
+			 __put_user(uoss.ss_flags, &ustack->ss_flags) ||
+			 __put_user(uoss.ss_size, &ustack->ss_size)))
 		return -EFAULT;
 	return ret;
 }
@@ -1198,6 +1096,7 @@
 	siginfo_t info;
 	struct k_sigaction *ka;
 	unsigned int frame, newsp;
+	unsigned long signr = 0;
 
 	if (!oldset)
 		oldset = &current->blocked;
@@ -1205,15 +1104,9 @@
 	newsp = frame = 0;
 
 	for (;;) {
-		unsigned long signr;
-		
 		spin_lock_irq(&current->sigmask_lock);
 		signr = dequeue_signal(&current->blocked, &info);
 		spin_unlock_irq(&current->sigmask_lock);
-		ifppcdebug(PPCDBG_SYS32) {
-			if (signr)
-				udbg_printf("do_signal32 - processing signal=%2lx - pid=%ld, comm=%s \n", signr, current->pid, current->comm);
-		}
 
 		if (!signr)
 			break;
@@ -1298,14 +1191,6 @@
 			}
 		}
 
-		PPCDBG(PPCDBG_SIGNAL, " do signal :sigaction flags = %lx \n" ,ka->sa.sa_flags);
-		PPCDBG(PPCDBG_SIGNAL, " do signal :on sig stack  = %lx \n" ,on_sig_stack(regs->gpr[1]));
-		PPCDBG(PPCDBG_SIGNAL, " do signal :reg1  = %lx \n" ,regs->gpr[1]);
-		PPCDBG(PPCDBG_SIGNAL, " do signal :alt stack  = %lx \n" ,current->sas_ss_sp);
-		PPCDBG(PPCDBG_SIGNAL, " do signal :alt stack size  = %lx \n" ,current->sas_ss_size);
-
-
-
 		if ( (ka->sa.sa_flags & SA_ONSTACK)
 		     && (! on_sig_stack(regs->gpr[1])))
 			newsp = (current->sas_ss_sp + current->sas_ss_size);
@@ -1333,8 +1218,10 @@
 
 	/* Invoke correct stack setup routine */
 	if (ka->sa.sa_flags & SA_SIGINFO) 
-		setup_rt_frame32(regs, (struct sigregs32*)(u64)frame, newsp);
+		setup_rt_frame32(regs, signr, ka,
+				 (struct sigregs32*)(u64)frame, newsp);
 	else
-		setup_frame32(regs, (struct sigregs32*)(u64)frame, newsp);
+		setup_frame32(regs, signr, ka,
+			      (struct sigregs32*)(u64)frame, newsp);
 	return 1;
 }
diff -Nru a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c
--- a/drivers/char/ip2/i2ellis.c	2002-02-04 23:54:45 -08:00
+++ b/drivers/char/ip2/i2ellis.c	2004-12-22 18:39:13 -08:00
@@ -605,7 +605,7 @@
 
 	set_current_state( TASK_INTERRUPTIBLE );
 
-	pDelayTimer->expires  = jiffies + ( mseconds + 9 ) / 10;
+	pDelayTimer->expires  = jiffies + ((HZ * mseconds + 999) / 1000);
 	pDelayTimer->function = ii2DelayWakeup;
 	pDelayTimer->data     = 0;
 
diff -Nru a/drivers/char/ip2/i2ellis.h b/drivers/char/ip2/i2ellis.h
--- a/drivers/char/ip2/i2ellis.h	2002-02-04 23:53:43 -08:00
+++ b/drivers/char/ip2/i2ellis.h	2004-12-22 19:34:38 -08:00
@@ -403,7 +403,6 @@
 //	For queuing interupt bottom half handlers.	/\/\|=mhw=|\/\/
 	struct tq_struct	tqueue_interrupt;
 
-	struct timer_list  SendPendingTimer;   // Used by iiSendPending
 	unsigned int	SendPendingRetry;
 
 #ifdef	CONFIG_DEVFS_FS
diff -Nru a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
--- a/drivers/char/ip2/i2lib.c	2004-12-16 06:44:31 -08:00
+++ b/drivers/char/ip2/i2lib.c	2004-12-22 19:35:26 -08:00
@@ -174,8 +174,12 @@
 			pB->i2eWaitingForEmptyFifo |=
 				(pB->i2eOutMailWaiting & MB_OUT_STUFFED);
 			pB->i2eOutMailWaiting = 0;
+			if( pB->SendPendingRetry ) {
+				printk( KERN_DEBUG "IP2: iiSendPendingMail: busy board pickup on %d\n", pB->SendPendingRetry );
+			}
 			pB->SendPendingRetry = 0;
 		} else {
+#ifdef	IP2_USE_TIMER_WAIT
 /*		The only time we hit this area is when "iiTrySendMail" has
 		failed.  That only occurs when the outbound mailbox is
 		still busy with the last message.  We take a short breather
@@ -193,6 +197,11 @@
 			} else {
 				printk( KERN_ERR "IP2: iiSendPendingMail unable to queue outbound mail\n" );
 			}
+#endif
+			pB->SendPendingRetry++;
+			if( 0 == ( pB->SendPendingRetry % 8 ) ) {
+				printk( KERN_ERR "IP2: iiSendPendingMail: board busy, retry %d\n", pB->SendPendingRetry );
+			}
 		}
 	}
 }
@@ -1329,8 +1338,9 @@
 	remove_wait_queue(&(pCh->pBookmarkWait), &wait);
 
 	// if expires == 0 then timer poped, then do not need to del_timer
+	// jiffy wrap per Tim Schmielau (tim@physik3.uni-rostock.de)
 	if ((timeout > 0) && pCh->BookmarkTimer.expires && 
-	                     time_before(jiffies, pCh->BookmarkTimer.expires)) {
+			time_before(jiffies, pCh->BookmarkTimer.expires)) {
 		del_timer( &(pCh->BookmarkTimer) );
 		pCh->BookmarkTimer.expires = 0;
 
diff -Nru a/drivers/char/ip2/ip2types.h b/drivers/char/ip2/ip2types.h
--- a/drivers/char/ip2/ip2types.h	2002-02-05 09:40:06 -08:00
+++ b/drivers/char/ip2/ip2types.h	2004-12-22 09:05:27 -08:00
@@ -49,6 +49,10 @@
 	short irq[IP2_MAX_BOARDS]; 
 	unsigned short addr[IP2_MAX_BOARDS];
 	int type[IP2_MAX_BOARDS];
+#ifdef CONFIG_PCI
+	struct pci_dev *pci_dev[IP2_MAX_BOARDS];
+#endif
+
 } ip2config_t;
 
 #endif
diff -Nru a/drivers/char/ip2main.c b/drivers/char/ip2main.c
--- a/drivers/char/ip2main.c	2004-12-16 06:27:10 -08:00
+++ b/drivers/char/ip2main.c	2004-12-22 19:36:08 -08:00
@@ -19,6 +19,26 @@
 //
 // Done:
 //
+// 1.2.18	/\/\|=mhw=|\/\/
+// Fixed jiffies math in ii2DelayTimer...
+//	How long has THIS been broken?  Delay was basically a noop...
+// Dumped some groady tracing code that hasn't been used (or tested) in
+//	years and was only a source of warning messages.
+//
+// 1.2.17	/\/\|=mhw=|\/\/
+// PCI fixes submitted by Bjorn Helgaas
+//	Added calls to Add pci_enable_device()/pci_disable_device() per
+//	submitted patches.  My thanks to Bjorn Helgaas <bjorn.helgaas@hp.com>.
+//
+// 1.2.16	/\/\|=mhw=|\/\/
+// Yet another shot at the busy board timing window (use the poll timer).
+// 	Because of this, the poll timer is always enabled...
+// Cleaned up some comments on immediate interrupt mode (ppp code elsewhere
+// 	has been fixed and the new busy board logic won't throw a hairball).
+//
+// 1.2.15	dmc
+// Fixed jiffy wrap, PCI card may now be set to poll.
+//
 // 1.2.14	/\/\|=mhw=|\/\/
 // Added bounds checking to ip2_ipl_ioctl to avoid potential terroristic acts.
 // Changed the definition of ip2trace to be more consistant with kernel style
@@ -227,7 +247,7 @@
 
 /* String constants to identify ourselves */
 static char *pcName    = "Computone IntelliPort Plus multiport driver";
-static char *pcVersion = "1.2.14";
+static char *pcVersion = "1.2.18";
 
 /* String constants for port names */
 static char *pcDriver_name   = "ip2";
@@ -437,7 +457,7 @@
 	}
 	return 0;
 }
-#endif
+#endif /* MODULE */
 
 static int __init
 have_requested_irq( char irq )
@@ -545,6 +565,12 @@
 	// free memory
 	for (i = 0; i < IP2_MAX_BOARDS; i++) {
 		void *pB;
+#ifdef CONFIG_PCI
+		if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) {
+			pci_disable_device(ip2config.pci_dev[i]);
+			ip2config.pci_dev[i] = NULL;
+		}
+#endif
 		if ((pB = i2BoardPtrTable[i]) != 0 ) {
 			kfree ( pB );
 			i2BoardPtrTable[i] = NULL;
@@ -604,17 +630,12 @@
 		if (iop) {
 			ip2config.addr[i] = iop[i];
 			if (irqp) {
-				if( irqp[i] >= 0 ) {
-					ip2config.irq[i] = irqp[i];
-				} else {
-					ip2config.irq[i] = 0;
-				}
+				ip2config.irq[i] = irqp[i];
 	// This is a little bit of a hack.  If poll_only=1 on command
 	// line back in ip2.c OR all IRQs on all specified boards are
 	// explicitly set to 0, then drop to poll only mode and override
 	// PCI or EISA interrupts.  This superceeds the old hack of
 	// triggering if all interrupts were zero (like da default).
-	// Still a hack but less prone to random acts of terrorism.
 	//
 	// What we really should do, now that the IRQ default is set
 	// to -1, is to use 0 as a hard coded, do not probe.
@@ -700,17 +721,12 @@
 					} else {
 						printk( KERN_ERR "IP2: PCI I/O address error\n");
 					}
-					pcibios_read_config_byte(pci_bus, pci_devfn,
+					if (ip2config.irq[i] != 0) {
+						pcibios_read_config_byte(pci_bus, pci_devfn,
 								  PCI_INTERRUPT_LINE, &pci_irq);
 
-//		If the PCI BIOS assigned it, lets try and use it.  If we
-//		can't acquire it or it screws up, deal with it then.
-
-//					if (!is_valid_irq(pci_irq)) {
-//						printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
-//						pci_irq = 0;
-//					}
-					ip2config.irq[i] = pci_irq;
+						ip2config.irq[i] = pci_irq;
+					}
 				} else {	// ann error
 					ip2config.addr[i] = 0;
 					if (status == PCIBIOS_DEVICE_NOT_FOUND) {
@@ -727,9 +743,15 @@
 							  PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
 				if (pci_dev_i != NULL) {
 					unsigned int addr;
-					unsigned char pci_irq;
+
+					if (pci_enable_device(pci_dev_i)) {
+						printk( KERN_ERR "IP2: can't enable PCI device at %s\n",
+						pci_name(pci_dev_i));
+						break;
+					}
 
 					ip2config.type[i] = PCI;
+					ip2config.pci_dev[i] = pci_dev_i;
 					status =
 					pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr);
 					if ( addr & 1 ) {
@@ -737,18 +759,8 @@
 					} else {
 						printk( KERN_ERR "IP2: PCI I/O address error\n");
 					}
-					status =
-					pci_read_config_byte(pci_dev_i, PCI_INTERRUPT_LINE, &pci_irq);
-
-//		If the PCI BIOS assigned it, lets try and use it.  If we
-//		can't acquire it or it screws up, deal with it then.
-
-//					if (!is_valid_irq(pci_irq)) {
-//						printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
-//						pci_irq = 0;
-//					}
-					ip2config.irq[i] = pci_irq;
-				} else {	// ann error
+					ip2config.irq[i] = pci_dev_i->irq;
+				} else {	// an error
 					ip2config.addr[i] = 0;
 					if (status == PCIBIOS_DEVICE_NOT_FOUND) {
 						printk( KERN_ERR "IP2: PCI board %d not found\n", i );
@@ -964,6 +976,14 @@
 				/* Initialise the interrupt handler bottom half (aka slih). */
 			}
 		}
+
+		if (!TimerOn) {
+//			Kick the timer on for stuck board safeties...
+			PollTimer.expires = POLL_TIMEOUT;
+			add_timer ( &PollTimer );
+			TimerOn = 1;
+		}
+
 		for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
 			if ( i2BoardPtrTable[i] ) {
 				set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */
@@ -1375,8 +1395,10 @@
 
 //		Only process those boards which match our IRQ.
 //			IRQ = 0 for polled boards, we won't poll "IRQ" boards
+//		Add an additional "check" if the irq is zero for boards
+//		which are "stuck"
 
-		if ( pB && (pB->i2eUsingIrq == irq) ) {
+		if ( pB && ( pB->i2eUsingIrq == irq || ( 0 == irq && 0 != pB->SendPendingRetry ) ) ) {
 #ifdef USE_IQI
 
 		    if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) {
@@ -1391,9 +1413,8 @@
 			mark_bh(IMMEDIATE_BH);
 		    }
 #else
-//		We are using immediate servicing here.  This sucks and can
-//		cause all sorts of havoc with ppp and others.  The failsafe
-//		check on iiSendPendingMail could also throw a hairball.
+//		We are using immediate servicing here.  Suboptimal
+//			to say the least...
 			i2ServiceBoard( pB );
 #endif /* USE_IQI */
 		}
@@ -1417,6 +1438,9 @@
 static void
 ip2_poll(unsigned long arg)
 {
+	int i;
+	i2eBordStrPtr  pB;
+
 	ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
 
 	TimerOn = 0; // it's the truth but not checked in service
@@ -1424,7 +1448,15 @@
 	// Just polled boards, IRQ = 0 will hit all non-interrupt boards.
 	// It will NOT poll boards handled by hard interrupts.
 	// The issue of queued BH interrups is handled in ip2_interrupt().
-	ip2_interrupt(0, NULL, NULL);
+
+	for( i = 0; i < i2nBoards; ++i ) {
+		pB = i2BoardPtrTable[i];
+	// Service the board if the irq indicates a polled board
+	// OR if the SendPendingRetry indicates a retry state in the board
+		if ( pB && ( 0 == pB->i2eUsingIrq || 0 != pB->SendPendingRetry ) ) {
+			i2ServiceBoard( pB );
+		}
+	}
 
 	PollTimer.expires = POLL_TIMEOUT;
 	add_timer( &PollTimer );
@@ -3196,7 +3228,16 @@
 	case 2:	    // Ping device
 		rc = -EINVAL;
 		break;
+
+#ifdef IP2_TRACE_DEVICE
 	case 3:	    // Trace device
+/*
+	This may have been useful at one time during early development
+	but has not been used for years and is just a source of excess
+	baggage and unused code and warnings.  The client programs that
+	understood this returned "blob" don't even currently compile...
+	Disabled until needed in the future.  /\/\|=mhw=|\/\/  12/22/2004
+*/
 		if ( cmd == 1 ) {
 			PUT_USER(rc, iiSendPendingMail, pIndex++ );
 			PUT_USER(rc, i2InitChannels, pIndex++ );
@@ -3257,6 +3298,7 @@
 		}
 
 		break;
+#endif
 
 	default:
 		rc = -ENODEV;
diff -Nru a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
--- a/drivers/media/video/bttv-if.c	2003-10-06 02:09:55 -07:00
+++ b/drivers/media/video/bttv-if.c	2004-12-04 06:13:46 -08:00
@@ -190,7 +190,6 @@
 	return state;
 }
 
-#ifndef I2C_PEC
 static void bttv_inc_use(struct i2c_adapter *adap)
 {
 	MOD_INC_USE_COUNT;
@@ -200,7 +199,6 @@
 {
 	MOD_DEC_USE_COUNT;
 }
-#endif
 
 static int attach_inform(struct i2c_client *client)
 {
@@ -243,12 +241,8 @@
 };
 
 static struct i2c_adapter bttv_i2c_adap_template = {
-#ifdef I2C_PEC
-	.owner             = THIS_MODULE,
-#else
 	.inc_use           = bttv_inc_use,
 	.dec_use           = bttv_dec_use,
-#endif
 #ifdef I2C_ADAP_CLASS_TV_ANALOG
 	.class             = I2C_ADAP_CLASS_TV_ANALOG,
 #endif
diff -Nru a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
--- a/drivers/media/video/tvmixer.c	2003-10-06 02:09:55 -07:00
+++ b/drivers/media/video/tvmixer.c	2004-12-04 06:20:07 -08:00
@@ -193,10 +193,8 @@
 
 	/* lock bttv in memory while the mixer is in use  */
 	file->private_data = mix;
-#ifndef I2C_PEC
 	if (client->adapter->inc_use)
 		client->adapter->inc_use(client->adapter);
-#endif
         return 0;
 }
 
@@ -210,17 +208,12 @@
 		return -ENODEV;
 	}
 
-#ifndef I2C_PEC
 	if (client->adapter->dec_use)
 		client->adapter->dec_use(client->adapter);
-#endif
 	return 0;
 }
 
 static struct i2c_driver driver = {
-#ifdef I2C_PEC
-	.owner           = THIS_MODULE,
-#endif
 	.name            = "tv card mixer driver",
         .id              = I2C_DRIVERID_TVMIXER,
 #ifdef I2C_DF_DUMMY
diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
--- a/drivers/scsi/libata-core.c	2004-12-07 16:14:39 -08:00
+++ b/drivers/scsi/libata-core.c	2004-12-27 12:51:43 -08:00
@@ -28,6 +28,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/spinlock.h>
 #include <linux/blkdev.h>
@@ -1918,7 +1919,24 @@
 	if (idx)
 		ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
 }
+/**
+ *	ata_check_atapi_dma - Check whether ATAPI DMA can be supported
+ *	@qc: Metadata associated with taskfile to check
+ *
+ *	LOCKING:
+ *	RETURNS: 0 when ATAPI DMA can be used
+ *               nonzero otherwise
+ */
+int ata_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	int rc = 0; /* Assume ATAPI DMA is OK by default */
+
+	if (ap->ops->check_atapi_dma)
+		rc = ap->ops->check_atapi_dma(qc);
 
+	return rc;
+}
 /**
  *	ata_qc_prep - Prepare taskfile for submission
  *	@qc: Metadata associated with taskfile to be prepared
@@ -2368,6 +2386,9 @@
 	unsigned long timeout = 0;
 
 	switch (ap->pio_task_state) {
+	case PIO_ST_IDLE:
+		return;
+
 	case PIO_ST:
 		ata_pio_block(ap);
 		break;
@@ -2384,7 +2405,7 @@
 	case PIO_ST_TMOUT:
 	case PIO_ST_ERR:
 		ata_pio_error(ap);
-		break;
+		return;
 	}
 
 	if (timeout) {
@@ -2392,11 +2413,7 @@
 		schedule_timeout(timeout);
 	}
 
-	if ((ap->pio_task_state != PIO_ST_IDLE) &&
-	    (ap->pio_task_state != PIO_ST_TMOUT) &&
-	    (ap->pio_task_state != PIO_ST_ERR)) {
-		schedule_task(&ap->pio_task);
-	}
+	schedule_task(&ap->pio_task);
 }
 
 static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
@@ -2405,7 +2422,6 @@
 	DECLARE_COMPLETION(wait);
 	struct ata_queued_cmd *qc;
 	unsigned long flags;
-	int using_pio = dev->flags & ATA_DFLAG_PIO;
 	int rc;
 
 	DPRINTK("ATAPI request sense\n");
@@ -2426,16 +2442,10 @@
 	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
 	qc->tf.command = ATA_CMD_PACKET;
 
-	if (using_pio) {
-		qc->tf.protocol = ATA_PROT_ATAPI;
-		qc->tf.lbam = (8 * 1024) & 0xff;
-		qc->tf.lbah = (8 * 1024) >> 8;
-
-		qc->nbytes = SCSI_SENSE_BUFFERSIZE;
-	} else {
-		qc->tf.protocol = ATA_PROT_ATAPI_DMA;
-		qc->tf.feature |= ATAPI_PKT_DMA;
-	}
+	qc->tf.protocol = ATA_PROT_ATAPI;
+	qc->tf.lbam = (8 * 1024) & 0xff;
+	qc->tf.lbah = (8 * 1024) >> 8;
+	qc->nbytes = SCSI_SENSE_BUFFERSIZE;
 
 	qc->waiting = &wait;
 	qc->complete_fn = ata_qc_complete_noop;
@@ -2707,7 +2717,7 @@
 			return 1;
 
 		/* fall through */
-	
+
 	default:
 		return 0;
 	}
diff -Nru a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
--- a/drivers/scsi/libata-scsi.c	2004-12-07 16:26:24 -08:00
+++ b/drivers/scsi/libata-scsi.c	2004-12-27 12:51:30 -08:00
@@ -1256,6 +1256,11 @@
 	int using_pio = (dev->flags & ATA_DFLAG_PIO);
 	int nodata = (cmd->sc_data_direction == SCSI_DATA_NONE);
 
+	if (!using_pio)
+		/* Check whether ATAPI DMA is safe */
+		if (ata_check_atapi_dma(qc))
+			using_pio = 1;
+
 	memcpy(&qc->cdb, scsicmd, qc->ap->cdb_len);
 
 	qc->complete_fn = atapi_qc_complete;
diff -Nru a/drivers/scsi/libata.h b/drivers/scsi/libata.h
--- a/drivers/scsi/libata.h	2004-11-13 11:27:54 -08:00
+++ b/drivers/scsi/libata.h	2004-12-27 12:51:30 -08:00
@@ -38,6 +38,7 @@
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
 				      struct ata_device *dev);
 extern int ata_qc_issue(struct ata_queued_cmd *qc);
+extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
 extern void ata_dev_select(struct ata_port *ap, unsigned int device,
                            unsigned int wait, unsigned int can_sleep);
 extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf);
diff -Nru a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
--- a/drivers/scsi/sata_nv.c	2004-11-13 11:27:54 -08:00
+++ b/drivers/scsi/sata_nv.c	2004-12-27 12:43:29 -08:00
@@ -219,10 +219,18 @@
 	.host_stop		= nv_host_stop,
 };
 
+/* FIXME: The hardware provides the necessary SATA PHY controls
+ * to support ATA_FLAG_SATA_RESET.  However, it is currently
+ * necessary to disable that flag, to solve misdetection problems.
+ * See http://bugme.osdl.org/show_bug.cgi?id=3352 for more info.
+ *
+ * This problem really needs to be investigated further.  But in the
+ * meantime, we avoid ATA_FLAG_SATA_RESET to get people working.
+ */
 static struct ata_port_info nv_port_info = {
 	.sht		= &nv_sht,
 	.host_flags	= ATA_FLAG_SATA |
-			  ATA_FLAG_SATA_RESET |
+			  /* ATA_FLAG_SATA_RESET | */
 			  ATA_FLAG_SRST |
 			  ATA_FLAG_NO_LEGACY,
 	.pio_mask	= NV_PIO_MASK,
diff -Nru a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
--- a/drivers/scsi/sata_uli.c	2004-11-13 11:27:54 -08:00
+++ b/drivers/scsi/sata_uli.c	2004-12-27 12:45:46 -08:00
@@ -32,16 +32,18 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"sata_uli"
-#define DRV_VERSION	"0.2"
+#define DRV_VERSION	"0.5"
 
 enum {
 	uli_5289		= 0,
 	uli_5287		= 1,
+	uli_5281		= 2,
 
 	/* PCI configuration registers */
-	ULI_SCR_BASE		= 0x90, /* sata0 phy SCR registers */
-	ULI_SATA1_OFS		= 0x10, /* offset from sata0->sata1 phy regs */
-
+	ULI5287_BASE		= 0x90, /* sata0 phy SCR registers */
+	ULI5287_OFFS		= 0x10, /* offset from sata0->sata1 phy regs */
+	ULI5281_BASE		= 0x60, /* sata0 phy SCR  registers */
+	ULI5281_OFFS		= 0x60, /* offset from sata0->sata1 phy regs */
 };
 
 static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
@@ -51,6 +53,7 @@
 static struct pci_device_id uli_pci_tbl[] = {
 	{ PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 },
 	{ PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 },
+	{ PCI_VENDOR_ID_AL, 0x5281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5281 },
 	{ }	/* terminate list */
 };
 
@@ -126,33 +129,15 @@
 MODULE_DEVICE_TABLE(pci, uli_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
 
-static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg)
+static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
 {
-	unsigned int addr = ULI_SCR_BASE + (4 * sc_reg);
-
-	switch (port_no) {
-	case 0:
-		break;
-	case 1:
-		addr += ULI_SATA1_OFS;
-		break;
-	case 2:
-		addr += ULI_SATA1_OFS*4;
-		break;
-	case 3:
-		addr += ULI_SATA1_OFS*5;
-		break;
-	default:
-		BUG();
-		break;
-	}
-	return addr;
+	return ap->ioaddr.scr_addr + (4 * sc_reg);
 }
 
 static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
-	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg);
+	unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
 	u32 val;
 
 	pci_read_config_dword(pdev, cfg_addr, &val);
@@ -162,7 +147,7 @@
 static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
-	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr);
+	unsigned int cfg_addr = get_scr_cfg_addr(ap, scr);
 
 	pci_write_config_dword(pdev, cfg_addr, val);
 }
@@ -220,9 +205,11 @@
 		rc = -ENOMEM;
 		goto err_out_regions;
 	}
-
+	
 	switch (board_idx) {
 	case uli_5287:
+		probe_ent->port[0].scr_addr = ULI5287_BASE;
+		probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
        		probe_ent->n_ports = 4;
 
        		probe_ent->port[2].cmd_addr = pci_resource_start(pdev, 0) + 8;
@@ -230,19 +217,27 @@
 		probe_ent->port[2].ctl_addr =
 			(pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4;
 		probe_ent->port[2].bmdma_addr = pci_resource_start(pdev, 4) + 16;
+		probe_ent->port[2].scr_addr = ULI5287_BASE + ULI5287_OFFS*4;
 
 		probe_ent->port[3].cmd_addr = pci_resource_start(pdev, 2) + 8;
 		probe_ent->port[3].altstatus_addr =
 		probe_ent->port[3].ctl_addr =
 			(pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4;
 		probe_ent->port[3].bmdma_addr = pci_resource_start(pdev, 4) + 24;
+		probe_ent->port[3].scr_addr = ULI5287_BASE + ULI5287_OFFS*5;
 
 		ata_std_ports(&probe_ent->port[2]);
 		ata_std_ports(&probe_ent->port[3]);
 		break;
 
 	case uli_5289:
-		/* do nothing; ata_pci_init_native_mode did it all */
+		probe_ent->port[0].scr_addr = ULI5287_BASE;
+		probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
+		break;
+
+	case uli_5281:
+		probe_ent->port[0].scr_addr = ULI5281_BASE;
+		probe_ent->port[1].scr_addr = ULI5281_BASE + ULI5281_OFFS;
 		break;
 
 	default:
diff -Nru a/include/linux/libata.h b/include/linux/libata.h
--- a/include/linux/libata.h	2004-12-07 16:14:39 -08:00
+++ b/include/linux/libata.h	2004-12-27 12:51:30 -08:00
@@ -340,6 +340,8 @@
 	void (*phy_reset) (struct ata_port *ap);
 	void (*post_set_mode) (struct ata_port *ap);
 
+	int (*check_atapi_dma) (struct ata_queued_cmd *qc);
+
 	void (*bmdma_setup) (struct ata_queued_cmd *qc);
 	void (*bmdma_start) (struct ata_queued_cmd *qc);
 
diff -Nru a/net/Config.in b/net/Config.in
--- a/net/Config.in	2004-04-23 16:38:28 -07:00
+++ b/net/Config.in	2004-12-15 00:58:03 -08:00
@@ -61,7 +61,9 @@
 fi
 
 tristate 'Appletalk protocol support' CONFIG_ATALK
-source drivers/net/appletalk/Config.in
+if [ "$CONFIG_ATALK" != "n" ]; then
+   source drivers/net/appletalk/Config.in
+fi
 
 tristate 'DECnet Support' CONFIG_DECNET
 if [ "$CONFIG_DECNET" != "n" ]; then
