From 383d0b6537cbf5a593be3359d32d2755cbb7a922 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 23 Nov 2003 22:02:15 -0600 Subject: [PATCH] Fix locking problems in scsi_report_bus_reset() causing aic7xxx to hang All the users of this function in the SCSI tree call it with the host lock held. With the new list traversal code, it was trying to take the lock again to traverse the list. Fix it to use the unlocked version of list traversal and modify the header comments to make it clear that the lock is expected to be held on calling it. --- drivers/scsi/scsi_error.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index c33e6bcfa554e..9458bb42cfe0e 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -911,7 +911,9 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd) if (rtn == SUCCESS) { scsi_sleep(BUS_RESET_SETTLE_TIME); + spin_lock_irqsave(scmd->device->host->host_lock, flags); scsi_report_bus_reset(scmd->device->host, scmd->device->channel); + spin_unlock_irqrestore(scmd->device->host->host_lock, flags); } return rtn; @@ -940,7 +942,9 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd) if (rtn == SUCCESS) { scsi_sleep(HOST_RESET_SETTLE_TIME); + spin_lock_irqsave(scmd->device->host->host_lock, flags); scsi_report_bus_reset(scmd->device->host, scmd->device->channel); + spin_unlock_irqrestore(scmd->device->host->host_lock, flags); } return rtn; @@ -1608,7 +1612,7 @@ int scsi_error_handler(void *data) * * Returns: Nothing * - * Lock status: No locks are assumed held. + * Lock status: Host lock must be held. * * Notes: This only needs to be called if the reset is one which * originates from an unknown location. Resets originated @@ -1622,7 +1626,7 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel) { struct scsi_device *sdev; - shost_for_each_device(sdev, shost) { + __shost_for_each_device(sdev, shost) { if (channel == sdev->channel) { sdev->was_reset = 1; sdev->expecting_cc_ua = 1; @@ -1642,7 +1646,7 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel) * * Returns: Nothing * - * Lock status: No locks are assumed held. + * Lock status: Host lock must be held * * Notes: This only needs to be called if the reset is one which * originates from an unknown location. Resets originated @@ -1656,7 +1660,7 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target) { struct scsi_device *sdev; - shost_for_each_device(sdev, shost) { + __shost_for_each_device(sdev, shost) { if (channel == sdev->channel && target == sdev->id) { sdev->was_reset = 1; -- 2.53.0