From 1cb4eb79605d9a283d9382d47e3e524291a1dcea Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Tue, 10 Apr 2012 05:43:59 -0700 Subject: [PATCH] Fixed Asynch I/O issues which may leave pending asynch I/O in limbo when device resets happen (found by Sergey Oboguev) --- PDP11/pdp11_rq.c | 1 + sim_defs.h | 2 +- sim_disk.c | 10 ++++++++++ sim_disk.h | 1 + sim_tape.c | 5 +++++ 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/PDP11/pdp11_rq.c b/PDP11/pdp11_rq.c index 130cea40..aa6120a1 100644 --- a/PDP11/pdp11_rq.c +++ b/PDP11/pdp11_rq.c @@ -2561,6 +2561,7 @@ rq_clrint (cp); /* clr intr req */ for (i = 0; i < (RQ_NUMDR + 2); i++) { /* init units */ uptr = dptr->units + i; sim_cancel (uptr); /* clr activity */ + sim_disk_reset (uptr); uptr->cnum = cidx; /* set ctrl index */ uptr->flags = uptr->flags & ~(UNIT_ONL | UNIT_ATP); uptr->uf = 0; /* clr unit flags */ diff --git a/sim_defs.h b/sim_defs.h index 32ad7bdd..7a35044c 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -606,7 +606,7 @@ extern int32 sim_asynch_inst_latency; #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) #define InterlockedCompareExchangePointer(Destination, Exchange, Comparand) __sync_val_compare_and_swap(Destination, Comparand, Exchange) #elif defined(__DECC_VER) -#define InterlockedCompareExchangePointer(Destination, Exchange, Comparand) (void *)((int32)_InterlockedCompareExchange64_rel(Destination, Exchange, Comparand)) +#define InterlockedCompareExchangePointer(Destination, Exchange, Comparand) (void *)((int32)_InterlockedCompareExchange64(Destination, Exchange, Comparand)) #else #error "Implementation of function InterlockedCompareExchangePointer() is needed to build with USE_AIO_INTRINSICS" #endif diff --git a/sim_disk.c b/sim_disk.c index 32627227..ee85441c 100644 --- a/sim_disk.c +++ b/sim_disk.c @@ -1073,6 +1073,16 @@ if (close_function (fileref) == EOF) return SCPE_OK; } +t_stat sim_disk_reset (UNIT *uptr) +{ +if (!(uptr->flags & UNIT_ATT)) /* attached? */ + return SCPE_OK; +_sim_disk_io_flush(uptr); +AIO_VALIDATE; +AIO_UPDATE_QUEUE; +return SCPE_OK; +} + /* Factory bad block table creation routine This routine writes a DEC standard 044 compliant bad block table on the diff --git a/sim_disk.h b/sim_disk.h index b704604e..1295ac91 100644 --- a/sim_disk.h +++ b/sim_disk.h @@ -78,6 +78,7 @@ t_stat sim_disk_set_capac (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat sim_disk_show_capac (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat sim_disk_set_asynch (UNIT *uptr, int latency); t_stat sim_disk_clr_asynch (UNIT *uptr); +t_stat sim_disk_reset (UNIT *uptr); t_bool sim_disk_isavailable (UNIT *uptr); t_bool sim_disk_isavailable_a (UNIT *uptr, DISK_PCALLBACK callback); t_bool sim_disk_wrp (UNIT *uptr); diff --git a/sim_tape.c b/sim_tape.c index 8c4d7bce..c6cbe410 100644 --- a/sim_tape.c +++ b/sim_tape.c @@ -1715,6 +1715,11 @@ return r; t_stat sim_tape_reset (UNIT *uptr) { MT_CLR_PNU (uptr); +if (!(uptr->flags & UNIT_ATT)) /* attached? */ + return SCPE_OK; +_sim_tape_io_flush(uptr); +AIO_VALIDATE; +AIO_UPDATE_QUEUE; return SCPE_OK; }