X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fscsi%2Fhosts.c;h=fed0b02ebc1d35ecba7c19b534956edf939eb7a6;hb=04489eeb02a40bc15029886cef7285ada3ab0de6;hp=c264a8c5f01e1f362284476f1513a38f38b56ed1;hpb=f838bad1b3be8ca0c785ee0e0c570dfda74cf377;p=linux-2.6 diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index c264a8c5f0..fed0b02ebc 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -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; @@ -228,8 +232,8 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev) } if (shost->transportt->create_work_queue) { - snprintf(shost->work_q_name, KOBJ_NAME_LEN, "scsi_wq_%d", - shost->host_no); + snprintf(shost->work_q_name, sizeof(shost->work_q_name), + "scsi_wq_%d", shost->host_no); shost->work_q = create_singlethread_workqueue( shost->work_q_name); if (!shost->work_q) { @@ -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); @@ -284,6 +290,11 @@ static void scsi_host_dev_release(struct device *dev) kfree(shost); } +static struct device_type scsi_host_type = { + .name = "scsi_host", + .release = scsi_host_dev_release, +}; + /** * scsi_host_alloc - register a scsi host adapter instance. * @sht: pointer to scsi host template @@ -376,33 +387,31 @@ 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); - shost->shost_gendev.release = scsi_host_dev_release; +#ifndef CONFIG_SYSFS_DEPRECATED + shost->shost_gendev.bus = &scsi_bus_type; +#endif + shost->shost_gendev.type = &scsi_host_type; device_initialize(&shost->shost_dev); shost->shost_dev.parent = &shost->shost_gendev; 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; @@ -447,16 +456,22 @@ 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) { struct device *cdev; struct Scsi_Host *shost = ERR_PTR(-ENXIO); - cdev = class_find_device(&shost_class, &hostnum, __scsi_host_match); - if (cdev) + cdev = class_find_device(&shost_class, NULL, &hostnum, + __scsi_host_match); + if (cdev) { shost = scsi_host_get(class_to_shost(cdev)); - + put_device(cdev); + } return shost; } EXPORT_SYMBOL(scsi_host_lookup); @@ -496,7 +511,7 @@ void scsi_exit_hosts(void) int scsi_is_host_device(const struct device *dev) { - return dev->release == scsi_host_dev_release; + return dev->type == &scsi_host_type; } EXPORT_SYMBOL(scsi_is_host_device);