summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>1998-09-16 22:46:04 +0000
committergibbs <gibbs@FreeBSD.org>1998-09-16 22:46:04 +0000
commit7bec193ef7864c772f237ef3cd18de8ccac0ca37 (patch)
tree27e9a96cc670a0f5775c6e58e06180c35f16c8ef
parent75e7cbc736bb5d1dcb25947fa87c096b216837b2 (diff)
downloadFreeBSD-src-7bec193ef7864c772f237ef3cd18de8ccac0ca37.zip
FreeBSD-src-7bec193ef7864c772f237ef3cd18de8ccac0ca37.tar.gz
Fix a regression that caused the script to spam itself by copying something
of size sizeof(struct timeval) that is really of size sizeof(ticks). Make another attempt at fixing the queue full case.
-rw-r--r--sys/pci/ncr.c66
1 files changed, 49 insertions, 17 deletions
diff --git a/sys/pci/ncr.c b/sys/pci/ncr.c
index 988cec0..41c1ddc 100644
--- a/sys/pci/ncr.c
+++ b/sys/pci/ncr.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: ncr.c,v 1.125 1998/09/15 22:05:38 gibbs Exp $
+** $Id: ncr.c,v 1.126 1998/09/16 17:11:59 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.125 1998/09/15 22:05:38 gibbs Exp $\n";
+ "\n$Id: ncr.c,v 1.126 1998/09/16 17:11:59 gibbs Exp $\n";
static const u_long ncr_version = NCR_VERSION * 11
+ (u_long) sizeof (struct ncb) * 7
@@ -1616,7 +1616,7 @@ static struct script script0 = {
/*
** Set a time stamp for this selection
*/
- SCR_COPY (sizeof (struct timeval)),
+ SCR_COPY (sizeof (ticks)),
KVAR (KVAR_TICKS),
NADDR (header.stamp.select),
/*
@@ -1798,7 +1798,7 @@ static struct script script0 = {
/*
** ... set a timestamp ...
*/
- SCR_COPY (sizeof (struct timeval)),
+ SCR_COPY (sizeof (ticks)),
KVAR (KVAR_TICKS),
NADDR (header.stamp.command),
/*
@@ -1820,7 +1820,7 @@ static struct script script0 = {
/*
** set the timestamp.
*/
- SCR_COPY (sizeof (struct timeval)),
+ SCR_COPY (sizeof (ticks)),
KVAR (KVAR_TICKS),
NADDR (header.stamp.status),
/*
@@ -2125,7 +2125,7 @@ static struct script script0 = {
** Set a time stamp,
** and count the disconnects.
*/
- SCR_COPY (sizeof (struct timeval)),
+ SCR_COPY (sizeof (ticks)),
KVAR (KVAR_TICKS),
NADDR (header.stamp.disconnect),
SCR_COPY (4),
@@ -2368,7 +2368,7 @@ static struct script script0 = {
**
** SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),
** PADDR (no_data),
-** SCR_COPY (sizeof (struct timeval)),
+** SCR_COPY (sizeof (ticks)),
** KVAR (KVAR_TICKS),
** NADDR (header.stamp.data),
** SCR_MOVE_TBL ^ SCR_DATA_IN,
@@ -2395,7 +2395,7 @@ static struct script script0 = {
**
** SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_OUT)),
** PADDR (no_data),
-** SCR_COPY (sizeof (struct timeval)),
+** SCR_COPY (sizeof (ticks)),
** KVAR (KVAR_TICKS),
** NADDR (header.stamp.data),
** SCR_MOVE_TBL ^ SCR_DATA_OUT,
@@ -2964,7 +2964,7 @@ void ncr_script_fill (struct script * scr, struct scripth * scrh)
*p++ =SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN));
*p++ =PADDR (no_data);
- *p++ =SCR_COPY (sizeof (struct timeval));
+ *p++ =SCR_COPY (sizeof (ticks));
*p++ =(ncrcmd) KVAR (KVAR_TICKS);
*p++ =NADDR (header.stamp.data);
*p++ =SCR_MOVE_TBL ^ SCR_DATA_IN;
@@ -2988,7 +2988,7 @@ void ncr_script_fill (struct script * scr, struct scripth * scrh)
*p++ =SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_OUT));
*p++ =PADDR (no_data);
- *p++ =SCR_COPY (sizeof (struct timeval));
+ *p++ =SCR_COPY (sizeof (ticks));
*p++ =(ncrcmd) KVAR (KVAR_TICKS);
*p++ =NADDR (header.stamp.data);
*p++ =SCR_MOVE_TBL ^ SCR_DATA_OUT;
@@ -3755,9 +3755,11 @@ ncr_attach (pcici_t config_id, int unit)
printf ("\tinterruptless mode: reduced performance.\n");
/*
- ** Create the device queue.
+ ** Create the device queue. We only allow MAX_START-1 concurrent
+ ** transactions so we can be sure to have one element free in our
+ ** start queue to reset to the idle loop.
*/
- devq = cam_simq_alloc(MAX_START);
+ devq = cam_simq_alloc(MAX_START - 1);
if (devq == NULL)
return;
@@ -4591,13 +4593,17 @@ ncr_wakeup (ncb_p np, u_long code)
static void
ncr_freeze_devq (ncb_p np, struct cam_path *path)
{
+ nccb_p cp;
+ int count;
+ int i;
/*
** Starting at the first nccb and following
** the links, complete all jobs that match
** the passed in path and are in the start queue.
*/
- nccb_p cp = np->link_nccb;
+ cp = np->link_nccb;
+ count = 0;
while (cp) {
switch (cp->host_status) {
@@ -4606,9 +4612,8 @@ ncr_freeze_devq (ncb_p np, struct cam_path *path)
if ((cp->phys.header.launch.l_paddr
== NCB_SCRIPT_PHYS (np, select))
&& (xpt_path_comp(path, cp->ccb->ccb_h.path) >= 0)) {
- int i;
- /* Remove from the start queue */
+ /* 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] =
@@ -4616,6 +4621,7 @@ ncr_freeze_devq (ncb_p np, struct cam_path *path)
}
cp->host_status=HS_STALL;
ncr_complete (np, cp);
+ count++;
}
break;
default:
@@ -4623,6 +4629,32 @@ ncr_freeze_devq (ncb_p np, struct cam_path *path)
}
cp = cp->link_nccb;
}
+
+ if (count > 0) {
+ int j;
+ int bidx;
+
+ /* Compress the start queue */
+ j = 0;
+ bidx = np->squeueput;
+ for (i = (np->squeueput + 1) % MAX_START;;
+ i = (i + 1) % MAX_START) {
+
+ bidx = i - j;
+ if (bidx < 0)
+ bidx = MAX_START + bidx;
+
+ if (np->squeue[i] == NCB_SCRIPT_PHYS (np, skip))
+ j++;
+ else if (j != 0) {
+ np->squeue[bidx] = np->squeue[i];
+ if (np->squeue[bidx]
+ == NCB_SCRIPT_PHYS(np, idle))
+ break;
+ }
+ }
+ np->squeueput = bidx;
+ }
}
/*==========================================================
@@ -6258,8 +6290,8 @@ void ncr_int_sir (ncb_p np)
**--------------------------------------------------------------------
*/
case SIR_STALL_QUEUE:
- cp->xerr_status == XE_OK;
- cp->host_status == HS_COMPLETE;
+ cp->xerr_status = XE_OK;
+ cp->host_status = HS_COMPLETE;
cp->s_status = SCSI_STATUS_QUEUE_FULL;
ncr_freeze_devq(np, cp->ccb->ccb_h.path);
ncr_complete(np, cp);
OpenPOWER on IntegriCloud