// SPDX-License-Identifier: GPL-2.0

// Copyright (C) 2024 Google LLC.

//! Rust misc device sample.

/// Below is an example userspace C program that exercises this sample's functionality.
///
/// ```c
/// #include <stdio.h>
/// #include <stdlib.h>
/// #include <errno.h>
/// #include <fcntl.h>
/// #include <unistd.h>
/// #include <sys/ioctl.h>
///
/// #define RUST_MISC_DEV_FAIL _IO('|', 0)
/// #define RUST_MISC_DEV_HELLO _IO('|', 0x80)
/// #define RUST_MISC_DEV_GET_VALUE _IOR('|', 0x81, int)
/// #define RUST_MISC_DEV_SET_VALUE _IOW('|', 0x82, int)
///
/// int main() {
///   int value, new_value;
///   int fd, ret;
///
///   // Open the device file
///   printf("Opening /dev/rust-misc-device for reading and writing\n");
///   fd = open("/dev/rust-misc-device", O_RDWR);
///   if (fd < 0) {
///     perror("open");
///     return errno;
///   }
///
///   // Make call into driver to say "hello"
///   printf("Calling Hello\n");
///   ret = ioctl(fd, RUST_MISC_DEV_HELLO, NULL);
///   if (ret < 0) {
///     perror("ioctl: Failed to call into Hello");
///     close(fd);
///     return errno;
///   }
///
///   // Get initial value
///   printf("Fetching initial value\n");
///   ret = ioctl(fd, RUST_MISC_DEV_GET_VALUE, &value);
///   if (ret < 0) {
///     perror("ioctl: Failed to fetch the initial value");
///     close(fd);
///     return errno;
///   }
///
///   value++;
///
///   // Set value to something different
///   printf("Submitting new value (%d)\n", value);
///   ret = ioctl(fd, RUST_MISC_DEV_SET_VALUE, &value);
///   if (ret < 0) {
///     perror("ioctl: Failed to submit new value");
///     close(fd);
///     return errno;
///   }
///
///   // Ensure new value was applied
///   printf("Fetching new value\n");
///   ret = ioctl(fd, RUST_MISC_DEV_GET_VALUE, &new_value);
///   if (ret < 0) {
///     perror("ioctl: Failed to fetch the new value");
///     close(fd);
///     return errno;
///   }
///
///   if (value != new_value) {
///     printf("Failed: Committed and retrieved values are different (%d - %d)\n", value, new_value);
///     close(fd);
///     return -1;
///   }
///
///   // Call the unsuccessful ioctl
///   printf("Attempting to call in to an non-existent IOCTL\n");
///   ret = ioctl(fd, RUST_MISC_DEV_FAIL, NULL);
///   if (ret < 0) {
///     perror("ioctl: Succeeded to fail - this was expected");
///   } else {
///     printf("ioctl: Failed to fail\n");
///     close(fd);
///     return -1;
///   }
///
///   // Close the device file
///   printf("Closing /dev/rust-misc-device\n");
///   close(fd);
///
///   printf("Success\n");
///   return 0;
/// }
/// ```
use core::pin::Pin;

use kernel::{
    c_str,
    device::Device,
    fs::File,
    ioctl::{_IO, _IOC_SIZE, _IOR, _IOW},
    miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration},
    new_mutex,
    prelude::*,
    sync::Mutex,
    types::ARef,
    uaccess::{UserSlice, UserSliceReader, UserSliceWriter},
};

const RUST_MISC_DEV_HELLO: u32 = _IO('|' as u32, 0x80);
const RUST_MISC_DEV_GET_VALUE: u32 = _IOR::<i32>('|' as u32, 0x81);
const RUST_MISC_DEV_SET_VALUE: u32 = _IOW::<i32>('|' as u32, 0x82);

module! {
    type: RustMiscDeviceModule,
    name: "rust_misc_device",
    author: "Lee Jones",
    description: "Rust misc device sample",
    license: "GPL",
}

#[pin_data]
struct RustMiscDeviceModule {
    #[pin]
    _miscdev: MiscDeviceRegistration<RustMiscDevice>,
}

impl kernel::InPlaceModule for RustMiscDeviceModule {
    fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> {
        pr_info!("Initialising Rust Misc Device Sample\n");

        let options = MiscDeviceOptions {
            name: c_str!("rust-misc-device"),
        };

        try_pin_init!(Self {
            _miscdev <- MiscDeviceRegistration::register(options),
        })
    }
}

struct Inner {
    value: i32,
}

#[pin_data(PinnedDrop)]
struct RustMiscDevice {
    #[pin]
    inner: Mutex<Inner>,
    dev: ARef<Device>,
}

#[vtable]
impl MiscDevice for RustMiscDevice {
    type Ptr = Pin<KBox<Self>>;

    fn open(_file: &File, misc: &MiscDeviceRegistration<Self>) -> Result<Pin<KBox<Self>>> {
        let dev = ARef::from(misc.device());

        dev_info!(dev, "Opening Rust Misc Device Sample\n");

        KBox::try_pin_init(
            try_pin_init! {
                RustMiscDevice {
                    inner <- new_mutex!( Inner{ value: 0_i32 } ),
                    dev: dev,
                }
            },
            GFP_KERNEL,
        )
    }

    fn ioctl(me: Pin<&RustMiscDevice>, _file: &File, cmd: u32, arg: usize) -> Result<isize> {
        dev_info!(me.dev, "IOCTLing Rust Misc Device Sample\n");

        let size = _IOC_SIZE(cmd);

        match cmd {
            RUST_MISC_DEV_GET_VALUE => me.get_value(UserSlice::new(arg, size).writer())?,
            RUST_MISC_DEV_SET_VALUE => me.set_value(UserSlice::new(arg, size).reader())?,
            RUST_MISC_DEV_HELLO => me.hello()?,
            _ => {
                dev_err!(me.dev, "-> IOCTL not recognised: {}\n", cmd);
                return Err(ENOTTY);
            }
        };

        Ok(0)
    }
}

#[pinned_drop]
impl PinnedDrop for RustMiscDevice {
    fn drop(self: Pin<&mut Self>) {
        dev_info!(self.dev, "Exiting the Rust Misc Device Sample\n");
    }
}

impl RustMiscDevice {
    fn set_value(&self, mut reader: UserSliceReader) -> Result<isize> {
        let new_value = reader.read::<i32>()?;
        let mut guard = self.inner.lock();

        dev_info!(
            self.dev,
            "-> Copying data from userspace (value: {})\n",
            new_value
        );

        guard.value = new_value;
        Ok(0)
    }

    fn get_value(&self, mut writer: UserSliceWriter) -> Result<isize> {
        let guard = self.inner.lock();
        let value = guard.value;

        // Free-up the lock and use our locally cached instance from here
        drop(guard);

        dev_info!(
            self.dev,
            "-> Copying data to userspace (value: {})\n",
            &value
        );

        writer.write::<i32>(&value)?;
        Ok(0)
    }

    fn hello(&self) -> Result<isize> {
        dev_info!(self.dev, "-> Hello from the Rust Misc Device\n");

        Ok(0)
    }
}
