Introduce alloc3_desc and UsedArea to make code easier to read
This commit is contained in:
parent
a8305b7318
commit
af6c35e14b
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -12,4 +12,6 @@ initcode
|
||||||
initcode.out
|
initcode.out
|
||||||
kernelmemfs
|
kernelmemfs
|
||||||
mkfs
|
mkfs
|
||||||
|
kernel/kernel
|
||||||
|
user/usys.S
|
||||||
.gdbinit
|
.gdbinit
|
||||||
|
|
|
@ -43,6 +43,10 @@
|
||||||
#define VIRTIO_RING_F_INDIRECT_DESC 28
|
#define VIRTIO_RING_F_INDIRECT_DESC 28
|
||||||
#define VIRTIO_RING_F_EVENT_IDX 29
|
#define VIRTIO_RING_F_EVENT_IDX 29
|
||||||
|
|
||||||
|
// this many virtio descriptors.
|
||||||
|
// must be a power of two.
|
||||||
|
#define NUM 8
|
||||||
|
|
||||||
struct VRingDesc {
|
struct VRingDesc {
|
||||||
uint64 addr;
|
uint64 addr;
|
||||||
uint32 len;
|
uint32 len;
|
||||||
|
@ -60,3 +64,9 @@ struct VRingUsedElem {
|
||||||
// for disk ops
|
// for disk ops
|
||||||
#define VIRTIO_BLK_T_IN 0 // read the disk
|
#define VIRTIO_BLK_T_IN 0 // read the disk
|
||||||
#define VIRTIO_BLK_T_OUT 1 // write the disk
|
#define VIRTIO_BLK_T_OUT 1 // write the disk
|
||||||
|
|
||||||
|
struct UsedArea {
|
||||||
|
uint16 flags;
|
||||||
|
uint16 id;
|
||||||
|
struct VRingUsedElem elems[NUM];
|
||||||
|
};
|
||||||
|
|
|
@ -22,10 +22,6 @@
|
||||||
|
|
||||||
struct spinlock virtio_disk_lock;
|
struct spinlock virtio_disk_lock;
|
||||||
|
|
||||||
// this many virtio descriptors.
|
|
||||||
// must be a power of two.
|
|
||||||
#define NUM 8
|
|
||||||
|
|
||||||
// memory for virtio descriptors &c for queue 0.
|
// memory for virtio descriptors &c for queue 0.
|
||||||
// this is a global instead of allocated because it has
|
// this is a global instead of allocated because it has
|
||||||
// to be multiple contiguous pages, which kalloc()
|
// to be multiple contiguous pages, which kalloc()
|
||||||
|
@ -34,7 +30,7 @@ __attribute__ ((aligned (PGSIZE)))
|
||||||
static char pages[2*PGSIZE];
|
static char pages[2*PGSIZE];
|
||||||
static struct VRingDesc *desc;
|
static struct VRingDesc *desc;
|
||||||
static uint16 *avail;
|
static uint16 *avail;
|
||||||
static char *used;
|
static struct UsedArea *used;
|
||||||
|
|
||||||
// our own book-keeping.
|
// our own book-keeping.
|
||||||
static char free[NUM]; // is a descriptor free?
|
static char free[NUM]; // is a descriptor free?
|
||||||
|
@ -106,7 +102,7 @@ virtio_disk_init(void)
|
||||||
|
|
||||||
desc = (struct VRingDesc *) pages;
|
desc = (struct VRingDesc *) pages;
|
||||||
avail = (uint16*)(((char*)desc) + NUM*sizeof(struct VRingDesc));
|
avail = (uint16*)(((char*)desc) + NUM*sizeof(struct VRingDesc));
|
||||||
used = pages + PGSIZE;
|
used = (struct UsedArea *) (pages + PGSIZE);
|
||||||
|
|
||||||
for(int i = 0; i < NUM; i++)
|
for(int i = 0; i < NUM; i++)
|
||||||
free[i] = 1;
|
free[i] = 1;
|
||||||
|
@ -153,6 +149,21 @@ free_chain(int i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
alloc3_desc(int *idx)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 3; i++){
|
||||||
|
idx[i] = alloc_desc();
|
||||||
|
if(idx[i] < 0){
|
||||||
|
for(int j = 0; j < i; j++)
|
||||||
|
free_desc(idx[j]);
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
virtio_disk_rw(struct buf *b)
|
virtio_disk_rw(struct buf *b)
|
||||||
{
|
{
|
||||||
|
@ -167,18 +178,9 @@ virtio_disk_rw(struct buf *b)
|
||||||
// allocate the three descriptors.
|
// allocate the three descriptors.
|
||||||
int idx[3];
|
int idx[3];
|
||||||
while(1){
|
while(1){
|
||||||
int done = 1;
|
if(alloc3_desc(idx) == 0) {
|
||||||
for(int i = 0; i < 3; i++){
|
|
||||||
idx[i] = alloc_desc();
|
|
||||||
if(idx[i] < 0){
|
|
||||||
for(int j = 0; j < i; j++)
|
|
||||||
free_desc(idx[j]);
|
|
||||||
done = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(done)
|
|
||||||
break;
|
|
||||||
sleep(&free[0], &virtio_disk_lock);
|
sleep(&free[0], &virtio_disk_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,28 +244,21 @@ virtio_disk_rw(struct buf *b)
|
||||||
void
|
void
|
||||||
virtio_disk_intr()
|
virtio_disk_intr()
|
||||||
{
|
{
|
||||||
// the used area is:
|
|
||||||
// uint16 flags
|
|
||||||
// uint16 idx
|
|
||||||
// array of VRingUsedElem
|
|
||||||
volatile uint16 *idxp = (uint16 *)(used + 2);
|
|
||||||
volatile struct VRingUsedElem *e0 = (struct VRingUsedElem *)(used + 4);
|
|
||||||
|
|
||||||
acquire(&virtio_disk_lock);
|
acquire(&virtio_disk_lock);
|
||||||
|
|
||||||
while((used_idx % NUM) != (*idxp % NUM)){
|
while((used_idx % NUM) != (used->id % NUM)){
|
||||||
volatile struct VRingUsedElem *ue = &e0[used_idx];
|
int id = used->elems[used_idx].id;
|
||||||
|
|
||||||
if(info[ue->id].status != 0)
|
if(info[id].status != 0)
|
||||||
panic("virtio_disk_intr status");
|
panic("virtio_disk_intr status");
|
||||||
|
|
||||||
info[ue->id].b->flags |= B_VALID;
|
info[id].b->flags |= B_VALID;
|
||||||
info[ue->id].b->flags &= ~B_DIRTY;
|
info[id].b->flags &= ~B_DIRTY;
|
||||||
|
|
||||||
wakeup(info[ue->id].b);
|
wakeup(info[id].b);
|
||||||
|
|
||||||
info[ue->id].b = 0;
|
info[id].b = 0;
|
||||||
free_chain(ue->id);
|
free_chain(id);
|
||||||
|
|
||||||
used_idx = (used_idx + 1) % NUM;
|
used_idx = (used_idx + 1) % NUM;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue