1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use super::{PciAccessor, PciHeader};
pub struct Capability<'a, const V: usize> {
base: u8,
pci_header: &'a PciHeader<V>,
}
impl<'a, const V: usize> Capability<'a, V> {
#[inline]
pub fn vendor(&self) -> u8 {
self.pci_header.accessor(self.base).read_u8()
}
#[inline]
pub fn offset(&self, offset: u8) -> PciAccessor {
PciAccessor::new(
self.pci_header.pci_device.bus,
self.pci_header.pci_device.device,
self.pci_header.function,
self.base + offset,
)
}
}
#[doc(hidden)]
pub struct CapabilityIterator<'a, const V: usize> {
pub(crate) next: u8,
pub(crate) pci_header: &'a PciHeader<V>,
}
impl<'a, const V: usize> core::iter::Iterator for CapabilityIterator<'a, V> {
type Item = Capability<'a, V>;
fn next(&mut self) -> Option<Self::Item> {
if self.next != 0 {
let cur = self.next;
self.next = self.pci_header.accessor(cur + 1).read_u8();
Some(Capability {
base: cur,
pci_header: self.pci_header,
})
} else {
None
}
}
}
bitflags::bitflags! {
pub struct MsixMessageControl: u16 {
const ENABLED = 1 << 15;
const FUNCTION_MASK = 1 << 14;
}
}
pub struct MessageControl {
accessor: PciAccessor,
}
impl MessageControl {
#[inline]
pub fn set(&self, ctrl: MsixMessageControl) {
let cap = unsafe {
MsixMessageControl::from_bits_unchecked(self.accessor.read_u16())
& !(MsixMessageControl::ENABLED | MsixMessageControl::FUNCTION_MASK)
| ctrl
};
self.accessor.write_u16(cap.bits())
}
#[inline]
pub fn get(&self) -> MsixMessageControl {
MsixMessageControl::from_bits_truncate(self.accessor.read_u16())
}
}