sd53c8xx: fix the driver for amd64, fix alignment/padding issues, fix freechain handling
This commit is contained in:
parent
87c8fa5415
commit
d32e5d130c
|
@ -31,10 +31,6 @@ extern SDifc sd53c8xxifc;
|
||||||
/* Portable configuration macros */
|
/* Portable configuration macros */
|
||||||
/**********************************/
|
/**********************************/
|
||||||
|
|
||||||
//#define BOOTDEBUG
|
|
||||||
//#define ASYNC_ONLY
|
|
||||||
//#define INTERNAL_SCLK
|
|
||||||
//#define ALWAYS_DO_WDTR
|
|
||||||
#define WMR_DEBUG
|
#define WMR_DEBUG
|
||||||
|
|
||||||
/**********************************/
|
/**********************************/
|
||||||
|
@ -43,36 +39,23 @@ extern SDifc sd53c8xxifc;
|
||||||
|
|
||||||
#define PRINTPREFIX "sd53c8xx: "
|
#define PRINTPREFIX "sd53c8xx: "
|
||||||
|
|
||||||
#ifdef BOOTDEBUG
|
static int idebug = 0;
|
||||||
|
|
||||||
#define KPRINT oprint
|
|
||||||
#define IPRINT intrprint
|
|
||||||
#define DEBUG(n) 1
|
|
||||||
#define IFLUSH() iflush()
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static int idebug = 1;
|
|
||||||
#define KPRINT if(0) iprint
|
#define KPRINT if(0) iprint
|
||||||
#define IPRINT if(idebug) iprint
|
#define IPRINT if(idebug) iprint
|
||||||
#define DEBUG(n) (0)
|
#define DEBUG(n) (0)
|
||||||
#define IFLUSH()
|
#define IFLUSH()
|
||||||
|
|
||||||
#endif /* BOOTDEBUG */
|
|
||||||
|
|
||||||
/*******************************/
|
/*******************************/
|
||||||
/* General */
|
/* General */
|
||||||
/*******************************/
|
/*******************************/
|
||||||
|
|
||||||
#ifndef DMASEG
|
|
||||||
#define DMASEG(x) PCIWADDR(x)
|
#define DMASEG(x) PCIWADDR(x)
|
||||||
#define legetl(x) (*(ulong*)(x))
|
#define legetl(x) (*(ulong*)(x))
|
||||||
#define lesetl(x,v) (*(ulong*)(x) = (v))
|
#define lesetl(x,v) (*(ulong*)(x) = (v))
|
||||||
#define swabl(a,b,c)
|
#define swabl(a,b,c)
|
||||||
#else
|
#define DMASEG_TO_PADDR(x) ((uintptr)(x)-PCIWINDOW)
|
||||||
#endif /*DMASEG */
|
#define DMASEG_TO_KADDR(x) KADDR(DMASEG_TO_PADDR(x))
|
||||||
#define DMASEG_TO_KADDR(x) KADDR((x)-PCIWINDOW)
|
#define KPTR(x) (((x) == 0) ? nil : DMASEG_TO_KADDR(x))
|
||||||
#define KPTR(x) ((x) == 0 ? 0 : DMASEG_TO_KADDR(x))
|
|
||||||
|
|
||||||
#define MEGA 1000000L
|
#define MEGA 1000000L
|
||||||
#ifdef INTERNAL_SCLK
|
#ifdef INTERNAL_SCLK
|
||||||
|
@ -209,10 +192,7 @@ struct Dsa {
|
||||||
uchar dmablks;
|
uchar dmablks;
|
||||||
uchar flag; /* setbyte(state,3,...) */
|
uchar flag; /* setbyte(state,3,...) */
|
||||||
|
|
||||||
union {
|
uchar dmaaddr[4]; /* For block transfer: NCR order (little-endian) */
|
||||||
ulong dmancr; /* For block transfer: NCR order (little-endian) */
|
|
||||||
uchar dmaaddr[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
uchar target; /* Target */
|
uchar target; /* Target */
|
||||||
uchar pad0[3];
|
uchar pad0[3];
|
||||||
|
@ -220,18 +200,21 @@ struct Dsa {
|
||||||
uchar lun; /* Logical Unit Number */
|
uchar lun; /* Logical Unit Number */
|
||||||
uchar pad1[3];
|
uchar pad1[3];
|
||||||
|
|
||||||
uchar scntl3;
|
uchar scntl3; /* Sync */
|
||||||
uchar sxfer;
|
uchar sxfer;
|
||||||
uchar pad2[2];
|
uchar pad2[2];
|
||||||
|
|
||||||
uchar next[4]; /* chaining for SCRIPT (NCR byte order) */
|
uchar next[4]; /* chaining for SCRIPT (NCR byte order) */
|
||||||
|
|
||||||
Dsa *freechain; /* chaining for freelist */
|
Dsa *freechain; /* chaining for freelist */
|
||||||
Rendez;
|
Rendez;
|
||||||
|
|
||||||
uchar scsi_id_buf[4];
|
uchar scsi_id_buf[4];
|
||||||
Movedata msg_out_buf;
|
Movedata msg_out_buf;
|
||||||
Movedata cmd_buf;
|
Movedata cmd_buf;
|
||||||
Movedata data_buf;
|
Movedata data_buf;
|
||||||
Movedata status_buf;
|
Movedata status_buf;
|
||||||
|
|
||||||
uchar msg_out[10]; /* enough to include SDTR */
|
uchar msg_out[10]; /* enough to include SDTR */
|
||||||
uchar status;
|
uchar status;
|
||||||
int p9status;
|
int p9status;
|
||||||
|
@ -382,7 +365,7 @@ oprint(char *format, ...)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sd53c8xx.i"
|
#include "../pc/sd53c8xx.i"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We used to use a linked list of Dsas with nil as the terminator,
|
* We used to use a linked list of Dsas with nil as the terminator,
|
||||||
|
@ -398,38 +381,31 @@ oprint(char *format, ...)
|
||||||
*/
|
*/
|
||||||
static Dsa *dsaend;
|
static Dsa *dsaend;
|
||||||
|
|
||||||
static Dsa*
|
|
||||||
dsaallocnew(Controller *c)
|
|
||||||
{
|
|
||||||
Dsa *d;
|
|
||||||
|
|
||||||
/* c->dsalist must be ilocked */
|
|
||||||
d = xalloc(sizeof *d);
|
|
||||||
if (d == nil)
|
|
||||||
panic("sd53c8xx dsaallocnew: no memory");
|
|
||||||
lesetl(d->next, legetl(c->dsalist.head));
|
|
||||||
lesetl(&d->stateb, A_STATE_FREE);
|
|
||||||
coherence();
|
|
||||||
lesetl(c->dsalist.head, DMASEG(d));
|
|
||||||
coherence();
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Dsa *
|
static Dsa *
|
||||||
dsaalloc(Controller *c, int target, int lun)
|
dsaalloc(Controller *c, int target, int lun)
|
||||||
{
|
{
|
||||||
Dsa *d;
|
Dsa *d;
|
||||||
|
|
||||||
ilock(&c->dsalist);
|
ilock(&c->dsalist);
|
||||||
if ((d = c->dsalist.freechain) != 0) {
|
if ((d = c->dsalist.freechain) != nil) {
|
||||||
|
c->dsalist.freechain = d->freechain;
|
||||||
|
d->freechain = nil;
|
||||||
if (DEBUG(1))
|
if (DEBUG(1))
|
||||||
IPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d);
|
IPRINT(PRINTPREFIX "%d/%d: reused dsa %#p\n", target, lun, d);
|
||||||
} else {
|
} else {
|
||||||
d = dsaallocnew(c);
|
/* c->dsalist must be ilocked */
|
||||||
|
d = xalloc(sizeof *d);
|
||||||
|
if (d == nil)
|
||||||
|
panic("sd53c8xx dsaallocnew: no memory");
|
||||||
|
d->freechain = nil;
|
||||||
|
lesetl(d->next, legetl(c->dsalist.head));
|
||||||
|
lesetl(&d->stateb, A_STATE_FREE);
|
||||||
|
coherence();
|
||||||
|
lesetl(c->dsalist.head, DMASEG(d));
|
||||||
|
coherence();
|
||||||
if (DEBUG(1))
|
if (DEBUG(1))
|
||||||
IPRINT(PRINTPREFIX "%d/%d: allocated dsa %lux\n", target, lun, (ulong)d);
|
IPRINT(PRINTPREFIX "%d/%d: allocated dsa %#p\n", target, lun, d);
|
||||||
}
|
}
|
||||||
c->dsalist.freechain = d->freechain;
|
|
||||||
lesetl(&d->stateb, A_STATE_ALLOCATED);
|
lesetl(&d->stateb, A_STATE_ALLOCATED);
|
||||||
iunlock(&c->dsalist);
|
iunlock(&c->dsalist);
|
||||||
d->target = target;
|
d->target = target;
|
||||||
|
@ -454,11 +430,7 @@ dsadump(Controller *c)
|
||||||
u32int *a;
|
u32int *a;
|
||||||
|
|
||||||
iprint("dsa controller list: c=%p head=%.8lux\n", c, legetl(c->dsalist.head));
|
iprint("dsa controller list: c=%p head=%.8lux\n", c, legetl(c->dsalist.head));
|
||||||
for(d=KPTR(legetl(c->dsalist.head)); d != dsaend; d=KPTR(legetl(d->next))){
|
for(d=KPTR(legetl(c->dsalist.head)); d != nil && d != dsaend; d=KPTR(legetl(d->next))){
|
||||||
if(d == (void*)-1){
|
|
||||||
iprint("\t dsa %p\n", d);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
a = (u32int*)d;
|
a = (u32int*)d;
|
||||||
iprint("\tdsa %p %.8ux %.8ux %.8ux %.8ux %.8ux %.8ux\n", a, a[0], a[1], a[2], a[3], a[4], a[5]);
|
iprint("\tdsa %p %.8ux %.8ux %.8ux %.8ux %.8ux %.8ux\n", a, a[0], a[1], a[2], a[3], a[4], a[5]);
|
||||||
}
|
}
|
||||||
|
@ -490,7 +462,8 @@ static Dsa *
|
||||||
dsafind(Controller *c, uchar target, uchar lun, uchar state)
|
dsafind(Controller *c, uchar target, uchar lun, uchar state)
|
||||||
{
|
{
|
||||||
Dsa *d;
|
Dsa *d;
|
||||||
for (d = KPTR(legetl(c->dsalist.head)); d != dsaend; d = KPTR(legetl(d->next))) {
|
|
||||||
|
for (d = KPTR(legetl(c->dsalist.head)); d != nil && d != dsaend; d = KPTR(legetl(d->next))) {
|
||||||
if (d->target != 0xff && d->target != target)
|
if (d->target != 0xff && d->target != target)
|
||||||
continue;
|
continue;
|
||||||
if (lun != 0xff && d->lun != lun)
|
if (lun != 0xff && d->lun != lun)
|
||||||
|
@ -1206,11 +1179,11 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
|
||||||
}
|
}
|
||||||
n->istat = Intf;
|
n->istat = Intf;
|
||||||
/* search for structures in A_STATE_DONE */
|
/* search for structures in A_STATE_DONE */
|
||||||
for (d = KPTR(legetl(c->dsalist.head)); d != dsaend; d = KPTR(legetl(d->next))) {
|
for (d = KPTR(legetl(c->dsalist.head)); d != nil && d != dsaend; d = KPTR(legetl(d->next))) {
|
||||||
if (d->stateb == A_STATE_DONE) {
|
if (d->stateb == A_STATE_DONE) {
|
||||||
d->p9status = d->status;
|
d->p9status = d->status;
|
||||||
if (DEBUG(1)) {
|
if (DEBUG(1)) {
|
||||||
IPRINT(PRINTPREFIX "waking up dsa %lux\n", (ulong)d);
|
IPRINT(PRINTPREFIX "waking up dsa %#p\n", d);
|
||||||
}
|
}
|
||||||
wakeup(d);
|
wakeup(d);
|
||||||
wokesomething = 1;
|
wokesomething = 1;
|
||||||
|
@ -1236,7 +1209,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
|
||||||
/*
|
/*
|
||||||
* Can't compute dsa until we know that dsapa is valid.
|
* Can't compute dsa until we know that dsapa is valid.
|
||||||
*/
|
*/
|
||||||
if(dsapa < -KZERO)
|
if(DMASEG_TO_PADDR(dsapa) < -KZERO)
|
||||||
dsa = (Dsa*)DMASEG_TO_KADDR(dsapa);
|
dsa = (Dsa*)DMASEG_TO_KADDR(dsapa);
|
||||||
else{
|
else{
|
||||||
dsa = nil;
|
dsa = nil;
|
||||||
|
@ -1307,7 +1280,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
|
||||||
dsa->dmablks, legetl(dsa->dmaaddr),
|
dsa->dmablks, legetl(dsa->dmaaddr),
|
||||||
legetl(dsa->data_buf.pa), legetl(dsa->data_buf.dbc));
|
legetl(dsa->data_buf.pa), legetl(dsa->data_buf.dbc));
|
||||||
n->scratcha[2] = dsa->dmablks;
|
n->scratcha[2] = dsa->dmablks;
|
||||||
lesetl(n->scratchb, dsa->dmancr);
|
lesetl(n->scratchb, *((ulong*)dsa->dmaaddr));
|
||||||
cont = E_data_block_mismatch_recover;
|
cont = E_data_block_mismatch_recover;
|
||||||
}
|
}
|
||||||
else if (sa == E_data_out_mismatch) {
|
else if (sa == E_data_out_mismatch) {
|
||||||
|
@ -1337,7 +1310,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
|
||||||
dmablks * A_BSIZE - tbc + legetl(dsa->data_buf.dbc));
|
dmablks * A_BSIZE - tbc + legetl(dsa->data_buf.dbc));
|
||||||
/* copy changes into scratch registers */
|
/* copy changes into scratch registers */
|
||||||
n->scratcha[2] = dsa->dmablks;
|
n->scratcha[2] = dsa->dmablks;
|
||||||
lesetl(n->scratchb, dsa->dmancr);
|
lesetl(n->scratchb, *((ulong*)dsa->dmaaddr));
|
||||||
cont = E_data_block_mismatch_recover;
|
cont = E_data_block_mismatch_recover;
|
||||||
}
|
}
|
||||||
else if (sa == E_id_out_mismatch) {
|
else if (sa == E_id_out_mismatch) {
|
||||||
|
@ -1458,7 +1431,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
|
||||||
break;
|
break;
|
||||||
case A_SIR_NOTIFY_LOAD_STATE:
|
case A_SIR_NOTIFY_LOAD_STATE:
|
||||||
IPRINT(PRINTPREFIX ": load_state dsa=%p\n", dsa);
|
IPRINT(PRINTPREFIX ": load_state dsa=%p\n", dsa);
|
||||||
if (dsa == (void*)KZERO || dsa == (void*)-1) {
|
if (dsa == nil) {
|
||||||
dsadump(c);
|
dsadump(c);
|
||||||
dumpncrregs(c, 1);
|
dumpncrregs(c, 1);
|
||||||
panic("bad dsa in load_state");
|
panic("bad dsa in load_state");
|
||||||
|
@ -1537,9 +1510,9 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
|
||||||
cont = -2;
|
cont = -2;
|
||||||
break;
|
break;
|
||||||
case A_SIR_NOTIFY_DUMP_NEXT_CODE: {
|
case A_SIR_NOTIFY_DUMP_NEXT_CODE: {
|
||||||
ulong *dsp = c->script + (legetl(n->dsp)-c->scriptpa)/4;
|
ulong *dsp = &c->script[(legetl(n->dsp)-c->scriptpa)/4];
|
||||||
int x;
|
int x;
|
||||||
IPRINT(PRINTPREFIX "code at %lux", dsp - c->script);
|
IPRINT(PRINTPREFIX "code at %lux", (ulong)(dsp - c->script));
|
||||||
for (x = 0; x < 6; x++) {
|
for (x = 0; x < 6; x++) {
|
||||||
IPRINT(" %.8lux", dsp[x]);
|
IPRINT(" %.8lux", dsp[x]);
|
||||||
}
|
}
|
||||||
|
@ -1567,7 +1540,7 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
|
||||||
case A_error_reselected: /* dsa isn't valid here */
|
case A_error_reselected: /* dsa isn't valid here */
|
||||||
iprint(PRINTPREFIX "reselection error\n");
|
iprint(PRINTPREFIX "reselection error\n");
|
||||||
dumpncrregs(c, 1);
|
dumpncrregs(c, 1);
|
||||||
for (dsa = KPTR(legetl(c->dsalist.head)); dsa != dsaend; dsa = KPTR(legetl(dsa->next))) {
|
for (dsa = KPTR(legetl(c->dsalist.head)); dsa != nil && dsa != dsaend; dsa = KPTR(legetl(dsa->next))) {
|
||||||
IPRINT(PRINTPREFIX "dsa target %d lun %d state %d\n", dsa->target, dsa->lun, dsa->stateb);
|
IPRINT(PRINTPREFIX "dsa target %d lun %d state %d\n", dsa->target, dsa->lun, dsa->stateb);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1597,10 +1570,10 @@ sd53c8xxinterrupt(Ureg *ur, void *a)
|
||||||
IPRINT(PRINTPREFIX "%d/%d: Iid pa=%.8lux sa=%.8lux dbc=%lux\n",
|
IPRINT(PRINTPREFIX "%d/%d: Iid pa=%.8lux sa=%.8lux dbc=%lux\n",
|
||||||
target, lun,
|
target, lun,
|
||||||
addr, addr - c->scriptpa, dbc);
|
addr, addr - c->scriptpa, dbc);
|
||||||
addr = (ulong)c->script + addr - c->scriptpa;
|
addr -= c->scriptpa;
|
||||||
addr -= 64;
|
addr -= 64;
|
||||||
addr &= ~63;
|
addr &= ~63;
|
||||||
v = (ulong*)addr;
|
v = &c->script[addr/4];
|
||||||
for(i=0; i<8; i++){
|
for(i=0; i<8; i++){
|
||||||
IPRINT("%.8lux: %.8lux %.8lux %.8lux %.8lux\n",
|
IPRINT("%.8lux: %.8lux %.8lux %.8lux %.8lux\n",
|
||||||
addr, v[0], v[1], v[2], v[3]);
|
addr, v[0], v[1], v[2], v[3]);
|
||||||
|
@ -2172,16 +2145,18 @@ buggery:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock(&ctlr->dsalist);
|
||||||
|
ctlr->dsalist.freechain = nil;
|
||||||
if(dsaend == nil)
|
if(dsaend == nil)
|
||||||
dsaend = xalloc(sizeof *dsaend);
|
dsaend = xalloc(sizeof *dsaend);
|
||||||
if(dsaend == nil)
|
if(dsaend == nil)
|
||||||
panic("sd53c8xxpnp: no memory");
|
panic("sd53c8xxpnp: no memory");
|
||||||
lesetl(&dsaend->stateb, A_STATE_END);
|
lesetl(&dsaend->stateb, A_STATE_END);
|
||||||
// lesetl(dsaend->next, DMASEG(dsaend));
|
lesetl(dsaend->next, DMASEG(dsaend));
|
||||||
coherence();
|
coherence();
|
||||||
lesetl(ctlr->dsalist.head, DMASEG(dsaend));
|
lesetl(ctlr->dsalist.head, DMASEG(dsaend));
|
||||||
coherence();
|
coherence();
|
||||||
ctlr->dsalist.freechain = 0;
|
unlock(&ctlr->dsalist);
|
||||||
|
|
||||||
ctlr->n = regva;
|
ctlr->n = regva;
|
||||||
ctlr->v = v;
|
ctlr->v = v;
|
||||||
|
|
|
@ -113,6 +113,10 @@ mp.$O: mp.h apbootstrap.h
|
||||||
apic.$O squidboy.$O: mp.h
|
apic.$O squidboy.$O: mp.h
|
||||||
archmp.$O archacpi.$O: mp.h
|
archmp.$O archacpi.$O: mp.h
|
||||||
|
|
||||||
|
sd53c8xx.$O: ../pc/sd53c8xx.i
|
||||||
|
../pc/sd53c8xx.i: ../pc/sd53c8xx.n
|
||||||
|
cd ../pc && mk sd53c8xx.i
|
||||||
|
|
||||||
$SDEV: ../port/sd.h
|
$SDEV: ../port/sd.h
|
||||||
sdiahci.$O: ahci.h
|
sdiahci.$O: ahci.h
|
||||||
devaoe.$O sdaoe.$O: ../port/aoe.h
|
devaoe.$O sdaoe.$O: ../port/aoe.h
|
||||||
|
|
|
@ -98,7 +98,7 @@ misc
|
||||||
|
|
||||||
sdaoe
|
sdaoe
|
||||||
sdide pci sdscsi
|
sdide pci sdscsi
|
||||||
# sd53c8xx pci sdscsi
|
sd53c8xx pci sdscsi
|
||||||
# sdmylex pci sdscsi
|
# sdmylex pci sdscsi
|
||||||
sdiahci pci sdscsi led
|
sdiahci pci sdscsi led
|
||||||
# sdodin pci sdscsi led
|
# sdodin pci sdscsi led
|
||||||
|
|
Loading…
Reference in a new issue