aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r--drivers/scsi/scsi_sysfs.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 093d4f6a54d..ce5224c92ed 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -1031,33 +1031,31 @@ static void __scsi_remove_target(struct scsi_target *starget)
1031void scsi_remove_target(struct device *dev) 1031void scsi_remove_target(struct device *dev)
1032{ 1032{
1033 struct Scsi_Host *shost = dev_to_shost(dev->parent); 1033 struct Scsi_Host *shost = dev_to_shost(dev->parent);
1034 struct scsi_target *starget, *found; 1034 struct scsi_target *starget, *last = NULL;
1035 unsigned long flags; 1035 unsigned long flags;
1036 1036
1037 restart: 1037 /* remove targets being careful to lookup next entry before
1038 found = NULL; 1038 * deleting the last
1039 */
1039 spin_lock_irqsave(shost->host_lock, flags); 1040 spin_lock_irqsave(shost->host_lock, flags);
1040 list_for_each_entry(starget, &shost->__targets, siblings) { 1041 list_for_each_entry(starget, &shost->__targets, siblings) {
1041 if (starget->state == STARGET_DEL) 1042 if (starget->state == STARGET_DEL)
1042 continue; 1043 continue;
1043 if (starget->dev.parent == dev || &starget->dev == dev) { 1044 if (starget->dev.parent == dev || &starget->dev == dev) {
1044 found = starget; 1045 /* assuming new targets arrive at the end */
1045 found->reap_ref++; 1046 starget->reap_ref++;
1046 break; 1047 spin_unlock_irqrestore(shost->host_lock, flags);
1048 if (last)
1049 scsi_target_reap(last);
1050 last = starget;
1051 __scsi_remove_target(starget);
1052 spin_lock_irqsave(shost->host_lock, flags);
1047 } 1053 }
1048 } 1054 }
1049 spin_unlock_irqrestore(shost->host_lock, flags); 1055 spin_unlock_irqrestore(shost->host_lock, flags);
1050 1056
1051 if (found) { 1057 if (last)
1052 __scsi_remove_target(found); 1058 scsi_target_reap(last);
1053 scsi_target_reap(found);
1054 /* in the case where @dev has multiple starget children,
1055 * continue removing.
1056 *
1057 * FIXME: does such a case exist?
1058 */
1059 goto restart;
1060 }
1061} 1059}
1062EXPORT_SYMBOL(scsi_remove_target); 1060EXPORT_SYMBOL(scsi_remove_target);
1063 1061