Index: arch/acorn26/acorn26/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/acorn26/acorn26/vm_machdep.c,v
retrieving revision 1.6
diff -u -p -r1.6 vm_machdep.c
--- arch/acorn26/acorn26/vm_machdep.c	14 Jul 2003 22:48:20 -0000	1.6
+++ arch/acorn26/acorn26/vm_machdep.c	23 Dec 2003 08:10:13 -0000
@@ -159,17 +159,19 @@ cpu_setfunc(struct lwp *l, void (*func)(
 }
 
 void
-cpu_exit(struct lwp *l, int proc)
+cpu_lwp_free(struct lwp *l, int proc)
 {
-	int s;
 
 	/* Nothing to do here? */
+}
+
+void
+cpu_exit(struct lwp *l)
+{
+	int s;
 
 	/* I think this is safe on a uniprocessor machine */
-	if (proc)
-		exit2(l);
-	else
-		lwp_exit2(l);
+	lwp_exit2(l);
 	SCHED_LOCK(s);		/* expected by cpu_switch */
 	cpu_switch(l, NULL);
 }
Index: arch/alpha/alpha/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/alpha/vm_machdep.c,v
retrieving revision 1.80
diff -u -p -r1.80 vm_machdep.c
--- arch/alpha/alpha/vm_machdep.c	29 Jun 2003 22:28:04 -0000	1.80
+++ arch/alpha/alpha/vm_machdep.c	23 Dec 2003 08:10:14 -0000
@@ -94,28 +94,25 @@ cpu_coredump(struct lwp *l, struct vnode
 	return error;
 }
 
-/*
- * cpu_exit is called as the last action during exit.
- * We block interrupts and call switch_exit.  switch_exit switches
- * to proc0's PCB and stack, then jumps into the middle of cpu_switch,
- * as if it were switching from proc0.
- */
 void
-cpu_exit(struct lwp *l, int proc)
+cpu_lwp_free(struct lwp *l, int proc)
 {
 
 	if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
 		fpusave_proc(l, 0);
+}
 
-	/*
-	 * Deactivate the exiting address space before the vmspace
-	 * is freed.  Note that we will continue to run on this
-	 * vmspace's context until the switch to proc0 in switch_exit().
-	 */
-	pmap_deactivate(l);
 
+/*
+ * cpu_exit is called as the last action during exit.
+ * We block interrupts and call switch_exit.  switch_exit switches
+ * to proc0's PCB and stack, then jumps into the middle of cpu_switch,
+ * as if it were switching from proc0.
+ */
+void
+cpu_exit(struct lwp *l)
 	(void) splhigh();
-	switch_exit(l, proc ? exit2 : lwp_exit2);
+	switch_exit(l, lwp_exit2);
 	/* NOTREACHED */
 }
 
Index: arch/alpha/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/include/cpu.h,v
retrieving revision 1.61
diff -u -p -r1.61 cpu.h
--- arch/alpha/include/cpu.h	7 Aug 2003 16:26:33 -0000	1.61
+++ arch/alpha/include/cpu.h	23 Dec 2003 08:10:17 -0000
@@ -216,7 +216,6 @@ void	cpu_pause_resume_all(int);
  * definitions of cpu-dependent requirements
  * referenced in generic code
  */
-#define	cpu_wait(p)		/* nothing */
 #define	cpu_number()		alpha_pal_whami()
 #define	cpu_proc_fork(p1, p2)	/* nothing */
 
Index: arch/amd64/amd64/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/vm_machdep.c,v
retrieving revision 1.3
diff -u -p -r1.3 vm_machdep.c
--- arch/amd64/amd64/vm_machdep.c	7 Aug 2003 16:26:35 -0000	1.3
+++ arch/amd64/amd64/vm_machdep.c	23 Dec 2003 08:10:17 -0000
@@ -244,33 +244,29 @@ cpu_swapout(l)
 	fpusave_lwp(l, 1);
 }
 
-/*
- * cpu_exit is called as the last action during exit.
- *
- * We clean up a little and then call switch_exit() with the old proc as an
- * argument.  switch_exit() first switches to proc0's context, and finally
- * jumps into switch() to wait for another process to wake up.
- */
 void
-cpu_exit(struct lwp *l, int proc)
+cpu_lwp_free(struct lwp *l, int proc)
 {
-
 	/* If we were using the FPU, forget about it. */
 	if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
 		fpusave_lwp(l, 0);
 
 	if (proc && l->l_md.md_flags & MDP_USEDMTRR)
 		mtrr_clean(l->l_proc);
+}
 
-	/*
-	 * No need to do user LDT cleanup here; it's handled in
-	 * pmap_destroy().
-	 */
-
-	pmap_deactivate(l);
+/*
+ * cpu_exit is called as the last action during exit.
+ *
+ * We clean up a little and then call switch_exit() with the old proc as an
+ * argument.  switch_exit() first switches to proc0's context, and finally
+ * jumps into switch() to wait for another process to wake up.
+ */
+void
+cpu_exit(struct lwp *l)
+{
 
-	uvmexp.swtch++;
-	switch_exit(l, proc ? exit2 : lwp_exit2);
+	switch_exit(l, lwp_exit2);
 }
 
 /*
Index: arch/amiga/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/amiga/include/cpu.h,v
retrieving revision 1.56
diff -u -p -r1.56 cpu.h
--- arch/amiga/include/cpu.h	7 Aug 2003 16:26:45 -0000	1.56
+++ arch/amiga/include/cpu.h	23 Dec 2003 08:10:17 -0000
@@ -111,7 +111,6 @@ extern struct cpu_info cpu_info_store;
  * referenced in generic code
  */
 #define	cpu_swapin(p)			/* nothing */
-#define	cpu_wait(p)			/* nothing */
 #define	cpu_swapout(p)			/* nothing */
 #define	cpu_number()			0
 
