Subject: port-sparc/2169: sparc: xd driver bugs (derived from sun3 fix)
To: None <gnats-bugs@NetBSD.ORG>
From: Don Koch <aardvark@poirot.krl.com>
List: netbsd-bugs
Date: 03/03/1996 18:56:14
>Number:         2169
>Category:       port-sparc
>Synopsis:       Xylogics 753 (xd) driver dies during boot
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Mar  3 19:20:03 1996
>Last-Modified:
>Originator:     Don Koch
>Organization:
	Koch Research Labs
>Release:        NetBSD-current-960302
>Environment:
	Sun-4/vme, NetBSD, sparc, na
System: NetBSD poirot 1.1A NetBSD 1.1A (SMD_DMK) #2: Sun Mar 3 17:32:02 EST 1996 aardvark@poirot:/usr/src/sys/arch/sun3/compile/SMD_DMK sun3


>Description:
	Assumeably, the Sun-4/xxx vme boxes with Xylogics SMD controllers
	have been having problems with using the xd code: bad dvma addrs
	and/or other random crashes.  A fix derived from the sun3 fix
	is included below.

	Problem stems from (a) not checking pointers for null before using
	them and (b) trying to |= into a virtual write only address
	(the control and status register is status when read, control when
	written; |= reads the status, ors in a bit and then writes it back
	out as a control code with semi-meaningless results).

>How-To-Repeat:
	Configure SMD kernel with xd controller, add Xylogics 753/7053, boot,
	watch it die.
>Fix:
	Assuming the bugs I fixed in the sun3 code are correct, apply the
	following patch (use at your own descretion, this is *UNTESTED*
	code):
--- xd.c.org	Mon Feb 26 07:22:30 1996
+++ xd.c	Sun Mar  3 18:30:40 1996
@@ -143,7 +143,7 @@
 	(ADDR) = ((ADDR) >> 8); \
 	(XDC)->xdc_iopbaddr3 = (ADDR); \
 	(XDC)->xdc_iopbamod = XDC_ADDRMOD; \
-	(XDC)->xdc_csr |= XDC_ADDIOPB; /* go! */ \
+	(XDC)->xdc_csr = XDC_ADDIOPB; /* go! */ \
 }
 
 /*
@@ -415,9 +415,9 @@
 
 	xdc->reqs = (struct xd_iorq *)
 	    malloc(XDC_MAXIOPB * sizeof(struct xd_iorq), M_DEVBUF, M_NOWAIT);
-	bzero(xdc->reqs, XDC_MAXIOPB * sizeof(struct xd_iorq));
 	if (xdc->reqs == NULL)
 		panic("xdc malloc");
+	bzero(xdc->reqs, XDC_MAXIOPB * sizeof(struct xd_iorq));
 
 	/* init free list, iorq to iopb pointers, and non-zero fields in the
 	 * iopb which never change. */
@@ -1662,7 +1662,7 @@
 		if (del <= 0)
 			panic("xdc_reset");
 	} else {
-		xdcsc->xdc->xdc_csr |= XDC_CLRRIO;	/* clear RIO */
+		xdcsc->xdc->xdc_csr = XDC_CLRRIO;	/* clear RIO */
 	}
 	bcopy(&tmpiopb, xdcsc->iopbase, sizeof(tmpiopb));
 }
@@ -1833,7 +1833,7 @@
 	 * done bit.
 	 */
 	if (xdc->xdc_csr & XDC_REMIOPB) {
-		xdc->xdc_csr |= XDC_CLRRIO;
+		xdc->xdc_csr = XDC_CLRRIO;
 	}
 
 	for (rqno = 0; rqno < XDC_MAXIOPB; rqno++) {

>Audit-Trail:
>Unformatted: