Cleaned up NodeRunStates handling
[bootmanager.git] / source / systeminfo.py
index aa31e10..5840ab0 100755 (executable)
@@ -65,8 +65,9 @@ import string
 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
@@ -93,10 +94,15 @@ class systeminfo:
     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):
         """
@@ -330,7 +336,7 @@ class systeminfo:
         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" % \
@@ -371,94 +377,71 @@ class systeminfo:
         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