Index: arch/amigappc/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/amigappc/include/cpu.h,v
retrieving revision 1.10
diff -u -p -r1.10 cpu.h
--- arch/amigappc/include/cpu.h	2 Nov 2003 16:37:09 -0000	1.10
+++ arch/amigappc/include/cpu.h	23 Dec 2003 08:10:17 -0000
@@ -61,7 +61,6 @@ void	physaccess	__P((caddr_t, caddr_t, i
 #define	PROC_PC(p)		(trapframe(p)->srr0)
 
 #define cpu_swapout(p)		/* nothing */
-#define cpu_wait(p)		/* nothing */
 #define cpu_number()            0
 
 extern void delay __P((unsigned));
Index: arch/arm/arm32/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/arm32/vm_machdep.c,v
retrieving revision 1.30
diff -u -p -r1.30 vm_machdep.c
--- arch/arm/arm32/vm_machdep.c	23 Oct 2003 08:59:10 -0000	1.30
+++ arch/arm/arm32/vm_machdep.c	23 Dec 2003 08:10:17 -0000
@@ -225,7 +225,7 @@ cpu_setfunc(struct lwp *l, void (*func)(
  */
 
 void
-cpu_exit(struct lwp *l, int proc)
+cpu_lwp_free(struct lwp *l, int proc)
 {
 #ifdef ARMFPE
 	/* Abort any active FP operation and deactivate the context */
@@ -249,10 +249,13 @@ cpu_exit(struct lwp *l, int proc)
 		log(LOG_INFO, "%d bytes of svc stack fill pattern\n", loop);
 	}
 #endif	/* STACKCHECKS */
-	uvmexp.swtch++;
-	switch_exit(l, &lwp0, proc ? exit2 : lwp_exit2);
 }
 
+void
+cpu_exit(struct lwp *l)
+{
+	switch_exit(l, &lwp0, lwp_exit2);
+}
 
 void
 cpu_swapin(l)
Index: arch/arm/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/include/cpu.h,v
retrieving revision 1.34
diff -u -p -r1.34 cpu.h
--- arch/arm/include/cpu.h	23 Jun 2003 11:01:08 -0000	1.34
+++ arch/arm/include/cpu.h	23 Dec 2003 08:10:17 -0000
@@ -240,8 +240,6 @@ extern int astpending;
 
 #define signotify(p)            setsoftast()
 
-#define cpu_wait(p)	/* nothing */
-
 /*
  * Preempt the current process if in interrupt from user mode,
  * or after the current trap/syscall if in system mode.
Index: arch/atari/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/atari/include/cpu.h,v
retrieving revision 1.42
diff -u -p -r1.42 cpu.h
--- arch/atari/include/cpu.h	7 Aug 2003 16:27:03 -0000	1.42
+++ arch/atari/include/cpu.h	23 Dec 2003 08:10:17 -0000
@@ -112,7 +112,6 @@ extern struct cpu_info cpu_info_store;
  * referenced in generic code
  */
 #define	cpu_swapin(p)			/* nothing */
-#define	cpu_wait(p)			/* nothing */
 #define cpu_swapout(p)			/* nothing */
 #define	cpu_number()			0
 
Index: arch/cesfic/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/cesfic/include/cpu.h,v
retrieving revision 1.7
diff -u -p -r1.7 cpu.h
--- arch/cesfic/include/cpu.h	7 Aug 2003 16:27:15 -0000	1.7
+++ arch/cesfic/include/cpu.h	23 Dec 2003 08:10:17 -0000
@@ -107,7 +107,6 @@ extern struct cpu_info cpu_info_store;
  * referenced in generic code
  */
 #define	cpu_swapin(p)			/* nothing */
-#define	cpu_wait(p)			/* nothing */
 #define	cpu_swapout(p)			/* nothing */
 #define cpu_number()			0
 
Index: arch/hp300/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/include/cpu.h,v
retrieving revision 1.42
diff -u -p -r1.42 cpu.h
--- arch/hp300/include/cpu.h	7 Aug 2003 16:27:39 -0000	1.42
+++ arch/hp300/include/cpu.h	23 Dec 2003 08:10:18 -0000
@@ -117,7 +117,6 @@ extern struct cpu_info cpu_info_store;
  * referenced in generic code
  */
 #define	cpu_swapin(p)			/* nothing */
-#define	cpu_wait(p)			/* nothing */
 #define	cpu_swapout(p)			/* nothing */
 #define	cpu_number()			0
 
Index: arch/hp700/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/hp700/include/cpu.h,v
retrieving revision 1.9
diff -u -p -r1.9 cpu.h
--- arch/hp700/include/cpu.h	8 Nov 2003 15:19:20 -0000	1.9
+++ arch/hp700/include/cpu.h	23 Dec 2003 08:10:18 -0000
@@ -186,7 +186,6 @@ extern struct cpu_info cpu_info_store;
  * definitions of cpu-dependent requirements
  * referenced in generic code
  */
-#define	cpu_wait(p)			/* nothing */
 #define	cpu_number()			0
 
 #define cpu_proc_fork(p1, p2)
Index: arch/hppa/hppa/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hppa/hppa/vm_machdep.c,v
retrieving revision 1.8
diff -u -p -r1.8 vm_machdep.c
--- arch/hppa/hppa/vm_machdep.c	28 Nov 2003 19:02:25 -0000	1.8
+++ arch/hppa/hppa/vm_machdep.c	23 Dec 2003 08:10:19 -0000
@@ -227,14 +227,18 @@ cpu_setfunc(struct lwp *l, void (*func)(
 }
 
 void
-cpu_exit(struct lwp *l, int proc)
+cpu_lwp_free(struct lwp *l, int proc)
 {
-	(void) splsched();
-	uvmexp.swtch++;
 
 	/* Flush the LWP out of the FPU. */
 	hppa_fpu_flush(l);
-	switch_exit(l, proc ? exit2 : lwp_exit2);
+}
+
+void
+cpu_exit(struct lwp *l)
+{
+	(void) splsched();
+	switch_exit(l, lwp_exit2);
 }
 
 /*
Index: arch/i386/i386/locore.S
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/locore.S,v
retrieving revision 1.20
diff -u -p -r1.20 locore.S
--- arch/i386/i386/locore.S	4 Nov 2003 10:33:15 -0000	1.20
+++ arch/i386/i386/locore.S	23 Dec 2003 08:10:21 -0000
@@ -2028,7 +2028,7 @@ ENTRY(cpu_switchto)
 	jmp	switch_resume
 
 /*
- * void switch_exit(struct lwp *l, void (*exit)(struct lwp *));
+ * void cpu_exit(struct lwp *l)
  * Switch to the appropriate idle context (lwp0's if uniprocessor; the cpu's 
  * if multiprocessor) and deallocate the address space and kernel stack for p. 
  * Then jump into cpu_switch(), as if we were in the idle proc all along.
@@ -2038,10 +2038,9 @@ ENTRY(cpu_switchto)
 #endif
 	.globl  _C_LABEL(uvmspace_free),_C_LABEL(kernel_map)
 	.globl	_C_LABEL(uvm_km_free),_C_LABEL(tss_free)
-/* LINTSTUB: Func: void switch_exit(struct lwp *l, void (*exit)(struct lwp *)) */
-ENTRY(switch_exit)
+/* LINTSTUB: Func: void cpu_exit(struct lwp *l) */
+ENTRY(cpu_exit)
 	movl	4(%esp),%edi		# old process
-	movl	8(%esp),%eax		# exit func
 #ifndef MULTIPROCESSOR
 	movl	$_C_LABEL(lwp0),%ebx
 	movl	L_ADDR(%ebx),%esi
@@ -2060,9 +2059,6 @@ ENTRY(switch_exit)
 	movl	PCB_ESP(%esi),%esp
 	movl	PCB_EBP(%esi),%ebp
 
-	/* Save exit func. */
-	pushl	%eax
-
 	/* Load TSS info. */
 #ifdef MULTIPROCESSOR
 	movl	CPUVAR(GDT),%eax
@@ -2092,11 +2088,10 @@ ENTRY(switch_exit)
 	sti
 
 	/*
-	 * Schedule the dead process's vmspace and stack to be freed.
+	 * Schedule the dead LWP's stack to be freed.
 	 */
-	movl	0(%esp),%eax		/* %eax = exit func */
-	movl	%edi,0(%esp)		/* {lwp_}exit2(l) */
-	call	*%eax
+	pushl	%edi
+	call	_C_LABEL(lwp_exit2)
 	addl	$4,%esp
 
 	/* Jump into cpu_switch() with the right state. */
Index: arch/i386/i386/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/vm_machdep.c,v
retrieving revision 1.112
diff -u -p -r1.112 vm_machdep.c
--- arch/i386/i386/vm_machdep.c	27 Oct 2003 14:11:47 -0000	1.112
+++ arch/i386/i386/vm_machdep.c	23 Dec 2003 08:10:22 -0000
@@ -249,18 +249,12 @@ cpu_swapout(l)
 }
 
 /*
- * cpu_exit is called as the last action during exit.
- *
- * We clean up a little and then call switch_exit() with the old proc as an
- * argument.  switch_exit() first switches to proc0's context, and finally
- * jumps into switch() to wait for another process to wake up.
- * 
- * If proc==0, we're an exiting lwp, and call switch_lwp_exit() instead of 
- * switch_exit(), and only do LWP-appropriate cleanup (e.g. don't deactivate
- * the pmap).
+ * cpu_lwp_free is called from exit() to let machine-dependent
+ * code free machine-dependent resources that should be cleaned
+ * while we can still block and have process associated with us
  */
 void
-cpu_exit(struct lwp *l, int proc)
+cpu_lwp_free(struct lwp *l, int proc)
 {
 
 #if NNPX > 0
@@ -274,35 +268,11 @@ cpu_exit(struct lwp *l, int proc)
 		mtrr_clean(l->l_proc);
 #endif
 
-	/*
-	 * No need to do user LDT cleanup here; it's handled in
-	 * pmap_destroy().
-	 */
-
-	/*
-	 * Deactivate the address space before the vmspace is
-	 * freed.  Note that we will continue to run on this
-	 * vmspace's context until the switch to the idle process
-	 * in switch_exit().
-	 */
-	pmap_deactivate(l);
-
-	uvmexp.swtch++;
-	switch_exit(l, proc ? exit2 : lwp_exit2);
-}
-
-/*
- * cpu_wait is called from reaper() to let machine-dependent
- * code free machine-dependent resources that couldn't be freed
- * in cpu_exit().
- */
-void
-cpu_wait(l)
-	struct lwp *l;
-{
-
 	/* Nuke the TSS. */
 	tss_free(l->l_md.md_tss_sel);
+#ifdef DEBUG
+	l->l_md.md_tss_sel = 0xfeedbeed;
+#endif
 }
 
 /*
Index: arch/luna68k/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/luna68k/include/cpu.h,v
retrieving revision 1.7
diff -u -p -r1.7 cpu.h
--- arch/luna68k/include/cpu.h	7 Aug 2003 16:28:05 -0000	1.7
+++ arch/luna68k/include/cpu.h	23 Dec 2003 08:10:22 -0000
@@ -108,7 +108,6 @@ extern struct cpu_info cpu_info_store;
  * referenced in generic code
  */
 #define cpu_swapin(p)			/* nothing */
-#define cpu_wait(p)			/* nothing */
 #define cpu_swapout(p)			/* nothing */
 #define cpu_number()			0
 
Index: arch/m68k/m68k/switch_subr.s
===================================================================
RCS file: /cvsroot/src/sys/arch/m68k/m68k/switch_subr.s,v
retrieving revision 1.8
diff -u -p -r1.8 switch_subr.s
--- arch/m68k/m68k/switch_subr.s	4 Nov 2003 10:33:16 -0000	1.8
+++ arch/m68k/m68k/switch_subr.s	23 Dec 2003 08:10:22 -0000
@@ -112,33 +112,6 @@ GLOBAL(masterpaddr)		| XXXcompatibility 
 ASBSS(nullpcb,SIZEOF_PCB)
 
 /*
- * void switch_exit(struct lwp *);
- *
- * At exit of a process, do a switch for the last time.
- * Switch to a safe stack and PCB, and select a new process to run.  The
- * old stack and u-area will be freed by the reaper.
- *
- * MUST BE CALLED AT SPLHIGH!
- */
-ENTRY(switch_exit)
-	movl    %sp@(4),%a0
-	/* save state into garbage pcb */
-	movl    #_ASM_LABEL(nullpcb),_C_LABEL(curpcb)
-	lea     _ASM_LABEL(tmpstk),%sp	| goto a tmp stack
-
-	/* Schedule the vmspace and stack to be freed. */
-	movl	%a0,%sp@-		| exit2(l)
-	jbsr	_C_LABEL(exit2)
-	lea	%sp@(4),%sp		| pop args
-
-#if defined(LOCKDEBUG)
-	/* Acquire sched_lock */ 
-	jbsr	_C_LABEL(sched_lock_idle)
-#endif
-
-	jra	_C_LABEL(cpu_switch)
-
-/*
  * void switch_lwp_exit(struct lwp *);
  *
  * At exit of a process, do a switch for the last time.
Index: arch/m68k/m68k/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/m68k/m68k/vm_machdep.c,v
retrieving revision 1.6
diff -u -p -r1.6 vm_machdep.c
--- arch/m68k/m68k/vm_machdep.c	7 Aug 2003 16:28:19 -0000	1.6
+++ arch/m68k/m68k/vm_machdep.c	23 Dec 2003 08:10:23 -0000
@@ -185,6 +185,13 @@ cpu_setfunc(l, func, arg)
 	pcb->pcb_regs[11] = (int)sf;		/* SSP */
 }	
 
+void
+cpu_lwp_free(struct lwp *l, int proc)
+{
+
+	/* Nothing to do */
+}
+
 /*
  * cpu_exit is called as the last action during exit.
  *
@@ -192,17 +199,12 @@ cpu_setfunc(l, func, arg)
  * switch to another process thus we never return.
  */
 void
-cpu_exit(l, proc)
+cpu_exit(l)
 	struct lwp *l;
-	int proc;
 {
 
 	(void) splhigh();
-	uvmexp.swtch++;
-	if (proc)
-		switch_exit(l);
-	else
-		switch_lwp_exit(l);
+	switch_lwp_exit(l);
 	/* NOTREACHED */
 }
 
Index: arch/mac68k/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/include/cpu.h,v
retrieving revision 1.73
diff -u -p -r1.73 cpu.h
--- arch/mac68k/include/cpu.h	7 Aug 2003 16:28:20 -0000	1.73
+++ arch/mac68k/include/cpu.h	23 Dec 2003 08:10:23 -0000
@@ -132,7 +132,6 @@ extern struct cpu_info cpu_info_store;
  * referenced in generic code
  */
 #define	cpu_swapin(p)			/* nothing */
-#define	cpu_wait(p)			/* nothing */
 #define	cpu_swapout(p)			/* nothing */
 #define	cpu_number()			0
 
Index: arch/mips/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/cpu.h,v
retrieving revision 1.71
diff -u -p -r1.71 cpu.h
--- arch/mips/include/cpu.h	7 Aug 2003 16:28:27 -0000	1.71
+++ arch/mips/include/cpu.h	23 Dec 2003 08:10:23 -0000
@@ -253,7 +253,6 @@ extern int mips3_pg_cached;
  * definitions of cpu-dependent requirements
  * referenced in generic code
  */
-#define	cpu_wait(p)			/* nothing */
 #define	cpu_swapout(p)			panic("cpu_swapout: can't get here");
 
 void cpu_intr(u_int32_t, u_int32_t, u_int32_t, u_int32_t);
Index: arch/mips/mips/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/vm_machdep.c,v
retrieving revision 1.99
diff -u -p -r1.99 vm_machdep.c
--- arch/mips/mips/vm_machdep.c	26 Nov 2003 08:36:51 -0000	1.99
+++ arch/mips/mips/vm_machdep.c	23 Dec 2003 08:10:24 -0000
@@ -240,6 +240,14 @@ cpu_swapin(l)
 		l->l_md.md_upte[i] = pte[i].pt_entry &~ x;
 }
 
+void
+cpu_lwp_free(struct lwp *l, int proc)
+{
+
+	if ((l->l_md.md_flags & MDP_FPUSED) && l == fpcurlwp)
+		fpcurlwp = (struct lwp *)0;
+}
+
 /*
  * cpu_exit is called as the last action during exit.
  *
@@ -249,18 +257,13 @@ cpu_swapin(l)
  * into the middle of cpu_switch(), as if it were switching from proc0.
  */
 void
-cpu_exit(l, proc)
+cpu_exit(l)
 	struct lwp *l;
-	int proc;
 {
 	void switch_exit(struct lwp *, void (*)(struct lwp *));
 
-	if ((l->l_md.md_flags & MDP_FPUSED) && l == fpcurlwp)
-		fpcurlwp = (struct lwp *)0;
-
-	uvmexp.swtch++;
 	(void)splhigh();
-	switch_exit(l, proc ? exit2 : lwp_exit2);
+	switch_exit(l, lwp_exit2);
 	/* NOTREACHED */
 }
 
Index: arch/mvme68k/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mvme68k/include/cpu.h,v
retrieving revision 1.28
diff -u -p -r1.28 cpu.h
--- arch/mvme68k/include/cpu.h	7 Aug 2003 16:28:41 -0000	1.28
+++ arch/mvme68k/include/cpu.h	23 Dec 2003 08:10:24 -0000
@@ -112,7 +112,6 @@ extern struct cpu_info cpu_info_store;
  * referenced in generic code
  */
 #define	cpu_swapin(p)			/* nothing */
-#define	cpu_wait(p)			/* nothing */
 #define cpu_swapout(p)			/* nothing */
 #define	cpu_number()			0
 
Index: arch/news68k/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/news68k/include/cpu.h,v
retrieving revision 1.16
diff -u -p -r1.16 cpu.h
--- arch/news68k/include/cpu.h	7 Aug 2003 16:28:50 -0000	1.16
+++ arch/news68k/include/cpu.h	23 Dec 2003 08:10:25 -0000
@@ -132,7 +132,6 @@ extern struct cpu_info cpu_info_store;
  * referenced in generic code
  */
 #define cpu_swapin(p)			/* nothing */
-#define cpu_wait(p)			/* nothing */
 #define cpu_swapout(p)			/* nothing */
 #define cpu_number()			0
 
Index: arch/next68k/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/include/cpu.h,v
retrieving revision 1.25
diff -u -p -r1.25 cpu.h
--- arch/next68k/include/cpu.h	5 Oct 2003 22:00:25 -0000	1.25
+++ arch/next68k/include/cpu.h	23 Dec 2003 08:10:25 -0000
@@ -119,7 +119,6 @@ extern struct cpu_info cpu_info_store;
  * referenced in generic code
  */
 #define	cpu_swapin(p)			/* nothing */
-#define	cpu_wait(p)			/* nothing */
 #define cpu_swapout(p)			/* nothing */
 #define	cpu_number()			0
 
Index: arch/pc532/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/pc532/include/cpu.h,v
retrieving revision 1.37
diff -u -p -r1.37 cpu.h
--- arch/pc532/include/cpu.h	7 Aug 2003 16:28:59 -0000	1.37
+++ arch/pc532/include/cpu.h	23 Dec 2003 08:10:25 -0000
@@ -72,7 +72,6 @@ extern struct cpu_info cpu_info_store;
  */
 #define	cpu_proc_fork(p1, p2)		/* nothing */
 #define cpu_swapin(p)           	/* nothing */
-#define	cpu_wait(p)			/* nothing */
 #define	cpu_number()			0
 
 /*
Index: arch/pc532/pc532/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pc532/pc532/vm_machdep.c,v
retrieving revision 1.58
diff -u -p -r1.58 vm_machdep.c
--- arch/pc532/pc532/vm_machdep.c	19 Oct 2003 17:45:35 -0000	1.58
+++ arch/pc532/pc532/vm_machdep.c	23 Dec 2003 08:10:26 -0000
@@ -212,6 +212,15 @@ cpu_swapout(l)
 	fpu_lwp = 0;
 }
 
+void
+cpu_lwp_free(struct lwp *l, int proc)
+{
+
+	/* If we were using the FPU, forget about it. */
+	if (fpu_lwp == l)
+		fpu_lwp = 0;
+}
+
 /*
  * cpu_exit is called as the last action during exit.
  *
@@ -220,31 +229,22 @@ cpu_swapout(l)
  * jumps into switch() to wait for another process to wake up.
  */
 void
