mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
rust: pci: add resource_flags accessor
Add a `Device::resource_flags()` method to the PCI Rust abstraction, wrapping the C-side static inline `pci_resource_flags()`. The flags returned correspond to the `IORESOURCE` bitmask carried by a PCI BAR's `struct resource`. The immediate motivation is BAR layout discovery on NVIDIA GPUs: a 64-bit BAR consumes two consecutive Linux PCI resource slots (the lower 32 bits at index N and the upper 32 bits at index N+1, with the latter having no flags or size of its own). Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Acked-by: Danilo Krummrich <dakr@kernel.org> Link: https://patch.msgid.link/20260908-pci-resource-flags-v1-1-269f29f81de6@nvidia.com Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
This commit is contained in:
parent
9cf1bc8bbc
commit
3f1e12fce1
|
|
@ -19,6 +19,12 @@ __rust_helper resource_size_t rust_helper_pci_resource_len(struct pci_dev *pdev,
|
|||
return pci_resource_len(pdev, bar);
|
||||
}
|
||||
|
||||
__rust_helper unsigned long rust_helper_pci_resource_flags(const struct pci_dev *pdev,
|
||||
int bar)
|
||||
{
|
||||
return pci_resource_flags(pdev, bar);
|
||||
}
|
||||
|
||||
__rust_helper bool rust_helper_dev_is_pci(const struct device *dev)
|
||||
{
|
||||
return dev_is_pci(dev);
|
||||
|
|
|
|||
|
|
@ -226,10 +226,18 @@ impl Flags {
|
|||
/// Resource represents a memory region that must be ioremaped using `ioremap_np`.
|
||||
pub const IORESOURCE_MEM_NONPOSTED: Flags = Flags::new(bindings::IORESOURCE_MEM_NONPOSTED);
|
||||
|
||||
/// Memory region uses a 64-bit address (consumes two consecutive PCI resource slots).
|
||||
pub const IORESOURCE_MEM_64: Flags = Flags::new(bindings::IORESOURCE_MEM_64);
|
||||
|
||||
// Always inline to optimize out error path of `build_assert`.
|
||||
#[inline(always)]
|
||||
const fn new(value: u32) -> Self {
|
||||
build_assert!(value as u64 <= c_ulong::MAX as u64);
|
||||
Flags(value as c_ulong)
|
||||
}
|
||||
|
||||
/// Wrap a raw `c_ulong` value returned by a C API into [`Flags`].
|
||||
pub(crate) const fn from_raw(value: c_ulong) -> Self {
|
||||
Flags(value)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
from_result,
|
||||
to_result, //
|
||||
},
|
||||
io::resource,
|
||||
prelude::*,
|
||||
str::CStr,
|
||||
types::Opaque,
|
||||
|
|
@ -439,6 +440,19 @@ pub fn resource_len(&self, bar: u32) -> Result<bindings::resource_size_t> {
|
|||
Ok(unsafe { bindings::pci_resource_len(self.as_raw(), bar.try_into()?) })
|
||||
}
|
||||
|
||||
/// Returns the resource flags (`IORESOURCE_*`) of the given PCI BAR.
|
||||
pub fn resource_flags(&self, bar: u32) -> Result<resource::Flags> {
|
||||
if !Bar::index_is_valid(bar) {
|
||||
return Err(EINVAL);
|
||||
}
|
||||
|
||||
// SAFETY:
|
||||
// - `bar` is a valid bar number, as guaranteed by the above call to `Bar::index_is_valid`,
|
||||
// - by its type invariant `self.as_raw` is always a valid pointer to a `struct pci_dev`.
|
||||
let raw = unsafe { bindings::pci_resource_flags(self.as_raw(), bar.try_into()?) };
|
||||
Ok(resource::Flags::from_raw(raw))
|
||||
}
|
||||
|
||||
/// Returns the PCI class as a `Class` struct.
|
||||
#[inline]
|
||||
pub fn pci_class(&self) -> Class {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user