22
22
23
23
struct spinlock virtio_disk_lock ;
24
24
25
- // this many virtio descriptors.
26
- // must be a power of two.
27
- #define NUM 8
28
-
29
25
// memory for virtio descriptors &c for queue 0.
30
26
// this is a global instead of allocated because it has
31
27
// to be multiple contiguous pages, which kalloc()
@@ -34,7 +30,7 @@ __attribute__ ((aligned (PGSIZE)))
34
30
static char pages [2 * PGSIZE ];
35
31
static struct VRingDesc * desc ;
36
32
static uint16 * avail ;
37
- static char * used ;
33
+ static struct UsedArea * used ;
38
34
39
35
// our own book-keeping.
40
36
static char free [NUM ]; // is a descriptor free?
@@ -106,7 +102,7 @@ virtio_disk_init(void)
106
102
107
103
desc = (struct VRingDesc * ) pages ;
108
104
avail = (uint16 * )(((char * )desc ) + NUM * sizeof (struct VRingDesc ));
109
- used = pages + PGSIZE ;
105
+ used = ( struct UsedArea * ) ( pages + PGSIZE ) ;
110
106
111
107
for (int i = 0 ; i < NUM ; i ++ )
112
108
free [i ] = 1 ;
@@ -153,6 +149,21 @@ free_chain(int i)
153
149
}
154
150
}
155
151
152
+ static int
153
+ alloc3_desc (int * idx )
154
+ {
155
+ for (int i = 0 ; i < 3 ; i ++ ){
156
+ idx [i ] = alloc_desc ();
157
+ if (idx [i ] < 0 ){
158
+ for (int j = 0 ; j < i ; j ++ )
159
+ free_desc (idx [j ]);
160
+ return -1 ;
161
+ break ;
162
+ }
163
+ }
164
+ return 0 ;
165
+ }
166
+
156
167
void
157
168
virtio_disk_rw (struct buf * b )
158
169
{
@@ -167,21 +178,12 @@ virtio_disk_rw(struct buf *b)
167
178
// allocate the three descriptors.
168
179
int idx [3 ];
169
180
while (1 ){
170
- int done = 1 ;
171
- for (int i = 0 ; i < 3 ; i ++ ){
172
- idx [i ] = alloc_desc ();
173
- if (idx [i ] < 0 ){
174
- for (int j = 0 ; j < i ; j ++ )
175
- free_desc (idx [j ]);
176
- done = 0 ;
177
- break ;
178
- }
179
- }
180
- if (done )
181
+ if (alloc3_desc (idx ) == 0 ) {
181
182
break ;
183
+ }
182
184
sleep (& free [0 ], & virtio_disk_lock );
183
185
}
184
-
186
+
185
187
// format the three descriptors.
186
188
// qemu's virtio-blk.c reads them.
187
189
@@ -242,28 +244,21 @@ virtio_disk_rw(struct buf *b)
242
244
void
243
245
virtio_disk_intr ()
244
246
{
245
- // the used area is:
246
- // uint16 flags
247
- // uint16 idx
248
- // array of VRingUsedElem
249
- volatile uint16 * idxp = (uint16 * )(used + 2 );
250
- volatile struct VRingUsedElem * e0 = (struct VRingUsedElem * )(used + 4 );
251
-
252
247
acquire (& virtio_disk_lock );
253
248
254
- while ((used_idx % NUM ) != (* idxp % NUM )){
255
- volatile struct VRingUsedElem * ue = & e0 [used_idx ];
249
+ while ((used_idx % NUM ) != (used -> id % NUM )){
250
+ int id = used -> elems [used_idx ]. id ;
256
251
257
- if (info [ue -> id ].status != 0 )
252
+ if (info [id ].status != 0 )
258
253
panic ("virtio_disk_intr status" );
259
254
260
- info [ue -> id ].b -> flags |= B_VALID ;
261
- info [ue -> id ].b -> flags &= ~B_DIRTY ;
255
+ info [id ].b -> flags |= B_VALID ;
256
+ info [id ].b -> flags &= ~B_DIRTY ;
262
257
263
- wakeup (info [ue -> id ].b );
258
+ wakeup (info [id ].b );
264
259
265
- info [ue -> id ].b = 0 ;
266
- free_chain (ue -> id );
260
+ info [id ].b = 0 ;
261
+ free_chain (id );
267
262
268
263
used_idx = (used_idx + 1 ) % NUM ;
269
264
}
0 commit comments