drm: Use new VERSION, GET_CAP and SET_CLIENT_CAP driver commands

This commit is contained in:
bjorn3
2025-12-14 20:47:41 +01:00
parent 395c686f8d
commit d70e2dc610
2 changed files with 88 additions and 11 deletions
+58 -11
View File
@@ -65,6 +65,41 @@ impl Dev {
)
}
fn version(&self) -> Result<ipc::Version> {
let mut cmd = ipc::Version {
version_major: 0,
version_minor: 0,
version_patchlevel: 0,
name_len: 0,
name: [0; 16],
desc_len: 0,
desc: [0; 16],
};
unsafe {
self.call(&mut cmd, ipc::VERSION)?;
}
Ok(cmd)
}
fn get_cap(&self, capability: u64) -> Result<u64> {
let mut cmd = ipc::GetCap {
capability,
value: 0,
};
unsafe {
self.call(&mut cmd, ipc::GET_CAP)?;
}
Ok(cmd.value)
}
fn set_client_cap(&self, capability: u64, value: u64) -> Result<()> {
let mut cmd = ipc::SetClientCap { capability, value };
unsafe {
self.call(&mut cmd, ipc::SET_CLIENT_CAP)?;
}
Ok(())
}
fn display_count(&self) -> Result<usize> {
let mut cmd = ipc::DisplayCount { count: 0 };
unsafe {
@@ -104,12 +139,21 @@ struct drm_version {
unsafe fn version(dev: Dev, mut buf: IoctlBuffer) -> Result<c_int> {
let mut vers = buf.read::<drm_version>()?;
vers.version_major = 1;
vers.version_minor = 0;
vers.version_patchlevel = 0;
vers.name_len = copy_array("redox".as_bytes(), vers.name as *mut u8, vers.name_len);
let version = dev.version()?;
vers.version_major = version.version_major as i32;
vers.version_minor = version.version_minor as i32;
vers.version_patchlevel = version.version_patchlevel as i32;
vers.name_len = copy_array(
&version.name[..version.name_len],
vers.name as *mut u8,
vers.name_len,
);
vers.date_len = copy_array("0".as_bytes(), vers.date as *mut u8, vers.date_len);
vers.desc_len = copy_array("Redox OS".as_bytes(), vers.desc as *mut u8, vers.desc_len);
vers.desc_len = copy_array(
&version.desc[..version.desc_len],
vers.desc as *mut u8,
vers.desc_len,
);
buf.write(vers)?;
Ok(0)
}
@@ -121,9 +165,11 @@ pub struct drm_get_cap {
pub value: u64,
}
unsafe fn get_cap(dev: Dev, buf: IoctlBuffer) -> Result<c_int> {
//TODO: get capabilities
Err(Errno(EINVAL))
unsafe fn get_cap(dev: Dev, mut buf: IoctlBuffer) -> Result<c_int> {
let mut cap = buf.read::<drm_get_cap>()?;
cap.value = dev.get_cap(cap.capability)?;
buf.write(cap)?;
Ok(0)
}
#[repr(C)]
@@ -133,9 +179,10 @@ pub struct drm_set_client_cap {
pub value: u64,
}
unsafe fn set_client_cap(dev: Dev, buf: IoctlBuffer) -> Result<c_int> {
//TODO: set capabilities
Err(Errno(EINVAL))
unsafe fn set_client_cap(dev: Dev, mut buf: IoctlBuffer) -> Result<c_int> {
let mut cap = buf.read::<drm_set_client_cap>()?;
dev.set_client_cap(cap.capability, cap.value)?;
Ok(0)
}
#[repr(C)]
@@ -8,6 +8,36 @@ pub struct Damage {
pub height: u32,
}
pub const VERSION: u64 = 0;
#[repr(C, packed)]
pub struct Version {
pub version_major: u32,
pub version_minor: u32,
pub version_patchlevel: u32,
// FIXME allow variable sized fields
pub name_len: usize,
pub name: [u8; 16],
pub desc_len: usize,
pub desc: [u8; 16],
}
pub const GET_CAP: u64 = 0x0C;
pub const CAP_DUMB_BUFFER: u64 = 0x1;
#[repr(C, packed)]
pub struct GetCap {
pub capability: u64,
pub value: u64,
}
pub const SET_CLIENT_CAP: u64 = 0x0D;
pub const CLIENT_CAP_CURSOR_PLANE_HOTSPOT: u64 = 6;
#[repr(C, packed)]
pub struct SetClientCap {
pub capability: u64,
pub value: u64,
}
// FIXME replace these with proper drm interfaces
pub const DISPLAY_COUNT: u64 = 1;
#[repr(C, packed)]
pub struct DisplayCount {