@@ -118,48 +118,45 @@ struct VirtqDMA {
118118 _pad2 : [ u8 ; 2042 ] , // 4096 - 2054 = 2042 bytes
119119} // 4096 * 3 = 12288 bytes in total
120120
121- struct Virtq {
122- _dma : DMAPool < VirtqDMA > ,
123- vq_freelist : LinkedList < VirtqEntry > ,
124- // TODO: add more fields
125- }
126-
127121#[ allow( dead_code) ]
128- struct VirtqEntry {
129- qe_index : u16 , // index in vq_desc array
130- // The following are used only in the `head' entry
131- qe_next : i16 , // next enq slot
132- qe_indirect : i16 , // 1 if using indirect
133- qe_vr_index : i16 , // index in sc_reqs array
134- qe_desc_base : VirtqDesc , // pointer to vd array
122+ struct Virtq {
123+ vq_dma : DMAPool < VirtqDMA > ,
124+ vq_freelist : LinkedList < usize > ,
125+ vq_num : usize ,
126+ vq_mask : usize ,
127+ vq_avail_idx : u16 ,
128+ vq_used_idx : u16 ,
129+ vq_index : u16 ,
130+ vq_intr_vec : u16 ,
135131}
136132
137133impl Virtq {
138- pub fn new ( dma : DMAPool < VirtqDMA > ) -> Self {
139- Self {
140- _dma : dma,
141- vq_freelist : LinkedList :: new ( ) ,
134+ fn init ( & mut self ) {
135+ assert ! ( self . vq_num > 0 ) ;
136+
137+ self . vq_freelist = LinkedList :: new ( ) ;
138+ for i in ( 0 ..self . vq_num ) . rev ( ) {
139+ self . vq_freelist . push_front ( i) ;
142140 }
141+
142+ self . vq_avail_idx = 0 ;
143+ self . vq_used_idx = 0 ;
143144 }
144145
145146 #[ allow( dead_code) ]
146- fn vq_alloc_entry ( & mut self ) -> Option < VirtqEntry > {
147+ fn vq_alloc_entry ( & mut self ) -> Option < usize > {
147148 self . vq_freelist . pop_front ( )
148149 }
149150
150151 #[ allow( dead_code) ]
151- fn vq_free_entry ( & mut self , entry : VirtqEntry ) {
152- self . vq_freelist . push_front ( entry ) ;
152+ fn vq_free_entry ( & mut self , slot : usize ) {
153+ self . vq_freelist . push_front ( slot ) ;
153154 }
154155
155156 /// enqueue_prep: allocate a slot number
156157 #[ allow( dead_code) ]
157- fn virtio_enqueue_prep ( & mut self ) -> Option < u16 > {
158- let mut qe = self . vq_alloc_entry ( ) ?;
159-
160- // next slot is not allocated yet
161- qe. qe_next = -1 ;
162- Some ( qe. qe_index )
158+ fn virtio_enqueue_prep ( & mut self ) -> Option < usize > {
159+ self . vq_alloc_entry ( )
163160 }
164161}
165162
@@ -520,10 +517,8 @@ impl VirtioNetInner {
520517 }
521518
522519 /// Allocate a vq.
523- /// maxnsegs denotes how much space should be allocated for indirect descriptors.
524- /// maxnsegs == 1 can be used to disable use indirect descriptors for this queue.
525520 #[ allow( dead_code) ]
526- fn virtio_alloc_vq ( & mut self , index : u16 , _maxnsegs : u16 ) -> Result < Virtq , VirtioDriverErr > {
521+ fn virtio_alloc_vq ( & mut self , index : u16 ) -> Result < Virtq , VirtioDriverErr > {
527522 let vq_size = self . virtio_pci_read_queue_size ( index) ? as usize ;
528523 if vq_size == 0 {
529524 return Err ( VirtioDriverErr :: NoVirtqueue ) ;
@@ -536,13 +531,21 @@ impl VirtioNetInner {
536531 }
537532
538533 // alloc and map the memory
539- let allocsize = core:: mem:: size_of :: < Virtq > ( ) ;
540- let dma = DMAPool :: new ( 0 , allocsize / PAGESIZE ) . ok_or ( VirtioDriverErr :: DMAPool ) ?;
534+ let allocsize = core:: mem:: size_of :: < VirtqDMA > ( ) ;
535+ let vq_dma = DMAPool :: new ( 0 , allocsize / PAGESIZE ) . ok_or ( VirtioDriverErr :: DMAPool ) ?;
541536
542- // remember addresses and offsets for later use
543- let vq = Virtq :: new ( dma) ;
537+ let mut vq = Virtq {
538+ vq_dma,
539+ vq_freelist : LinkedList :: new ( ) ,
540+ vq_num : vq_size,
541+ vq_mask : vq_size - 1 ,
542+ vq_avail_idx : 0 ,
543+ vq_used_idx : 0 ,
544+ vq_index : index,
545+ vq_intr_vec : 0 ,
546+ } ;
544547
545- // TODO: continue Virtq initialization
548+ vq . init ( ) ;
546549
547550 Ok ( vq)
548551 }
0 commit comments