From af6c35e14bc4d9e4c24726600971921cba406a83 Mon Sep 17 00:00:00 2001
From: Frans Kaashoek <kaashoek@mit.edu>
Date: Mon, 1 Jul 2019 08:20:35 -0400
Subject: [PATCH] Introduce alloc3_desc and UsedArea to make code easier to
 read

---
 .gitignore           |  2 ++
 kernel/virtio.h      | 10 ++++++++
 kernel/virtio_disk.c | 61 ++++++++++++++++++++------------------------
 3 files changed, 40 insertions(+), 33 deletions(-)

diff --git a/.gitignore b/.gitignore
index fe754f0..07216f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,4 +12,6 @@ initcode
 initcode.out
 kernelmemfs
 mkfs
+kernel/kernel
+user/usys.S
 .gdbinit
diff --git a/kernel/virtio.h b/kernel/virtio.h
index c142af9..03b53a9 100644
--- a/kernel/virtio.h
+++ b/kernel/virtio.h
@@ -43,6 +43,10 @@
 #define VIRTIO_RING_F_INDIRECT_DESC 28
 #define VIRTIO_RING_F_EVENT_IDX     29
 
+// this many virtio descriptors.
+// must be a power of two.
+#define NUM 8
+
 struct VRingDesc {
   uint64 addr;
   uint32 len;
@@ -60,3 +64,9 @@ struct VRingUsedElem {
 // for disk ops
 #define VIRTIO_BLK_T_IN  0 // read the disk
 #define VIRTIO_BLK_T_OUT 1 // write the disk
+
+struct UsedArea {
+  uint16 flags;
+  uint16 id;
+  struct VRingUsedElem elems[NUM];
+};
diff --git a/kernel/virtio_disk.c b/kernel/virtio_disk.c
index 6bcad9c..855c902 100644
--- a/kernel/virtio_disk.c
+++ b/kernel/virtio_disk.c
@@ -22,10 +22,6 @@
 
 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.
 // this is a global instead of allocated because it has
 // to be multiple contiguous pages, which kalloc()
@@ -34,7 +30,7 @@ __attribute__ ((aligned (PGSIZE)))
 static char pages[2*PGSIZE];
 static struct VRingDesc *desc;
 static uint16 *avail;
-static char *used;
+static struct UsedArea *used;
 
 // our own book-keeping.
 static char free[NUM];  // is a descriptor free?
@@ -106,7 +102,7 @@ virtio_disk_init(void)
 
   desc = (struct VRingDesc *) pages;
   avail = (uint16*)(((char*)desc) + NUM*sizeof(struct VRingDesc));
-  used = pages + PGSIZE;
+  used = (struct UsedArea *) (pages + PGSIZE);
 
   for(int i = 0; i < NUM; i++)
     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
 virtio_disk_rw(struct buf *b)
 {
@@ -167,21 +178,12 @@ virtio_disk_rw(struct buf *b)
   // allocate the three descriptors.
   int idx[3];
   while(1){
-    int done = 1;
-    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;
-      }
-    }
-    if(done)
+    if(alloc3_desc(idx) == 0) {
       break;
+    }
     sleep(&free[0], &virtio_disk_lock);
   }
-
+  
   // format the three descriptors.
   // qemu's virtio-blk.c reads them.
 
@@ -242,28 +244,21 @@ virtio_disk_rw(struct buf *b)
 void
 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);
 
-  while((used_idx % NUM) != (*idxp % NUM)){
-    volatile struct VRingUsedElem *ue = &e0[used_idx];
+  while((used_idx % NUM) != (used->id % NUM)){
+    int id = used->elems[used_idx].id;
 
-    if(info[ue->id].status != 0)
+    if(info[id].status != 0)
       panic("virtio_disk_intr status");
 
-    info[ue->id].b->flags |= B_VALID;
-    info[ue->id].b->flags &= ~B_DIRTY;
+    info[id].b->flags |= B_VALID;
+    info[id].b->flags &= ~B_DIRTY;
 
-    wakeup(info[ue->id].b);
+    wakeup(info[id].b);
 
-    info[ue->id].b = 0;
-    free_chain(ue->id);
+    info[id].b = 0;
+    free_chain(id);
 
     used_idx = (used_idx + 1) % NUM;
   }