Subject: port-sun3/2168: sun3: xd driver dies on boot
To: None <gnats-bugs@NetBSD.ORG>
From: Don Koch <aardvark@poirot.krl.com>
List: netbsd-bugs
Date: 03/03/1996 18:47:53
>Number: 2168
>Category: port-sun3
>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:05:03 1996
>Last-Modified:
>Originator: Don Koch
>Organization:
Koch Research Labs
>Release: NetBSD-current-960302
>Environment:
Sun 3/280, NetBSD-current, sun3, 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:
xd driver dies with bad dvma_kvtopa() call:
Jan 30 19:09:26 poirot /netbsd: xdc0 at vmel0 addr 0xffffee80 level 2 vector 0x44panic: dvma_kvtopa: bad dmva addr=0x0
Jan 30 19:09:26 poirot /netbsd:
Jan 30 19:09:26 poirot /netbsd: trap type=0x0, code=0x145, v=0x37006442
Jan 30 19:09:26 poirot /netbsd: kernel: Bus error trap
Jan 30 19:09:26 poirot /netbsd: syncing disks... trap type=0x8, code=0x145, v=0x0
Jan 30 19:09:27 poirot /netbsd: kernel: MMU fault trap
Jan 30 19:09:27 poirot /netbsd: trap during panic!
Problem stems from (a) not checking pointers for null before using
them (twice!) 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 with xd driver, add one Xylogics 753/7053, boot well.
>Fix:
Apply following patch:
--- xd.c.org Thu Feb 22 07:42:00 1996
+++ xd.c Sun Mar 3 18:31:49 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! */ \
}
/*
@@ -402,9 +402,9 @@
dvma_kvtopa((long) xdc->iopbase, BUS_VME32);
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. */
@@ -1257,8 +1257,8 @@
block = block / iorq->xd->nhead;
iopb->cylno = block;
}
- dp = dvma_kvtopa((long)iorq->dbuf, BUS_VME32);
- iopb->daddr = dp = (iorq->dbuf == NULL) ? 0 : dp;
+ iopb->daddr = dp = (iorq->dbuf == NULL) ? 0 :
+ dvma_kvtopa((long)iorq->dbuf, BUS_VME32);
iopb->addrmod = XDC_ADDRMOD;
}
}
@@ -1646,7 +1646,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));
}
@@ -1815,7 +1815,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: