#!/bin/sh
#
# serio-specific hotplug policy agent.
#
# This should handle 2.6.* serio port hotplugging.
# with a consistent framework for adding device and driver specific
# treatments.
#
# Kernel serio params are:
#
#	ACTION=%s [add or remove]
#	SERIO_TYPE=%02x
#	SERIO_PROTO=%02x
#	SERIO_ID=%02X
#	SERIO_EXTRA=%02x
#
# HISTORY:
#	23-Jan-2005	Initial version by Dmitry Torokhov <dtor@mail.ru>

cd /etc/hotplug
. ./hotplug.functions

# DEBUG=yes export DEBUG

# generated by modutils
MAP_CURRENT=$MODULE_DIR/modules.seriomap

# accumulates list of modules we may care about
DRIVERS=

if [ "$ACTION" = "" ]; then
    mesg Bad serio agent invocation
    exit 1
fi

#
# Each modules.seriomap format line corresponds to one entry in a
# MODULE_DEVICE_TABLE(serio,...) 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.
#

serio_convert_vars ()
{
    serio_id_type=$((0x$SERIO_TYPE))
    serio_id_extra=$((0x$SERIO_EXTRA))
    serio_id_id=$((0x$SERIO_ID))
    serio_id_proto=$((0x$SERIO_PROTO))
}

SERIO_ANY=$((0xff))

#
# stdin is "modules.seriomap" syntax
# on return, all matching modules were added to $DRIVERS
#
serio_map_modules ()
{
    local module ignored

    # comment line lists (current) serio_device_id field names
    read ignored

    # look at each pci_device_id entry
    # collect one match in $DRIVERS
    while read module type extra id proto 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
	type=$(($type));
	extra=$(($extra))
	id=$(($id));
	proto=$(($proto))

	: check match for $module

	: type $type $serio_id_type
	if [ $type -ne $SERIO_ANY -a $type -ne $serio_id_type ]; then
	    continue
	fi
	: extra $extra $serio_id_extra
	if [ $extra -ne $SERIO_ANY -a $extra -ne $serio_id_extra ]; then
	    continue
	fi
	: id $id $serio_id_id
	if [ $id -ne $SERIO_ANY -a $id -ne $serio_id_id ]; then
	    continue
	fi
	: protocol $proto $pci_id_proto
	if [ $proto -ne $SERIO_ANY -a $proto -ne $serio_id_proto ]; then
	    continue
	fi

	DRIVERS="$module $DRIVERS"
	debug_mesg serio.agent $DRIVRES
	: drivers $DRIVERS
    done
}


#
# What to do with this PCI hotplug event?
#
case $ACTION in

add)
    serio_convert_vars

    LABEL="SERIO port 0x$SERIO_TYPE/0x$SERIO_PROTO/0x$SERIO_ID/0x$SERIO_EXTRA"

    if [ -r $MAP_CURRENT ]; then
    	load_drivers serio $MAP_CURRENT "$LABEL"
    fi

    if [ "$DRIVERS" = "" ]; then
	debug_mesg "... no modules for $LABEL"
	exit 2
    fi
    ;;

remove)
    : nothing so far

    ;;

*)
    debug_mesg SERIO $ACTION event not supported
    exit 1
    ;;

esac
