Subject: Re: CVS commit: syssrc/sys/dev/ic
To: Chuck Silvers <chuq@chuq.com>
From: Charles Hannum <abuse@spamalicious.com>
List: source-changes
Date: 09/24/2002 13:40:51
> this change causes my ultra2 to panic:
I didn't realize quite how broken the driver was. Could you try the
following patch?
I had to do a hack for the config flags, because there aren't enough
bits, but I figure most people just turn them on or off for all
devices anyway...
Index: ncr53c9x.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/ncr53c9x.c,v
retrieving revision 1.99
diff -u -r1.99 ncr53c9x.c
--- ncr53c9x.c 2002/09/24 13:29:44 1.99
+++ ncr53c9x.c 2002/09/24 13:38:50
@@ -200,7 +200,20 @@
struct scsipi_adapter *adapt = &sc->sc_adapter;
struct scsipi_channel *chan = &sc->sc_channel;
- callout_init(&sc->sc_watchdog);
+ /*
+ * Note, the front-end has set us up to print the chip variation.
+ */
+ if (sc->sc_rev >= NCR_VARIANT_MAX) {
+ printf("\n%s: unknown variant %d, devices not attached\n",
+ sc->sc_dev.dv_xname, sc->sc_rev);
+ return;
+ }
+
+ printf(": %s, %dMHz, SCSI ID %d\n",
+ ncr53c9x_variant_names[sc->sc_rev], sc->sc_freq, sc->sc_id);
+
+ sc->sc_ntarg = (sc->sc_rev == NCR_VARIANT_FAS366) ? 16 : 8;
+
/*
* Allocate SCSI message buffers.
* Front-ends can override allocation to avoid alignment
@@ -213,22 +226,14 @@
if (sc->sc_imess == NULL)
sc->sc_imess = malloc(NCR_MAX_MSG_LEN + 1, M_DEVBUF, M_NOWAIT);
- if (sc->sc_omess == NULL || sc->sc_imess == NULL) {
- printf("out of memory\n");
- return;
- }
+ sc->sc_tinfo = malloc(sc->sc_ntarg * sizeof(sc->sc_tinfo[0]));
- /*
- * Note, the front-end has set us up to print the chip variation.
- */
- if (sc->sc_rev >= NCR_VARIANT_MAX) {
- printf("\n%s: unknown variant %d, devices not attached\n",
- sc->sc_dev.dv_xname, sc->sc_rev);
+ if (!sc->sc_omess || !sc->sc_imess || !sc->sc_tinfo) {
+ printf("out of memory\n");
return;
}
- printf(": %s, %dMHz, SCSI ID %d\n",
- ncr53c9x_variant_names[sc->sc_rev], sc->sc_freq, sc->sc_id);
+ callout_init(&sc->sc_watchdog);
/*
* Treat NCR53C90 with the 86C01 DMA chip exactly as ESP100
@@ -277,11 +282,7 @@
chan->chan_adapter = adapt;
chan->chan_bustype = &scsi_bustype;
chan->chan_channel = 0;
-#if 0 /* XXX */
- chan->chan_ntargets = (sc->sc_rev == NCR_VARIANT_FAS366) ? 16 : 8;
-#else
- chan->chan_ntargets = 8;
-#endif
+ chan->chan_ntargets = sc->sc_ntarg;
chan->chan_nluns = 8;
chan->chan_id = sc->sc_id;
@@ -449,7 +450,7 @@
TAILQ_INIT(&sc->ready_list);
sc->sc_nexus = NULL;
memset(sc->sc_tinfo, 0, sizeof(sc->sc_tinfo));
- for (r = 0; r < NCR_NTARG; r++) {
+ for (r = 0; r < sc->sc_ntarg; r++) {
LIST_INIT(&sc->sc_tinfo[r].luns);
}
} else {
@@ -461,7 +462,7 @@
ncr53c9x_done(sc, ecb);
}
/* Cancel outstanding disconnected commands on each LUN */
- for (r = 0; r < 8; r++) {
+ for (r = 0; r < sc->sc_ntarg; r++) {
LIST_FOREACH(li, &sc->sc_tinfo[r].luns, link) {
if ((ecb = li->untagged) != NULL) {
li->untagged = NULL;
@@ -492,13 +493,13 @@
ncr53c9x_reset(sc);
sc->sc_phase = sc->sc_prevphase = INVALID_PHASE;
- for (r = 0; r < 8; r++) {
+ for (r = 0; r < sc->sc_ntarg; r++) {
struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[r];
/* XXX - config flags per target: low bits: no reselect; high bits: no synch */
- ti->flags = ((sc->sc_minsync && !(sc->sc_cfflags & (1<<(r+8))))
+ ti->flags = ((sc->sc_minsync && !(sc->sc_cfflags & (1<<((r&7)+8))))
? 0 : T_SYNCHOFF) |
- ((sc->sc_cfflags & (1<<r)) ? T_RSELECTOFF : 0);
+ ((sc->sc_cfflags & (1<<(r&7))) ? T_RSELECTOFF : 0);
#ifdef DEBUG
if (ncr53c9x_notag)
ti->flags &= ~T_TAG;
@@ -905,7 +906,7 @@
ti->period = 0;
ti->offset = 0;
- if ((sc->sc_cfflags & (1<<(xm->xm_target+16))) == 0 &&
+ if ((sc->sc_cfflags & (1<<((xm->xm_target&7)+16))) == 0 &&
(xm->xm_mode & PERIPH_CAP_TQING)) {
NCR_MISC(("%s: target %d: tagged queuing\n",
sc->sc_dev.dv_xname, xm->xm_target));
@@ -2921,7 +2922,8 @@
/* XXX ASYNC CALLBACK! */
scsipi_printaddr(periph);
printf("sync negotiation disabled\n");
- sc->sc_cfflags |= (1 << (periph->periph_target + 8));
+ sc->sc_cfflags |=
+ (1 << ((periph->periph_target & 7) + 8));
ncr53c9x_update_xfer_mode(sc, periph->periph_target);
}
}
@@ -2941,7 +2943,7 @@
time_t old = time.tv_sec - (10 * 60);
s = splbio();
- for (t = 0; t < NCR_NTARG; t++) {
+ for (t = 0; t < sc->sc_ntarg; t++) {
ti = &sc->sc_tinfo[t];
li = LIST_FIRST(&ti->luns);
while (li) {
Index: ncr53c9xvar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/ic/ncr53c9xvar.h,v
retrieving revision 1.37
diff -u -r1.37 ncr53c9xvar.h
--- ncr53c9xvar.h 2002/08/26 06:23:32 1.37
+++ ncr53c9xvar.h 2002/09/24 13:38:50
@@ -70,7 +70,6 @@
/* #define NCR53C9X_DEBUG 1 */
/* Wide or differential can have 16 targets */
-#define NCR_NTARG 8
#define NCR_NLUN 8
#define NCR_ABORT_TIMEOUT 2000 /* time to wait for abort */
@@ -299,7 +298,8 @@
ready_list;
struct ncr53c9x_ecb *sc_nexus; /* Current command */
- struct ncr53c9x_tinfo sc_tinfo[NCR_NTARG];
+ int sc_ntarg;
+ struct ncr53c9x_tinfo *sc_tinfo;
/* Data about the current nexus (updated for every cmd switch) */
caddr_t sc_dp; /* Current data pointer */