]> git.ozlabs.org Git - yaboot.git/blob - ybin/ofpath
fs_of: Increase the LOAD_BUFFER_SIZE to 32MB
[yaboot.git] / ybin / ofpath
1 #! /bin/sh
2
3 ###############################################################################
4 ##
5 ## ofpath: determine OpenFirmware path from unix device node
6 ## Copyright (C) 2000, 2001, 2002, 2003 Ethan Benson
7 ##
8 ## Portions based on show_of_path.sh:
9 ##
10 ## Copyright (C) 2000 Olaf Hering <olh@suse.de>
11 ##
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.
16 ##
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.
21 ##
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.
25 ##
26 ###############################################################################
27
28 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
29 PRG="${0##*/}"
30 VERSION=1.0.7
31 DEBUG=0
32 export LC_COLLATE=C
33
34 ## --version output.
35 version()
36 {
37 echo \
38 "$PRG $VERSION
39 Written by Ethan Benson
40 Portions based on show_of_path.sh written by Olaf Hering
41
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."
46 }
47
48 ## --help output.
49 usage()
50 {
51 echo \
52 "Usage: $PRG [OPTION]... FILE
53 Find OpenFirmware device path from unix device node.
54
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"
58 }
59
60 ## a small seq replacement, seq is not present on boot/rescue floppies.
61 smallseq()
62 {
63     local v="$1"
64     local n=1
65     echo 1
66     while [ "$v" -gt 1 ] ; do
67         echo "$(($n + 1))"
68         local n="$(($n + 1))"
69         local v="$(($v - 1))"
70     done
71     return 0
72 }
73
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.
77 linecount()
78 {
79     if [ $# = 0 ] ; then
80         local file="$(cat)"
81         local v="$file"
82     else
83         local file="$(cat $1)"
84         local v="$file"
85     fi
86
87     if [ -z "$file" ] ; then
88         echo 0
89         return 0
90     fi
91
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)"
96             if [ $? = 0 ] ; then
97                 echo $lines
98                 unset lines
99                 return 0
100             fi
101         fi
102     fi
103
104     while true ; do
105         for i in `smallseq 145` ; do
106             local b="$(echo "$file" | tail -n $i)"
107             if [ "$v" = "$b" ] ; then
108                 echo "$i"
109                 break 2
110             fi
111         done
112     done
113     return 0
114 }
115
116 ## small tr replacment which handles a specific need of this script.
117 smalltr()
118 {
119         local i a d t val out mod cur
120
121         val="$1"
122         out="0"
123
124         d=$(printf "%d\n" \'${val:0:1})
125
126         if (( $d > 57 )) ; then  # is a letter
127                 for ((i=0; i < ${#val}; i++)) ; do
128                         d=$(printf "%d\n" \'${val:$i:1})
129                         a=$(($d - 96))
130                         out=$(($out * 26))
131                         out=$(($out + $a))
132                 done
133
134         else  # is a number
135                 t=$val
136                 out=""
137
138                 while ((t != 0)) ; do
139                         mod=$(($t % 26))
140                         t=$(($t / 26))
141                         if (($mod == 0)) ; then
142                                 cur="z"
143                                 t=$(($t - 1))
144                         else
145                                 mod=$(($mod + 96))
146                                 cur=$(echo $mod | gawk '{printf "%c", $1}')
147                         fi
148                         out="$cur$out"
149                 done
150         fi
151
152         echo "$out"
153
154     return 0
155 }
156
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 ...
162 lgrep()
163 {
164     local f="$1"
165     shift
166     for i in "$@" ; do
167         echo "$(cat "$f")" | grep -q "$i" && echo "$f" && break
168     done
169     return 0
170 }
171
172 ## if readlink is missing use a kludge
173 if (command -v readlink > /dev/null 2>&1) ; then
174     true
175 else
176     readlink()
177     {
178         local SYMTARGET="$(v=`ls -l "$1" 2>/dev/null` ; echo ${v##*> })"
179         if [ -n "$SYMTARGET" ] ; then
180             echo "$SYMTARGET"
181             return 0
182         else
183             return 1
184         fi
185     }
186 fi
187
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
190 ## /compatible.
191 printhost()
192 {
193     case "$1" in
194         1)
195         echo "${2%/*}"
196         ;;
197         2)
198         echo "${3%/*}"
199         ;;
200         3)
201         echo "${4%/*}"
202         ;;
203         4)
204         echo "${5%/*}"
205         ;;
206     esac
207     return 0
208 }
209
210 ## this finds information we need on both newworld and oldworld macs.
211 ## mainly what scsi host a disk is attached to.
212 scsiinfo()
213 {
214     ## see if system has scsi at all
215     if [ ! -f /proc/scsi/scsi ] ; then
216         local kver="$(uname -r)"
217         case "$kver" in
218             2.5.*|2.6.*)
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"
223                     return 1
224                 fi
225                 ;;
226         esac
227         echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
228         return 1
229     fi
230
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
234
235     ## get last letter of device node, ie sda -> a
236     SUBNODE=${DEVNODE##*sd}
237
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"
241
242     DEVCOUNT=0
243
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.
247
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:
251
252     SCSILINES="$(($(linecount /proc/scsi/scsi) - 1))"
253
254     if [ "$SUBDEV" -gt "$(cat /proc/scsi/scsi | grep Direct-Access | linecount)" ] ; then
255         echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
256         return 1
257     fi
258
259     PROCSCSI="$(cat /proc/scsi/scsi | tail -n $SCSILINES)"
260
261     for i in $(smallseq $(($SCSILINES / 3))) ; do
262
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"
266
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"
270
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"
274
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"
278
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"
282
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"
286
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
293                         DEVICE_HOST=$DEVHOST
294                         DEVICE_BUS=$DEVBUS
295                         DEVICE_ID=$DEVID
296                         DEVICE_LUN=$DEVLUN
297                         [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVICE_HOST=$DEVICE_HOST"
298                         break
299                 fi
300             fi
301         fi
302     done
303
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"
308
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"
312
313     return 0
314 }
315
316 read_attr()
317 {
318         local ATTR=$1
319         local START=$2
320         local OLDDIR=$(pwd)
321         local RET
322
323         cd -P "$START"
324         while [[ $PWD != "/" ]]; do
325                 ls $ATTR > /dev/null 2>&1
326                 if [[ $? -eq 0 ]]; then
327                         RET=$(cat $ATTR)
328                         cd $OLDDIR
329                         echo "$RET"
330                         return 0
331                 fi
332                 cd ..
333         done
334
335         cd $OLDDIR
336         echo 1>&2 "$PRG: Cannot find $RET for $DEVICE"
337         exit 1
338 }
339
340 read_dev_attr()
341 {
342         local ATTR=$1
343         local DEVICE="$DEVICE_HOST:$DEVICE_BUS:$DEVICE_ID:$DEVICE_LUN"
344         local START="/sys/bus/scsi/devices/$DEVICE"
345
346         read_attr $ATTR $START
347 }
348
349 read_parent_attr()
350 {
351         local ATTR=$1
352         local DEVICE="$DEVICE_HOST:$DEVICE_BUS:$DEVICE_ID:$DEVICE_LUN"
353         local START="/sys/bus/scsi/devices/$DEVICE/.."
354
355         read_attr $ATTR $START
356 }
357
358 get_vdisk_lun()
359 {
360         local B C D
361         typeset -i B C D
362
363         B=$((0x$DEVICE_ID << 8))
364         C=$((0x$DEVICE_BUS << 5))
365         D=$((0x$DEVICE_LUN))
366
367         local vdiskno vdisk
368         typeset -i vdiskno
369         vdiskno=$((0x8000 | $B | $C | $D ))
370         vdisk=${vdiskno##-}
371
372         vdisk=$(printf "%x" $vdisk)
373         local extrazeroes="000000000000"
374         echo $vdisk$extrazeroes
375 }
376
377 int_to_scsilun()
378 {
379         local lunint=$1
380         local A B C D
381
382         A=$(( ($lunint >> 8) & 0xff ))
383         B=$(($lunint & 0xff))
384         C=$(( ($lunint >> 24) & 0xff ))
385         D=$(( ($lunint >> 16) & 0xff ))
386
387         local lunstr=$(printf "%02x%02x%02x%02x00000000" $A $B $C $D)
388         lunstr=$(echo $lunstr | sed 's/^[0]*//')
389         echo "$lunstr"
390 }
391
392 get_fc_scsilun()
393 {
394         local L=$(echo "$DEVICE_LUN"|gawk '{$1=tolower($1);print}')
395         L=$(printf "%d" $L)
396
397         local fc_lun=$(int_to_scsilun $L)
398         echo "$fc_lun"
399 }
400
401 get_fc_wwpn()
402 {
403         local start_dir=$1
404
405         for f in `find -H $start_dir -maxdepth 2 -name port_name`; do
406                 local wwpn=$(cat $f)
407                 break
408         done
409
410         # strip the leading 0x
411         wwpn=${wwpn:2}
412         echo "$wwpn"
413 }
414
415 scsi_ofpath2()
416 {
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"
420
421         case "$COMPAT" in
422             IBM,v-scsi)
423                 local vdisk=$(get_vdisk_lun)
424                 if [[ $PARTITION = "" ]]; then
425                         echo "$DEVSPEC/disk@$vdisk"
426                 else
427                         echo "$DEVSPEC/disk@$vdisk:$PARTITION"
428                 fi
429                 return 0
430                 ;;
431             IBM,vfc-client)
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"
437                 else
438                         echo "$DEVSPEC/disk@$wwpn"
439                 fi
440                 return 0
441                 ;;
442             *)
443                 ;;
444         esac
445
446         if [[ -d "/proc/device-tree$DEVSPEC/sas" ]]; then
447                 local vendor_id=$(read_parent_attr vendor)
448                 local sas_addr
449
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"
456                         else
457                                 echo "$DEVSPEC/sas/disk@$sas_addr"
458                         fi
459                         return 0
460                 fi
461
462                 local fwtype="0"
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)
465                 fi
466
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"
473                         else
474                                 echo "$DEVSPEC/sas/disk@$sas_addr"
475                         fi
476                 else
477                         local B T L
478
479                         B=$(echo "$DEVICE_BUS"|gawk '{$1=tolower($1);print}')
480                         B=$(printf "%d" $B)
481                         T=$(echo "$DEVICE_ID"|gawk '{$1=tolower($1);print}')
482                         T=$(printf "%d" $T)
483                         L=$(echo "$DEVICE_LUN"|gawk '{$1=tolower($1);print}')
484                         L=$(printf "%d" $L)
485
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
489                         else
490                                 printf "%s/sas/disk@%x\n" $DEVSPEC $sas_addr
491                         fi
492                 fi
493                 return 0
494         fi
495
496         local fc=${DEVSPEC%@*}
497         fc=${fc##/*/}
498
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
502                         fc="fibre-channel";
503                 fi
504         fi
505
506         if [[ $fc = "fibre-channel" ]]; then
507                 local wwpn=$(get_fc_wwpn "$DEVICE_PATH/../../fc_remote_ports*")
508                 local ofpath=$DEVSPEC
509
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}
514                                         break;
515                                 fi
516                         done
517                 fi
518
519                 ofpath=$(printf "%s/disk@%s" $ofpath $wwpn)
520
521                 if [[ $DEVICE_LUN != "0" ]]; then
522                         local fc_lun=$(get_fc_scsilun $DEVICE_LUN)
523                         ofpath=$(printf "%s,%s" $ofpath $fc_lun)
524                 fi
525
526                 echo "$ofpath"
527                 return 0
528         fi
529
530         echo 1>&2 "$PRG: Driver: $SCSI_DRIVER is not supported"
531         return 1
532 }
533
534 ## generic function that can find OF device paths for scsi devices,
535 ## must be run after scsiinfo().
536 scsi_ofpath()
537 {
538     case "$SCSI_DRIVER" in
539         aic7xxx)
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"
544             ;;
545         sym53c8xx)
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"
550             ;;
551         mesh)
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"
556             ;;
557         ata_k2|sata_svw)
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)"
563             K2_DEVICE_ID=0
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)"
568             done
569             echo "${DEVICE_PATH##*device-tree}/k2-sata@$K2_DEVICE_ID/disk@0:$PARTITION"
570             ;;
571         usb-storage)
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"
576             ;;
577         sbp2|"")
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
582                 scsi_ofpath2
583             else
584                 if [ "$SCSI_HOSTNUMBER" = "" ] ; then
585                         SCSI_HOSTNUMBER=1
586                 fi
587                 DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
588                 echo "${DEVICE_PATH##*device-tree}/disk@0:$PARTITION"
589             fi
590             ;;
591         *)
592             echo 1>&2 "$PRG: Driver: $SCSI_DRIVER is not supported"
593             return 1
594             ;;
595     esac
596     return 0
597 }
598
599 ide_ofpath()
600 {
601     if [ ! -L "/proc/ide/$DEVNODE" ] ; then
602         echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
603         return 1
604     fi
605
606     local IDEBUS="$(v=`readlink /proc/ide/$DEVNODE` ; echo ${v%%/*} )"
607     if [ -z "$IDEBUS" ] ; then
608         echo 1>&2 "$PRG: BUG: IDEBUS == NULL"
609         return 1
610     fi
611
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"
615             return 1
616             ;;
617         2.6.*|2.7.*)
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"
620                 return 1
621             fi
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"
625                 return 1
626             fi
627             local OF1275IDE="${SYS}/block/${DEVNODE}/device/../../devspec"
628             ;;
629         *)
630             local OF1275IDE="/proc/ide/$IDEBUS/devspec"
631             ;;
632     esac
633
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"
641                 else
642                     echo "cd:$PARTITION"
643                 fi
644                 ;;
645             *)
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
649                         echo "hd:$PARTITION"
650                     else
651                         echo "ultra1:$PARTITION"
652                     fi
653                 else
654                     echo "cd:$PARTITION"
655                 fi
656                 ;;
657         esac
658     else
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"
663             return 1
664         fi
665
666         if [ ! -f "/proc/ide/${IDEBUS}/channel" ] ; then
667             echo 1>&2 "$PRG: KERNEL BUG: /proc/ide/${IDEBUS}/channel does not exist"
668             return 1
669         fi
670
671         case "$(cat /proc/device-tree${DEVSPEC}/device_type 2> /dev/null)" in
672             ide|ata)
673                 local MASTER="/disk@0"
674                 local SLAVE="/disk@1"
675                 ;;
676             pci-ide|pci-ata)
677                 local MASTER="/@$(cat /proc/ide/${IDEBUS}/channel)/disk@0"
678                 local SLAVE="/@$(cat /proc/ide/${IDEBUS}/channel)/disk@1"
679                 ;;
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))"
683                 ;;
684             spi)
685                 local MASTER="/disk@$(cat /proc/ide/${IDEBUS}/channel),0"
686                 local SLAVE="/disk@$(cat /proc/ide/${IDEBUS}/channel),1"
687                 ;;
688             *)
689                 echo 1>&2 "$PRG: Unsupported IDE device type: \"$(cat /proc/device-tree${DEVSPEC}/device_type 2> /dev/null)\""
690                 return 1
691                 ;;
692         esac
693
694         case "$DEVNODE" in
695             hda|hdc|hde|hdg|hdi|hdk|hdm|hdo)
696                 echo "${DEVSPEC}${MASTER}:$PARTITION"
697                 return 0
698                 ;;
699             hdb|hdd|hdf|hdh|hdj|hdl|hdn|hdp)
700                 echo "${DEVSPEC}${SLAVE}:$PARTITION"
701                 return 0
702                 ;;
703             *)
704                 echo 1>&2 "$PRG: /dev/$DEVNODE is not supported"
705                 return 1
706                 ;;
707         esac
708     fi
709 }
710
711 ## figure out the OpenFirmware device path for newworld macs.
712 ## sd* scsi disks , hd* ide disks.
713 newworld()
714 {
715     case "$DEVNODE" in
716         sd*)
717             ## use common scsiinfo function to get info we need.
718             scsiinfo || return 1
719
720             ## now we have the data for /@$DEVID:$PARTITION
721             ## find the actual OF path.
722             scsi_ofpath || return 1
723             ;;
724         hd*)
725             ide_ofpath || return 1
726             ;;
727         *)
728             echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
729             return 1
730             ;;
731     esac
732     return 0
733 }
734
735 oldworld()
736 {
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"
742     else
743         echo 1>&2 "$PRG: Cannot find OpenFirmware aliases directory in /proc/device-tree/"
744         return 1
745     fi
746
747     local MODEL="$(cat /proc/device-tree/compatible)"
748     [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: Oldworld subarch: $MODEL"
749
750     case "$MODEL" in
751         AAPL,7300*|AAPL,7500*|AAPL,8500*|AAPL,9500*|AAPL,\?\?\?\?*)
752             case "$DEVNODE" in
753                 sd*)
754                 scsiinfo || return 1
755                 case "$SCSI_DRIVER" in
756                     mesh)
757                     echo $(cat /proc/device-tree/$ALIASES/scsi-int)/sd\@$DEVICE_ID:$PARTITION
758                     ;;
759                     53c94)
760                     echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
761                     ;;
762                     *)
763                     echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
764                     return 1
765                     ;;
766                 esac
767                 ;;
768                 *)
769                 echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE"
770                 return 1
771                 ;;
772             esac
773             ;;
774         AAPL,e407*)
775             case "$DEVNODE" in
776                 sd*)
777                 scsiinfo || return 1
778                 case "$SCSI_DRIVER" in
779                     mesh)
780                     echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
781                     ;;
782                     *)
783                     echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
784                     return 1
785                     ;;
786                 esac
787                 ;;
788                 hda*)
789                 echo $(cat /proc/device-tree/$ALIASES/ata)/ATA-Disk\@0:$PARTITION
790                 ;;
791                 hdb*)
792                 echo $(cat /proc/device-tree/$ALIASES/ata)/ATA-Disk\@1:$PARTITION
793                 ;;
794                 hd*)
795                 echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
796                 ;;
797             esac
798             ;;
799         AAPL,e826*)
800             case "$DEVNODE" in
801                 sd*)
802                 scsiinfo || return 1
803                 case "$SCSI_DRIVER" in
804                     mesh)
805                     echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
806                     ;;
807                     *)
808                     echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
809                     return 1
810                     ;;
811                 esac
812                 ;;
813                 hda*)
814                 echo $(cat /proc/device-tree/$ALIASES/ata)/ata-disk\@0:$PARTITION
815                 ;;
816                 hdb*)
817                 echo $(cat /proc/device-tree/$ALIASES/ata)/ata-disk\@1:$PARTITION
818                 ;;
819                 hd*)
820                 echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
821                 ;;
822             esac
823             ;;
824         AAPL,Gossamer*|AAPL,PowerMac\ G3*)
825             case "$DEVNODE" in
826                 sd*)
827                 scsiinfo || return 1
828                 case "$SCSI_DRIVER" in
829                     mesh)
830                     echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
831                     ;;
832                     *)
833                     echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
834                     return 1
835                     ;;
836                 esac
837                 ;;
838                 hda*)
839                 echo $(cat /proc/device-tree/$ALIASES/ide0)/ata-disk\@0:$PARTITION
840                 ;;
841                 hdb*)
842                 echo $(cat /proc/device-tree/$ALIASES/ide0)/ata-disk\@1:$PARTITION
843                 ;;
844                 hdc*)
845                 echo $(cat /proc/device-tree/$ALIASES/ide1)/ata-disk\@0:$PARTITION
846                 ;;
847                 hdd*)
848                 echo $(cat /proc/device-tree/$ALIASES/ide1)/ata-disk\@1:$PARTITION
849                 ;;
850                 hd*)
851                 echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
852                 ;;
853             esac
854             ;;
855         AAPL,PowerBook1998*)
856             if [ -f  /proc/device-tree/$ALIASES/ata0 ] ; then
857                 local ATA0=ata0
858             else
859                 local ATA0=ide0
860             fi
861             if [ -f  /proc/device-tree/$ALIASES/ata1 ] ; then
862                 local ATA1=ata1
863             else
864                 local ATA1=bay-ata1
865             fi
866             case "$DEVNODE" in
867                 sd*)
868                 scsiinfo || return 1
869                 case "$SCSI_DRIVER" in
870                     mesh)
871                     echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITON
872                     ;;
873                     *)
874                     echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
875                     return 1
876                     ;;
877                 esac
878                 ;;
879                 hda*)
880                 echo $(cat /proc/device-tree/$ALIASES/$ATA0)/ata-disk\@0:$PARTITION
881                 ;;
882                 hdb*)
883                 echo $(cat /proc/device-tree/$ALIASES/$ATA0)/ata-disk\@1:$PARTITION
884                 ;;
885                 hdc*)
886                 echo $(cat /proc/device-tree/$ALIASES/$ATA1)/atapi-disk\@0:$PARTITION
887                 ;;
888                 hdd*)
889                 echo $(cat /proc/device-tree/$ALIASES/$ATA1)/atapi-disk\@1:$PARTITION
890                 ;;
891                 *)
892                 echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE"
893                 return 1
894                 ;;
895             esac
896             ;;
897         AAPL,3400/2400*)
898             case "$DEVNODE" in
899                 sd*)
900                 scsiinfo || return 1
901                 case "$SCSI_DRIVER" in
902                     mesh)
903                     echo $(cat /proc/device-tree/$ALIASES/scsi-int)/sd\@$DEVICE_ID:$PARTITON
904                     ;;
905                     53c94)
906                     echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITON
907                     ;;
908                     *)
909                     echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
910                     return 1
911                     ;;
912                 esac
913                 ;;
914                 hda*)
915                 echo $(cat /proc/device-tree/$ALIASES/ata0)/ata-disk\@0:$PARTITION
916                 ;;
917                 hdb*)
918                 echo $(cat /proc/device-tree/$ALIASES/ata0)/ata-disk\@1:$PARTITION
919                 ;;
920                 hdc*)
921                 echo $(cat /proc/device-tree/$ALIASES/ata1)/atapi-disk\@0:$PARTITION
922                 ;;
923                 hdd*)
924                 echo $(cat /proc/device-tree/$ALIASES/ata1)/atapi-disk\@1:$PARTITION
925                 ;;
926                 hde*)
927                 echo $(cat /proc/device-tree/$ALIASES/ata2):$PARTITION
928                 ;;
929                 hdf*)
930                 echo $(cat /proc/device-tree/$ALIASES/ata3):$PARTITION
931                 ;;
932                 *)
933                 echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE"
934                 return 1
935                 ;;
936             esac
937             ;;
938         *)
939             echo 1>&2 "$PRG: This machine is not supported: $MODEL"
940             return 1
941             ;;
942     esac
943     return 0
944 }
945
946 eth_ofpath()
947 {
948         read_attr devspec /sys/class/net/$DEVICE/device
949 }
950
951 hfi_ofpath()
952 {
953         local hfnum=${DEVICE##hf}
954         local hfpath
955
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)
960         else
961                 echo 1>&2 "$PRG: Unsupported device: $DEVICE"
962                 return 1
963         fi
964
965         hfpath=${hfpath##/proc/device-tree}
966         echo "$hfpath"
967 }
968
969 ## find OpenFirmware device path for IBM CHRP hardware (scsi only)
970 chrp()
971 {
972     case "$DEVNODE" in
973         sd*)
974
975             ## use common scsiinfo function to get info we need.
976             scsiinfo || return 1
977
978             ## now we have the data for /@$DEVID:$PARTITION
979             ## find the actual OF path.
980             scsi_ofpath || return 1
981             ;;
982         eth*)
983             eth_ofpath || return 1
984             ;;
985         hfi*)
986             hfi_ofpath || return 1
987             ;;
988         *)
989             echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
990             return 1
991             ;;
992     esac
993     return 0
994 }
995
996 ## If we get lame devfs name, we need to make it foad
997 ckdevfs()
998 {
999     case "$1" in
1000         /dev/ide/*|/dev/scsi/*|/dev/discs/*)
1001         return 0
1002         ;;
1003         *)
1004         return 1
1005         ;;
1006     esac
1007 }
1008
1009 ## convert devfs names into normal short ones, written by Tom Rini.
1010 fixdevfs()
1011 {
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*})"
1020     ## Find the target.
1021     local TARGET="$(v=${1#/dev/*/target} ; echo ${v%/lun*})"
1022
1023     case "$TYPE" in
1024         ide)
1025         case "$HOST" in
1026             0)
1027             case "$TARGET" in
1028                 0)
1029                 local DEV=hda
1030                 ;;
1031                 1)
1032                 local DEV=hdb
1033                 ;;
1034             esac
1035             ;;
1036             1)
1037             case "$TARGET" in
1038                 0)
1039                 local DEV=hdc
1040                 ;;
1041                 1)
1042                 local DEV=hdd
1043                 ;;
1044             esac
1045             ;;
1046             *)
1047                 echo 1>&2 "$PRG: $1: Unable to translate this device, try again without devfs."
1048                 return 1
1049         esac
1050         local DEV="${DEV}${PARTNUM}"
1051         echo "/dev/$DEV"
1052         return 0
1053         ;;
1054         scsi)
1055         local LUN="$(v=${1#/dev/*/lun} ; echo ${v%/*})"
1056
1057         ## In this case, we need to figure out what number our device is
1058         local DEVCOUNT=0
1059
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.
1063
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:
1067
1068         local SCSILINES="$(($(linecount /proc/scsi/scsi) - 1))"
1069         local PROCSCSI="$(cat /proc/scsi/scsi | tail -n $SCSILINES)"
1070
1071         for i in $(smallseq $(($SCSILINES / 3))) ; do
1072
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"
1076
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"
1080
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"
1086
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"
1090
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"
1094
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"
1098
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}"
1104                     echo "/dev/$DEV"
1105                     return 0
1106                 fi
1107             fi
1108         done
1109         echo 1>&2 "$PRG: $1: Unable to translate this device, try again without devfs."
1110         return 1
1111         ;;
1112         *)
1113         echo 1>&2 "$PRG: Unknown bus $TYPE"
1114         return 1
1115         ;;
1116     esac
1117     ## we should never get here
1118     return 1
1119 }
1120
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.
1124 checkutils()
1125 {
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
1132
1133     if [ "$FAIL" = 1 ] ; then
1134         echo 1>&2 "$PRG: \`find', \`head', or \`tail' could not be found, aborting."
1135         return 1
1136     else
1137         return 0
1138     fi
1139 }
1140
1141 ## parse command line switches.
1142 if [ $# != 0 ] ; then
1143     while true ; do
1144         case "$1" in
1145             -V|--version)
1146                 version
1147                 exit 0
1148                 ;;
1149             -h|--help)
1150                 usage
1151                 exit 0
1152                 ;;
1153             --debug)
1154                 DEBUG=1
1155                 shift
1156                 ;;
1157             -*)
1158                 echo 1>&2 "$PRG: unrecognized option \`$1'"
1159                 echo 1>&2 "$PRG: Try \`$PRG --help' for more information."
1160                 exit 1
1161                 ;;
1162             "")
1163                 echo 1>&2 "$PRG: You must specify a filename"
1164                 echo 1>&2 "Try \`$PRG --help' for more information."
1165                 exit 1
1166                 ;;
1167             *)
1168                 device="$1"
1169                 break
1170                 ;;
1171         esac
1172     done
1173 else
1174     echo 1>&2 "$PRG: You must specify a /dev device"
1175     echo 1>&2 "Try \`$PRG --help' for more information."
1176     exit 1
1177 fi
1178
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"
1183     exit 1
1184 fi
1185
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"
1189     exit 1
1190 fi
1191
1192 ## ofpath cannot live without procfs
1193 if [ ! -f /proc/uptime ] ; then
1194     echo 1>&2 "$PRG: This utility requires the /proc filesystem"
1195     exit 1
1196 fi
1197
1198 ## check for retarded devfs names and tell them to foad.
1199 if ckdevfs "$device" ; then
1200     device="$(fixdevfs $device)" || exit 1
1201 fi
1202
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
1205     SUBARCH=NewWorld
1206 elif [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:[ ]})" = OldWorld ] ; then
1207     SUBARCH=OldWorld
1208 elif (cat /proc/cpuinfo 2>/dev/null | grep ^motherboard | grep -q AAPL) ; then
1209     SUBARCH=OldWorld
1210 elif (cat /proc/cpuinfo 2> /dev/null | grep ^machine | grep -q 'CHRP IBM') ; then
1211     SUBARCH=CHRP
1212 elif (cat /proc/cpuinfo 2>/dev/null | grep ^machine | grep -q 'CHRP Pegasos') ; then
1213     SUBARCH=Pegasos
1214 else
1215     echo 1>&2 "$PRG: This machine is not yet supported"
1216     exit 1
1217 fi
1218
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"
1223     exit 1
1224 fi
1225
1226 ## make sure we have what we need.
1227 checkutils || exit 1
1228
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]}"
1233
1234 ## use appropriate search for right sub arch.
1235 case "$SUBARCH" in
1236     # Pegasos OF seems to be NewWorld-ish enough to cope with this.
1237     NewWorld|Pegasos)
1238         newworld || exit 1
1239         ;;
1240     OldWorld)
1241         oldworld || exit 1
1242         ;;
1243     CHRP)
1244         chrp || exit 1
1245         ;;
1246 esac
1247
1248 exit 0