aic79xx bus reset update
Subsystems (2)
PATCH 1/1 aic79xx bus reset update
Hi all,
as James B. noted bus reset has to be protected by a lock to prevent access to the sequencer during reset.
However, the main reason of _not_ holding the lock there was this very curious 'poll till bus reset is gone' feature in ahd_reset_channel(), which would deadlock if the procedure was called with ahd_lock held.
So I've reworked this 'feature' to just use a flag to signify 'the bus has just been reset by us, ignore any incoming external resets'. This should be equivalent in functionality but won't deadlock as the flag is tested in the main SCSI interrupt routine.
I still wonder whether we need this functionality at all. The original code will only trigger on very specialized cases (bus reset followed by continuous external resets), and this smells like it would trigger various other effects, too.
Please apply.
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke [email protected] SuSE Linux Products GmbH S390 & zSeries Maxfeldstraße 5 +49 911 74053 688 90409 Nürnberg http://www.suse.de
From: Hannes Reinecke <[email protected]>
Subject: Update aic79xx bus reset handling
As James B. correctly noted, ahd_reset_channel() in ahd_linux_bus_reset() should be protected by ahd_lock(). However, the main reason for not doing so was a deadlock with the interesting polling mechanism to detect the end a bus reset.
This patch replaces the polling mechanism with a saner signalling via flags; it also gives us the benefit of detecting any multiple calls to ahd_reset_channel().
drivers/scsi/aic7xxx/aic79xx.h +1 -1
@@ -372,7 +372,7 @@ typedef enum {AHD_CURRENT_SENSING =0x40000 ,AHD_SCB_CONFIG_USED =0x80000 ,/* No SEEPROM but SCB had info. */ AHD_HP_BOARD =0x100000 , -AHD_RESET_POLL_ACTIVE =0x200000 , +AHD_BUS_RESET_ACTIVE =0x200000 ,AHD_UPDATE_PEND_CMDS =0x400000 ,AHD_RUNNING_QOUTFIFO =0x800000 ,AHD_HAD_FIRST_SEL =0x1000000
drivers/scsi/aic7xxx/aic79xx_core.c +54 -62
160 lines not on this page · raw message
drivers/scsi/aic7xxx/aic79xx_osm.c +4 -0
@@ -782,6 +782,7 @@ ahd_linux_bus_reset(struct scsi_cmnd *cm {struct ahd_softc *ahd;int found; +unsigned long flags; ahd = *(struct ahd_softc **)cmd->device->host->hostdata;#ifdef AHD_DEBUG
@@ -789,8 +790,11 @@ ahd_linux_bus_reset(struct scsi_cmnd *cmprintf ("%s: Bus reset called for cmd %p\n" ,ahd_name (ahd), cmd);#endif +ahd_lock (ahd, &flags); + found =ahd_reset_channel (ahd,scmd_channel (cmd) +'A' ,/*initiate reset*/ TRUE); +ahd_unlock (ahd, &flags);if (bootverbose) printf("%s: SCSI bus reset delivered. "