mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-06 02:25:23 +00:00
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:
parent
e1196921a7
commit
ccb9e902d0
2 changed files with 21 additions and 25 deletions
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue