@@ 1103,7 1103,7 @@ write_mismatch_recover(Controller *c, Ncr *n, Dsa *dsa)
}
static void
-interrupt(Ureg *ur, void *a)
+sd53c8xxinterrupt(Ureg *ur, void *a)
{
uchar istat;
ushort sist;
@@ 1581,7 1581,7 @@ reset(Controller *c)
}
static int
-symrio(SDreq* r)
+sd53c8xxrio(SDreq* r)
{
Dsa *d;
uchar *bp;
@@ 1896,7 1896,7 @@ na_fixup(Controller *c, ulong pa_reg,
}
static SDev*
-sympnp(void)
+sd53c8xxpnp(void)
{
char *cp;
Pcidev *p;
@@ 1985,6 1985,14 @@ buggery:
ctlr->v = v;
ctlr->script = script;
memmove(ctlr->script, na_script, sizeof(na_script));
+
+ /*
+ * Because we don't yet have an abstraction for the
+ * addresses as seen from the controller side (and on
+ * the 386 it doesn't matter), the follwong two lines
+ * are different between the 386 and alpha copies of
+ * this driver.
+ */
ctlr->scriptpa = p->mem[ba].bar & ~0x0F;
if(!na_fixup(ctlr, p->mem[1].bar & ~0x0F, na_patches, NA_PATCHES, xfunc)){
print("script fixup failed\n");
@@ 2018,13 2026,13 @@ buggery:
}
static SDev*
-symid(SDev* sdev)
+sd53c8xxid(SDev* sdev)
{
return scsiid(sdev, &sd53c8xxifc);
}
static int
-symenable(SDev* sdev)
+sd53c8xxenable(SDev* sdev)
{
Pcidev *pcidev;
Controller *ctlr;
@@ 2035,7 2043,7 @@ symenable(SDev* sdev)
pcisetbme(pcidev);
snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
- intrenable(pcidev->intl, interrupt, ctlr, pcidev->tbdf, name);
+ intrenable(pcidev->intl, sd53c8xxinterrupt, ctlr, pcidev->tbdf, name);
ilock(ctlr);
synctabinit(ctlr);
@@ 2049,18 2057,20 @@ symenable(SDev* sdev)
SDifc sd53c8xxifc = {
"53c8xx", /* name */
- sympnp, /* pnp */
+ sd53c8xxpnp, /* pnp */
nil, /* legacy */
- symid, /* id */
- symenable, /* enable */
+ sd53c8xxid, /* id */
+ sd53c8xxenable, /* enable */
nil, /* disable */
scsiverify, /* verify */
scsionline, /* online */
- symrio, /* rio */
+ sd53c8xxrio, /* rio */
nil, /* rctl */
nil, /* wctl */
scsibio, /* bio */
+ nil, /* probe */
+ nil, /* clear */
+ nil, /* stat */
};
-
@@ 2,6 2,8 @@
* NCR/Symbios/LSI Logic 53c8xx driver for Plan 9
* Nigel Roles (nigel@9fs.org)
*
+ * 13/3/01 Fixed microcode to support targets > 7
+ *
* 01/12/00 Removed previous comments. Fixed a small problem in
* mismatch recovery for targets with synchronous offsets of >=16
* connected to >=875s. Thanks, Jean.
@@ 60,13 62,13 @@ extern SDifc sd53c8xxifc;
/*******************************/
#ifndef DMASEG
-#define DMASEG(x) PADDR(x)
+#define DMASEG(x) PCIWADDR(x)
#define legetl(x) (*(ulong*)(x))
#define lesetl(x,v) (*(ulong*)(x) = (v))
#define swabl(a,b,c)
#else
#endif /*DMASEG */
-#define DMASEG_TO_KADDR(x) KADDR(PADDR(x))
+#define DMASEG_TO_KADDR(x) KADDR((x)-PCIWINDOW)
#define KPTR(x) ((x) == 0 ? 0 : DMASEG_TO_KADDR(x))
#define MEGA 1000000L
@@ 198,20 200,12 @@ typedef enum State {
} State;
typedef struct Dsa {
- union {
- uchar state[4];
- struct {
- uchar stateb;
- uchar result;
- uchar dmablks;
- uchar flag; /* setbyte(state,3,...) */
- };
- };
-
- union {
- ulong dmancr; /* For block transfer: NCR order (little-endian) */
- uchar dmaaddr[4];
- };
+ uchar stateb;
+ uchar result;
+ uchar dmablks;
+ uchar flag; /* setbyte(state,3,...) */
+
+ uchar dmaaddr[4];
uchar target; /* Target */
uchar pad0[3];
@@ 313,6 307,7 @@ typedef struct Controller {
} Controller;
#define SYNCOFFMASK(c) (((c)->v->maxsyncoff * 2) - 1)
+#define SSIDMASK(c) (((c)->v->feature & Wide) ? 15 : 7)
/* ISTAT */
enum { Abrt = 0x80, Srst = 0x40, Sigp = 0x20, Sem = 0x10, Con = 0x08, Intf = 0x04, Sip = 0x02, Dip = 0x01 };
@@ 394,7 389,7 @@ dsaalloc(Controller *c, int target, int lun)
if (DEBUG(1))
KPRINT(PRINTPREFIX "%d/%d: allocated new dsa %lux\n", target, lun, (ulong)d);
lesetl(d->next, 0);
- lesetl(d->state, A_STATE_ALLOCATED);
+ lesetl(&d->stateb, A_STATE_ALLOCATED);
if (legetl(c->dsalist.head) == 0)
lesetl(c->dsalist.head, DMASEG(d)); /* ATOMIC?!? */
else
@@ 405,7 400,7 @@ dsaalloc(Controller *c, int target, int lun)
if (DEBUG(1))
KPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d);
c->dsalist.freechain = d->freechain;
- lesetl(d->state, A_STATE_ALLOCATED);
+ lesetl(&d->stateb, A_STATE_ALLOCATED);
}
iunlock(&c->dsalist);
d->target = target;
@@ 419,7 414,7 @@ dsafree(Controller *c, Dsa *d)
ilock(&c->dsalist);
d->freechain = c->dsalist.freechain;
c->dsalist.freechain = d;
- lesetl(d->state, A_STATE_FREE);
+ lesetl(&d->stateb, A_STATE_FREE);
iunlock(&c->dsalist);
}
@@ 1108,7 1103,7 @@ write_mismatch_recover(Controller *c, Ncr *n, Dsa *dsa)
}
static void
-interrupt(Ureg *ur, void *a)
+sd53c8xxinterrupt(Ureg *ur, void *a)
{
uchar istat;
ushort sist;
@@ 1201,7 1196,7 @@ interrupt(Ureg *ur, void *a)
dsa->dmablks, legetl(dsa->dmaaddr),
legetl(dsa->data_buf.pa), legetl(dsa->data_buf.dbc));
n->scratcha[2] = dsa->dmablks;
- lesetl(n->scratchb, dsa->dmancr);
+ lesetl(n->scratchb, *(ulong*)dsa->dmaaddr);
cont = E_data_block_mismatch_recover;
}
else if (sa == E_data_out_mismatch) {
@@ 1228,7 1223,7 @@ interrupt(Ureg *ur, void *a)
dmablks * A_BSIZE - tbc + legetl(dsa->data_buf.dbc));
/* copy changes into scratch registers */
n->scratcha[2] = dsa->dmablks;
- lesetl(n->scratchb, dsa->dmancr);
+ lesetl(n->scratchb, *(ulong*)dsa->dmaaddr);
cont = E_data_block_mismatch_recover;
}
else if (sa == E_id_out_mismatch) {
@@ 1338,8 1333,8 @@ interrupt(Ureg *ur, void *a)
break;
case A_SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT:
IPRINT(PRINTPREFIX "%d: not msg_in after reselect (%s)",
- n->ssid & 7, phase[n->sstat1 & 7]);
- dsa = dsafind(c, n->ssid & 7, -1, A_STATE_DISCONNECTED);
+ n->ssid & SSIDMASK(c), phase[n->sstat1 & 7]);
+ dsa = dsafind(c, n->ssid & SSIDMASK(c), -1, A_STATE_DISCONNECTED);
dumpncrregs(c, 1);
wakeme = 1;
break;
@@ 1439,6 1434,12 @@ interrupt(Ureg *ur, void *a)
dsa->target, dsa->lun);
cont = -2;
break;
+ case A_error_reselected: /* dsa isn't valid here */
+ print(PRINTPREFIX "reselection error\n");
+ dumpncrregs(c, 1);
+ for (dsa = KPTR(legetl(c->dsalist.head)); dsa; dsa = KPTR(legetl(dsa->next)))
+ IPRINT(PRINTPREFIX "dsa target %d lun %d state %d\n", dsa->target, dsa->lun, dsa->stateb);
+ break;
default:
IPRINT(PRINTPREFIX "%d/%d: script error %ld\n",
dsa->target, dsa->lun, legetl(n->dsps));
@@ 1580,7 1581,7 @@ reset(Controller *c)
}
static int
-symrio(SDreq* r)
+sd53c8xxrio(SDreq* r)
{
Dsa *d;
uchar *bp;
@@ 1749,7 1750,7 @@ docheck:
* Clear out the microcode state
* so the Dsa can be re-used.
*/
- lesetl(d->state, A_STATE_ALLOCATED);
+ lesetl(&d->stateb, A_STATE_ALLOCATED);
goto docheck;
}
qunlock(&c->q[target]);
@@ 1835,6 1836,8 @@ xfunc(Controller *c, enum na_external x, unsigned long *v)
*v = offsetof(Dsa, status_buf); return 1;
case X_dsa_head:
*v = DMASEG(&c->dsalist.head[0]); return 1;
+ case X_ssid_mask:
+ *v = SSIDMASK(c); return 1;
default:
print("xfunc: can't find external %d\n", x);
return 0;
@@ 1893,7 1896,7 @@ na_fixup(Controller *c, ulong pa_reg,
}
static SDev*
-sympnp(void)
+sd53c8xxpnp(void)
{
char *cp;
Pcidev *p;
@@ 1982,6 1985,14 @@ buggery:
ctlr->v = v;
ctlr->script = script;
memmove(ctlr->script, na_script, sizeof(na_script));
+
+ /*
+ * Because we don't yet have an abstraction for the
+ * addresses as seen from the controller side (and on
+ * the 386 it doesn't matter), the follwong two lines
+ * are different between the 386 and alpha copies of
+ * this driver.
+ */
ctlr->scriptpa = scriptpa;
if(!na_fixup(ctlr, regpa, na_patches, NA_PATCHES, xfunc)){
print("script fixup failed\n");
@@ 2015,13 2026,13 @@ buggery:
}
static SDev*
-symid(SDev* sdev)
+sd53c8xxid(SDev* sdev)
{
return scsiid(sdev, &sd53c8xxifc);
}
static int
-symenable(SDev* sdev)
+sd53c8xxenable(SDev* sdev)
{
Pcidev *pcidev;
Controller *ctlr;
@@ 2032,7 2043,7 @@ symenable(SDev* sdev)
pcisetbme(pcidev);
snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
- intrenable(pcidev->intl, interrupt, ctlr, pcidev->tbdf, name);
+ intrenable(pcidev->intl, sd53c8xxinterrupt, ctlr, pcidev->tbdf, name);
ilock(ctlr);
synctabinit(ctlr);
@@ 2046,15 2057,15 @@ symenable(SDev* sdev)
SDifc sd53c8xxifc = {
"53c8xx", /* name */
- sympnp, /* pnp */
+ sd53c8xxpnp, /* pnp */
nil, /* legacy */
- symid, /* id */
- symenable, /* enable */
+ sd53c8xxid, /* id */
+ sd53c8xxenable, /* enable */
nil, /* disable */
scsiverify, /* verify */
scsionline, /* online */
- symrio, /* rio */
+ sd53c8xxrio, /* rio */
nil, /* rctl */
nil, /* wctl */
@@ 2063,4 2074,3 @@ SDifc sd53c8xxifc = {
nil, /* clear */
nil, /* stat */
};
-