fn write_common_config(
        &mut self,
        device: &Arc<Mutex<dyn VirtioDevice>>,
        interrupt_status: &Arc<AtomicU32>,
        offset: u64,
        value: u32,
    ) -> Result<()> {
        match offset {
            DEVICE_FEATURES_SEL_REG => self.features_select = value,
            DRIVER_FEATURES_REG => {
                if self.check_device_status(
                    CONFIG_STATUS_DRIVER,
                    CONFIG_STATUS_FEATURES_OK | CONFIG_STATUS_FAILED,
                ) {
                    device
                        .lock()
                        .unwrap()
                        .set_driver_features(self.acked_features_select, value);
                    if self.acked_features_select == 1
                        && virtio_has_feature(u64::from(value) << 32, VIRTIO_F_RING_PACKED)
                    {
                        self.queue_type = QUEUE_TYPE_PACKED_VRING;
                    }
                } else {
                    return Err(ErrorKind::DevStatErr(self.device_status).into());
                }
            }
            DRIVER_FEATURES_SEL_REG => self.acked_features_select = value,
            QUEUE_SEL_REG => self.queue_select = value,
            QUEUE_NUM_REG => self
                .get_mut_queue_config()
                .map(|config| config.size = value as u16)?,
            QUEUE_READY_REG => self
                .get_mut_queue_config()
                .map(|config| config.ready = value == 1)?,
            INTERRUPT_ACK_REG => {
                if self.check_device_status(CONFIG_STATUS_DRIVER_OK, 0) {
                    self.interrupt_status = interrupt_status.fetch_and(!value, Ordering::SeqCst);
                }
            }
            STATUS_REG => self.device_status = value,
            QUEUE_DESC_LOW_REG => self.get_mut_queue_config().map(|config| {
                config.desc_table = GuestAddress(config.desc_table.0 | u64::from(value));
            })?,
            QUEUE_DESC_HIGH_REG => self.get_mut_queue_config().map(|config| {
                config.desc_table = GuestAddress(config.desc_table.0 | (u64::from(value) << 32));
            })?,
            QUEUE_AVAIL_LOW_REG => self.get_mut_queue_config().map(|config| {
                config.avail_ring = GuestAddress(config.avail_ring.0 | u64::from(value));
            })?,
            QUEUE_AVAIL_HIGH_REG => self.get_mut_queue_config().map(|config| {
                config.avail_ring = GuestAddress(config.avail_ring.0 | (u64::from(value) << 32));
            })?,
            QUEUE_USED_LOW_REG => self.get_mut_queue_config().map(|config| {
                config.used_ring = GuestAddress(config.used_ring.0 | u64::from(value));
            })?,
            QUEUE_USED_HIGH_REG => self.get_mut_queue_config().map(|config| {
                config.used_ring = GuestAddress(config.used_ring.0 | (u64::from(value) << 32));
            })?,
            _ => {
                return Err(ErrorKind::MmioRegErr(offset).into());
            }
        };
        Ok(())
    }
/// Write data to the common config of virtio device.
///
/// # Arguments
///
/// * `device` - Virtio device entity.
/// * `offset` - The offset of common config.
/// * `value` - The value to write.
///
/// # Errors
///
/// Returns Error if the offset is out of bound.
Write data to the common config of virtio device.
Write data to the common config of virtio device .
fn write_common_config(
        &mut self,
        device: &Arc<Mutex<dyn VirtioDevice>>,
        interrupt_status: &Arc<AtomicU32>,
        offset: u64,
        value: u32,
    ) -> Result<()> {
        match offset {
            DEVICE_FEATURES_SEL_REG => self.features_select = value,
            DRIVER_FEATURES_REG => {
                if self.check_device_status(
                    CONFIG_STATUS_DRIVER,
                    CONFIG_STATUS_FEATURES_OK | CONFIG_STATUS_FAILED,
                ) {
                    device
                        .lock()
                        .unwrap()
                        .set_driver_features(self.acked_features_select, value);
                    if self.acked_features_select == 1
                        && virtio_has_feature(u64::from(value) << 32, VIRTIO_F_RING_PACKED)
                    {
                        self.queue_type = QUEUE_TYPE_PACKED_VRING;
                    }
                } else {
                    return Err(ErrorKind::DevStatErr(self.device_status).into());
                }
            }
            DRIVER_FEATURES_SEL_REG => self.acked_features_select = value,
            QUEUE_SEL_REG => self.queue_select = value,
            QUEUE_NUM_REG => self
                .get_mut_queue_config()
                .map(|config| config.size = value as u16)?,
            QUEUE_READY_REG => self
                .get_mut_queue_config()
                .map(|config| config.ready = value == 1)?,
            INTERRUPT_ACK_REG => {
                if self.check_device_status(CONFIG_STATUS_DRIVER_OK, 0) {
                    self.interrupt_status = interrupt_status.fetch_and(!value, Ordering::SeqCst);
                }
            }
            STATUS_REG => self.device_status = value,
            QUEUE_DESC_LOW_REG => self.get_mut_queue_config().map(|config| {
                config.desc_table = GuestAddress(config.desc_table.0 | u64::from(value));
            })?,
            QUEUE_DESC_HIGH_REG => self.get_mut_queue_config().map(|config| {
                config.desc_table = GuestAddress(config.desc_table.0 | (u64::from(value) << 32));
            })?,
            QUEUE_AVAIL_LOW_REG => self.get_mut_queue_config().map(|config| {
                config.avail_ring = GuestAddress(config.avail_ring.0 | u64::from(value));
            })?,
            QUEUE_AVAIL_HIGH_REG => self.get_mut_queue_config().map(|config| {
                config.avail_ring = GuestAddress(config.avail_ring.0 | (u64::from(value) << 32));
            })?,
            QUEUE_USED_LOW_REG => self.get_mut_queue_config().map(|config| {
                config.used_ring = GuestAddress(config.used_ring.0 | u64::from(value));
            })?,
            QUEUE_USED_HIGH_REG => self.get_mut_queue_config().map(|config| {
                config.used_ring = GuestAddress(config.used_ring.0 | (u64::from(value) << 32));
            })?,
            _ => {
                return Err(ErrorKind::MmioRegErr(offset).into());
            }
        };
        Ok(())
    }
