[SCSI] switch EH thread startup to the kthread API

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 8640ad1..85503fa 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/blkdev.h>
 #include <linux/kernel.h>
+#include <linux/kthread.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/init.h>
@@ -225,15 +226,8 @@
 	struct Scsi_Host *shost = dev_to_shost(dev);
 	struct device *parent = dev->parent;
 
-	if (shost->ehandler) {
-		DECLARE_COMPLETION(sem);
-		shost->eh_notify = &sem;
-		shost->eh_kill = 1;
-		up(shost->eh_wait);
-		wait_for_completion(&sem);
-		shost->eh_notify = NULL;
-	}
-
+	if (shost->ehandler)
+		kthread_stop(shost->ehandler);
 	if (shost->work_q)
 		destroy_workqueue(shost->work_q);
 
@@ -263,7 +257,6 @@
 {
 	struct Scsi_Host *shost;
 	int gfp_mask = GFP_KERNEL, rval;
-	DECLARE_COMPLETION(complete);
 
 	if (sht->unchecked_isa_dma && privsize)
 		gfp_mask |= __GFP_DMA;
@@ -369,12 +362,12 @@
 	snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d",
 		  shost->host_no);
 
-	shost->eh_notify = &complete;
-	rval = kernel_thread(scsi_error_handler, shost, 0);
-	if (rval < 0)
+	shost->ehandler = kthread_run(scsi_error_handler, shost,
+			"scsi_eh_%d", shost->host_no);
+	if (IS_ERR(shost->ehandler)) {
+		rval = PTR_ERR(shost->ehandler);
 		goto fail_destroy_freelist;
-	wait_for_completion(&complete);
-	shost->eh_notify = NULL;
+	}
 
 	scsi_proc_hostdir_add(shost->hostt);
 	return shost;
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 688bce7..ebe74cc 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
+#include <linux/kthread.h>
 #include <linux/interrupt.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
@@ -1585,16 +1586,8 @@
 	int rtn;
 	DECLARE_MUTEX_LOCKED(sem);
 
-	/*
-	 *    Flush resources
-	 */
-
-	daemonize("scsi_eh_%d", shost->host_no);
-
 	current->flags |= PF_NOFREEZE;
-
 	shost->eh_wait = &sem;
-	shost->ehandler = current;
 
 	/*
 	 * Wake up the thread that created us.
@@ -1602,8 +1595,6 @@
 	SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of"
 					  " scsi_eh_%d\n",shost->host_no));
 
-	complete(shost->eh_notify);
-
 	while (1) {
 		/*
 		 * If we get a signal, it means we are supposed to go
@@ -1624,7 +1615,7 @@
 		 * semaphores isn't unreasonable.
 		 */
 		down_interruptible(&sem);
-		if (shost->eh_kill)
+		if (kthread_should_stop())
 			break;
 
 		SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
@@ -1663,22 +1654,6 @@
 	 * Make sure that nobody tries to wake us up again.
 	 */
 	shost->eh_wait = NULL;
-
-	/*
-	 * Knock this down too.  From this point on, the host is flying
-	 * without a pilot.  If this is because the module is being unloaded,
-	 * that's fine.  If the user sent a signal to this thing, we are
-	 * potentially in real danger.
-	 */
-	shost->eh_active = 0;
-	shost->ehandler = NULL;
-
-	/*
-	 * If anyone is waiting for us to exit (i.e. someone trying to unload
-	 * a driver), then wake up that process to let them know we are on
-	 * the way out the door.
-	 */
-	complete_and_exit(shost->eh_notify, 0);
 	return 0;
 }
 
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index ac1b612..916144b 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -467,12 +467,10 @@
 	struct task_struct    * ehandler;  /* Error recovery thread. */
 	struct semaphore      * eh_wait;   /* The error recovery thread waits
 					      on this. */
-	struct completion     * eh_notify; /* wait for eh to begin or end */
 	struct semaphore      * eh_action; /* Wait for specific actions on the
                                           host. */
 	unsigned int            eh_active:1; /* Indicates the eh thread is awake and active if
                                           this is true. */
-	unsigned int            eh_kill:1; /* set when killing the eh thread */
 	wait_queue_head_t       host_wait;
 	struct scsi_host_template *hostt;
 	struct scsi_transport_template *transportt;