use crate::StatusExt;
use uefi_macros::unsafe_protocol;
use uefi_raw::protocol::disk::DiskInfoProtocol;
#[cfg(doc)]
use crate::Status;
#[derive(Debug, Eq, PartialEq)]
pub enum DiskInfoInterface {
Unknown,
IDE,
UFS,
USB,
AHCI,
NVME,
SCSI,
SDMMC,
}
#[derive(Debug)]
pub struct SenseDataInfo {
pub bytes: usize,
pub number: u8,
}
#[derive(Debug)]
pub struct DeviceLocationInfo {
pub channel: u32,
pub device: u32,
}
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(DiskInfoProtocol::GUID)]
pub struct DiskInfo(DiskInfoProtocol);
impl DiskInfo {
#[must_use]
pub const fn interface(&self) -> DiskInfoInterface {
match self.0.interface {
DiskInfoProtocol::IDE_INTERFACE_GUID => DiskInfoInterface::IDE,
DiskInfoProtocol::UFS_INTERFACE_GUID => DiskInfoInterface::UFS,
DiskInfoProtocol::USB_INTERFACE_GUID => DiskInfoInterface::USB,
DiskInfoProtocol::AHCI_INTERFACE_GUID => DiskInfoInterface::AHCI,
DiskInfoProtocol::NVME_INTERFACE_GUID => DiskInfoInterface::NVME,
DiskInfoProtocol::SCSI_INTERFACE_GUID => DiskInfoInterface::SCSI,
DiskInfoProtocol::SD_MMC_INTERFACE_GUID => DiskInfoInterface::SDMMC,
_ => DiskInfoInterface::Unknown,
}
}
pub fn inquiry(&self, bfr: &mut [u8]) -> crate::Result<usize> {
let mut len: u32 = bfr.len() as u32;
unsafe {
(self.0.inquiry)(&self.0, bfr.as_mut_ptr().cast(), &mut len)
.to_result_with_val(|| len as usize)
}
}
pub fn identify(&self, bfr: &mut [u8]) -> crate::Result<usize> {
let mut len: u32 = bfr.len() as u32;
unsafe {
(self.0.identify)(&self.0, bfr.as_mut_ptr().cast(), &mut len)
.to_result_with_val(|| len as usize)
}
}
pub fn sense_data(&self, bfr: &mut [u8]) -> crate::Result<SenseDataInfo> {
let mut len: u32 = bfr.len() as u32;
let mut number: u8 = 0;
unsafe {
(self.0.sense_data)(&self.0, bfr.as_mut_ptr().cast(), &mut len, &mut number)
.to_result_with_val(|| SenseDataInfo {
bytes: len as usize,
number,
})
}
}
pub fn bus_location(&self) -> crate::Result<DeviceLocationInfo> {
let mut ide_channel: u32 = 0; let mut ide_device: u32 = 0;
unsafe {
(self.0.which_ide)(&self.0, &mut ide_channel, &mut ide_device).to_result_with_val(
|| DeviceLocationInfo {
channel: ide_channel,
device: ide_device,
},
)
}
}
}