Hi Danilo, On Tue, Oct 22, 2024 at 11:31:48PM +0200, Danilo Krummrich wrote: [...] > +/// The PCI device representation. > +/// > +/// A PCI device is based on an always reference counted `device:Device` instance. Cloning a PCI > +/// device, hence, also increments the base device' reference count. > +#[derive(Clone)] > +pub struct Device(ARef<device::Device>); > + Similar to https://lore.kernel.org/rust-for-linux/ZgG7TlybSa00cuoy@boqun-archlinux/ Could you also avoid wrapping a point to a PCI device? Instead, wrap the object type: #[repr(transparent)] pub struct Device(Opaque<bindings::pci_dev>); impl AlwaysRefCounted for Device { <put_device() and get_device() on ->dev> } Regards, Boqun > +impl Device { > + /// Create a PCI Device instance from an existing `device::Device`. > + /// > + /// # Safety > + /// > + /// `dev` must be an `ARef<device::Device>` whose underlying `bindings::device` is a member of > + /// a `bindings::pci_dev`. > + pub unsafe fn from_dev(dev: ARef<device::Device>) -> Self { > + Self(dev) > + } > + > + fn as_raw(&self) -> *mut bindings::pci_dev { > + // SAFETY: By the type invariant `self.0.as_raw` is a pointer to the `struct device` > + // embedded in `struct pci_dev`. > + unsafe { container_of!(self.0.as_raw(), bindings::pci_dev, dev) as _ } > + } > + > + /// Enable memory resources for this device. > + pub fn enable_device_mem(&self) -> Result { > + // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`. > + let ret = unsafe { bindings::pci_enable_device_mem(self.as_raw()) }; > + if ret != 0 { > + Err(Error::from_errno(ret)) > + } else { > + Ok(()) > + } > + } > + > + /// Enable bus-mastering for this device. > + pub fn set_master(&self) { > + // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`. > + unsafe { bindings::pci_set_master(self.as_raw()) }; > + } > +} > + > +impl AsRef<device::Device> for Device { > + fn as_ref(&self) -> &device::Device { > + &self.0 > + } > +} > -- > 2.46.2 > >