Rather than run a periph's queue from scsipi_periph_timed_thaw which is
called via a callout, kick the completion thread to run it for us (uses a new flag, SCSIPI_CHAN_KICK). If we've received BUSY status and we haven't started the completion thread yet, don't freeze do a callout to scsipi_periph_timed_thaw which then will try and kick the completion thread- instead treat the command as if it were a polled command and just call delay for 1 second. If DIAGNOSTIC is defined, and the periph qfreeze count is less than zero, panic because some HBA has corrupted the periph structure's accounting.
This commit is contained in:
parent
501d75ad7f
commit
849eac52f2
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: scsipi_base.c,v 1.55 2001/09/01 00:54:38 mjacob Exp $ */
|
||||
/* $NetBSD: scsipi_base.c,v 1.56 2001/09/18 20:20:26 mjacob Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
|
||||
|
@ -621,6 +621,14 @@ scsipi_periph_thaw(periph, count)
|
|||
|
||||
s = splbio();
|
||||
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 &&
|
||||
(periph->periph_flags & PERIPH_WAITING) != 0)
|
||||
wakeup(periph);
|
||||
|
@ -636,17 +644,20 @@ void
|
|||
scsipi_periph_timed_thaw(arg)
|
||||
void *arg;
|
||||
{
|
||||
int s;
|
||||
struct scsipi_periph *periph = arg;
|
||||
|
||||
callout_stop(&periph->periph_callout);
|
||||
|
||||
s = splbio();
|
||||
scsipi_periph_thaw(periph, 1);
|
||||
|
||||
/*
|
||||
* Kick the channel's queue here. Note, we're running in
|
||||
* interrupt context (softclock), so the adapter driver
|
||||
* had better not sleep.
|
||||
* Tell the completion thread to kick the channel's queue here.
|
||||
*/
|
||||
scsipi_run_queue(periph->periph_channel);
|
||||
periph->periph_channel->chan_flags |= SCSIPI_CHAN_KICK;
|
||||
wakeup(&periph->periph_channel->chan_complete);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -919,7 +930,6 @@ scsipi_interpret_sense(xs)
|
|||
printf("\n");
|
||||
}
|
||||
#else
|
||||
|
||||
scsipi_printaddr(periph);
|
||||
printf("Sense Error Code 0x%x",
|
||||
sense->error_code & SSD_ERRCODE);
|
||||
|
@ -1413,9 +1423,10 @@ scsipi_complete(xs)
|
|||
/*
|
||||
* 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);
|
||||
else {
|
||||
} else {
|
||||
scsipi_periph_freeze(periph, 1);
|
||||
callout_reset(&periph->periph_callout,
|
||||
hz, scsipi_periph_timed_thaw, periph);
|
||||
|
@ -1505,7 +1516,7 @@ scsipi_complete(xs)
|
|||
} else {
|
||||
bp->b_error = 0;
|
||||
bp->b_resid = xs->resid;
|
||||
}
|
||||
}
|
||||
biodone(bp);
|
||||
}
|
||||
|
||||
|
@ -1942,12 +1953,16 @@ scsipi_completion_thread(arg)
|
|||
struct scsipi_xfer *xs;
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
chan->chan_flags |= SCSIPI_CHAN_TACTIVE;
|
||||
splx(s);
|
||||
for (;;) {
|
||||
s = splbio();
|
||||
xs = TAILQ_FIRST(&chan->chan_complete);
|
||||
if (xs == NULL &&
|
||||
(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,
|
||||
"sccomp", 0);
|
||||
splx(s);
|
||||
|
@ -1960,6 +1975,13 @@ scsipi_completion_thread(arg)
|
|||
splx(s);
|
||||
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) {
|
||||
splx(s);
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: scsipiconf.h,v 1.57 2001/09/02 13:11:53 tsutsui Exp $ */
|
||||
/* $NetBSD: scsipiconf.h,v 1.58 2001/09/18 20:20:26 mjacob Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
|
||||
|
@ -305,6 +305,8 @@ struct scsipi_channel {
|
|||
#define SCSIPI_CHAN_CANGROW 0x04 /* channel can grow resources */
|
||||
#define SCSIPI_CHAN_NOSETTLE 0x08 /* don't wait for devices to settle */
|
||||
#define SCSIPI_CHAN_CALLBACK 0x10 /* has to call chan_callback() */
|
||||
#define SCSIPI_CHAN_KICK 0x20 /* need to run queues */
|
||||
#define SCSIPI_CHAN_TACTIVE 0x40 /* completion thread is active */
|
||||
|
||||
#define SCSIPI_CHAN_MAX_PERIPH(chan) \
|
||||
(((chan)->chan_flags & SCSIPI_CHAN_OPENINGS) ? \
|
||||
|
|
Loading…
Reference in New Issue