shithub: riscv

Download patch

ref: d32e5d130c3940d4a6793fb50a31c3c9fd167508
parent: 87c8fa541572387c012dab672890e13334ef8c37
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Nov 24 16:56:54 EST 2019

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

--- a/sys/src/9/pc/sd53c8xx.c
+++ b/sys/src/9/pc/sd53c8xx.c
@@ -31,10 +31,6 @@
 /* Portable configuration macros  */
 /**********************************/
 
-//#define BOOTDEBUG
-//#define ASYNC_ONLY
-//#define	INTERNAL_SCLK
-//#define ALWAYS_DO_WDTR
 #define WMR_DEBUG
 
 /**********************************/
@@ -43,36 +39,23 @@
 
 #define PRINTPREFIX "sd53c8xx: "
 
-#ifdef BOOTDEBUG
-
-#define KPRINT oprint
-#define IPRINT intrprint
-#define DEBUG(n) 1
-#define IFLUSH() iflush()
-
-#else
-
-static int idebug = 1;
+static int idebug = 0;
 #define KPRINT	if(0) iprint
 #define IPRINT	if(idebug) iprint
-#define DEBUG(n)	(0)
+#define DEBUG(n) (0)
 #define IFLUSH()
 
-#endif /* BOOTDEBUG */
-
 /*******************************/
 /* General                     */
 /*******************************/
 
-#ifndef DMASEG
 #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((x)-PCIWINDOW)
-#define KPTR(x) ((x) == 0 ? 0 : DMASEG_TO_KADDR(x))
+#define DMASEG_TO_PADDR(x) ((uintptr)(x)-PCIWINDOW)
+#define DMASEG_TO_KADDR(x) KADDR(DMASEG_TO_PADDR(x))
+#define KPTR(x) (((x) == 0) ? nil : DMASEG_TO_KADDR(x))
 
 #define MEGA 1000000L
 #ifdef INTERNAL_SCLK
@@ -209,10 +192,7 @@
 	uchar dmablks;
 	uchar flag;	/* setbyte(state,3,...) */
 
-	union {
-		ulong dmancr;		/* For block transfer: NCR order (little-endian) */
-		uchar dmaaddr[4];
-	};
+	uchar dmaaddr[4];	/* For block transfer: NCR order (little-endian) */
 
 	uchar target;			/* Target */
 	uchar pad0[3];
@@ -220,18 +200,21 @@
 	uchar lun;			/* Logical Unit Number */
 	uchar pad1[3];
 
-	uchar scntl3;
+	uchar scntl3;			/* Sync */
 	uchar sxfer;
 	uchar pad2[2];
 
 	uchar next[4];			/* chaining for SCRIPT (NCR byte order) */
+
 	Dsa	*freechain;		/* chaining for freelist */
 	Rendez;
+
 	uchar scsi_id_buf[4];
 	Movedata msg_out_buf;
 	Movedata cmd_buf;
 	Movedata data_buf;
 	Movedata status_buf;
+
 	uchar msg_out[10];		/* enough to include SDTR */
 	uchar status;
 	int p9status;
@@ -382,7 +365,7 @@
 }
 #endif
 
-#include "sd53c8xx.i"
+#include "../pc/sd53c8xx.i"
 
 /*
  * We used to use a linked list of Dsas with nil as the terminator,
@@ -398,23 +381,6 @@
  */
 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 *
 dsaalloc(Controller *c, int target, int lun)
 {
@@ -421,15 +387,25 @@
 	Dsa *d;
 
 	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))
