diff --git a/drivers/audio/ac97d/src/main.rs b/drivers/audio/ac97d/src/main.rs index ccfa03e33e..c006bce282 100644 --- a/drivers/audio/ac97d/src/main.rs +++ b/drivers/audio/ac97d/src/main.rs @@ -149,14 +149,19 @@ fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! { std::process::exit(1); } - if !device.irq() { - continue; - } + let ours = device.irq(); + // The kernel masks the IRQ line on delivery and only re-arms + // it on write-back; ack unconditionally or a foreign interrupt + // on a shared line leaves the line masked forever. if let Err(err) = irq_file.write(&mut irq) { error!("ac97d: failed to acknowledge IRQ: {err}"); std::process::exit(1); } + if !ours { + continue; + } + readiness_based .poll_all_requests(&mut device) .unwrap_or_else(|err| { diff --git a/drivers/audio/sb16d/src/main.rs b/drivers/audio/sb16d/src/main.rs index 66348596c5..dd11c379a6 100644 --- a/drivers/audio/sb16d/src/main.rs +++ b/drivers/audio/sb16d/src/main.rs @@ -79,10 +79,15 @@ fn daemon(daemon: daemon::Daemon) -> ! { let mut irq = [0; 8]; irq_file.read(&mut irq).unwrap(); - if !device.irq() { + let ours = device.irq(); + // The kernel masks the IRQ line on delivery and only re-arms + // it on write-back; ack unconditionally or a foreign interrupt + // on a shared line leaves the line masked forever. + irq_file.write(&mut irq).unwrap(); + + if !ours { continue; } - irq_file.write(&mut irq).unwrap(); readiness_based .poll_all_requests(&mut device) diff --git a/drivers/graphics/ihdgd/src/main.rs b/drivers/graphics/ihdgd/src/main.rs index a8b6cc6038..42fa051c48 100644 --- a/drivers/graphics/ihdgd/src/main.rs +++ b/drivers/graphics/ihdgd/src/main.rs @@ -86,9 +86,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { Source::Irq => { let mut irq = [0; 8]; irq_file.irq_handle().read(&mut irq).unwrap(); - if scheme.adapter_mut().handle_irq() { - irq_file.irq_handle().write(&mut irq).unwrap(); + let ours = scheme.adapter_mut().handle_irq(); + // The kernel masks the IRQ line on delivery and only re-arms + // it on write-back; ack unconditionally or a foreign interrupt + // on a shared line leaves the line masked forever. + irq_file.irq_handle().write(&mut irq).unwrap(); + if ours { scheme.adapter_mut().handle_events(); scheme.tick().unwrap(); } diff --git a/drivers/net/ixgbed/src/main.rs b/drivers/net/ixgbed/src/main.rs index 4a6ce74dcd..f16c7f9077 100644 --- a/drivers/net/ixgbed/src/main.rs +++ b/drivers/net/ixgbed/src/main.rs @@ -73,9 +73,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { Source::Irq => { let mut irq = [0; 8]; irq_file.read(&mut irq).unwrap(); - if scheme.adapter().irq() { - irq_file.write(&mut irq).unwrap(); + let ours = scheme.adapter().irq(); + // The kernel masks the IRQ line on delivery and only re-arms + // it on write-back; ack unconditionally or a foreign interrupt + // on a shared line leaves the line masked forever. + irq_file.write(&mut irq).unwrap(); + if ours { scheme.tick().unwrap(); } } diff --git a/drivers/net/rtl8139d/src/main.rs b/drivers/net/rtl8139d/src/main.rs index d470e814df..c99ae8d8a6 100644 --- a/drivers/net/rtl8139d/src/main.rs +++ b/drivers/net/rtl8139d/src/main.rs @@ -99,10 +99,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { Source::Irq => { let mut irq = [0; 8]; irq_file.irq_handle().read(&mut irq).unwrap(); - //TODO: This may be causing spurious interrupts - if unsafe { scheme.adapter_mut().irq() } { - irq_file.irq_handle().write(&mut irq).unwrap(); + let ours = unsafe { scheme.adapter_mut().irq() }; + // The kernel masks the IRQ line on delivery and only re-arms + // it on write-back; ack unconditionally or a foreign interrupt + // on a shared line leaves the line masked forever. + irq_file.irq_handle().write(&mut irq).unwrap(); + if ours { scheme.tick().unwrap(); } } diff --git a/drivers/net/rtl8168d/src/main.rs b/drivers/net/rtl8168d/src/main.rs index 1d9963a3ad..f9a5982339 100644 --- a/drivers/net/rtl8168d/src/main.rs +++ b/drivers/net/rtl8168d/src/main.rs @@ -99,10 +99,13 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { Source::Irq => { let mut irq = [0; 8]; irq_file.irq_handle().read(&mut irq).unwrap(); - //TODO: This may be causing spurious interrupts - if unsafe { scheme.adapter_mut().irq() } { - irq_file.irq_handle().write(&mut irq).unwrap(); + let ours = unsafe { scheme.adapter_mut().irq() }; + // The kernel masks the IRQ line on delivery and only re-arms + // it on write-back; ack unconditionally or a foreign interrupt + // on a shared line leaves the line masked forever. + irq_file.irq_handle().write(&mut irq).unwrap(); + if ours { scheme.tick().unwrap(); } }