]> git.ozlabs.org Git - yaboot.git/blobdiff - ybin/ofpath
Makefile: add cscope target
[yaboot.git] / ybin / ofpath
index 6763dfd97e631aff2e8f2a73d1a5039a0e33a3ab..4892d8c755717a8a55f75e9ec246fcd22d36fffc 100755 (executable)
@@ -8,7 +8,7 @@
 ## Portions based on show_of_path.sh:
 ##
 ## Copyright (C) 2000 Olaf Hering <olh@suse.de>
-## 
+##
 ## This program is free software; you can redistribute it and/or
 ## modify it under the terms of the GNU General Public License
 ## as published by the Free Software Foundation; either version 2
@@ -27,7 +27,7 @@
 
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
 PRG="${0##*/}"
-VERSION=1.0.5-UNRELEASED_UNSUPPORTED
+VERSION=1.0.7
 DEBUG=0
 export LC_COLLATE=C
 
@@ -116,15 +116,41 @@ linecount()
 ## small tr replacment which handles a specific need of this script.
 smalltr()
 {
-    case "$1" in 
-       a) echo 1 ;; b) echo 2 ;; c) echo 3 ;; d) echo 4 ;; e) echo 5 ;; f) echo 6 ;;
-       g) echo 7 ;; h) echo 8 ;; i) echo 9 ;; j) echo 10 ;; k) echo 11 ;; l) echo 12 ;;
-       m) echo 13 ;; n) echo 14 ;; o) echo 15 ;; p) echo 16 ;;
-       1) echo a ;; 2) echo b ;; 3) echo c ;; 4) echo d ;; 5) echo e ;; 
-       6) echo f ;; 7) echo g ;; 8) echo h ;; 9) echo i ;; 10) echo j ;;
-       11) echo k ;; 12) echo l ;; 13) echo m ;; 14) echo n ;; 15) echo o ;;
-       16) echo p ;;
-    esac
+        local i a d t val out mod cur
+
+        val="$1"
+        out="0"
+
+        d=$(printf "%d\n" \'${val:0:1})
+
+        if (( $d > 57 )) ; then  # is a letter
+                for ((i=0; i < ${#val}; i++)) ; do
+                        d=$(printf "%d\n" \'${val:$i:1})
+                        a=$(($d - 96))
+                        out=$(($out * 26))
+                        out=$(($out + $a))
+                done
+
+        else  # is a number
+                t=$val
+                out=""
+
+                while ((t != 0)) ; do
+                        mod=$(($t % 26))
+                        t=$(($t / 26))
+                        if (($mod == 0)) ; then
+                                cur="z"
+                                t=$(($t - 1))
+                        else
+                                mod=$(($mod + 96))
+                                cur=$(echo $mod | gawk '{printf "%c", $1}')
+                        fi
+                        out="$cur$out"
+                done
+        fi
+
+        echo "$out"
+
     return 0
 }
 
@@ -187,6 +213,17 @@ scsiinfo()
 {
     ## see if system has scsi at all
     if [ ! -f /proc/scsi/scsi ] ; then
+       local kver="$(uname -r)"
+       case "$kver" in
+           2.5.*|2.6.*)
+               if [ -d /sys/bus/scsi/devices -a \
+                   -n "$(ls /sys/bus/scsi/devices 2>/dev/null)" ] ; then
+                   echo 1>&2 "$PRG: /proc/scsi/scsi does not exist"
+                   echo 1>&2 "$PRG: Make sure you compiled your kernel with CONFIG_SCSI_PROC_FS=y"
+                   return 1
+               fi
+               ;;
+       esac
        echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
        return 1
     fi
@@ -231,24 +268,37 @@ 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"
 
-       if [ "$DEVTYPE" = "Direct-Access" ] ; then
-           DEVCOUNT="$(($DEVCOUNT + 1))"
-           [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVCOUNT=$DEVCOUNT"
-           if [ "$SUBDEV" = "$DEVCOUNT" ] ; then
-               DEVICE_HOST=$DEVHOST
-               DEVICE_ID=$DEVID
-               [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVICE_HOST=$DEVICE_HOST"
-               break
-           fi
-       fi
+       if [ "$DEVTYPE" = "Direct-Access" ] || [ "$DEVTYPE" = "Direct-Access-RBC" ] ; then
+           ls /sys/bus/scsi/devices/$DEVHOST:$DEVBUS:$DEVID:$DEVLUN/scsi_disk* > /dev/null 2>&1
+           if [ $? -eq 0 ] ; then
+                DEVCOUNT="$(($DEVCOUNT + 1))"
+                [ "$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
+            fi
+        fi
     done
 
     ## figure out what the scsi driver is, it is /proc/scsi/dirname.
@@ -263,6 +313,224 @@ 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
+
+        local fc=${DEVSPEC%@*}
+        fc=${fc##/*/}
+
+        if [[ -e /proc/device-tree$DEVSPEC/device_type ]]; then
+                local devtype=$(cat /proc/device-tree$DEVSPEC/device_type);
+                if [[ $devtype = "fcp" || $devtype = "scsi-fcp" ]]; then
+                        fc="fibre-channel";
+                fi
+        fi
+
+        if [[ $fc = "fibre-channel" ]]; then
+                local wwpn=$(get_fc_wwpn "$DEVICE_PATH/../../fc_remote_ports*")
+                local ofpath=$DEVSPEC
+
+                if [[ ! -e /proc/device-tree$DEVSPEC/disk ]]; then
+                        for dir in `find /proc/device-tree$DEVSPEC -type d`; do
+                                if [[ -e $dir/disk ]]; then
+                                        ofpath=${dir##/proc/device-tree}
+                                        break;
+                                fi
+                        done
+                fi
+
+                ofpath=$(printf "%s/disk@%s" $ofpath $wwpn)
+
+                if [[ $DEVICE_LUN != "0" ]]; then
+                        local fc_lun=$(get_fc_scsilun $DEVICE_LUN)
+                        ofpath=$(printf "%s,%s" $ofpath $fc_lun)
+                fi
+
+                echo "$ofpath"
+                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()
@@ -286,11 +554,39 @@ scsi_ofpath()
            DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
            echo "${DEVICE_PATH##*device-tree}/@$DEVICE_ID:$PARTITION"
            ;;
-       ata_k2)
-           HOST_LIST="$(for i in `find /proc/device-tree -name compatible` ; do
-                       lgrep "$i" "k2-s-ata" ; done)"
+       ata_k2|sata_svw)
+            #Not all G5 device trees have a compatible "k2-sata" node 
+            #per channel use parent
+           HOST_LIST="$(for i in `find /proc/device-tree -name compatible ` ; do
+                       lgrep "$i" "k2-s-ata" ; done | sort)"
            DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
-           echo "${DEVICE_PATH##*device-tree}/k2-sata@$DEVICE_ID/disk@0:$PARTITION"
+           K2_DEVICE_ID=0
+           while [ "$DEVICE_PATH" = "" ] ; do
+               SCSI_HOSTNUMBER=`expr $SCSI_HOSTNUMBER - 1`
+               let "K2_DEVICE_ID += 1"
+               DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
+           done
+           echo "${DEVICE_PATH##*device-tree}/k2-sata@$K2_DEVICE_ID/disk@0:$PARTITION"
+           ;;
+       usb-storage)
+            HOST_LIST="$(for i in `find /proc/device-tree -name name | grep usb` ; do
+                        lgrep "$i" "disk" ; done)"
+            DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
+            echo "${DEVICE_PATH##*device-tree}:$PARTITION"
+           ;;
+       sbp2|"")
+            # 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 [ "$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
            ;;
        *)
            echo 1>&2 "$PRG: Driver: $SCSI_DRIVER is not supported"
@@ -303,7 +599,7 @@ scsi_ofpath()
 ide_ofpath()
 {
     if [ ! -L "/proc/ide/$DEVNODE" ] ; then
-       echo 2>&1 "$PRG: /dev/$DEVNODE: Device not configured"
+       echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
        return 1
     fi
 
@@ -312,11 +608,32 @@ ide_ofpath()
        echo 1>&2 "$PRG: BUG: IDEBUS == NULL"
        return 1
     fi
-    local OF1275IDE="/proc/ide/$IDEBUS/devspec"
+
+    case "$(uname -r)" in
+       2.5.*|2.6.0*|2.6.1|2.6.1-*|2.6.2|2.6.2-*)
+           echo 1>&2 "$PRG: Linux kernel `uname -r` is not supported"
+           return 1
+           ;;
+       2.6.*|2.7.*)
+           if ! (grep -q '.* .* sysfs ' /proc/mounts 2> /dev/null) ; then
+               echo 1>&2 "$PRG: sysfs must be mounted for ofpath to support this system"
+               return 1
+           fi
+           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"
+               return 1
+           fi
+           local OF1275IDE="${SYS}/block/${DEVNODE}/device/../../devspec"
+           ;;
+       *)
+           local OF1275IDE="/proc/ide/$IDEBUS/devspec"
+           ;;
+    esac
 
     if [ ! -f "$OF1275IDE" ] ; then
        case "$(cat /proc/device-tree/model)" in
