80 lines
2.3 KiB
Python
80 lines
2.3 KiB
Python
"""
|
|
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
|