merge 'sorted' change into trunk.
[bootmanager.git] / source / systeminfo.py
index 966c149..8be877f 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/python2
+#!/usr/bin/python
 
 # Copyright (c) 2003 Intel Corporation
 # All rights reserved.
 
 # Copyright (c) 2003 Intel Corporation
 # All rights reserved.
@@ -23,13 +23,12 @@ import string
 import sys
 import os
 import popen2
 import sys
 import os
 import popen2
-import merge_hw_tables
 import re
 import errno
 import ModelOptions
 import re
 import errno
 import ModelOptions
+from pypci import *
 from Exceptions import *
 
 from Exceptions import *
 
-hwdatapath = "usr/share/hwdata"
 """
 a utility class for finding and returning information about
 block devices, memory, and other hardware on the system
 """
 a utility class for finding and returning information about
 block devices, memory, and other hardware on the system
@@ -47,21 +46,12 @@ DEVICES_SCANNED_FLAG= "/tmp/devices_scanned"
 BLOCKS_PER_GB = pow(10, 9) / 1024.0;
 
 
 BLOCKS_PER_GB = pow(10, 9) / 1024.0;
 
 
-# -n is numeric ids (no lookup), -m is machine readable
-LSPCI_CMD= "/sbin/lspci -nm"
-
 MODULE_CLASS_NETWORK= "network"
 MODULE_CLASS_SCSI= "scsi"
 
 MODULE_CLASS_NETWORK= "network"
 MODULE_CLASS_SCSI= "scsi"
 
-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
+#PCI_* is now defined in the pypci modules
+#PCI_BASE_CLASS_NETWORK=0x02L
+#PCI_BASE_CLASS_STORAGE=0x01L
 
 def get_total_phsyical_mem(vars = {}, log = sys.stderr):
     """
 
 def get_total_phsyical_mem(vars = {}, log = sys.stderr):
     """
@@ -139,6 +129,16 @@ def get_block_device_list(vars = {}, log = sys.stderr):
             devicename = "cciss/c%dd%d" % (M,N)
             valid_blk_names[devicename]=None
 
             devicename = "cciss/c%dd%d" % (M,N)
             valid_blk_names[devicename]=None
 
+    for devicename in valid_blk_names.keys():
+        # devfs under 2.4 (old boot cds) used to list partitions
+        # in a format such as scsi/host0/bus0/target0/lun0/disc
+        # and /dev/sda, etc. were just symlinks
+        try:
+            devfsname= os.readlink( "/dev/%s" % devicename )
+            valid_blk_names[devfsname]=None
+        except OSError:
+            pass
+
     # only do this once every system boot
     if not os.access(DEVICES_SCANNED_FLAG, os.R_OK):
 
     # only do this once every system boot
     if not os.access(DEVICES_SCANNED_FLAG, os.R_OK):
 
@@ -213,10 +213,8 @@ def get_system_modules( vars = {}, log = sys.stderr):
     """
     Return a list of kernel modules that this system requires.
     This requires access to the installed system's root
     """
     Return a list of kernel modules that this system requires.
     This requires access to the installed system's root
-    directory, as the following files must exist and are used:
-    <install_root>/usr/share/hwdata/pcitable
+    directory, as the following file must exist and is used:
     <install_root>/lib/modules/(first entry if kernel_version unspecified)/modules.pcimap
     <install_root>/lib/modules/(first entry if kernel_version unspecified)/modules.pcimap
-    <install_root>/lib/modules/(first entry if kernel version unspecified)/modules.dep
 
     If there are more than one kernels installed, and the kernel
     version is not specified, then only the first one in
 
     If there are more than one kernels installed, and the kernel
     version is not specified, then only the first one in
@@ -260,27 +258,15 @@ def get_system_modules( vars = {}, log = sys.stderr):
 
     print( "Using kernel version %s" % kernel_version )
 
 
     print( "Using kernel version %s" % kernel_version )
 
-    # test to make sure the three files we need are present
-    pcitable_path = "%s/%s/pcitable" % (SYSIMG_PATH,hwdatapath)
+    # test to make sure the file we need is present
     modules_pcimap_path = "%s/lib/modules/%s/modules.pcimap" % \
                           (SYSIMG_PATH,kernel_version)
     modules_pcimap_path = "%s/lib/modules/%s/modules.pcimap" % \
                           (SYSIMG_PATH,kernel_version)
-    modules_dep_path = "%s/lib/modules/%s/modules.dep" % \
-                       (SYSIMG_PATH,kernel_version)
-
-    for path in (pcitable_path,modules_pcimap_path,modules_dep_path):
-        if not os.access(path,os.R_OK):
-            print( "Unable to read %s" % path )
-            return
-
-    # 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." )
+    if not os.access(modules_pcimap_path,os.R_OK):
+        print( "WARNING: Unable to read %s" % modules_pcimap_path )
         return
 
         return
 
+    pcimap = pypcimap.PCIMap(modules_pcimap_path)
+
     # this is the actual data structure we return
     system_mods= {}
 
     # this is the actual data structure we return
     system_mods= {}
 
@@ -288,85 +274,24 @@ def get_system_modules( vars = {}, log = sys.stderr):
     network_mods= []
     scsi_mods= []
 
     network_mods= []
     scsi_mods= []
 
+    # XXX: this is really similar to what BootCD/conf_files/pl_hwinit does. merge?
+    pcidevs = get_devices()
 
 
-    # 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_RAID,
-                           PCI_CLASS_STORAGE_OTHER,
-                           PCI_CLASS_STORAGE_IDE):
+    devlist=pcidevs.keys()
+    devlist.sort()
+    for slot in devlist:
+        dev = pcidevs[slot]
+        base = (dev[4] & 0xff0000) >> 16
+        if base not in (PCI_BASE_CLASS_STORAGE,
+                        PCI_BASE_CLASS_NETWORK):
             continue
 
             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_RAID,
-                                 PCI_CLASS_STORAGE_OTHER,
-                                 PCI_CLASS_STORAGE_IDE):
-                    scsi_mods.append(module[0])
-                else:
-                    print "not network or scsi: 0x%x" % classid
-                break
+        modules = pcimap.get(dev)
+        if len(modules) > 0:
+            if base == PCI_BASE_CLASS_NETWORK:
+                network_mods += modules
+            elif base == PCI_BASE_CLASS_STORAGE:
+                scsi_mods += modules
 
     system_mods[MODULE_CLASS_SCSI]= scsi_mods
     system_mods[MODULE_CLASS_NETWORK]= network_mods
 
     system_mods[MODULE_CLASS_SCSI]= scsi_mods
     system_mods[MODULE_CLASS_NETWORK]= network_mods
@@ -439,13 +364,10 @@ if __name__ == "__main__":
     if not modules:
         print "unable to list system modules"
     else:
     if not modules:
         print "unable to list system modules"
     else:
-        for type in modules:
-            if type == MODULE_CLASS_SCSI:
-                print( "all scsi modules:" )
-                for a_mod in modules[type]:
-                    print a_mod
-            elif type == MODULE_CLASS_NETWORK:
-                print( "all network modules:" )
-                for a_mod in modules[type]:
-                    print a_mod
+        for module_class in (MODULE_CLASS_SCSI,MODULE_CLASS_NETWORK):
+            if len(modules[module_class]) > 0:
+                module_list = ""
+                for a_mod in modules[module_class]:
+                    module_list = module_list + "%s " % a_mod
+                print "all %s modules: %s" % (module_class, module_list)