fn write_common_config(
        &mut self,
        device: &Arc<Mutex<dyn VirtioDevice>>,
        offset: u64,
        value: u32,
    ) -> PciResult<()> {
        match offset {
            COMMON_DFSELECT_REG => {
                self.features_select = value;
            }
            COMMON_GFSELECT_REG => {
                self.acked_features_select = value;
            }
            COMMON_GF_REG => {
                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)
                {
                    error!("Set packed virtqueue, which is not supported");
                    self.queue_type = QUEUE_TYPE_PACKED_VRING;
                }
            }
            COMMON_MSIX_REG => {
                self.msix_config.store(value as u16, Ordering::SeqCst);
                self.interrupt_status.store(0_u32, Ordering::SeqCst);
            }
            COMMON_STATUS_REG => {
                self.device_status = value;
                if self.device_status == 0 {
                    self.queues_config.iter_mut().for_each(|q| {
                        q.ready = false;
                        q.vector = 0;
                        q.avail_ring = GuestAddress(0);
                        q.desc_table = GuestAddress(0);
                        q.used_ring = GuestAddress(0);
                    });
                    self.msix_config.store(0_u16, Ordering::SeqCst)
                }
            }
            COMMON_Q_SELECT_REG => {
                if value < VIRTIO_QUEUE_MAX {
                    self.queue_select = value as u16;
                }
            }
            COMMON_Q_SIZE_REG => self
                .get_mut_queue_config()
                .map(|config| config.size = value as u16)?,
            COMMON_Q_ENABLE_REG => self
                .get_mut_queue_config()
                .map(|config| config.ready = value == 1)?,
            COMMON_Q_MSIX_REG => self
                .get_mut_queue_config()
                .map(|config| config.vector = value as u16)?,
            COMMON_Q_DESCLO_REG => self.get_mut_queue_config().map(|config| {
                config.desc_table = GuestAddress(config.desc_table.0 | u64::from(value));
            })?,
            COMMON_Q_DESCHI_REG => self.get_mut_queue_config().map(|config| {
                config.desc_table = GuestAddress(config.desc_table.0 | (u64::from(value) << 32));
            })?,
            COMMON_Q_AVAILLO_REG => self.get_mut_queue_config().map(|config| {
                config.avail_ring = GuestAddress(config.avail_ring.0 | u64::from(value));
            })?,
            COMMON_Q_AVAILHI_REG => self.get_mut_queue_config().map(|config| {
                config.avail_ring = GuestAddress(config.avail_ring.0 | (u64::from(value) << 32));
            })?,
            COMMON_Q_USEDLO_REG => self.get_mut_queue_config().map(|config| {
                config.used_ring = GuestAddress(config.used_ring.0 | u64::from(value));
            })?,
            COMMON_Q_USEDHI_REG => self.get_mut_queue_config().map(|config| {
                config.used_ring = GuestAddress(config.used_ring.0 | (u64::from(value) << 32));
            })?,
            _ => {
                return Err(ErrorKind::PciRegister(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>>,
        offset: u64,
        value: u32,
    ) -> PciResult<()> {
        match offset {
            COMMON_DFSELECT_REG => {
                self.features_select = value;
            }
            COMMON_GFSELECT_REG => {
                self.acked_features_select = value;
            }
            COMMON_GF_REG => {
                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)
                {
                    error!("Set packed virtqueue, which is not supported");
                    self.queue_type = QUEUE_TYPE_PACKED_VRING;
                }
            }
            COMMON_MSIX_REG => {
                self.msix_config.store(value as u16, Ordering::SeqCst);
                self.interrupt_status.store(0_u32, Ordering::SeqCst);
            }
            COMMON_STATUS_REG => {
                self.device_status = value;
                if self.device_status == 0 {
                    self.queues_config.iter_mut().for_each(|q| {
                        q.ready = false;
                        q.vector = 0;
                        q.avail_ring = GuestAddress(0);
                        q.desc_table = GuestAddress(0);
                        q.used_ring = GuestAddress(0);
                    });
                    self.msix_config.store(0_u16, Ordering::SeqCst)
                }
            }
            COMMON_Q_SELECT_REG => {
                if value < VIRTIO_QUEUE_MAX {
                    self.queue_select = value as u16;
                }
            }
            COMMON_Q_SIZE_REG => self
                .get_mut_queue_config()
                .map(|config| config.size = value as u16)?,
            COMMON_Q_ENABLE_REG => self
                .get_mut_queue_config()
                .map(|config| config.ready = value == 1)?,
            COMMON_Q_MSIX_REG => self
                .get_mut_queue_config()
                .map(|config| config.vector = value as u16)?,
            COMMON_Q_DESCLO_REG => self.get_mut_queue_config().map(|config| {
                config.desc_table = GuestAddress(config.desc_table.0 | u64::from(value));
            })?,
            COMMON_Q_DESCHI_REG => self.get_mut_queue_config().map(|config| {
                config.desc_table = GuestAddress(config.desc_table.0 | (u64::from(value) << 32));
            })?,
            COMMON_Q_AVAILLO_REG => self.get_mut_queue_config().map(|config| {
                config.avail_ring = GuestAddress(config.avail_ring.0 | u64::from(value));
            })?,
            COMMON_Q_AVAILHI_REG => self.get_mut_queue_config().map(|config| {
                config.avail_ring = GuestAddress(config.avail_ring.0 | (u64::from(value) << 32));
            })?,
            COMMON_Q_USEDLO_REG => self.get_mut_queue_config().map(|config| {
                config.used_ring = GuestAddress(config.used_ring.0 | u64::from(value));
            })?,
            COMMON_Q_USEDHI_REG => self.get_mut_queue_config().map(|config| {
                config.used_ring = GuestAddress(config.used_ring.0 | (u64::from(value) << 32));
            })?,
            _ => {
                return Err(ErrorKind::PciRegister(offset).into());
            }
        };
        Ok(())
    }
fn write_common_config ( & mut self , device : & Arc < Mutex < dyn VirtioDevice > > , offset : u64 , value : u32 , ) -> PciResult < ( ) > { match offset { COMMON_DFSELECT_REG => { self . features_select = value ; } COMMON_GFSELECT_REG => { self . acked_features_select = value ; } COMMON_GF_REG => { 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 ) { error ! ( " " ) ; self . queue_type = QUEUE_TYPE_PACKED_VRING ; } } COMMON_MSIX_REG => { self . msix_config . store ( value as u16 , Ordering :: SeqCst ) ; self . interrupt_status . store ( 0_u32 , Ordering :: SeqCst ) ; } COMMON_STATUS_REG => { self . device_status = value ; if self . device_status == 0 { self . queues_config . iter_mut ( ) . for_each ( | q | { q . ready = false ; q . vector = 0 ; q . avail_ring = GuestAddress ( 0 ) ; q . desc_table = GuestAddress ( 0 ) ; q . used_ring = GuestAddress ( 0 ) ; } ) ; self . msix_config . store ( 0_u16 , Ordering :: SeqCst ) } } COMMON_Q_SELECT_REG => { if value < VIRTIO_QUEUE_MAX { self . queue_select = value as u16 ; } } COMMON_Q_SIZE_REG => self . get_mut_queue_config ( ) . map ( | config | config . size = value as u16 ) ? , COMMON_Q_ENABLE_REG => self . get_mut_queue_config ( ) . map ( | config | config . ready = value == 1 ) ? , COMMON_Q_MSIX_REG => self . get_mut_queue_config ( ) . map ( | config | config . vector = value as u16 ) ? , COMMON_Q_DESCLO_REG => self . get_mut_queue_config ( ) . map ( | config | { config . desc_table = GuestAddress ( config . desc_table . 0 | u64 :: from ( value ) ) ; } ) ? , COMMON_Q_DESCHI_REG => self . get_mut_queue_config ( ) . map ( | config | { config . desc_table = GuestAddress ( config . desc_table . 0 | ( u64 :: from ( value ) << 32 ) ) ; } ) ? , COMMON_Q_AVAILLO_REG => self . get_mut_queue_config ( ) . map ( | config | { config . avail_ring = GuestAddress ( config . avail_ring . 0 | u64 :: from ( value ) ) ; } ) ? , COMMON_Q_AVAILHI_REG => self . get_mut_queue_config ( ) . map ( | config | { config . avail_ring = GuestAddress ( config . avail_ring . 0 | ( u64 :: from ( value ) << 32 ) ) ; } ) ? , COMMON_Q_USEDLO_REG => self . get_mut_queue_config ( ) . map ( | config | { config . used_ring = GuestAddress ( config . used_ring . 0 | u64 :: from ( value ) ) ; } ) ? , COMMON_Q_USEDHI_REG => self . get_mut_queue_config ( ) . map ( | config | { config . used_ring = GuestAddress ( config . used_ring . 0 | ( u64 :: from ( value ) << 32 ) ) ; } ) ? , _ => { return Err ( ErrorKind :: PciRegister ( 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>>
offset
u64
value
u32
&mut self
device
&Arc<Mutex<dyn VirtioDevice>>
offset
u64
value
u32
errors
Returns Error if the offset is out of bound.
Returns Error if the offset is out of bound .