devices: ac97: convert to using IrqLevelEvent

This converts AC97 code to use IrqLevelEvent.

BUG=None
TEST=./tools/presubmit

Change-Id: If388b724db808891a5bcb5ad040a7dfc4a4dff9b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3548060
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Dmitry Torokhov <dtor@chromium.org>
This commit is contained in:
Dmitry Torokhov 2022-03-19 15:37:24 -07:00 committed by Chromeos LUCI
parent e1196921a7
commit ccb9e902d0
2 changed files with 21 additions and 25 deletions

View file

@ -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<PciAddress>,
// 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<Event>,
irq_resample_evt: Option<Event>,
irq_evt: Option<IrqLevelEvent>,
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<u32>,
) -> 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)
}

View file

@ -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<Event>,
irq_evt: Option<IrqLevelEvent>,
}
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;