-           "PowerMac3,6")
+           PowerMac3*|PowerMac4*|PowerMac5*|PowerMac6*|PowerMac7*|RackMac*)
                local CDROM="$(grep "^drive name:" /proc/sys/dev/cdrom/info 2> /dev/null | grep $DEVNODE)"
                if [ -z "$CDROM" ] ; then
                    echo 1>&2 "$PRG: WARNING: Your kernel is too old for proper support, device may be innaccurate."
@@ -361,11 +678,15 @@ ide_ofpath()
                local SLAVE="/@$(cat /proc/ide/${IDEBUS}/channel)/disk@1"
                ;;
            scsi) ## some lame controllers pretend they are scsi, hopefully all kludges are created equal.
-               local MASTER="/$(($(cat /proc/ide/${IDEBUS}/channel) * 2 + 0)),0"
-               local SLAVE="/$(($(cat /proc/ide/${IDEBUS}/channel) * 2 + 1)),0"
+               local MASTER="/@$(($(cat /proc/ide/${IDEBUS}/channel) * 2 + 0))"
+               local SLAVE="/@$(($(cat /proc/ide/${IDEBUS}/channel) * 2 + 1))"
+               ;;
+           spi)
+               local MASTER="/disk@$(cat /proc/ide/${IDEBUS}/channel),0"
+               local SLAVE="/disk@$(cat /proc/ide/${IDEBUS}/channel),1"
                ;;
            *)
