]> git.ozlabs.org Git - yaboot.git/blob - ybin/ofpath
ofpath: Add support for fibre channel devices
[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     case "$1" in
120         a) echo 1 ;; b) echo 2 ;; c) echo 3 ;; d) echo 4 ;; e) echo 5 ;; f) echo 6 ;;
121         g) echo 7 ;; h) echo 8 ;; i) echo 9 ;; j) echo 10 ;; k) echo 11 ;; l) echo 12 ;;
122         m) echo 13 ;; n) echo 14 ;; o) echo 15 ;; p) echo 16 ;;
123         1) echo a ;; 2) echo b ;; 3) echo c ;; 4) echo d ;; 5) echo e ;;
124         6) echo f ;; 7) echo g ;; 8) echo h ;; 9) echo i ;; 10) echo j ;;
125         11) echo k ;; 12) echo l ;; 13) echo m ;; 14) echo n ;; 15) echo o ;;
126         16) echo p ;;
127     esac
128     return 0
129 }
130
131 ## replacment for grep -l which is not supported by busybox grep.
132 ## echo $(cat..) hack needed because busybox grep barfs with `line too
133 ## long' when fed /proc files.  the for loop is needed since busybox
134 ## grep seems to have somewhat broken regexp support.
135 ## usage: lgrep filename regexp regexp ...
136 lgrep()
137 {
138     local f="$1"
139     shift
140     for i in "$@" ; do
141         echo "$(cat "$f")" | grep -q "$i" && echo "$f" && break
142     done
143     return 0
144 }
145
146 ## if readlink is missing use a kludge
147 if (command -v readlink > /dev/null 2>&1) ; then
148     true
149 else
150     readlink()
151     {
152         local SYMTARGET="$(v=`ls -l "$1" 2>/dev/null` ; echo ${v##*> })"
153         if [ -n "$SYMTARGET" ] ; then
154             echo "$SYMTARGET"
155             return 0
156         else
157             return 1
158         fi
159     }
160 fi
161
162 ## a function to print relevant scsi host path when there is more then
163 ## one.  this function also takes care of stripping off the trailing
164 ## /compatible.
165 printhost()
166 {
167     case "$1" in
168         1)
169         echo "${2%/*}"
170         ;;
171         2)
172         echo "${3%/*}"
173         ;;
174         3)
175         echo "${4%/*}"
176         ;;
177         4)
178         echo "${5%/*}"
179         ;;
180     esac
181     return 0
182 }
183
184 ## this finds information we need on both newworld and oldworld macs.
185 ## mainly what scsi host a disk is attached to.
186 scsiinfo()
187 {
188     ## see if system has scsi at all
189     if [ ! -f /proc/scsi/scsi ] ; then
190         local kver="$(uname -r)"
191         case "$kver" in
192             2.5.*|2.6.*)
193                 if [ -d /sys/bus/scsi/devices -a \
194                     -n "$(ls /sys/bus/scsi/devices 2>/dev/null)" ] ; then
195                     echo 1>&2 "$PRG: /proc/scsi/scsi does not exist"
196                     echo 1>&2 "$PRG: Make sure you compiled your kernel with CONFIG_SCSI_PROC_FS=y"
197                     return 1
198                 fi
199                 ;;
200         esac
201         echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
202         return 1
203     fi
204
205     ## first we have to figure out the SCSI ID, have to do that
206     ## anyway [to] find the attached scsi disks = "Direct-Access" and
207     ## stop at sda=1 sdb=2 or whatever count in 3 lines steps
208
209     ## get last letter of device node, ie sda -> a
210     SUBNODE=${DEVNODE##*sd}
211
212     ## turn SUBNODE above into a number starting at 1, ie a -> 1
213     SUBDEV="$(smalltr $SUBNODE)"
214     [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: SUBNODE=$SUBNODE SUBDEV=$SUBDEV"
215
216     DEVCOUNT=0
217
218     ## copy scsi file into a variable removing "Attached Devices"
219     ## which is the first line. this avoids a lot of
220     ## [incmopatible] crap later, and improves readability.
221
222     ## find number of lines once and recycle that number, to save
223     ## some time (linecount is a bit slow). subtract one line
224     ## to scrap Attached Devices:
225
226     SCSILINES="$(($(linecount /proc/scsi/scsi) - 1))"
227
228     if [ "$SUBDEV" -gt "$(cat /proc/scsi/scsi | grep Direct-Access | linecount)" ] ; then
229         echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
230         return 1
231     fi
232
233     PROCSCSI="$(cat /proc/scsi/scsi | tail -n $SCSILINES)"
234
235     for i in $(smallseq $(($SCSILINES / 3))) ; do
236
237         ## put every scsi device into one single line
238         DEVINFO="$(echo "$PROCSCSI" | head -n $(($i * 3)) | tail -n 3)"
239         [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVINFO=$DEVINFO"
240
241         ## cut the type field, expect "Direct-Access" later.
242         DEVTYPE="$(v=$(echo ${DEVINFO##*Type: }) ; echo ${v%% *})"
243         [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVTYPE=$DEVTYPE"
244
245         ## get the device LUN.
246         DEVLUN="$(v=$(echo ${DEVINFO##*Lun: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
247         [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVLUN=$DEVLUN"
248
249         ## get the device id.
250         DEVID="$(v=$(echo ${DEVINFO##*Id: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
251         [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVID=$DEVID"
252
253         ## get the device bus.
254         DEVBUS="$(v=$(echo ${DEVINFO##*Channel: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
255         [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVBUS=$DEVBUS"
256
257         ## get the scsi host id.
258         DEVHOST="$(v=$(echo ${DEVINFO##*Host: scsi}) ; echo ${v%% *})"
259         [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVHOST=$DEVHOST"
260
261         if [ "$DEVTYPE" = "Direct-Access" ] || [ "$DEVTYPE" = "Direct-Access-RBC" ] ; then
262             DEVCOUNT="$(($DEVCOUNT + 1))"
263             [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVCOUNT=$DEVCOUNT"
264             if [ "$SUBDEV" = "$DEVCOUNT" ] ; then
265                 DEVICE_HOST=$DEVHOST
266                 DEVICE_BUS=$DEVBUS
267                 DEVICE_ID=$DEVID
268                 DEVICE_LUN=$DEVLUN
269                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVICE_HOST=$DEVICE_HOST"
270                 break
271             fi
272         fi
273     done
274
275     ## figure out what the scsi driver is, it is /proc/scsi/dirname.
276     [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVICE_HOST=$DEVICE_HOST"
277     SCSI_DRIVER="$(x=`ls /proc/scsi/*/$DEVICE_HOST 2>/dev/null | cat` ; y=`echo ${x##*proc/scsi/}` ; echo ${y%%/*})"
278     [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: SCSI_DRIVER=$SCSI_DRIVER"
279
280     ## figure out which host we found.
281     SCSI_HOSTNUMBER="$(v=`ls /proc/scsi/$SCSI_DRIVER/* 2>/dev/null | cat | grep -n "$DEVICE_HOST\>"` ; echo ${v%%:*})"
282     [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: SCSI_HOSTNUMBER=$SCSI_HOSTNUMBER"
283
284     return 0
285 }
286
287 read_attr()
288 {
289         local ATTR=$1
290         local START=$2
291         local OLDDIR=$(pwd)
292         local RET
293
294         cd -P "$START"
295         while [[ $PWD != "/" ]]; do
296                 ls $ATTR > /dev/null 2>&1
297                 if [[ $? -eq 0 ]]; then
298                         RET=$(cat $ATTR)
299                         cd $OLDDIR
300                         echo "$RET"
301                         return 0
302                 fi
303                 cd ..
304         done
305
306         cd $OLDDIR
307         echo 1>&2 "$PRG: Cannot find $RET for $DEVICE"
308         exit 1
309 }
310
311 read_dev_attr()
312 {
313         local ATTR=$1
314         local DEVICE="$DEVICE_HOST:$DEVICE_BUS:$DEVICE_ID:$DEVICE_LUN"
315         local START="/sys/bus/scsi/devices/$DEVICE"
316
317         read_attr $ATTR $START
318 }
319
320 read_parent_attr()
321 {
322         local ATTR=$1
323         local DEVICE="$DEVICE_HOST:$DEVICE_BUS:$DEVICE_ID:$DEVICE_LUN"
324         local START="/sys/bus/scsi/devices/$DEVICE/.."
325
326         read_attr $ATTR $START
327 }
328
329 get_vdisk_lun()
330 {
331         local B C D
332         typeset -i B C D
333
334         B=$((0x$DEVICE_ID << 8))
335         C=$((0x$DEVICE_BUS << 5))
336         D=$((0x$DEVICE_LUN))
337
338         local vdiskno vdisk
339         typeset -i vdiskno
340         vdiskno=$((0x8000 | $B | $C | $D ))
341         vdisk=${vdiskno##-}
342
343         vdisk=$(printf "%x" $vdisk)
344         local extrazeroes="000000000000"
345         echo $vdisk$extrazeroes
346 }
347
348 int_to_scsilun()
349 {
350         local lunint=$1
351         local A B C D
352
353         A=$(( ($lunint >> 8) & 0xff ))
354         B=$(($lunint & 0xff))
355         C=$(( ($lunint >> 24) & 0xff ))
356         D=$(( ($lunint >> 16) & 0xff ))
357
358         local lunstr=$(printf "%02x%02x%02x%02x00000000" $A $B $C $D)
359         lunstr=$(echo $lunstr | sed 's/^[0]*//')
360         echo "$lunstr"
361 }
362
363 get_fc_scsilun()
364 {
365         local L=$(echo "$DEVICE_LUN"|gawk '{$1=tolower($1);print}')
366         L=$(printf "%d" $L)
367
368         local fc_lun=$(int_to_scsilun $L)
369         echo "$fc_lun"
370 }
371
372 get_fc_wwpn()
373 {
374         local start_dir=$1
375
376         for f in `find -H $start_dir -maxdepth 2 -name port_name`; do
377                 local wwpn=$(cat $f)
378                 break
379         done
380
381         # strip the leading 0x
382         wwpn=${wwpn:2}
383         echo "$wwpn"
384 }
385
386 scsi_ofpath2()
387 {
388         local DEVSPEC=$(read_parent_attr devspec)
389         local COMPAT=$(cat "/proc/device-tree$DEVSPEC/compatible")
390         local DEVICE_PATH="/sys/bus/scsi/devices/$DEVICE_HOST:$DEVICE_BUS:$DEVICE_ID:$DEVICE_LUN"
391
392         case "$COMPAT" in
393             IBM,v-scsi)
394                 local vdisk=$(get_vdisk_lun)
395                 if [[ $PARTITION = "" ]]; then
396                         echo "$DEVSPEC/disk@$vdisk"
397                 else
398                         echo "$DEVSPEC/disk@$vdisk:$PARTITION"
399                 fi
400                 return 0
401                 ;;
402             IBM,vfc-client)
403                 local vfc_lun=$(get_fc_scsilun)
404                 local wwpn=$(get_fc_wwpn "$DEVICE_PATH/../../fc_remote_ports*")
405                 if [[ $DEVICE_LUN != "0" ]]; then
406                         local vfc_lun=$(get_fc_scsilun)
407                         echo "$DEVSPEC/disk@$wwpn,$vfc_lun"
408                 else
409                         echo "$DEVSPEC/disk@$wwpn"
410                 fi
411                 return 0
412                 ;;
413             *)
414                 ;;
415         esac
416
417         if [[ -d "/proc/device-tree$DEVSPEC/sas" ]]; then
418                 local vendor_id=$(read_parent_attr vendor)
419                 local sas_addr
420
421                 if [[ $vendor_id = "0x1000" ]]; then
422                         sas_addr=$(read_dev_attr sas_address)
423                         sas_addr=${sas_addr##0x}
424                         if [[ $DEVICE_LUN != "0" ]]; then
425                                 local LUN=$(int_to_scsilun $DEVICE_LUN)
426                                 echo "$DEVSPEC/sas/disk@$sas_addr,$LUN"
427                         else
428                                 echo "$DEVSPEC/sas/disk@$sas_addr"
429                         fi
430                         return 0
431                 fi
432
433                 local fwtype="0"
434                 if [[ -e /sys/class/scsi_host/host$DEVICE_HOST/fw_type ]]; then
435                         fwtype=$(cat /sys/class/scsi_host/host$DEVICE_HOST/fw_type)
436                 fi
437
438                 if [[ $fwtype = "1" ]]; then
439                         sas_addr=$(read_dev_attr device_id)
440                         sas_addr=${sas_addr##0x}
441                         if [[ $DEVICE_LUN != "0" ]]; then
442                                 local LUN=$(int_to_scsilun $DEVICE_LUN)
443                                 echo "$DEVSPEC/sas/disk@$sas_addr,$LUN"
444                         else
445                                 echo "$DEVSPEC/sas/disk@$sas_addr"
446                         fi
447                 else
448                         local B T L
449
450                         B=$(echo "$DEVICE_BUS"|gawk '{$1=tolower($1);print}')
451                         B=$(printf "%d" $B)
452                         T=$(echo "$DEVICE_ID"|gawk '{$1=tolower($1);print}')
453                         T=$(printf "%d" $T)
454                         L=$(echo "$DEVICE_LUN"|gawk '{$1=tolower($1);print}')
455                         L=$(printf "%d" $L)
456
457                         sas_addr=$(( ($B << 16) | ($T << 8) | $L ))
458                         if [[ $DEVICE_LUN != "0" ]]; then
459                                 printf "%s/sas/disk@%x,%x\n" $DEVSPEC $sas_addr $DEVICE_LUN
460                         else
461                                 printf "%s/sas/disk@%x\n" $DEVSPEC $sas_addr
462                         fi
463                 fi
464                 return 0
465         fi
466
467         local fc=${DEVSPEC%@*}
468         fc=${fc##/*/}
469
470         if [[ -e /proc/device-tree$DEVSPEC/device_type ]]; then
471                 local devtype=$(cat /proc/device-tree$DEVSPEC/device_type);
472                 if [[ $devtype = "fcp" || $devtype = "scsi-fcp" ]]; then
473                         fc="fibre-channel";
474                 fi
475         fi
476
477         if [[ $fc = "fibre-channel" ]]; then
478                 local wwpn=$(get_fc_wwpn "$DEVICE_PATH/../../fc_remote_ports*")
479                 local ofpath=$DEVSPEC
480
481                 if [[ ! -e /proc/device-tree$DEVSPEC/disk ]]; then
482                         for dir in `find /proc/device-tree$DEVSPEC -type d`; do
483                                 if [[ -e $dir/disk ]]; then
484                                         ofpath=${dir##/proc/device-tree}
485                                         break;
486                                 fi
487                         done
488                 fi
489
490                 ofpath=$(printf "%s/disk@%s" $ofpath $wwpn)
491
492                 if [[ $DEVICE_LUN != "0" ]]; then
493                         local fc_lun=$(get_fc_scsilun $DEVICE_LUN)
494                         ofpath=$(printf "%s,%s" $ofpath $fc_lun)
495                 fi
496
497                 echo "$ofpath"
498                 return 0
499         fi
500
501         echo 1>&2 "$PRG: Driver: $SCSI_DRIVER is not supported"
502         return 1
503 }
504
505 ## generic function that can find OF device paths for scsi devices,
506 ## must be run after scsiinfo().
507 scsi_ofpath()
508 {
509     case "$SCSI_DRIVER" in
510         aic7xxx)
511             HOST_LIST="$(for i in `find /proc/device-tree -name compatible` ; do
512                         lgrep "$i" "^ADPT" "^pci900[45]" "^pciclass,01000" ; done)"
513             DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
514             echo "${DEVICE_PATH##*device-tree}/@$DEVICE_ID:$PARTITION"
515             ;;
516         sym53c8xx)
517             HOST_LIST="$(for i in `find /proc/device-tree -name compatible` ; do
518                         lgrep "$i" "^Symbios" "^pci1000" "^pciclass,01000" ; done)"
519             DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
520             echo "${DEVICE_PATH##*device-tree}/@$DEVICE_ID:$PARTITION"
521             ;;
522         mesh)
523             HOST_LIST="$(for i in `find /proc/device-tree -name compatible` ; do
524                         lgrep "$i" "mesh" ; done)"
525             DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
526             echo "${DEVICE_PATH##*device-tree}/@$DEVICE_ID:$PARTITION"
527             ;;
528         ata_k2|sata_svw)
529             #Not all G5 device trees have a compatible "k2-sata" node 
530             #per channel use parent
531             HOST_LIST="$(for i in `find /proc/device-tree -name compatible ` ; do
532                         lgrep "$i" "k2-s-ata" ; done | sort)"
533             DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
534             K2_DEVICE_ID=0
535             while [ "$DEVICE_PATH" = "" ] ; do
536                 SCSI_HOSTNUMBER=`expr $SCSI_HOSTNUMBER - 1`
537                 let "K2_DEVICE_ID += 1"
538                 DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
539             done
540             echo "${DEVICE_PATH##*device-tree}/k2-sata@$K2_DEVICE_ID/disk@0:$PARTITION"
541             ;;
542         usb-storage)
543             HOST_LIST="$(for i in `find /proc/device-tree -name name | grep usb` ; do
544                         lgrep "$i" "disk" ; done)"
545             DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
546             echo "${DEVICE_PATH##*device-tree}:$PARTITION"
547             ;;
548         sbp2|"")
549             # sbp-2 driver may not have a dir in /proc/scsi
550             HOST_LIST="$(for i in `find /proc/device-tree -name name` ; do
551                         lgrep "$i" "sbp-2" ; done)"
552             if [ "$HOST_LIST" = "" ] ; then
553                 scsi_ofpath2
554             else
555                 if [ "$SCSI_HOSTNUMBER" = "" ] ; then
556                         SCSI_HOSTNUMBER=1
557                 fi
558                 DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
559                 echo "${DEVICE_PATH##*device-tree}/disk@0:$PARTITION"
560             fi
561             ;;
562         *)
563             echo 1>&2 "$PRG: Driver: $SCSI_DRIVER is not supported"
564             return 1
565             ;;
566     esac
567     return 0
568 }
569
570 ide_ofpath()
571 {
572     if [ ! -L "/proc/ide/$DEVNODE" ] ; then
573         echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
574         return 1
575     fi
576
577     local IDEBUS="$(v=`readlink /proc/ide/$DEVNODE` ; echo ${v%%/*} )"
578     if [ -z "$IDEBUS" ] ; then
579         echo 1>&2 "$PRG: BUG: IDEBUS == NULL"
580         return 1
581     fi
582
583     case "$(uname -r)" in
584         2.5.*|2.6.0*|2.6.1|2.6.1-*|2.6.2|2.6.2-*)
585             echo 1>&2 "$PRG: Linux kernel `uname -r` is not supported"
586             return 1
587             ;;
588         2.6.*|2.7.*)
589             if ! (grep -q '.* .* sysfs ' /proc/mounts 2> /dev/null) ; then
590                 echo 1>&2 "$PRG: sysfs must be mounted for ofpath to support this system"
591                 return 1
592             fi
593             local SYS="$(m=`grep '.* .* sysfs ' /proc/mounts | head -n 1` ; echo `d=${m#* };echo ${d%% *}`)"
594             if [ -z "$SYS" -o ! -d "$SYS" ] ; then
595                 echo 1>&2 "$PRG: Unable to determine sysfs mountpoint"
596                 return 1
597             fi
598             local OF1275IDE="${SYS}/block/${DEVNODE}/device/../../devspec"
599             ;;
600         *)
601             local OF1275IDE="/proc/ide/$IDEBUS/devspec"
602             ;;
603     esac
604
605     if [ ! -f "$OF1275IDE" ] ; then
606         case "$(cat /proc/device-tree/model)" in
607             PowerMac3*|PowerMac4*|PowerMac5*|PowerMac6*|PowerMac7*|RackMac*)
608                 local CDROM="$(grep "^drive name:" /proc/sys/dev/cdrom/info 2> /dev/null | grep $DEVNODE)"
609                 if [ -z "$CDROM" ] ; then
610                     echo 1>&2 "$PRG: WARNING: Your kernel is too old for proper support, device may be innaccurate."
611                     echo "ultra2:$PARTITION"
612                 else
613                     echo "cd:$PARTITION"
614                 fi
615                 ;;
616             *)
617                 local CDROM="$(grep "^drive name:" /proc/sys/dev/cdrom/info 2> /dev/null | grep $DEVNODE)"
618                 if [ -z "$CDROM" ] ; then
619                     if [ "$DEVNODE" = hda ] ; then
620                         echo "hd:$PARTITION"
621                     else
622                         echo "ultra1:$PARTITION"
623                     fi
624                 else
625                     echo "cd:$PARTITION"
626                 fi
627                 ;;
628         esac
629     else
630         local DEVSPEC="$(cat $OF1275IDE)"
631         [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVSPEC=$DEVSPEC"
632         if [ -z "$DEVSPEC" ] ; then
633             echo 1>&2 "$PRG: KERNEL BUG: $OF1275IDE exists, but is empty"
634             return 1
635         fi
636
637         if [ ! -f "/proc/ide/${IDEBUS}/channel" ] ; then
638             echo 1>&2 "$PRG: KERNEL BUG: /proc/ide/${IDEBUS}/channel does not exist"
639             return 1
640         fi
641
642         case "$(cat /proc/device-tree${DEVSPEC}/device_type 2> /dev/null)" in
643             ide|ata)
644                 local MASTER="/disk@0"
645                 local SLAVE="/disk@1"
646                 ;;
647             pci-ide|pci-ata)
648                 local MASTER="/@$(cat /proc/ide/${IDEBUS}/channel)/disk@0"
649                 local SLAVE="/@$(cat /proc/ide/${IDEBUS}/channel)/disk@1"
650                 ;;
651             scsi) ## some lame controllers pretend they are scsi, hopefully all kludges are created equal.
652                 local MASTER="/@$(($(cat /proc/ide/${IDEBUS}/channel) * 2 + 0))"
653                 local SLAVE="/@$(($(cat /proc/ide/${IDEBUS}/channel) * 2 + 1))"
654                 ;;
655             spi)
656                 local MASTER="/disk@$(cat /proc/ide/${IDEBUS}/channel),0"
657                 local SLAVE="/disk@$(cat /proc/ide/${IDEBUS}/channel),1"
658                 ;;
659             *)
660                 echo 1>&2 "$PRG: Unsupported IDE device type: \"$(cat /proc/device-tree${DEVSPEC}/device_type 2> /dev/null)\""
661                 return 1
662                 ;;
663         esac
664
665         case "$DEVNODE" in
666             hda|hdc|hde|hdg|hdi|hdk|hdm|hdo)
667                 echo "${DEVSPEC}${MASTER}:$PARTITION"
668                 return 0
669                 ;;
670             hdb|hdd|hdf|hdh|hdj|hdl|hdn|hdp)
671                 echo "${DEVSPEC}${SLAVE}:$PARTITION"
672                 return 0
673                 ;;
674             *)
675                 echo 1>&2 "$PRG: /dev/$DEVNODE is not supported"
676                 return 1
677                 ;;
678         esac
679     fi
680 }
681
682 ## figure out the OpenFirmware device path for newworld macs.
683 ## sd* scsi disks , hd* ide disks.
684 newworld()
685 {
686     case "$DEVNODE" in
687         sd*)
688             ## use common scsiinfo function to get info we need.
689             scsiinfo || return 1
690
691             ## now we have the data for /@$DEVID:$PARTITION
692             ## find the actual OF path.
693             scsi_ofpath || return 1
694             ;;
695         hd*)
696             ide_ofpath || return 1
697             ;;
698         *)
699             echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
700             return 1
701             ;;
702     esac
703     return 0
704 }
705
706 oldworld()
707 {
708     ## for some reason 2.4 kernels put OF aliases in aliases@0/ instead of plain aliases/
709     if [ -d "/proc/device-tree/aliases" ] ; then
710         local ALIASES="aliases"
711     elif [ -d "/proc/device-tree/aliases@0" ] ; then
712         local ALIASES="aliases@0"
713     else
714         echo 1>&2 "$PRG: Cannot find OpenFirmware aliases directory in /proc/device-tree/"
715         return 1
716     fi
717
718     local MODEL="$(cat /proc/device-tree/compatible)"
719     [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: Oldworld subarch: $MODEL"
720
721     case "$MODEL" in
722         AAPL,7300*|AAPL,7500*|AAPL,8500*|AAPL,9500*|AAPL,\?\?\?\?*)
723             case "$DEVNODE" in
724                 sd*)
725                 scsiinfo || return 1
726                 case "$SCSI_DRIVER" in
727                     mesh)
728                     echo $(cat /proc/device-tree/$ALIASES/scsi-int)/sd\@$DEVICE_ID:$PARTITION
729                     ;;
730                     53c94)
731                     echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
732                     ;;
733                     *)
734                     echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
735                     return 1
736                     ;;
737                 esac
738                 ;;
739                 *)
740                 echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE"
741                 return 1
742                 ;;
743             esac
744             ;;
745         AAPL,e407*)
746             case "$DEVNODE" in
747                 sd*)
748                 scsiinfo || return 1
749                 case "$SCSI_DRIVER" in
750                     mesh)
751                     echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
752                     ;;
753                     *)
754                     echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
755                     return 1
756                     ;;
757                 esac
758                 ;;
759                 hda*)
760                 echo $(cat /proc/device-tree/$ALIASES/ata)/ATA-Disk\@0:$PARTITION
761                 ;;
762                 hdb*)
763                 echo $(cat /proc/device-tree/$ALIASES/ata)/ATA-Disk\@1:$PARTITION
764                 ;;
765                 hd*)
766                 echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
767                 ;;
768             esac
769             ;;
770         AAPL,e826*)
771             case "$DEVNODE" in
772                 sd*)
773                 scsiinfo || return 1
774                 case "$SCSI_DRIVER" in
775                     mesh)
776                     echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
777                     ;;
778                     *)
779                     echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
780                     return 1
781                     ;;
782                 esac
783                 ;;
784                 hda*)
785                 echo $(cat /proc/device-tree/$ALIASES/ata)/ata-disk\@0:$PARTITION
786                 ;;
787                 hdb*)
788                 echo $(cat /proc/device-tree/$ALIASES/ata)/ata-disk\@1:$PARTITION
789                 ;;
790                 hd*)
791                 echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
792                 ;;
793             esac
794             ;;
795         AAPL,Gossamer*|AAPL,PowerMac\ G3*)
796             case "$DEVNODE" in
797                 sd*)
798                 scsiinfo || return 1
799                 case "$SCSI_DRIVER" in
800                     mesh)
801                     echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
802                     ;;
803                     *)
804                     echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
805                     return 1
806                     ;;
807                 esac
808                 ;;
809                 hda*)
810                 echo $(cat /proc/device-tree/$ALIASES/ide0)/ata-disk\@0:$PARTITION
811                 ;;
812                 hdb*)
813                 echo $(cat /proc/device-tree/$ALIASES/ide0)/ata-disk\@1:$PARTITION
814                 ;;
815                 hdc*)
816                 echo $(cat /proc/device-tree/$ALIASES/ide1)/ata-disk\@0:$PARTITION
817                 ;;
818                 hdd*)
819                 echo $(cat /proc/device-tree/$ALIASES/ide1)/ata-disk\@1:$PARTITION
820                 ;;
821                 hd*)
822                 echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
823                 ;;
824             esac
825             ;;
826         AAPL,PowerBook1998*)
827             if [ -f  /proc/device-tree/$ALIASES/ata0 ] ; then
828                 local ATA0=ata0
829             else
830                 local ATA0=ide0
831             fi
832             if [ -f  /proc/device-tree/$ALIASES/ata1 ] ; then
833                 local ATA1=ata1
834             else
835                 local ATA1=bay-ata1
836             fi
837             case "$DEVNODE" in
838                 sd*)
839                 scsiinfo || return 1
840                 case "$SCSI_DRIVER" in
841                     mesh)
842                     echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITON
843                     ;;
844                     *)
845                     echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
846                     return 1
847                     ;;
848                 esac
849                 ;;
850                 hda*)
851                 echo $(cat /proc/device-tree/$ALIASES/$ATA0)/ata-disk\@0:$PARTITION
852                 ;;
853                 hdb*)
854                 echo $(cat /proc/device-tree/$ALIASES/$ATA0)/ata-disk\@1:$PARTITION
855                 ;;
856                 hdc*)
857                 echo $(cat /proc/device-tree/$ALIASES/$ATA1)/atapi-disk\@0:$PARTITION
858                 ;;
859                 hdd*)
860                 echo $(cat /proc/device-tree/$ALIASES/$ATA1)/atapi-disk\@1:$PARTITION
861                 ;;
862                 *)
863                 echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE"
864                 return 1
865                 ;;
866             esac
867             ;;
868         AAPL,3400/2400*)
869             case "$DEVNODE" in
870                 sd*)
871                 scsiinfo || return 1
872                 case "$SCSI_DRIVER" in
873                     mesh)
874                     echo $(cat /proc/device-tree/$ALIASES/scsi-int)/sd\@$DEVICE_ID:$PARTITON
875                     ;;
876                     53c94)
877                     echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITON
878                     ;;
879                     *)
880                     echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
881                     return 1
882                     ;;
883                 esac
884                 ;;
885                 hda*)
886                 echo $(cat /proc/device-tree/$ALIASES/ata0)/ata-disk\@0:$PARTITION
887                 ;;
888                 hdb*)
889                 echo $(cat /proc/device-tree/$ALIASES/ata0)/ata-disk\@1:$PARTITION
890                 ;;
891                 hdc*)
892                 echo $(cat /proc/device-tree/$ALIASES/ata1)/atapi-disk\@0:$PARTITION
893                 ;;
894                 hdd*)
895                 echo $(cat /proc/device-tree/$ALIASES/ata1)/atapi-disk\@1:$PARTITION
896                 ;;
897                 hde*)
898                 echo $(cat /proc/device-tree/$ALIASES/ata2):$PARTITION
899                 ;;
900                 hdf*)
901                 echo $(cat /proc/device-tree/$ALIASES/ata3):$PARTITION
902                 ;;
903                 *)
904                 echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE"
905                 return 1
906                 ;;
907             esac
908             ;;
909         *)
910             echo 1>&2 "$PRG: This machine is not supported: $MODEL"
911             return 1
912             ;;
913     esac
914     return 0
915 }
916
917 eth_ofpath()
918 {
919         read_attr devspec /sys/class/net/$DEVICE/device
920 }
921
922 hfi_ofpath()
923 {
924         local hfnum=${DEVICE##hf}
925         local hfpath
926
927         if [[ $hfnum = "0" || $hfnum = "2" ]]; then
928                 hfpath=$(find /proc/device-tree -name hfi-ethernet* | sort | head -n 1)
929         elif [[ $hfnum = "1" || $hfnum = "3" ]]; then
930                 hfpath=$(find /proc/device-tree -name hfi-ethernet* | sort | tail -n 1)
931         else
932                 echo 1>&2 "$PRG: Unsupported device: $DEVICE"
933                 return 1
934         fi
935
936         hfpath=${hfpath##/proc/device-tree}
937         echo "$hfpath"
938 }
939
940 ## find OpenFirmware device path for IBM CHRP hardware (scsi only)
941 chrp()
942 {
943     case "$DEVNODE" in
944         sd*)
945
946             ## use common scsiinfo function to get info we need.
947             scsiinfo || return 1
948
949             ## now we have the data for /@$DEVID:$PARTITION
950             ## find the actual OF path.
951             scsi_ofpath || return 1
952             ;;
953         eth*)
954             eth_ofpath || return 1
955             ;;
956         hfi*)
957             hfi_ofpath || return 1
958             ;;
959         *)
960             echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
961             return 1
962             ;;
963     esac
964     return 0
965 }
966
967 ## If we get lame devfs name, we need to make it foad
968 ckdevfs()
969 {
970     case "$1" in
971         /dev/ide/*|/dev/scsi/*|/dev/discs/*)
972         return 0
973         ;;
974         *)
975         return 1
976         ;;
977     esac
978 }
979
980 ## convert devfs names into normal short ones, written by Tom Rini.
981 fixdevfs()
982 {
983     ## get partition number, if any
984     local PARTNUM="${1##*[a-z]}"
985     ## Find the bus type.
986     local TYPE="$(v=${1#/dev/} ; echo ${v%/host*})"
987     ## Find the host number.
988     local HOST="$(v=${1#/dev/*/host} ; echo ${v%/bus*})"
989     ## Find the bus number.
990     local BUS="$(v=${1#/dev/*/bus} ; echo ${v%/tar*})"
991     ## Find the target.
992     local TARGET="$(v=${1#/dev/*/target} ; echo ${v%/lun*})"
993
994     case "$TYPE" in
995         ide)
996         case "$HOST" in
997             0)
998             case "$TARGET" in
999                 0)
1000                 local DEV=hda
1001                 ;;
1002                 1)
1003                 local DEV=hdb
1004                 ;;
1005             esac
1006             ;;
1007             1)
1008             case "$TARGET" in
1009                 0)
1010                 local DEV=hdc
1011                 ;;
1012                 1)
1013                 local DEV=hdd
1014                 ;;
1015             esac
1016             ;;
1017             *)
1018                 echo 1>&2 "$PRG: $1: Unable to translate this device, try again without devfs."
1019                 return 1
1020         esac
1021         local DEV="${DEV}${PARTNUM}"
1022         echo "/dev/$DEV"
1023         return 0
1024         ;;
1025         scsi)
1026         local LUN="$(v=${1#/dev/*/lun} ; echo ${v%/*})"
1027
1028         ## In this case, we need to figure out what number our device is
1029         local DEVCOUNT=0
1030
1031         ## copy scsi file into a variable removing "Attached Devices"
1032         ## which is the first line. this avoids a lot of
1033         ## [incmopatible] crap later, and improves readability.
1034
1035         ## find number of lines once and recycle that number, to save
1036         ## some time (linecount is a bit slow). subtract one line
1037         ## to scrap Attached Devices:
1038
1039         local SCSILINES="$(($(linecount /proc/scsi/scsi) - 1))"
1040         local PROCSCSI="$(cat /proc/scsi/scsi | tail -n $SCSILINES)"
1041
1042         for i in $(smallseq $(($SCSILINES / 3))) ; do
1043
1044             ## put every scsi device into one single line
1045             local DEVINFO="$(echo "$PROCSCSI" | head -n $(($i * 3)) | tail -n 3)"
1046             [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVINFO=$DEVINFO"
1047
1048             ## cut the type field, expect "Direct-Access" later.
1049             local DEVTYPE="$(v=$(echo ${DEVINFO##*Type: }) ; echo ${v%% *})"
1050             [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVTYPE=$DEVTYPE"
1051
1052             if [ "$DEVTYPE" = "Direct-Access" ] || [ "$DEVTYPE" = "Direct-Access-RBC" ] ; then
1053                 ## Lets find out some more information
1054                 ## get the device id.
1055                 local DEVID="$(v=$(echo ${DEVINFO##*Id: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
1056                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVID=$DEVID"
1057
1058                 ## get the device lun.
1059                 local DEVLUN="$(v=$(echo ${DEVINFO##*Lun: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
1060                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVLUN=$DEVLUN"
1061
1062                 ## get the device channel.
1063                 local DEVCHAN="$(v=$(echo ${DEVINFO##*Channel: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
1064                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVCHAN=$DEVCHAN"
1065
1066                 ## get the scsi host id.
1067                 local DEVHOST="$(v=$(echo ${DEVINFO##*Host: scsi}) ; echo ${v%% *})"
1068                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVHOST=$DEVHOST"
1069
1070                 local DEVCOUNT="$(($DEVCOUNT + 1))"
1071                 [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVCOUNT=$DEVCOUNT"
1072                 if [ "$DEVHOST" = "$HOST" -a "$DEVCHAN" = "$BUS" -a \
1073                     "$DEVID" = "$TARGET" -a "$DEVLUN" = "$LUN" ] ; then
1074                     local DEV="sd$(smalltr $DEVCOUNT)${PARTNUM}"
1075                     echo "/dev/$DEV"
1076                     return 0
1077                 fi
1078             fi
1079         done
1080         echo 1>&2 "$PRG: $1: Unable to translate this device, try again without devfs."
1081         return 1
1082         ;;
1083         *)
1084         echo 1>&2 "$PRG: Unknown bus $TYPE"
1085         return 1
1086         ;;
1087     esac
1088     ## we should never get here
1089     return 1
1090 }
1091
1092 ## make sure that find, head and tail can be found.  otherwise the
1093 ## script will silently give bogus paths.  these are the only /usr/*
1094 ## utilities this script depends on.
1095 checkutils()
1096 {
1097     if command -v find > /dev/null 2>&1 ; then
1098         [ -x `command -v find` ] || FAIL=1 ; else FAIL=1 ; fi
1099     if command -v head > /dev/null 2>&1 ; then
1100         [ -x `command -v head` ] || FAIL=1 ; else FAIL=1 ; fi
1101     if command -v tail > /dev/null 2>&1 ; then
1102         [ -x `command -v tail` ] || FAIL=1 ; else FAIL=1 ; fi
1103
1104     if [ "$FAIL" = 1 ] ; then
1105         echo 1>&2 "$PRG: \`find', \`head', or \`tail' could not be found, aborting."
1106         return 1
1107     else
1108         return 0
1109     fi
1110 }
1111
1112 ## parse command line switches.
1113 if [ $# != 0 ] ; then
1114     while true ; do
1115         case "$1" in
1116             -V|--version)
1117                 version
1118                 exit 0
1119                 ;;
1120             -h|--help)
1121                 usage
1122                 exit 0
1123                 ;;
1124             --debug)
1125                 DEBUG=1
1126                 shift
1127                 ;;
1128             -*)
1129                 echo 1>&2 "$PRG: unrecognized option \`$1'"
1130                 echo 1>&2 "$PRG: Try \`$PRG --help' for more information."
1131                 exit 1
1132                 ;;
1133             "")
1134                 echo 1>&2 "$PRG: You must specify a filename"
1135                 echo 1>&2 "Try \`$PRG --help' for more information."
1136                 exit 1
1137                 ;;
1138             *)
1139                 device="$1"
1140                 break
1141                 ;;
1142         esac
1143     done
1144 else
1145     echo 1>&2 "$PRG: You must specify a /dev device"
1146     echo 1>&2 "Try \`$PRG --help' for more information."
1147     exit 1
1148 fi
1149
1150 ## check that we are running on a GNU/Linux system, OSX/BSD does not
1151 ## have the same /proc stuff
1152 if [ `uname -s` != Linux ] ; then
1153     echo 1>&2 "$PRG: This utility will only work with GNU/Linux"
1154     exit 1
1155 fi
1156
1157 ## check for ppc, i think uname -m is safe for this...
1158 if [ `uname -m` != ppc -a `uname -m` != ppc64 ] ; then
1159     echo 1>&2 "$PRG: This utility will only work on PowerPC hardware"
1160     exit 1
1161 fi
1162
1163 ## ofpath cannot live without procfs
1164 if [ ! -f /proc/uptime ] ; then
1165     echo 1>&2 "$PRG: This utility requires the /proc filesystem"
1166     exit 1
1167 fi
1168
1169 ## check for retarded devfs names and tell them to foad.
1170 if ckdevfs "$device" ; then
1171     device="$(fixdevfs $device)" || exit 1
1172 fi
1173
1174 ## check for newworld mac. use cat hack due to /proc wierdness.
1175 if [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:[ ]})" = NewWorld ] ; then
1176     SUBARCH=NewWorld
1177 elif [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:[ ]})" = OldWorld ] ; then
1178     SUBARCH=OldWorld
1179 elif (cat /proc/cpuinfo 2>/dev/null | grep ^motherboard | grep -q AAPL) ; then
1180     SUBARCH=OldWorld
1181 elif (cat /proc/cpuinfo 2> /dev/null | grep ^machine | grep -q 'CHRP IBM') ; then
1182     SUBARCH=CHRP
1183 elif (cat /proc/cpuinfo 2>/dev/null | grep ^machine | grep -q 'CHRP Pegasos') ; then
1184     SUBARCH=Pegasos
1185 else
1186     echo 1>&2 "$PRG: This machine is not yet supported"
1187     exit 1
1188 fi
1189
1190 ## make sure /proc/device-tree exists
1191 if [ ! -d /proc/device-tree ] ; then
1192     echo 1>&2 "$PRG: /proc/device-tree does not exist"
1193     echo 1>&2 "$PRG: Make sure you compiled your kernel with CONFIG_PROC_DEVICETREE=y"
1194     exit 1
1195 fi
1196
1197 ## make sure we have what we need.
1198 checkutils || exit 1
1199
1200 ## get the base device node and scrap /dev/ ie /dev/hda2 -> hda
1201 DEVICE="${device##*/}"
1202 DEVNODE="${DEVICE%%[0-9]*}"
1203 PARTITION="${DEVICE##*[a-z]}"
1204
1205 ## use appropriate search for right sub arch.
1206 case "$SUBARCH" in
1207     # Pegasos OF seems to be NewWorld-ish enough to cope with this.
1208     NewWorld|Pegasos)
1209         newworld || exit 1
1210         ;;
1211     OldWorld)
1212         oldworld || exit 1
1213         ;;
1214     CHRP)
1215         chrp || exit 1
1216         ;;
1217 esac
1218
1219 exit 0