|
@@ -1466,23 +1466,17 @@ EXPORT_SYMBOL(scsi_scan_single_target);
|
|
|
|
|
|
void scsi_forget_host(struct Scsi_Host *shost)
|
|
|
{
|
|
|
- struct scsi_target *starget, *tmp;
|
|
|
+ struct scsi_device *sdev;
|
|
|
unsigned long flags;
|
|
|
|
|
|
- /*
|
|
|
- * Ok, this look a bit strange. We always look for the first device
|
|
|
- * on the list as scsi_remove_device removes them from it - thus we
|
|
|
- * also have to release the lock.
|
|
|
- * We don't need to get another reference to the device before
|
|
|
- * releasing the lock as we already own the reference from
|
|
|
- * scsi_register_device that's release in scsi_remove_device. And
|
|
|
- * after that we don't look at sdev anymore.
|
|
|
- */
|
|
|
+ restart:
|
|
|
spin_lock_irqsave(shost->host_lock, flags);
|
|
|
- list_for_each_entry_safe(starget, tmp, &shost->__targets, siblings) {
|
|
|
+ list_for_each_entry(sdev, &shost->__devices, siblings) {
|
|
|
+ if (sdev->sdev_state == SDEV_DEL)
|
|
|
+ continue;
|
|
|
spin_unlock_irqrestore(shost->host_lock, flags);
|
|
|
- scsi_remove_target(&starget->dev);
|
|
|
- spin_lock_irqsave(shost->host_lock, flags);
|
|
|
+ __scsi_remove_device(sdev);
|
|
|
+ goto restart;
|
|
|
}
|
|
|
spin_unlock_irqrestore(shost->host_lock, flags);
|
|
|
}
|