Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: pci: impl TryFrom<&Device> for &pci::Device

Implement TryFrom<&device::Device> for &Device.

This allows us to get a &pci::Device from a generic &Device in a safe
way; the conversion fails if the device' bus type does not match with
the PCI bus type.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20250321214826.140946-3-dakr@kernel.org
[ Support device context types, use dev_is_pci() helper. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>

+26 -1
+5
rust/helpers/pci.c
··· 16 16 { 17 17 return pci_resource_len(pdev, bar); 18 18 } 19 + 20 + bool rust_helper_dev_is_pci(const struct device *dev) 21 + { 22 + return dev_is_pci(dev); 23 + }
+21 -1
rust/kernel/pci.rs
··· 6 6 7 7 use crate::{ 8 8 alloc::flags::*, 9 - bindings, device, 9 + bindings, container_of, device, 10 10 device_id::RawDeviceId, 11 11 devres::Devres, 12 12 driver, ··· 452 452 453 453 // SAFETY: `dev` points to a valid `struct device`. 454 454 unsafe { device::Device::as_ref(dev) } 455 + } 456 + } 457 + 458 + impl<Ctx: device::DeviceContext> TryFrom<&device::Device<Ctx>> for &Device<Ctx> { 459 + type Error = kernel::error::Error; 460 + 461 + fn try_from(dev: &device::Device<Ctx>) -> Result<Self, Self::Error> { 462 + // SAFETY: By the type invariant of `Device`, `dev.as_raw()` is a valid pointer to a 463 + // `struct device`. 464 + if !unsafe { bindings::dev_is_pci(dev.as_raw()) } { 465 + return Err(EINVAL); 466 + } 467 + 468 + // SAFETY: We've just verified that the bus type of `dev` equals `bindings::pci_bus_type`, 469 + // hence `dev` must be embedded in a valid `struct pci_dev` as guaranteed by the 470 + // corresponding C code. 471 + let pdev = unsafe { container_of!(dev.as_raw(), bindings::pci_dev, dev) }; 472 + 473 + // SAFETY: `pdev` is a valid pointer to a `struct pci_dev`. 474 + Ok(unsafe { &*pdev.cast() }) 455 475 } 456 476 } 457 477