Fix negative timeout symptoms caused by integer multiply overflow,
which is revealed with larger HZ systems like NetBSD/pmax (256Hz) and NetBSD/alpha (1024Hz) as reported by PR#8645. Polled tape drive access is done with maximum 6 hour timeout which ended up with negative time and then confused SCSI bus severely.
This commit is contained in:
parent
0f20cdad3f
commit
0c92b006c6
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ncr53c9x.c,v 1.51 2000/06/05 15:19:42 tsutsui Exp $ */
|
||||
/* $NetBSD: ncr53c9x.c,v 1.52 2000/07/04 01:10:18 nisimura Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
@ -541,9 +541,16 @@ ncr53c9x_select(sc, ecb)
|
||||
* expecting to come back due to an interrupt, because it is
|
||||
* always possible that the interrupt may never happen.
|
||||
*/
|
||||
if ((ecb->xs->xs_control & XS_CTL_POLL) == 0)
|
||||
callout_reset(&ecb->xs->xs_callout, (ecb->timeout * hz) / 1000,
|
||||
if ((ecb->xs->xs_control & XS_CTL_POLL) == 0) {
|
||||
int timeout = ecb->timeout;
|
||||
|
||||
if (hz > 100 && timeout > 1000)
|
||||
timeout = (timeout / 1000) * hz;
|
||||
else
|
||||
timeout = (timeout * hz) / 1000;
|
||||
callout_reset(&ecb->xs->xs_callout, timeout,
|
||||
ncr53c9x_timeout, ecb);
|
||||
}
|
||||
|
||||
/*
|
||||
* The docs say the target register is never reset, and I
|
||||
@ -2179,6 +2186,8 @@ ncr53c9x_abort(sc, ecb)
|
||||
ecb->flags |= ECB_ABORT;
|
||||
|
||||
if (ecb == sc->sc_nexus) {
|
||||
int timeout;
|
||||
|
||||
/*
|
||||
* If we're still selecting, the message will be scheduled
|
||||
* after selection is complete.
|
||||
@ -2189,7 +2198,12 @@ ncr53c9x_abort(sc, ecb)
|
||||
/*
|
||||
* Reschedule timeout.
|
||||
*/
|
||||
callout_reset(&ecb->xs->xs_callout, (ecb->timeout * hz) / 1000,
|
||||
timeout = ecb->timeout;
|
||||
if (hz > 100 && timeout > 1000)
|
||||
timeout = (timeout / 1000) * hz;
|
||||
else
|
||||
timeout = (timeout * hz) / 1000;
|
||||
callout_reset(&ecb->xs->xs_callout, timeout,
|
||||
ncr53c9x_timeout, ecb);
|
||||
} else {
|
||||
/* The command should be on the nexus list */
|
||||
|
Loading…
Reference in New Issue
Block a user