// SPDX-License-Identifier: GPL-2.0

//! Rust PCI driver sample (based on QEMU's `pci-testdev`).
//!
//! To make this driver probe, QEMU must be run with `-device pci-testdev`.

use kernel::{bindings, c_str, devres::Devres, pci, prelude::*};

struct Regs;

impl Regs {
    const TEST: usize = 0x0;
    const OFFSET: usize = 0x4;
    const DATA: usize = 0x8;
    const COUNT: usize = 0xC;
    const END: usize = 0x10;
}

type Bar0 = pci::Bar<{ Regs::END }>;

#[derive(Debug)]
struct TestIndex(u8);

impl TestIndex {
    const NO_EVENTFD: Self = Self(0);
}

struct SampleDriver {
    pdev: pci::Device,
    bar: Devres<Bar0>,
}

kernel::pci_device_table!(
    PCI_TABLE,
    MODULE_PCI_TABLE,
    <SampleDriver as pci::Driver>::IdInfo,
    [(
        pci::DeviceId::from_id(bindings::PCI_VENDOR_ID_REDHAT, 0x5),
        TestIndex::NO_EVENTFD
    )]
);

impl SampleDriver {
    fn testdev(index: &TestIndex, bar: &Bar0) -> Result<u32> {
        // Select the test.
        bar.writeb(index.0, Regs::TEST);

        let offset = u32::from_le(bar.readl(Regs::OFFSET)) as usize;
        let data = bar.readb(Regs::DATA);

        // Write `data` to `offset` to increase `count` by one.
        //
        // Note that we need `try_writeb`, since `offset` can't be checked at compile-time.
        bar.try_writeb(data, offset)?;

        Ok(bar.readl(Regs::COUNT))
    }
}

impl pci::Driver for SampleDriver {
    type IdInfo = TestIndex;

    const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;

    fn probe(pdev: &mut pci::Device, info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
        dev_dbg!(
            pdev.as_ref(),
            "Probe Rust PCI driver sample (PCI ID: 0x{:x}, 0x{:x}).\n",
            pdev.vendor_id(),
            pdev.device_id()
        );

        pdev.enable_device_mem()?;
        pdev.set_master();

        let bar = pdev.iomap_region_sized::<{ Regs::END }>(0, c_str!("rust_driver_pci"))?;

        let drvdata = KBox::new(
            Self {
                pdev: pdev.clone(),
                bar,
            },
            GFP_KERNEL,
        )?;

        let bar = drvdata.bar.try_access().ok_or(ENXIO)?;

        dev_info!(
            pdev.as_ref(),
            "pci-testdev data-match count: {}\n",
            Self::testdev(info, &bar)?
        );

        Ok(drvdata.into())
    }
}

impl Drop for SampleDriver {
    fn drop(&mut self) {
        dev_dbg!(self.pdev.as_ref(), "Remove Rust PCI driver sample.\n");
    }
}

kernel::module_pci_driver! {
    type: SampleDriver,
    name: "rust_driver_pci",
    author: "Danilo Krummrich",
    description: "Rust PCI driver",
    license: "GPL v2",
}
