From b486d8871b3ae20745f32b9d509d75d5a911ec65 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Mon, 22 Dec 2014 12:17:48 +0100 Subject: [PATCH] sdvirtio: move common "queue i/o and wait" code into vqio() function, handle notify suppression --- sys/src/9/pc/sdvirtio.c | 71 +++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/sys/src/9/pc/sdvirtio.c b/sys/src/9/pc/sdvirtio.c index fdcc929b2..17cab9cc3 100644 --- a/sys/src/9/pc/sdvirtio.c +++ b/sys/src/9/pc/sdvirtio.c @@ -298,10 +298,34 @@ viodone(void *arg) 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 @@ vioblkreq(Vdev *vd, int typ, void *a, long count, long secsize, uvlong lba) req.prio = 0; req.lba = lba; - rock.done = 0; - rock.sleep = &up->sleep; - q = vd->queue[0]; ilock(q); while(q->nfree < 3){ @@ -353,23 +374,8 @@ vioblkreq(Vdev *vd, int typ, void *a, long count, long secsize, uvlong lba) q->free = free; q->nfree -= 3; - 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); return status; } @@ -379,7 +385,6 @@ vioscsireq(SDreq *r) { 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 @@ vioscsireq(SDreq *r) 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 @@ vioscsireq(SDreq *r) 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];