-cpu_exit(arg, proc)
+cpu_exit(arg)
 	struct lwp *arg;
-	int proc;
 {
 	extern struct user *proc0paddr;
 	register struct lwp *l __asm("r3");
-	uvmexp.swtch++;
 
 	/* Copy arg into a register. */
 	movd(arg, l);
 
-	/* If we were using the FPU, forget about it. */
-	if (fpu_lwp == l)
-		fpu_lwp = 0;
-
 	/* Switch to temporary stack and address space. */
 	lprd(sp, INTSTACK);
 	load_ptb(proc0paddr->u_pcb.pcb_ptb);
 
 	/* Schedule the vmspace and stack to be freed. */
 	(void) splhigh();
-	if (proc)		/* XXXJRT FRAGILE!  USE A REGISTER! */
-		exit2(l);
-	else
-		lwp_exit2(l);
+	lwp_exit2(l);		/* XXXJRT FRAGILE!  USE A REGISTER! */
 
 	/* Don't update pcb in cpu_switch. */
 	curlwp = NULL;
Index: arch/pdp10/pdp10/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pdp10/pdp10/machdep.c,v
retrieving revision 1.3
diff -u -p -r1.3 machdep.c
--- arch/pdp10/pdp10/machdep.c	6 Dec 2003 03:16:49 -0000	1.3
+++ arch/pdp10/pdp10/machdep.c	23 Dec 2003 08:10:26 -0000
@@ -205,13 +205,13 @@ sendsig(int sig, const sigset_t *mask, u
 }
 
 void
-cpu_wait(struct lwp *p)
+cpu_lwp_free(struct lwp *l, int proc)
 {
-	panic("cpu_wait");
+	panic("cpu_lwp_free");
 }
 
 void
-cpu_exit(struct lwp *p, int a)
+cpu_exit(struct lwp *l)
 {
 	panic("cpu_exit");
 }
Index: arch/powerpc/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/include/cpu.h,v
retrieving revision 1.38
diff -u -p -r1.38 cpu.h
--- arch/powerpc/include/cpu.h	21 Nov 2003 18:07:29 -0000	1.38
+++ arch/powerpc/include/cpu.h	23 Dec 2003 08:10:27 -0000
@@ -268,7 +268,6 @@ mfpvr(void)
 #define	LWP_PC(l)		(trapframe(l)->srr0)
 
 #define	cpu_swapout(p)
-#define cpu_wait(p)
 #define	cpu_proc_fork(p1, p2)
 
 extern int powersave;
Index: arch/powerpc/powerpc/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/powerpc/vm_machdep.c,v
retrieving revision 1.57
diff -u -p -r1.57 vm_machdep.c
--- arch/powerpc/powerpc/vm_machdep.c	27 Sep 2003 04:44:42 -0000	1.57
+++ arch/powerpc/powerpc/vm_machdep.c	23 Dec 2003 08:10:27 -0000
@@ -214,19 +214,9 @@ pagemove(caddr_t from, caddr_t to, size_
 	pmap_update(pmap_kernel());
 }
 
-/*
- * cpu_exit is called as the last action during exit.
- *
- * We clean up a little and then call switchexit() with the old proc
- * as an argument.  switchexit() switches to the idle context, schedules
- * the old vmspace and stack to be freed, then selects a new process to
- * run.
- */
 void
-cpu_exit(struct lwp *l, int proc)
+cpu_lwp_free(struct lwp *l, int proc)
 {
-	/* This is in locore_subr.S */
-	void switch_exit(struct lwp *, void (*)(struct lwp *));
 #if defined(PPC_HAVE_FPU) || defined(ALTIVEC)
 	struct pcb *pcb = &l->l_addr->u_pcb;
 #endif
@@ -240,8 +230,24 @@ cpu_exit(struct lwp *l, int proc)
 		save_vec_lwp(l);
 #endif
 
+}
+
+/*
+ * cpu_exit is called as the last action during exit.
+ *
+ * We clean up a little and then call switchexit() with the old proc
+ * as an argument.  switchexit() switches to the idle context, schedules
+ * the old vmspace and stack to be freed, then selects a new process to
+ * run.
+ */
+void
+cpu_exit(struct lwp *l)
+{
+	/* This is in locore_subr.S */
+	void switch_exit(struct lwp *, void (*)(struct lwp *));
+
 	splsched();
-	switch_exit(l, proc ? exit2 : lwp_exit2);
+	switch_exit(l, lwp_exit2);
 }
 
 /*
Index: arch/sh3/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/include/cpu.h,v
retrieving revision 1.32
diff -u -p -r1.32 cpu.h
--- arch/sh3/include/cpu.h	7 Aug 2003 16:29:28 -0000	1.32
+++ arch/sh3/include/cpu.h	23 Dec 2003 08:10:27 -0000
@@ -104,7 +104,6 @@ extern struct cpu_info cpu_info_store;
  * definitions of cpu-dependent requirements
  * referenced in generic code
  */
-#define	cpu_wait(p)			/* nothing */
 #define	cpu_number()			0
 /*
  * Can't swapout u-area, (__SWAP_BROKEN)
Index: arch/sh3/sh3/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/vm_machdep.c,v
retrieving revision 1.39
diff -u -p -r1.39 vm_machdep.c
--- arch/sh3/sh3/vm_machdep.c	15 Nov 2003 23:47:58 -0000	1.39
+++ arch/sh3/sh3/vm_machdep.c	23 Dec 2003 08:10:28 -0000
@@ -302,6 +302,13 @@ cpu_setfunc(struct lwp *l, void (*func)(
 	sf->sf_sr = PSL_MD;		/* kernel mode, interrupt enable */
 }
 
+void
+cpu_lwp_free(struct lwp *l)
+{
+
+	/* Nothing to do */
+}
+
 /*
  * void cpu_exit(struct lwp *l):
  *	+ Change kernel context to lwp0's one.
@@ -309,12 +316,11 @@ cpu_setfunc(struct lwp *l, void (*func)(
  *	+ switch to another process.
  */
 void
-cpu_exit(struct lwp *l, int proc)
+cpu_exit(struct lwp *l)
 {
 	struct switchframe *sf;
 
 	splsched();
-	uvmexp.swtch++;
 
 	/* Switch to lwp0 stack */
 	curlwp = 0;
@@ -330,10 +336,7 @@ cpu_exit(struct lwp *l, int proc)
 		"r"(sf->sf_r7_bank));
 
 	/* Schedule freeing process resources */
-	if (proc)
-		exit2(l);
-	else
-		lwp_exit2(l);
+	lwp_exit2(l);
 
 	cpu_switch(l, NULL);
 	/* NOTREACHED */
