From 50c5dd6f0d1726c946efc66ba4e7c483064c4c69 Mon Sep 17 00:00:00 2001 From: dean Date: Mon, 5 Dec 1994 19:11:12 +0000 Subject: [PATCH] fix problem with disconnects (Ralph Campbell) --- sys/arch/pmax/dev/asc.c | 42 ++++++++++++++++++++++++++++++----------- sys/dev/tc/asc.c | 42 ++++++++++++++++++++++++++++++----------- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/sys/arch/pmax/dev/asc.c b/sys/arch/pmax/dev/asc.c index cf54e2177b64..d69c21de845e 100644 --- a/sys/arch/pmax/dev/asc.c +++ b/sys/arch/pmax/dev/asc.c @@ -1,4 +1,4 @@ -/* $NetBSD: asc.c,v 1.9 1994/12/01 16:41:05 dean Exp $ */ +/* $NetBSD: asc.c,v 1.10 1994/12/05 19:11:12 dean Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -250,6 +250,7 @@ static int asc_disconnect(); /* process an expected disconnect */ #define SCRIPT_CONTINUE_OUT 5 #define SCRIPT_SIMPLE 6 #define SCRIPT_GET_STATUS 7 +#define SCRIPT_DONE 8 #define SCRIPT_MSG_IN 9 #define SCRIPT_REPLY_SYNC 11 #define SCRIPT_TRY_SYNC 12 @@ -299,10 +300,10 @@ script_t asc_scripts[] = { /* get status and finish command */ {SCRIPT_MATCH(ASC_INT_FC, ASC_PHASE_MSG_IN), /* 7 */ asc_get_status, ASC_CMD_MSG_ACPT, - &asc_scripts[SCRIPT_GET_STATUS + 1]}, + &asc_scripts[SCRIPT_DONE]}, {SCRIPT_MATCH(ASC_INT_DISC, 0), /* 8 */ asc_end, ASC_CMD_NOP, - &asc_scripts[SCRIPT_GET_STATUS + 1]}, + &asc_scripts[SCRIPT_DONE]}, /* message in */ {SCRIPT_MATCH(ASC_INT_FC, ASC_PHASE_MSG_IN), /* 9 */ @@ -1022,14 +1023,30 @@ again: /* check for disconnect */ if (ir & ASC_INT_DISC) { state = &asc->st[asc->target]; - switch (ASC_SS(ss)) { - case 0: /* device did not respond */ - /* check for one of the starting scripts */ - switch (asc->script - asc_scripts) { - case SCRIPT_TRY_SYNC: - case SCRIPT_SIMPLE: - case SCRIPT_DATA_IN: - case SCRIPT_DATA_OUT: + switch (asc->script - asc_scripts) { + case SCRIPT_DONE: + case SCRIPT_DISCONNECT: + /* + * Disconnects can happen normally when the + * command is complete with the phase being + * either ASC_PHASE_DATAO or ASC_PHASE_MSG_IN. + * The SCRIPT_MATCH() only checks for one phase + * so we can wind up here. + * Perform the appropriate operation, then proceed. + */ + if ((*scpt->action)(asc, status, ss, ir)) { + regs->asc_cmd = scpt->command; + readback(regs->asc_cmd); + asc->script = scpt->next; + } + goto done; + + case SCRIPT_TRY_SYNC: + case SCRIPT_SIMPLE: + case SCRIPT_DATA_IN: + case SCRIPT_DATA_OUT: /* one of the starting scripts */ + if (ASC_SS(ss) == 0) { + /* device did not respond */ if (regs->asc_flags & ASC_FLAGS_FIFO_CNT) { regs->asc_cmd = ASC_CMD_FLUSH; readback(regs->asc_cmd); @@ -1043,6 +1060,9 @@ again: default: printf("asc%d: SCSI device %d: unexpected disconnect\n", asc - asc_softc, asc->target); +#ifdef DEBUG + asc_DumpLog("asc_disc"); +#endif /* * On rare occasions my RZ24 does a disconnect during * data in phase and the following seems to keep it diff --git a/sys/dev/tc/asc.c b/sys/dev/tc/asc.c index cf54e2177b64..d69c21de845e 100644 --- a/sys/dev/tc/asc.c +++ b/sys/dev/tc/asc.c @@ -1,4 +1,4 @@ -/* $NetBSD: asc.c,v 1.9 1994/12/01 16:41:05 dean Exp $ */ +/* $NetBSD: asc.c,v 1.10 1994/12/05 19:11:12 dean Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -250,6 +250,7 @@ static int asc_disconnect(); /* process an expected disconnect */ #define SCRIPT_CONTINUE_OUT 5 #define SCRIPT_SIMPLE 6 #define SCRIPT_GET_STATUS 7 +#define SCRIPT_DONE 8 #define SCRIPT_MSG_IN 9 #define SCRIPT_REPLY_SYNC 11 #define SCRIPT_TRY_SYNC 12 @@ -299,10 +300,10 @@ script_t asc_scripts[] = { /* get status and finish command */ {SCRIPT_MATCH(ASC_INT_FC, ASC_PHASE_MSG_IN), /* 7 */ asc_get_status, ASC_CMD_MSG_ACPT, - &asc_scripts[SCRIPT_GET_STATUS + 1]}, + &asc_scripts[SCRIPT_DONE]}, {SCRIPT_MATCH(ASC_INT_DISC, 0), /* 8 */ asc_end, ASC_CMD_NOP, - &asc_scripts[SCRIPT_GET_STATUS + 1]}, + &asc_scripts[SCRIPT_DONE]}, /* message in */ {SCRIPT_MATCH(ASC_INT_FC, ASC_PHASE_MSG_IN), /* 9 */ @@ -1022,14 +1023,30 @@ again: /* check for disconnect */ if (ir & ASC_INT_DISC) { state = &asc->st[asc->target]; - switch (ASC_SS(ss)) { - case 0: /* device did not respond */ - /* check for one of the starting scripts */ - switch (asc->script - asc_scripts) { - case SCRIPT_TRY_SYNC: - case SCRIPT_SIMPLE: - case SCRIPT_DATA_IN: - case SCRIPT_DATA_OUT: + switch (asc->script - asc_scripts) { + case SCRIPT_DONE: + case SCRIPT_DISCONNECT: + /* + * Disconnects can happen normally when the + * command is complete with the phase being + * either ASC_PHASE_DATAO or ASC_PHASE_MSG_IN. + * The SCRIPT_MATCH() only checks for one phase + * so we can wind up here. + * Perform the appropriate operation, then proceed. + */ + if ((*scpt->action)(asc, status, ss, ir)) { + regs->asc_cmd = scpt->command; + readback(regs->asc_cmd); + asc->script = scpt->next; + } + goto done; + + case SCRIPT_TRY_SYNC: + case SCRIPT_SIMPLE: + case SCRIPT_DATA_IN: + case SCRIPT_DATA_OUT: /* one of the starting scripts */ + if (ASC_SS(ss) == 0) { + /* device did not respond */ if (regs->asc_flags & ASC_FLAGS_FIFO_CNT) { regs->asc_cmd = ASC_CMD_FLUSH; readback(regs->asc_cmd); @@ -1043,6 +1060,9 @@ again: default: printf("asc%d: SCSI device %d: unexpected disconnect\n", asc - asc_softc, asc->target); +#ifdef DEBUG + asc_DumpLog("asc_disc"); +#endif /* * On rare occasions my RZ24 does a disconnect during * data in phase and the following seems to keep it