From 83139cc63667693163a7450e0c6aaea9c2ced5d7 Mon Sep 17 00:00:00 2001 From: Daniel Hokka Zakrisson Date: Wed, 21 Nov 2007 02:32:06 +0000 Subject: [PATCH] Rewrite pl_hwinit in Python. --- conf_files/pl_hwinit | 268 ++++++++++++++++++++----------------------- 1 file changed, 126 insertions(+), 142 deletions(-) diff --git a/conf_files/pl_hwinit b/conf_files/pl_hwinit index 256fe6c..8654708 100755 --- a/conf_files/pl_hwinit +++ b/conf_files/pl_hwinit @@ -1,142 +1,126 @@ -#!/bin/sh - -pci_table=/etc/pl_pcitable - -loaded_module_list=/tmp/loadedmodules - -echo "pl_hwinit: loading applicable modules" - -echo > $loaded_module_list - -# this will contain lines of device_id:vendor_id (no 0x) -system_devices=$(lspci -n | cut -d " " -f4) - -for device in $system_devices; do - - # now vendor_id and device_id are broken apart - vendor_id=$(echo $device | cut -d ":" -f1) - device_id=$(echo $device | cut -d ":" -f2) - - # either exactly match vendor:device, or a vendor:ffff (let the module - # figure out if it can be used for this device), or ffff:device - # (not sure if this is legal, but shows up in the pci map) - mods=$(grep -i "\($vendor_id:ffff\|$vendor_id:$device_id\|ffff:$device_id\)" \ - $pci_table | cut -d " " -f1) - - for module in $mods; do - if [ -n "$module" ]; then - echo "pl_hwinit: found and loading module $module" - /sbin/modprobe $module - echo $module >> $loaded_module_list - fi - done -done - -# just in case, look for any modules that are ffff:ffff and load them -mods=$(grep -i "ffff:ffff" $pci_table | cut -d " " -f1) -for module in $mods; do - if [ -n "$module" ]; then - echo "pl_hwinit: found and loading wild module $module" - /sbin/modprobe $module - fi -done - -# sd_mod won't get loaded automatically -echo "pl_hwinit: loading sd_mod" -/sbin/modprobe sd_mod - -# load usb_storage to support node conf files on flash disks -echo "pl_hwinit: loading usb_storage" -/sbin/modprobe usb_storage - -echo "pl_hwinit: loading floppy device driver" -/sbin/modprobe floppy - -# always wait a bit between loading the usb drivers, and checking /sys/ -# for usb devices (this isn't necessarily for waiting for mass storage files, -# that is done below) -echo "pl_hwinit: waiting for usb system to initialize." -/bin/sleep 10s - -# sometimes, flash devices take a while to initialize. in fact, the kernel -# intentionally waits 5 seconds for a device to 'settle'. some take even longer -# to show up. if there are any mass storage devices on the system, try to -# delay until they come online, up to a max delay of 30s. - -# the way this will be done is to look for files in /sys/devices that are named -# 'bInterfaceClass', these will be a list of the usb devices on the system, and -# their primary usb device interface class ids. The base directory these files -# exist in will be the full path to the /sys/device entry for that device. -# for each mass storage devices (they have an interface class value of 08), -# we wait for a new symbolic link named 'driver' to exist in that directory, -# indicating the kernel loaded a driver for that device. - -# usb interface class id for mass storage -INTERFACE_CLASS_MASS_STORAGE="08" - -# how long to wait in seconds before continuing on if devices -# aren't available -MAX_USB_WAIT_TIME=30 - -# low long in seconds to wait between checks -PER_CHECK_USB_WAIT_TIME=5 - - -# find out if the device identified by the /sys dir has a module -# loaded for it. check for a symlink in the dir named driver. -function does_device_dir_have_driver() -{ - if [[ -h "$1/driver" ]]; then - return 1 - else - return 0 - fi -} - -wait_dev_list="" -for interface_class_file in `find /sys/devices -name 'bInterfaceClass'`; do - interface_class=`cat $interface_class_file` - if [[ "$interface_class" == $INTERFACE_CLASS_MASS_STORAGE ]]; then - wait_dev_list="$wait_dev_list "`dirname $interface_class_file` - fi -done - -if [[ -n "$wait_dev_list" ]]; then - echo "pl_hwinit: found USB mass storage device(s). Attempting to wait" - echo "pl_hwinit: up to $MAX_USB_WAIT_TIME seconds for them to come online." - - total_wait_time=0 - success=0 - while [[ $total_wait_time < $MAX_USB_WAIT_TIME ]]; do - - total_wait_time=$(($total_wait_time+$PER_CHECK_USB_WAIT_TIME)) - - echo "pl_hwinit: waiting $PER_CHECK_USB_WAIT_TIME seconds." - /bin/sleep $PER_CHECK_USB_WAIT_TIME - - all_devices_online=1 - for device_dir in $wait_dev_list; do - does_device_dir_have_driver $device_dir - if [[ "$?" -eq 0 ]]; then - all_devices_online=0 - fi - done - - if [[ $all_devices_online -eq 1 ]]; then - success=1 - echo "pl_hwinit: looks like the devices are now online." - break; - else - echo "pl_hwinit: not all devices online yet, waiting..." - fi - done - - if [[ $success -eq 1 ]]; then - echo "pl_hwinit: Succesfully waited for USB mass storage devices" - echo "pl_hwinit: to come online." - else - echo "pl_hwinit: One or more USB mass storage devices did not" - echo "pl_hwinit: initialize in time. Continuing anyway." - fi -fi - +#!/usr/bin/python + +import sys +import pypciscan +import pypcimap +import os +import time + +def modprobe(module): + ret = os.system("/sbin/modprobe %s" % module) + return os.WEXITSTATUS(ret) == 0 + +def main(argv): + if len(argv) == 0: + kernel = os.uname()[2] + else: + kernel = argv[0] + + if os.path.exists(kernel): + path = kernel + else: + path = "/lib/modules/%s/modules.pcimap" % kernel + + pcimap = pypcimap.PCIMap(path) + print "pl_hwinit: loading applicable modules" + devices = pypciscan.get_devices() + missing = [] + for (slot, dev) in devices.iteritems(): + modules = pcimap.get(dev) + if len(modules) == 0: + base = (dev[4] & 0xff00) >> 8 + if base == 0x01 or base == 0x02: + # storage or network device, in that order + missing.append((slot, dev)) + else: + # FIXME: This needs improved logic in the case of multiple matching modules + for module in modules: + modprobe(module) + + # sd_mod won't get loaded automatically + print "pl_hwinit: loading sd_mod" + modprobe("sd_mod") + + # load usb_storage to support node conf files on flash disks + print "pl_hwinit: loading usb_storage" + modprobe("usb_storage") + + print "pl_hwinit: loading floppy device driver" + modprobe("floppy") + + # always wait a bit between loading the usb drivers, and checking /sys/ + # for usb devices (this isn't necessarily for waiting for mass storage files, + # that is done below) + print "pl_hwinit: waiting for usb system to initialize." + time.sleep(10) + + # sometimes, flash devices take a while to initialize. in fact, the kernel + # intentionally waits 5 seconds for a device to 'settle'. some take even longer + # to show up. if there are any mass storage devices on the system, try to + # delay until they come online, up to a max delay of 30s. + + # the way this will be done is to look for files in /sys/devices that are named + # 'bInterfaceClass', these will be a list of the usb devices on the system, and + # their primary usb device interface class ids. The base directory these files + # exist in will be the full path to the /sys/device entry for that device. + # for each mass storage devices (they have an interface class value of 08), + # we wait for a new symbolic link named 'driver' to exist in that directory, + # indicating the kernel loaded a driver for that device. + + # usb interface class id for mass storage + INTERFACE_CLASS_MASS_STORAGE = "08" + + # how long to wait in seconds before continuing on if devices + # aren't available + MAX_USB_WAIT_TIME = 30 + + # low long in seconds to wait between checks + PER_CHECK_USB_WAIT_TIME = 5 + + + # find out if the device identified by the /sys dir has a module + # loaded for it. check for a symlink in the dir named driver. + def does_device_dir_have_driver(device): + return os.path.exists(os.path.join(device, "driver")) + + def filter_and_add(list, directory, files): + if ("bInterfaceClass" in files and + int(file(os.path.join(directory, "bInterfaceClass")).read(), 16) == INTERFACE_CLASS_MASS_STORAGE): + list.append(directory) + + wait_dev_list = [] + os.path.walk("/sys/devices", filter_and_add, wait_dev_list) + + if len(wait_dev_list) > 0: + print "pl_hwinit: found USB mass storage device(s). Attempting to wait" + print "pl_hwinit: up to %d seconds for them to come online." % MAX_USB_WAIT_TIME + + total_wait_time = 0 + success = False + while total_wait_time < MAX_USB_WAIT_TIME: + total_wait_time += PER_CHECK_USB_WAIT_TIME + + print "pl_hwinit: waiting %d seconds." % PER_CHECK_USB_WAIT_TIME + time.sleep(PER_CHECK_USB_WAIT_TIME) + + all_devices_online = True + for device in wait_dev_list: + if not does_device_dir_have_driver(device): + all_devices_online = False + + if all_devices_online: + success = True + print "pl_hwinit: looks like the devices are now online." + break + else: + print "pl_hwinit: not all devices online yet, waiting..." + + if success: + print "pl_hwinit: Succesfully waited for USB mass storage devices" + print "pl_hwinit: to come online." + else: + print "pl_hwinit: One or more USB mass storage devices did not" + print "pl_hwinit: initialize in time. Continuing anyway." + +if __name__ == "__main__": + main(sys.argv[1:]) -- 2.43.0