Index: arch/sh5/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sh5/include/cpu.h,v
retrieving revision 1.11
diff -u -p -r1.11 cpu.h
--- arch/sh5/include/cpu.h	7 Aug 2003 16:29:31 -0000	1.11
+++ arch/sh5/include/cpu.h	23 Dec 2003 08:10:28 -0000
@@ -194,7 +194,6 @@ curcpu(void)
  * definitions of cpu-dependent requirements
  * referenced in generic code
  */
-#define	cpu_wait(p)			/* nothing */
 #define	cpu_number()			0
 #define	cpu_proc_fork(p1, p2)		/* nothing */
 
Index: arch/sh5/sh5/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh5/sh5/vm_machdep.c,v
retrieving revision 1.7
diff -u -p -r1.7 vm_machdep.c
--- arch/sh5/sh5/vm_machdep.c	15 Jul 2003 03:36:01 -0000	1.7
+++ arch/sh5/sh5/vm_machdep.c	23 Dec 2003 08:10:28 -0000
@@ -135,6 +135,13 @@ cpu_coredump(struct lwp *l, struct vnode
 #endif
 }
 
+void
+cpu_lwp_free(struct lwp *l, int proc)
+{
+
+	/* Nothing to do */
+}
+
 /*
  * cpu_exit is called as the last action during exit.
  *
@@ -142,15 +149,12 @@ cpu_coredump(struct lwp *l, struct vnode
  * switch to another LWP thus we never return.
  */
 void
-cpu_exit(struct lwp *l, int proc)
+cpu_exit(struct lwp *l)
 {
 	extern volatile void switch_exit(struct lwp *, void (*)(struct lwp *));
 
-	pmap_deactivate(l);
-
 	(void) splhigh();
-	uvmexp.swtch++;
-	switch_exit(l, proc ? exit2 : lwp_exit2);
+	switch_exit(l, lwp_exit2);
 	/* NOTREACHED */
 }
 
Index: arch/sparc/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/include/cpu.h,v
retrieving revision 1.65
diff -u -p -r1.65 cpu.h
--- arch/sparc/include/cpu.h	8 Nov 2003 15:19:20 -0000	1.65
+++ arch/sparc/include/cpu.h	23 Dec 2003 08:10:29 -0000
@@ -86,7 +86,6 @@
 
 #define	cpu_swapin(p)		/* nothing */
 #define	cpu_swapout(p)		/* nothing */
-#define	cpu_wait(p)		/* nothing */
 #define	cpu_number()		(cpuinfo.ci_cpuid)
 #define	cpu_proc_fork(p1, p2)	/* nothing */
 
Index: arch/sparc/sparc/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/vm_machdep.c,v
retrieving revision 1.77
diff -u -p -r1.77 vm_machdep.c
--- arch/sparc/sparc/vm_machdep.c	15 Jul 2003 00:05:10 -0000	1.77
+++ arch/sparc/sparc/vm_machdep.c	23 Dec 2003 08:10:29 -0000
@@ -308,20 +308,10 @@ cpu_lwp_fork(l1, l2, stack, stacksize, f
 }
 
 /*
- * cpu_exit is called as the last action during exit.
- *
- * We clean up the FPU state and then call switchexit() with the old proc
- * as an argument.  switchexit() switches to the idle context, schedules
- * the old vmspace and stack to be freed, then selects a new process to
- * run.
- *
- * If proc==0, we're an exiting lwp and arrange to call lwp_exit2() instead
- * of exit2().
+ * Cleanup FPU state.
  */
 void
-cpu_exit(l, proc)
-	struct lwp *l;
-	int proc;
+cpu_lwp_free(struct lwp *l, int proc)
 {
 	struct fpstate *fs;
 
@@ -347,7 +337,24 @@ cpu_exit(l, proc)
 		l->l_md.md_fpstate = NULL;
 		free((void *)fs, M_SUBPROC);
 	}
-	switchexit(l, proc ? exit2 : lwp_exit2);
+}
+
+/*
+ * cpu_exit is called as the last action during exit.
+ *
+ * We just call switchexit() with the old lwp
+ * as an argument.  switchexit() switches to the idle context, schedules
+ * the old vmspace and stack to be freed, then selects a new process to
+ * run.
+ *
+ * If proc==0, we're an exiting lwp and arrange to call lwp_exit2() instead
+ * of exit2().
+ */
+void
+cpu_exit(l)
+	struct lwp *l;
+{
+	switchexit(l, lwp_exit2);
 	/* NOTREACHED */
 }
 
Index: arch/sparc64/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/include/cpu.h,v
retrieving revision 1.40
diff -u -p -r1.40 cpu.h
--- arch/sparc64/include/cpu.h	25 Nov 2003 05:14:58 -0000	1.40
+++ arch/sparc64/include/cpu.h	23 Dec 2003 08:10:30 -0000
@@ -136,7 +136,6 @@ extern struct cpu_info *cpus;
  */
 #define	cpu_swapin(p)	/* nothing */
 #define	cpu_swapout(p)	/* nothing */
-#define	cpu_wait(p)	/* nothing */
 #if 1
 #define cpu_number()	0
 #else
Index: arch/sparc64/sparc64/locore.s
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/locore.s,v
retrieving revision 1.185
diff -u -p -r1.185 locore.s
--- arch/sparc64/sparc64/locore.s	2 Dec 2003 22:44:17 -0000	1.185
+++ arch/sparc64/sparc64/locore.s	23 Dec 2003 08:10:35 -0000
@@ -7404,7 +7404,6 @@ ENTRY(switchexit)
 #endif
 	wrpr	%g0, PSTATE_KERN, %pstate ! Make sure we're on the right globals
 	mov	%o0, %l2		! save proc arg for exit2() call XXXXX
-	mov	%o1, %l3		! remember if we are a proc or lwp
 
 #ifdef SCHED_DEBUG
 	save	%sp, -CC64FSZ, %sp
@@ -7460,17 +7459,10 @@ ENTRY(switchexit)
 	set	_C_LABEL(idle_u), %l6
 	SET_SP_REDZONE(%l6, %l5)
 #endif
-	brz,pn	%l3, 0f				! Are we a lwp?
-	 wrpr	%g0, PSTATE_INTR, %pstate	! and then enable traps
+	wrpr	%g0, PSTATE_INTR, %pstate	! and then enable traps
 	
-	call	_C_LABEL(exit2)			! exit2(p)
-	 mov	%l2, %o0
-	ba,a,pt	%icc, 1f
-	 nop
-0:
 	call	_C_LABEL(lwp_exit2)		! lwp_exit2(p)
 	 mov	%l2, %o0
-1:	
 
 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
 	call	_C_LABEL(sched_lock_idle)	! Acquire sched_lock
Index: arch/sparc64/sparc64/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/vm_machdep.c,v
retrieving revision 1.52
diff -u -p -r1.52 vm_machdep.c
--- arch/sparc64/sparc64/vm_machdep.c	2 Dec 2003 22:44:17 -0000	1.52
+++ arch/sparc64/sparc64/vm_machdep.c	23 Dec 2003 08:10:36 -0000
@@ -330,16 +330,8 @@ cpu_setfunc(l, func, arg)
 	npcb->pcb_sp = (long)rp - STACK_OFFSET;
 }	
 
-/*
- * cpu_exit is called as the last action during exit.
- *
- * We clean up a little and then call switchexit() with the old proc
- * as an argument.  switchexit() switches to the idle context, schedules
- * the old vmspace and stack to be freed, then selects a new process to
- * run.
- */
 void
-cpu_exit(l, proc)
+cpu_lwp_free(l, proc)
 	struct lwp *l;
 	int proc;
 {
@@ -352,7 +344,21 @@ cpu_exit(l, proc)
 		}
 		free((void *)fs, M_SUBPROC);
 	}
-	switchexit(l, proc);
+}
+
+/*
+ * cpu_exit is called as the last action during exit.
+ *
+ * We clean up a little and then call switchexit() with the old proc
+ * as an argument.  switchexit() switches to the idle context, schedules
+ * the old vmspace and stack to be freed, then selects a new process to
+ * run.
+ */
+void
+cpu_exit(l)
+	struct lwp *l;
+{
+	switchexit(l, 0);
 	/* NOTREACHED */
 }
 
Index: arch/sun3/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sun3/include/cpu.h,v
retrieving revision 1.34
diff -u -p -r1.34 cpu.h
--- arch/sun3/include/cpu.h	22 Sep 2003 17:11:46 -0000	1.34
+++ arch/sun3/include/cpu.h	23 Dec 2003 08:10:36 -0000
@@ -123,7 +123,6 @@ extern struct cpu_info cpu_info_store;
  * referenced in generic code
  */
 #define	cpu_number()			0
-#define	cpu_wait(p)			/* nothing */
 #define	cpu_swapin(p)			/* nothing */
 #define	cpu_swapout(p)			/* nothing */
 
Index: arch/sun68k/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sun68k/include/cpu.h,v
retrieving revision 1.6
diff -u -p -r1.6 cpu.h
--- arch/sun68k/include/cpu.h	21 Sep 2003 14:41:34 -0000	1.6
+++ arch/sun68k/include/cpu.h	23 Dec 2003 08:10:37 -0000
@@ -120,7 +120,6 @@ extern struct cpu_info cpu_info_store;
  * referenced in generic code
  */
 #define	cpu_number()			0
-#define	cpu_wait(p)			/* nothing */
 #define	cpu_swapin(p)			/* nothing */
 #define	cpu_swapout(p)			/* nothing */
 
Index: arch/vax/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/vax/include/cpu.h,v
retrieving revision 1.66
diff -u -p -r1.66 cpu.h
--- arch/vax/include/cpu.h	1 Mar 2003 21:51:59 -0000	1.66
+++ arch/vax/include/cpu.h	23 Dec 2003 08:10:37 -0000
@@ -65,7 +65,6 @@
 #include <machine/psl.h>
 
 #define enablertclock()
-#define	cpu_wait(p)
 
 /*
  * All cpu-dependent info is kept in this struct. Pointer to the
Index: arch/vax/vax/subr.S
===================================================================
RCS file: /cvsroot/src/sys/arch/vax/vax/subr.S,v
retrieving revision 1.9
diff -u -p -r1.9 subr.S
--- arch/vax/vax/subr.S	10 Nov 2003 08:51:52 -0000	1.9
+++ arch/vax/vax/subr.S	23 Dec 2003 08:10:37 -0000
@@ -456,9 +456,6 @@ JSBENTRY(Swtchto)
 ENTRY(cpu_exit,0)
 	movl	4(%ap),%r6	# Process pointer in %r6
 
-	pushl	%r6
-	calls	$1,_C_LABEL(pmap_deactivate)
-
 	mtpr	$IPL_CLOCK,$PR_IPL # Block almost everything
 	mfpr	$PR_SSP,%r7	# get cpu_info ptr
 	movl	CI_EXIT(%r7),%r8	# scratch page address
@@ -467,7 +464,7 @@ ENTRY(cpu_exit,0)
 	mtpr	%r8,$PR_PCBB	# new PCB
 	mtpr	%r7,$PR_SSP	# In case...
 	pushl	%r6
-	calls	$1,_C_LABEL(exit2)	# release last resources.
+	calls	$1,_C_LABEL(lwp_exit2)	# release last resources.
 	mtpr	$IPL_HIGH,$PR_IPL	# block all types of interrupts
 #if defined(LOCKDEBUG)
 	calls	$0,_C_LABEL(sched_lock_idle)
Index: arch/x68k/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/include/cpu.h,v
retrieving revision 1.29
diff -u -p -r1.29 cpu.h
--- arch/x68k/include/cpu.h	7 Aug 2003 16:30:26 -0000	1.29
+++ arch/x68k/include/cpu.h	23 Dec 2003 08:10:37 -0000
@@ -118,7 +118,6 @@ extern struct cpu_info cpu_info_store;
  * referenced in generic code
  */
 #define	cpu_swapin(p)			/* nothing */
