From: Andrew Morton Signed-off-by: Andrew Morton --- drivers/scsi/scsi_scan.c | 65 +++++++++++++------------- drivers/scsi/scsi_sysfs.c | 86 ++++++----------------------------- include/scsi/scsi_device.h | 8 --- 3 files changed, 50 insertions(+), 109 deletions(-) diff -puN drivers/scsi/scsi_scan.c~revert-resurrect-sdev drivers/scsi/scsi_scan.c --- a/drivers/scsi/scsi_scan.c~revert-resurrect-sdev +++ a/drivers/scsi/scsi_scan.c @@ -300,7 +300,8 @@ static struct scsi_device *scsi_alloc_sd return sdev; out_device_destroy: - scsi_destroy_device(sdev); + transport_destroy_device(&sdev->sdev_gendev); + put_device(&sdev->sdev_gendev); out: if (display_failure_msg) printk(ALLOC_FAILURE_MSG, __FUNCTION__); @@ -713,8 +714,6 @@ static int scsi_probe_lun(struct scsi_de static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, int *bflags, int async) { - int ret; - /* * XXX do not save the inquiry, since it can change underneath us, * save just vendor/model/rev. @@ -878,6 +877,10 @@ static int scsi_add_lun(struct scsi_devi if (*bflags & BLIST_USE_10_BYTE_MS) sdev->use_10_for_ms = 1; + /* set the device running here so that slave configure + * may do I/O */ + scsi_device_set_state(sdev, SDEV_RUNNING); + if (*bflags & BLIST_MS_192_BYTES_FOR_3F) sdev->use_192_bytes_for_3f = 1; @@ -887,18 +890,21 @@ static int scsi_add_lun(struct scsi_devi if (*bflags & BLIST_RETRY_HWERROR) sdev->retry_hwerror = 1; - ret = scsi_configure_device(sdev); - if (ret) { - /* - * if LLDD reports slave not present, don't clutter - * console with alloc failure messages - */ - if (ret != -ENXIO) { - sdev_printk(KERN_ERR, sdev, - "failed to configure device\n"); + transport_configure_device(&sdev->sdev_gendev); + + if (sdev->host->hostt->slave_configure) { + int ret = sdev->host->hostt->slave_configure(sdev); + if (ret) { + /* + * if LLDD reports slave not present, don't clutter + * console with alloc failure messages + */ + if (ret != -ENXIO) { + sdev_printk(KERN_ERR, sdev, + "failed to configure device\n"); + } + return SCSI_SCAN_NO_RESPONSE; } - scsi_destroy_device(sdev); - return SCSI_SCAN_NO_RESPONSE; } /* @@ -912,6 +918,15 @@ static int scsi_add_lun(struct scsi_devi return SCSI_SCAN_LUN_PRESENT; } +static inline void scsi_destroy_sdev(struct scsi_device *sdev) +{ + scsi_device_set_state(sdev, SDEV_DEL); + if (sdev->host->hostt->slave_destroy) + sdev->host->hostt->slave_destroy(sdev); + transport_destroy_device(&sdev->sdev_gendev); + put_device(&sdev->sdev_gendev); +} + #ifdef CONFIG_SCSI_LOGGING /** * scsi_inq_str - print INQUIRY data from min to max index, @@ -973,10 +988,6 @@ static int scsi_probe_and_add_lun(struct */ sdev = scsi_device_lookup_by_target(starget, lun); if (sdev) { - if (scsi_resurrect_device(sdev)) { - scsi_device_put(sdev); - return SCSI_SCAN_NO_RESPONSE; - } if (rescan || sdev->sdev_state != SDEV_CREATED) { SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: device exists on %s\n", @@ -1087,12 +1098,11 @@ static int scsi_probe_and_add_lun(struct *sdevp = sdev; } else { __scsi_remove_device(sdev); - scsi_destroy_device(sdev); res = SCSI_SCAN_NO_RESPONSE; } } } else - scsi_destroy_device(sdev); + scsi_destroy_sdev(sdev); out: return res; } @@ -1294,9 +1304,6 @@ static int scsi_report_lun_scan(struct s return 0; if (scsi_device_get(sdev)) return 0; - } else if (scsi_resurrect_device(sdev)) { - scsi_device_put(sdev); - return 0; } sprintf(devname, "host %d channel %d id %d", @@ -1449,7 +1456,7 @@ static int scsi_report_lun_scan(struct s /* * the sdev we used didn't appear in the report luns scan */ - scsi_destroy_device(sdev); + scsi_destroy_sdev(sdev); return ret; } @@ -1658,11 +1665,8 @@ static void scsi_sysfs_add_devices(struc { struct scsi_device *sdev; shost_for_each_device(sdev, shost) { - /* - * scsi_sysfs_add_sdev will clean up on failure, - * no need to do it here. - */ - scsi_sysfs_add_sdev(sdev); + if (scsi_sysfs_add_sdev(sdev) != 0) + scsi_destroy_sdev(sdev); } } @@ -1809,7 +1813,6 @@ void scsi_forget_host(struct Scsi_Host * continue; spin_unlock_irqrestore(shost->host_lock, flags); __scsi_remove_device(sdev); - scsi_destroy_device(sdev); goto restart; } spin_unlock_irqrestore(shost->host_lock, flags); @@ -1877,7 +1880,7 @@ void scsi_free_host_dev(struct scsi_devi { BUG_ON(sdev->id != sdev->host->this_id); - scsi_destroy_device(sdev); + scsi_destroy_sdev(sdev); } EXPORT_SYMBOL(scsi_free_host_dev); diff -puN drivers/scsi/scsi_sysfs.c~revert-resurrect-sdev drivers/scsi/scsi_sysfs.c --- a/drivers/scsi/scsi_sysfs.c~revert-resurrect-sdev +++ a/drivers/scsi/scsi_sysfs.c @@ -231,10 +231,6 @@ static void scsi_device_dev_release_user parent = sdev->sdev_gendev.parent; starget = to_scsi_target(parent); - if (sdev->host->hostt->slave_destroy) - sdev->host->hostt->slave_destroy(sdev); - transport_destroy_device(&sdev->sdev_gendev); - spin_lock_irqsave(sdev->host->host_lock, flags); starget->reap_ref++; list_del(&sdev->siblings); @@ -686,17 +682,14 @@ int scsi_sysfs_add_sdev(struct scsi_devi error = device_add(&sdev->sdev_gendev); if (error) { - printk(KERN_INFO "error 1\n"); - scsi_device_set_state(sdev, SDEV_CANCEL); put_device(sdev->sdev_gendev.parent); + printk(KERN_INFO "error 1\n"); return error; } error = class_device_add(&sdev->sdev_classdev); if (error) { printk(KERN_INFO "error 2\n"); - scsi_device_set_state(sdev, SDEV_CANCEL); - device_del(&sdev->sdev_gendev); - goto out_error; + goto clean_device; } /* take a reference for the sdev_classdev; this is @@ -708,7 +701,7 @@ int scsi_sysfs_add_sdev(struct scsi_devi sdev->host->hostt->sdev_attrs[i]); if (error) { __scsi_remove_device(sdev); - goto out_error; + goto out; } } } @@ -722,74 +715,23 @@ int scsi_sysfs_add_sdev(struct scsi_devi error = device_create_file(&sdev->sdev_gendev, attr); if (error) { __scsi_remove_device(sdev); - goto out_error; + goto out; } } } transport_add_device(&sdev->sdev_gendev); - + out: return error; - out_error: - scsi_destroy_device(sdev); + clean_device: + scsi_device_set_state(sdev, SDEV_CANCEL); - return error; -} - -int scsi_resurrect_device(struct scsi_device *sdev) -{ - int ret = 0; - - /* Device is active, return */ - if (sdev->sdev_state == SDEV_RUNNING || sdev->sdev_state == SDEV_CREATED) - return 0; - - /* - * Set the device to SDEV_CANCEL to start resurrection - */ - if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0) - return -ENXIO; - - ret = scsi_configure_device(sdev); - if (ret) { - scsi_destroy_device(sdev); - return ret; - } - - /* - * Ok, the device is now all set up, we can - * register it and tell the rest of the kernel - * about it. - */ - return scsi_sysfs_add_sdev(sdev); -} - -int scsi_configure_device(struct scsi_device *sdev) -{ - /* set the device running here so that slave configure - * may do I/O */ - if (scsi_device_set_state(sdev, SDEV_RUNNING) != 0) - return -ENXIO; - - transport_configure_device(&sdev->sdev_gendev); - - if (sdev->host->hostt->slave_configure) { - int ret = sdev->host->hostt->slave_configure(sdev); - if (ret) { - /* - * if LLDD reports slave not present, don't clutter - * console with alloc failure messages - */ - if (ret != -ENXIO) { - sdev_printk(KERN_ERR, sdev, - "failed to configure device\n"); - } - return ret; - } - } + device_del(&sdev->sdev_gendev); + transport_destroy_device(&sdev->sdev_gendev); + put_device(&sdev->sdev_gendev); - return 0; + return error; } void __scsi_remove_device(struct scsi_device *sdev) @@ -802,6 +744,11 @@ void __scsi_remove_device(struct scsi_de class_device_unregister(&sdev->sdev_classdev); transport_remove_device(dev); device_del(dev); + scsi_device_set_state(sdev, SDEV_DEL); + if (sdev->host->hostt->slave_destroy) + sdev->host->hostt->slave_destroy(sdev); + transport_destroy_device(dev); + put_device(dev); } /** @@ -814,7 +761,6 @@ void scsi_remove_device(struct scsi_devi mutex_lock(&shost->scan_mutex); __scsi_remove_device(sdev); - scsi_destroy_device(sdev); mutex_unlock(&shost->scan_mutex); } EXPORT_SYMBOL(scsi_remove_device); diff -puN include/scsi/scsi_device.h~revert-resurrect-sdev include/scsi/scsi_device.h --- a/include/scsi/scsi_device.h~revert-resurrect-sdev +++ a/include/scsi/scsi_device.h @@ -203,8 +203,6 @@ extern struct scsi_device *__scsi_add_de uint, uint, uint, void *hostdata); extern int scsi_add_device(struct Scsi_Host *host, uint channel, uint target, uint lun); -extern int scsi_configure_device(struct scsi_device *); -extern int scsi_resurrect_device(struct scsi_device *); extern void scsi_remove_device(struct scsi_device *); extern int scsi_device_cancel(struct scsi_device *, int); @@ -319,12 +317,6 @@ static inline unsigned int sdev_id(struc #define scmd_id(scmd) sdev_id((scmd)->device) #define scmd_channel(scmd) sdev_channel((scmd)->device) -static inline void scsi_destroy_device(struct scsi_device *sdev) -{ - scsi_device_set_state(sdev, SDEV_DEL); - put_device(&sdev->sdev_gendev); -} - static inline int scsi_device_online(struct scsi_device *sdev) { return sdev->sdev_state != SDEV_OFFLINE; _