Path: blob/main/devices/src/virtio/video/async_cmd_desc_map.rs
5394 views
// Copyright 2020 The ChromiumOS Authors1// Use of this source code is governed by a BSD-style license that can be2// found in the LICENSE file.34use std::collections::BTreeMap;56use crate::virtio::video::command::QueueType;7use crate::virtio::video::device::AsyncCmdResponse;8use crate::virtio::video::device::AsyncCmdTag;9use crate::virtio::video::error::VideoError;10use crate::virtio::video::protocol;11use crate::virtio::video::response::CmdResponse;12use crate::virtio::DescriptorChain;1314/// AsyncCmdDescMap is a BTreeMap which stores descriptor chains in which asynchronous15/// responses will be written.16#[derive(Default)]17pub struct AsyncCmdDescMap(BTreeMap<AsyncCmdTag, DescriptorChain>);1819impl AsyncCmdDescMap {20pub fn insert(&mut self, tag: AsyncCmdTag, descriptor_chain: DescriptorChain) {21self.0.insert(tag, descriptor_chain);22}2324pub fn remove(&mut self, tag: &AsyncCmdTag) -> Option<DescriptorChain> {25self.0.remove(tag)26}2728/// Returns a list of `AsyncCmdResponse`s to cancel pending commands that target29/// stream `target_stream_id`.30/// If `target_queue_type` is specified, then only create the requests for the specified queue.31/// Otherwise, create the requests for both input and output queue.32/// If `processing_tag` is specified, a cancellation request for that tag will33/// not be created.34pub fn create_cancellation_responses(35&self,36target_stream_id: &u32,37target_queue_type: Option<QueueType>,38processing_tag: Option<AsyncCmdTag>,39) -> Vec<AsyncCmdResponse> {40let mut responses = vec![];41for tag in self.0.keys().filter(|&&k| Some(k) != processing_tag) {42match tag {43AsyncCmdTag::Queue {44stream_id,45queue_type,46..47} if stream_id == target_stream_id48&& target_queue_type.as_ref().unwrap_or(queue_type) == queue_type =>49{50responses.push(AsyncCmdResponse::from_response(51*tag,52CmdResponse::ResourceQueue {53timestamp: 0,54flags: protocol::VIRTIO_VIDEO_BUFFER_FLAG_ERR,55size: 0,56},57));58}59AsyncCmdTag::Drain { stream_id } if stream_id == target_stream_id => {60// TODO(b/1518105): Use more appropriate error code if a new protocol supports61// one.62responses.push(AsyncCmdResponse::from_error(63*tag,64VideoError::InvalidOperation,65));66}67AsyncCmdTag::Clear {68stream_id,69queue_type,70} if stream_id == target_stream_id71&& target_queue_type.as_ref().unwrap_or(queue_type) == queue_type =>72{73// TODO(b/1518105): Use more appropriate error code if a new protocol supports74// one.75responses.push(AsyncCmdResponse::from_error(76*tag,77VideoError::InvalidOperation,78));79}80_ => {81// Keep commands for other streams.82}83}84}85responses86}87}888990