""" PCI Information Parser Combines lspci -v and lspci -n outputs to get complete device information. """ import re import subprocess from typing import Dict, Any, Optional def get_pci_ids_from_lspci_n(lspci_n_output: str) -> Dict[str, str]: """ Parse lspci -n output to extract vendor:device IDs for all slots. Args: lspci_n_output: Output from 'lspci -n' command Returns: Dictionary mapping slot -> vendor:device ID Example: {"04:00.0": "10ec:8168", "08:00.0": "10de:2504"} """ slot_to_id = {} lines = lspci_n_output.strip().split('\n') for line in lines: # Format: "04:00.0 0200: 10ec:8168 (rev 16)" # Format: "00:00.0 0600: 1022:1480" match = re.match(r'^([0-9a-fA-F]{2}:[0-9a-fA-F]{2}\.[0-9a-fA-F])\s+[0-9a-fA-F]+:\s+([0-9a-fA-F]{4}):([0-9a-fA-F]{4})', line) if match: slot = match.group(1) vendor_id = match.group(2).lower() device_id = match.group(3).lower() slot_to_id[slot] = f"{vendor_id}:{device_id}" return slot_to_id def enrich_device_info_with_ids(device_info: Dict[str, Any], pci_ids: Dict[str, str]) -> Dict[str, Any]: """ Enrich device info with vendor:device ID from lspci -n output. Args: device_info: Parsed device information from lspci -v pci_ids: Mapping from slot to vendor:device ID Returns: Enriched device info with pci_device_id field """ slot = device_info.get("slot") if slot and slot in pci_ids: device_info["pci_device_id"] = pci_ids[slot] # Also split into vendor_id and device_id parts = pci_ids[slot].split(':') if len(parts) == 2: device_info["vendor_id"] = f"0x{parts[0]}" device_info["device_id"] = f"0x{parts[1]}" return device_info def run_lspci_n() -> Optional[str]: """ Run lspci -n command and return output. This is a helper function that executes the command. Returns: Output from lspci -n or None if command fails """ try: result = subprocess.run( ['lspci', '-n'], capture_output=True, text=True, timeout=10 ) if result.returncode == 0: return result.stdout return None except Exception: return None