1+ use alloc:: boxed:: Box ;
12use alloc:: string:: String ;
23use alloc:: vec:: Vec ;
34use core:: ptr:: NonNull ;
@@ -135,23 +136,10 @@ unsafe fn check_ptr(
135136 Some ( mmio)
136137}
137138
138- trait MmioIterator : Iterator < Item = ( VolatileRef < ' static , DeviceRegisters > , u8 ) > { }
139-
140- impl <
141- I : Iterator ,
142- U : IntoIterator < Item = ( VolatileRef < ' static , DeviceRegisters > , u8 ) > ,
143- F : FnMut ( I :: Item ) -> U ,
144- > MmioIterator for core:: iter:: FlatMap < I , U , F >
145- {
146- }
147-
148- type LinuxArgsMmioIterator = impl MmioIterator ;
149-
150- #[ define_opaque( LinuxArgsMmioIterator ) ]
151139fn check_linux_args (
152140 linux_mmio : & ' static [ String ] ,
153141 virtual_address : VirtAddr ,
154- ) -> LinuxArgsMmioIterator {
142+ ) -> impl Iterator < Item = ( VolatileRef < ' static , DeviceRegisters > , u8 ) > {
155143 linux_mmio
156144 . iter ( )
157145 . inspect ( |arg| trace ! ( "check linux parameter: {arg}" ) )
@@ -169,17 +157,9 @@ fn check_linux_args(
169157 } )
170158}
171159
172- impl <
173- I : Iterator < Item : IntoIterator < IntoIter = U , Item = U :: Item > > ,
174- U : Iterator < Item = ( VolatileRef < ' static , DeviceRegisters > , u8 ) > ,
175- > MmioIterator for core:: iter:: Flatten < I >
176- {
177- }
178-
179- type GuessMmioIterator = impl MmioIterator ;
180-
181- #[ define_opaque( GuessMmioIterator ) ]
182- fn guess_device ( virtual_address : VirtAddr ) -> GuessMmioIterator {
160+ fn guess_device (
161+ virtual_address : VirtAddr ,
162+ ) -> impl Iterator < Item = ( VolatileRef < ' static , DeviceRegisters > , u8 ) > {
183163 // Look for the device-ID in all possible 64-byte aligned addresses within this range.
184164 ( MMIO_START ..MMIO_END )
185165 . step_by ( 512 )
@@ -202,37 +182,6 @@ fn guess_device(virtual_address: VirtAddr) -> GuessMmioIterator {
202182 . flatten ( )
203183}
204184
205- #[ enum_dispatch:: enum_dispatch( MmioIterator ) ]
206- enum MmioIteratorEnum {
207- LinuxArgsMmioIterator ,
208- GuessMmioIterator ,
209- }
210-
211- impl Iterator for MmioIteratorEnum {
212- type Item = ( VolatileRef < ' static , DeviceRegisters > , u8 ) ;
213-
214- fn next ( & mut self ) -> Option < Self :: Item > {
215- match self {
216- MmioIteratorEnum :: LinuxArgsMmioIterator ( iter) => iter. next ( ) ,
217- MmioIteratorEnum :: GuessMmioIterator ( iter) => iter. next ( ) ,
218- }
219- }
220- }
221-
222- fn detect_devices ( ) -> MmioIteratorEnum {
223- let layout = PageLayout :: from_size ( BasePageSize :: SIZE as usize ) . unwrap ( ) ;
224- let page_range = PageBox :: new ( layout) . unwrap ( ) ;
225- let virtual_address = VirtAddr :: from ( page_range. start ( ) ) ;
226-
227- let linux_mmio = env:: mmio ( ) ;
228-
229- if linux_mmio. is_empty ( ) {
230- MmioIteratorEnum :: GuessMmioIterator ( guess_device ( virtual_address) )
231- } else {
232- MmioIteratorEnum :: LinuxArgsMmioIterator ( check_linux_args ( linux_mmio, virtual_address) )
233- }
234- }
235-
236185#[ cfg( any(
237186 feature = "virtio-console" ,
238187 feature = "virtio-fs" ,
@@ -269,29 +218,43 @@ pub(crate) fn get_vsock_driver() -> Option<&'static InterruptTicketMutex<VirtioV
269218 . find_map ( |drv| drv. get_vsock_driver ( ) )
270219}
271220
221+ fn register_mmio ( mmio : VolatileRef < ' static , DeviceRegisters > , irq : u8 ) {
222+ match mmio_virtio:: init_device ( mmio, irq) {
223+ #[ cfg( feature = "virtio-console" ) ]
224+ Ok ( VirtioDriver :: Console ( drv) ) => {
225+ register_driver ( MmioDriver :: VirtioConsole ( InterruptTicketMutex :: new ( * drv) ) ) ;
226+ }
227+ #[ cfg( feature = "virtio-fs" ) ]
228+ Ok ( VirtioDriver :: Fs ( drv) ) => {
229+ register_driver ( MmioDriver :: VirtioFs ( InterruptTicketMutex :: new ( * drv) ) ) ;
230+ }
231+ #[ cfg( feature = "virtio-net" ) ]
232+ Ok ( VirtioDriver :: Net ( drv) ) => {
233+ * NETWORK_DEVICE . lock ( ) = Some ( * drv) ;
234+ }
235+ #[ cfg( feature = "virtio-vsock" ) ]
236+ Ok ( VirtioDriver :: Vsock ( drv) ) => {
237+ register_driver ( MmioDriver :: VirtioVsock ( InterruptTicketMutex :: new ( * drv) ) ) ;
238+ }
239+ Err ( err) => error ! ( "Could not initialize virtio-mmio device: {err}" ) ,
240+ }
241+ }
242+
272243pub ( crate ) fn init_drivers ( ) {
273244 without_interrupts ( || {
274- let devices = detect_devices ( ) ;
275-
276- for ( mmio, irq) in devices {
277- match mmio_virtio:: init_device ( mmio, irq) {
278- #[ cfg( feature = "virtio-console" ) ]
279- Ok ( VirtioDriver :: Console ( drv) ) => {
280- register_driver ( MmioDriver :: VirtioConsole ( InterruptTicketMutex :: new ( * drv) ) ) ;
281- }
282- #[ cfg( feature = "virtio-fs" ) ]
283- Ok ( VirtioDriver :: Fs ( drv) ) => {
284- register_driver ( MmioDriver :: VirtioFs ( InterruptTicketMutex :: new ( * drv) ) ) ;
285- }
286- #[ cfg( feature = "virtio-net" ) ]
287- Ok ( VirtioDriver :: Net ( drv) ) => {
288- * NETWORK_DEVICE . lock ( ) = Some ( * drv) ;
289- }
290- #[ cfg( feature = "virtio-vsock" ) ]
291- Ok ( VirtioDriver :: Vsock ( drv) ) => {
292- register_driver ( MmioDriver :: VirtioVsock ( InterruptTicketMutex :: new ( * drv) ) ) ;
293- }
294- Err ( err) => error ! ( "Could not initialize virtio-mmio device: {err}" ) ,
245+ let layout = PageLayout :: from_size ( BasePageSize :: SIZE as usize ) . unwrap ( ) ;
246+ let page_range = PageBox :: new ( layout) . unwrap ( ) ;
247+ let virtual_address = VirtAddr :: from ( page_range. start ( ) ) ;
248+
249+ let linux_mmio = env:: mmio ( ) ;
250+
251+ if linux_mmio. is_empty ( ) {
252+ for ( mmio, irq) in guess_device ( virtual_address) {
253+ register_mmio ( mmio, irq) ;
254+ }
255+ } else {
256+ for ( mmio, irq) in check_linux_args ( linux_mmio, virtual_address) {
257+ register_mmio ( mmio, irq) ;
295258 }
296259 }
297260
0 commit comments