Merge commit 'v2.6.26-rc9' into cpus4096
[cascardo/linux.git] / drivers / scsi / hosts.c
index 63bed62..c6457bf 100644 (file)
@@ -199,9 +199,13 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
        if (!shost->can_queue) {
                printk(KERN_ERR "%s: can_queue = 0 no longer supported\n",
                                sht->name);
-               goto out;
+               goto fail;
        }
 
+       error = scsi_setup_command_freelist(shost);
+       if (error)
+               goto fail;
+
        if (!shost->shost_gendev.parent)
                shost->shost_gendev.parent = dev ? dev : &platform_bus;
 
@@ -255,6 +259,8 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
  out_del_gendev:
        device_del(&shost->shost_gendev);
  out:
+       scsi_destroy_command_freelist(shost);
+ fail:
        return error;
 }
 EXPORT_SYMBOL(scsi_add_host);
@@ -381,10 +387,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
        else
                shost->dma_boundary = 0xffffffff;
 
-       rval = scsi_setup_command_freelist(shost);
-       if (rval)
-               goto fail_kfree;
-
        device_initialize(&shost->shost_gendev);
        snprintf(shost->shost_gendev.bus_id, BUS_ID_SIZE, "host%d",
                shost->host_no);
@@ -398,19 +400,18 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
        shost->shost_dev.class = &shost_class;
        snprintf(shost->shost_dev.bus_id, BUS_ID_SIZE, "host%d",
                 shost->host_no);
+       shost->shost_dev.groups = scsi_sysfs_shost_attr_groups;
 
        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;
+               goto fail_kfree;
        }
 
        scsi_proc_hostdir_add(shost->hostt);
        return shost;
 
- fail_destroy_freelist:
-       scsi_destroy_command_freelist(shost);
  fail_kfree:
        kfree(shost);
        return NULL;
@@ -455,6 +456,10 @@ static int __scsi_host_match(struct device *dev, void *data)
  *
  * Return value:
  *     A pointer to located Scsi_Host or NULL.
+ *
+ *     The caller must do a scsi_host_put() to drop the reference
+ *     that scsi_host_get() took. The put_device() below dropped
+ *     the reference from class_find_device().
  **/
 struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
 {
@@ -462,9 +467,10 @@ struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
        struct Scsi_Host *shost = ERR_PTR(-ENXIO);
 
        cdev = class_find_device(&shost_class, &hostnum, __scsi_host_match);
-       if (cdev)
+       if (cdev) {
                shost = scsi_host_get(class_to_shost(cdev));
-
+               put_device(cdev);
+       }
        return shost;
 }
 EXPORT_SYMBOL(scsi_host_lookup);