fn write_common_config ( & mut self , device : & Arc < Mutex < dyn VirtioDevice > > , interrupt_status : & Arc < AtomicU32 > , offset : u64 , value : u32 , ) -> Result < ( ) > { match offset { DEVICE_FEATURES_SEL_REG => self . features_select = value , DRIVER_FEATURES_REG => { if self . check_device_status ( CONFIG_STATUS_DRIVER , CONFIG_STATUS_FEATURES_OK | CONFIG_STATUS_FAILED , ) { device . lock ( ) . unwrap ( ) . set_driver_features ( self . acked_features_select , value ) ; if self . acked_features_select == 1 && virtio_has_feature ( u64 :: from ( value ) << 32 , VIRTIO_F_RING_PACKED ) { self . queue_type = QUEUE_TYPE_PACKED_VRING ; } } else { return Err ( ErrorKind :: DevStatErr ( self . device_status ) . into ( ) ) ; } } DRIVER_FEATURES_SEL_REG => self . acked_features_select = value , QUEUE_SEL_REG => self . queue_select = value , QUEUE_NUM_REG => self . get_mut_queue_config ( ) . map ( | config | config . size = value as u16 ) ? , QUEUE_READY_REG => self . get_mut_queue_config ( ) . map ( | config | config . ready = value == 1 ) ? , INTERRUPT_ACK_REG => { if self . check_device_status ( CONFIG_STATUS_DRIVER_OK , 0 ) { self . interrupt_status = interrupt_status . fetch_and ( ! value , Ordering :: SeqCst ) ; } } STATUS_REG => self . device_status = value , QUEUE_DESC_LOW_REG => self . get_mut_queue_config ( ) . map ( | config | { config . desc_table = GuestAddress ( config . desc_table . 0 | u64 :: from ( value ) ) ; } ) ? , QUEUE_DESC_HIGH_REG => self . get_mut_queue_config ( ) . map ( | config | { config . desc_table = GuestAddress ( config . desc_table . 0 | ( u64 :: from ( value ) << 32 ) ) ; } ) ? , QUEUE_AVAIL_LOW_REG => self . get_mut_queue_config ( ) . map ( | config | { config . avail_ring = GuestAddress ( config . avail_ring . 0 | u64 :: from ( value ) ) ; } ) ? , QUEUE_AVAIL_HIGH_REG => self . get_mut_queue_config ( ) . map ( | config | { config . avail_ring = GuestAddress ( config . avail_ring . 0 | ( u64 :: from ( value ) << 32 ) ) ; } ) ? , QUEUE_USED_LOW_REG => self . get_mut_queue_config ( ) . map ( | config | { config . used_ring = GuestAddress ( config . used_ring . 0 | u64 :: from ( value ) ) ; } ) ? , QUEUE_USED_HIGH_REG => self . get_mut_queue_config ( ) . map ( | config | { config . used_ring = GuestAddress ( config . used_ring . 0 | ( u64 :: from ( value ) << 32 ) ) ; } ) ? , _ => { return Err ( ErrorKind :: MmioRegErr ( offset ) . into ( ) ) ; } } ; Ok ( ( ) ) }
Write data to the common config of virtio device.
Write data to the common config of virtio device .
&mut self
device
&Arc<Mutex<dyn VirtioDevice>>
interrupt_status
&Arc<AtomicU32>
offset
u64
value
u32
&mut self
device
&Arc<Mutex<dyn VirtioDevice>>
interrupt_status
&Arc<AtomicU32>
offset
u64
value
u32
errors
Returns Error if the offset is out of bound.
Returns Error if the offset is out of bound .