]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/hosts.c
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
[linux-2.6-omap-h63xx.git] / drivers / scsi / hosts.c
index 6828ca305c2a36852c02ce49131c4e796563ac04..85503fad789a099d4d69a2fb6cda0db36ba256be 100644 (file)
@@ -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>
@@ -127,30 +128,16 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
 }
 EXPORT_SYMBOL(scsi_host_set_state);
 
-/**
- * scsi_host_cancel - cancel outstanding IO to this host
- * @shost:     pointer to struct Scsi_Host
- * recovery:   recovery requested to run.
- **/
-static void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
-{
-       struct scsi_device *sdev;
-
-       scsi_host_set_state(shost, SHOST_CANCEL);
-       shost_for_each_device(sdev, shost) {
-               scsi_device_cancel(sdev, recovery);
-       }
-       wait_event(shost->host_wait, (shost->shost_state != SHOST_RECOVERY));
-}
-
 /**
  * scsi_remove_host - remove a scsi host
  * @shost:     a pointer to a scsi host to remove
  **/
 void scsi_remove_host(struct Scsi_Host *shost)
 {
+       down(&shost->scan_mutex);
+       scsi_host_set_state(shost, SHOST_CANCEL);
+       up(&shost->scan_mutex);
        scsi_forget_host(shost);
-       scsi_host_cancel(shost, 0);
        scsi_proc_host_rm(shost);
 
        scsi_host_set_state(shost, SHOST_DEL);
@@ -239,15 +226,8 @@ static void scsi_host_dev_release(struct device *dev)
        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);
 
@@ -277,7 +257,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
 {
        struct Scsi_Host *shost;
        int gfp_mask = GFP_KERNEL, rval;
-       DECLARE_COMPLETION(complete);
 
        if (sht->unchecked_isa_dma && privsize)
                gfp_mask |= __GFP_DMA;
@@ -383,12 +362,12 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
        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;