}
static DEVICE_ATTR_WO(new_device);
- static int __i2c_find_user_addr(struct device *dev, void *addrp)
++static int __i2c_find_user_addr(struct device *dev, const void *addrp)
+{
+ struct i2c_client *client = i2c_verify_client(dev);
+ unsigned short addr = *(unsigned short *)addrp;
+
+ return client && client->flags & I2C_CLIENT_USER &&
+ i2c_encode_flags_to_addr(client) == addr;
+}
+
/*
* And of course let the users delete the devices they instantiated, if
* they got it wrong. This interface can only be used to delete devices
if (err)
return err;
- return le16_to_cpu(reply);
+ return reply;
+}
+
- static int omnia_match_mcu_client(struct device *dev, void *data)
++static int omnia_match_mcu_client(struct device *dev, const void *data)
+{
+ struct i2c_client *client;
+
+ client = i2c_verify_client(dev);
+ if (!client)
+ return 0;
+
+ return client->addr == OMNIA_MCU_I2C_ADDR;
+}
+
+static int omnia_find_mcu_and_get_features(struct device *dev)
+{
+ struct device *mcu_dev;
+ int ret;
+
+ mcu_dev = device_find_child(dev->parent, NULL, omnia_match_mcu_client);
+ if (!mcu_dev)
+ return -ENODEV;
+
+ ret = omnia_mcu_get_features(i2c_verify_client(mcu_dev));
+
+ put_device(mcu_dev);
+
+ return ret;
}
static int omnia_leds_probe(struct i2c_client *client)
#![no_std]
#![feature(arbitrary_self_types)]
-#![feature(coerce_unsized)]
-#![feature(dispatch_from_dyn)]
+#![cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, feature(derive_coerce_pointee))]
+#![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(coerce_unsized))]
+#![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(dispatch_from_dyn))]
+#![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(unsize))]
#![feature(inline_const)]
#![feature(lint_reasons)]
-#![feature(unsize)]
+ // Stable in Rust 1.83
+ #![feature(const_maybe_uninit_as_mut_ptr)]
+ #![feature(const_mut_refs)]
+ #![feature(const_ptr_write)]
+ #![feature(const_refs_to_cell)]
// Ensure conditional compilation based on the kernel configuration works;
// otherwise we may silently break things like initcall handling.
pub mod alloc;
#[cfg(CONFIG_BLOCK)]
pub mod block;
-mod build_assert;
+#[doc(hidden)]
+pub mod build_assert;
pub mod cred;
pub mod device;
+ pub mod device_id;
+ pub mod devres;
+ pub mod driver;
pub mod error;
#[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)]
pub mod firmware;
use crate::{
bindings,
+ device::Device,
error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR},
+ ffi::{c_int, c_long, c_uint, c_ulong},
+ fs::File,
prelude::*,
+ seq_file::SeqFile,
str::CStr,
types::{ForeignOwnable, Opaque},
};
_cmd: u32,
_arg: usize,
) -> Result<isize> {
- kernel::build_error!(VTABLE_DEFAULT_ERROR)
+ build_error!(VTABLE_DEFAULT_ERROR)
}
- kernel::build_error!(VTABLE_DEFAULT_ERROR)
+
+ /// Show info for this fd.
+ fn show_fdinfo(
+ _device: <Self::Ptr as ForeignOwnable>::Borrowed<'_>,
+ _m: &SeqFile,
+ _file: &File,
+ ) {
++ build_error!(VTABLE_DEFAULT_ERROR)
+ }
}
const fn create_vtable<T: MiscDevice>() -> &'static bindings::file_operations {
Err(err) => return err.to_errno(),
};
- // SAFETY: The open call of a file owns the private data.
- unsafe { (*file).private_data = ptr.into_foreign() };
+ // This overwrites the private data with the value specified by the user, changing the type of
+ // this file's private data. All future accesses to the private data is performed by other
+ // fops_* methods in this file, which all correctly cast the private data to the new type.
+ //
+ // SAFETY: The open call of a file can access the private data.
- unsafe { (*raw_file).private_data = ptr.into_foreign().cast_mut() };
++ unsafe { (*raw_file).private_data = ptr.into_foreign() };
0
}
// SAFETY: Ioctl calls can borrow the private data of the file.
let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) };
- match T::ioctl(device, cmd, arg) {
+ // SAFETY:
+ // * The file is valid for the duration of this call.
+ // * There is no active fdget_pos region on the file on this thread.
+ let file = unsafe { File::from_raw_file(file) };
+
- match T::ioctl(device, file, cmd, arg as usize) {
++ match T::ioctl(device, file, cmd, arg) {
Ok(ret) => ret as c_long,
Err(err) => err.to_errno() as c_long,
}
// SAFETY: Ioctl calls can borrow the private data of the file.
let device = unsafe { <T::Ptr as ForeignOwnable>::borrow(private) };
- match T::compat_ioctl(device, cmd, arg) {
+ // SAFETY:
+ // * The file is valid for the duration of this call.
+ // * There is no active fdget_pos region on the file on this thread.
+ let file = unsafe { File::from_raw_file(file) };
+
- match T::compat_ioctl(device, file, cmd, arg as usize) {
++ match T::compat_ioctl(device, file, cmd, arg) {
Ok(ret) => ret as c_long,
Err(err) => err.to_errno() as c_long,
}