hardware 0.0.9

A no_std bare-metal hardware abstraction layer — all port I/O, memory and swap allocations are guarded at runtime. Do not consider this dependency stable before x.1.x
Documentation
use crate::bus::pci;

#[derive(Copy, Clone, Debug)]
pub struct PciDevice {
    pub bus: u8,
    pub device: u8,
    pub function: u8,
    pub vendor_id: u16,
    pub device_id: u16,
    pub class: u8,
    pub subclass: u8,
}

impl PciDevice {
    pub fn from_bdf(bus: u8, device: u8, function: u8) -> Option<Self> {
        if let Some(d0) = pci::read_config_u32(bus, device, function, 0) {
            let vendor = (d0 & 0xffff) as u16;
            if vendor == 0xffff {
                return None;
            }
            let did = ((d0 >> 16) & 0xffff) as u16;
            let cls = pci::read_config_u32(bus, device, function, 0x08).unwrap_or(0);
            let class = ((cls >> 24) & 0xff) as u8;
            let subclass = ((cls >> 16) & 0xff) as u8;
            Some(PciDevice {
                bus,
                device,
                function,
                vendor_id: vendor,
                device_id: did,
                class,
                subclass,
            })
        } else {
            None
        }
    }
}

pub fn scan_all(out: &mut [PciDevice]) -> usize {
    let mut found = 0usize;
    for b in 0u8..=255u8 {
        for d in 0u8..32u8 {
            for f in 0u8..8u8 {
                if let Some(dev) = PciDevice::from_bdf(b, d, f) {
                    if found < out.len() {
                        out[found] = dev;
                        found += 1;
                    } else {
                        return found;
                    }
                }
            }
        }
    }
    found
}