#![no_std]
#![cfg_attr(feature = "virtio", feature(associated_type_defaults))]
#[macro_use]
extern crate log;
#[cfg(feature = "dyn")]
extern crate alloc;
#[macro_use]
mod macros;
#[cfg(not(feature = "dyn"))]
mod bus;
mod drivers;
mod dummy;
mod structs;
#[cfg(feature = "virtio")]
mod virtio;
#[cfg(feature = "ixgbe")]
mod ixgbe;
#[cfg(feature = "dyn")]
mod dyn_drivers;
pub mod prelude;
#[cfg(feature = "block")]
pub use ax_driver_block::partition::{
PartitionBlockDevice, PartitionInfo, PartitionRegion, PartitionTable, PartitionTableKind,
scan_partitions,
};
#[allow(unused_imports)]
use self::prelude::*;
#[cfg(feature = "block")]
pub use self::structs::AxBlockDevice;
#[cfg(feature = "display")]
pub use self::structs::AxDisplayDevice;
#[cfg(feature = "net")]
pub use self::structs::AxNetDevice;
pub use self::structs::{AxDeviceContainer, AxDeviceEnum};
#[derive(Default)]
pub struct AllDevices {
#[cfg(feature = "net")]
pub net: AxDeviceContainer<AxNetDevice>,
#[cfg(feature = "block")]
pub block: AxDeviceContainer<AxBlockDevice>,
#[cfg(feature = "display")]
pub display: AxDeviceContainer<AxDisplayDevice>,
#[cfg(feature = "input")]
pub input: AxDeviceContainer<AxInputDevice>,
#[cfg(feature = "vsock")]
pub vsock: AxDeviceContainer<AxVsockDevice>,
}
impl AllDevices {
pub const fn device_model() -> &'static str {
if cfg!(feature = "dyn") {
"dyn"
} else {
"static"
}
}
fn probe(&mut self) {
#[cfg(feature = "dyn")]
for dev in dyn_drivers::probe_all_devices() {
self.add_device(dev);
}
#[cfg(not(feature = "dyn"))]
{
for_each_drivers!(type Driver, {
if let Some(dev) = Driver::probe_global() {
info!(
"registered a new {:?} device: {:?}",
dev.device_type(),
dev.device_name(),
);
self.add_device(dev);
}
});
self.probe_bus_devices();
}
}
#[allow(dead_code)]
fn add_device(&mut self, dev: AxDeviceEnum) {
match dev {
#[cfg(feature = "net")]
AxDeviceEnum::Net(dev) => self.net.push(dev),
#[cfg(feature = "block")]
AxDeviceEnum::Block(dev) => self.block.push(dev),
#[cfg(feature = "display")]
AxDeviceEnum::Display(dev) => self.display.push(dev),
#[cfg(feature = "input")]
AxDeviceEnum::Input(dev) => self.input.push(dev),
#[cfg(feature = "vsock")]
AxDeviceEnum::Vsock(dev) => self.vsock.push(dev),
}
}
}
pub fn init_drivers() -> AllDevices {
info!("Initialize device drivers...");
info!(" device model: {}", AllDevices::device_model());
let mut all_devs = AllDevices::default();
all_devs.probe();
#[cfg(feature = "net")]
{
debug!("number of NICs: {}", all_devs.net.len());
for (i, dev) in all_devs.net.iter().enumerate() {
assert_eq!(dev.device_type(), DeviceType::Net);
debug!(" NIC {}: {:?}", i, dev.device_name());
}
}
#[cfg(feature = "block")]
{
debug!("number of block devices: {}", all_devs.block.len());
for (i, dev) in all_devs.block.iter().enumerate() {
assert_eq!(dev.device_type(), DeviceType::Block);
debug!(" block device {}: {:?}", i, dev.device_name());
}
}
#[cfg(feature = "display")]
{
debug!("number of graphics devices: {}", all_devs.display.len());
for (i, dev) in all_devs.display.iter().enumerate() {
assert_eq!(dev.device_type(), DeviceType::Display);
debug!(" graphics device {}: {:?}", i, dev.device_name());
}
}
#[cfg(feature = "input")]
{
debug!("number of input devices: {}", all_devs.input.len());
for (i, dev) in all_devs.input.iter().enumerate() {
assert_eq!(dev.device_type(), DeviceType::Input);
debug!(" input device {}: {:?}", i, dev.device_name());
}
}
#[cfg(feature = "vsock")]
{
debug!("number of vsock devices: {}", all_devs.vsock.len());
for (i, dev) in all_devs.vsock.iter().enumerate() {
assert_eq!(dev.device_type(), DeviceType::Vsock);
debug!(" vsock device {}: {:?}", i, dev.device_name());
}
}
all_devs
}