Skip to content

Commit

Permalink
Merge pull request #454 from peterdk/feature/link-usb
Browse files Browse the repository at this point in the history
USB Link speeds
  • Loading branch information
nokyan authored Feb 21, 2025
2 parents ac4cb1c + e32e01e commit 56e2e74
Show file tree
Hide file tree
Showing 3 changed files with 234 additions and 37 deletions.
50 changes: 45 additions & 5 deletions src/utils/drive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ static RE_ATA_LINK: Lazy<Regex> = lazy_regex!(r"(^link(\d+))$");

static RE_ATA_SLOT: Lazy<Regex> = lazy_regex!(r"(^.+?/ata(\d+))/");

static RE_USB_SLOT: Lazy<Regex> = lazy_regex!(r"(^.+?/usb(\d+))/(.+?)/");

#[derive(Debug)]
pub struct DriveData {
pub inner: Drive,
Expand Down Expand Up @@ -87,10 +89,11 @@ pub enum DriveType {
Unknown,
}

#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
pub enum DriveSlot {
Pci(PciSlot),
Ata(AtaSlot),
Usb(UsbSlot),
#[default]
Unknown,
}
Expand All @@ -101,6 +104,12 @@ pub struct AtaSlot {
pub ata_link: u8,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct UsbSlot {
pub usb_bus: u8,
pub usb_device: String,
}

#[derive(Debug, Clone, Default, Eq)]
pub struct Drive {
pub model: Option<String>,
Expand Down Expand Up @@ -334,10 +343,11 @@ impl Drive {
/// Will return `Err` if there are errors during
/// reading or parsing, or if the drive link type is not supported
pub fn link(&self) -> Result<Link> {
match self.slot {
DriveSlot::Pci(slot) => Ok(Link::Pcie(LinkData::from_pci_slot(&slot)?)),
DriveSlot::Ata(slot) => Ok(Link::Sata(LinkData::from_ata_slot(&slot)?)),
_ => bail!("unsupported drive connection type"),
match &self.slot {
DriveSlot::Pci(slot) => Ok(Link::Pcie(LinkData::from_pci_slot(slot)?)),
DriveSlot::Ata(slot) => Ok(Link::Sata(LinkData::from_ata_slot(slot)?)),
DriveSlot::Usb(slot) => Ok(Link::Usb(LinkData::from_usb_slot(slot)?)),
DriveSlot::Unknown => bail!("unsupported drive connection type"),
}
}

Expand All @@ -346,6 +356,8 @@ impl Drive {
Ok(DriveSlot::Pci(pci_slot))
} else if let Ok(ata_slot) = self.ata_slot() {
Ok(DriveSlot::Ata(ata_slot))
} else if let Ok(usb_slot) = self.usb_slot() {
Ok(DriveSlot::Usb(usb_slot))
} else {
bail!("unsupported drive slot type")
}
Expand Down Expand Up @@ -403,6 +415,34 @@ impl Drive {
})
}

fn usb_slot(&self) -> Result<UsbSlot> {
let symlink = std::fs::read_link(&self.sysfs_path)
.context("Could not read sysfs_path as symlink")?
.to_string_lossy()
.to_string();
// ../../devices/pci0000:00/0000:00:08.1/0000:0e:00.3/usb4/4-2/4-2:1.0/host6/target6:0:0/6:0:0:0/block/sdb

let usb_match = RE_USB_SLOT
.captures(&symlink)
.context("No usb match found, probably no usb device")?;

let usb_bus = usb_match
.get(2)
.and_then(|capture| capture.as_str().parse::<u8>().ok())
.context("could not match digits in usb")?;

let usb_device = usb_match
.get(3)
.context("could not find usb device")?
.as_str()
.to_string();

Ok(UsbSlot {
usb_bus,
usb_device,
})
}

/// Returns the World-Wide Identification of the drive
///
/// # Errors
Expand Down
Loading

0 comments on commit 56e2e74

Please sign in to comment.