-#!/usr/bin/python2
+#!/usr/bin/python
# Copyright (c) 2003 Intel Corporation
# All rights reserved.
import sys
import os
import popen2
-import merge_hw_tables
import re
import errno
import ModelOptions
+from pypci 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
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"
-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):
"""
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):
"""
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.dep
If there are more than one kernels installed, and the kernel
version is not specified, then only the first one in
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_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
+ pcimap = pypcimap.PCIMap(modules_pcimap_path)
+
# this is the actual data structure we return
system_mods= {}
network_mods= []
scsi_mods= []
+ # XXX: this is really similar to what BootCD/conf_files/pl_hwinit does. merge?
+ pcidevs = get_devices()
+
+ devlist=pcidevs.keys()
+ devlist.sort()
+ for slot in devlist:
+ dev = pcidevs[slot]
+ base = (dev[4] & 0xff0000) >> 16
+ modules = pcimap.get(dev)
+ if base not in (PCI_BASE_CLASS_STORAGE,
+ PCI_BASE_CLASS_NETWORK):
+ # special exception for forcedeth NICs whose base id
+ # claims to be a Bridge, even though it is clearly a
+ # network device
+ if "forcedeth" in modules:
+ base=PCI_BASE_CLASS_NETWORK
+ else:
+ continue
- # 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):
- 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
+ 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
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)