diff --git a/devices/src/pci/ac97.rs b/devices/src/pci/ac97.rs index ed53f6ad40..40dd0c3d83 100644 --- a/devices/src/pci/ac97.rs +++ b/devices/src/pci/ac97.rs @@ -28,6 +28,7 @@ use crate::pci::{PciAddress, PciDeviceError, PciInterruptPin}; use crate::virtio::snd::vios_backend::Error as VioSError; #[cfg(any(target_os = "linux", target_os = "android"))] use crate::virtio::snd::vios_backend::VioSShmStreamSource; +use crate::IrqLevelEvent; // Use 82801AA because it's what qemu does. const PCI_DEVICE_ID_INTEL_82801AA_5: u16 = 0x2415; @@ -114,8 +115,7 @@ pub struct Ac97Dev { pci_address: Option, // The irq events are temporarily saved here. They need to be passed to the device after the // jail forks. This happens when the bus is first written. - irq_evt: Option, - irq_resample_evt: Option, + irq_evt: Option, bus_master: Ac97BusMaster, mixer: Ac97Mixer, backend: Ac97Backend, @@ -145,7 +145,6 @@ impl Ac97Dev { config_regs, pci_address: None, irq_evt: None, - irq_resample_evt: None, bus_master: Ac97BusMaster::new(mem, audio_server), mixer: Ac97Mixer::new(), backend, @@ -308,8 +307,10 @@ impl PciDevice for Ac97Dev { irq_resample_evt: &Event, irq_num: Option, ) -> Option<(u32, PciInterruptPin)> { - self.irq_evt = Some(irq_evt.try_clone().ok()?); - self.irq_resample_evt = Some(irq_resample_evt.try_clone().ok()?); + self.irq_evt = Some(IrqLevelEvent::from_event_pair( + irq_evt.try_clone().ok()?, + irq_resample_evt.try_clone().ok()?, + )); let gsi = irq_num?; let pin = self.pci_address.map_or( PciInterruptPin::IntA, @@ -404,10 +405,8 @@ impl PciDevice for Ac97Dev { rds.append(&mut server_fds); } if let Some(irq_evt) = &self.irq_evt { - rds.push(irq_evt.as_raw_descriptor()); - } - if let Some(irq_resample_evt) = &self.irq_resample_evt { - rds.push(irq_resample_evt.as_raw_descriptor()); + rds.push(irq_evt.get_trigger().as_raw_descriptor()); + rds.push(irq_evt.get_resample().as_raw_descriptor()); } rds } @@ -431,10 +430,8 @@ impl PciDevice for Ac97Dev { a if a >= bar0 && a < bar0 + MIXER_REGS_SIZE => self.write_mixer(addr - bar0, data), a if a >= bar1 && a < bar1 + MASTER_REGS_SIZE => { // Check if the irq needs to be passed to the device. - if let (Some(irq_evt), Some(irq_resample_evt)) = - (self.irq_evt.take(), self.irq_resample_evt.take()) - { - self.bus_master.set_irq_event(irq_evt, irq_resample_evt); + if let Some(irq_evt) = self.irq_evt.take() { + self.bus_master.set_irq_event(irq_evt); } self.write_bus_master(addr - bar1, data) } diff --git a/devices/src/pci/ac97_bus_master.rs b/devices/src/pci/ac97_bus_master.rs index dc9b3ef36f..f0350f2460 100644 --- a/devices/src/pci/ac97_bus_master.rs +++ b/devices/src/pci/ac97_bus_master.rs @@ -15,7 +15,7 @@ use audio_streams::{ }; use base::{ self, error, set_rt_prio_limit, set_rt_round_robin, warn, AsRawDescriptor, AsRawDescriptors, - Event, FromRawDescriptor, RawDescriptor, SharedMemoryUnix, + FromRawDescriptor, RawDescriptor, SharedMemoryUnix, }; use remain::sorted; use sync::{Condvar, Mutex}; @@ -24,6 +24,7 @@ use vm_memory::{GuestAddress, GuestMemory}; use crate::pci::ac97_mixer::Ac97Mixer; use crate::pci::ac97_regs::*; +use crate::IrqLevelEvent; const INPUT_SAMPLE_RATE: u32 = 48000; const DEVICE_INPUT_CHANNEL_COUNT: usize = 2; @@ -39,7 +40,7 @@ struct Ac97BusMasterRegs { glob_sta: u32, // IRQ event - driven by the glob_sta register. - irq_evt: Option, + irq_evt: Option, } impl Ac97BusMasterRegs { @@ -248,12 +249,12 @@ impl Ac97BusMaster { } /// Provides the events needed to raise interrupts in the guest. - pub fn set_irq_event(&mut self, irq_evt: Event, irq_resample_evt: Event) { + pub fn set_irq_event(&mut self, irq_evt: IrqLevelEvent) { let thread_regs = self.regs.clone(); - self.regs.lock().irq_evt = Some(irq_evt); + self.regs.lock().irq_evt = Some(irq_evt.try_clone().expect("cloning irq_evt failed")); self.irq_resample_thread = Some(thread::spawn(move || { loop { - if let Err(e) = irq_resample_evt.read() { + if let Err(e) = irq_evt.get_resample().read() { error!( "Failed to read the irq event from the resample thread: {}.", e, @@ -264,11 +265,9 @@ impl Ac97BusMaster { // Scope for the lock on thread_regs. let regs = thread_regs.lock(); if regs.has_irq() { - if let Some(irq_evt) = regs.irq_evt.as_ref() { - if let Err(e) = irq_evt.write(1) { - error!("Failed to set the irq from the resample thread: {}.", e); - break; - } + if let Err(e) = irq_evt.trigger() { + error!("Failed to set the irq from the resample thread: {}.", e); + break; } } } @@ -939,9 +938,9 @@ fn update_sr(regs: &mut Ac97BusMasterRegs, func: Ac97Function, val: u16) { if interrupt_high { regs.glob_sta |= int_mask; - if let Some(irq_evt) = regs.irq_evt.as_ref() { + if let Some(ref irq_evt) = regs.irq_evt { // Ignore write failure, nothing can be done about it from here. - let _ = irq_evt.write(1); + let _ = irq_evt.trigger(); } } else { regs.glob_sta &= !int_mask;