Add internal locking to the Xhci struct.
This commit is contained in:
@@ -10,21 +10,42 @@ use thiserror::Error;
|
||||
pub use crate::pci::PciBar;
|
||||
pub use crate::pci::msi;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
#[repr(u8)]
|
||||
pub enum LegacyInterruptPin {
|
||||
/// INTa#
|
||||
IntA = 1,
|
||||
/// INTb#
|
||||
IntB = 2,
|
||||
/// INTc#
|
||||
IntC = 3,
|
||||
/// INTd#
|
||||
IntD = 4,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub struct PciFunction {
|
||||
/// Number of PCI bus
|
||||
pub bus_num: u8,
|
||||
|
||||
/// Number of PCI device
|
||||
pub dev_num: u8,
|
||||
|
||||
/// Number of PCI function
|
||||
pub func_num: u8,
|
||||
|
||||
/// PCI Base Address Registers
|
||||
pub bars: [PciBar; 6],
|
||||
|
||||
/// BAR sizes
|
||||
pub bar_sizes: [u32; 6],
|
||||
|
||||
/// Legacy IRQ line
|
||||
// TODO: Stop using legacy IRQ lines, and physical pins, but MSI/MSI-X instead.
|
||||
pub legacy_interrupt_line: u8,
|
||||
|
||||
/// Legacy interrupt pin (INTx#), none if INTx# interrupts aren't supported at all.
|
||||
pub legacy_interrupt_pin: Option<LegacyInterruptPin>,
|
||||
|
||||
/// Vendor ID
|
||||
pub venid: u16,
|
||||
/// Device ID
|
||||
|
||||
+22
-1
@@ -75,7 +75,10 @@ impl DriverHandler {
|
||||
None => return PcidClientResponse::Error(PcidServerResponseError::NonexistentFeature(feature)),
|
||||
};
|
||||
unsafe {
|
||||
with_pci_func_raw(&self.state.pci, self.bus_num, self.dev_num, self.func_num, |func| capability.set_enabled(func, offset, true));
|
||||
with_pci_func_raw(&self.state.pci, self.bus_num, self.dev_num, self.func_num, |func| {
|
||||
capability.set_enabled(true);
|
||||
capability.write_message_control(func, offset);
|
||||
});
|
||||
}
|
||||
PcidClientResponse::FeatureEnabled(feature)
|
||||
}
|
||||
@@ -255,6 +258,8 @@ fn handle_parsed_header(state: Arc<State>, config: &Config, bus_num: u8,
|
||||
pci.write(bus_num, dev_num, func_num, 0x3C, data);
|
||||
}
|
||||
|
||||
let interrupt_pin = unsafe { pci.read(bus_num, dev_num, func_num, 0x3B) };
|
||||
|
||||
// Find BAR sizes
|
||||
let mut bars = [PciBar::None; 6];
|
||||
let mut bar_sizes = [0; 6];
|
||||
@@ -308,6 +313,21 @@ fn handle_parsed_header(state: Arc<State>, config: &Config, bus_num: u8,
|
||||
};
|
||||
println!("PCI DEVICE CAPABILITIES for {}: {:?}", args.iter().map(|string| string.as_ref()).nth(0).unwrap_or("[unknown]"), capabilities);
|
||||
|
||||
use driver_interface::LegacyInterruptPin;
|
||||
|
||||
let legacy_interrupt_pin = match interrupt_pin {
|
||||
0 => None,
|
||||
1 => Some(LegacyInterruptPin::IntA),
|
||||
2 => Some(LegacyInterruptPin::IntB),
|
||||
3 => Some(LegacyInterruptPin::IntC),
|
||||
4 => Some(LegacyInterruptPin::IntD),
|
||||
|
||||
other => {
|
||||
println!("pcid: invalid interrupt pin: {}", other);
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let func = driver_interface::PciFunction {
|
||||
bars,
|
||||
bar_sizes,
|
||||
@@ -316,6 +336,7 @@ fn handle_parsed_header(state: Arc<State>, config: &Config, bus_num: u8,
|
||||
func_num,
|
||||
devid: header.device_id(),
|
||||
legacy_interrupt_line: irq,
|
||||
legacy_interrupt_pin,
|
||||
venid: header.vendor_id(),
|
||||
};
|
||||
|
||||
|
||||
+11
-4
@@ -68,11 +68,10 @@ impl MsiCapability {
|
||||
pub fn message_control(&self) -> u16 {
|
||||
(self.message_control_raw() >> 16) as u16
|
||||
}
|
||||
pub unsafe fn set_message_control<W: ConfigWriter>(&mut self, writer: &W, offset: u8, value: u16) {
|
||||
pub fn set_message_control(&mut self, value: u16) {
|
||||
let mut new_message_control = self.message_control_raw();
|
||||
new_message_control &= 0x0000_FFFF;
|
||||
new_message_control |= u32::from(value) << 16;
|
||||
writer.write_u32(offset, new_message_control);
|
||||
|
||||
match self {
|
||||
Self::_32BitAddress { ref mut message_control, .. }
|
||||
@@ -81,6 +80,9 @@ impl MsiCapability {
|
||||
| Self::_64BitAddressWithPvm { ref mut message_control, .. } => *message_control = new_message_control,
|
||||
}
|
||||
}
|
||||
pub unsafe fn write_message_control<W: ConfigWriter>(&mut self, writer: &W, offset: u8) {
|
||||
writer.write_u32(offset, self.message_control_raw());
|
||||
}
|
||||
pub fn is_pvt_capable(&self) -> bool {
|
||||
self.message_control() & Self::MC_PVT_CAPABLE_BIT != 0
|
||||
}
|
||||
@@ -90,10 +92,10 @@ impl MsiCapability {
|
||||
pub fn enabled(&self) -> bool {
|
||||
self.message_control() & Self::MC_MSI_ENABLED_BIT != 0
|
||||
}
|
||||
pub unsafe fn set_enabled<W: ConfigWriter>(&mut self, writer: &W, offset: u8, enabled: bool) {
|
||||
pub fn set_enabled(&mut self, enabled: bool) {
|
||||
let mut new_message_control = self.message_control() & (!Self::MC_MSI_ENABLED_BIT);
|
||||
new_message_control |= u16::from(enabled);
|
||||
self.set_message_control(writer, offset, new_message_control)
|
||||
self.set_message_control(new_message_control);
|
||||
}
|
||||
pub fn multi_message_capable(&self) -> u8 {
|
||||
((self.message_control() & Self::MC_MULTI_MESSAGE_MASK) >> Self::MC_MULTI_MESSAGE_SHIFT) as u8
|
||||
@@ -101,6 +103,11 @@ impl MsiCapability {
|
||||
pub fn multi_message_enabled(&self) -> u8 {
|
||||
((self.message_control() & Self::MC_MULTI_MESSAGE_ENABLE_MASK) >> Self::MC_MULTI_MESSAGE_ENABLE_SHIFT) as u8
|
||||
}
|
||||
pub fn set_multi_message_enabled(&mut self, log_mme: u8) {
|
||||
let mut new_message_control = self.message_control() & (!Self::MC_MULTI_MESSAGE_ENABLE_MASK);
|
||||
new_message_control |= (u16::from(log_mme) << Self::MC_MULTI_MESSAGE_ENABLE_SHIFT);
|
||||
self.set_message_control(new_message_control);
|
||||
}
|
||||
}
|
||||
|
||||
impl MsixCapability {
|
||||
|
||||
Reference in New Issue
Block a user