#!/bin/sh # # PCI-specific hotplug policy agent. # # This should handle 2.4.* PCI (including Cardbus) hotplugging, # with a consistent framework for adding device and driver specific # treatments. # # Kernel Cardbus/PCI params are: # # ACTION=%s [add or remove] # PCI_CLASS=%06X # PCI_ID=%04X:%04X # PCI_SLOT_NAME=%s # PCI_SUBSYS_ID=%04X:%04X # # If /proc is mounted, /proc/bus/pci/$PCI_SLOT_NAME is almost the name # of the binary device descriptor file ... just change ':' to '/'. # # On systems using Linux 2.4.* kernels, be sure to use the right # modutils (2.4.1+). # # # HISTORY: # # 26-Feb-2001 Cleanup, support comments (Gioele Barabucci) # 13-Jan-2001 Initial version of "new" hotplug agent; needs # retesting. # 17-Jan-2001 Update to latest kernel syntax (Dan Zink) # 15-Feb-2001 Remove use of "<<" (Adam Richter) # # $Id: pci.agent,v 1.15 2004/03/26 22:36:38 kroah Exp $ # cd /etc/hotplug . ./hotplug.functions # generated by modutils, for current 2.4.x kernels MAP_CURRENT=$MODULE_DIR/modules.pcimap # accumulates list of modules we may care about DRIVERS= if [ "$PCI_CLASS" = "" -o "$PCI_CLASS" = "" ]; then mesg Bad PCI agent invocation exit 1 fi # # Each modules.usbmap format line corresponds to one entry in a # MODULE_DEVICE_TABLE(pci,...) declaration in a kernel file. # # Think of it as a database column with up to three "match specs" # to associate kernel modules with particular devices or classes # of device. The match specs provide a reasonably good filtering # mechanism, but some driver probe() routines need to provide # extra filtering. # pci_convert_vars () { pci_class=$((0x$PCI_CLASS)) set $(echo $PCI_ID | sed -e 's/\([^:]*\):\(.*\)/\1 \2/') pci_id_vendor=$((0x$1)) pci_id_device=$((0x$2)) set $(echo $PCI_SUBSYS_ID | sed -e 's/\([^:]*\):\(.*\)/\1 \2/') pci_subid_vendor=$((0x$1)) pci_subid_device=$((0x$2)) } PCI_ANY=$((0xffffffff)) # # stdin is "modules.pcimap" syntax # on return, ONE matching module was added to $DRIVERS # pci_map_modules () { local module ignored # comment line lists (current) pci_device_id field names read ignored # look at each pci_device_id entry # collect one match in $DRIVERS while read module vendor device subvendor subdevice class class_mask ignored do # comments are lines that start with "#" ... # be careful, they still get parsed by bash! case "$module" in \#*) continue ;; esac # convert the fields from hex to dec vendor=$(($vendor)); device=$(($device)) subvendor=$(($subvendor)); subdevice=$(($subdevice)) class=$(($class)); class_mask=$(($class_mask)) : checkmatch $module : vendor $vendor $pci_id_vendor if [ $vendor -ne $PCI_ANY -a $vendor -ne $pci_id_vendor ]; then continue fi : device $device $pci_id_device if [ $device -ne $PCI_ANY -a $device -ne $pci_id_device ]; then continue fi : sub-vendor $subvendor $pci_subid_vendor if [ $subvendor -ne $PCI_ANY -a $subvendor -ne $pci_subid_vendor ]; then continue fi : sub-device $subdevice $pci_subid_device if [ $subdevice -ne $PCI_ANY -a $subdevice -ne $pci_subid_device ]; then continue fi class_temp=$(($pci_class & $class_mask)) if [ $class_temp -eq $class ]; then DRIVERS="$module $DRIVERS" : drivers $DRIVERS break fi done } # # What to do with this PCI hotplug event? # case $ACTION in add) pci_convert_vars LABEL="PCI slot $PCI_SLOT_NAME" # on 2.4 systems, modutils maintains MAP_CURRENT if [ -r $MAP_CURRENT ]; then load_drivers pci $MAP_CURRENT "$LABEL" fi if [ "$DRIVERS" = "" ]; then debug_mesg "... no modules for $LABEL" exit 2 fi ;; *) debug_mesg PCI $ACTION event not supported exit 1 ;; esac