File qeth_configure of Package s390-tools
#! /bin/sh
#
# qeth_configure
#
# Configures a qeth device
#
# Usage:
# qeth_configure <read chan> <write chan> <ctrl chan> <online>
#
# Return values:
# 1 sysfs not mounted
# 2 Invalid status for <online>
# 3 No device found for read channel
# 4 No device found for write channel
# 5 No device found for control channel
# 6 Invalid device type
# 7 Could not load module
# 8 CCW devices grouped different devices
# 9 Could not group devices
# 10 Could not set device online
# 11 Could not set device offline
#
DEBUG=no
mesg () {
echo "$@"
}
debug_mesg () {
case "$DEBUG" in
yes) mesg "$@" ;;
*) ;;
esac
}
# Get the mount point for sysfs
while read MNTPT MNTDIR MNTSYS MNTTYPE; do
if test "$MNTSYS" = "sysfs"; then
SYSFS="$MNTDIR"
break;
fi
done </proc/mounts
if [ -z "$SYSFS" ]; then
exit 1
fi
while [ $# -gt 0 ] ; do
case "$1" in
-i)
# Configure IP takeover
QETH_IPA_TAKEOVER=1
;;
-l)
# Configure Layer2 support
QETH_LAYER2_SUPPORT=1
;;
-p*)
# QETH Portname to use
if [ "$1" = "-p" ] ; then
QETH_PORTNAME=$2
shift
else
QETH_PORTNAME=${1#-p}
fi
;;
-n*)
# QETH port number to use
if [ "$1" = "-n" ] ; then
QETH_PORTNO=$2
shift
else
QETH_PORTNO=${1#-n}
fi
;;
-o)
# General QETH options, separated by spaces
QETH_OPTIONS=$2
shift
;;
*)
break;
;;
esac
shift
done
QETH_READ_CHAN=$1
QETH_WRITE_CHAN=$2
QETH_CTRL_CHAN=$3
ONLINE=$4
if [ $# -lt 4 ] ; then
echo "Usage: $0 [options] <read chan> <write chan> <control chan> <online>"
exit 1
fi
if [ -z "$ONLINE" ] || [ "$ONLINE" -ne "1" -a "$ONLINE" -ne "0" ]; then
debug_mesg "Invalid device status $ONLINE"
exit 2
fi
_ccw_dir=${SYSFS}/bus/ccw/devices
debug_mesg "Configuring QETH device ${QETH_READ_CHAN}/${QETH_WRITE_CHAN}/${QETH_CTRL_CHAN}"
if test ! -d "$_ccw_dir/$QETH_READ_CHAN" ; then
debug_mesg "No device ${QETH_READ_CHAN}"
exit 3
fi
if test ! -d "$_ccw_dir/$QETH_WRITE_CHAN" ; then
debug_mesg "No device ${QETH_WRITE_CHAN}"
exit 4
fi
if test ! -d "$_ccw_dir/$QETH_CTRL_CHAN" ; then
debug_mesg "No device ${QETH_CTRL_CHAN}"
exit 5
fi
CCW_CHAN_GROUP=
for ccw in $_ccw_dir/$QETH_READ_CHAN $_ccw_dir/$QETH_WRITE_CHAN $_ccw_dir/$QETH_CTRL_CHAN; do
read _cu_type < $ccw/cutype
read _dev_type < $ccw/devtype
case "$_cu_type" in
1731/01)
# OSA/Express / Guest LAN
CCW_DRV="qeth"
QETH_CARD="qeth"
;;
1731/05)
# Hipersockets
CCW_DRV="qeth"
QETH_CARD="hsi"
;;
1731/06)
# OSA/N
CCW_DRV="qeth"
QETH_CARD="osn"
;;
*)
CCW_DRV=
;;
esac
if [ -z "$CCW_DRV" ]; then
mesg "No a valid QETH device (cu $_cutype, dev $_devtype)"
exit 6
fi
done
# Portname is only required for OSA/Express
if [ -n "$QETH_PORTNAME" -a "$QETH_CARD" != "qeth" ] ; then
debug_mesg "No portname required for $QETH_CARD adapters"
QETH_PORTNAME=
fi
_ccw_groupdir=${SYSFS}/bus/ccwgroup
# Check for modules
if test ! -d "${_ccw_groupdir}/drivers/${CCW_DRV}" ; then
/sbin/modprobe $CCW_DRV
# Re-check whether module loading has succeeded
if test ! -d "${_ccw_groupdir}/drivers/${CCW_DRV}"; then
debug_mesg "Could not load module ${CCW_DRV}"
exit 7
fi
fi
# Check for grouping
_ccwgroup_dir=
if [ -e ${_ccw_dir}/${QETH_READ_CHAN}/group_device ] ; then
_ccwgroup_dir=$(cd -P ${_ccw_dir}/${QETH_READ_CHAN}/group_device; echo $PWD)
fi
if [ -e ${_ccw_dir}/${QETH_WRITE_CHAN}/group_device ] ; then
_tmp_status_dir=$(cd -P ${_ccw_dir}/${QETH_READ_CHAN}/group_device; echo $PWD)
if [ "$_ccwgroup_dir" ] && [ "$_ccwgroup_dir" != "$_tmp_status_dir" ] ; then
mesg "CCW devices grouped to different devices"
exit 8
fi
_ccwgroup_dir=$_tmp_status_dir
fi
if [ -e ${_ccw_dir}/${QETH_CTRL_CHAN}/group_device ] ; then
_tmp_status_dir=$(cd -P ${_ccw_dir}/${QETH_CTRL_CHAN}/group_device; echo $PWD)
if [ "$_ccwgroup_dir" ] && [ "$_ccwgroup_dir" != "$_tmp_status_dir" ] ; then
mesg "CCW devices grouped to different devices"
exit 8
fi
_ccwgroup_dir=$_tmp_status_dir
fi
if [ -z "$_ccwgroup_dir" ] ; then
echo "$QETH_READ_CHAN,$QETH_WRITE_CHAN,$QETH_CTRL_CHAN" > ${_ccw_groupdir}/drivers/${CCW_DRV}/group
if [ -e ${_ccw_dir}/${QETH_READ_CHAN}/group_device ] ; then
_ccwgroup_dir=$(cd -P ${_ccw_dir}/${QETH_READ_CHAN}/group_device; echo $PWD)
fi
fi
if [ -z "$_ccwgroup_dir" -o ! -e "$_ccwgroup_dir" ] ; then
mesg "Could not group $CCW_DRV devices $QETH_READ_CHAN/$QETH_WRITE_CHAN/$QETH_CTRL_CHAN"
exit 9
fi
CCW_CHAN_ID=${_ccwgroup_dir##*/}
read _online < $_ccwgroup_dir/online
if [ "$ONLINE" -eq 1 ]; then
# Check whether we need to do something
# We do not check for the value of CCW_CHAN_MODE, since we
# might want to switch back and forth between several modes
if test "$_online" -eq "0" ; then
# Set the portname
if [ "$QETH_PORTNAME" ]; then
mesg "(portname $QETH_PORTNAME) "
echo "$QETH_PORTNAME" > $_ccwgroup_dir/portname
fi
# Enable IP address takeover
if [ "$QETH_IPA_TAKEOVER" ]; then
if [ "$QETH_IPA_TAKEOVER" = "1" ]; then
mesg "(IP takeover) "
echo 1 > $_ccwgroup_dir/ipa_takeover/enable
fi
fi
# Activate Layer2 support
if [ -w "$_ccwgroup_dir/layer2" ] ; then
if [ "$QETH_LAYER2_SUPPORT" = "1" ]; then
mesg "(Layer2) "
echo 1 > $_ccwgroup_dir/layer2
else
echo 0 > $_ccwgroup_dir/layer2
fi
else
QETH_LAYER2_SUPPORT=
fi
# Relative port number
if [ -w "$_ccwgroup_dir/portno" ] ; then
if [ -n "$QETH_PORTNO" ]; then
mesg "(Port $QETH_PORTNO) "
# This may fail, but trial and error is the only way to tell.
echo "$QETH_PORTNO" > $_ccwgroup_dir/portno
fi
else
unset QETH_PORTNO
fi
# Set additional options
if [ "$QETH_OPTIONS" ]; then
for opt in $QETH_OPTIONS; do
set -- $(IFS='='; echo $opt)
opt_name=$1
opt_val=$2
case "$opt_name" in
portname|ipa_takeover|layer2)
# These options are set above
debug_mesg "invalid option $opt_name"
;;
*)
if [ "$opt_name" -a "$opt_val" ]; then
if [ -w "$_ccwgroup_dir/$opt_name" ]; then
mesg "($opt_name) "
echo "$opt_val" > $_ccwgroup_dir/$opt_name
if [ $? -gt 0 ] ; then
cur_opts="$cur_opts ${opt_name}=${opt_val}"
fi
else
# Skip invalid options
debug_mesg "invalid option $opt_name"
fi
fi
;;
esac
done
# Update options list
QETH_OPTIONS="$cur_opts"
fi
echo "1" > $_ccwgroup_dir/online
# Re-read device status
read _ccw_dev_status < $_ccwgroup_dir/online
if [ "$_ccw_dev_status" -eq 0 ]; then
mesg "Could not set device ${CCW_CHAN_ID} online"
exit 10
fi
else
debug_mesg "Device ${CCW_CHAN_ID} is already online"
fi
else
if [ "$_online" -eq 1 ]; then
# Set the device offline
debug_mesg "Setting device offline"
echo "$ONLINE" > $_ccwgroup_dir/online
# Re-read to check whether we have succeeded
_online=$(cat $_ccwgroup_dir/online)
if [ "$_online" -ne "$ONLINE" ]; then
debug_mesg "Could not set device ${CCW_CHAN_ID} offline"
exit 11
fi
else
debug_mesg "Device ${CCW_CHAN_ID} is already offline"
fi
echo 1 > $_ccwgroup_dir/ungroup
fi
RULES_DIR=/etc/udev/rules.d
RULES_FILE=51-${QETH_CARD}-${CCW_CHAN_ID}.rules
if [ -d "$RULES_DIR" ]; then
if [ -f ${RULES_DIR}/${RULES_FILE} ]; then
rm -f ${RULES_DIR}/${RULES_FILE}
fi
if [ "$ONLINE" -eq "1" ]; then
# Write a new udev rules file
cat > ${RULES_DIR}/${RULES_FILE} <<EOF
# Configure ${QETH_CARD} device at ${QETH_READ_CHAN}/${QETH_WRITE_CHAN}/${QETH_CTRL_CHAN}
ACTION=="add", SUBSYSTEM=="drivers", KERNEL=="$CCW_DRV", IMPORT{program}="collect $CCW_CHAN_ID %k $QETH_READ_CHAN $QETH_WRITE_CHAN $QETH_CTRL_CHAN $CCW_DRV"
ACTION=="add", SUBSYSTEM=="ccw", KERNEL=="$QETH_READ_CHAN", IMPORT{program}="collect $CCW_CHAN_ID %k $QETH_READ_CHAN $QETH_WRITE_CHAN $QETH_CTRL_CHAN $CCW_DRV"
ACTION=="add", SUBSYSTEM=="ccw", KERNEL=="$QETH_WRITE_CHAN", IMPORT{program}="collect $CCW_CHAN_ID %k $QETH_READ_CHAN $QETH_WRITE_CHAN $QETH_CTRL_CHAN $CCW_DRV"
ACTION=="add", SUBSYSTEM=="ccw", KERNEL=="$QETH_CTRL_CHAN", IMPORT{program}="collect $CCW_CHAN_ID %k $QETH_READ_CHAN $QETH_WRITE_CHAN $QETH_CTRL_CHAN $CCW_DRV"
TEST=="[ccwgroup/${CCW_CHAN_ID}]", GOTO="${QETH_CARD}-${CCW_CHAN_ID}-end"
ACTION=="add", SUBSYSTEM=="ccw", ENV{COLLECT_$CCW_CHAN_ID}=="0", ATTR{[drivers/ccwgroup:$CCW_DRV]group}="$QETH_READ_CHAN,$QETH_WRITE_CHAN,$QETH_CTRL_CHAN"
ACTION=="add", SUBSYSTEM=="drivers", KERNEL=="$CCW_DRV", ENV{COLLECT_$CCW_CHAN_ID}=="0", ATTR{[drivers/ccwgroup:$CCW_DRV]group}="$QETH_READ_CHAN,$QETH_WRITE_CHAN,$QETH_CTRL_CHAN"
LABEL="${QETH_CARD}-${CCW_CHAN_ID}-end"
EOF
if [ "$QETH_PORTNAME" ]; then
cat >> ${RULES_DIR}/${RULES_FILE} <<EOF
ACTION=="add", SUBSYSTEM=="ccwgroup", KERNEL=="$CCW_CHAN_ID", ATTR{portname}="$QETH_PORTNAME"
EOF
fi
if [ "$QETH_PORTNO" ]; then
cat >> ${RULES_DIR}/${RULES_FILE} <<EOF
ACTION=="add", SUBSYSTEM=="ccwgroup", KERNEL=="$CCW_CHAN_ID", ATTR{portno}="$QETH_PORTNO"
EOF
fi
if [ "$QETH_IPA_TAKEOVER" ]; then
cat >> ${RULES_DIR}/${RULES_FILE} <<EOF
ACTION=="add", SUBSYSTEM=="ccwgroup", KERNEL=="$CCW_CHAN_ID", ATTR{ipa_takeover/enable}="1"
EOF
fi
if [ "$QETH_LAYER2_SUPPORT" ]; then
cat >> ${RULES_DIR}/${RULES_FILE} <<EOF
ACTION=="add", SUBSYSTEM=="ccwgroup", KERNEL=="$CCW_CHAN_ID", ATTR{layer2}="1"
EOF
else
cat >> ${RULES_DIR}/${RULES_FILE} <<EOF
ACTION=="add", SUBSYSTEM=="ccwgroup", KERNEL=="$CCW_CHAN_ID", ATTR{layer2}="0"
EOF
fi
for opt in $QETH_OPTIONS; do
set -- $(IFS='='; echo $opt)
opt_name=$1
opt_val=$2
cat >> ${RULES_DIR}/${RULES_FILE} <<EOF
ACTION=="add", SUBSYSTEM=="ccwgroup", KERNEL=="$CCW_CHAN_ID", ATTR{$opt_name}="$opt_val"
EOF
done
cat >> ${RULES_DIR}/${RULES_FILE} <<EOF
ACTION=="add", SUBSYSTEM=="ccwgroup", KERNEL=="$CCW_CHAN_ID", ATTR{online}="1"
EOF
fi
fi