-#define	cpu_wait(p)			/* nothing */
 #define	cpu_swapout(p)			/* nothing */
 #define	cpu_number()			0
 
Index: dev/ata/atavar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/atavar.h,v
retrieving revision 1.35
diff -u -p -r1.35 atavar.h
--- dev/ata/atavar.h	14 Dec 2003 05:33:29 -0000	1.35
+++ dev/ata/atavar.h	23 Dec 2003 08:10:38 -0000
@@ -236,7 +236,9 @@ struct ata_smart_attr {
 	u_int8_t		id;		/* attribute id number */
 	u_int16_t		flags;
 	u_int8_t		value;		/* attribute value */
-	u_int8_t		vendor_specific[8];
+	u_int8_t		worst;
+	u_int8_t		raw[6];
+	u_int8_t		reserved;
 } __attribute__((packed));
 
 struct ata_smart_attributes {
@@ -271,6 +273,25 @@ struct ata_smart_thresholds {
 	int8_t			checksum;
 } __attribute__((packed));
 
+struct ata_smart_selftest {
+	u_int8_t		number;
+	u_int8_t		status;
+	uint16_t		time_stamp;
+	u_int8_t		failure_check_point;
+	u_int32_t		lba_first_error;
+	u_int8_t		vendor_specific[15];
+} __attribute__((packed));
+
+struct ata_smart_selftestlog {
+	u_int16_t	data_structure_revision;
+	struct ata_smart_selftest log_entries[21];
+	u_int8_t		vendorspecific[2];
+	u_int8_t		mostrecenttest;
+	u_int8_t		reserved[2];
+	u_int8_t		checksum;
+} __attribute__((packed));
+
+#ifdef _KERNEL
 int	wdc_downgrade_mode(struct ata_drive_datas *, int);
 
 struct ataparams;
@@ -282,5 +303,6 @@ int	ata_set_mode(struct ata_drive_datas 
 #define CMD_AGAIN 2
 
 void	ata_dmaerr(struct ata_drive_datas *, int);
+#endif /* _KERNEL */
 
 #endif /* _DEV_ATA_ATAVAR_H_ */
Index: dev/ic/wdcreg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdcreg.h,v
retrieving revision 1.30
diff -u -p -r1.30 wdcreg.h
--- dev/ic/wdcreg.h	3 Dec 2003 12:01:18 -0000	1.30
+++ dev/ic/wdcreg.h	23 Dec 2003 08:10:39 -0000
@@ -167,6 +167,7 @@
 #define	WDSM_ATTR_AUTOSAVE_EN	0xd2
 #define	WDSM_SAVE_ATTR		0xd3
 #define	WDSM_EXEC_OFFL_IMM	0xd4
+#define	WDSM_RD_LOG		0xd5
 #define	WDSM_ENABLE_OPS		0xd8
 #define	WDSM_DISABLE_OPS	0xd9
 #define	WDSM_STATUS		0xda
Index: dev/mca/aha_mca.c
===================================================================
RCS file: /cvsroot/src/sys/dev/mca/aha_mca.c,v
retrieving revision 1.10
diff -u -p -r1.10 aha_mca.c
--- dev/mca/aha_mca.c	2 Oct 2002 16:34:06 -0000	1.10
+++ dev/mca/aha_mca.c	23 Dec 2003 08:10:39 -0000
@@ -94,6 +94,10 @@ aha_mca_probe(parent, match, aux)
 	if (ma->ma_id == MCA_PRODUCT_AHA1640)
 		return (1);
 
+	/* match Buslogic BT-640A with low priority */
+	if (ma->ma_id == MCA_PRODUCT_BT640A)
+		return (10);
+
 	return (0);
 }
 
@@ -110,10 +114,10 @@ aha_mca_attach(parent, self, aux)
 	struct aha_probe_data apd;
 	mca_chipset_tag_t mc = ma->ma_mc;
 	bus_addr_t iobase;
+	const char *model;
 
 	/*
-	 * POS registers differ much between 8003 and 8013, so they are
-	 * divided to two sections.
+	 * POS registers for Adaptec AHA-1640
 	 * 
 	 * POS register 2: (adf pos0)
 	 * 7 6 5 4 3 2 1 0
@@ -141,18 +145,55 @@ aha_mca_attach(parent, self, aux)
 	 *       |       \__ Arbitration lvl (DMA channel)
 	 *       |__________ Fairness On/Off
 	 *
+	 * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+	 *
+	 * POS registers for Buslogic BT-640A
+	 * 
+	 * POS register 2: (adf pos0)
+	 * 7 6 5 4 3 2 1 0
+	 *       \  \__/ \__ enable: 0=adapter disabled, 1=adapter enabled
+	 *        \    \___ IRQ: 8 + X (9-15)
+	 *         \_______ I/O port base add: 0=+0 1=+4
+	 *
+	 *
+	 * POS register 3: (adf pos1)
+	 * 7 6 5 4 3 2 1 0
+	 * \____________/
+	 *              \__ I/O port base: 1=130 2=230 3=330
+	 *
+	 * POS register 4: (adf pos2)
+	 * 7 6 5 4 3 2 1 0
+	 * \___/         \__ Slot Data Width: 0=16 1=32
+	 *     \____________ Adapter SCSI Id
+	 *
+	 * POS register 5: (adf pos3)
+	 * 7 6 5 4 3 2 1 0
+	 *           \___/
+	 *               \__ Arbitration level (0, 1, 3, 4, 5, 6, 7)
 	 */
 
-	apd.sc_irq = (ma->ma_pos[4] & 0x7) + 8;
-	apd.sc_drq = ma->ma_pos[5] & 0xf;
-	apd.sc_scsi_dev = (ma->ma_pos[4] & 0xe0) >> 5;
+	if (ma->ma_id == MCA_PRODUCT_AHA1640) {
+		apd.sc_irq = (ma->ma_pos[4] & 0x7) + 8;
+		apd.sc_drq = ma->ma_pos[5] & 0xf;
+		apd.sc_scsi_dev = (ma->ma_pos[4] & 0xe0) >> 5;
+		iobase = ((ma->ma_pos[3] & 0x03) << 8) + 0x30 +
+			 ((ma->ma_pos[3] & 0x40) >> 4);
+		model = "Adaptec AHA-1640";
+	} else if (ma->ma_id == MCA_PRODUCT_BT640A) {
+		apd.sc_irq = 8 + ((ma->ma_pos[2] & 0x0e) >> 1);
+		apd.sc_drq = ma->ma_pos[5] & 0x7;
+		apd.sc_scsi_dev = (ma->ma_pos[4] & 0xe0) >> 5;
+		iobase = ((ma->ma_pos[3] & 0x3) * 100) + 0x30 + ((ma->ma_pos[2] & 0x10) ? 4 : 0);
+		model = "BusTek BT-604A";
+	} else
+		panic("aha_mca: impossible");
 
-	printf(" slot %d irq %d drq %d: Adaptec AHA-1640 SCSI Adapter\n",
+	printf(" slot %d port %#lx-%#lx irq %d drq %d dev %d: %s\n",
 		ma->ma_slot + 1,
-		apd.sc_irq, apd.sc_drq);
-
-	iobase = ((ma->ma_pos[3] & 0x03) << 8) + 0x30 +
-		 ((ma->ma_pos[3] & 0x40) >> 4);
+		(long) iobase, (long) iobase + AHA_ISA_IOSIZE - 1,
+		apd.sc_irq, apd.sc_drq,
+		apd.sc_scsi_dev,
+		model);
 
 	if (bus_space_map(iot, iobase, AHA_ISA_IOSIZE, 0, &ioh)) {
 		printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
Index: dev/mca/if_we_mca.c
===================================================================
RCS file: /cvsroot/src/sys/dev/mca/if_we_mca.c,v
retrieving revision 1.8
diff -u -p -r1.8 if_we_mca.c
--- dev/mca/if_we_mca.c	2 Oct 2002 16:34:13 -0000	1.8
+++ dev/mca/if_we_mca.c	23 Dec 2003 08:10:39 -0000
@@ -54,8 +54,9 @@
  * Device driver for the Western Digital/SMC 8003 and 8013 series,
  * and the SMC Elite Ultra (8216).
  *
- * Currently only tested with WD8003W/A. Other WD8003-based cards
- * should work without problems, the SMC Elite based ones hopefully too.
+ * Currently only tested with WD8003W/A and EtherCard PLUS Elite 10T/A
+ * (8013WP/A). Other WD8003 and SMC Elite based cards should work
+ * without problems too.
  */
 
 #include <sys/cdefs.h>
@@ -108,7 +109,7 @@ static const struct we_mca_product {
 	{ MCA_PRODUCT_WD_8013EP, "EtherCard PLUS Elite/A (8013EP/A)",
 		WD_ELITE,	WE_TYPE_WD8013EP, "WD8013EP/A" },
 	{ MCA_PRODUCT_WD_8013WP, "EtherCard PLUS Elite 10T/A (8013WP/A)",
-		WD_ELITE,	WE_TYPE_WD8013EP, "WD8013WP/A" }, /* XXX */
+		WD_ELITE,	WE_TYPE_WD8013EP, "WD8013WP/A" },
 	{ MCA_PRODUCT_IBM_WD_2,"IBM PS/2 Adapter/A for Ethernet Networks (UTP)",
 		WD_ELITE, WE_TYPE_WD8013EP, "WD8013WP/A"}, /* XXX */
 	{ MCA_PRODUCT_IBM_WD_T,"IBM PS/2 Adapter/A for Ethernet Networks (BNC)",
@@ -146,12 +147,13 @@ static const struct {
 	{ 0x90,	0xFC0000, 16384 },
 	{ 0x94,	0xFC8000, 16384 },
 	{ 0x98,	0xFD0000, 16384 },
+	{ 0x9A, 0xFD8000, 16384 },
 	{ 0x9C,	0x0C0000, 16384 },
 	{ 0x00,	0x0C0000, 8192 },
 	{ 0x01,	0x0C2000, 8192 },
-	{ 0x10,	0x0C4000, 8192 },
-	{ 0x11,	0x0C6000, 8192 },
-	{ 0x00, 0x000000, 0    },
+	{ 0x02,	0x0C4000, 8192 },
+	{ 0x03,	0x0C6000, 8192 },
+	{ 0, 0, 0 },
 };
 
 	
@@ -201,7 +203,7 @@ we_mca_attach(parent, self, aux)
 	pos5 = mca_conf_read(ma->ma_mc, ma->ma_slot, 5);
 
 	/*
-	 * POS registers differ much between 8003 and 8013, so they are
+	 * POS registers differ a lot between 8003 and 8013, so they are
 	 * divided to two sections.
 	 * 
 	 * 8003: POS register 2: (adf pos0)
@@ -259,7 +261,7 @@ we_mca_attach(parent, self, aux)
 		int i, id;
 
 		iobase = 0x800 + (((pos2 & 0xf0) >> 4) * 0x1000);
-		irq = we_mca_irq[(pos5 & 0x06) >> 2];
+		irq = we_mca_irq[(pos5 & 0x0c) >> 2];
 
 		/* find location of shared mem and it's size */
 		id = (pos3 & 0x9f);
@@ -274,12 +276,20 @@ we_mca_attach(parent, self, aux)
 				
 		maddr = we_mca_elite_mem[i].maddr;
 		sc->mem_size = we_mca_elite_mem[i].memsize;
+printf(": pos2 %d pos3 %d pos5 %d iobase %x irq %d id %d maddr %#x-%#x\n%s",
+	pos2, pos3, pos5, iobase, irq, id, maddr, maddr + sc->mem_size - 1,
+	sc->sc_dev.dv_xname
+	);
 	}
 
 	nict = asict = ma->ma_iot;
 	memt = ma->ma_memt;
 
-	printf(" slot %d irq %d: %s\n", ma->ma_slot + 1, irq, wep->we_name);
+	printf(" slot %d port %#x-%#x mem %#x-%#x irq %d: %s\n",
+		ma->ma_slot + 1,
+		iobase, iobase + WE_NPORTS - 1,
+		maddr, maddr + sc->mem_size - 1,
+		irq, wep->we_name);
 
 	/* Map the device. */
 	if (bus_space_map(asict, iobase, WE_NPORTS, 0, &asich)) {
@@ -304,8 +314,9 @@ we_mca_attach(parent, self, aux)
 	 * Map memory space.
 	 */
 	if (bus_space_map(memt, maddr, sc->mem_size, 0, &memh)) {
-		printf("%s: can't map shared memory\n",
-		    sc->sc_dev.dv_xname);
+		printf("%s: can't map shared memory %#x-%#x\n",
+		    sc->sc_dev.dv_xname,
+		    maddr, maddr + sc->mem_size - 1);
 		return;
 	}
 
Index: dev/pci/pciconf.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pciconf.c,v
retrieving revision 1.22
diff -u -p -r1.22 pciconf.c
--- dev/pci/pciconf.c	2 Dec 2003 16:31:06 -0000	1.22
+++ dev/pci/pciconf.c	23 Dec 2003 08:10:40 -0000
@@ -555,7 +555,7 @@ pci_do_device_query(pciconf_bus_t *pb, p
 			if (pci_conf_debug) {
 				print_tag(pb->pc, tag);
 				printf("Register 0x%x, I/O size %llu\n",
-				    br, pi->size);
+				    br, (long long) pi->size);
 			}
 			pb->niowin++;
 			pb->io_total += size;
@@ -615,7 +615,7 @@ pci_do_device_query(pciconf_bus_t *pb, p
 			if (pci_conf_debug) {
 				print_tag(pb->pc, tag);
 				printf("Register 0x%x, memory size %llu\n",
-				    br, pm->size);
+				    br, (long long) pm->size);
 			}
 			pb->nmemwin++;
 			if (pm->prefetch) {
@@ -647,7 +647,8 @@ pci_do_device_query(pciconf_bus_t *pb, p
 			pm->prefetch = 1;
 			if (pci_conf_debug) {
 				print_tag(pb->pc, tag);
-				printf("Expansion ROM memory size %llu\n", pm->size);
+				printf("Expansion ROM memory size %llu\n",
+				    (long long) pm->size);
 			}
 			pb->nmemwin++;
 			pb->pmem_total += size;
@@ -679,7 +680,7 @@ pci_allocate_range(struct extent *ex, u_
 	if (r) {
 		addr = (u_long) -1;
 		printf("extent_alloc(%p, %llu, %d) returned %d\n",
-		    ex, amt, align, r);
+		    ex, (long long) amt, align, r);
 		extent_print(ex);
 	}
 	return (pcireg_t) addr;
@@ -701,7 +702,7 @@ setup_iowins(pciconf_bus_t *pb)
 		if (pi->address == -1) {
 			print_tag(pd->pc, pd->tag);
 			printf("Failed to allocate PCI I/O space (%llu req)\n",
-			   pi->size);
+			   (long long) pi->size);
 			return -1;
 		}
 		if (!pb->io_32bit && pi->address > 0xFFFF) {
@@ -724,7 +725,8 @@ setup_iowins(pciconf_bus_t *pb)
 		if (pci_conf_debug) {
 			print_tag(pd->pc, pd->tag);
 			printf("Putting %llu I/O bytes @ %#llx (reg %x)\n",
-			    pi->size, pi->address, pi->reg);
+			    (long long) pi->size,
+			    (long long) pi->address, pi->reg);
 		}
 		pci_conf_write(pd->pc, pd->tag, pi->reg,
 		    PCI_MAPREG_IO_ADDR(pi->address) | PCI_MAPREG_TYPE_IO);
@@ -751,7 +753,7 @@ setup_memwins(pciconf_bus_t *pb)
 			print_tag(pd->pc, pd->tag);
 			printf(
 			   "Failed to allocate PCI memory space (%llu req)\n",
-			   pm->size);
+			   (long long) pm->size);
 			return -1;
 		}
 		if (pd->ppb && pm->reg == 0) {
@@ -783,7 +785,8 @@ setup_memwins(pciconf_bus_t *pb)
 				print_tag(pd->pc, pd->tag);
 				printf(
 				    "Putting %llu MEM bytes @ %#llx (reg %x)\n",
-				     pm->size, pm->address, pm->reg);
+				     (long long) pm->size,
+				     (long long) pm->address, pm->reg);
 			}
 			base = pci_conf_read(pd->pc, pd->tag, pm->reg);
 			base = PCI_MAPREG_MEM_ADDR(pm->address) |
@@ -805,7 +808,8 @@ setup_memwins(pciconf_bus_t *pb)
 				print_tag(pd->pc, pd->tag);
 				printf(
 				    "Putting %llu ROM bytes @ %#llx (reg %x)\n",
-				    pm->size, pm->address, pm->reg);
+				    (long long) pm->size,
+				    (long long) pm->address, pm->reg);
 			}
 			base = (pcireg_t) (pm->address | PCI_MAPREG_ROM_ENABLE);
 			pci_conf_write(pd->pc, pd->tag, pm->reg, base);