-               echo 2>&1 "$PRG: Unsupported IDE device type: \"$(cat /proc/device-tree${DEVSPEC}/device_type 2> /dev/null)\""
+               echo 1>&2 "$PRG: Unsupported IDE device type: \"$(cat /proc/device-tree${DEVSPEC}/device_type 2> /dev/null)\""
                return 1
                ;;
        esac
@@ -393,19 +714,11 @@ newworld()
 {
     case "$DEVNODE" in
        sd*)
-           if ls -l /proc/device-tree | grep -q ^lr ; then
-               true
-           else
-               echo 1>&2 "$PRG: /proc/device-tree is broken.  Do not use BootX to boot, use yaboot."
-               echo 1>&2 "$PRG: The yaboot HOWTO can be found here: http://www.alaska.net/~erbenson/doc"
-               return 1
-           fi
-
            ## 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. 
+           ## find the actual OF path.
            scsi_ofpath || return 1
            ;;
        hd*)
@@ -630,25 +943,48 @@ oldworld()
     return 0
 }
 
+eth_ofpath()
+{
+        read_attr devspec /sys/class/net/$DEVICE/device
+}
+
+hfi_ofpath()
+{
+        local hfnum=${DEVICE##hf}
+        local hfpath
+
+        if [[ $hfnum = "0" || $hfnum = "2" ]]; then
+                hfpath=$(find /proc/device-tree -name hfi-ethernet* | sort | head -n 1)
+        elif [[ $hfnum = "1" || $hfnum = "3" ]]; then
+                hfpath=$(find /proc/device-tree -name hfi-ethernet* | sort | tail -n 1)
+        else
+               echo 1>&2 "$PRG: Unsupported device: $DEVICE"
+               return 1
+        fi
+
+        hfpath=${hfpath##/proc/device-tree}
+        echo "$hfpath"
+}
+
 ## find OpenFirmware device path for IBM CHRP hardware (scsi only)
 chrp()
 {
     case "$DEVNODE" in
        sd*)
-           if ls -l /proc/device-tree | grep -q ^lr ; then
-               true
-           else
-               echo 1>&2 "$PRG: /proc/device-tree is broken."
-               return 1
-           fi
 
            ## 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. 
+           ## find the actual OF path.
            scsi_ofpath || return 1
            ;;
+       eth*)
+           eth_ofpath || return 1
+           ;;
+       hfi*)
+           hfi_ofpath || return 1
+           ;;
        *)
            echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
            return 1
