@@ -10,7 +10,7 @@ use core::{mem, ptr};
1010
1111use pci_types:: capability:: PciCapability ;
1212use virtio_spec:: pci:: {
13- CapCfgType , CommonCfg , CommonCfgVolatileFieldAccess , CommonCfgVolatileWideFieldAccess ,
13+ Cap , CapCfgType , CommonCfg , CommonCfgVolatileFieldAccess , CommonCfgVolatileWideFieldAccess ,
1414 IsrStatus as IsrStatusRaw ,
1515} ;
1616use virtio_spec:: DeviceStatus ;
@@ -39,7 +39,7 @@ use crate::drivers::virtio::error::VirtioError;
3939pub struct Origin {
4040 cfg_ptr : u16 , // Register to be read to reach configuration structure of type cfg_type
4141 dev_id : u16 ,
42- cap_struct : PciCapRaw ,
42+ cap_struct : Cap ,
4343}
4444
4545/// Maps a given device specific pci configuration structure and
@@ -172,45 +172,6 @@ impl PciCap {
172172 }
173173}
174174
175- /// Virtio's PCI capabilities structure.
176- /// See Virtio specification v.1.1 - 4.1.4
177- ///
178- /// WARN: endianness of this structure should be seen as little endian.
179- /// As this structure is not meant to be used outside of this module and for
180- /// ease of conversion from reading data into struct from PCI configuration
181- /// space, no conversion is made for struct fields.
182- #[ derive( Clone , Debug ) ]
183- #[ repr( C ) ]
184- struct PciCapRaw {
185- cap_vndr : u8 ,
186- cap_next : u8 ,
187- cap_len : u8 ,
188- cfg_type : u8 ,
189- bar_index : u8 ,
190- id : u8 ,
191- padding : [ u8 ; 2 ] ,
192- offset : u32 ,
193- length : u32 ,
194- }
195-
196- // This only shows compiler, that structs are identical
197- // with themselves.
198- impl Eq for PciCapRaw { }
199-
200- // In order to compare two PciCapRaw structs PartialEq is needed
201- impl PartialEq for PciCapRaw {
202- fn eq ( & self , other : & Self ) -> bool {
203- self . cap_vndr == other. cap_vndr
204- && self . cap_next == other. cap_next
205- && self . cap_len == other. cap_len
206- && self . cfg_type == other. cfg_type
207- && self . bar_index == other. bar_index
208- && self . id == other. id
209- && self . offset == other. offset
210- && self . length == other. length
211- }
212- }
213-
214175/// Universal Caplist Collections holds all universal capability structures for
215176/// a given Virtio PCI device.
216177///
@@ -597,7 +558,7 @@ impl NotifCfg {
597558 // Assumes the cap_len is a multiple of 8
598559 // This read MIGHT be slow, as it does NOT ensure 32 bit alignment.
599560 let notify_off_multiplier_ptr =
600- cap. origin . cfg_ptr + u16:: try_from ( mem:: size_of :: < PciCapRaw > ( ) ) . unwrap ( ) ;
561+ cap. origin . cfg_ptr + u16:: try_from ( mem:: size_of :: < Cap > ( ) ) . unwrap ( ) ;
601562 let notify_off_multiplier = cap. device . read_register ( notify_off_multiplier_ptr) ;
602563
603564 // define base memory address from which the actual Queue Notify address can be derived via
@@ -790,23 +751,24 @@ impl ShMemCfg {
790751
791752 // Assumes the cap_len is a multiple of 8
792753 // This read MIGHT be slow, as it does NOT ensure 32 bit alignment.
793- let offset_hi_ptr =
794- cap. origin . cfg_ptr + u16:: try_from ( mem:: size_of :: < PciCapRaw > ( ) ) . unwrap ( ) ;
754+ let offset_hi_ptr = cap. origin . cfg_ptr + u16:: try_from ( mem:: size_of :: < Cap > ( ) ) . unwrap ( ) ;
795755 let offset_hi = cap. device . read_register ( offset_hi_ptr) ;
796756
797757 // Create 64 bit offset from high and low 32 bit values
798- let offset =
799- MemOff :: from ( ( u64:: from ( offset_hi) << 32 ) ^ u64:: from ( cap. origin . cap_struct . offset ) ) ;
758+ let offset = MemOff :: from (
759+ ( u64:: from ( offset_hi) << 32 ) ^ u64:: from ( cap. origin . cap_struct . offset . to_ne ( ) ) ,
760+ ) ;
800761
801762 // Assumes the cap_len is a multiple of 8
802763 // This read MIGHT be slow, as it does NOT ensure 32 bit alignment.
803764 let length_hi_ptr = cap. origin . cfg_ptr
804- + u16:: try_from ( mem:: size_of :: < PciCapRaw > ( ) + mem:: size_of :: < u32 > ( ) ) . unwrap ( ) ;
765+ + u16:: try_from ( mem:: size_of :: < Cap > ( ) + mem:: size_of :: < u32 > ( ) ) . unwrap ( ) ;
805766 let length_hi = cap. device . read_register ( length_hi_ptr) ;
806767
807768 // Create 64 bit length from high and low 32 bit values
808- let length =
809- MemLen :: from ( ( u64:: from ( length_hi) << 32 ) ^ u64:: from ( cap. origin . cap_struct . length ) ) ;
769+ let length = MemLen :: from (
770+ ( u64:: from ( length_hi) << 32 ) ^ u64:: from ( cap. origin . cap_struct . length . to_ne ( ) ) ,
771+ ) ;
810772
811773 let virt_addr_raw = cap. bar . mem_addr + offset;
812774 let raw_ptr = ptr:: with_exposed_provenance_mut :: < u8 > ( virt_addr_raw. into ( ) ) ;
@@ -890,36 +852,6 @@ impl PciBar {
890852 }
891853}
892854
893- /// Reads a raw capability struct [PciCapRaw] out of a PCI device's configuration space.
894- fn read_cap_raw ( device : & PciDevice < PciConfigRegion > , register : u16 ) -> PciCapRaw {
895- let mut quadruple_word: [ u8 ; 16 ] = [ 0 ; 16 ] ;
896-
897- debug ! ( "Converting read word from PCI device config space into native endian bytes." ) ;
898-
899- // Write words sequentially into array
900- for i in 0 ..4 {
901- // Read word need to be converted to little endian bytes as PCI is little endian.
902- // Interpretation of multi byte values needs to be swapped for big endian machines
903- let word: [ u8 ; 4 ] = device. read_register ( register + 4 * i) . to_le_bytes ( ) ;
904- let i = 4 * i as usize ;
905- quadruple_word[ i..i + 4 ] . copy_from_slice ( & word) ;
906- }
907-
908- PciCapRaw {
909- cap_vndr : quadruple_word[ 0 ] ,
910- cap_next : quadruple_word[ 1 ] ,
911- cap_len : quadruple_word[ 2 ] ,
912- cfg_type : quadruple_word[ 3 ] ,
913- bar_index : quadruple_word[ 4 ] ,
914- id : quadruple_word[ 5 ] ,
915- // Unwrapping is okay here, as transformed array slice is always 2 * u8 long and initialized
916- padding : quadruple_word[ 6 ..8 ] . try_into ( ) . unwrap ( ) ,
917- // Unwrapping is okay here, as transformed array slice is always 4 * u8 long and initialized
918- offset : u32:: from_le_bytes ( quadruple_word[ 8 ..12 ] . try_into ( ) . unwrap ( ) ) ,
919- length : u32:: from_le_bytes ( quadruple_word[ 12 ..16 ] . try_into ( ) . unwrap ( ) ) ,
920- }
921- }
922-
923855/// Reads all PCI capabilities, starting at the capabilities list pointer from the
924856/// PCI device.
925857///
@@ -938,17 +870,17 @@ fn read_caps(
938870 PciCapability :: Vendor ( capability) => Some ( capability) ,
939871 _ => None ,
940872 } )
941- . map ( |capability| ( capability. offset , read_cap_raw ( device, capability. offset ) ) )
873+ . map ( |addr| {
874+ let cap = Cap :: read ( addr. clone ( ) , device. access ( ) ) . unwrap ( ) ;
875+ ( addr. offset , cap)
876+ } )
942877 . filter ( |( _ptr, capability) | capability. cfg_type != CapCfgType :: Pci . into ( ) )
943878 . map ( |( ptr, capability) | PciCap {
944879 cfg_type : CapCfgType :: from ( capability. cfg_type ) ,
945- bar : * bars
946- . iter ( )
947- . find ( |bar| bar. index == capability. bar_index )
948- . unwrap ( ) ,
880+ bar : * bars. iter ( ) . find ( |bar| bar. index == capability. bar ) . unwrap ( ) ,
949881 id : capability. id ,
950- offset : MemOff :: from ( capability. offset ) ,
951- length : MemLen :: from ( capability. length ) ,
882+ offset : MemOff :: from ( capability. offset . to_ne ( ) ) ,
883+ length : MemLen :: from ( capability. length . to_ne ( ) ) ,
952884 device : * device,
953885 origin : Origin {
954886 cfg_ptr : ptr,
0 commit comments