summaryrefslogtreecommitdiffstats
path: root/sys/dev/aic7xxx
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>1999-04-19 21:28:15 +0000
committergibbs <gibbs@FreeBSD.org>1999-04-19 21:28:15 +0000
commit888d5241035a7e2b44aad57a1960d1b73b33a27d (patch)
tree7268247cbdd415369144117c42a7b5dcbe21a2c8 /sys/dev/aic7xxx
parentdeb3dc05945881a83f9063301d8bfa56720eb332 (diff)
downloadFreeBSD-src-888d5241035a7e2b44aad57a1960d1b73b33a27d.zip
FreeBSD-src-888d5241035a7e2b44aad57a1960d1b73b33a27d.tar.gz
Preserve termination settings across the card reset in our shutdown hook.
Diffstat (limited to 'sys/dev/aic7xxx')
-rw-r--r--sys/dev/aic7xxx/aic7xxx.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.c b/sys/dev/aic7xxx/aic7xxx.c
index 0c4cfbd..5e0ccab 100644
--- a/sys/dev/aic7xxx/aic7xxx.c
+++ b/sys/dev/aic7xxx/aic7xxx.c
@@ -36,7 +36,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aic7xxx.c,v 1.20 1999/03/23 07:24:26 gibbs Exp $
+ * $Id: aic7xxx.c,v 1.21 1999/04/07 23:02:45 gibbs Exp $
*/
/*
* A few notes on features of the driver.
@@ -2635,8 +2635,6 @@ ahc_handle_message_phase(struct ahc_softc *ahc, struct cam_path *path)
int end_session;
ahc_fetch_devinfo(ahc, &devinfo);
-
-
end_session = FALSE;
bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
@@ -4206,11 +4204,12 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
else
maxsync = AHC_SYNCRATE_FAST;
- if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) == 0)
+ if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) == 0) {
if (update_type & AHC_TRANS_USER)
cts->sync_offset = tinfo->user.offset;
else
cts->sync_offset = tinfo->goal.offset;
+ }
syncrate = ahc_find_syncrate(ahc, &cts->sync_period,
maxsync);
@@ -5970,10 +5969,43 @@ ahc_shutdown(int howto, void *arg)
{
struct ahc_softc *ahc;
int i;
+ u_int sxfrctl1_a, sxfrctl1_b;
ahc = (struct ahc_softc *)arg;
+ pause_sequencer(ahc);
+
+ /*
+ * Preserve the value of the SXFRCTL1 register for all channels.
+ * It contains settings that affect termination and we don't want
+ * to disturb the integrity of the bus during shutdown in case
+ * we are in a multi-initiator setup.
+ */
+ sxfrctl1_b = 0;
+ if ((ahc->features & AHC_TWIN) != 0) {
+ u_int sblkctl;
+
+ sblkctl = ahc_inb(ahc, SBLKCTL);
+ ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
+ sxfrctl1_b = ahc_inb(ahc, SXFRCTL1);
+ ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
+ }
+
+ sxfrctl1_a = ahc_inb(ahc, SXFRCTL1);
+
+ /* This will reset most registers to 0, but not all */
ahc_reset(ahc);
+
+ if ((ahc->features & AHC_TWIN) != 0) {
+ u_int sblkctl;
+
+ sblkctl = ahc_inb(ahc, SBLKCTL);
+ ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
+ ahc_outb(ahc, SXFRCTL1, sxfrctl1_b);
+ ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
+ }
+ ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
+
ahc_outb(ahc, SCSISEQ, 0);
ahc_outb(ahc, SXFRCTL0, 0);
ahc_outb(ahc, DSPCISTATUS, 0);
OpenPOWER on IntegriCloud