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: