pub struct DeviceInterruptManager<T: InterruptManager> { /* private fields */ }
Expand description

A struct to manage interrupts and interrupt modes for a device.

The interrupt manager may support multiple working mode. For example, an interrupt manager for a PCI device may work in legacy mode, PCI MSI mode or PCI MSIx mode. Under certain conditions, the interrupt manager may switch between interrupt working modes. To simplify implementation, switching working mode is only supported at configuration stage and will be disabled at runtime stage. The DeviceInterruptManager::enable() switches the interrupt manager from configuration stage into runtime stage. And DeviceInterruptManager::reset() switches from runtime stage back to initial configuration stage.

Implementations§

source§

impl<T: InterruptManager> DeviceInterruptManager<T>

source

pub fn new(intr_mgr: T, resources: &DeviceResources) -> Result<Self>

Create an interrupt manager for a device.

Arguments
  • intr_mgr: underline interrupt manager to allocate/free interrupt groups.
  • resources: resources assigned to the device, including assigned interrupt resources.
source

pub fn set_device_id(&mut self, device_id: Option<u32>)

Set device_id for MSI routing

source

pub fn is_enabled(&self) -> bool

Check whether the interrupt manager has been activated.

source

pub fn enable(&mut self) -> Result<()>

Switch the interrupt manager from configuration stage into runtime stage.

The working mode could only be changed at configuration stage, and all requests to change working mode at runtime stage will be rejected.

If the interrupt manager is still in DISABLED mode when DeviceInterruptManager::enable() is called, it will be put into LEGACY mode if LEGACY mode is supported.

source

pub fn reset(&mut self) -> Result<()>

Switch the interrupt manager from runtime stage back into initial configuration stage.

Currently we doesn’t track the usage of interrupt group object given out by get_group(), so the the caller needs to take the responsibility to release all interrupt group object reference before calling DeviceInterruptManager::reset().

source

pub fn get_working_mode(&mut self) -> DeviceInterruptMode

Get the current interrupt working mode.

source

pub fn set_working_mode(&mut self, mode: DeviceInterruptMode) -> Result<()>

Switch interrupt working mode.

Currently switching working mode is only supported during device configuration stage and will always return failure if called during device runtime stage. The device switches from configuration stage to runtime stage by invoking DeviceInterruptManager::enable(). With this constraint, the device drivers may call DeviceInterruptManager::get_group() to get the underline active interrupt group object, and directly calls the interrupt group object’s methods to trigger/acknowledge interrupts.

This is a key design decision for optimizing performance. Though the DeviceInterruptManager object itself is not multi-thread safe and must be protected from concurrent access by the caller, the interrupt source group object is multi-thread safe and could be called concurrently to trigger/acknowledge interrupts. This design may help to improve performance for MSI interrupts.

Arguments
  • mode: target working mode.
source

pub fn get_group(&self) -> Option<Arc<Box<dyn InterruptSourceGroup>>>

Get the underline interrupt source group object, so the device driver could concurrently trigger/acknowledge interrupts by using the returned group object.

source

pub fn get_group_unchecked(&self) -> Arc<Box<dyn InterruptSourceGroup>>

Get the underline interrupt source group object, ignore the mode

source

pub fn update(&mut self, index: u32) -> Result<()>

Reconfigure a specific interrupt in current working mode at configuration or runtime stage.

It’s mainly used to reconfigure Generic MSI/PCI MSI/PCI MSIx interrupts. Actually legacy interrupts don’t support reconfiguration yet.

source§

impl<T: InterruptManager> DeviceInterruptManager<T>

source

pub fn set_msi_high_address(&mut self, index: u32, data: u32) -> Result<()>

Set the high address for a MSI message.

source

pub fn set_msi_low_address(&mut self, index: u32, data: u32) -> Result<()>

Set the low address for a MSI message.

source

pub fn set_msi_data(&mut self, index: u32, data: u32) -> Result<()>

Set the data for a MSI message.

source

pub fn set_msi_mask(&mut self, index: u32, mask: bool) -> Result<()>

Set msi irq MASK bit

source

pub fn get_msi_mask(&self, index: u32) -> Result<bool>

Get msi irq MASK state

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.