@@ -742,7 +1078,7 @@ fixdevfs()
            local DEVTYPE="$(v=$(echo ${DEVINFO##*Type: }) ; echo ${v%% *})"
            [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVTYPE=$DEVTYPE"
 
-           if [ "$DEVTYPE" = "Direct-Access" ] ; then
+           if [ "$DEVTYPE" = "Direct-Access" ] || [ "$DEVTYPE" = "Direct-Access-RBC" ] ; then
                ## Lets find out some more information
                ## get the device id.
                local DEVID="$(v=$(echo ${DEVINFO##*Id: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
@@ -840,15 +1176,6 @@ else
     exit 1
 fi
 
-## check that FILE is a block device and exists.
-if [ ! -e "$device" ] ; then
-    echo 1>&2 "$PRG: $device: No such file or directory"
-    exit 1
-elif [ ! -b "$device" ] ; then
-    echo 1>&2 "$PRG: $device is not a block device"
-    exit 1
-fi
-
 ## check that we are running on a GNU/Linux system, OSX/BSD does not
 ## have the same /proc stuff
 if [ `uname -s` != Linux ] ; then
@@ -857,7 +1184,7 @@ if [ `uname -s` != Linux ] ; then
 fi
 
 ## check for ppc, i think uname -m is safe for this...
-if [ `uname -m` != ppc ] ; then
+if [ `uname -m` != ppc -a `uname -m` != ppc64 ] ; then
     echo 1>&2 "$PRG: This utility will only work on PowerPC hardware"
     exit 1
 fi
@@ -882,6 +1209,8 @@ elif (cat /proc/cpuinfo 2>/dev/null | grep ^motherboard | grep -q AAPL) ; then
     SUBARCH=OldWorld
 elif (cat /proc/cpuinfo 2> /dev/null | grep ^machine | grep -q 'CHRP IBM') ; then
     SUBARCH=CHRP
+elif (cat /proc/cpuinfo 2>/dev/null | grep ^machine | grep -q 'CHRP Pegasos') ; then
+    SUBARCH=Pegasos
 else
     echo 1>&2 "$PRG: This machine is not yet supported"
     exit 1
@@ -904,7 +1233,8 @@ PARTITION="${DEVICE##*[a-z]}"
 
 ## use appropriate search for right sub arch.
 case "$SUBARCH" in
-    NewWorld)
+    # Pegasos OF seems to be NewWorld-ish enough to cope with this.
+    NewWorld|Pegasos)
        newworld || exit 1
        ;;
     OldWorld)