Subject: ahc and Semantics of the "COMPLETE" return code
To: None <tech-kern@NetBSD.ORG>
From: Manuel BOUYER <bouyer@antioche.ibp.fr>
List: tech-kern
Date: 06/23/1997 11:31:10
Hi,
while browsing the SCSI code, I've found the reason of a problem
I didn't have the time to track down before.
While heavy disk IO with several, specially with an ASYNC-mounted ext2 file
system, I occasionally sees a message from the ahc driver:
ahc_scsi_cmd: more than 256 DMA segs
and then one of the processes is stuck in the "D" state.
Looking at the code, this messages comes from ahc_scsi_cmd():
        if (datalen) {
		/* there's still data, must have run out of segs! */
			printf("%s: ahc_scsi_cmd: more than %d DMA segs\n",
				ahc_name(ahc), AHC_NSEG);
			xs->error = XS_DRIVER_STUFFUP;
			ahc_free_scb(ahc, scb, flags);
			return (COMPLETE);  
		}

ahc_scsi_cmd() is called from scsi_execute_xs(), which, when it gets the
"COMPLETE" return status, does:
    case COMPLETE:      /* Polling command completed ok */
		if (xs->bp)
			return EJUSTRETURN;
doit:
		SC_DEBUG(xs->sc_link, SDEV_DB3, ("back in cmd()\n"));
		if ((error = sc_err1(xs, 0)) != ERESTART)
			return error;
		goto retry;

So there has been an error, but it is just ignored by scsi_execute_xs()
by the two lines "if (xs->bp) return EJUSTRETURN;" when there is a buffer.
As the driver has throw away the command, this buffer will never
get the biodone().
What I can't understand here is this "if (xs->bp)" case. If the driver
returned COMPLETE, then the command is done, so why not let sc_err1 process
it, and biodone() the buffer if needed ?
This is a rather anoying bug, as I have to reboot the box after such an error.

Now, about this specific ahc error (and this is why I've put Justin in Cc:)
This error is quite reproductible, bus this sounds like a resources shortage
rather than a real error. The process causing the error (and staying in the
"D" state) can be doing large or small IO's, on an ffs or ext2fs.
I think the reason ext2fs triggers this more easily is because it uses a lot
of small blocks (1k blocks without clustering). So the question is:
should't the driver return an error code wich would cause the command to be
tried again, rather than an EIO ?

--
Manuel Bouyer, LIP6, Universite Paris VI.                 bouyer@masi.ibp.fr
--