| #! /bin/sh |
| |
| ############################################################################### |
| ## |
| ## ofpath: determine OpenFirmware path from unix device node |
| ## |
| ## Copyright (C) 2010, 2011 Milan Kupcevic |
| ## |
| ## Copyright (C) 2000, 2001, 2002, 2003 Ethan Benson |
| ## |
| ## 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 |
| ## of the License, or (at your option) any later version. |
| ## |
| ## This program is distributed in the hope that it will be useful, |
| ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
| ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| ## GNU General Public License for more details. |
| ## |
| ## You should have received a copy of the GNU General Public License |
| ## along with this program; if not, write to the Free Software |
| ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| ## |
| ############################################################################### |
| |
| PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" |
| PRG="${0##*/}" |
| VERSION=1.0.7+debian3 |
| DEBUG=0 |
| export LC_COLLATE=C |
| |
| ## --version output. |
| version() |
| { |
| echo \ |
| "$PRG $VERSION |
| Written by Ethan Benson, portions rewritten by Milan Kupcevic |
| Portions based on show_of_path.sh written by Olaf Hering |
| |
| Copyright (C) 2010, 2011 Milan Kupcevic |
| Copyright (C) 2000, 2001, 2002, 2003 Ethan Benson |
| Portions Copyright (C) 2000 Olaf Hering |
| This is free software; see the source for copying conditions. There is NO |
| warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." |
| } |
| |
| ## --help output. |
| usage() |
| { |
| echo \ |
| "Usage: $PRG [OPTION]... FILE |
| Find OpenFirmware device path from unix device node. |
| |
| --debug print boring junk only useful for debugging |
| -h, --help display this help and exit |
| -V, --version output version information and exit" |
| } |
| |
| ## a small seq replacement, seq is not present on boot/rescue floppies. |
| smallseq() |
| { |
| local v="$1" |
| local n=1 |
| echo 1 |
| while [ "$v" -gt 1 ] ; do |
| n=$((n+1)) |
| echo $n |
| v=$((v-1)) |
| done |
| return 0 |
| } |
| |
| ## a kludge to replace wc -l, wc is not present on boot/rescue |
| ## floppies. max file is 145 lines, 3 hosts * 16 devs each * 3 lines |
| ## per device, + 1 "Attached Devices:" line. |
| linecount() |
| { |
| local file v |
| if [ $# = 0 ] ; then |
| file="$(cat)" |
| v="$file" |
| else |
| file="$(cat $1)" |
| v="$file" |
| fi |
| |
| if [ -z "$file" ] ; then |
| echo 0 |
| return 0 |
| fi |
| |
| ## use real wc if available |
| if command -v wc > /dev/null 2>&1 && [ -x `command -v wc` ] ; then |
| if lines="`printf '%s\\n' \"$file\" | wc -l`"; then |
| echo "$lines" |
| unset lines |
| return 0 |
| fi |
| fi |
| |
| while true ; do |
| for i in `smallseq 145` ; do |
| local b="$(echo "$file" | tail -n $i)" |
| if [ "$v" = "$b" ] ; then |
| echo "$i" |
| break 2 |
| fi |
| done |
| done |
| return 0 |
| } |
| |
| ## 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 |
| return 0 |
| } |
| |
| ## replacment for grep -l which is not supported by busybox grep. |
| ## echo $(cat..) hack needed because busybox grep barfs with `line too |
| ## long' when fed /proc files. the for loop is needed since busybox |
| ## grep seems to have somewhat broken regexp support. |
| ## usage: lgrep filename regexp regexp ... |
| lgrep() |
| { |
| local f buffer |
| f="$1" |
| buffer="`cat \"$f\"`" || return |
| shift |
| for e in "$@" ; do |
| if printf %s\\n "$buffer" | grep -q "$e"; then |
| printf %s\\n "$f" |
| break |
| fi |
| done |
| return 1 |
| } |
| |
| ## if readlink is missing use a kludge |
| if ! command -v readlink > /dev/null 2>&1; then |
| readlink() |
| { |
| local SYMTARGET="$(v=`ls -l "$1" 2>/dev/null` ; echo ${v##*> })" |
| if [ -n "$SYMTARGET" ] ; then |
| printf %s\\n "$SYMTARGET" |
| return 0 |
| else |
| return 1 |
| fi |
| } |
| fi |
| |
| ## a function to print relevant scsi host path when there is more then |
| ## one. this function also takes care of stripping off the trailing |
| ## /compatible. |
| printhost() |
| { |
| case "$1" in |
| 1) |
| echo "${2%/*}" |
| ;; |
| 2) |
| echo "${3%/*}" |
| ;; |
| 3) |
| echo "${4%/*}" |
| ;; |
| 4) |
| echo "${5%/*}" |
| ;; |
| esac |
| return 0 |
| } |
| |
| # read OpenFirmware device path from its corresponding devspec |
| find_of_path() |
| { |
| [ -z "$1" ] && return |
| if [ -f "$1/devspec" ]; then |
| OF_PATH="`cat $1/devspec`" |
| SYS_PATH="$1" |
| return |
| fi |
| find_of_path "${1%/*}" |
| } |
| |
| ## this finds information we need on both newworld and oldworld macs. |
| ## mainly what scsi host a disk is attached to. |
| scsiinfo() |
| { |
| SYS_DEVICE="`readlink -f /sys/block/$DEVNODE/device`" |
| |
| [ -e "$SYS_DEVICE" ] && { |
| |
| SCSI_DEVICE=${SYS_DEVICE##*/} |
| HOST_ID=${SCSI_DEVICE%%:*} |
| BUS_ID=`T=${SCSI_DEVICE#*:}; echo ${T%%:*}` |
| DEVICE_ID=`T=${SCSI_DEVICE#*:*:}; echo ${T%%:*}` |
| LUN_ID=${SCSI_DEVICE##*:} |
| |
| OF_PATH=;find_of_path "$SYS_DEVICE" |
| |
| SCSI_DRIVER=`cat /sys/class/scsi_host/host$HOST_ID/proc_name 2>/dev/null` |
| |
| SCSI_NAME=`cat /proc/device-tree$OF_PATH/name 2>/dev/null` |
| |
| IEEE1394_ID=`cat /sys/block/$DEVNODE/device/ieee1394_id 2>/dev/null` |
| IEEE1394_ID=${IEEE1394_ID%%:*} |
| |
| PLUG_ID=$(ls -dv $SYS_PATH/host* 2>/dev/null | grep -n "/host$HOST_ID$") |
| PLUG_ID=$((${PLUG_ID%%:*}-1)) |
| |
| PART=${PARTITION:+:$PARTITION} |
| |
| [ "$LUN_ID" != "0" ] && LUNX=`printf ",%x" $LUN_ID` |
| |
| [ "$DEBUG" = "1" ] && { |
| echo SYS_DEVICE=$SYS_DEVICE |
| echo SCSI_DEVICE=$SCSI_DEVICE |
| echo HOST_ID=$HOST_ID |
| echo BUS_ID=$BUS_ID |
| echo DEVICE_ID=$DEVICE_ID |
| echo LUN_ID=$LUN_ID |
| echo PLUG_ID=$PLUG_ID |
| echo IEEE1394_ID=$IEEE1394_ID |
| echo SCSI_NAME=$SCSI_NAME |
| echo SCSI_DRIVER=$SCSI_DRIVER |
| echo SYS_PATH=$SYS_PATH |
| echo OF_PATH=$OF_PATH |
| echo PART=$PART |
| echo LUNX=$LUNX |
| } |
| |
| SCSI_DRIVER=${SCSI_DRIVER:?} |
| |
| [ -z "$OF_PATH" ] && { |
| echo 1>&2 "Cannot find $DEVNODE among OpenFirmware registered devices" |
| |
| exit 1 |
| } |
| |
| return 0 |
| } |
| |
| echo 1>&2 "Link /sys/block/$DEVNODE/device does not exist" |
| |
| exit 1 |
| } |
| |
| ## add OF device node to the host OF path, |
| ## must be run after scsiinfo(). |
| scsi_ofpath() |
| { |
| if [ -d "/proc/device-tree$OF_PATH/sas" ] ; then |
| |
| SAS_ID=$(( (BUS_ID << 16) | (DEVICE_ID << 8) | LUN_ID)) |
| printf "%s/sas/disk@%x%s\\n" $OF_PATH $SAS_ID $LUNX$PART |
| |
| elif [ -d "/proc/device-tree$OF_PATH/scsi@`printf %x $BUS_ID`" ] ; then |
| |
| printf "%s/scsi@%x/@%x%s\\n" $OF_PATH $BUS_ID $DEVICE_ID $LUNX$PART |
| |
| else |
| |
| case "$SCSI_DRIVER-$SCSI_NAME" in |
| aic7xxx-*|sym53c8xx-*|mesh-*|*-scsi) |
| printf "%s/@%x%s\\n" $OF_PATH $DEVICE_ID $LUNX$PART |
| ;; |
| sata_sil-*|sata_vsc-*) |
| printf "%s/@%x%s\\n" $OF_PATH $((PLUG_ID*2)) $PART |
| ;; |
| sata_svw-*|*-pci-ata) |
| printf "%s/@%x/@%x%s\\n" $OF_PATH $PLUG_ID $DEVICE_ID $PART |
| ;; |
| pata_macio-*) |
| printf "%s/@%x%s\\n" $OF_PATH $DEVICE_ID $PART |
| ;; |
| sbp2-*) |
| IEEE1394_ID=${IEEE1394_ID:?} |
| printf "%s/node@%s/sbp-2/@%x%s\\n" $OF_PATH $IEEE1394_ID $DEVICE_ID $PART |
| ;; |
| ipr-obsidian) |
| printf "%s/@%x,%x%s\\n" $OF_PATH $BUS_ID $DEVICE_ID $LUNX$PART |
| ;; |
| *) |
| printf "%s: %s (%s) is not supported\\n" "${PRG}" "${SCSI_NAME}" "${SCSI_DRIVER}" 1>&2 |
| return 1 |
| ;; |
| esac |
| |
| fi |
| |
| return 0 |
| } |
| |
| ide_ofpath() |
| { |
| if [ ! -L "/proc/ide/$DEVNODE" ] ; then |
| echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured" |
| return 1 |
| fi |
| |
| local IDEBUS="$(v=`readlink /proc/ide/$DEVNODE` ; echo ${v%%/*} )" |
| if [ -z "$IDEBUS" ] ; then |
| echo 1>&2 "$PRG: BUG: IDEBUS == NULL" |
| return 1 |
| fi |
| |
| local kernel_release="`uname -r`" |
| case "$kernel_release" in |
| 2.5.*|2.6.0*|2.6.1|2.6.1-*|2.6.2|2.6.2-*) |
| printf "%s: Linux %s is not supported\\n" "$PRG" "$kernel_release" 1>&2 |
| 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`; 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*|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." |
| echo "ultra2:$PARTITION" |
| else |
| echo "cd:$PARTITION" |
| fi |
| ;; |
| *) |
| local CDROM="$(grep "^drive name:" /proc/sys/dev/cdrom/info 2> /dev/null | grep $DEVNODE)" |
| if [ -z "$CDROM" ] ; then |
| if [ "$DEVNODE" = hda ] ; then |
| echo "hd:$PARTITION" |
| else |
| echo "ultra1:$PARTITION" |
| fi |
| else |
| echo "cd:$PARTITION" |
| fi |
| ;; |
| esac |
| else |
| local DEVSPEC="$(cat $OF1275IDE)" |
| [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVSPEC=$DEVSPEC" |
| if [ -z "$DEVSPEC" ] ; then |
| echo 1>&2 "$PRG: KERNEL BUG: $OF1275IDE exists, but is empty" |
| return 1 |
| fi |
| |
| if [ ! -f "/proc/ide/${IDEBUS}/channel" ] ; then |
| echo 1>&2 "$PRG: KERNEL BUG: /proc/ide/${IDEBUS}/channel does not exist" |
| return 1 |
| fi |
| |
| case "$(cat /proc/device-tree${DEVSPEC}/device_type 2> /dev/null)" in |
| ide|ata) |
| local MASTER="/disk@0" |
| local SLAVE="/disk@1" |
| ;; |
| pci-ide|pci-ata) |
| local MASTER="/@$(cat /proc/ide/${IDEBUS}/channel)/disk@0" |
| 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))" |
| 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 1>&2 "$PRG: Unsupported IDE device type: \"$(cat /proc/device-tree${DEVSPEC}/device_type 2> /dev/null)\"" |
| return 1 |
| ;; |
| esac |
| |
| case "$DEVNODE" in |
| hda|hdc|hde|hdg|hdi|hdk|hdm|hdo) |
| echo "${DEVSPEC}${MASTER}${PARTITION:+:${PARTITION}}" |
| return 0 |
| ;; |
| hdb|hdd|hdf|hdh|hdj|hdl|hdn|hdp) |
| echo "${DEVSPEC}${SLAVE}${PARTITION:+:${PARTITION}}" |
| return 0 |
| ;; |
| *) |
| echo 1>&2 "$PRG: /dev/$DEVNODE is not supported" |
| return 1 |
| ;; |
| esac |
| fi |
| } |
| |
| ## figure out the OpenFirmware device path for newworld macs. |
| ## sd* scsi disks , hd* ide disks. |
| newworld() |
| { |
| case "$DEVNODE" in |
| sd*) |
| ## 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_ofpath || return 1 |
| ;; |
| hd*) |
| ide_ofpath || return 1 |
| ;; |
| *) |
| echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported" |
| return 1 |
| ;; |
| esac |
| return 0 |
| } |
| |
| oldworld() |
| { |
| ## for some reason 2.4 kernels put OF aliases in aliases@0/ instead of plain aliases/ |
| if [ -d "/proc/device-tree/aliases" ] ; then |
| local ALIASES="aliases" |
| elif [ -d "/proc/device-tree/aliases@0" ] ; then |
| local ALIASES="aliases@0" |
| else |
| echo 1>&2 "$PRG: Cannot find OpenFirmware aliases directory in /proc/device-tree/" |
| return 1 |
| fi |
| |
| local MODEL="$(cat /proc/device-tree/compatible)" |
| [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: Oldworld subarch: $MODEL" |
| |
| case "$MODEL" in |
| AAPL,7300*|AAPL,7500*|AAPL,8500*|AAPL,9500*|AAPL,\?\?\?\?*) |
| case "$DEVNODE" in |
| sd*) |
| scsiinfo || return 1 |
| case "$SCSI_DRIVER" in |
| mesh) |
| printf "%s/sd@%s:%s\\n" "$(cat /proc/device-tree/$ALIASES/scsi-int)" "$DEVICE_ID" "$PARTITION" |
| ;; |
| 53c94) |
| printf "%s/sd@%s:%s\\n" "$(cat /proc/device-tree/$ALIASES/scsi)" "$DEVICE_ID" "$PARTITION" |
| ;; |
| *) |
| printf "%s: Driver %s is not supported\\n" "$PRG" "$SCSI_DRIVER" 1>&2 |
| return 1 |
| ;; |
| esac |
| ;; |
| *) |
| echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE" |
| return 1 |
| ;; |
| esac |
| ;; |
| AAPL,e407*) |
| case "$DEVNODE" in |
| sd*) |
| scsiinfo || return 1 |
| case "$SCSI_DRIVER" in |
| mesh) |
| printf "%s/sd@%s:%s\\n" "$(cat /proc/device-tree/$ALIASES/scsi)" "$DEVICE_ID" "$PARTITION" |
| ;; |
| *) |
| printf "%s: Driver %s is not supported\\n" "$PRG" "$SCSI_DRIVER" 1>&2 |
| return 1 |
| ;; |
| esac |
| ;; |
| hda*) |
| printf "%s/ATA-Disk@0:%s\\n" "$(cat /proc/device-tree/$ALIASES/ata)" "$PARTITION" |
| ;; |
| hdb*) |
| printf "%s/ATA-Disk@1:%s\\n" "$(cat /proc/device-tree/$ALIASES/ata)" "$PARTITION" |
| ;; |
| hd*) |
| printf "%s: Device /dev/%s is not supported\\n" "$PRG" "$DEVNODE" 1>&2 |
| ;; |
| esac |
| ;; |
| AAPL,e826*) |
| case "$DEVNODE" in |
| sd*) |
| scsiinfo || return 1 |
| case "$SCSI_DRIVER" in |
| mesh) |
| printf "%s/sd@%s:%s\\n" "$(cat /proc/device-tree/$ALIASES/scsi)" "$DEVICE_ID" "$PARTITION" |
| ;; |
| *) |
| printf "%s: Driver %s is not supported\\n" "$PRG" "$SCSI_DRIVER" 1>&2 |
| return 1 |
| ;; |
| esac |
| ;; |
| hda*) |
| printf "%s/ata-disk@0:%s\\n" "$(cat /proc/device-tree/$ALIASES/ata)" "$PARTITION" |
| ;; |
| hdb*) |
| printf "%s/ata-disk@1:%s\\n" "$(cat /proc/device-tree/$ALIASES/ata)" "$PARTITION" |
| ;; |
| hd*) |
| printf "%s: Device /dev/%s is not supported\\n" "$PRG" "$DEVNODE" 1>&2 |
| ;; |
| esac |
| ;; |
| AAPL,Gossamer*|AAPL,PowerMac\ G3*) |
| case "$DEVNODE" in |
| sd*) |
| scsiinfo || return 1 |
| case "$SCSI_DRIVER" in |
| mesh) |
| printf "%s/sd@%s:%s\\n" "$(cat /proc/device-tree/$ALIASES/scsi)" "$DEVICE_ID" "$PARTITION" |
| ;; |
| *) |
| printf "%s: Driver %s is not supported\\n" "$PRG" "$SCSI_DRIVER" 1>&2 |
| return 1 |
| ;; |
| esac |
| ;; |
| hda*) |
| printf "%s/ata-disk@0:%s\\n" "$(cat /proc/device-tree/$ALIASES/ide0)" "$PARTITION" |
| ;; |
| hdb*) |
| printf "%s/ata-disk@1:%s\\n" "$(cat /proc/device-tree/$ALIASES/ide0)" "$PARTITION" |
| ;; |
| hdc*) |
| printf "%s/ata-disk@0:%s\\n" "$(cat /proc/device-tree/$ALIASES/ide1)" "$PARTITION" |
| ;; |
| hdd*) |
| printf "%s/ata-disk@1:%s\\n" "$(cat /proc/device-tree/$ALIASES/ide1)" "$PARTITION" |
| ;; |
| hd*) |
| printf "%s: Device /dev/%s is not supported\\n" "$PRG" "$DEVNODE" 1>&2 |
| ;; |
| esac |
| ;; |
| AAPL,PowerBook1998*) |
| if [ -f /proc/device-tree/$ALIASES/ata0 ] ; then |
| local ATA0=ata0 |
| else |
| local ATA0=ide0 |
| fi |
| if [ -f /proc/device-tree/$ALIASES/ata1 ] ; then |
| local ATA1=ata1 |
| else |
| local ATA1=bay-ata1 |
| fi |
| case "$DEVNODE" in |
| sd*) |
| scsiinfo || return 1 |
| case "$SCSI_DRIVER" in |
| mesh) |
| printf "%s/sd@%s:%s\\n" "$(cat /proc/device-tree/$ALIASES/scsi)" "$DEVICE_ID" "$PARTITION" |
| ;; |
| *) |
| printf "%s: Driver %s is not supported\\n" "$PRG" "$SCSI_DRIVER" 1>&2 |
| return 1 |
| ;; |
| esac |
| ;; |
| hda*) |
| printf "%s/ata-disk@0:%s\\n" "$(cat /proc/device-tree/$ALIASES/$ATA0)" "$PARTITION" |
| ;; |
| hdb*) |
| printf "%s/ata-disk@1:%s\\n" "$(cat /proc/device-tree/$ALIASES/$ATA0)" "$PARTITION" |
| ;; |
| hdc*) |
| printf "%s/atapi-disk@0:%s\\n" "$(cat /proc/device-tree/$ALIASES/$ATA1)" "$PARTITION" |
| ;; |
| hdd*) |
| printf "%s/atapi-disk@1:%s\\n" "$(cat /proc/device-tree/$ALIASES/$ATA1)" "$PARTITION" |
| ;; |
| *) |
| printf "%s: Device /dev/%s is not supported\\n" "$PRG" "$DEVNODE" 1>&2 |
| return 1 |
| ;; |
| esac |
| ;; |
| AAPL,3400/2400*) |
| case "$DEVNODE" in |
| sd*) |
| scsiinfo || return 1 |
| case "$SCSI_DRIVER" in |
| mesh) |
| printf "%s/sd@%s:%s\\n" "$(cat /proc/device-tree/$ALIASES/scsi-int)" "$DEVICE_ID" "$PARTITION" |
| ;; |
| 53c94) |
| printf "%s/sd@%s:%s\\n" "$(cat /proc/device-tree/$ALIASES/scsi)" "$DEVICE_ID" "$PARTITION" |
| ;; |
| *) |
| printf "%s: Driver %s is not supported\\n" "$PRG" "$SCSI_DRIVER" 1>&2 |
| return 1 |
| ;; |
| esac |
| ;; |
| hda*) |
| printf "%s/ata-disk@0:%s\\n" "$(cat /proc/device-tree/$ALIASES/ata0)" "$PARTITION" |
| ;; |
| hdb*) |
| printf "%s/ata-disk@1:%s\\n" "$(cat /proc/device-tree/$ALIASES/ata0)" "$PARTITION" |
| ;; |
| hdc*) |
| printf "%s/atapi-disk@0:%s\\n" "$(cat /proc/device-tree/$ALIASES/ata1)" "$PARTITION" |
| ;; |
| hdd*) |
| printf "%s/atapi-disk@1:%s\\n" "$(cat /proc/device-tree/$ALIASES/ata1)" "$PARTITION" |
| ;; |
| hde*) |
| printf "%s:%s\\n" "$(cat /proc/device-tree/$ALIASES/ata2)" "$PARTITION" |
| ;; |
| hdf*) |
| printf "%s:%s\\n" "$(cat /proc/device-tree/$ALIASES/ata3)" "$PARTITION" |
| ;; |
| *) |
| printf "%s: Device /dev/%s is not supported\\n" "$PRG" "$DEVNODE" 1>&2 |
| return 1 |
| ;; |
| esac |
| ;; |
| *) |
| echo 1>&2 "$PRG: This machine is not supported: $MODEL" |
| return 1 |
| ;; |
| esac |
| return 0 |
| } |
| |
| ## find OpenFirmware device path for IBM CHRP hardware (scsi only) |
| chrp() |
| { |
| case "$DEVNODE" in |
| sd*) |
| |
| ## 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_ofpath || return 1 |
| ;; |
| *) |
| echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported" |
| return 1 |
| ;; |
| esac |
| return 0 |
| } |
| |
| ## If we get lame devfs name, we need to make it foad |
| ckdevfs() |
| { |
| case "$1" in |
| /dev/ide/*|/dev/scsi/*|/dev/discs/*) |
| return 0 |
| ;; |
| *) |
| return 1 |
| ;; |
| esac |
| } |
| |
| ## convert devfs names into normal short ones, written by Tom Rini. |
| fixdevfs() |
| { |
| local DEV |
| |
| ## get partition number, if any |
| local PARTNUM="${1##*[a-z]}" |
| ## Find the bus type. |
| local TYPE="$(v=${1#/dev/} ; echo ${v%/host*})" |
| ## Find the host number. |
| local HOST="$(v=${1#/dev/*/host} ; echo ${v%/bus*})" |
| ## Find the bus number. |
| local BUS="$(v=${1#/dev/*/bus} ; echo ${v%/tar*})" |
| ## Find the target. |
| local TARGET="$(v=${1#/dev/*/target} ; echo ${v%/lun*})" |
| |
| case "$TYPE" in |
| ide) |
| case "$HOST" in |
| 0) |
| case "$TARGET" in |
| 0) |
| DEV=hda |
| ;; |
| 1) |
| DEV=hdb |
| ;; |
| esac |
| ;; |
| 1) |
| case "$TARGET" in |
| 0) |
| DEV=hdc |
| ;; |
| 1) |
| DEV=hdd |
| ;; |
| esac |
| ;; |
| *) |
| echo 1>&2 "$PRG: $1: Unable to translate this device, try again without devfs." |
| return 1 |
| esac |
| DEV="${DEV}${PARTNUM}" |
| echo "/dev/$DEV" |
| return 0 |
| ;; |
| scsi) |
| local LUN="$(v=${1#/dev/*/lun} ; echo ${v%/*})" |
| |
| ## In this case, we need to figure out what number our device is |
| local DEVCOUNT=0 |
| |
| ## copy scsi file into a variable removing "Attached Devices" |
| ## which is the first line. this avoids a lot of |
| ## [incmopatible] crap later, and improves readability. |
| |
| ## find number of lines once and recycle that number, to save |
| ## some time (linecount is a bit slow). subtract one line |
| ## to scrap Attached Devices: |
| |
| local SCSILINES="$(($(linecount /proc/scsi/scsi) - 1))" |
| local PROCSCSI="$(cat /proc/scsi/scsi | tail -n $SCSILINES)" |
| |
| for i in $(smallseq $((SCSILINES/3))) ; do |
| |
| ## put every scsi device into one single line |
| local DEVINFO="$(echo "$PROCSCSI" | head -n $((i*3)) | tail -n 3)" |
| [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVINFO=$DEVINFO" |
| |
| ## cut the type field, expect "Direct-Access" later. |
| local DEVTYPE="$(v=${DEVINFO##*Type: }; echo ${v%% *})" |
| [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVTYPE=$DEVTYPE" |
| |
| if [ "$DEVTYPE" = "Direct-Access" ] || [ "$DEVTYPE" = "Direct-Access-RBC" ] ; then |
| ## Lets find out some more information |
| ## get the device id. |
| local DEVID="$(v=${DEVINFO##*Id: }; n=${v%% *}; echo ${n#*0})" |
| [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVID=$DEVID" |
| |
| ## get the device lun. |
| local DEVLUN="$(v=${DEVINFO##*Lun: }; n=${v%% *}; echo ${n#*0})" |
| [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVLUN=$DEVLUN" |
| |
| ## get the device channel. |
| local DEVCHAN="$(v=${DEVINFO##*Channel: }; n=${v%% *}; echo ${n#*0})" |
| [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVCHAN=$DEVCHAN" |
| |
| ## get the scsi host id. |
| local DEVHOST="$(v=${DEVINFO##*Host: scsi}; echo ${v%% *})" |
| [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVHOST=$DEVHOST" |
| |
| local DEVCOUNT="$((DEVCOUNT+1))" |
| [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVCOUNT=$DEVCOUNT" |
| if [ "$DEVHOST" = "$HOST" -a "$DEVCHAN" = "$BUS" -a \ |
| "$DEVID" = "$TARGET" -a "$DEVLUN" = "$LUN" ] ; then |
| DEV="sd$(smalltr $DEVCOUNT)${PARTNUM}" |
| echo "/dev/$DEV" |
| return 0 |
| fi |
| fi |
| done |
| echo 1>&2 "$PRG: $1: Unable to translate this device, try again without devfs." |
| return 1 |
| ;; |
| *) |
| echo 1>&2 "$PRG: Unknown bus $TYPE" |
| return 1 |
| ;; |
| esac |
| ## we should never get here |
| return 1 |
| } |
| |
| ## make sure that find, head and tail can be found. otherwise the |
| ## script will silently give bogus paths. these are the only /usr/* |
| ## utilities this script depends on. |
| checkutils() |
| { |
| if command -v find > /dev/null 2>&1 ; then |
| [ -x `command -v find` ] || FAIL=1 ; else FAIL=1 ; fi |
| if command -v head > /dev/null 2>&1 ; then |
| [ -x `command -v head` ] || FAIL=1 ; else FAIL=1 ; fi |
| if command -v tail > /dev/null 2>&1 ; then |
| [ -x `command -v tail` ] || FAIL=1 ; else FAIL=1 ; fi |
| |
| if [ "$FAIL" = 1 ] ; then |
| echo 1>&2 "$PRG: \`find', \`head', or \`tail' could not be found, aborting." |
| return 1 |
| else |
| return 0 |
| fi |
| } |
| |
| ## parse command line switches. |
| if [ $# != 0 ] ; then |
| while true ; do |
| case "$1" in |
| -V|--version) |
| version |
| exit 0 |
| ;; |
| -h|--help) |
| usage |
| exit 0 |
| ;; |
| --debug) |
| DEBUG=1 |
| shift |
| ;; |
| -*) |
| echo 1>&2 "$PRG: unrecognized option \`$1'" |
| echo 1>&2 "$PRG: Try \`$PRG --help' for more information." |
| exit 1 |
| ;; |
| "") |
| echo 1>&2 "$PRG: You must specify a filename" |
| echo 1>&2 "Try \`$PRG --help' for more information." |
| exit 1 |
| ;; |
| *) |
| device="$1" |
| break |
| ;; |
| esac |
| done |
| else |
| echo 1>&2 "$PRG: You must specify a /dev device" |
| echo 1>&2 "Try \`$PRG --help' for more information." |
| 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 Linux-based system, other kernels does not |
| ## have the same /proc stuff |
| if [ "`uname -s`" != Linux ] ; then |
| echo 1>&2 "$PRG: This utility will only work with Linux" |
| exit 1 |
| fi |
| |
| ## check for ppc, i think uname -m is safe for this... |
| machine="`uname -m`" |
| if [ "$machine" != ppc -a "$machine" != ppc64 ] ; then |
| echo 1>&2 "$PRG: This utility will only work on PowerPC hardware" |
| exit 1 |
| fi |
| unset machine |
| |
| ## ofpath cannot live without procfs |
| if [ ! -f /proc/uptime ] ; then |
| echo 1>&2 "$PRG: This utility requires the /proc filesystem" |
| exit 1 |
| fi |
| |
| ## check for retarded devfs names and tell them to foad. |
| if ckdevfs "$device" ; then |
| device="$(fixdevfs $device)" || exit 1 |
| fi |
| |
| ## check for newworld mac. use cat hack due to /proc wierdness. |
| if [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:[ ]})" = NewWorld ] ; then |
| SUBARCH=NewWorld |
| elif [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:[ ]})" = OldWorld ] ; then |
| SUBARCH=OldWorld |
| 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 ^platform | grep -q 'Maple'; then |
| SUBARCH=Maple |
| 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 |
| fi |
| |
| ## make sure /proc/device-tree exists |
| if [ ! -d /proc/device-tree ] ; then |
| echo 1>&2 "$PRG: /proc/device-tree does not exist" |
| echo 1>&2 "$PRG: Make sure you compiled your kernel with CONFIG_PROC_DEVICETREE=y" |
| exit 1 |
| fi |
| |
| ## make sure we have what we need. |
| checkutils || exit 1 |
| |
| ## get the base device node and scrap /dev/ ie /dev/hda2 -> hda |
| DEVICE="${device##*/}" |
| DEVNODE="${DEVICE%%[0-9]*}" |
| PARTITION="${DEVICE##*[a-z]}" |
| |
| ## use appropriate search for right sub arch. |
| case "$SUBARCH" in |
| # Pegasos OF seems to be NewWorld-ish enough to cope with this. |
| NewWorld|Pegasos) |
| newworld || exit 1 |
| ;; |
| OldWorld) |
| oldworld || exit 1 |
| ;; |
| CHRP|Maple) |
| chrp || exit 1 |
| ;; |
| esac |
| |
| exit 0 |