sdvirtio: move common "queue i/o and wait" code into vqio() function, handle notify suppression
This commit is contained in:
parent
515893dda6
commit
b486d8871b
1 changed files with 29 additions and 42 deletions
|
@ -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];
|
||||
|
|
Loading…
Reference in a new issue