3 ###############################################################################
5 ## ofpath: determine OpenFirmware path from unix device node
6 ## Copyright (C) 2000, 2001, 2002, 2003 Ethan Benson
8 ## Portions based on show_of_path.sh:
10 ## Copyright (C) 2000 Olaf Hering <olh@suse.de>
12 ## This program is free software; you can redistribute it and/or
13 ## modify it under the terms of the GNU General Public License
14 ## as published by the Free Software Foundation; either version 2
15 ## of the License, or (at your option) any later version.
17 ## This program is distributed in the hope that it will be useful,
18 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ## GNU General Public License for more details.
22 ## You should have received a copy of the GNU General Public License
23 ## along with this program; if not, write to the Free Software
24 ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 ###############################################################################
28 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
39 Written by Ethan Benson
40 Portions based on show_of_path.sh written by Olaf Hering
42 Copyright (C) 2000, 2001, 2002, 2003 Ethan Benson
43 Portions Copyright (C) 2000 Olaf Hering
44 This is free software; see the source for copying conditions. There is NO
45 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
52 "Usage: $PRG [OPTION]... FILE
53 Find OpenFirmware device path from unix device node.
55 --debug print boring junk only useful for debugging
56 -h, --help display this help and exit
57 -V, --version output version information and exit"
60 ## a small seq replacement, seq is not present on boot/rescue floppies.
66 while [ "$v" -gt 1 ] ; do
74 ## a kludge to replace wc -l, wc is not present on boot/rescue
75 ## floppies. max file is 145 lines, 3 hosts * 16 devs each * 3 lines
76 ## per device, + 1 "Attached Devices:" line.
83 local file="$(cat $1)"
87 if [ -z "$file" ] ; then
92 ## use real wc if available
93 if (command -v wc > /dev/null 2>&1) ; then
94 if [ -x `command -v wc` ] ; then
95 lines="$(echo "$file" | wc -l)"
105 for i in `smallseq 145` ; do
106 local b="$(echo "$file" | tail -n $i)"
107 if [ "$v" = "$b" ] ; then
116 ## small tr replacment which handles a specific need of this script.
119 local i a d t val out mod cur
124 d=$(printf "%d\n" \'${val:0:1})
126 if (( $d > 57 )) ; then # is a letter
127 for ((i=0; i < ${#val}; i++)) ; do
128 d=$(printf "%d\n" \'${val:$i:1})
138 while ((t != 0)) ; do
141 if (($mod == 0)) ; then
146 cur=$(echo $mod | gawk '{printf "%c", $1}')
157 ## replacment for grep -l which is not supported by busybox grep.
158 ## echo $(cat..) hack needed because busybox grep barfs with `line too
159 ## long' when fed /proc files. the for loop is needed since busybox
160 ## grep seems to have somewhat broken regexp support.
161 ## usage: lgrep filename regexp regexp ...
167 echo "$(cat "$f")" | grep -q "$i" && echo "$f" && break
172 ## if readlink is missing use a kludge
173 if (command -v readlink > /dev/null 2>&1) ; then
178 local SYMTARGET="$(v=`ls -l "$1" 2>/dev/null` ; echo ${v##*> })"
179 if [ -n "$SYMTARGET" ] ; then
188 ## a function to print relevant scsi host path when there is more then
189 ## one. this function also takes care of stripping off the trailing
210 ## this finds information we need on both newworld and oldworld macs.
211 ## mainly what scsi host a disk is attached to.
214 ## see if system has scsi at all
215 if [ ! -f /proc/scsi/scsi ] ; then
216 local kver="$(uname -r)"
219 if [ -d /sys/bus/scsi/devices -a \
220 -n "$(ls /sys/bus/scsi/devices 2>/dev/null)" ] ; then
221 echo 1>&2 "$PRG: /proc/scsi/scsi does not exist"
222 echo 1>&2 "$PRG: Make sure you compiled your kernel with CONFIG_SCSI_PROC_FS=y"
227 echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
231 ## first we have to figure out the SCSI ID, have to do that
232 ## anyway [to] find the attached scsi disks = "Direct-Access" and
233 ## stop at sda=1 sdb=2 or whatever count in 3 lines steps
235 ## get last letter of device node, ie sda -> a
236 SUBNODE=${DEVNODE##*sd}
238 ## turn SUBNODE above into a number starting at 1, ie a -> 1
239 SUBDEV="$(smalltr $SUBNODE)"
240 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: SUBNODE=$SUBNODE SUBDEV=$SUBDEV"
244 ## copy scsi file into a variable removing "Attached Devices"
245 ## which is the first line. this avoids a lot of
246 ## [incmopatible] crap later, and improves readability.
248 ## find number of lines once and recycle that number, to save
249 ## some time (linecount is a bit slow). subtract one line
250 ## to scrap Attached Devices:
252 SCSILINES="$(($(linecount /proc/scsi/scsi) - 1))"
254 if [ "$SUBDEV" -gt "$(cat /proc/scsi/scsi | grep Direct-Access | linecount)" ] ; then
255 echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
259 PROCSCSI="$(cat /proc/scsi/scsi | tail -n $SCSILINES)"
261 for i in $(smallseq $(($SCSILINES / 3))) ; do
263 ## put every scsi device into one single line
264 DEVINFO="$(echo "$PROCSCSI" | head -n $(($i * 3)) | tail -n 3)"
265 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVINFO=$DEVINFO"
267 ## cut the type field, expect "Direct-Access" later.
268 DEVTYPE="$(v=$(echo ${DEVINFO##*Type: }) ; echo ${v%% *})"
269 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVTYPE=$DEVTYPE"
271 ## get the device LUN.
272 DEVLUN="$(v=$(echo ${DEVINFO##*Lun: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
273 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVLUN=$DEVLUN"
275 ## get the device id.
276 DEVID="$(v=$(echo ${DEVINFO##*Id: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
277 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVID=$DEVID"
279 ## get the device bus.
280 DEVBUS="$(v=$(echo ${DEVINFO##*Channel: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
281 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVBUS=$DEVBUS"
283 ## get the scsi host id.
284 DEVHOST="$(v=$(echo ${DEVINFO##*Host: scsi}) ; echo ${v%% *})"
285 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVHOST=$DEVHOST"
287 if [ "$DEVTYPE" = "Direct-Access" ] || [ "$DEVTYPE" = "Direct-Access-RBC" ] ; then
288 ls /sys/bus/scsi/devices/$DEVHOST:$DEVBUS:$DEVID:$DEVLUN/scsi_disk* > /dev/null 2>&1
289 if [ $? -eq 0 ] ; then
290 DEVCOUNT="$(($DEVCOUNT + 1))"
291 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVCOUNT=$DEVCOUNT"
292 if [ "$SUBDEV" = "$DEVCOUNT" ] ; then
297 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVICE_HOST=$DEVICE_HOST"
304 ## figure out what the scsi driver is, it is /proc/scsi/dirname.
305 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVICE_HOST=$DEVICE_HOST"
306 SCSI_DRIVER="$(x=`ls /proc/scsi/*/$DEVICE_HOST 2>/dev/null | cat` ; y=`echo ${x##*proc/scsi/}` ; echo ${y%%/*})"
307 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: SCSI_DRIVER=$SCSI_DRIVER"
309 ## figure out which host we found.
310 SCSI_HOSTNUMBER="$(v=`ls /proc/scsi/$SCSI_DRIVER/* 2>/dev/null | cat | grep -n "$DEVICE_HOST\>"` ; echo ${v%%:*})"
311 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: SCSI_HOSTNUMBER=$SCSI_HOSTNUMBER"
324 while [[ $PWD != "/" ]]; do
325 ls $ATTR > /dev/null 2>&1
326 if [[ $? -eq 0 ]]; then
336 echo 1>&2 "$PRG: Cannot find $RET for $DEVICE"
343 local DEVICE="$DEVICE_HOST:$DEVICE_BUS:$DEVICE_ID:$DEVICE_LUN"
344 local START="/sys/bus/scsi/devices/$DEVICE"
346 read_attr $ATTR $START
352 local DEVICE="$DEVICE_HOST:$DEVICE_BUS:$DEVICE_ID:$DEVICE_LUN"
353 local START="/sys/bus/scsi/devices/$DEVICE/.."
355 read_attr $ATTR $START
363 B=$((0x$DEVICE_ID << 8))
364 C=$((0x$DEVICE_BUS << 5))
369 vdiskno=$((0x8000 | $B | $C | $D ))
372 vdisk=$(printf "%x" $vdisk)
373 local extrazeroes="000000000000"
374 echo $vdisk$extrazeroes
382 A=$(( ($lunint >> 8) & 0xff ))
383 B=$(($lunint & 0xff))
384 C=$(( ($lunint >> 24) & 0xff ))
385 D=$(( ($lunint >> 16) & 0xff ))
387 local lunstr=$(printf "%02x%02x%02x%02x00000000" $A $B $C $D)
388 lunstr=$(echo $lunstr | sed 's/^[0]*//')
394 local L=$(echo "$DEVICE_LUN"|gawk '{$1=tolower($1);print}')
397 local fc_lun=$(int_to_scsilun $L)
405 for f in `find -H $start_dir -maxdepth 2 -name port_name`; do
410 # strip the leading 0x
417 local DEVSPEC=$(read_parent_attr devspec)
418 local COMPAT=$(cat "/proc/device-tree$DEVSPEC/compatible")
419 local DEVICE_PATH="/sys/bus/scsi/devices/$DEVICE_HOST:$DEVICE_BUS:$DEVICE_ID:$DEVICE_LUN"
423 local vdisk=$(get_vdisk_lun)
424 if [[ $PARTITION = "" ]]; then
425 echo "$DEVSPEC/disk@$vdisk"
427 echo "$DEVSPEC/disk@$vdisk:$PARTITION"
432 local vfc_lun=$(get_fc_scsilun)
433 local wwpn=$(get_fc_wwpn "$DEVICE_PATH/../../fc_remote_ports*")
434 if [[ $DEVICE_LUN != "0" ]]; then
435 local vfc_lun=$(get_fc_scsilun)
436 echo "$DEVSPEC/disk@$wwpn,$vfc_lun"
438 echo "$DEVSPEC/disk@$wwpn"
446 if [[ -d "/proc/device-tree$DEVSPEC/sas" ]]; then
447 local vendor_id=$(read_parent_attr vendor)
450 if [[ $vendor_id = "0x1000" ]]; then
451 sas_addr=$(read_dev_attr sas_address)
452 sas_addr=${sas_addr##0x}
453 if [[ $DEVICE_LUN != "0" ]]; then
454 local LUN=$(int_to_scsilun $DEVICE_LUN)
455 echo "$DEVSPEC/sas/disk@$sas_addr,$LUN"
457 echo "$DEVSPEC/sas/disk@$sas_addr"
463 if [[ -e /sys/class/scsi_host/host$DEVICE_HOST/fw_type ]]; then
464 fwtype=$(cat /sys/class/scsi_host/host$DEVICE_HOST/fw_type)
467 if [[ $fwtype = "1" ]]; then
468 sas_addr=$(read_dev_attr device_id)
469 sas_addr=${sas_addr##0x}
470 if [[ $DEVICE_LUN != "0" ]]; then
471 local LUN=$(int_to_scsilun $DEVICE_LUN)
472 echo "$DEVSPEC/sas/disk@$sas_addr,$LUN"
474 echo "$DEVSPEC/sas/disk@$sas_addr"
479 B=$(echo "$DEVICE_BUS"|gawk '{$1=tolower($1);print}')
481 T=$(echo "$DEVICE_ID"|gawk '{$1=tolower($1);print}')
483 L=$(echo "$DEVICE_LUN"|gawk '{$1=tolower($1);print}')
486 sas_addr=$(( ($B << 16) | ($T << 8) | $L ))
487 if [[ $DEVICE_LUN != "0" ]]; then
488 printf "%s/sas/disk@%x,%x\n" $DEVSPEC $sas_addr $DEVICE_LUN
490 printf "%s/sas/disk@%x\n" $DEVSPEC $sas_addr
496 local fc=${DEVSPEC%@*}
499 if [[ -e /proc/device-tree$DEVSPEC/device_type ]]; then
500 local devtype=$(cat /proc/device-tree$DEVSPEC/device_type);
501 if [[ $devtype = "fcp" || $devtype = "scsi-fcp" ]]; then
506 if [[ $fc = "fibre-channel" ]]; then
507 local wwpn=$(get_fc_wwpn "$DEVICE_PATH/../../fc_remote_ports*")
508 local ofpath=$DEVSPEC
510 if [[ ! -e /proc/device-tree$DEVSPEC/disk ]]; then
511 for dir in `find /proc/device-tree$DEVSPEC -type d`; do
512 if [[ -e $dir/disk ]]; then
513 ofpath=${dir##/proc/device-tree}
519 ofpath=$(printf "%s/disk@%s" $ofpath $wwpn)
521 if [[ $DEVICE_LUN != "0" ]]; then
522 local fc_lun=$(get_fc_scsilun $DEVICE_LUN)
523 ofpath=$(printf "%s,%s" $ofpath $fc_lun)
530 echo 1>&2 "$PRG: Driver: $SCSI_DRIVER is not supported"
534 ## generic function that can find OF device paths for scsi devices,
535 ## must be run after scsiinfo().
538 case "$SCSI_DRIVER" in
540 HOST_LIST="$(for i in `find /proc/device-tree -name compatible` ; do
541 lgrep "$i" "^ADPT" "^pci900[45]" "^pciclass,01000" ; done)"
542 DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
543 echo "${DEVICE_PATH##*device-tree}/@$DEVICE_ID:$PARTITION"
546 HOST_LIST="$(for i in `find /proc/device-tree -name compatible` ; do
547 lgrep "$i" "^Symbios" "^pci1000" "^pciclass,01000" ; done)"
548 DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
549 echo "${DEVICE_PATH##*device-tree}/@$DEVICE_ID:$PARTITION"
552 HOST_LIST="$(for i in `find /proc/device-tree -name compatible` ; do
553 lgrep "$i" "mesh" ; done)"
554 DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
555 echo "${DEVICE_PATH##*device-tree}/@$DEVICE_ID:$PARTITION"
558 #Not all G5 device trees have a compatible "k2-sata" node
559 #per channel use parent
560 HOST_LIST="$(for i in `find /proc/device-tree -name compatible ` ; do
561 lgrep "$i" "k2-s-ata" ; done | sort)"
562 DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
564 while [ "$DEVICE_PATH" = "" ] ; do
565 SCSI_HOSTNUMBER=`expr $SCSI_HOSTNUMBER - 1`
566 let "K2_DEVICE_ID += 1"
567 DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
569 echo "${DEVICE_PATH##*device-tree}/k2-sata@$K2_DEVICE_ID/disk@0:$PARTITION"
572 HOST_LIST="$(for i in `find /proc/device-tree -name name | grep usb` ; do
573 lgrep "$i" "disk" ; done)"
574 DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
575 echo "${DEVICE_PATH##*device-tree}:$PARTITION"
578 # sbp-2 driver may not have a dir in /proc/scsi
579 HOST_LIST="$(for i in `find /proc/device-tree -name name` ; do
580 lgrep "$i" "sbp-2" ; done)"
581 if [ "$HOST_LIST" = "" ] ; then
584 if [ "$SCSI_HOSTNUMBER" = "" ] ; then
587 DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
588 echo "${DEVICE_PATH##*device-tree}/disk@0:$PARTITION"
592 echo 1>&2 "$PRG: Driver: $SCSI_DRIVER is not supported"
601 if [ ! -L "/proc/ide/$DEVNODE" ] ; then
602 echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
606 local IDEBUS="$(v=`readlink /proc/ide/$DEVNODE` ; echo ${v%%/*} )"
607 if [ -z "$IDEBUS" ] ; then
608 echo 1>&2 "$PRG: BUG: IDEBUS == NULL"
612 case "$(uname -r)" in
613 2.5.*|2.6.0*|2.6.1|2.6.1-*|2.6.2|2.6.2-*)
614 echo 1>&2 "$PRG: Linux kernel `uname -r` is not supported"
618 if ! (grep -q '.* .* sysfs ' /proc/mounts 2> /dev/null) ; then
619 echo 1>&2 "$PRG: sysfs must be mounted for ofpath to support this system"
622 local SYS="$(m=`grep '.* .* sysfs ' /proc/mounts | head -n 1` ; echo `d=${m#* };echo ${d%% *}`)"
623 if [ -z "$SYS" -o ! -d "$SYS" ] ; then
624 echo 1>&2 "$PRG: Unable to determine sysfs mountpoint"
627 local OF1275IDE="${SYS}/block/${DEVNODE}/device/../../devspec"
630 local OF1275IDE="/proc/ide/$IDEBUS/devspec"
634 if [ ! -f "$OF1275IDE" ] ; then
635 case "$(cat /proc/device-tree/model)" in
636 PowerMac3*|PowerMac4*|PowerMac5*|PowerMac6*|PowerMac7*|RackMac*)
637 local CDROM="$(grep "^drive name:" /proc/sys/dev/cdrom/info 2> /dev/null | grep $DEVNODE)"
638 if [ -z "$CDROM" ] ; then
639 echo 1>&2 "$PRG: WARNING: Your kernel is too old for proper support, device may be innaccurate."
640 echo "ultra2:$PARTITION"
646 local CDROM="$(grep "^drive name:" /proc/sys/dev/cdrom/info 2> /dev/null | grep $DEVNODE)"
647 if [ -z "$CDROM" ] ; then
648 if [ "$DEVNODE" = hda ] ; then
651 echo "ultra1:$PARTITION"
659 local DEVSPEC="$(cat $OF1275IDE)"
660 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVSPEC=$DEVSPEC"
661 if [ -z "$DEVSPEC" ] ; then
662 echo 1>&2 "$PRG: KERNEL BUG: $OF1275IDE exists, but is empty"
666 if [ ! -f "/proc/ide/${IDEBUS}/channel" ] ; then
667 echo 1>&2 "$PRG: KERNEL BUG: /proc/ide/${IDEBUS}/channel does not exist"
671 case "$(cat /proc/device-tree${DEVSPEC}/device_type 2> /dev/null)" in
673 local MASTER="/disk@0"
674 local SLAVE="/disk@1"
677 local MASTER="/@$(cat /proc/ide/${IDEBUS}/channel)/disk@0"
678 local SLAVE="/@$(cat /proc/ide/${IDEBUS}/channel)/disk@1"
680 scsi) ## some lame controllers pretend they are scsi, hopefully all kludges are created equal.
681 local MASTER="/@$(($(cat /proc/ide/${IDEBUS}/channel) * 2 + 0))"
682 local SLAVE="/@$(($(cat /proc/ide/${IDEBUS}/channel) * 2 + 1))"
685 local MASTER="/disk@$(cat /proc/ide/${IDEBUS}/channel),0"
686 local SLAVE="/disk@$(cat /proc/ide/${IDEBUS}/channel),1"
689 echo 1>&2 "$PRG: Unsupported IDE device type: \"$(cat /proc/device-tree${DEVSPEC}/device_type 2> /dev/null)\""
695 hda|hdc|hde|hdg|hdi|hdk|hdm|hdo)
696 echo "${DEVSPEC}${MASTER}:$PARTITION"
699 hdb|hdd|hdf|hdh|hdj|hdl|hdn|hdp)
700 echo "${DEVSPEC}${SLAVE}:$PARTITION"
704 echo 1>&2 "$PRG: /dev/$DEVNODE is not supported"
711 ## figure out the OpenFirmware device path for newworld macs.
712 ## sd* scsi disks , hd* ide disks.
717 ## use common scsiinfo function to get info we need.
720 ## now we have the data for /@$DEVID:$PARTITION
721 ## find the actual OF path.
722 scsi_ofpath || return 1
725 ide_ofpath || return 1
728 echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
737 ## for some reason 2.4 kernels put OF aliases in aliases@0/ instead of plain aliases/
738 if [ -d "/proc/device-tree/aliases" ] ; then
739 local ALIASES="aliases"
740 elif [ -d "/proc/device-tree/aliases@0" ] ; then
741 local ALIASES="aliases@0"
743 echo 1>&2 "$PRG: Cannot find OpenFirmware aliases directory in /proc/device-tree/"
747 local MODEL="$(cat /proc/device-tree/compatible)"
748 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: Oldworld subarch: $MODEL"
751 AAPL,7300*|AAPL,7500*|AAPL,8500*|AAPL,9500*|AAPL,\?\?\?\?*)
755 case "$SCSI_DRIVER" in
757 echo $(cat /proc/device-tree/$ALIASES/scsi-int)/sd\@$DEVICE_ID:$PARTITION
760 echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
763 echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
769 echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE"
778 case "$SCSI_DRIVER" in
780 echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
783 echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
789 echo $(cat /proc/device-tree/$ALIASES/ata)/ATA-Disk\@0:$PARTITION
792 echo $(cat /proc/device-tree/$ALIASES/ata)/ATA-Disk\@1:$PARTITION
795 echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
803 case "$SCSI_DRIVER" in
805 echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
808 echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
814 echo $(cat /proc/device-tree/$ALIASES/ata)/ata-disk\@0:$PARTITION
817 echo $(cat /proc/device-tree/$ALIASES/ata)/ata-disk\@1:$PARTITION
820 echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
824 AAPL,Gossamer*|AAPL,PowerMac\ G3*)
828 case "$SCSI_DRIVER" in
830 echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
833 echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
839 echo $(cat /proc/device-tree/$ALIASES/ide0)/ata-disk\@0:$PARTITION
842 echo $(cat /proc/device-tree/$ALIASES/ide0)/ata-disk\@1:$PARTITION
845 echo $(cat /proc/device-tree/$ALIASES/ide1)/ata-disk\@0:$PARTITION
848 echo $(cat /proc/device-tree/$ALIASES/ide1)/ata-disk\@1:$PARTITION
851 echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
856 if [ -f /proc/device-tree/$ALIASES/ata0 ] ; then
861 if [ -f /proc/device-tree/$ALIASES/ata1 ] ; then
869 case "$SCSI_DRIVER" in
871 echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITON
874 echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
880 echo $(cat /proc/device-tree/$ALIASES/$ATA0)/ata-disk\@0:$PARTITION
883 echo $(cat /proc/device-tree/$ALIASES/$ATA0)/ata-disk\@1:$PARTITION
886 echo $(cat /proc/device-tree/$ALIASES/$ATA1)/atapi-disk\@0:$PARTITION
889 echo $(cat /proc/device-tree/$ALIASES/$ATA1)/atapi-disk\@1:$PARTITION
892 echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE"
901 case "$SCSI_DRIVER" in
903 echo $(cat /proc/device-tree/$ALIASES/scsi-int)/sd\@$DEVICE_ID:$PARTITON
906 echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITON
909 echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
915 echo $(cat /proc/device-tree/$ALIASES/ata0)/ata-disk\@0:$PARTITION
918 echo $(cat /proc/device-tree/$ALIASES/ata0)/ata-disk\@1:$PARTITION
921 echo $(cat /proc/device-tree/$ALIASES/ata1)/atapi-disk\@0:$PARTITION
924 echo $(cat /proc/device-tree/$ALIASES/ata1)/atapi-disk\@1:$PARTITION
927 echo $(cat /proc/device-tree/$ALIASES/ata2):$PARTITION
930 echo $(cat /proc/device-tree/$ALIASES/ata3):$PARTITION
933 echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE"
939 echo 1>&2 "$PRG: This machine is not supported: $MODEL"
948 read_attr devspec /sys/class/net/$DEVICE/device
953 local hfnum=${DEVICE##hf}
956 if [[ $hfnum = "0" || $hfnum = "2" ]]; then
957 hfpath=$(find /proc/device-tree -name hfi-ethernet* | sort | head -n 1)
958 elif [[ $hfnum = "1" || $hfnum = "3" ]]; then
959 hfpath=$(find /proc/device-tree -name hfi-ethernet* | sort | tail -n 1)
961 echo 1>&2 "$PRG: Unsupported device: $DEVICE"
965 hfpath=${hfpath##/proc/device-tree}
969 ## find OpenFirmware device path for IBM CHRP hardware (scsi only)
975 ## use common scsiinfo function to get info we need.
978 ## now we have the data for /@$DEVID:$PARTITION
979 ## find the actual OF path.
980 scsi_ofpath || return 1
983 eth_ofpath || return 1
986 hfi_ofpath || return 1
989 echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
996 ## If we get lame devfs name, we need to make it foad
1000 /dev/ide/*|/dev/scsi/*|/dev/discs/*)
1009 ## convert devfs names into normal short ones, written by Tom Rini.
1012 ## get partition number, if any
1013 local PARTNUM="${1##*[a-z]}"
1014 ## Find the bus type.
1015 local TYPE="$(v=${1#/dev/} ; echo ${v%/host*})"
1016 ## Find the host number.
1017 local HOST="$(v=${1#/dev/*/host} ; echo ${v%/bus*})"
1018 ## Find the bus number.
1019 local BUS="$(v=${1#/dev/*/bus} ; echo ${v%/tar*})"
1021 local TARGET="$(v=${1#/dev/*/target} ; echo ${v%/lun*})"
1047 echo 1>&2 "$PRG: $1: Unable to translate this device, try again without devfs."
1050 local DEV="${DEV}${PARTNUM}"
1055 local LUN="$(v=${1#/dev/*/lun} ; echo ${v%/*})"
1057 ## In this case, we need to figure out what number our device is
1060 ## copy scsi file into a variable removing "Attached Devices"
1061 ## which is the first line. this avoids a lot of
1062 ## [incmopatible] crap later, and improves readability.
1064 ## find number of lines once and recycle that number, to save
1065 ## some time (linecount is a bit slow). subtract one line
1066 ## to scrap Attached Devices:
1068 local SCSILINES="$(($(linecount /proc/scsi/scsi) - 1))"
1069 local PROCSCSI="$(cat /proc/scsi/scsi | tail -n $SCSILINES)"
1071 for i in $(smallseq $(($SCSILINES / 3))) ; do
1073 ## put every scsi device into one single line
1074 local DEVINFO="$(echo "$PROCSCSI" | head -n $(($i * 3)) | tail -n 3)"
1075 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVINFO=$DEVINFO"
1077 ## cut the type field, expect "Direct-Access" later.
1078 local DEVTYPE="$(v=$(echo ${DEVINFO##*Type: }) ; echo ${v%% *})"
1079 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVTYPE=$DEVTYPE"
1081 if [ "$DEVTYPE" = "Direct-Access" ] || [ "$DEVTYPE" = "Direct-Access-RBC" ] ; then
1082 ## Lets find out some more information
1083 ## get the device id.
1084 local DEVID="$(v=$(echo ${DEVINFO##*Id: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
1085 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVID=$DEVID"
1087 ## get the device lun.
1088 local DEVLUN="$(v=$(echo ${DEVINFO##*Lun: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
1089 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVLUN=$DEVLUN"
1091 ## get the device channel.
1092 local DEVCHAN="$(v=$(echo ${DEVINFO##*Channel: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
1093 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVCHAN=$DEVCHAN"
1095 ## get the scsi host id.
1096 local DEVHOST="$(v=$(echo ${DEVINFO##*Host: scsi}) ; echo ${v%% *})"
1097 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVHOST=$DEVHOST"
1099 local DEVCOUNT="$(($DEVCOUNT + 1))"
1100 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVCOUNT=$DEVCOUNT"
1101 if [ "$DEVHOST" = "$HOST" -a "$DEVCHAN" = "$BUS" -a \
1102 "$DEVID" = "$TARGET" -a "$DEVLUN" = "$LUN" ] ; then
1103 local DEV="sd$(smalltr $DEVCOUNT)${PARTNUM}"
1109 echo 1>&2 "$PRG: $1: Unable to translate this device, try again without devfs."
1113 echo 1>&2 "$PRG: Unknown bus $TYPE"
1117 ## we should never get here
1121 ## make sure that find, head and tail can be found. otherwise the
1122 ## script will silently give bogus paths. these are the only /usr/*
1123 ## utilities this script depends on.
1126 if command -v find > /dev/null 2>&1 ; then
1127 [ -x `command -v find` ] || FAIL=1 ; else FAIL=1 ; fi
1128 if command -v head > /dev/null 2>&1 ; then
1129 [ -x `command -v head` ] || FAIL=1 ; else FAIL=1 ; fi
1130 if command -v tail > /dev/null 2>&1 ; then
1131 [ -x `command -v tail` ] || FAIL=1 ; else FAIL=1 ; fi
1133 if [ "$FAIL" = 1 ] ; then
1134 echo 1>&2 "$PRG: \`find', \`head', or \`tail' could not be found, aborting."
1141 ## parse command line switches.
1142 if [ $# != 0 ] ; then
1158 echo 1>&2 "$PRG: unrecognized option \`$1'"
1159 echo 1>&2 "$PRG: Try \`$PRG --help' for more information."
1163 echo 1>&2 "$PRG: You must specify a filename"
1164 echo 1>&2 "Try \`$PRG --help' for more information."
1174 echo 1>&2 "$PRG: You must specify a /dev device"
1175 echo 1>&2 "Try \`$PRG --help' for more information."
1179 ## check that we are running on a GNU/Linux system, OSX/BSD does not
1180 ## have the same /proc stuff
1181 if [ `uname -s` != Linux ] ; then
1182 echo 1>&2 "$PRG: This utility will only work with GNU/Linux"
1186 ## check for ppc, i think uname -m is safe for this...
1187 if [ `uname -m` != ppc -a `uname -m` != ppc64 ] ; then
1188 echo 1>&2 "$PRG: This utility will only work on PowerPC hardware"
1192 ## ofpath cannot live without procfs
1193 if [ ! -f /proc/uptime ] ; then
1194 echo 1>&2 "$PRG: This utility requires the /proc filesystem"
1198 ## check for retarded devfs names and tell them to foad.
1199 if ckdevfs "$device" ; then
1200 device="$(fixdevfs $device)" || exit 1
1203 ## check for newworld mac. use cat hack due to /proc wierdness.
1204 if [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:[ ]})" = NewWorld ] ; then
1206 elif [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:[ ]})" = OldWorld ] ; then
1208 elif (cat /proc/cpuinfo 2>/dev/null | grep ^motherboard | grep -q AAPL) ; then
1210 elif (cat /proc/cpuinfo 2> /dev/null | grep ^machine | grep -q 'CHRP IBM') ; then
1212 elif (cat /proc/cpuinfo 2>/dev/null | grep ^machine | grep -q 'CHRP Pegasos') ; then
1215 echo 1>&2 "$PRG: This machine is not yet supported"
1219 ## make sure /proc/device-tree exists
1220 if [ ! -d /proc/device-tree ] ; then
1221 echo 1>&2 "$PRG: /proc/device-tree does not exist"
1222 echo 1>&2 "$PRG: Make sure you compiled your kernel with CONFIG_PROC_DEVICETREE=y"
1226 ## make sure we have what we need.
1227 checkutils || exit 1
1229 ## get the base device node and scrap /dev/ ie /dev/hda2 -> hda
1230 DEVICE="${device##*/}"
1231 DEVNODE="${DEVICE%%[0-9]*}"
1232 PARTITION="${DEVICE##*[a-z]}"
1234 ## use appropriate search for right sub arch.
1236 # Pegasos OF seems to be NewWorld-ish enough to cope with this.