pub struct DeviceRegistry {
pub objects: KObjectStore,
/* private fields */
}Expand description
The registry for devices.
Devices are specified in file systems with major and minor device numbers, together referred to
as a DeviceId. When userspace opens one of those files, we look up the DeviceId in the
device registry to instantiate a file for that device.
The DeviceRegistry also manages the KObjectStore, which provides metadata for devices via
the sysfs file system, typically mounted at /sys.
Fields§
§objects: KObjectStoreThe KObjects for registered devices.
Implementations§
Source§impl DeviceRegistry
impl DeviceRegistry
Sourcepub fn add_device(
&self,
kernel: &Kernel,
name: &FsStr,
metadata: DeviceMetadata,
class: Class,
dev_ops: impl DeviceOps,
) -> Device
pub fn add_device( &self, kernel: &Kernel, name: &FsStr, metadata: DeviceMetadata, class: Class, dev_ops: impl DeviceOps, ) -> Device
Adds a numbered minor device to the DeviceRegistry.
If you are adding a device that exists in other systems, please check the metadata for that device in /sys and make sure you use the same properties when calling this function because these values are visible to userspace.
For example, a typical device will appear in sysfs at a path like:
/sys/devices/{bus}/{class}/{name}
Many common classes have convenient accessors on DeviceRegistry::objects.
To fill out the DeviceMetadata, look at the uevent file:
/sys/devices/{bus}/{class}/{name}/uevent
which has the following format:
MAJOR={major-number}
MINOR={minor-number}
DEVNAME={devname}
DEVMODE={devmode}Often, the {name} and the {devname} are the same, but if they are not the same,
please take care to use the correct string in the correct field.
If the {major-number} is 10 and the {minor-number} is in the range 52..128, please use
Self::add_misc_device instead because these device numbers are dynamically allocated.
If the {major-number} is in the range 234..255, please use Self::add_dyn_device
instead because these devices are also dynamically allocated.
If you are unsure which device numbers to use, consult devices.txt:
https://www.kernel.org/doc/Documentation/admin-guide/devices.txt
If you are still unsure, please ask an experienced Starnix contributor rather than make up a device number.
Uses build_device_directory to populate the standard sysfs directory for the device.
To populate custom sysfs attributes or specify a parent device, use
Self::add_device_with_dir.
Finally, the dev_ops parameter is where you provide the callback for instantiating
your device. The returned Device can be removed with Self::remove_device.
Sourcepub fn add_device_with_dir(
&self,
kernel: &Kernel,
name: &FsStr,
metadata: DeviceMetadata,
parent: Option<Device>,
subsystem: impl Into<DeviceSubsystem>,
build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator),
dev_ops: impl DeviceOps,
) -> Device
pub fn add_device_with_dir( &self, kernel: &Kernel, name: &FsStr, metadata: DeviceMetadata, parent: Option<Device>, subsystem: impl Into<DeviceSubsystem>, build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator), dev_ops: impl DeviceOps, ) -> Device
Adds a numbered minor device to the DeviceRegistry, with a sysfs directory populated
by build_directory beneath parent.
If parent is itself a class device then the device directory is created directly within
the parent’s directory, otherwise it is created within a <class> directory under
parent. If parent is None then /sys/devices/virtual is used.
Dispatches UEventAction::Add after creating the sysfs and devtmpfs nodes. The
returned Device can be removed with Self::remove_device.
See Self::add_device for an explanation of the other parameters.
Sourcepub fn add_misc_device(
&self,
kernel: &Kernel,
name: &FsStr,
dev_ops: impl DeviceOps,
) -> Result<Device, Errno>
pub fn add_misc_device( &self, kernel: &Kernel, name: &FsStr, dev_ops: impl DeviceOps, ) -> Result<Device, Errno>
Allocates a dynamic device number in MISC_MAJOR and adds the device to the
DeviceRegistry.
MISC devices (major number 10) with minor numbers in the range 52..128 are dynamically assigned. Rather than hardcoding registrations with these device numbers, use this function instead to add the device.
See Self::add_device for an explanation of the parameters.
Sourcepub fn add_dyn_device(
&self,
kernel: &Kernel,
name: &FsStr,
class: Class,
dev_ops: impl DeviceOps,
) -> Result<Device, Errno>
pub fn add_dyn_device( &self, kernel: &Kernel, name: &FsStr, class: Class, dev_ops: impl DeviceOps, ) -> Result<Device, Errno>
Allocates a dynamic character device number (major 234..255) and adds the device to the
DeviceRegistry.
Major device numbers 234..255 are dynamically assigned. Rather than hardcoding registrations with these device numbers, use this function instead to add the device.
Note: We do not currently allocate from this entire range because we have mistakenly hardcoded some device registrations from the dynamic range. Once we fix these registrations to be dynamic, we should expand to using the full dynamic range.
See Self::add_device for an explanation of the parameters.
Sourcepub fn add_dyn_device_with_dir(
&self,
kernel: &Kernel,
name: &FsStr,
class: Class,
build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator),
dev_ops: impl DeviceOps,
) -> Result<Device, Errno>
pub fn add_dyn_device_with_dir( &self, kernel: &Kernel, name: &FsStr, class: Class, build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator), dev_ops: impl DeviceOps, ) -> Result<Device, Errno>
Allocates a dynamic character device number (major 234..255) and adds the device to the
DeviceRegistry, with a sysfs directory populated by build_directory.
See Self::add_device for an explanation of the parameters.
Sourcepub fn add_dyn_device_with_devname(
&self,
kernel: &Kernel,
name: &FsStr,
devname: &FsStr,
class: Class,
build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator),
dev_ops: impl DeviceOps,
) -> Result<Device, Errno>
pub fn add_dyn_device_with_devname( &self, kernel: &Kernel, name: &FsStr, devname: &FsStr, class: Class, build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator), dev_ops: impl DeviceOps, ) -> Result<Device, Errno>
Allocates a dynamic character device number (major 234..255) and adds the device to the
DeviceRegistry with a separate sysfs name and /dev devname, and a sysfs
directory populated by build_directory.
See Self::add_dyn_device for an explanation of dynamic devices and parameters.
Sourcepub fn register_silent_dyn_device(
&self,
name: &FsStr,
dev_ops: impl DeviceOps,
) -> Result<DeviceMetadata, Errno>
pub fn register_silent_dyn_device( &self, name: &FsStr, dev_ops: impl DeviceOps, ) -> Result<DeviceMetadata, Errno>
Registers a “silent” dynamic device with major numbers 234..255.
Only use for devices that should not be added to the KObjectStore or appear in sysfs.
This is a rare occurrence.
See Self::add_dyn_device for an explanation of dynamic devices and parameters.
Sourcepub fn add_major_device(
&self,
kernel: &Kernel,
name: &FsStr,
metadata: DeviceMetadata,
parent: Option<Device>,
subsystem: impl Into<DeviceSubsystem>,
build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator),
) -> Device
pub fn add_major_device( &self, kernel: &Kernel, name: &FsStr, metadata: DeviceMetadata, parent: Option<Device>, subsystem: impl Into<DeviceSubsystem>, build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator), ) -> Device
Adds a numbered device whose major number was previously registered via
Self::register_major, with a sysfs directory populated by build_directory.
If you want to add a single minor device with its own DeviceOps, use
Self::add_device or Self::add_device_with_dir instead.
The returned Device can be removed with Self::remove_device.
See Self::add_device_with_dir for an explanation of the parameters.
Sourcepub fn add_net_device(&self, name: &FsStr) -> Device
pub fn add_net_device(&self, name: &FsStr) -> Device
Adds a network device to the device registry and dispatches UEventAction::Add.
Network devices do not have a /dev node or device number. Instead, in addition to
DEVPATH and SUBSYSTEM=net, their uevent files have the following properties:
INTERFACE={name}
IFINDEX={index}TODO(https://fxbug.dev/297438880): Populate INTERFACE and IFINDEX in the uevent file
and uevent netlink messages. Currently, we only register net devices by name with the
standard DEVPATH and SUBSYSTEM=net properties, and stub the address attribute so that
reads by userspace are tracked.
The returned Device can be removed with Self::remove_device.
Sourcepub fn add_subsystemless_device(
&self,
name: &FsStr,
parent: Option<Device>,
build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator),
) -> Device
pub fn add_subsystemless_device( &self, name: &FsStr, parent: Option<Device>, build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator), ) -> Device
Directly adds a device without a bus or class subsystem to the KObjectStore, populated
by build_directory, and dispatches UEventAction::Add.
Such devices typically act as structural parents for other devices, e.g. the root of a
subsystem’s devices (/sys/devices/system/cpu). If parent is Some, the device
directory is created under parent; otherwise it is created directly under
/sys/devices/<name>.
The returned Device can be removed with Self::remove_device.
Sourcepub fn add_bus_device(
&self,
name: &FsStr,
parent: Option<Device>,
bus: Bus,
build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator),
) -> Device
pub fn add_bus_device( &self, name: &FsStr, parent: Option<Device>, bus: Bus, build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator), ) -> Device
Directly adds a bus device to the KObjectStore, populated by build_directory, and
dispatches UEventAction::Add.
If parent is Some, the device directory is created under parent; otherwise it is
created directly under /sys/devices/<name>. A symlink is also created under
/sys/bus/<bus.name>/devices/<name>.
The returned Device can be removed with Self::remove_device.
Sourcepub fn add_numberless_device(
&self,
name: &FsStr,
parent: Option<Device>,
class: Class,
build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator),
) -> Device
pub fn add_numberless_device( &self, name: &FsStr, parent: Option<Device>, class: Class, build_directory: impl FnOnce(&Device, &SimpleDirectoryMutator), ) -> Device
Directly adds a class device without a device number to the KObjectStore, populated by
build_directory, and dispatches UEventAction::Add.
This function should be used by class devices that are exposed via sysfs or netlink and
do not have a /dev device node (and therefore have no major or minor device number).
If parent is Some and is itself a class device, the device directory is created under
<parent>/<name>; otherwise it is created under <parent>/<class.name>/<name> (defaulting
parent to /sys/devices/virtual). A symlink is also created under
/sys/class/<class.name>/<name>.
The returned Device can be removed with Self::remove_device.
Sourcepub fn remove_device(&self, current_task: &CurrentTask, device: Device)
pub fn remove_device(&self, current_task: &CurrentTask, device: Device)
Unregisters device from devtmpfs, sysfs, and the minor device table, recycling any
dynamically allocated DeviceId before dispatching UEventAction::Remove.
Any child devices parented under device must be removed before device itself so
removal uevents are dispatched in child-before-parent order and intermediate class
directories are cleaned up.
Sourcepub fn list_major_devices(&self, mode: DeviceMode) -> Vec<(u32, FsString)>
pub fn list_major_devices(&self, mode: DeviceMode) -> Vec<(u32, FsString)>
Returns a list of the registered major device numbers for the given DeviceMode and their
names.
Sourcepub fn list_minor_devices(
&self,
mode: DeviceMode,
range: Range<DeviceId>,
) -> Vec<(DeviceId, FsString)>
pub fn list_minor_devices( &self, mode: DeviceMode, range: Range<DeviceId>, ) -> Vec<(DeviceId, FsString)>
Returns a list of the registered minor devices for the given DeviceMode and their names.
Sourcepub fn register_major<'a>(
&self,
name: FsString,
mode: DeviceMode,
major: u32,
dev_ops: impl DeviceOps,
) -> Result<(), Errno>
pub fn register_major<'a>( &self, name: FsString, mode: DeviceMode, major: u32, dev_ops: impl DeviceOps, ) -> Result<(), Errno>
Register an entire major device number.
If you register an entire major device, use Self::add_major_device and
Self::remove_device to manage the sysfs and devtmpfs entries for each minor device
rather than registering individual minor devices.
Sourcepub fn next_anonymous_dev_id<'a>(&self) -> DeviceId
pub fn next_anonymous_dev_id<'a>(&self) -> DeviceId
Allocate an anonymous device identifier.
Sourcepub fn register_listener<'a>(
&self,
listener: impl DeviceListener + 'static,
) -> DeviceListenerKey
pub fn register_listener<'a>( &self, listener: impl DeviceListener + 'static, ) -> DeviceListenerKey
Registers a listener for device uevents and returns its DeviceListenerKey.
Sourcepub fn unregister_listener<'a>(&self, key: &DeviceListenerKey)
pub fn unregister_listener<'a>(&self, key: &DeviceListenerKey)
Unregisters a listener previously registered via Self::register_listener.
Sourcepub fn dispatch_uevent<'a>(&self, action: UEventAction, device: Device)
pub fn dispatch_uevent<'a>(&self, action: UEventAction, device: Device)
Dispatches a uevent with the next monotonic sequence number for device to all registered
listeners.
Sourcepub fn open_device(
&self,
current_task: &CurrentTask,
node: &NamespaceNode,
flags: OpenFlags,
devt: DeviceId,
mode: DeviceMode,
) -> Result<Box<dyn FileOps>, Errno>
pub fn open_device( &self, current_task: &CurrentTask, node: &NamespaceNode, flags: OpenFlags, devt: DeviceId, mode: DeviceMode, ) -> Result<Box<dyn FileOps>, Errno>
Instantiate a file for the specified device.
The device will be looked up in the device registry by DeviceMode and DeviceId.
pub fn get_device( &self, devt: DeviceId, mode: DeviceMode, ) -> Result<DeviceHandle, Errno>
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for DeviceRegistry
impl !RefUnwindSafe for DeviceRegistry
impl !UnwindSafe for DeviceRegistry
impl Send for DeviceRegistry
impl Sync for DeviceRegistry
impl Unpin for DeviceRegistry
impl UnsafeUnpin for DeviceRegistry
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T, D> Encode<Ambiguous1, D> for Twhere
D: ResourceDialect,
impl<T, D> Encode<Ambiguous1, D> for Twhere
D: ResourceDialect,
Source§impl<T, D> Encode<Ambiguous2, D> for Twhere
D: ResourceDialect,
impl<T, D> Encode<Ambiguous2, D> for Twhere
D: ResourceDialect,
§impl<F, N> FidlIntoNative<Box<N>> for Fwhere
F: FidlIntoNative<N>,
impl<F, N> FidlIntoNative<Box<N>> for Fwhere
F: FidlIntoNative<N>,
fn fidl_into_native(self) -> Box<N>
§impl<T> InstanceFromServiceTransport<T> for T
impl<T> InstanceFromServiceTransport<T> for T
§fn from_service_transport(handle: T) -> T
fn from_service_transport(handle: T) -> T
T to [Self]Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more