#! /bin/sh # # qeth_configure # # Configures a qeth device # # Usage: # qeth_configure [-i] [-l] [-f -t ] [-o "Values"] -n -p # # -i Configure IP takeover # -l Configure Layer2 support # -f force creation of udev rules, do not check values in /sys # -t Valid cardtypes are: qeth, hsi, osn # -o General QETH options, separated by spaces # -n QETH port number to use, 0 or 1. Only needed for real, not virtual devices. # -p QETH Portname to use. Only needed if sharing a real OSA with z/OS. # read/write/data chan = x.y.ssss where # x is always 0 until IBM creates something that uses that number # y is the logical channel subsystem (lcss) number. Most often this is 0, but it could be non-zero # ssss is the four digit subchannel address of the device, in hexidecimal, with leading zeros. # online = 0 to take the device offline # 1 to bring the device online # # Return values: # 1 sysfs not mounted # 2 Invalid status for # 3 No device found for read channel # 4 No device found for write channel # 5 No device found for data 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 # if [ "${DEBUG}" != "yes" ]; then DEBUG="no" fi QETH_FORCE=0 mesg () { echo "$@" } DATUM=$(date) add_channel_for_cio() { echo "$* # $DATUM" >> /boot/zipl/active_devices.txt } remove_channel_for_cio() { [ -w /boot/zipl/active_devices.txt ] && sed -i -e "/^$1/d" /boot/zipl/active_devices.txt } debug_mesg () { case "$DEBUG" in yes) mesg "$@" ;; *) ;; esac } while [ $# -gt 0 ] ; do case "$1" in -i) # Configure IP takeover QETH_IPA_TAKEOVER=1 ;; -f) # force creation of udev rules, do not check values in /sys QETH_FORCE=1 ;; -l) # Configure Layer2 support QETH_LAYER2_SUPPORT=1 ;; -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 ;; -p*) # QETH Portname to use if [ "$1" = "-p" ] ; then QETH_PORTNAME=$2 shift else QETH_PORTNAME=${1#-p} fi ;; -t*) # Card type. Must be provided if -f is used. if [ "$1" = "-t" ] ; then if [ "$2" = "qeth" -o "$2" = "hsi" -o "$2" = "osn" ]; then QETH_CARD=$2 shift else mesg "Only qeth, hsi and osn are supported." exit 6 fi fi CCW_DRV="$QETH_CARD" ;; *) break; ;; esac shift done if [ $QETH_FORCE -eq 0 ]; then # Get the mount point for sysfs while read MNTPT MNTDIR MNTSYS MNTTYPE; do if test "$MNTSYS" = "sysfs"; then SYSFS="$MNTDIR" break; fi done " echo " -i Configure IP takeover" echo " -l Configure Layer2 support" echo " -f force creation of udev rules, do not check values in /sys" echo " -t Valid cardtypes are: qeth, hsi, osn" echo " -o General QETH options, separated by spaces" echo " -n QETH port number to use, 0 or 1. Only needed for real, not virtual devices." echo " -p QETH Portname to use. Only needed if sharing a real OSA with z/OS." echo " read/write/data chan = x.y.ssss where" echo " x is always 0 until IBM creates something that uses that number" echo " y is the logical channel subsystem (lcss) number. Most often this is 0, but it could be non-zero" echo " ssss is the four digit subchannel address of the device, in hexidecimal, with leading zeros." echo " online = 0 to take the device offline" echo " 1 to bring the device online" exit 1 fi if [ -z "$ONLINE" ] || [ "$ONLINE" -ne "1" -a "$ONLINE" -ne "0" ]; then mesg "Invalid device status $ONLINE" exit 2 fi if [ $QETH_FORCE -eq 0 ]; then _ccw_dir=${SYSFS}/bus/ccw/devices # Convert any hexidecimal numbers to lower case QETH_READ_CHAN=$(echo ${QETH_READ_CHAN} | tr "[A-Z]" "[a-z]") QETH_WRITE_CHAN=$(echo ${QETH_WRITE_CHAN} | tr "[A-Z]" "[a-z]") QETH_DATA_CHAN=$(echo ${QETH_DATA_CHAN} | tr "[A-Z]" "[a-z]") debug_mesg "Configuring QETH device ${QETH_READ_CHAN}/${QETH_WRITE_CHAN}/${QETH_DATA_CHAN}" if test ! -d "$_ccw_dir/$QETH_READ_CHAN" ; then mesg "No device ${QETH_READ_CHAN}" exit 3 fi if test ! -d "$_ccw_dir/$QETH_WRITE_CHAN" ; then mesg "No device ${QETH_WRITE_CHAN}" exit 4 fi if test ! -d "$_ccw_dir/$QETH_DATA_CHAN" ; then mesg "No device ${QETH_DATA_CHAN}" exit 5 fi CCW_CHAN_GROUP= for ccw in $_ccw_dir/$QETH_READ_CHAN $_ccw_dir/$QETH_WRITE_CHAN $_ccw_dir/$QETH_DATA_CHAN; do read _cu_type < $ccw/cutype read _dev_type < $ccw/devtype case "$_cu_type" in 1731/01|1731/02) # 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 "Not a valid QETH device (cu $_cutype, dev $_devtype)" exit 6 fi done fi # end QETH_FORCE # 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 if [ $QETH_FORCE -eq 0 ]; then _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 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_DATA_CHAN}/group_device ] ; then _tmp_status_dir=$(cd -P ${_ccw_dir}/${QETH_DATA_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_DATA_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_DATA_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 # 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 # 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 # 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 [ $? -eq 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 2> /dev/null # 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 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 else CCW_CHAN_ID=$QETH_READ_CHAN fi # QETH_FORCE if [ $DEBUG = "no" ]; then RULES_DIR=/etc/udev/rules.d else RULES_DIR=. fi 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 remove_channel_for_cio "${QETH_READ_CHAN}" remove_channel_for_cio "${QETH_WRITE_CHAN}" remove_channel_for_cio "${QETH_DATA_CHAN}" if [ "$ONLINE" -eq "1" ]; then add_channel_for_cio "${QETH_READ_CHAN},${QETH_WRITE_CHAN},${QETH_DATA_CHAN}" # Write a new udev rules file cat > ${RULES_DIR}/${RULES_FILE} <> ${RULES_DIR}/${RULES_FILE} <> ${RULES_DIR}/${RULES_FILE} <> ${RULES_DIR}/${RULES_FILE} <> ${RULES_DIR}/${RULES_FILE} <> ${RULES_DIR}/${RULES_FILE} <> ${RULES_DIR}/${RULES_FILE} <> ${RULES_DIR}/${RULES_FILE} <