File ctc_configure of Package s390-tools
#! /bin/sh
#
# ctc_configure
#
# Configures a CTC device
#
# Usage:
# ctc_configure <read channel> <write channel> <online> [<protocol>]
#
# 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 Invalid device type
# 6 Device type mismatch
# 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
if [ $# -lt 3 ] ; then
echo "Usage: $0 <read channel> <write channel> <online> [<protocol>]"
exit 1
fi
CTC_READ_CHAN=$1
CTC_WRITE_CHAN=$2
ONLINE=$3
CTC_MODE=$4
[ -z "$CTC_MODE" ] && CTC_MODE=0
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 CTC device ${CTC_READ_CHAN}/${CTC_WRITE_CHAN}"
if test ! -d "$_ccw_dir/$CTC_READ_CHAN" ; then
debug_mesg "No device ${CTC_READ_CHAN}"
exit 3
fi
if test ! -d "$_ccw_dir/$CTC_WRITE_CHAN" ; then
debug_mesg "No device ${CTC_WRITE_CHAN}"
exit 4
fi
CCW_CHAN_GROUP=
for ccw in $_ccw_dir/$CTC_READ_CHAN $_ccw_dir/$CTC_WRITE_CHAN; do
read _cu_type < $ccw/cutype
read _dev_type < $ccw/devtype
case "$_cu_type" in
3088/01)
# P/390 network adapter
CCW_CHAN_NAME="cu3088"
CCW_CHAN_GROUP="lcs"
;;
3088/08)
# Channel To Channel
CCW_CHAN_NAME="cu3088"
CCW_CHAN_GROUP="ctcm"
;;
3088/1e)
# FICON adapter
CCW_CHAN_NAME="cu3088"
CCW_CHAN_GROUP="ctcm"
;;
3088/1f)
# ESCON adapter (I.e. hardware CTC device)
CCW_CHAN_NAME="cu3088"
CCW_CHAN_GROUP="ctcm"
;;
3088/60)
# Lan Control Station
CCW_CHAN_NAME="cu3088"
CCW_CHAN_GROUP="lcs"
;;
*)
CCW_CHAN_NAME=
;;
esac
if [ -z "$CCW_CHAN_NAME" ]; then
mesg "No a valid CTC device (cu $_cutype, dev $_devtype)"
exit 5
fi
[ -z "$tmp_chan" ] && tmp_chan=$CCW_CHAN_GROUP
done
if [ "$tmp_chan" != "$CCW_CHAN_GROUP" ] ; then
mesg "CTC type mismatch (read: $tmp_chan, write: $CCW_CHAN_GROUP)"
exit 6
fi
_ccw_groupdir=${SYSFS}/bus/ccwgroup
# Check for modules
if test ! -d "${_ccw_groupdir}/drivers/${CCW_CHAN_GROUP}" ; then
/sbin/modprobe $CCW_CHAN_GROUP
# Re-check whether module loading has succeeded
if test ! -d "${_ccw_groupdir}/drivers/${CCW_CHAN_GROUP}"; then
debug_mesg "Could not load module ${CCW_CHAN_GROUP}"
exit 7
fi
fi
# Check for grouping
_ccw_status_dir=
if [ -e ${_ccw_dir}/${CTC_READ_CHAN}/group_device ] ; then
_ccw_status_dir=$(cd -P ${_ccw_dir}/${CTC_READ_CHAN}/group_device; echo $PWD)
fi
if [ -e ${_ccw_dir}/${CTC_WRITE_CHAN}/group_device ] ; then
_tmp_status_dir=$(cd -P ${_ccw_dir}/${CTC_READ_CHAN}/group_device; echo $PWD)
if [ "$_ccw_status_dir" ] && [ "$_ccw_status_dir" != "$_tmp_status_dir" ] ; then
mesg "CCW devices grouped to different devices"
exit 8
fi
_ccw_status_dir=$_tmp_status_dir
fi
if [ -z "$_ccw_status_dir" ] ; then
echo "$CTC_READ_CHAN,$CTC_WRITE_CHAN" > ${_ccw_groupdir}/drivers/${CCW_CHAN_GROUP}/group
if [ -e ${_ccw_dir}/${CTC_READ_CHAN}/group_device ] ; then
_ccw_status_dir=$(cd -P ${_ccw_dir}/${CTC_READ_CHAN}/group_device; echo $PWD)
fi
fi
if [ -z "$_ccw_status_dir" -o ! -e "$_ccw_status_dir" ] ; then
mesg "Could not group $CCW_CHAN_GROUP devices $CTC_READ_CHAN/$CTC_WRITE_CHAN"
exit 9
fi
CCW_CHAN_ID=${_ccw_status_dir##*/}
read _ccw_dev_status < $_ccw_status_dir/online
if [ "$ONLINE" -eq 1 ]; then
# Check whether we need to do something
if [ "$_ccw_dev_status" -eq 0 ]; then
if [ "$CTC_MODE" -gt 0 ]; then
echo $CTC_MODE > $_ccw_status_dir/protocol
fi
# Set the device online
debug_mesg "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
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 [ "$_ccw_dev_status" -eq 1 ]; then
# Set the device offline
debug_mesg "Setting device offline"
echo "$ONLINE" > $_ccw_status_dir/online
# Re-read to check whether we have succeeded
_ccw_dev_status=$(cat $_ccw_status_dir/online)
if [ "$_ccw_dev_status" -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
# Always reset CTC Protocol
echo 0 > $_ccw_status_dir/protocol
fi
RULES_DIR=/etc/udev/rules.d
RULES_FILE=51-${CCW_CHAN_GROUP}-${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 ${CCW_CHAN_GROUP} device at ${CTC_READ_CHAN}/${CTC_WRITE_CHAN} (Protocol ${CTC_MODE})
ACTION=="add", SUBSYSTEM=="ccw", KERNEL=="$CTC_READ_CHAN", RUN+="/sbin/modprobe --quiet $CCW_CHAN_GROUP"
ACTION=="add", SUBSYSTEM=="ccw", KERNEL=="$CTC_READ_CHAN", IMPORT{program}="collect $CCW_CHAN_ID %k $CTC_READ_CHAN $CTC_WRITE_CHAN $CCW_CHAN_GROUP"
ACTION=="add", SUBSYSTEM=="ccw", KERNEL=="$CTC_WRITE_CHAN", RUN+="/sbin/modprobe --quiet $CCW_CHAN_GROUP"
ACTION=="add", SUBSYSTEM=="ccw", KERNEL=="$CTC_WRITE_CHAN", IMPORT{program}="collect $CCW_CHAN_ID %k $CTC_READ_CHAN $CTC_WRITE_CHAN $CCW_CHAN_GROUP"
ACTION=="add", SUBSYSTEM=="drivers", KERNEL=="$CCW_CHAN_GROUP", IMPORT{program}="collect $CCW_CHAN_ID %k $CTC_READ_CHAN $CTC_WRITE_CHAN $CCW_CHAN_GROUP"
TEST=="[ccwgroup/${CCW_CHAN_ID}]", GOTO="ctc-${CCW_CHAN_ID}-end"
ACTION=="add", SUBSYSTEM=="ccw", ENV{COLLECT_$CCW_CHAN_ID}=="0", ATTR{[drivers/ccwgroup:$CCW_CHAN_GROUP]group}="$CTC_READ_CHAN,$CTC_WRITE_CHAN"
ACTION=="add", SUBSYSTEM=="drivers", KERNEL=="$CCW_CHAN_GROUP", ENV{COLLECT_$CCW_CHAN_ID}=="0", ATTR{group}="$CTC_READ_CHAN,$CTC_WRITE_CHAN"
LABEL="ctc-${CCW_CHAN_ID}-end"
EOF
if [ "$CTC_MODE" -gt 0 ]; then
cat >> ${RULES_DIR}/${RULES_FILE} <<EOF
ACTION=="add", SUBSYSTEM=="ccwgroup", KERNEL=="$CCW_CHAN_ID", ATTR{protocol}="$CTC_MODE"
EOF
fi
cat >> ${RULES_DIR}/${RULES_FILE} <<EOF
ACTION=="add", SUBSYSTEM=="ccwgroup", KERNEL=="$CCW_CHAN_ID", ATTR{online}="1"
EOF
fi
fi