-			IPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d);
-	} else {	
-		d = dsaallocnew(c);
+			IPRINT(PRINTPREFIX "%d/%d: reused dsa %#p\n", target, lun, d);
+	} else {
+		/* 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))
-			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);
 	iunlock(&c->dsalist);
 	d->target = target;
@@ -454,11 +430,7 @@
 	u32int *a;
 	
 	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))){
-		if(d == (void*)-1){
-			iprint("\t dsa %p\n", d);
-			break;
-		}
+	for(d=KPTR(legetl(c->dsalist.head)); d != nil && d != dsaend; d=KPTR(legetl(d->next))){
 		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]);
 	}
@@ -490,7 +462,8 @@
 dsafind(Controller *c, uchar target, uchar lun, uchar state)
 {
 	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)
 			continue;
 		if (lun != 0xff && d->lun != lun)
@@ -1206,11 +1179,11 @@
 		}
 		n->istat = Intf;
 		/* 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) {
 				d->p9status = d->status;
 				if (DEBUG(1)) {
-					IPRINT(PRINTPREFIX "waking up dsa %lux\n", (ulong)d);
+					IPRINT(PRINTPREFIX "waking up dsa %#p\n", d);
 				}
 				wakeup(d);
 				wokesomething = 1;
@@ -1236,7 +1209,7 @@
 	/*
 	 * 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);
 	else{
 		dsa = nil;
@@ -1307,7 +1280,7 @@
 				    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) {
@@ -1337,7 +1310,7 @@
 				    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) {
@@ -1458,7 +1431,7 @@
 				break;
 			case A_SIR_NOTIFY_LOAD_STATE:
 				IPRINT(PRINTPREFIX ": load_state dsa=%p\n", dsa);
-				if (dsa == (void*)KZERO || dsa == (void*)-1) {
+				if (dsa == nil) {
 					dsadump(c);
 					dumpncrregs(c, 1);
 					panic("bad dsa in load_state");
@@ -1537,9 +1510,9 @@
 				cont = -2;
 				break;
 			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;
-				IPRINT(PRINTPREFIX "code at %lux", dsp - c->script);
+				IPRINT(PRINTPREFIX "code at %lux", (ulong)(dsp - c->script));
 				for (x = 0; x < 6; x++) {
 					IPRINT(" %.8lux", dsp[x]);
 				}
@@ -1567,7 +1540,7 @@
 			case A_error_reselected:		/* dsa isn't valid here */
 				iprint(PRINTPREFIX "reselection error\n");
 				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);
 				}
 				break;
@@ -1597,10 +1570,10 @@
 			IPRINT(PRINTPREFIX "%d/%d: Iid pa=%.8lux sa=%.8lux dbc=%lux\n",
 			    target, lun,
 			    addr, addr - c->scriptpa, dbc);
-			addr = (ulong)c->script + addr - c->scriptpa;
+			addr -= c->scriptpa;
 			addr -= 64;
 			addr &= ~63;
-			v = (ulong*)addr;
+			v = &c->script[addr/4];
 			for(i=0; i<8; i++){
 				IPRINT("%.8lux: %.8lux %.8lux %.8lux %.8lux\n", 
 					addr, v[0], v[1], v[2], v[3]);
@@ -2172,16 +2145,18 @@
 			continue;
 		}
 
+		lock(&ctlr->dsalist);
+		ctlr->dsalist.freechain = nil;
 		if(dsaend == nil)
 			dsaend = xalloc(sizeof *dsaend);
 		if(dsaend == nil)
 			panic("sd53c8xxpnp: no memory");
 		lesetl(&dsaend->stateb, A_STATE_END);
-	//	lesetl(dsaend->next, DMASEG(dsaend));
+		lesetl(dsaend->next, DMASEG(dsaend));
 		coherence();
 		lesetl(ctlr->dsalist.head, DMASEG(dsaend));
 		coherence();
-		ctlr->dsalist.freechain = 0;
+		unlock(&ctlr->dsalist);
 
 		ctlr->n = regva;
 		ctlr->v = v;
--- a/sys/src/9/pc64/mkfile
+++ b/sys/src/9/pc64/mkfile
@@ -113,6 +113,10 @@
 apic.$O squidboy.$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
 sdiahci.$O:			ahci.h
 devaoe.$O sdaoe.$O:		../port/aoe.h
--- a/sys/src/9/pc64/pc64
+++ b/sys/src/9/pc64/pc64
@@ -98,7 +98,7 @@
 
 	sdaoe
 	sdide		pci sdscsi
-#	sd53c8xx	pci sdscsi
+	sd53c8xx	pci sdscsi
 #	sdmylex		pci sdscsi
 	sdiahci		pci sdscsi led
 #	sdodin		pci sdscsi led