sd53c8xx: fix the driver for amd64, fix alignment/padding issues, fix freechain handling

This commit is contained in:
cinap_lenrek 2019-11-24 21:56:54 +01:00
parent 87c8fa5415
commit d32e5d130c
3 changed files with 50 additions and 71 deletions

View file

@ -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;

View file

@ -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

View file

@ -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