summaryrefslogtreecommitdiffstats
path: root/sys/pci/ncr.c
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>1998-09-17 22:29:02 +0000
committergibbs <gibbs@FreeBSD.org>1998-09-17 22:29:02 +0000
commit9784d6e14354811d14915da4c191ac506ce20e38 (patch)
tree5bfc3f4b82afbf6ac1137931563045cc1640d891 /sys/pci/ncr.c
parent23bdbca2d46a44c119d0a48bd31b6fb92d960b90 (diff)
downloadFreeBSD-src-9784d6e14354811d14915da4c191ac506ce20e38.zip
FreeBSD-src-9784d6e14354811d14915da4c191ac506ce20e38.tar.gz
Really correct ncr_freeze_devq now. We scan backwards from the current
insertion point into the start queue looking for entries to remove and mark them with the 'skip' address, recording the entry furthest from the insertion point that needs to be removed. We then go through a second loop starting at the furthest entry to be removed and compress the start queue. The old algorithm started at (old insert point + 1) and wrapped through the whole queue which would end up moving the start position in the queue out from under the nose of the scrip processor.
Diffstat (limited to 'sys/pci/ncr.c')
-rw-r--r--sys/pci/ncr.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/sys/pci/ncr.c b/sys/pci/ncr.c
index 7a0e12f..193039f 100644
--- a/sys/pci/ncr.c
+++ b/sys/pci/ncr.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: ncr.c,v 1.127 1998/09/16 22:46:04 gibbs Exp $
+** $Id: ncr.c,v 1.128 1998/09/17 00:08:23 gibbs Exp $
**
** Device driver for the NCR 53C8XX PCI-SCSI-Controller Family.
**
@@ -1288,7 +1288,7 @@ static void ncr_attach (pcici_t tag, int unit);
static char ident[] =
- "\n$Id: ncr.c,v 1.127 1998/09/16 22:46:04 gibbs Exp $\n";
+ "\n$Id: ncr.c,v 1.128 1998/09/17 00:08:23 gibbs Exp $\n";
static const u_long ncr_version = NCR_VERSION * 11
+ (u_long) sizeof (struct ncb) * 7
@@ -4594,8 +4594,9 @@ static void
ncr_freeze_devq (ncb_p np, struct cam_path *path)
{
nccb_p cp;
- int count;
int i;
+ int count;
+ int firstskip;
/*
** Starting at the first nccb and following
** the links, complete all jobs that match
@@ -4604,6 +4605,7 @@ ncr_freeze_devq (ncb_p np, struct cam_path *path)
cp = np->link_nccb;
count = 0;
+ firstskip = 0;
while (cp) {
switch (cp->host_status) {
@@ -4614,10 +4616,21 @@ ncr_freeze_devq (ncb_p np, struct cam_path *path)
&& (xpt_path_comp(path, cp->ccb->ccb_h.path) >= 0)) {
/* Mark for removal from the start queue */
- for (i = 0; i < MAX_START; i++) {
- if (np->squeue[i] == CCB_PHYS(cp, phys))
- np->squeue[i] =
+ for (i = 1; i < MAX_START; i++) {
+ int idx;
+
+ idx = np->squeueput - i;
+
+ if (idx < 0)
+ idx = MAX_START + idx;
+ if (np->squeue[idx]
+ == CCB_PHYS(cp, phys)) {
+ np->squeue[idx] =
NCB_SCRIPT_PHYS (np, skip);
+ if (i > firstskip)
+ firstskip = i;
+ break;
+ }
}
cp->host_status=HS_STALL;
ncr_complete (np, cp);
@@ -4637,21 +4650,24 @@ ncr_freeze_devq (ncb_p np, struct cam_path *path)
/* Compress the start queue */
j = 0;
bidx = np->squeueput;
- for (i = (np->squeueput + 1) % MAX_START;;
- i = (i + 1) % MAX_START) {
+ i = np->squeueput - firstskip;
+ if (i < 0)
+ i = MAX_START + i;
+ for (;;) {
bidx = i - j;
if (bidx < 0)
bidx = MAX_START + bidx;
- if (np->squeue[i] == NCB_SCRIPT_PHYS (np, skip))
+ if (np->squeue[i] == NCB_SCRIPT_PHYS (np, skip)) {
j++;
- else if (j != 0) {
+ } else if (j != 0) {
np->squeue[bidx] = np->squeue[i];
if (np->squeue[bidx]
== NCB_SCRIPT_PHYS(np, idle))
break;
}
+ i = (i + 1) % MAX_START;
}
np->squeueput = bidx;
}
@@ -5631,7 +5647,6 @@ static void ncr_int_ma (ncb_p np, u_char dstat)
/*
** locate matching cp
*/
- dsa = INL (nc_dsa);
cp = np->link_nccb;
while (cp && (CCB_PHYS (cp, phys) != dsa))
cp = cp->link_nccb;
OpenPOWER on IntegriCloud