shithub: riscv

Download patch

ref: b7089d66ad5a26a2b39c1c1e17a4761cd1670728
parent: 68f15d65942da7e30cf9cbae7362f778fe5da1d2
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Feb 23 09:05:01 EST 2020

sdiahci, sdodin: avoid calling kproc() while holding ilock()

--- a/sys/src/9/pc/sdiahci.c
+++ b/sys/src/9/pc/sdiahci.c
@@ -1546,21 +1546,25 @@
 
 	c = s->ctlr;
 	ilock(c);
-	if(!c->enabled){
-		if(once == 0)
-			kproc("iasata", satakproc, 0);
-		if(c->ndrive == 0)
-			panic("iaenable: zero s->ctlr->ndrive");
-		pcisetbme(c->pci);
-		snprint(name, sizeof name, "%s (%s)", s->name, s->ifc->name);
-		intrenable(c->pci->intl, iainterrupt, c, c->pci->tbdf, name);
-		/* supposed to squelch leftover interrupts here. */
-		ahcienable(c->hba);
-		c->enabled = 1;
-		if(++once == niactlr)
-			kproc("ialed", ledkproc, 0);
+	if(c->enabled){
+		iunlock(c);
+		return 1;
 	}
+	if(c->ndrive == 0)
+		panic("iaenable: zero s->ctlr->ndrive");
+	pcisetbme(c->pci);
+	snprint(name, sizeof name, "%s (%s)", s->name, s->ifc->name);
+	intrenable(c->pci->intl, iainterrupt, c, c->pci->tbdf, name);
+	/* supposed to squelch leftover interrupts here. */
+	ahcienable(c->hba);
+	c->enabled = 1;
 	iunlock(c);
+
+	if(once == 0)
+		kproc("iasata", satakproc, 0);
+	if(++once == niactlr)
+		kproc("ialed", ledkproc, 0);
+
 	return 1;
 }
 
--- a/sys/src/9/pc/sdodin.c
+++ b/sys/src/9/pc/sdodin.c
@@ -2414,16 +2414,20 @@
 
 	c = s->ctlr;
 	ilock(c);
-	if(!c->enabled){
-		if(once++ == 0)
-			kproc("odin", mskproc, 0);
-		pcisetbme(c->pci);
-		snprint(buf, sizeof buf, "%s (%s)", s->name, s->ifc->name);
-		intrenable(c->pci->intl, msinterrupt, c, c->pci->tbdf, buf);
-//		c->reg[Cis] |= Swirq1;		/* force initial interrupt. */
-		c->enabled = 1;
+	if(c->enabled){
+		iunlock(c);
+		return 1;
 	}
+	pcisetbme(c->pci);
+	snprint(buf, sizeof buf, "%s (%s)", s->name, s->ifc->name);
+	intrenable(c->pci->intl, msinterrupt, c, c->pci->tbdf, buf);
+//	c->reg[Cis] |= Swirq1;		/* force initial interrupt. */
+	c->enabled = 1;
 	iunlock(c);
+
+	if(once++ == 0)
+		kproc("odin", mskproc, 0);
+
 	return 1;
 }
 
@@ -2517,9 +2521,6 @@
 	if(d->unit == nil){
 		d->unit = u;
 		sdaddfile(u, "led", 0644, eve, odinledr, odinledw);
-		once++;
-		if(once == nmsctlr)
-			kproc("mvled", ledkproc, 0);
 		chk = 1;
 	}
 	iunlock(d);
@@ -2530,6 +2531,8 @@
 	 * we need to give detected drives a chance.
 	 */
 	if(chk){
+		if(++once == nmsctlr)
+			kproc("mvled", ledkproc, 0);
 		reset(d);
 		verifychk(d);
 	}