@@ -109,8 +109,15 @@ impl PartialOrd for PciIoAddress {
109109}
110110
111111impl Ord for PciIoAddress {
112- fn cmp ( & self , other : & Self ) -> Ordering {
113- u64:: from ( * self ) . cmp ( & u64:: from ( * other) )
112+ fn cmp ( & self , o : & Self ) -> Ordering {
113+ // extract fields because taking references to unaligned fields in packed structs is a nono
114+ let ( bus, dev, fun, reg, ext_reg) = ( self . bus , self . dev , self . fun , self . reg , self . ext_reg ) ;
115+ let ( o_bus, o_dev, o_fun, o_reg, o_ext_reg) = ( o. bus , o. dev , o. fun , o. reg , o. ext_reg ) ;
116+ bus. cmp ( & o_bus)
117+ . then ( dev. cmp ( & o_dev) )
118+ . then ( fun. cmp ( & o_fun) )
119+ . then ( reg. cmp ( & o_reg) )
120+ . then ( ext_reg. cmp ( & o_ext_reg) )
114121 }
115122}
116123
@@ -152,6 +159,8 @@ fn encode_io_mode_and_unit<U: PciIoUnit>(mode: PciIoMode) -> PciRootBridgeIoProt
152159
153160#[ cfg( test) ]
154161mod tests {
162+ use core:: cmp:: Ordering ;
163+
155164 use super :: PciIoAddress ;
156165
157166 #[ test]
@@ -170,4 +179,43 @@ mod tests {
170179 assert_eq ! ( rawaddr, 0x99_bb_dd_ff_7755_3311 ) ;
171180 assert_eq ! ( srcaddr, dstaddr) ;
172181 }
182+
183+ #[ test]
184+ fn test_pci_order ( ) {
185+ let addr0_0_0 = PciIoAddress :: new ( 0 , 0 , 0 ) ;
186+ let addr0_0_1 = PciIoAddress :: new ( 0 , 0 , 1 ) ;
187+ let addr0_1_0 = PciIoAddress :: new ( 0 , 1 , 0 ) ;
188+ let addr1_0_0 = PciIoAddress :: new ( 1 , 0 , 0 ) ;
189+
190+ assert_eq ! ( addr0_0_0. cmp( & addr0_0_0) , Ordering :: Equal ) ;
191+ assert_eq ! ( addr0_0_0. cmp( addr0_0_1) , Ordering :: Less ) ;
192+ assert_eq ! ( addr0_0_0. cmp( & addr0_1_0) , Ordering :: Less ) ;
193+ assert_eq ! ( addr0_0_0. cmp( & addr1_0_0) , Ordering :: Less ) ;
194+
195+ assert_eq ! ( addr0_0_1. cmp( addr0_0_0) , Ordering :: Greater ) ;
196+ assert_eq ! ( addr0_0_1. cmp( addr0_0_1) , Ordering :: Equal ) ;
197+ assert_eq ! ( addr0_0_1. cmp( & addr0_1_0) , Ordering :: Less ) ;
198+ assert_eq ! ( addr0_0_1. cmp( & addr1_0_0) , Ordering :: Less ) ;
199+
200+ assert_eq ! ( addr0_1_0. cmp( addr0_0_0) , Ordering :: Greater ) ;
201+ assert_eq ! ( addr0_1_0. cmp( addr0_0_1) , Ordering :: Greater ) ;
202+ assert_eq ! ( addr0_1_0. cmp( & addr0_1_0) , Ordering :: Equal ) ;
203+ assert_eq ! ( addr0_1_0. cmp( & addr1_0_0) , Ordering :: Less ) ;
204+
205+ assert_eq ! ( addr1_0_0. cmp( addr0_0_0) , Ordering :: Greater ) ;
206+ assert_eq ! ( addr1_0_0. cmp( addr0_0_1) , Ordering :: Greater ) ;
207+ assert_eq ! ( addr1_0_0. cmp( & addr0_1_0) , Ordering :: Greater ) ;
208+ assert_eq ! ( addr1_0_0. cmp( & addr1_0_0) , Ordering :: Equal ) ;
209+
210+ assert_eq ! ( addr0_0_0. cmp( addr0_0_0. with_register( 1 ) ) , Ordering :: Less ) ;
211+ assert_eq ! ( addr0_0_0. with_register( 1 ) . cmp( addr0_0_0) , Ordering :: Greater ) ;
212+ assert_eq ! (
213+ addr0_0_0. cmp( addr0_0_0. with_extended_register( 1 ) ) ,
214+ Ordering :: Less
215+ ) ;
216+ assert_eq ! (
217+ addr0_0_0. with_extended_register( 1 ) . cmp( addr0_0_0) ,
218+ Ordering :: Greater
219+ ) ;
220+ }
173221}
0 commit comments