Subject: uda.c versus 3rd party controllers
To: None <port-vax@NetBSD.ORG>
From: Ken Wellsch <kcwellsc@math.uwaterloo.ca>
List: port-vax
Date: 08/30/1995 10:16:42
We have a number of different Dilog MSCP controllers, for both SCSI and
SMD and while playing with an SMD version (DQ256) I was reminded again
of some local stuff we did to handle certain "features" of these
controllers.

The bottom line is that they just don't work when polled too fast (I
suspect their processor cannot do its thing and respond to constant
register polling at the same time).

We also found that our SCSI versions (SQ706A and SU726A) while going
through the initialization steps on start up needed to be queried an
extra time or so to get a successful response.

Here is a massaged copy of our changes to give the flavor of what we did,
if for some reason anyone has found they've got a 3rd party controller
that just doesn't respond as I have on several occasions over the years.

% diff waterloo-uda.c netbsd-uda.c
==============================================================
< 	while ( count < DELAYTEN ) {
< 		if ( (udaddr->udasa & UDA_STEP1) != 0 )
< 			break;
< 		DELAY(10000);
< 		count += 1;
< 	}
< 
< 	/* nothing there */
< 	if ( count == DELAYTEN )
< 		return(0);
---
> 	timeout = todr() + 1000;	/* timeout in 10 seconds */
> 	while ((udaddr->udasa & UDA_STEP1) == 0)
> 		if (todr() > timeout)
> 			goto bad;
==============================================================
< 	count = 0;
< 	while ( count < DELAYTEN ) {
< 	    if ( (udaddr->udasa & UDA_STEP2 ) != 0 )
< 		break;
< 	    DELAY(10000);
< 	    count += 1;
< 	    }
< 	
< 	if ( count == DELAYTEN ) {
< 	    printf("udaprobe: uda%d: init step2 no change.\n",
< 		   um->um_ctlr);
< 	    goto bad;
< 	    }
---
> 	while ((udaddr->udasa & UDA_STEP2) == 0)
> 		if (todr() > timeout)
> 			goto bad;
==============================================================
< 	count = 0;
< 	while ( count < DELAYTEN ) {
< 	    if ( (udaddr->udasa & UDA_STEP1) != 0 )
< 		break;
< 	    DELAY(10000);
< 	    count += 1;
< 	    }
< 	if ( count == DELAYTEN ) {
< 	    printf("uda%d: timeout during init\n", ctlr);
< 	    return (-1);
< 	    }
---
> 	timo = todr() + 1000;
> 	while ((udaddr->udasa & STEP0MASK) == 0) {
> 		if (todr() > timo) {
> 			printf("uda%d: timeout during init\n", ctlr);
> 			return (-1);
> 		}
> 	}
==============================================================
< #define DELAYTEN 1000
< #define Wait_step( mask, result, status ) { \
< 	status = 1; \
< 	if ( (udaddr->udasa & mask) != result ) { \
< 		int count = 0; \
< 		while ( (udaddr->udasa & mask) != result ) { \
< 			DELAY(100); \
< 			count += 1; \
< 			if (count > DELAYTEN) \
< 				break; \
< 		} \
< 		if (count > DELAYTEN) \
< 			status = 0; \
< 	} \
< }
==============================================================
< 		i = 0;
< 		Wait_step(STEP1MASK, STEP1GOOD, wait_status);
< 		if ( !wait_status ) {
---
> 		if ((udaddr->udasa & STEP1MASK) != STEP1GOOD) {
> 			i = 1;
==============================================================
< 		i = 2;
< 		Wait_step(STEP2MASK, STEP2GOOD, wait_status);
< 		if ( !wait_status )
< 		    goto initfailed;
< 
---
> 		if ((udaddr->udasa & STEP2MASK) != STEP2GOOD) {
> 			i = 2;
> 			goto initfailed;
> 		}
==============================================================
< 		i = 3;
< 		Wait_step(STEP3MASK, STEP3GOOD, wait_status);
< 		if ( !wait_status )
< 		    goto initfailed;
< 		
---
> 		if ((udaddr->udasa & STEP3MASK) != STEP3GOOD) {
> 			i = 3;
> 			goto initfailed;
> 		}
==============================================================