# -*- shell-script -*-

# 21sysfs_hotplug - Definitions and routines relating to sysfs and hotplug.

# This file is part of the Linux lsvpd package.

# (C) Copyright IBM Corp. 2004

# Maintained by Martin Schwenke <martins@au.ibm.com>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    
# $Id: 21sysfs_hotplug,v 1.2 2004/09/13 05:55:56 martins Exp $

[ -n "$sysfs_dir" ] || return 0

######################################################################

add_device_hooks="${add_device_hooks} sysfs_add_device_bus_alias"
make_multiplexed sysfs_add_device_bus_alias

######################################################################

hotplug_add_device ()
{
#set -x
#exec 2>/tmp/lsvpd.hotplug.log

    # Uses: DEVPATH (set by hotplug)

    type="$1"

    local dl="${sysfs_dir}${DEVPATH}/device"
    
    wait_for_node "$dl"
    
    if [ -L "$dl" ] ; then
	local t=$(readlink "$dl")
	cu="${t##*/}" # basename
	add_device "$type" "$cu"
    else
	echo "$0: ${dl} did not appear" >&2
    fi
}

hotplug_remove_device ()
{
#set -x
#exec 2>/tmp/lsvpd.hotplug.log

    # Uses: DEVPATH (set by hotplug)

    type="$1"

    local sysfs_bus_info="${sysfs_dir#/}${DEVPATH}"

    local device_bus_dir=$(bus_alias_get "$sysfs_bus_info")

    bus_alias_clear "$sysfs_bus_info"

    if [ -n "$device_bus_dir" ] ; then
	local bus_info t
	remove_device_hook "$type"
	bus_alias_clear "$bus_info"

	# Remove device OS dir - contains overkill to avoid serious errors.
	t="${device_bus_dir}/linux,os-node"
	t=$(cd "$t" ; pwd -P)
	if [ "$t" = "${t#${db_os_dir}}" ] ; then
	    debug "hotplug_remove_device: bad OS directory \"${t}\"" 
	else
	    rm -rf "$t"
	fi
    
	# Remove $device_bus_dir - contains overkill to avoid serious errors.
	t="$device_bus_dir"
	t=$(cd "$t" ; pwd -P) # FIXME: check if this is needed in general.
	if [ "$t" = "${t#${db_bus_dir}}" ] ; then
	    debug "hotplug_remove_device: bad bus directory \"${t}\"" 
	else
	    rm -rf "$t"
	fi
    fi
}

hotplug_name_and_crosslink ()
{
#set -x
#exec 2>/tmp/lsvpd.crosslink.log
    # Uses: DEVPATH

    type="$1"

    local dl="${sysfs_dir}${DEVPATH}/device"
    
    wait_for_node "$dl"
	
    if [ -L "$dl" ] ; then
	local t=$(readlink "$dl")
	cu="${t##*/}" # basename

	local name=$(get_device_name "$type" "$cu")
	if [ -n "$name" ] ; then
	    local ba="${sysfs_dir#/}${DEVPATH}"
	    local device_bus_dir=$(bus_alias_get "$ba")
	    local adapter_bus_dir="${device_bus_dir%/*}"
	    local t="${adapter_bus_dir}/linux,os-node"
	    # FIXME: Yet another gross hack, just to make this work!
	    while [ ! -L "$t" -a "$adapter_bus_dir" != "/" -a "$adapter_bus_dir" != "" ] ; do
		local adapter_bus_dir="${adapter_bus_dir%/*}"
		local t="${adapter_bus_dir}/linux,os-node"
	    done
	    if [ -L "$t" ] ; then
		t=$(readlink "$t")
		local adapter_os_dir=$(pseudo_realpath "${adapter_bus_dir}/${t}")
		add_device_name_and_crosslink \
		    "$adapter_os_dir" "$name" "$device_bus_dir"
	    fi
	fi
    else
	echo "$0: ${dl} did not appear" >&2
    fi
}
