#!/bin/bash
#
# Configures a ccw interface.
# $Id: hwup-ccw,v 1.9 2004/04/29 15:08:54 hare Exp $
#
# Detects all ccw devices as per modules.ccwmap
# (current as of 2.6.3)
#
# Should be called from /sbin/hwup with the
# hardware configuration as argument
#
# The hardware configuration should look like
# <type>-bus-<bus>-<id>
# e.g.
# 'hwup-ccw dasd-bus-ccw-0.0.0190'
# 
# Programs called from this script:
#  echo
#  expr
#  test
#

SCRIPTNAME=${0##*/}
CONFIG=$1
HWDESC=$2

# Read in common functions
. ./scripts/functions


if test -z "$SYSFS"; then
    mesg sysfs not mounted, aborting.
    exit 1
fi

# Read in the configuration file
. ./hwcfg-${CONFIG}

# Set defaults
if [ -z "$HWD_DEVPATH" ]; then
    HWD_DEVPATH=${SYSFS}/bus/ccw/devices/${HWD_BUSID}
fi

if [ ! -d "$HWD_DEVPATH" ]; then
    message "$SCRIPTNAME: No hardware devicepath given, cannot configure"
    exit 1
fi

# Check for the attached control unit and device type
read _cu_type < $HWD_DEVPATH/cutype
read _dev_type < $HWD_DEVPATH/devtype

#
# This checks for all known control units and device types.
# Information is from /lib/modules/<kversion>/modules.ccwmap
#
if [ -z "$CCW_CHAN_NAME" ] ; then
    CCW_CHAN_GROUP=
    CCW_CHAN_NUM=
    case "$_cu_type" in
	3088/01)
	    # P/390 network adapter (Not testet)
	    CCW_CHAN_NAME="cu3088"
	    CCW_CHAN_GROUP="p390"
	    CCW_CHAN_NUM=2
	    ;;
	3088/08)
	    # Channel To Channel
	    CCW_CHAN_NAME="cu3088"
	    CCW_CHAN_GROUP="ctc"
	    CCW_CHAN_NUM=2
	    ;;
	3088/1e)
	    # FICON adapter (Not testet)
	    CCW_CHAN_NAME="cu3088"
	    CCW_CHAN_GROUP="ficon"
	    CCW_CHAN_NUM=2
	    ;;
	3088/1f)
	    # ESCON adapter (Not testet)
	    CCW_CHAN_NAME="cu3088"
	    CCW_CHAN_GROUP="escon"
	    CCW_CHAN_NUM=2
	    ;;
	3088/60)
	    # Lan Control Station (Not testet)
	    CCW_CHAN_NAME="cu3088"
	    CCW_CHAN_GROUP="lcs"
	    CCW_CHAN_NUM=2
	    ;;
	1731/01|1731/05)
	    # OSA/Express or Guest LAN
	    CCW_CHAN_NAME="qeth"
	    CCW_CHAN_NUM=3
	    ;;
	1731/03)
	    # zFCP adapter
	    if [ "$_dev_type" == "1732/03" -o "$_dev_type" == "1732/04" ]; then
		CCW_CHAN_NAME="zfcp"
	    else
		CCW_CHAN_NAME=
	    fi
	    ;;
	3480/*|3490/*)
	    # IBM 3480/3490 tape driver
	    if [ "$_dev_type" == "$_cu_type" ]; then
		CCW_CHAN_NAME="tape-34xx"
	    else
		CCW_CHAN_NAME=
	    fi
	    ;;
	3990/*|2105/*|9343/*)
	    # DASD (ECKD mode)
	    CCW_CHAN_NAME="dasd-eckd"
	    ;;
	6310/*)
	    # DASD (FBA mode)
	    CCW_CHAN_NAME="dasd-fba"
	    ;;
	3880/*)
	    case "$_dev_type" in
		3390/*)
	            # DASD (ECKD mode)
		    CCW_CHAN_NAME="dasd-eckd"
		    ;;
		3370/*)
	            # DASD (FBA mode)
		    CCW_CHAN_NAME="dasd-fba"
		    ;;
		*)
		    CCW_CHAN_NAME=
		    ;;
	    esac
	    ;;
	*)
	    CCW_CHAN_NAME=
	    ;;
    esac
fi

# Unknown device
if [ -z "$CCW_CHAN_NAME" ]; then
    message "$SCRIPTNAME: Invalid device type (cu ${_cu_type} dev ${_dev_type}"
    exit 1
fi

# Set defaults
if test -z "$CCW_CHAN_GROUP"; then
    CCW_CHAN_GROUP="$CCW_CHAN_NAME"
fi
if test -z "$CCW_CHAN_NUM"; then
    CCW_CHAN_NUM="1"
fi
if test -z "$CCW_CHAN_IDS"; then
    CCW_CHAN_IDS="$HWD_BUSID"
fi

# Set sysfs paths
_ccw_dir=${SYSFS}/bus/ccw/drivers/${CCW_CHAN_NAME}
_ccwgroup_dir=${SYSFS}/bus/ccwgroup/drivers/${CCW_CHAN_GROUP}

if [ -z "$CCW_CHAN_IDS" ] ; then
    message "$SCRIPTNAME: no channel IDs given"
    exit 1
fi

# Checking channel availability

# Check whether we need to configure the channel group
if test "$CCW_CHAN_NUM" -gt 1 ; then
    set -- $CCW_CHAN_IDS
    CCW_CHAN_GROUPID=$1
    
    if test -d "$_ccwgroup_dir/$CCW_CHAN_GROUPID" ; then
	# Device group already configured
	debug "Device group $CCW_CHAN_GROUPID already configured!"
    else
	debug "Checking group ${CCW_CHAN_GROUPID}"
	
        # Check whether all channels for this device are accessible
	num=0
	for _ccw_file in $CCW_CHAN_IDS; do
	    if test ! -d "${_ccw_dir}/${_ccw_file}" ; then
		_ccw_group_lst=
		break;
	    fi
	    _ccw_group_lst="${_ccw_group_lst:-${_ccw_file}}${_ccw_group_lst:+,${_ccw_file}}"
	    num=$(expr $num + 1)
	done
	
        # Configure the channel group
	# Note that the non-existence of channels is not a failure;
	# if we were called during start-up it might well be that
	# not all channels are available yet.
	if test "$num" -lt "$CCW_CHAN_NUM" ; then 
	    if test -z "$_ccw_group_lst" ; then
		message "$SCRIPTNAME: Device group ${CCW_CHAN_GROUPID} not (yet) available!"
	    else
		message "$SCRIPTNAME: Not enough channels for this device!"
	    fi
	else
	    message "$SCRIPTNAME: Configuring group ${CCW_CHAN_GROUPID}"
	    echo $_ccw_group_lst > $_ccwgroup_dir/group
	fi
    fi
else
    message "$SCRIPTNAME: Configuring device ${CCW_CHAN_IDS}"
    _ccw_status_dir="$_ccw_dir/$CCW_CHAN_IDS"
    # Set the device online
    if test -d "$_ccw_status_dir" ; then
	read _ccw_dev_online < $_ccw_status_dir/online
	if [ $_ccw_dev_online -eq 0 ]; then
            # DIAG access for DASDs
            # Need to be done prior to activation
	    case "$CCW_CHAN_NAME" in
		dasd-*)
		    if [ "$DASD_USE_DIAG" -eq 1 ]; then
			debug "Activating DIAG access mode"
			echo 1 > $_ccw_status_dir/use_diag
	                # Set the device online
			debug "Setting device online"
			echo "1" > $_ccw_status_dir/online
                        # Re-read device status
			read _ccw_dev_status < $_ccw_status_dir/online
			if [ "$_ccw_dev_status" -eq 0 ]; then
			    message "$SCRIPTNAME: Could not activate DIAG access mode for device ${CCW_CHAN_ID}"
			    echo 0 > $_ccw_status_dir/use_diag
	                    # Set the device online
			    debug "Setting device online"
			    echo "1" > $_ccw_status_dir/online
			fi
		    fi
		    ;;
		*)
		    debug "Setting device online"
		    echo "1" > $_ccw_status_dir/online
		    ;;
	    esac
	fi
    else
	message "$SCRIPTNAME: Failed to configure device ${CCW_CHAN_IDS}"
    fi
fi
