import os
import popen2
import merge_hw_tables
+import re
-
+hwdatapath = "usr/share/hwdata"
class systeminfo:
"""
a utility class for finding and returning information about
MODULE_CLASS_NETWORK= "network"
MODULE_CLASS_SCSI= "scsi"
- PCI_CLASS_NETWORK= "0200"
- PCI_CLASS_RAID= "0104"
- PCI_CLASS_RAID2= "0100"
- PCI_CLASS_IDE= "0101"
+ PCI_CLASS_NETWORK_ETHERNET=0x0200L
+ PCI_CLASS_STORAGE_SCSI=0x0100L
+ PCI_CLASS_STORAGE_IDE=0x0101L
+ PCI_CLASS_STORAGE_FLOPPY=0x0102L
+ PCI_CLASS_STORAGE_IPI=0x0103L
+ PCI_CLASS_STORAGE_RAID=0x0104L
+ PCI_CLASS_STORAGE_OTHER=0x0180L
+
+ PCI_ANY=0xffffffffL
def get_total_phsyical_mem(self):
"""
print( "Using kernel version %s" % kernel_version )
# test to make sure the three files we need are present
- pcitable_path = "%s/usr/share/hwdata/pcitable" % install_root
+ pcitable_path = "%s/%s/pcitable" % (install_root,hwdatapath)
modules_pcimap_path = "%s/lib/modules/%s/modules.pcimap" % \
(install_root,kernel_version)
modules_dep_path = "%s/lib/modules/%s/modules.dep" % \
else:
print( "Successfully ran %s" % self.LSPCI_CMD )
+ # for every lspci line, parse in the four tuple PCI id and the
+ # search for the corresponding driver from the dictionary
+ # generated by merge_hw_tables
for line in lspci_prog.fromchild:
- if string.strip(line) == "":
- continue
-
- parts= string.split(line)
-
+ # A sample line:
+ #
+ # 00:1f.1 "Class 0101" "8086" "2411" -r02 -p80 "8086" "2411"
+ #
+ # Remove '"', 'Class ', and anything beginning with '-'
+ # (usually revisions and prog-if flags) so that we can
+ # split on whitespace:
+ #
+ # 00:1f.1 0101 8086 2411 8086 2411
+ #
+ line = line.strip()
+ line = line.replace('"', '')
+ line = line.replace('Class ', '')
+ line = re.sub('-[^ ]*', '', line)
+
+ parts = line.split()
try:
- classid= self.remove_quotes(parts[2])
- except IndexError:
- print( "Skipping invalid line:", string.strip(line) )
+ if len(parts) < 4:
+ raise
+ classid = long(parts[1], 16)
+ vendorid = long(parts[2], 16)
+ deviceid = long(parts[3], 16)
+ except:
+ print "Invalid line:", line
continue
- if classid not in (self.PCI_CLASS_NETWORK,
- self.PCI_CLASS_RAID,
- self.PCI_CLASS_RAID2,
- self.PCI_CLASS_IDE):
+ if classid not in (self.PCI_CLASS_NETWORK_ETHERNET,
+ self.PCI_CLASS_STORAGE_SCSI,
+ self.PCI_CLASS_STORAGE_RAID,
+ self.PCI_CLASS_STORAGE_OTHER,
+ self.PCI_CLASS_STORAGE_IDE):
continue
+ # Device may have a subvendorid and subdeviceid
try:
- vendorid= self.remove_quotes(parts[3])
- vendorid= long(vendorid,16)
- deviceid= self.remove_quotes(parts[4])
- deviceid= long(deviceid,16)
- except IndexError:
- print( "Skipping invalid line:", string.strip(line) )
- continue
- except ValueError, e:
- print( "Skipping invalid line:", string.strip(line) )
- continue
-
-
- # full device id with subvednor & subdevice set to ANY
- PCI_ANY = 0xffffffffL
- full_id= (vendorid,deviceid,PCI_ANY,PCI_ANY)
- module = all_pci_ids.get(full_id, None)
- if module is None:
- # continue searching parts[5:] for module with
- # subvendor first and then subdevice
- subvendorindex = -1
- subdeviceindex = -1
- for i in range(5,len(parts)):
- p = self.remove_quotes(parts[i])
- if p[0] != '-':
- subvendorindex = i
- break
-
- if subvendorindex != -1:
- try:
- subvendorid= self.remove_quotes(parts[subvendorindex])
- subvendorid= long(subvendorid,16)
- except IndexError:
- print( "Skipping invalid line:", string.strip(line) )
- continue
- except ValueError, e:
- print( "Skipping invalid line:", string.strip(line) )
- continue
-
- full_id=(vendorid,deviceid,subvendorid,PCI_ANY)
- module = all_pci_ids.get(full_id, None)
- if module is None:
- for i in range(subvendorindex+1,len(parts)):
- p = self.remove_quotes(parts[i])
- if p[0] != '-':
- subdeviceindex = i
- break
-
- if subdeviceindex != -1:
- try:
- subdeviceid= self.remove_quotes(parts[subdeviceindex])
- subdeviceid= long(subdeviceid,16)
- except IndexError:
- print( "Skipping invalid line:", string.strip(line) )
- continue
- except ValueError, e:
- print( "Skipping invalid line:", string.strip(line) )
- continue
-
- full_id= (vendorid,deviceid,subvendorid,subdeviceid)
- module = all_pci_ids.get(full_id, None)
- if module is None:
- continue
-
- if classid == self.PCI_CLASS_NETWORK:
- network_mods.append(module[0])
- elif classid in (self.PCI_CLASS_RAID,
- self.PCI_CLASS_RAID2,
- self.PCI_CLASS_IDE):
- scsi_mods.append(module[0])
+ subvendorid = long(parts[4], 16)
+ subdeviceid = long(parts[5], 16)
+ except:
+ subvendorid = self.PCI_ANY
+ subdeviceid = self.PCI_ANY
+
+ # search for driver that most closely matches the full_id
+ # to drivers that can handle any subvendor/subdevice
+ # version of the hardware.
+ full_ids = ((vendorid,deviceid,subvendorid,subdeviceid),
+ (vendorid,deviceid,subvendorid,self.PCI_ANY),
+ (vendorid,deviceid,self.PCI_ANY,self.PCI_ANY))
+
+ for full_id in full_ids:
+ module = all_pci_ids.get(full_id, None)
+ if module is not None:
+ if classid == self.PCI_CLASS_NETWORK_ETHERNET:
+ network_mods.append(module[0])
+ elif classid in (self.PCI_CLASS_STORAGE_SCSI,
+ self.PCI_CLASS_STORAGE_RAID,
+ self.PCI_CLASS_STORAGE_OTHER,
+ self.PCI_CLASS_STORAGE_IDE):
+ scsi_mods.append(module[0])
+ else:
+ print "not network or scsi: 0x%x" % classid
+ break
system_mods[self.MODULE_CLASS_SCSI]= scsi_mods
system_mods[self.MODULE_CLASS_NETWORK]= network_mods