shithub: riscv

Download patch

ref: b486d8871b3ae20745f32b9d509d75d5a911ec65
parent: 515893dda6d67853ff271819d877fe2986b03456
author: cinap_lenrek <[email protected]>
date: Mon Dec 22 07:17:48 EST 2014

sdvirtio: move common "queue i/o and wait" code into vqio() function, handle notify suppression

--- a/sys/src/9/pc/sdvirtio.c
+++ b/sys/src/9/pc/sdvirtio.c
@@ -298,10 +298,34 @@
 	return ((struct Rock*)arg)->done;
 }
 
+static void
+vqio(Vqueue *q, int head)
+{
+	struct Rock rock;
+
+	rock.done = 0;
+	rock.sleep = &up->sleep;
+	q->rock[head] = &rock;
+	q->availent[q->avail->idx & (q->size-1)] = head;
+	coherence();
+	q->avail->idx++;
+	iunlock(q);
+	if((q->used->flags & 1) == 0)
+		outs(q->dev->port+Qnotify, q->idx);
+	while(!rock.done){
+		while(waserror())
+			;
+		tsleep(rock.sleep, viodone, &rock, 1000);
+		poperror();
+
+		if(!rock.done)
+			vqinterrupt(q);
+	}
+}
+
 static int
 vioblkreq(Vdev *vd, int typ, void *a, long count, long secsize, uvlong lba)
 {
-	struct Rock rock;
 	int free, head;
 	Vqueue *q;
 	Vdesc *d;
@@ -318,9 +342,6 @@
 	req.prio = 0;
 	req.lba = lba;
 
-	rock.done = 0;
-	rock.sleep = &up->sleep;
-
 	q = vd->queue[0];
 	ilock(q);
 	while(q->nfree < 3){
@@ -353,24 +374,9 @@
 	q->free = free;
 	q->nfree -= 3;
 
-	q->rock[head] = &rock;
+	/* queue io, unlock and wait for completion */
+	vqio(q, head);
 
-	coherence();
-	q->availent[q->avail->idx++ & (q->size-1)] = head;
-	coherence();
-	outs(vd->port+Qnotify, q->idx);
-	iunlock(q);
-
-	while(!rock.done){
-		while(waserror())
-			;
-		tsleep(rock.sleep, viodone, &rock, 1000);
-		poperror();
-
-		if(!rock.done)
-			vqinterrupt(q);
-	}
-
 	return status;
 }
 
@@ -379,7 +385,6 @@
 {
 	u8int resp[4+4+2+2+SENSESIZE];
 	u8int req[8+8+3+CDBSIZE];
-	struct Rock rock;
 	int free, head;
 	u32int len;
 	Vqueue *q;
@@ -402,9 +407,6 @@
 
 	memmove(&req[8+8+3], r->cmd, r->clen);
 
-	rock.done = 0;
-	rock.sleep = &up->sleep;
-
 	q = vd->queue[2];
 	ilock(q);
 	while(q->nfree < 3){
@@ -448,23 +450,8 @@
 	q->free = free;
 	q->nfree -= 2 + (r->dlen > 0);
 
-	q->rock[head] = &rock;
-
-	coherence();
-	q->availent[q->avail->idx++ & (q->size-1)] = head;
-	coherence();
-	outs(vd->port+Qnotify, q->idx);
-	iunlock(q);
-
-	while(!rock.done){
-		while(waserror())
-			;
-		tsleep(rock.sleep, viodone, &rock, 1000);
-		poperror();
-
-		if(!rock.done)
-			vqinterrupt(q);
-	}
+	/* queue io, unlock and wait for completion */
+	vqio(q, head);
 
 	/* response+status */
 	r->status = resp[10];