starry-kernel 0.7.0

A Linux-compatible OS kernel built on ArceOS unikernel
use ax_errno::{AxError, AxResult};
use usb_serial::{ControlTransfer, UsbSerialChip, UsbSerialPort, probe_supported_port};

use crate::pseudofs::usbfs::{self, UsbDeviceHandle, UsbDeviceSnapshotInfo};

#[derive(Clone, Copy)]
pub(super) struct UsbSerialPortInfo {
    pub(super) bus_num: u8,
    pub(super) device_num: u8,
    chip: UsbSerialChip,
    port: UsbSerialPort,
}

impl UsbSerialPortInfo {
    fn new(snapshot: &UsbDeviceSnapshotInfo, chip: UsbSerialChip, port: UsbSerialPort) -> Self {
        Self {
            bus_num: snapshot.bus_num,
            device_num: snapshot.device_num,
            chip,
            port,
        }
    }

    pub(super) fn name(&self) -> &'static str {
        self.chip.name()
    }

    pub(super) fn interface(&self) -> u8 {
        self.port.interface
    }

    pub(super) fn bulk_in(&self) -> u8 {
        self.port.bulk_in
    }

    pub(super) fn bulk_out(&self) -> u8 {
        self.port.bulk_out
    }

    pub(super) fn init(&self, handle: &UsbDeviceHandle, baud: u32) -> AxResult<()> {
        self.chip.init(&StarryControl(handle), &self.port, baud)
    }

    pub(super) fn set_baud(&self, handle: &UsbDeviceHandle, baud: u32) -> AxResult<()> {
        self.chip.set_baud(&StarryControl(handle), &self.port, baud)
    }
}

struct StarryControl<'a>(&'a UsbDeviceHandle);

impl ControlTransfer for StarryControl<'_> {
    type Error = AxError;

    fn control_out(
        &self,
        request_type: u8,
        request: u8,
        value: u16,
        index: u16,
        data: &mut [u8],
    ) -> Result<usize, Self::Error> {
        self.0
            .control_transfer(request_type, request, value, index, data)
    }
}

pub(super) fn find_usb_serial_port(index: usize) -> Option<UsbSerialPortInfo> {
    usbfs::usb_device_snapshots()
        .into_iter()
        .filter_map(|snapshot| {
            let matched = probe_supported_port(&snapshot.descriptor_blob)?;
            Some(UsbSerialPortInfo::new(
                &snapshot,
                matched.chip,
                matched.port,
            ))
        })
        .nth(index)
}