diff --git a/src/runtime/src/rtio_mgt.rs b/src/runtime/src/rtio_mgt.rs index b6c1d2b..ee8d79c 100644 --- a/src/runtime/src/rtio_mgt.rs +++ b/src/runtime/src/rtio_mgt.rs @@ -45,7 +45,7 @@ pub mod drtio { unsafe { (csr::DRTIO[linkno].rx_up_read)() == 1 } } - async fn process_async_packets(linkno: u8, packet: Packet) -> Option { + async fn process_async_packets(aux_mutex: &Mutex, linkno: u8, packet: Packet) -> Option { // returns None if an async packet has been consumed match packet { Packet::DmaPlaybackStatus { @@ -71,6 +71,7 @@ pub mod drtio { } => { subkernel::message_handle_incoming(id, last, length as usize, &data).await; // acknowledge receiving part of the message + let _lock = aux_mutex.async_lock().await; drtioaux_async::send(linkno, &Packet::SubkernelMessageAck { destination: from }) .await .unwrap(); @@ -102,14 +103,7 @@ pub mod drtio { } let _lock = aux_mutex.async_lock().await; drtioaux_async::send(linkno, request).await.unwrap(); - loop { - let reply = recv_aux_timeout(linkno, 200, timer).await?; - let packet = process_async_packets(linkno, reply).await; - match packet { - Some(packet) => return Ok(packet), - None => (), - } - } + Ok(recv_aux_timeout(linkno, 200, timer).await?) } async fn drain_buffer(linkno: u8, draining_time: Milliseconds, timer: GlobalTimer) { @@ -219,7 +213,7 @@ pub mod drtio { let _lock = aux_mutex.async_lock().await; match drtioaux_async::recv(linkno).await { Ok(Some(packet)) => { - if let Some(packet) = process_async_packets(linkno, packet).await { + if let Some(packet) = process_async_packets(aux_mutex, linkno, packet).await { warn!("[LINK#{}] unsolicited aux packet: {:?}", linkno, packet); } } @@ -291,53 +285,61 @@ pub mod drtio { let linkno = hop - 1; if destination_up(up_destinations, destination).await { if up_links[linkno as usize] { - let reply = aux_transact( - aux_mutex, - linkno, - &Packet::DestinationStatusRequest { - destination: destination, - }, - timer, - ) - .await; - match reply { - Ok(Packet::DestinationDownReply) => { - destination_set_up(routing_table, up_destinations, destination, false).await; - remote_dma::destination_changed(aux_mutex, routing_table, timer, destination, false) - .await; - subkernel::destination_changed(aux_mutex, routing_table, timer, destination, false) - .await; + loop { + let reply = aux_transact( + aux_mutex, + linkno, + &Packet::DestinationStatusRequest { + destination: destination, + }, + timer, + ) + .await; + match reply { + Ok(Packet::DestinationDownReply) => { + destination_set_up(routing_table, up_destinations, destination, false).await; + remote_dma::destination_changed(aux_mutex, routing_table, timer, destination, false) + .await; + subkernel::destination_changed(aux_mutex, routing_table, timer, destination, false) + .await; + } + Ok(Packet::DestinationOkReply) => (), + Ok(Packet::DestinationSequenceErrorReply { channel }) => { + error!( + "[DEST#{}] RTIO sequence error involving channel 0x{:04x}:{}", + destination, + channel, + resolve_channel_name(channel as u32) + ); + unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_SEQUENCE_ERROR }; + } + Ok(Packet::DestinationCollisionReply { channel }) => { + error!( + "[DEST#{}] RTIO collision involving channel 0x{:04x}:{}", + destination, + channel, + resolve_channel_name(channel as u32) + ); + unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_COLLISION }; + } + Ok(Packet::DestinationBusyReply { channel }) => { + error!( + "[DEST#{}] RTIO busy error involving channel 0x{:04x}:{}", + destination, + channel, + resolve_channel_name(channel as u32) + ); + unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_BUSY }; + } + Ok(packet) => { + match process_async_packets(aux_mutex, linkno, packet).await { + Some(packet) => error!("[DEST#{}] received unexpected aux packet: {:?}", destination, packet), + None => continue + } + }, + Err(e) => error!("[DEST#{}] communication failed ({})", destination, e), } - Ok(Packet::DestinationOkReply) => (), - Ok(Packet::DestinationSequenceErrorReply { channel }) => { - error!( - "[DEST#{}] RTIO sequence error involving channel 0x{:04x}:{}", - destination, - channel, - resolve_channel_name(channel as u32) - ); - unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_SEQUENCE_ERROR }; - } - Ok(Packet::DestinationCollisionReply { channel }) => { - error!( - "[DEST#{}] RTIO collision involving channel 0x{:04x}:{}", - destination, - channel, - resolve_channel_name(channel as u32) - ); - unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_COLLISION }; - } - Ok(Packet::DestinationBusyReply { channel }) => { - error!( - "[DEST#{}] RTIO busy error involving channel 0x{:04x}:{}", - destination, - channel, - resolve_channel_name(channel as u32) - ); - unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_BUSY }; - } - Ok(packet) => error!("[DEST#{}] received unexpected aux packet: {:?}", destination, packet), - Err(e) => error!("[DEST#{}] communication failed ({})", destination, e), + break; } } else { destination_set_up(routing_table, up_destinations, destination, false).await;