Browse Source

Plan 9 from Bell Labs 2011-01-04

David du Colombier 13 years ago
parent
commit
75b1f264cf

+ 24 - 38
sys/src/9/kw/ether1116.c

@@ -296,9 +296,6 @@ enum {
 	MFS60by	= 15<<2,
 	MFS64by	= 16<<2,
 
-	/* receive descriptor */
-#define Bufsize(v)	((v)<<3)
-
 	/* receive descriptor status */
 	RCSmacerr	= 1<<0,
 	RCSmacmask	= 3<<1,
@@ -492,7 +489,6 @@ rxfreeb(Block *b)
 {
 	/* freeb(b) will have previously decremented b->ref to 0; raise to 1 */
 	_xinc(&b->ref);
-//iprint("fr %ld ", b->ref);
 	b->wp = b->rp =
 		(uchar*)((uintptr)(b->lim - Rxblklen) & ~(Bufalign - 1));
 	assert(((uintptr)b->rp & (Bufalign - 1)) == 0);
@@ -560,18 +556,16 @@ rxreplenish(Ctlr *ctlr)
 
 		ctlr->rxb[ctlr->rxtail] = b;
 
-		/* set up receive descriptor */
+		/* set up uncached receive descriptor */
 		r = &ctlr->rx[ctlr->rxtail];
 		assert(((uintptr)r & (Descralign - 1)) == 0);
-		r->countsize = Bufsize(Rxblklen);
+		r->countsize = ROUNDUP(Rxblklen, 8);
 		r->buf = PADDR(b->rp);
-		cachedwbse(r, sizeof *r);
-		l2cacheuwbse(r, sizeof *r);
+		coherence();
 
 		/* and fire */
 		r->cs = RCSdmaown | RCSenableintr;
-		cachedwbse(&r->cs, BY2WD);
-		l2cacheuwbse(&r->cs, BY2WD);
+		coherence();
 
 		ctlr->rxtail = NEXT(ctlr->rxtail, Nrx);
 	}
@@ -615,14 +609,12 @@ receive(Ether *ether)
 
 	ethercheck(ether);
 	for (i = Nrx-2; i > 0; i--) {
-		r = &ctlr->rx[ctlr->rxhead];
+		r = &ctlr->rx[ctlr->rxhead];	/* *r is uncached */
 		assert(((uintptr)r & (Descralign - 1)) == 0);
-		l2cacheuinvse(r, sizeof *r);
-		cachedinvse(r, sizeof *r);
-		if(r->cs & RCSdmaown)
+		if(r->cs & RCSdmaown)		/* descriptor busy? */
 			break;
 
-		b = ctlr->rxb[ctlr->rxhead];
+		b = ctlr->rxb[ctlr->rxhead];	/* got input buffer? */
 		if (b == nil)
 			panic("ether1116: nil ctlr->rxb[ctlr->rxhead] "
 				"in receive");
@@ -630,7 +622,7 @@ receive(Ether *ether)
 		ctlr->rxhead = NEXT(ctlr->rxhead, Nrx);
 
 		if((r->cs & (RCSfirst|RCSlast)) != (RCSfirst|RCSlast)) {
-			ctlr->nofirstlast++;
+			ctlr->nofirstlast++;	/* partial packet */
 			freeb(b);
 			continue;
 		}
@@ -642,6 +634,7 @@ receive(Ether *ether)
 		n = r->countsize >> 16;		/* TODO includes 2 pad bytes? */
 		assert(n >= 2 && n < 2048);
 
+		/* clear any cached packet or part thereof */
 		l2cacheuinvse(b->rp, n+2);
 		cachedinvse(b->rp, n+2);
 		b->wp = b->rp + n;
@@ -668,8 +661,7 @@ txreplenish(Ether *ether)			/* free transmitted packets */
 
 	ctlr = ether->ctlr;
 	while(ctlr->txtail != ctlr->txhead) {
-		l2cacheuinvse(&ctlr->tx[ctlr->txtail].cs, BY2WD);
-		cachedinvse(&ctlr->tx[ctlr->txtail].cs, BY2WD);
+		/* ctlr->tx is uncached */
 		if(ctlr->tx[ctlr->txtail].cs & TCSdmaown)
 			break;
 		if(ctlr->txb[ctlr->txtail] == nil)
@@ -700,14 +692,12 @@ transmit(Ether *ether)
 	ilock(ctlr);
 	txreplenish(ether);			/* reap old packets */
 
-	/* queue new packets; don't use more than half the tx descs. */
+	/* queue new packets; use at most half the tx descs to avoid livelock */
 	kick = 0;
 	for (i = Ntx/2 - 2; i > 0; i--) {
-		t = &ctlr->tx[ctlr->txhead];
+		t = &ctlr->tx[ctlr->txhead];	/* *t is uncached */
 		assert(((uintptr)t & (Descralign - 1)) == 0);
-		l2cacheuinvse(t, sizeof *t);
-		cachedinvse(t, sizeof *t);
-		if(t->cs & TCSdmaown) {		/* free descriptor? */
+		if(t->cs & TCSdmaown) {		/* descriptor busy? */
 			ctlr->txringfull++;
 			break;
 		}
@@ -729,14 +719,12 @@ transmit(Ether *ether)
 		/* set up the transmit descriptor */
 		t->buf = PADDR(b->rp);
 		t->countchk = len << 16;
-		cachedwbse(t, sizeof *t);
-		l2cacheuwbse(t, sizeof *t);
+		coherence();
 
 		/* and fire */
 		t->cs = TCSpadding | TCSfirst | TCSlast | TCSdmaown |
 			TCSenableintr;
-		cachedwbse(&t->cs, BY2WD);
-		l2cacheuwbse(&t->cs, BY2WD);
+		coherence();
 
 		kick++;
 		ctlr->txhead = NEXT(ctlr->txhead, Ntx);
@@ -861,10 +849,8 @@ interrupt(Ureg*, void *arg)
 			handled++;
 	}
 	if (irq & Isum) {
-		if (irq & Irxerr) {
+		if (irq & Irxerr) {  /* nil desc. ptr. or desc. owned by cpu */
 			ether->buffs++;		/* approx. error */
-			/* null descriptor pointer or descriptor owned by cpu */
-//			iprint("#l%d: rx err - input ring full\n", ether->ctlrno);
 
 			/* if the input ring is full, drain it */
 			ctlr->haveinput = 1;
@@ -1438,24 +1424,26 @@ ctlralloc(Ctlr *ctlr)
 	}
 	iunlock(&freeblocks);
 
-	ctlr->rx = xspanalloc(Nrx * sizeof(Rx), Descralign, 0);
+	/*
+	 * allocate uncached rx ring descriptors because rings are shared
+	 * with the ethernet controller and more than one fits in a cache line.
+	 */
+	ctlr->rx = ucallocalign(Nrx * sizeof(Rx), Descralign, 0);
 	if(ctlr->rx == nil)
 		panic("ether1116: no memory for rx ring");
 	for(i = 0; i < Nrx; i++) {
 		r = &ctlr->rx[i];
 		assert(((uintptr)r & (Descralign - 1)) == 0);
-		r->cs = 0;	/* not owned by hardware until r->buf is set */
+		r->cs = 0;	/* owned by software until r->buf is non-nil */
 		r->buf = 0;
 		r->next = PADDR(&ctlr->rx[NEXT(i, Nrx)]);
 		ctlr->rxb[i] = nil;
 	}
 	ctlr->rxtail = ctlr->rxhead = 0;
-
 	rxreplenish(ctlr);
-	cachedwb();
-	l2cacheuwb();
 
-	ctlr->tx = xspanalloc(Ntx * sizeof(Tx), Descralign, 0);
+	/* allocate uncached tx ring descriptors */
+	ctlr->tx = ucallocalign(Ntx * sizeof(Tx), Descralign, 0);
 	if(ctlr->tx == nil)
 		panic("ether1116: no memory for tx ring");
 	for(i = 0; i < Ntx; i++) {
@@ -1467,8 +1455,6 @@ ctlralloc(Ctlr *ctlr)
 		ctlr->txb[i] = nil;
 	}
 	ctlr->txtail = ctlr->txhead = 0;
-	cachedwb();
-	l2cacheuwb();
 }
 
 static void

+ 2 - 2
sys/src/9/kw/syscall.c

@@ -42,8 +42,8 @@ noted(Ureg* cur, uintptr arg0)
 
 	/* sanity clause */
 	if(!okaddr(PTR2UINT(nf), sizeof(NFrame), 0)){
-		pprint("bad ureg in noted %#p\n", nf);
 		qunlock(&up->debug);
+		pprint("bad ureg in noted %#p\n", nf);
 		pexit("Suicide", 0);
 	}
 
@@ -151,8 +151,8 @@ notify(Ureg* ureg)
 
 	sp = ureg->sp - sizeof(NFrame);
 	if(!okaddr(sp, sizeof(NFrame), 1)){
-		pprint("suicide: notify stack address %#p\n", sp);
 		qunlock(&up->debug);
+		pprint("suicide: notify stack address %#p\n", sp);
 		pexit("Suicide", 0);
 	}
 

+ 2 - 2
sys/src/9/omap/syscall.c

@@ -42,8 +42,8 @@ noted(Ureg* cur, uintptr arg0)
 
 	/* sanity clause */
 	if(!okaddr(PTR2UINT(nf), sizeof(NFrame), 0)){
-		pprint("bad ureg in noted %#p\n", nf);
 		qunlock(&up->debug);
+		pprint("bad ureg in noted %#p\n", nf);
 		pexit("Suicide", 0);
 	}
 
@@ -151,8 +151,8 @@ notify(Ureg* ureg)
 
 	sp = ureg->sp - sizeof(NFrame);
 	if(!okaddr(sp, sizeof(NFrame), 1)){
-		pprint("suicide: notify stack address %#p\n", sp);
 		qunlock(&up->debug);
+		pprint("suicide: notify stack address %#p\n", sp);
 		pexit("Suicide", 0);
 	}
 

+ 3 - 3
sys/src/9/pc/trap.c

@@ -834,8 +834,8 @@ if(0) print("%s %lud: notify %.8lux %.8lux %.8lux %s\n",
 
 	if(!okaddr((ulong)up->notify, 1, 0)
 	|| !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)){
-		pprint("suicide: bad address in notify\n");
 		qunlock(&up->debug);
+		pprint("suicide: bad address in notify\n");
 		pexit("Suicide", 0);
 	}
 
@@ -884,8 +884,8 @@ noted(Ureg* ureg, ulong arg0)
 	/* sanity clause */
 	oureg = (ulong)nureg;
 	if(!okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
-		pprint("bad ureg in noted or call to noted when not notified\n");
 		qunlock(&up->debug);
+		pprint("bad ureg in noted or call to noted when not notified\n");
 		pexit("Suicide", 0);
 	}
 
@@ -899,8 +899,8 @@ noted(Ureg* ureg, ulong arg0)
 	if((nureg->cs & 0xFFFF) != UESEL || (nureg->ss & 0xFFFF) != UDSEL
 	  || (nureg->ds & 0xFFFF) != UDSEL || (nureg->es & 0xFFFF) != UDSEL
 	  || (nureg->fs & 0xFFFF) != UDSEL || (nureg->gs & 0xFFFF) != UDSEL){
-		pprint("bad segment selector in noted\n");
 		qunlock(&up->debug);
+		pprint("bad segment selector in noted\n");
 		pexit("Suicide", 0);
 	}
 

+ 116 - 43
sys/src/9/port/devaoe.c

@@ -1,5 +1,5 @@
 /*
- *	© 2005-7 coraid
+ *	© 2005-2010 coraid
  *	aoe storage initiator
  */
 
@@ -35,6 +35,11 @@ enum {
 #define QID(u, t) 	((u)<<4 | (t))
 #define Q3(l, u, t)	((l)<<8 | QID(u, t))
 #define UP(d)		((d)->flag & Dup)
+/*
+ * would like this to depend on the chan (srb).
+ * not possible in the current structure.
+ */
+#define Nofail(d, s)	((d)->flag & Dnofail)
 
 #define	MS2TK(t)	((t)/MS2HZ)
 
@@ -62,7 +67,7 @@ enum {
 	Qdevlinkfiles	= Qdevlinkend-Qdevlinkbase,
 
 	Eventlen 	= 256,
-	Nevents 	= 64,
+	Nevents 	= 64,			/* must be power of 2 */
 
 	Fread		= 0,
 	Fwrite,
@@ -110,6 +115,7 @@ enum {
 	/* aoe specific */
 	Dup	= 1<<6,
 	Djumbo	= 1<<7,
+	Dnofail	= 1<<8,
 };
 
 static char *flagname[] = {
@@ -122,11 +128,12 @@ static char *flagname[] = {
 
 	"up",
 	"jumbo",
+	"nofail",
 };
 
 typedef struct {
-	uchar	flag;
-	uchar	lostjumbo;
+	ushort	flag;
+	uint	lostjumbo;
 	int	datamtu;
 
 	Chan	*cc;
@@ -143,7 +150,7 @@ typedef struct {
 	uchar	eatab[Nea][Eaddrlen];
 	ulong	npkt;
 	ulong	resent;
-	uchar	flag;
+	ushort	flag;
 
 	ulong	rttavg;
 	ulong	mintimer;
@@ -191,7 +198,7 @@ struct Aoedev {
 	Devlink	dltab[Ndevlink];
 
 	ushort	fwver;
-	uchar	flag;
+	ushort	flag;
 	int	nopen;
 	int	major;
 	int	minor;
@@ -203,7 +210,6 @@ struct Aoedev {
 	vlong	realbsize;
 
 	uint	maxbcnt;
-	ulong	lostjumbo;
 	ushort	nout;
 	ushort	maxout;
 	ulong	lastwadj;
@@ -384,10 +390,8 @@ eventcount(void)
 	lock(&events);
 	if(*events.rp == 0)
 		n = 0;
-	else if(events.wp < events.rp)
-		n = Nevents - (events.rp - events.wp);
 	else
-		n = events.wp - events.rp;
+		n = (events.wp - events.rp) & (Nevents - 1);
 	unlock(&events);
 	return n/Eventlen;
 }
@@ -492,15 +496,19 @@ hset(Aoedev *d, Frame *f, Aoehdr *h, int cmd)
 	int i;
 	Devlink *l;
 
+	if(f->srb && MACHP(0)->ticks - f->srb->ticksent > Maxreqticks){
+		eventlog("%æ: srb timeout\n", d);
+		if(cmd == ACata && f->srb && Nofail(d, s))
+			f->srb->ticksent = MACHP(0)->ticks;
+		else
+			frameerror(d, f, Etimedout);
+		return -1;
+	}
 	l = pickdevlink(d);
 	i = pickea(l);
 	if(i == -1){
-		downdev(d, "resend fails; no netlink/ea");
-		return -1;
-	}
-	if(f->srb && MACHP(0)->ticks - f->srb->ticksent > Maxreqticks){
-		eventlog("%æ: srb timeout\n", d);
-		frameerror(d, f, Etimedout);
+		if(cmd != ACata || f->srb == nil || !Nofail(d, s))
+			downdev(d, "resend fails; no netlink/ea");
 		return -1;
 	}
 	memmove(h->dst, l->eatab[i], Eaddrlen);
@@ -863,6 +871,7 @@ aoegen(Chan *c, char *, Dirtab *, int, int s, Dir *dp)
 			return -1;
 		mkqid(&q, QID(s, Qunitdir), 0, QTDIR);
 		d = unit2dev(s);
+		assert(d != nil);
 		devdir(c, q, unitname(d), 0, eve, 0555, dp);
 		return 1;
 	case Qtopctl:
@@ -975,8 +984,10 @@ atarw(Aoedev *d, Frame *f)
 	f->nhdr = AOEATASZ;
 	memset(f->hdr, 0, f->nhdr);
 	ah = (Aoeata*)f->hdr;
-	if(hset(d, f, ah, ACata) == -1)
+	if(hset(d, f, ah, ACata) == -1) {
+		d->inprocess = nil;
 		return;
+	}
 	f->dp = srb->dp;
 	f->bcnt = bcnt;
 	f->lba = srb->sector;
@@ -1029,6 +1040,7 @@ aoeerror(Aoehdr *h)
 		"aoe protocol error: device unavailable",
 		"aoe protocol error: config string present",
 		"aoe protocol error: unsupported version",
+		"aoe protocol error: target is reserved",
 	};
 
 	if((h->verflag & AFerr) == 0)
@@ -1140,7 +1152,7 @@ static long
 rw(Aoedev *d, int write, uchar *db, long len, uvlong off)
 {
 	long n, nlen, copy;
-	enum { Srbsz = 1<<18, };
+	enum { Srbsz = 1<<19, };	/* magic allocation */
 	Srb *srb;
 
 	if((off|len) & (Aoesectsz-1))
@@ -1490,6 +1502,7 @@ unitctlwrite(Aoedev *d, void *db, long n)
 		Jumbo,
 		Maxbno,
 		Mtu,
+		Nofailf,
 		Setsize,
 	};
 	Cmdbuf *cb;
@@ -1500,6 +1513,7 @@ unitctlwrite(Aoedev *d, void *db, long n)
 		{Jumbo, 	"jumbo", 	0 },
 		{Maxbno,	"maxbno",	0 },
 		{Mtu,		"mtu",		0 },
+		{Nofailf,	"nofail",	0 },
 		{Setsize, 	"setsize", 	0 },
 	};
 
@@ -1541,12 +1555,18 @@ unitctlwrite(Aoedev *d, void *db, long n)
 				m -= AOEATASZ;
 				m &= ~(Aoesectsz-1);
 			}
-			if(m > maxbcnt)
-				cmderror(cb, "maxb greater than media mtu");
+			if(m == 0 || m > maxbcnt)
+				cmderror(cb, "mtu out of legal range");
 			maxbcnt = m;
 		}
 		d->maxbcnt = maxbcnt;
 		break;
+	case Nofailf:
+		if (toggle(cb->f[1], (d->flag & Dnofail) != 0))
+			d->flag |= Dnofail;
+		else
+			d->flag &= ~Dnofail;
+		break;
 	case Setsize:
 		bsize = d->realbsize;
 		if(cb->nf > 2)
@@ -1588,9 +1608,14 @@ unitwrite(Chan *c, void *db, long n, vlong off)
 		if(off + n > sizeof d->config)
 			error(Etoobig);
 		buf = malloc(sizeof d->config);
+		if(waserror()){
+			free(buf);
+			nexterror();
+		}
 		memmove(buf, d->config, d->nconfig);
 		memmove(buf + off, db, n);
 		rv = configwrite(d, buf, n + off);
+		poperror();
 		free(buf);
 		return rv;
 	}
@@ -1648,6 +1673,9 @@ dropunit(void)
 	return x;
 }
 
+/*
+ * always allocate max frames.  maxout may change.
+ */
 static Aoedev*
 newdev(long major, long minor, int n)
 {
@@ -1655,7 +1683,7 @@ newdev(long major, long minor, int n)
 	Frame *f, *e;
 
 	d = mallocz(sizeof *d, 1);
-	f = mallocz(sizeof *f * n, 1);
+	f = mallocz(sizeof *f * Maxframes, 1);
 	if (!d || !f) {
 		free(d);
 		free(f);
@@ -1702,6 +1730,8 @@ getdev(long major, long minor, int n)
 {
 	Aoedev *d;
 
+	if(major == 0xffff || minor == 0xff)
+		return 0;
 	wlock(&devs);
 	if(waserror()){
 		wunlock(&devs);
@@ -1831,8 +1861,11 @@ newdevlink(Aoedev *d, Netlink *n, Aoeqc *c)
 			l->rttavg = Rtmax;
 			return l;
 		}
-		if(l->nl == n)
+		if(l->nl == n) {
+			newdlea(l, c->src);
+			l->flag |= Dup;
 			return l;
+		}
 	}
 	eventlog("%æ: out of links: %s:%E to %E\n", d, n->path, n->ea, c->src);
 	return 0;
@@ -1883,7 +1916,7 @@ qcfgrsp(Block *b, Netlink *nl)
 		}
 		cslen = nhgets(ch->cslen);
 		blen = BLEN(b) - AOEQCSZ;
-		if(cslen < blen)
+		if(cslen < blen && BLEN(b) > 60)
 			eventlog("%æ: cfgrsp: tag %.8ux oversized %d %d\n",
 				d, n, cslen, blen);
 		if(cslen > blen){
@@ -1916,8 +1949,11 @@ qcfgrsp(Block *b, Netlink *nl)
 	}
 	d = getdev(major, ch->minor, n);
 	poperror();
+	if(d == 0)
+		return;
 
 	qlock(d);
+	*up->errstr = 0;
 	if(waserror()){
 		qunlock(d);
 		eventlog("%æ: %s\n", d, up->errstr);
@@ -1958,8 +1994,8 @@ aoeidmove(char *p, ushort *u, unsigned n)
 
 	op = p;
 	/*
-	 * the ushort `a' is sometimes not aligned on a short boundary,
-	 * so dereferencing a[i] would cause an alignment exception on
+	 * the ushort `*u' is sometimes not aligned on a short boundary,
+	 * so dereferencing u[i] causes an alignment exception on
 	 * some machines.
 	 */
 	s = (char *)u;
@@ -2174,9 +2210,12 @@ netrdaoeproc(void *v)
 					qcfgrsp(b, nl);
 					break;
 				default:
-					eventlog("%s: unknown cmd %d\n",
-						nl->path, h->cmd);
-					errrsp(b, "unknown command");
+					if((h->cmd & 0xf0) == 0){
+						eventlog("%s: unknown cmd %d\n",
+							nl->path, h->cmd);
+						errrsp(b, "unknown command");
+					}
+					break;
 				}
 		freeb(b);
 	}
@@ -2330,14 +2369,21 @@ netunbind(char *path)
 
 	/* squeeze orphan devices */
 	wlock(&devs);
-	for(p = d = devs.d; d; p = d, d = next){
+	for(p = d = devs.d; d; d = next){
 		next = d->next;
-		if(d->ndl > 0)
+		if(d->ndl > 0) {
+			p = d;
 			continue;
+		}
+		qlock(d);
+		downdev(d, "orphan");
+		qunlock(d);
 		if(p != devs.d)
 			p->next = next;
-		else
+		else{
 			devs.d = next;
+			p = devs.d;
+		}
 		free(d->frames);
 		free(d);
 		dropunit();
@@ -2346,26 +2392,26 @@ netunbind(char *path)
 }
 
 static void
-removedev(char *name)
+removeaoedev(Aoedev *d)
 {
 	int i;
-	Aoedev *d, *p;
+	Aoedev *p;
 
 	wlock(&devs);
-	for(p = d = devs.d; d; p = d, d = d->next)
-		if(strcmp(name, unitname(d)) == 0)
-			goto found;
-	wunlock(&devs);
-	error("device not bound");
-found:
+	p = 0;
+	if(d != devs.d)
+		for(p = devs.d; p; p = p->next)
+			if(p->next == d)
+				break;
+	qlock(d);
 	d->flag &= ~Dup;
 	newvers(d);
 	d->ndl = 0;
-
+	qunlock(d);
 	for(i = 0; i < d->nframes; i++)
 		frameerror(d, d->frames+i, Enotup);
 
-	if(p != devs.d)
+	if(p)
 		p->next = d->next;
 	else
 		devs.d = d->next;
@@ -2375,6 +2421,22 @@ found:
 	wunlock(&devs);
 }
 
+static void
+removedev(char *name)
+{
+	Aoedev *d, *p;
+
+	wlock(&devs);
+	for(p = d = devs.d; d; p = d, d = d->next)
+		if(strcmp(name, unitname(d)) == 0) {
+			wunlock(&devs);
+			removeaoedev(p);
+			return;
+		}
+	wunlock(&devs);
+	error("device not bound");
+}
+
 static void
 discoverstr(char *f)
 {
@@ -2401,6 +2463,18 @@ discoverstr(char *f)
 }
 
 
+static void
+aoeremove(Chan *c)
+{
+	switch(TYPE(c->qid)){
+	default:
+		error(Eperm);
+	case Qunitdir:
+		removeaoedev(unit2dev(UNIT(c->qid)));
+		break;
+	}
+}
+
 static long
 topctlwrite(void *db, long n)
 {
@@ -2409,7 +2483,6 @@ topctlwrite(void *db, long n)
 		Bind,
 		Debug,
 		Discover,
-		Closewait,
 		Rediscover,
 		Remove,
 		Unbind,
@@ -2501,7 +2574,7 @@ Dev aoedevtab = {
 	devbread,
 	aoewrite,
 	devbwrite,
-	devremove,
+	aoeremove,
 	devwstat,
 	devpower,
 	devconfig,

+ 10 - 16
sys/src/9/port/sdaoe.c

@@ -248,6 +248,7 @@ delctlr(Ctlr *c)
 	free(x);
 }
 
+/* don't call aoeprobe from within a loop; it loops internally retrying open. */
 static SDev*
 aoeprobe(char *path, SDev *s)
 {
@@ -340,8 +341,7 @@ aoepnp(void)
 static Ctlr*
 pnpprobe(SDev *sd)
 {
-	int j;
-	ulong start, duration;
+	ulong start;
 	char *p;
 	static int i;
 
@@ -354,22 +354,16 @@ pnpprobe(SDev *sd)
 		p += 2;
 
 	start = TK2MS(MACHP(0)->ticks);
-	for(j = 0; j < Probemax; j++){
-		if(!waserror()){
-			/* aoeprobe does a similar round of probing */
-			sd = aoeprobe(p, sd);
-			poperror();
-			break;
-		}
-		tsleep(&up->sleep, return0, 0, Probeintvl);
-	}
-	duration = TK2MS(MACHP(0)->ticks) - start;
-	if(j >= Probemax){
-		print("#æ: pnpprobe failed in %lud ms: %s: %s\n", duration,
-			probef[i-1], up->errstr);
+	if(waserror()){
+		print("#æ: pnpprobe failed in %lud ms: %s: %s\n",
+			TK2MS(MACHP(0)->ticks) - start, probef[i-1],
+			up->errstr);
 		return nil;
 	}
-	print("#æ: pnpprobe established %s in %lud ms\n", probef[i-1], duration);
+	sd = aoeprobe(p, sd);			/* does a round of probing */
+	poperror();
+	print("#æ: pnpprobe established %s in %lud ms\n",
+		probef[i-1], TK2MS(MACHP(0)->ticks) - start);
 	return sd->ctlr;
 }
 

+ 0 - 1
sys/src/cmd/8c/txt.c

@@ -306,7 +306,6 @@ regalloc(Node *n, Node *tn, Node *o)
 			if(reg[i] == 0)
 				goto out;
 		diag(tn, "out of fixed registers");
-abort();
 		goto err;
 
 	case TFLOAT:

+ 1 - 0
sys/src/cmd/aux/getflags.c

@@ -43,6 +43,7 @@ main(int argc, char *argv[])
 	int i, n;
 	Fmt fmt;
 	
+	doquote = needsrcquote;
 	quotefmtinstall();
 	argv0 = argv[0];	/* for sysfatal */