From patchwork Mon Jul 11 14:02:24 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian King X-Patchwork-Id: 104212 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (localhost [IPv6:::1]) by ozlabs.org (Postfix) with ESMTP id 94D09100837 for ; Tue, 12 Jul 2011 00:02:58 +1000 (EST) Received: from e8.ny.us.ibm.com (e8.ny.us.ibm.com [32.97.182.138]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "e8.ny.us.ibm.com", Issuer "Equifax" (not verified)) by ozlabs.org (Postfix) with ESMTPS id B237BB6F6F for ; Tue, 12 Jul 2011 00:02:55 +1000 (EST) Received: from d01relay05.pok.ibm.com (d01relay05.pok.ibm.com [9.56.227.237]) by e8.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p6BDoES1028794 for ; Mon, 11 Jul 2011 09:50:14 -0400 Received: from d01av02.pok.ibm.com (d01av02.pok.ibm.com [9.56.224.216]) by d01relay05.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p6BE2SjZ155386 for ; Mon, 11 Jul 2011 10:02:28 -0400 Received: from d01av02.pok.ibm.com (loopback [127.0.0.1]) by d01av02.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p6BE2Q6n005246 for ; Mon, 11 Jul 2011 11:02:27 -0300 Received: from localhost.localdomain (sig-9-49-189-235.mts.ibm.com [9.49.189.235]) by d01av02.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p6BE2MTS004408; Mon, 11 Jul 2011 11:02:23 -0300 Message-Id: <201107111402.p6BE2MTS004408@d01av02.pok.ibm.com> Subject: [PATCH 1/5] ofpath: Add support for VSCSI, VFC, and SAS To: yaboot-devel@lists.ozlabs.org From: Brian King Date: Mon, 11 Jul 2011 09:02:24 -0500 X-BeenThere: yaboot-devel@lists.ozlabs.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Technical and development discussion regarding yaboot List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: yaboot-devel-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: yaboot-devel-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Adds support to ofpath for Virtual SCSI, Virtual Fibre Channel, and SAS devices on IBM Power Systems. Signed-off-by: Brian King --- ybin/ofpath | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 202 insertions(+), 4 deletions(-) diff -puN ybin/ofpath~ofpath_vscsi ybin/ofpath --- yaboot/ybin/ofpath~ofpath_vscsi 2011-06-20 16:12:33.000000000 -0500 +++ yaboot-bjking1/ybin/ofpath 2011-06-24 12:56:40.000000000 -0500 @@ -242,10 +242,18 @@ scsiinfo() DEVTYPE="$(v=$(echo ${DEVINFO##*Type: }) ; echo ${v%% *})" [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVTYPE=$DEVTYPE" + ## get the device LUN. + DEVLUN="$(v=$(echo ${DEVINFO##*Lun: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})" + [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVLUN=$DEVLUN" + ## get the device id. DEVID="$(v=$(echo ${DEVINFO##*Id: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})" [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVID=$DEVID" + ## get the device bus. + DEVBUS="$(v=$(echo ${DEVINFO##*Channel: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})" + [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVBUS=$DEVBUS" + ## get the scsi host id. DEVHOST="$(v=$(echo ${DEVINFO##*Host: scsi}) ; echo ${v%% *})" [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVHOST=$DEVHOST" @@ -255,7 +263,9 @@ scsiinfo() [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVCOUNT=$DEVCOUNT" if [ "$SUBDEV" = "$DEVCOUNT" ] ; then DEVICE_HOST=$DEVHOST + DEVICE_BUS=$DEVBUS DEVICE_ID=$DEVID + DEVICE_LUN=$DEVLUN [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVICE_HOST=$DEVICE_HOST" break fi @@ -274,6 +284,190 @@ scsiinfo() return 0 } +read_attr() +{ + local ATTR=$1 + local START=$2 + local OLDDIR=$(pwd) + local RET + + cd -P "$START" + while [[ $PWD != "/" ]]; do + ls $ATTR > /dev/null 2>&1 + if [[ $? -eq 0 ]]; then + RET=$(cat $ATTR) + cd $OLDDIR + echo "$RET" + return 0 + fi + cd .. + done + + cd $OLDDIR + echo 1>&2 "$PRG: Cannot find $RET for $DEVICE" + exit 1 +} + +read_dev_attr() +{ + local ATTR=$1 + local DEVICE="$DEVICE_HOST:$DEVICE_BUS:$DEVICE_ID:$DEVICE_LUN" + local START="/sys/bus/scsi/devices/$DEVICE" + + read_attr $ATTR $START +} + +read_parent_attr() +{ + local ATTR=$1 + local DEVICE="$DEVICE_HOST:$DEVICE_BUS:$DEVICE_ID:$DEVICE_LUN" + local START="/sys/bus/scsi/devices/$DEVICE/.." + + read_attr $ATTR $START +} + +get_vdisk_lun() +{ + local B C D + typeset -i B C D + + B=$((0x$DEVICE_ID << 8)) + C=$((0x$DEVICE_BUS << 5)) + D=$((0x$DEVICE_LUN)) + + local vdiskno vdisk + typeset -i vdiskno + vdiskno=$((0x8000 | $B | $C | $D )) + vdisk=${vdiskno##-} + + vdisk=$(printf "%x" $vdisk) + local extrazeroes="000000000000" + echo $vdisk$extrazeroes +} + +int_to_scsilun() +{ + local lunint=$1 + local A B C D + + A=$(( ($lunint >> 8) & 0xff )) + B=$(($lunint & 0xff)) + C=$(( ($lunint >> 24) & 0xff )) + D=$(( ($lunint >> 16) & 0xff )) + + local lunstr=$(printf "%02x%02x%02x%02x00000000" $A $B $C $D) + lunstr=$(echo $lunstr | sed 's/^[0]*//') + echo "$lunstr" +} + +get_fc_scsilun() +{ + local L=$(echo "$DEVICE_LUN"|gawk '{$1=tolower($1);print}') + L=$(printf "%d" $L) + + local fc_lun=$(int_to_scsilun $L) + echo "$fc_lun" +} + +get_fc_wwpn() +{ + local start_dir=$1 + + for f in `find -H $start_dir -maxdepth 2 -name port_name`; do + local wwpn=$(cat $f) + break + done + + # strip the leading 0x + wwpn=${wwpn:2} + echo "$wwpn" +} + +scsi_ofpath2() +{ + local DEVSPEC=$(read_parent_attr devspec) + local COMPAT=$(cat "/proc/device-tree$DEVSPEC/compatible") + local DEVICE_PATH="/sys/bus/scsi/devices/$DEVICE_HOST:$DEVICE_BUS:$DEVICE_ID:$DEVICE_LUN" + + case "$COMPAT" in + IBM,v-scsi) + local vdisk=$(get_vdisk_lun) + if [[ $PARTITION = "" ]]; then + echo "$DEVSPEC/disk@$vdisk" + else + echo "$DEVSPEC/disk@$vdisk:$PARTITION" + fi + return 0 + ;; + IBM,vfc-client) + local vfc_lun=$(get_fc_scsilun) + local wwpn=$(get_fc_wwpn "$DEVICE_PATH/../../fc_remote_ports*") + if [[ $DEVICE_LUN != "0" ]]; then + local vfc_lun=$(get_fc_scsilun) + echo "$DEVSPEC/disk@$wwpn,$vfc_lun" + else + echo "$DEVSPEC/disk@$wwpn" + fi + return 0 + ;; + *) + ;; + esac + + if [[ -d "/proc/device-tree$DEVSPEC/sas" ]]; then + local vendor_id=$(read_parent_attr vendor) + local sas_addr + + if [[ $vendor_id = "0x1000" ]]; then + sas_addr=$(read_dev_attr sas_address) + sas_addr=${sas_addr##0x} + if [[ $DEVICE_LUN != "0" ]]; then + local LUN=$(int_to_scsilun $DEVICE_LUN) + echo "$DEVSPEC/sas/disk@$sas_addr,$LUN" + else + echo "$DEVSPEC/sas/disk@$sas_addr" + fi + return 0 + fi + + local fwtype="0" + if [[ -e /sys/class/scsi_host/host$DEVICE_HOST/fw_type ]]; then + fwtype=$(cat /sys/class/scsi_host/host$DEVICE_HOST/fw_type) + fi + + if [[ $fwtype = "1" ]]; then + sas_addr=$(read_dev_attr device_id) + sas_addr=${sas_addr##0x} + if [[ $DEVICE_LUN != "0" ]]; then + local LUN=$(int_to_scsilun $DEVICE_LUN) + echo "$DEVSPEC/sas/disk@$sas_addr,$LUN" + else + echo "$DEVSPEC/sas/disk@$sas_addr" + fi + else + local B T L + + B=$(echo "$DEVICE_BUS"|gawk '{$1=tolower($1);print}') + B=$(printf "%d" $B) + T=$(echo "$DEVICE_ID"|gawk '{$1=tolower($1);print}') + T=$(printf "%d" $T) + L=$(echo "$DEVICE_LUN"|gawk '{$1=tolower($1);print}') + L=$(printf "%d" $L) + + sas_addr=$(( ($B << 16) | ($T << 8) | $L )) + if [[ $DEVICE_LUN != "0" ]]; then + printf "%s/sas/disk@%x,%x\n" $DEVSPEC $sas_addr $DEVICE_LUN + else + printf "%s/sas/disk@%x\n" $DEVSPEC $sas_addr + fi + fi + return 0 + fi + + echo 1>&2 "$PRG: Driver: $SCSI_DRIVER is not supported" + return 1 +} + ## generic function that can find OF device paths for scsi devices, ## must be run after scsiinfo(). scsi_ofpath() @@ -321,11 +515,15 @@ scsi_ofpath() # sbp-2 driver may not have a dir in /proc/scsi HOST_LIST="$(for i in `find /proc/device-tree -name name` ; do lgrep "$i" "sbp-2" ; done)" - if [ "$SCSI_HOSTNUMBER" = "" ] ; then - SCSI_HOSTNUMBER=1 + if [ "$HOST_LIST" = "" ] ; then + scsi_ofpath2 + else + if [ "$SCSI_HOSTNUMBER" = "" ] ; then + SCSI_HOSTNUMBER=1 + fi + DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)" + echo "${DEVICE_PATH##*device-tree}/disk@0:$PARTITION" fi - DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)" - echo "${DEVICE_PATH##*device-tree}/disk@0:$PARTITION" ;; *) echo 1>&2 "$PRG: Driver: $SCSI_DRIVER is not supported"