Restore previous functionality- in scsipi_periph_timed_thaw check to

make sure the completion thread is running before you try to schedule
it.

Fixes port-i386/14013
This commit is contained in:
mjacob 2001-09-27 18:11:06 +00:00
parent 79d74959da
commit 87a8b82ae9
1 changed files with 44 additions and 14 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsipi_base.c,v 1.57 2001/09/21 13:54:47 fvdl Exp $ */ /* $NetBSD: scsipi_base.c,v 1.58 2001/09/27 18:11:06 mjacob Exp $ */
/*- /*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -621,6 +621,14 @@ scsipi_periph_thaw(periph, count)
s = splbio(); s = splbio();
periph->periph_qfreeze -= count; periph->periph_qfreeze -= count;
#ifdef DIAGNOSTIC
if (periph->periph_qfreeze < 0) {
static const char pc[] = "periph freeze count < 0";
scsipi_printaddr(periph);
printf("%s\n", pc);
panic(pc);
}
#endif
if (periph->periph_qfreeze == 0 && if (periph->periph_qfreeze == 0 &&
(periph->periph_flags & PERIPH_WAITING) != 0) (periph->periph_flags & PERIPH_WAITING) != 0)
wakeup(periph); wakeup(periph);
@ -636,17 +644,28 @@ void
scsipi_periph_timed_thaw(arg) scsipi_periph_timed_thaw(arg)
void *arg; void *arg;
{ {
int s;
struct scsipi_periph *periph = arg; struct scsipi_periph *periph = arg;
callout_stop(&periph->periph_callout); callout_stop(&periph->periph_callout);
scsipi_periph_thaw(periph, 1);
/* s = splbio();
* Kick the channel's queue here. Note, we're running in scsipi_periph_thaw(periph, 1);
* interrupt context (softclock), so the adapter driver if ((periph->periph_channel->chan_flags & SCSIPI_CHAN_TACTIVE) == 0) {
* had better not sleep. /*
*/ * Kick the channel's queue here. Note, we're running in
scsipi_run_queue(periph->periph_channel); * interrupt context (softclock), so the adapter driver
* had better not sleep.
*/
scsipi_run_queue(periph->periph_channel);
} else {
/*
* Tell the completion thread to kick the channel's queue here.
*/
periph->periph_channel->chan_flags |= SCSIPI_CHAN_KICK;
wakeup(&periph->periph_channel->chan_complete);
}
splx(s);
} }
/* /*
@ -919,7 +938,6 @@ scsipi_interpret_sense(xs)
printf("\n"); printf("\n");
} }
#else #else
scsipi_printaddr(periph); scsipi_printaddr(periph);
printf("Sense Error Code 0x%x", printf("Sense Error Code 0x%x",
sense->error_code & SSD_ERRCODE); sense->error_code & SSD_ERRCODE);
@ -1228,7 +1246,7 @@ scsipi_done(xs)
} }
/* /*
* If this was an xfer that was not to complete asynchrnously, * If this was an xfer that was not to complete asynchronously,
* let the requesting thread perform error checking/handling * let the requesting thread perform error checking/handling
* in its context. * in its context.
*/ */
@ -1413,9 +1431,10 @@ scsipi_complete(xs)
/* /*
* Wait one second, and try again. * Wait one second, and try again.
*/ */
if (xs->xs_control & XS_CTL_POLL) if ((xs->xs_control & XS_CTL_POLL) ||
(chan->chan_flags & SCSIPI_CHAN_TACTIVE) == 0) {
delay(1000000); delay(1000000);
else { } else {
scsipi_periph_freeze(periph, 1); scsipi_periph_freeze(periph, 1);
callout_reset(&periph->periph_callout, callout_reset(&periph->periph_callout,
hz, scsipi_periph_timed_thaw, periph); hz, scsipi_periph_timed_thaw, periph);
@ -1505,7 +1524,7 @@ scsipi_complete(xs)
} else { } else {
bp->b_error = 0; bp->b_error = 0;
bp->b_resid = xs->resid; bp->b_resid = xs->resid;
} }
biodone(bp); biodone(bp);
} }
@ -1942,12 +1961,16 @@ scsipi_completion_thread(arg)
struct scsipi_xfer *xs; struct scsipi_xfer *xs;
int s; int s;
s = splbio();
chan->chan_flags |= SCSIPI_CHAN_TACTIVE;
splx(s);
for (;;) { for (;;) {
s = splbio(); s = splbio();
xs = TAILQ_FIRST(&chan->chan_complete); xs = TAILQ_FIRST(&chan->chan_complete);
if (xs == NULL && if (xs == NULL &&
(chan->chan_flags & (chan->chan_flags &
(SCSIPI_CHAN_SHUTDOWN | SCSIPI_CHAN_CALLBACK)) == 0) { (SCSIPI_CHAN_SHUTDOWN | SCSIPI_CHAN_CALLBACK |
SCSIPI_CHAN_KICK)) == 0) {
(void) tsleep(&chan->chan_complete, PRIBIO, (void) tsleep(&chan->chan_complete, PRIBIO,
"sccomp", 0); "sccomp", 0);
splx(s); splx(s);
@ -1960,6 +1983,13 @@ scsipi_completion_thread(arg)
splx(s); splx(s);
continue; continue;
} }
if (chan->chan_flags & SCSIPI_CHAN_KICK) {
/* explicitly run the queues for this channel */
chan->chan_flags &= ~SCSIPI_CHAN_KICK;
scsipi_run_queue(chan);
splx(s);
continue;
}
if (chan->chan_flags & SCSIPI_CHAN_SHUTDOWN) { if (chan->chan_flags & SCSIPI_CHAN_SHUTDOWN) {
splx(s); splx(s);
break; break;