>From 3e2f4c19c2c0d5af785ab904395ff58d9ba7104e Mon Sep 17 00:00:00 2001
From: Joseph Jezak josejx@gentoo.org <Joseph Jezak josejx@gentoo.org>
Date: Sun, 13 Feb 2011 23:38:36 -0500
Subject: Update ofpath for libata devices.


Signed-off-by: Joseph Jezak josejx@gentoo.org <Joseph Jezak josejx@gentoo.org>
---
 ybin/ofpath |  103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 95 insertions(+), 8 deletions(-)

diff --git a/ybin/ofpath b/ybin/ofpath
index aff5583..2e0fad8 100755
--- a/ybin/ofpath
+++ b/ybin/ofpath
@@ -329,10 +329,86 @@ scsi_ofpath()
 	    ;;
 	*)
 	    echo 1>&2 "$PRG: Driver: $SCSI_DRIVER is not supported"
-	    return 1
+	    echo ""
 	    ;;
     esac
-    return 0
+    echo ""
+}
+
+### If scsi_ofpath can't find anything, try a new method
+scsi_sys_ofpath() {
+	### Get the sysfs mount point
+	local SYS="$(m=`grep '.* .* sysfs ' /proc/mounts | head -n 1` ; echo `d=${m#* };echo ${d%% *}`)";
+	if [ -z "$SYS" -o ! -d "$SYS" ] ; then
+		echo 1>&2 "$PRG: Unable to determine sysfs mountpoint";
+		echo "";
+		return;
+	fi
+
+	### Get the device name and dereference it to support devices like /dev/cdrom1
+	local REAL_DEV=$(readlink -f "$DEVICE")
+	REAL_DEV=$(basename "$DEVICE")
+	if [ "$DEVICE" == "" ] || [ ! -e "/dev/$DEVICE" ]; then
+		echo 1>&2 "ofpath: Invalid device: /dev/$DEVICE";
+		echo "";
+		return;
+	fi
+
+	### Get the partition if it exists
+	case ${REAL_DEV} in
+		sd*) PARTITION="${DEVICE#sd?}" ;;
+		### No partition for sr/sg devices
+		sr*) PARTITION="${DEVICE#sr?}" ;;
+		sg*) PARTITION="${DEVICE#sg?}" ;;
+		*) echo 1>&2 "ofpath: Unknown device string."; return "";;
+	esac
+
+	### Get the disk device name
+	DISK_NAME="${DEVICE%%${PARTITION}}";
+
+	### Find the devspec for the controller
+	DEVSPEC=$(cd -P "$SYS/block/${DISK_NAME}/device" && pwd)
+	if [ "${DEVSPEC}" == "" ]; then
+		echo 1>&2 "ofpath: Unable to determine device path!";
+		echo "";
+		return;
+	fi
+
+	### Get the OF Path of the controller
+	CONTROLLER_PATH=$(cat "${DEVSPEC}/../../../devspec");
+	if [ "$CONTROLLER_PATH" == "" ]; then
+		echo 1>&2 "ofpath: Unable to find the controller path!";
+		echo "";
+		return;
+	fi
+
+	### Generate the disk number and partition info
+	DISK_NO="$(cd ${DEVSPEC}/../; pwd)";
+	DISK_NO="${DISK_NO##*:}";
+	DISK_NO="disk@${DISK_NO}:";
+
+	### We need to get the controller port path if it has one
+	if [ ! -d "/proc/device-tree/$CONTROLLER_PATH/disk" ] && [ ! -d "/proc/device-tree/$CONTROLLER_PATH/$DISK_NO" ]; then
+		### FIXME Does every scsi device uses the host nomenclature?
+		PORT="$(cd ${DEVSPEC}/../../; pwd)";
+		PORT="${PORT##*host}";
+		CTL_PORT="${CONTROLLER_PATH##*/}";
+		CTL_PORT="${CTL_PORT%%-root*}";
+		PORT="$CTL_PORT@$PORT";
+	fi
+
+	### Add the partition information if required
+	if [ ! $PARTITION == "" ]; then
+		DISK_NO="${DISK_NO}${PARTITION}";
+	fi
+
+	### Build the OF Path and print it out
+	if [ "$PORT" == "" ]; then
+		echo "$CONTROLLER_PATH/$DISK_NO";
+	else
+		echo "$CONTROLLER_PATH/$PORT/$DISK_NO";
+	fi
+	return;
 }
 
 ide_ofpath()
@@ -451,14 +527,25 @@ ide_ofpath()
 ## sd* scsi disks , hd* ide disks.
 newworld()
 {
+    local SCSI_PATH=""
     case "$DEVNODE" in
-	sd*)
-	    ## use common scsiinfo function to get info we need.
-	    scsiinfo || return 1
+	sd*|sr*|sg*)
+	    ### Run the new sysfs version, this version will get libata results
+	    SCSI_PATH=`scsi_sys_ofpath`
+
+	    ### Check if we got a result from the last call and if not, run the old code
+	    if [ "${SCSI_PATH}" == "" ]; then
+		## use common scsiinfo function to get info we need.
+		scsiinfo || return 1
+
+		## now we have the data for /@$DEVID:$PARTITION
+		## find the actual OF path.
+	        SCSI_PATH=`scsi_ofpath`
+	    fi
+
+	    ### Echo the found path
+	    echo ${SCSI_PATH}
 
-	    ## now we have the data for /@$DEVID:$PARTITION
-	    ## find the actual OF path.
-	    scsi_ofpath || return 1
 	    ;;
 	hd*)
 	    ide_ofpath || return 1
-- 
1.7.3.4

