@@ -525,6 +525,7 @@ enum ProtocolState {
525
525
526
526
struct ReadyState {
527
527
send_device : bool ,
528
+ send_completion : Option < u64 > ,
528
529
vpci_version : protocol:: ProtocolVersion ,
529
530
}
530
531
@@ -566,6 +567,7 @@ impl<T: RingMem> VpciChannelState<T> {
566
567
self . state = ProtocolState :: Ready ( ReadyState {
567
568
vpci_version : version,
568
569
send_device : false ,
570
+ send_completion : None ,
569
571
} ) ;
570
572
}
571
573
} else {
@@ -639,6 +641,10 @@ impl ReadyState {
639
641
self . send_child_device ( conn, dev) . await ?;
640
642
self . send_device = false ;
641
643
}
644
+ if let Some ( transaction_id) = self . send_completion {
645
+ conn. send_completion ( Some ( transaction_id) , & protocol:: Status :: SUCCESS , & [ ] ) ?;
646
+ self . send_completion = None ;
647
+ }
642
648
643
649
// Don't pull a packets off the ring until there is space for its completion.
644
650
conn. wait_for_completion_space ( ) . await ?;
@@ -688,8 +694,9 @@ impl ReadyState {
688
694
}
689
695
PacketData :: FdoD0Entry { mmio_start } => {
690
696
dev. config_space . map ( mmio_start) ;
691
- conn. send_completion ( transaction_id, & protocol:: Status :: SUCCESS , & [ ] ) ?;
692
697
self . send_device = true ;
698
+ // Send the completion after the device has been sent.
699
+ self . send_completion = transaction_id;
693
700
}
694
701
PacketData :: FdoD0Exit => {
695
702
dev. config_space . unmap ( ) ;
@@ -1055,11 +1062,16 @@ impl VpciConfigSpace {
1055
1062
}
1056
1063
1057
1064
fn map ( & mut self , addr : u64 ) {
1065
+ tracing:: debug!( addr, "mapping config space" ) ;
1058
1066
self . offset . 0 . store ( addr, Ordering :: Relaxed ) ;
1059
1067
self . control_mmio . map ( addr) ;
1060
1068
}
1061
1069
1062
1070
fn unmap ( & mut self ) {
1071
+ tracing:: debug!(
1072
+ addr = self . offset. 0 . load( Ordering :: Relaxed ) ,
1073
+ "unmapping config space"
1074
+ ) ;
1063
1075
// Note that there may be some current accessors that this will not
1064
1076
// flush out synchronously. The MMIO implementation in bus.rs must be
1065
1077
// careful to ignore reads/writes that are not to an expected address.
@@ -1073,7 +1085,7 @@ impl VpciConfigSpace {
1073
1085
/// PCI Config space offset structure
1074
1086
#[ derive( Debug , Clone , Inspect ) ]
1075
1087
#[ inspect( transparent) ]
1076
- pub struct VpciConfigSpaceOffset ( Arc < AtomicU64 > ) ;
1088
+ pub struct VpciConfigSpaceOffset ( # [ inspect ( hex ) ] Arc < AtomicU64 > ) ;
1077
1089
1078
1090
impl VpciConfigSpaceOffset {
1079
1091
const INVALID : u64 = !0 ;
@@ -1391,7 +1403,7 @@ mod tests {
1391
1403
}
1392
1404
}
1393
1405
1394
- async fn power_on ( & mut self , base_address : u64 ) {
1406
+ async fn initiate_power_on ( & mut self , base_address : u64 ) -> u64 {
1395
1407
let power_on = protocol:: FdoD0Entry {
1396
1408
message_type : protocol:: MessageType :: FDO_D0_ENTRY ,
1397
1409
padding : 0 ,
@@ -1401,15 +1413,7 @@ mod tests {
1401
1413
self . write_packet ( Some ( transaction_id) , & power_on)
1402
1414
. await
1403
1415
. unwrap ( ) ;
1404
-
1405
- let mut pkt_info = ReadPacketInfo :: None ;
1406
- let status: protocol:: Status = self . read_packet ( & mut pkt_info) . await . unwrap ( ) ;
1407
- if let ReadPacketInfo :: Completion ( id) = pkt_info {
1408
- assert_eq ! ( id, transaction_id) ;
1409
- assert_eq ! ( status, protocol:: Status :: SUCCESS ) ;
1410
- } else {
1411
- panic ! ( "Unexpected D0 (power on) reply" ) ;
1412
- }
1416
+ transaction_id
1413
1417
}
1414
1418
1415
1419
fn verify_device_relations2 ( & self , message : & Relations2 ) {
@@ -1432,7 +1436,7 @@ mod tests {
1432
1436
1433
1437
async fn start_device ( & mut self , base_address : u64 ) {
1434
1438
self . negotiate_version ( ) . await ;
1435
- self . power_on ( base_address) . await ;
1439
+ let transaction_id = self . initiate_power_on ( base_address) . await ;
1436
1440
let mut pkt_info = ReadPacketInfo :: None ;
1437
1441
let relations: Relations2 = self . read_packet ( & mut pkt_info) . await . unwrap ( ) ;
1438
1442
if let ReadPacketInfo :: NewTransaction = pkt_info {
@@ -1444,6 +1448,15 @@ mod tests {
1444
1448
} else {
1445
1449
panic ! ( "Expecting QueryBusRelations2 message in response to version." ) ;
1446
1450
}
1451
+
1452
+ let mut pkt_info = ReadPacketInfo :: None ;
1453
+ let status: protocol:: Status = self . read_packet ( & mut pkt_info) . await . unwrap ( ) ;
1454
+ if let ReadPacketInfo :: Completion ( id) = pkt_info {
1455
+ assert_eq ! ( id, transaction_id) ;
1456
+ assert_eq ! ( status, protocol:: Status :: SUCCESS ) ;
1457
+ } else {
1458
+ panic ! ( "Unexpected D0 (power on) reply" ) ;
1459
+ }
1447
1460
}
1448
1461
1449
1462
// returns MSI address and data
0 commit comments