########################################################################### # ScanPCI.py - # # ------------------------------ # # copyright : (C) 2005 by Simon Edwards # # email : simon@simonzone.com # # # ########################################################################### # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ########################################################################### """Provides information about the devices attached to the PCI bus. """ import struct import csv import os.path import sys ########################################################################### class PCIDevice(object): def __init__(self,line=None): self.vendor = None # PCI vendor id self.device = None self.subvendor = None # 0xffff if not probe_type'd or no subid self.subdevice = None # 0xffff if not probe_type'd or no subid self.pci_class = None # 'None' if not probe_type'd self.pci_bus = None # pci bus id 8 bits wide self.pci_device = None # pci device id 5 bits wide self.pci_function = None# pci function id 3 bits wide self.module = None self.text = None self.already_found = False if line is not None: self.loadFromString(line) def isGfxCard(self): if self.module is not None and \ (self.module.startswith("Card:") or self.module.startswith("Server:XFree86(")): return True return (self.pci_class & PCIBus.PCI_BASE_CLASS_MASK)==PCIBus.PCI_BASE_CLASS_DISPLAY def getModule(self): if self.module is not None: if self.module.startswith("Server:XFree86("): return self.module[15:-1] elif self.module.startswith("Card:"): return self.module[5:] return self.module def isModuleXorgDriver(self): return self.module is not None and \ (self.module.startswith("Server:XFree86(") or self.module.startswith("Card:")) def __str__(self): s = "PCI:%i:%i:%i, " % (self.pci_bus,self.pci_device,self.pci_function) s += "Vendor:%x, Device:%x," % (self.vendor,self.device) if self.subvendor is not None: s += " Subvendor:%x," % self.subvendor if self.subdevice is not None: s += " Subdevice:%x," % self.subdevice if self.pci_class is not None: s += " Class:%x," % self.pci_class if self.module is not None: s += " Module:%s," % self.module if self.text is not None: s += " Text:%s" % self.text return s def loadFromString(self,line): parts = line.split(",") for i in range(len(parts)): bit = parts[i].strip() if bit.startswith("PCI:"): pci_code = bit[4:].split(":") self.pci_bus = int(pci_code[0]) self.pci_device = int(pci_code[1]) self.pci_function = int(pci_code[2]) elif bit.startswith("Vendor:"): self.vendor = int(bit[7:],16) elif bit.startswith("Device:"): self.device = int(bit[7:],16) elif bit.startswith("Subvendor:"): self.subvendor = int(bit[10:],16) elif bit.startswith("Subdevice:"): self.subdevice = int(bit[10:],16) elif bit.startswith("Class:"): self.pci_class = int(bit[6:],16) elif bit.startswith("Module:"): self.module = bit[7:] elif bit.startswith("Text:"): self.text = " ".join(parts[i:]).strip()[5:] break ############################################################################ class PCIBus(object): PCI_CLASS_SERIAL_USB = 0x0c03 PCI_CLASS_SERIAL_FIREWIRE = 0x0c00 PCI_BASE_CLASS_MASK = 0xff00 PCI_BASE_CLASS_DISPLAY = 0x0300 def __init__(self, data_file_dir="."): self.devices = [] self.data_file_dir = data_file_dir def detect(self,device_data="/proc/bus/pci/devices"): # Shamelessly translated from ldetect's pci.c. fhandle = open(device_data) for line in fhandle.readlines(): #print "L:",line entry = PCIDevice() self.devices.append(entry) parts = line.split() devbusfn = int(parts[0],16) idbits = int(parts[1],16) entry.vendor = idbits >> 16 entry.device = idbits & 0xffff entry.pci_bus = devbusfn >> 8 entry.pci_device = (devbusfn & 0xff) >> 3 entry.pci_function = (devbusfn & 0xff) & 0x07 try: infohandle = open("/proc/bus/pci/%02x/%02x.%d" % ( entry.pci_bus, entry.pci_device, entry.pci_function),"r") # these files are 256 bytes but we only need first 48 bytes buf = infohandle.read(48) (class_prog, entry.pci_class, entry.subvendor, entry.subdevice) = \ struct.unpack("= 1 and row[0] != '': # Skip manufacturer info lines. continue vendor = int(row[1][:4],16) device = int(row[1][4:],16) module = row[3] text = ' '.join(row[4:]).strip() i = 0 while i1: if sys.argv[1]=="--help" or sys.argv[1]=="-h": print "Usage:\n ScanPCI.py " sys.exit(0) bus.detect(sys.argv[1]) else: bus.detect() print bus if __name__=='__main__': main()