+ # now, with those three files, merge them all into one easy to
+ # use lookup table
+ (all_pci_ids, all_modules) = merge_hw_tables.merge_files( modules_dep_path,
+ modules_pcimap_path,
+ pcitable_path )
+ if all_modules is None:
+ print( "Unable to merge pci id tables." )
+ return
+
+ # this is the actual data structure we return
+ system_mods= {}
+
+ # these are the lists that will be in system_mods
+ network_mods= []
+ scsi_mods= []
+
+
+ # get all the system devices from lspci
+ lspci_prog= popen2.Popen3( LSPCI_CMD, 1 )
+ if lspci_prog is None:
+ print( "Unable to run %s with popen2.Popen3" % LSPCI_CMD )
+ return
+
+ returncode= lspci_prog.wait()
+ if returncode != 0:
+ print( "Running %s failed" % LSPCI_CMD )
+ return
+ else:
+ print( "Successfully ran %s" % 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:
+ # 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:
+ 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 (PCI_CLASS_NETWORK_ETHERNET,
+ PCI_CLASS_STORAGE_SCSI,
+ PCI_CLASS_STORAGE_SATA,
+ PCI_CLASS_STORAGE_RAID,
+ PCI_CLASS_STORAGE_OTHER,
+ PCI_CLASS_STORAGE_IDE):
+ continue
+
+ # Device may have a subvendorid and subdeviceid
+ try:
+ subvendorid = long(parts[4], 16)
+ subdeviceid = long(parts[5], 16)
+ except:
+ subvendorid = PCI_ANY
+ subdeviceid = 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,PCI_ANY),
+ (vendorid,deviceid,PCI_ANY,PCI_ANY))
+
+ for full_id in full_ids:
+ module = all_pci_ids.get(full_id, None)
+ if module is not None:
+ if classid == PCI_CLASS_NETWORK_ETHERNET:
+ network_mods.append(module[0])
+ elif classid in (PCI_CLASS_STORAGE_SCSI,
+ PCI_CLASS_STORAGE_SATA,
+ PCI_CLASS_STORAGE_RAID,
+ PCI_CLASS_STORAGE_OTHER,
+ PCI_CLASS_STORAGE_IDE):
+ scsi_mods.append(module[0])
+ else:
+ print "not network or scsi: 0x%x" % classid
+ break