Index: kern/init_main.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_main.c,v
retrieving revision 1.227
diff -u -p -r1.227 init_main.c
--- kern/init_main.c	14 Nov 2003 07:13:25 -0000	1.227
+++ kern/init_main.c	23 Dec 2003 08:10:41 -0000
@@ -566,10 +566,6 @@ main(void)
 	if (kthread_create1(uvm_pageout, NULL, NULL, "pagedaemon"))
 		panic("fork pagedaemon");
 
-	/* Create the process reaper kernel thread. */
-	if (kthread_create1(reaper, NULL, NULL, "reaper"))
-		panic("fork reaper");
-
 	/* Create the filesystem syncer kernel thread. */
 	if (kthread_create1(sched_sync, NULL, NULL, "ioflush"))
 		panic("fork syncer");
Index: kern/kern_exit.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exit.c,v
retrieving revision 1.130
diff -u -p -r1.130 kern_exit.c
--- kern/kern_exit.c	6 Dec 2003 04:16:33 -0000	1.130
+++ kern/kern_exit.c	23 Dec 2003 08:10:41 -0000
@@ -131,7 +131,7 @@ static void lwp_exit_hook(struct lwp *, 
 static void exit_psignal(struct proc *, struct proc *);
 
 /*
- * Fill in the appropriate signal information, and kill the parent.
+ * Fill in the appropriate signal information, and signal the parent.
  */
 static void
 exit_psignal(struct proc *p, struct proc *pp)
@@ -245,9 +245,15 @@ exit1(struct lwp *l, int rv)
 	p->p_sigctx.ps_sigcheck = 0;
 	timers_free(p, TIMERS_ALL);
 
-	if (sa || (p->p_nlwps > 1))
+	if (sa || (p->p_nlwps > 1)) {
 		exit_lwps(l);
 
+		/*
+		 * Collect thread u-areas.
+		 */
+		uvm_uarea_drain(FALSE);
+	}
+
 #if defined(__HAVE_RAS)
 	ras_purgeall(p);
 #endif
@@ -339,9 +345,9 @@ exit1(struct lwp *l, int rv)
 	 * Give orphaned children to init(8).
 	 */
 	q = LIST_FIRST(&p->p_children);
-	if (q)		/* only need this if any child is S_ZOMB */
+	if (q)		/* only need this if any child is SZOMB */
 		wakeup(initproc);
-	for (; q != 0; q = nq) {
+	for (; q != NULL; q = nq) {
 		nq = LIST_NEXT(q, p_sibling);
 
 		/*
@@ -367,6 +373,38 @@ exit1(struct lwp *l, int rv)
 	proclist_unlock_write(s);
 
 	/*
+	 * Deactivate the address space before the vmspace is
+	 * freed.  Note that we will continue to run on this
+	 * vmspace's context until the switch to the idle process.
+	 */
+	pmap_deactivate(l);
+
+	/*
+	 * Free the VM resources we're still holding on to.
+	 * We must do this from a valid thread because doing
+	 * so may block. This frees vmspace, which we don't
+	 * need anymore. The only remaining lwp is the one
+	 * we run at this moment, nothing runs in userland
+	 * anymore.
+	 */
+	uvm_proc_exit(p);
+
+	/*
+	 * Give machine-dependent code a chance to free any
+	 * MD LWP resources while we can still block. This must be done
+	 * before uvm_lwp_exit(), in case these resources are in the 
+	 * PCB.
+	 * THIS IS LAST BLOCKING OPERATION.
+	 */
+#ifndef __NO_CPU_LWP_FREE
+	cpu_lwp_free(l, 1);
+#endif
+
+	/*
+	 * NOTE: WE ARE NO LONGER ALLOWED TO SLEEP!
+	 */
+
+	/*
 	 * Save exit status and final rusage info, adding in child rusage
 	 * info and self times.
 	 * In order to pick up the time for the current execution, we must
@@ -378,24 +416,33 @@ exit1(struct lwp *l, int rv)
 	ruadd(p->p_ru, &p->p_stats->p_cru);
 
 	/*
-	 * NOTE: WE ARE NO LONGER ALLOWED TO SLEEP!
-	 */
-
-	/*
-	 * Move proc from allproc to zombproc, but do not yet
-	 * wake up the reaper.  We will put the proc on the
-	 * deadproc list later (using the p_dead member), and
-	 * wake up the reaper when we do.
-	 * Changing the state to SDEAD stops it being found by pfind().
+	 * Move proc from allproc to zombproc, it's now ready
+	 * to be collected by parent. Remaining lwp resources
+	 * will be freed in lwp_exit2() once we'd switch to idle
+	 * context.
+	 * Changing the state to SZOMB stops it being found by pfind().
 	 */
 	s = proclist_lock_write();
-	p->p_stat = SDEAD;
-	p->p_nrlwps--;
-	l->l_stat = LSDEAD;
 	LIST_REMOVE(p, p_list);
 	LIST_INSERT_HEAD(&zombproc, p, p_list);
+	p->p_stat = SZOMB;
+
 	LIST_REMOVE(l, l_list);
-	l->l_flag |= L_DETACHED;
+	l->l_flag |= L_DETACHED|L_PROCEXIT;	/* detached from proc too */
+	l->l_stat = LSDEAD;
+
+	p->p_nrlwps--;
+	p->p_nlwps--;
+
+	/* Put in front of parent's sibling list for parent to collect it */
+	q = p->p_pptr;
+	q->p_nstopchild++;
+	if (LIST_FIRST(&q->p_children) != p) {
+		/* Put child where it can be found quickly */
+		LIST_REMOVE(p, p_sibling);
+		LIST_INSERT_HEAD(&q->p_children, p, p_sibling);
+	}
+
 	proclist_unlock_write(s);
 
 	/*
@@ -422,6 +469,7 @@ exit1(struct lwp *l, int rv)
 	if (p->p_pptr->p_flag & P_NOCLDWAIT) {
 		struct proc *pp = p->p_pptr;
 		proc_reparent(p, initproc);
+
 		/*
 		 * If this was the last child of our parent, notify
 		 * parent, so in case he was wait(2)ing, he will
@@ -431,6 +479,11 @@ exit1(struct lwp *l, int rv)
 			wakeup(pp);
 	}
 
+	/* Wake up the parent so it can get exit status. */
+	if ((p->p_flag & P_FSTRACE) == 0 && p->p_exitsig != 0)
+		exit_psignal(p, p->p_pptr);
+	wakeup(p->p_pptr);
+
 	/*
 	 * Release the process's signal state.
 	 */
@@ -454,18 +507,23 @@ exit1(struct lwp *l, int rv)
 	/* This process no longer needs to hold the kernel lock. */
 	KERNEL_PROC_UNLOCK(l);
 
+#ifdef DEBUG
+	/* Nothing should use the process link anymore */
+	l->l_proc = NULL;
+#endif
+
 	/*
 	 * Finally, call machine-dependent code to switch to a new
 	 * context (possibly the idle context).  Once we are no longer
-	 * using the dead process's vmspace and stack, exit2() will be
-	 * called to schedule those resources to be released by the
-	 * reaper thread.
+	 * using the dead lwp's stack, lwp_exit2() will be called
+	 * to arrange for the resources to be released.
 	 *
 	 * Note that cpu_exit() will end with a call equivalent to
 	 * cpu_switch(), finishing our execution (pun intended).
 	 */
 
-	cpu_exit(l, 1);
+	uvmexp.swtch++;
+	cpu_exit(l);
 }
 
 void
@@ -545,123 +603,6 @@ lwp_exit_hook(struct lwp *l, void *arg)
 	lwp_exit(l);
 }
 
-/*
- * We are called from cpu_exit() once it is safe to schedule the
- * dead process's resources to be freed (i.e., once we've switched to
- * the idle PCB for the current CPU).
- *
- * NOTE: One must be careful with locking in this routine.  It's
- * called from a critical section in machine-dependent code, so
- * we should refrain from changing any interrupt state.
- *
- * We lock the deadproc list (a spin lock), place the proc on that
- * list (using the p_dead member), and wake up the reaper.
- */
-void
-exit2(struct lwp *l)
-{
-	struct proc *p = l->l_proc;
-
-	simple_lock(&deadproc_slock);
-	SLIST_INSERT_HEAD(&deadprocs, p, p_dead);
-	simple_unlock(&deadproc_slock);
-
-	/* lwp_exit2() will wake up deadproc for us. */
-	lwp_exit2(l);
-}
-
-/*
- * Process reaper.  This is run by a kernel thread to free the resources
- * of a dead process.  Once the resources are free, the process becomes
- * a zombie, and the parent is allowed to read the undead's status.
- */
-void
-reaper(void *arg)
-{
-	struct proc *p, *parent;
-	struct lwp *l;
-
-	KERNEL_PROC_UNLOCK(curlwp);
-
-	for (;;) {
-		simple_lock(&deadproc_slock);
-		p = SLIST_FIRST(&deadprocs);
-		l = LIST_FIRST(&deadlwp);
-		if (p == NULL && l == NULL) {
-			/* No work for us; go to sleep until someone exits. */
-			(void) ltsleep(&deadprocs, PVM|PNORELOCK,
-			    "reaper", 0, &deadproc_slock);
-			continue;
-		}
-
-		if (l != NULL ) {
-			p = l->l_proc;
-
-			/* Remove lwp from the deadlwp list. */
-			LIST_REMOVE(l, l_list);
-			simple_unlock(&deadproc_slock);
-			KERNEL_PROC_LOCK(curlwp);
-			
-			/*
-			 * Give machine-dependent code a chance to free any
-			 * resources it couldn't free while still running on
-			 * that process's context.  This must be done before
-			 * uvm_lwp_exit(), in case these resources are in the 
-			 * PCB.
-			 */
-			cpu_wait(l);
-
-			/*
-			 * Free the VM resources we're still holding on to.
-			 */
-			uvm_lwp_exit(l);
-
-			l->l_stat = LSZOMB;
-			if (l->l_flag & L_DETACHED) {
-				/* Nobody waits for detached LWPs. */
-				LIST_REMOVE(l, l_sibling);
-				p->p_nlwps--;
-				pool_put(&lwp_pool, l);
-			} else {
-				p->p_nzlwps++;
-				wakeup(&p->p_nlwps);
-			}
-			/* XXXNJW where should this be with respect to 
-			 * the wakeup() above? */
-			KERNEL_PROC_UNLOCK(curlwp);
-		} else {
-			/* Remove proc from the deadproc list. */
-			SLIST_REMOVE_HEAD(&deadprocs, p_dead);
-			simple_unlock(&deadproc_slock);
-			KERNEL_PROC_LOCK(curlwp);
-
-			/*
-			 * Free the VM resources we're still holding on to.
-			 * We must do this from a valid thread because doing
-			 * so may block.
-			 */
-			uvm_proc_exit(p);
-			
-			/* Process is now a true zombie. */
-			p->p_stat = SZOMB;
-			parent = p->p_pptr;
-			parent->p_nstopchild++;
-			if (LIST_FIRST(&parent->p_children) != p) {
-				/* Put child where it can be found quickly */
-				LIST_REMOVE(p, p_sibling);
-				LIST_INSERT_HEAD(&parent->p_children,
-						p, p_sibling);
-			}
-			
-			/* Wake up the parent so it can get exit status. */
-			if ((p->p_flag & P_FSTRACE) == 0 && p->p_exitsig != 0)
-				exit_psignal(p, p->p_pptr);
-			KERNEL_PROC_UNLOCK(curlwp);
-			wakeup(p->p_pptr);
-		}
-	}
-}
-
 int
 sys_wait4(struct lwp *l, void *v, register_t *retval)
 {
@@ -690,6 +631,11 @@ sys_wait4(struct lwp *l, void *v, regist
 		return 0;
 	}
 
+	/*
+	 * Collect child u-areas.
+	 */
+	uvm_uarea_drain(FALSE);
+
 	retval[0] = child->p_pid;
 
 	if (child->p_stat == SZOMB) {
Index: kern/kern_lwp.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_lwp.c,v
retrieving revision 1.15
diff -u -p -r1.15 kern_lwp.c
--- kern/kern_lwp.c	4 Nov 2003 10:33:15 -0000	1.15
+++ kern/kern_lwp.c	23 Dec 2003 08:10:42 -0000
@@ -57,8 +57,6 @@ __KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v
 #include <uvm/uvm_extern.h>
 
 struct lwplist alllwp;
-struct lwplist deadlwp;
-struct lwplist zomblwp;
 
 #define LWP_DEBUG
 
@@ -369,9 +367,9 @@ lwp_wait1(struct lwp *l, lwpid_t lid, lw
 
 	struct proc *p = l->l_proc;
 	struct lwp *l2, *l3;
-	int nfound, error, s, wpri;
-	static char waitstr1[] = "lwpwait";
-	static char waitstr2[] = "lwpwait2";
+	int nfound, error, wpri;
+	static const char waitstr1[] = "lwpwait";
+	static const char waitstr2[] = "lwpwait2";
 
 	DPRINTF(("lwp_wait1: %d.%d waiting for %d.\n",
 	    p->p_pid, l->l_lid, lid));
@@ -393,10 +391,6 @@ lwp_wait1(struct lwp *l, lwpid_t lid, lw
 			if (departed)
 				*departed = l2->l_lid;
 
-			s = proclist_lock_write();
-			LIST_REMOVE(l2, l_zlist); /* off zomblwp */
-			proclist_unlock_write(s);
-
 			simple_lock(&p->p_lock);
 			LIST_REMOVE(l2, l_sibling);
 			p->p_nlwps--;
@@ -544,17 +538,18 @@ lwp_exit(struct lwp *l)
 		DPRINTF(("lwp_exit: %d.%d calling exit1()\n",
 		    p->p_pid, l->l_lid));
 		exit1(l, 0);
+		/* NOTREACHED */
 	}
 
 	s = proclist_lock_write();
 	LIST_REMOVE(l, l_list);
-	if ((l->l_flag & L_DETACHED) == 0) {
-		DPRINTF(("lwp_exit: %d.%d going on zombie list\n", p->p_pid,
-		    l->l_lid));
-		LIST_INSERT_HEAD(&zomblwp, l, l_zlist);
-	}
 	proclist_unlock_write(s);
 
+	/* Free MD LWP resources */
+#ifndef __NO_CPU_LWP_FREE
+	cpu_lwp_free(l, 0);
+#endif
+
 	simple_lock(&p->p_lock);
 	p->p_nrlwps--;
 	simple_unlock(&p->p_lock);
@@ -565,20 +560,45 @@ lwp_exit(struct lwp *l)
 	KERNEL_PROC_UNLOCK(l);
 
 	/* cpu_exit() will not return */
-	cpu_exit(l, 0);
+	cpu_exit(l);
 
 }
 
-
+/*
+ * We are called from cpu_exit() once it is safe to schedule the
+ * dead process's resources to be freed (i.e., once we've switched to
+ * the idle PCB for the current CPU).
+ *
+ * NOTE: One must be careful with locking in this routine.  It's
+ * called from a critical section in machine-dependent code, so
+ * we should refrain from changing any interrupt state.
+ */
 void
 lwp_exit2(struct lwp *l)
 {
+	struct proc *p;
 
-	simple_lock(&deadproc_slock);
-	LIST_INSERT_HEAD(&deadlwp, l, l_list);
-	simple_unlock(&deadproc_slock);
+	/*
+	 * Free the VM resources we're still holding on to.
+	 */
+	uvm_lwp_exit(l);
+
+	l->l_stat = LSZOMB;
+	if (l->l_flag & L_DETACHED) {
+		/* Nobody waits for detached LWPs. */
+		LIST_REMOVE(l, l_sibling);
+
+		if ((l->l_flag & L_PROCEXIT) == 0) {
+			p = l->l_proc;
+			p->p_nlwps--;
+		}
 
-	wakeup(&deadprocs);
+		pool_put(&lwp_pool, l);
+	} else {
+		p = l->l_proc;
+		p->p_nzlwps++;
+		wakeup(&p->p_nlwps);
+	}
 }
 
 /*
Index: kern/kern_proc.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_proc.c,v
retrieving revision 1.69
diff -u -p -r1.69 kern_proc.c
--- kern/kern_proc.c	17 Nov 2003 22:52:09 -0000	1.69
+++ kern/kern_proc.c	23 Dec 2003 08:10:42 -0000
@@ -134,17 +134,6 @@ struct proclist zombproc;	/* resources h
 struct lock proclist_lock;
 
 /*
- * List of processes that has called exit, but need to be reaped.
- * Locking of this proclist is special; it's accessed in a
- * critical section of process exit, and thus locking it can't
- * modify interrupt state.
- * We use a simple spin lock for this proclist.
- * Processes on this proclist are also on zombproc.
- */
-struct simplelock deadproc_slock;
-struct deadprocs deadprocs = SLIST_HEAD_INITIALIZER(deadprocs);
-
-/*
  * pid to proc lookup is done by indexing the pid_table array. 
  * Since pid numbers are only allocated when an empty slot
  * has been found, there is no need to search any lists ever.
@@ -229,8 +218,6 @@ procinit(void)
 
 	spinlockinit(&proclist_lock, "proclk", 0);
 
-	simple_lock_init(&deadproc_slock);
-
 	pid_table = malloc(INITIAL_PID_TABLE_SIZE * sizeof *pid_table,
 			    M_PROC, M_WAITOK);
 	/* Set free list running through table...
@@ -249,8 +236,6 @@ procinit(void)
 #undef LINK_EMPTY
 
 	LIST_INIT(&alllwp);
-	LIST_INIT(&deadlwp);
-	LIST_INIT(&zomblwp);
 
 	uihashtbl =
 	    hashinit(maxproc / 16, HASH_LIST, M_PROC, M_WAITOK, &uihash);
Index: sys/lwp.h
===================================================================
RCS file: /cvsroot/src/sys/sys/lwp.h,v
retrieving revision 1.14
diff -u -p -r1.14 lwp.h
--- sys/lwp.h	17 Nov 2003 22:52:09 -0000	1.14
+++ sys/lwp.h	23 Dec 2003 08:10:43 -0000
@@ -100,8 +100,6 @@ struct	lwp {
 LIST_HEAD(lwplist, lwp);		/* a list of LWPs */
 
 extern struct lwplist alllwp;		/* List of all LWPs. */
-extern struct lwplist deadlwp;		/* */
-extern struct lwplist zomblwp;
 
 extern struct pool lwp_pool;		/* memory pool for LWPs */
 extern struct pool lwp_uc_pool;		/* memory pool for LWP startup args */
@@ -113,6 +111,7 @@ extern struct lwp lwp0;			/* LWP for pro
 #define	L_SELECT	0x00040	/* Selecting; wakeup/waiting danger. */
 #define	L_SINTR		0x00080	/* Sleep is interruptible. */
 #define	L_TIMEOUT	0x00400	/* Timing out during sleep. */
+#define	L_PROCEXIT	0x00800 /* In process exit, l_proc no longer valid */
 #define	L_BIGLOCK	0x80000	/* LWP needs kernel "big lock" to run */
 #define	L_SA		0x100000 /* Scheduler activations LWP */
 #define	L_SA_UPCALL	0x200000 /* SA upcall is pending */
Index: sys/proc.h
===================================================================
RCS file: /cvsroot/src/sys/sys/proc.h,v
retrieving revision 1.182
diff -u -p -r1.182 proc.h
--- sys/proc.h	6 Dec 2003 04:16:33 -0000	1.182
+++ sys/proc.h	23 Dec 2003 08:10:43 -0000
@@ -174,7 +174,7 @@ struct proc {
 	char		p_pad1[3];
 
 	pid_t		p_pid;		/* Process identifier. */
-	SLIST_ENTRY(proc) p_dead;	/* Processes waiting for reaper */
+	SLIST_ENTRY(proc) p_nu3;	/* unused: was link to deadproc list */
 	LIST_ENTRY(proc) p_pglist;	/* l: List of processes in pgrp. */
 	struct proc 	*p_pptr;	/* l: Pointer to parent process. */
 	LIST_ENTRY(proc) p_sibling;	/* l: List of sibling processes. */
@@ -447,9 +447,7 @@ int	ltsleep(const void *, int, const cha
 	    __volatile struct simplelock *);
 void	wakeup(const void *);
 void	wakeup_one(const void *);
-void	reaper(void *);
 void	exit1(struct lwp *, int);
-void	exit2(struct lwp *);
 int	find_stopped_child(struct proc *, pid_t, int, struct proc **);
 struct proc *proc_alloc(void);
 void	proc0_insert(struct proc *, struct lwp *, struct pgrp *, struct session *);
@@ -464,15 +462,10 @@ int	pgid_in_session(struct proc *, pid_t
 #ifndef cpu_idle
 void	cpu_idle(void);
 #endif
-void	cpu_exit(struct lwp *, int);
+void	cpu_exit(struct lwp *);
 void	cpu_lwp_fork(struct lwp *, struct lwp *, void *, size_t,
 	    void (*)(void *), void *);
-
-		/*
-		 * XXX: use __P() to allow ports to have as a #define.
-		 * XXX: we need a better way to solve this.
-		 */
-void	cpu_wait __P((struct lwp *));
+void	cpu_lwp_free(struct lwp *, int);
 
 void	child_return(void *);
 
Index: ufs/ufs/ufs_readwrite.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_readwrite.c,v
retrieving revision 1.55
diff -u -p -r1.55 ufs_readwrite.c
--- ufs/ufs/ufs_readwrite.c	7 Aug 2003 16:34:46 -0000	1.55
+++ ufs/ufs/ufs_readwrite.c	23 Dec 2003 08:10:43 -0000
@@ -467,7 +467,8 @@ WRITE(void *v)
 #else
 		if (ioflag & IO_SYNC)
 			(void)bwrite(bp);
-		else if (xfersize + blkoffset == fs->fs_bsize)
+		else if (xfersize + blkoffset == fs->fs_bsize
+		    && (vp->v_mount->mnt_flag & MNT_ASYNC) == 0)
 			bawrite(bp);
 		else
 			bdwrite(bp);
Index: uvm/uvm_extern.h
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_extern.h,v
retrieving revision 1.87
diff -u -p -r1.87 uvm_extern.h
--- uvm/uvm_extern.h	18 Dec 2003 15:02:04 -0000	1.87
+++ uvm/uvm_extern.h	23 Dec 2003 08:10:44 -0000
@@ -576,7 +576,7 @@ boolean_t		uvm_kernacc __P((caddr_t, siz
 __dead void		uvm_scheduler __P((void)) __attribute__((noreturn));
 void			uvm_swapin __P((struct lwp *));
 boolean_t		uvm_uarea_alloc(vaddr_t *);
-void			uvm_uarea_free(vaddr_t);
+void			uvm_uarea_drain(boolean_t);
 int			uvm_vslock __P((struct proc *, caddr_t, size_t,
 			    vm_prot_t));
 void			uvm_vsunlock __P((struct proc *, caddr_t, size_t));
Index: uvm/uvm_glue.c
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_glue.c,v
retrieving revision 1.73
diff -u -p -r1.73 uvm_glue.c
--- uvm/uvm_glue.c	13 Nov 2003 03:09:30 -0000	1.73
+++ uvm/uvm_glue.c	23 Dec 2003 08:10:44 -0000
@@ -99,6 +99,8 @@ void *uvm_uareas;
 int uvm_nuarea;
 struct simplelock uvm_uareas_slock = SIMPLELOCK_INITIALIZER;
 
+static void uvm_uarea_free(vaddr_t);
+
 /*
  * XXXCDC: do these really belong here?
  */
@@ -350,8 +352,8 @@ uvm_uarea_alloc(vaddr_t *uaddrp)
 #endif
 
 	simple_lock(&uvm_uareas_slock);
-	uaddr = (vaddr_t)uvm_uareas;
-	if (uaddr) {
+	if (uvm_nuarea > 0) {
+		uaddr = (vaddr_t)uvm_uareas;
 		uvm_uareas = *(void **)uvm_uareas;
 		uvm_nuarea--;
 		simple_unlock(&uvm_uareas_slock);
@@ -365,23 +367,43 @@ uvm_uarea_alloc(vaddr_t *uaddrp)
 }
 
 /*
- * uvm_uarea_free: free a u-area
+ * uvm_uarea_free: free a u-area; never blocks
  */
 
-void
+static void
 uvm_uarea_free(vaddr_t uaddr)
 {
+	simple_lock(&uvm_uareas_slock);
+	*(void **)uaddr = uvm_uareas;
+	uvm_uareas = (void *)uaddr;
+	uvm_nuarea++;
+	simple_unlock(&uvm_uareas_slock);
+}
+
+/*
+ * uvm_uarea_drain: return memory of u-areas over limit
+ * back to system
+ */
+
+void
+uvm_uarea_drain(boolean_t empty)
+{
+	int leave = empty ? 0 : UVM_NUAREA_MAX;
+	vaddr_t uaddr;
+
+	if (uvm_nuarea <= leave)
+		return;
 
 	simple_lock(&uvm_uareas_slock);
-	if (uvm_nuarea < UVM_NUAREA_MAX) {
-		*(void **)uaddr = uvm_uareas;
-		uvm_uareas = (void *)uaddr;
-		uvm_nuarea++;
-		simple_unlock(&uvm_uareas_slock);
-	} else {
+	while(uvm_nuarea > leave) {
+		uaddr = (vaddr_t)uvm_uareas;
+		uvm_uareas = *(void **)uvm_uareas;
+		uvm_nuarea--;
 		simple_unlock(&uvm_uareas_slock);
 		uvm_km_free(kernel_map, uaddr, USPACE);
+		simple_lock(&uvm_uareas_slock);
 	}
+	simple_unlock(&uvm_uareas_slock);
 }
 
 /*
Index: uvm/uvm_pdaemon.c
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_pdaemon.c,v
retrieving revision 1.55
diff -u -p -r1.55 uvm_pdaemon.c
--- uvm/uvm_pdaemon.c	26 Sep 2003 04:03:39 -0000	1.55
+++ uvm/uvm_pdaemon.c	23 Dec 2003 08:10:45 -0000
@@ -274,6 +274,12 @@ uvm_pageout(void *arg)
 		 */
 
 		pool_drain(0);
+
+		/*
+		 * free any cached u-areas we don't need
+		 */
+		uvm_uarea_drain(TRUE);
+
 	}
 	/*NOTREACHED*/
 }
