Store decoded MSI info instead of full capability in PciFeatureInfo
This commit is contained in:
@@ -199,7 +199,11 @@ impl DriverHandler {
|
||||
.iter()
|
||||
.find_map(|capability| capability.as_msi())
|
||||
{
|
||||
PciFeatureInfo::Msi(*info)
|
||||
PciFeatureInfo::Msi(msi::MsiInfo {
|
||||
log2_multiple_message_capable: info.multi_message_capable(),
|
||||
is_64bit: info.has_64_bit_addr(),
|
||||
has_per_vector_masking: info.is_pvt_capable(),
|
||||
})
|
||||
} else {
|
||||
return PcidClientResponse::Error(
|
||||
PcidServerResponseError::NonexistentFeature(feature),
|
||||
|
||||
@@ -132,7 +132,7 @@ impl PciFeature {
|
||||
}
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum PciFeatureInfo {
|
||||
Msi(msi::MsiCapability),
|
||||
Msi(msi::MsiInfo),
|
||||
MsiX(msi::MsixInfo),
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,13 @@ impl MsiAddrAndData {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct MsiInfo {
|
||||
pub log2_multiple_message_capable: u8,
|
||||
pub is_64bit: bool,
|
||||
pub has_per_vector_masking: bool,
|
||||
}
|
||||
|
||||
impl MsiCapability {
|
||||
pub const MC_PVT_CAPABLE_BIT: u16 = 1 << 8;
|
||||
pub const MC_64_BIT_ADDR_BIT: u16 = 1 << 7;
|
||||
|
||||
@@ -149,7 +149,7 @@ fn get_int_method(
|
||||
Ok((interrupt_method, interrupt_sources))
|
||||
} else if has_msi {
|
||||
// Message signaled interrupts.
|
||||
let capability_struct = match pcid_handle.feature_info(PciFeature::Msi).unwrap() {
|
||||
let msi_info = match pcid_handle.feature_info(PciFeature::Msi).unwrap() {
|
||||
PciFeatureInfo::Msi(msi) => msi,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@@ -171,7 +171,10 @@ fn get_int_method(
|
||||
(0, irq_handle)
|
||||
};
|
||||
|
||||
let interrupt_method = InterruptMethod::Msi(capability_struct);
|
||||
let interrupt_method = InterruptMethod::Msi {
|
||||
msi_info,
|
||||
log2_multiple_message_enabled: 0,
|
||||
};
|
||||
let interrupt_sources =
|
||||
InterruptSources::Msi(std::iter::once((msi_vector_number, irq_handle)).collect());
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ pub mod queues;
|
||||
use self::cq_reactor::NotifReq;
|
||||
pub use self::queues::{NvmeCmd, NvmeCmdQueue, NvmeComp, NvmeCompQueue};
|
||||
|
||||
use pcid_interface::msi::{MsiCapability, MsixInfo, MsixTableEntry};
|
||||
use pcid_interface::msi::{MsiInfo, MsixInfo, MsixTableEntry};
|
||||
use pcid_interface::PcidServerHandle;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
@@ -91,7 +91,7 @@ pub enum InterruptMethod {
|
||||
/// Traditional level-triggered, INTx# interrupt pins.
|
||||
Intx,
|
||||
/// Message signaled interrupts
|
||||
Msi(MsiCapability),
|
||||
Msi { msi_info: MsiInfo, log2_multiple_message_enabled: u8 },
|
||||
/// Extended message signaled interrupts
|
||||
MsiX(MappedMsixRegs),
|
||||
}
|
||||
@@ -104,7 +104,7 @@ impl InterruptMethod {
|
||||
}
|
||||
}
|
||||
fn is_msi(&self) -> bool {
|
||||
if let Self::Msi(_) = self {
|
||||
if let Self::Msi { .. } = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
@@ -289,7 +289,7 @@ impl Nvme {
|
||||
}
|
||||
|
||||
match self.interrupt_method.get_mut().unwrap() {
|
||||
&mut InterruptMethod::Intx | InterruptMethod::Msi(_) => {
|
||||
&mut InterruptMethod::Intx | InterruptMethod::Msi { .. } => {
|
||||
self.regs.get_mut().unwrap().intms.write(0xFFFF_FFFF);
|
||||
self.regs.get_mut().unwrap().intmc.write(0x0000_0001);
|
||||
}
|
||||
@@ -371,13 +371,13 @@ impl Nvme {
|
||||
self.regs.write().unwrap().intmc.write(0x0000_0001);
|
||||
}
|
||||
}
|
||||
&mut InterruptMethod::Msi(ref mut cap) => {
|
||||
&mut InterruptMethod::Msi { msi_info: _, log2_multiple_message_enabled: log2_enabled_messages } => {
|
||||
let mut to_mask = 0x0000_0000;
|
||||
let mut to_clear = 0x0000_0000;
|
||||
|
||||
for (vector, mask) in vectors {
|
||||
assert!(
|
||||
vector < (1 << cap.multi_message_enable()),
|
||||
vector < (1 << log2_enabled_messages),
|
||||
"nvmed: internal error: MSI vector out of range"
|
||||
);
|
||||
let vector = vector as u8;
|
||||
|
||||
Reference in New Issue
Block a user