The RPC parsing should not be done in the same method as the transport header parsing. Split it out and introduce a `RpcMessage` type to indicate messages that have been successfully parsed as RPC. This makes the code easier to move around into its new destination.
Signed-off-by: Alexandre Courbot <[email protected]> --- drivers/gpu/nova-core/gsp/cmdq.rs | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs index d8a7716fc500..b8a9e02b76fe 100644 --- a/drivers/gpu/nova-core/gsp/cmdq.rs +++ b/drivers/gpu/nova-core/gsp/cmdq.rs @@ -553,6 +553,17 @@ struct GspMessage<'a> { contents: (&'a [u8], &'a [u8]), } +/// A RPC message ready to be processed from the message queue. +/// +/// This is the type returned by [`CmdqInner::parse_rpc_message`]. +struct RpcMessage<'a> { + // Reference to the RPC header of the message. + header: &'a RpcMessageHeader, + // Slices to the contents of the message. The second slice is zero unless the message loops + // over the message queue. + contents: (&'a [u8], &'a [u8]), +} + /// GSP command queue. /// /// Provides the ability to send commands and receive messages from the GSP using a shared memory @@ -794,7 +805,7 @@ fn send_command<M>(&mut self, command: M) -> Result /// message queue. /// /// Error codes returned by the message constructor are propagated as-is. - fn wait_for_msg(&self, timeout: Delta) -> Result<GspMessage<'_>> { + fn wait_for_msg(&self, timeout: Delta) -> Result<RpcMessage<'_>> { // Wait for a message to arrive from the GSP. let (slice_1, slice_2) = read_poll_timeout( || Ok(self.gsp_mem.driver_read_area()), @@ -816,6 +827,24 @@ fn wait_for_msg(&self, timeout: Delta) -> Result<GspMessage<'_>> { return Err(EIO); } + self.parse_rpc_message(GspMessage { + header, + contents: (slice_1, slice_2), + }) + } + + /// Validate the RPC layer of `element` and returns its RPC header and its contents trimmed down + /// to the RPC payload. + /// + /// # Errors + /// + /// - `EIO` if the element is shorter than the payload length advertised by the RPC header. + fn parse_rpc_message<'a>(&self, element: GspMessage<'a>) -> Result<RpcMessage<'a>> { + let GspMessage { + header, + contents: (slice_1, slice_2), + } = element; + let rpc_header = header.rpc_header(); let payload_length = rpc_header.length(); @@ -845,8 +874,8 @@ fn wait_for_msg(&self, timeout: Delta) -> Result<GspMessage<'_>> { ) }; - Ok(GspMessage { - header, + Ok(RpcMessage { + header: rpc_header, contents: (slice_1, slice_2), }) } @@ -873,7 +902,7 @@ fn receive_msg<M: MessageFromGsp>(&mut self, timeout: Delta) -> Result<M> Error: From<M::InitError>, { let message = self.wait_for_msg(timeout)?; - let function = message.header.rpc_header().function().map_err(|_| EINVAL)?; + let function = message.header.function().map_err(|_| EINVAL)?; // Extract the message. Store the result as we want to advance the read pointer even in // case of failure. -- 2.55.0
