ndisgen.sh revision 145485
1145485Swpaul#!/bin/sh 2145485Swpaul# 3145485Swpaul# Copyright (c) 2005 4145485Swpaul# Bill Paul <wpaul@windriver.com>. All rights reserved. 5145485Swpaul# 6145485Swpaul# Redistribution and use in source and binary forms, with or without 7145485Swpaul# modification, are permitted provided that the following conditions 8145485Swpaul# are met: 9145485Swpaul# 1. Redistributions of source code must retain the above copyright 10145485Swpaul# notice, this list of conditions and the following disclaimer. 11145485Swpaul# 2. Redistributions in binary form must reproduce the above copyright 12145485Swpaul# notice, this list of conditions and the following disclaimer in the 13145485Swpaul# documentation and/or other materials provided with the distribution. 14145485Swpaul# 3. All advertising materials mentioning features or use of this software 15145485Swpaul# must display the following acknowledgement: 16145485Swpaul# This product includes software developed by Bill Paul. 17145485Swpaul# 4. Neither the name of the author nor the names of any co-contributors 18145485Swpaul# may be used to endorse or promote products derived from this software 19145485Swpaul# without specific prior written permission. 20145485Swpaul# 21145485Swpaul# THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 22145485Swpaul# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23145485Swpaul# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24145485Swpaul# ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 25145485Swpaul# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26145485Swpaul# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27145485Swpaul# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28145485Swpaul# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29145485Swpaul# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30145485Swpaul# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31145485Swpaul# THE POSSIBILITY OF SUCH DAMAGE. 32145485Swpaul# 33145485Swpaul# $FreeBSD: head/usr.sbin/ndiscvt/ndisgen.sh 145485 2005-04-24 20:21:22Z wpaul $ 34145485Swpaul# 35145485Swpaul 36145485Swpaulheader () { 37145485Swpaulclear 38145485Swpaulecho " ==================================================================" 39145485Swpaulecho " ------------------ Windows(r) driver converter -------------------" 40145485Swpaulecho " ==================================================================" 41145485Swpaulecho "" 42145485Swpaul} 43145485Swpaul 44145485Swpaulmainmenu() { 45145485Swpaulheader 46145485Swpaulecho " This is script is designed to guide you through the process" 47145485Swpaulecho " of converting a Windows(r) binary driver module and .INF" 48145485Swpaulecho " specification file into a FreeBSD ELF kernel module for use" 49145485Swpaulecho " with the NDIS compatibility system." 50145485Swpaulecho "" 51145485Swpaulecho " The following options are available:" 52145485Swpaulecho "" 53145485Swpaulecho " 1] Learn about the NDIS compatibility system" 54145485Swpaulecho " 2] Convert individual firmware files" 55145485Swpaulecho " 3] Convert driver" 56145485Swpaulecho " 4] Exit" 57145485Swpaulecho "" 58145485Swpaulecho -n " Enter your selection here and press return: " 59145485Swpaulread KEYPRESS 60145485Swpaul} 61145485Swpaul 62145485Swpaul 63145485Swpaulhelp1 () { 64145485Swpaulheader 65145485Swpaulecho " General information" 66145485Swpaulecho "" 67145485Swpaulecho " The NDIS compatibility system is designed to let you use Windows(r)" 68145485Swpaulecho " binary drivers for networking devices with FreeBSD, in cases where" 69145485Swpaulecho " a native FreeBSD driver is not available due to hardware manufacturer" 70145485Swpaulecho " oversight or stupidity. NDIS stands for Network Driver Interface" 71145485Swpaulecho " Standard, and refers to the programming model used to write Windows(r)" 72145485Swpaulecho " network drivers. (These are often called \"NDIS miniport\" drivers.)" 73145485Swpaulecho "" 74145485Swpaulecho " In order to use your network device in NDIS compatibility mode," 75145485Swpaulecho " you need the Windows(r) driver that goes with it. Also, the driver" 76145485Swpaulecho " must be compiled for the same architecture as the release of FreeBSD" 77145485Swpaulecho " you have installed. At this time, the i386 and amd64 architectures" 78145485Swpaulecho " are both supported. Note that you cannot use a Windows/i386 driver" 79145485Swpaulecho " with FreeBSD/amd64: you must obtain a Windows/amd64 driver." 80145485Swpaulecho "" 81145485Swpaulecho -n " Press any key to continue... " 82145485Swpaulread KEYPRESS 83145485Swpaul} 84145485Swpaul 85145485Swpaulhelp2() { 86145485Swpaulheader 87145485Swpaulecho " Where to get drivers" 88145485Swpaulecho "" 89145485Swpaulecho " If you purchased your network card separately from your computer," 90145485Swpaulecho " there should have been a driver distribution CD included with the" 91145485Swpaulecho " card which contains Windows(r) drivers. The NDIS compatibility" 92145485Swpaulecho " system is designed to emulate the NDIS API of a couple of different" 93145485Swpaulecho " Windows(r) releases, however it works best with drivers designed" 94145485Swpaulecho " for NDIS 5.0 or later. Drivers distributed for Windows 2000 should" 95145485Swpaulecho " work, however for best results you should use a driver designed" 96145485Swpaulecho " for Windows XP or Windows Server 2003." 97145485Swpaulecho "" 98145485Swpaulecho " If your card was supplied with your computer, or is a built-in device," 99145485Swpaulecho " drivers may have been included on a special driver bundle CD shipped" 100145485Swpaulecho " with the computer." 101145485Swpaulecho "" 102145485Swpaulecho " If you don't have a driver CD, you should be able to find a driver" 103145485Swpaulecho " kit on the card or computer vendor's web site." 104145485Swpaulecho "" 105145485Swpaulecho -n " Press any key to continue... " 106145485Swpaulread KEYPRESS 107145485Swpaul} 108145485Swpaul 109145485Swpaulhelp3 () { 110145485Swpaulheader 111145485Swpaulecho " What files do I need?" 112145485Swpaulecho "" 113145485Swpaulecho " In most cases, you will need only two files: a .INF file and a .SYS" 114145485Swpaulecho " file. The .INF file is a text file used by the Windows(r) installer to" 115145485Swpaulecho " perform the driver installation. It contains information that tells" 116145485Swpaulecho " the intaller what devices the driver supports and what registry keys" 117145485Swpaulecho " should be created to control driver configuration. The .SYS file" 118145485Swpaulecho " is the actual driver executable code in Windows(r) Portable Executable" 119145485Swpaulecho " (PE) format. Note that sometimes the .INF file is supplied in unicode" 120145485Swpaulecho " format. Unicode .INF files must be converted to ASCII form with the" 121145485Swpaulecho " iconv(1) utility before this installer script can use them." 122145485Swpaulecho " Occasionally, a driver may require firmware or register setup" 123145485Swpaulecho " files that are external to the main .SYS file. These are provided" 124145485Swpaulecho " on the same CD with the driver itself, and sometimes have a .BIN" 125145485Swpaulecho " extension, though they can be named almost anything. You will need" 126145485Swpaulecho " these additional files to make your device work with the NDIS" 127145485Swpaulecho " compatibility system as well." 128145485Swpaulecho "" 129145485Swpaulecho -n " Press any key to continue... " 130145485Swpaulread KEYPRESS 131145485Swpaul} 132145485Swpaul 133145485Swpaulhelp4 () { 134145485Swpaulheader 135145485Swpaulecho " How does it all work?" 136145485Swpaulecho "" 137145485Swpaulecho " The installer script uses the ndiscvt(1) utility to convert the .INF," 138145485Swpaulecho " .SYS and optional firmware files into a FreeBSD kernel loadable module" 139145485Swpaulecho " (.ko) file. This module can be loaded via the kldload(8) utility or" 140145485Swpaulecho " loaded automatically via the /boot/loader.conf file. The ndiscvt(1)" 141145485Swpaulecho " utility extracts the device ID information and registry key data" 142145485Swpaulecho " from the .INF file and converts it into a C header file. It also uses" 143145485Swpaulecho " the objcopy(1) utility to convert the .SYS file and optional firmware" 144145485Swpaulecho " files into ELF objects. The header file is compiled into a small C" 145145485Swpaulecho " stub file which contains a small amount of code to interface with" 146145485Swpaulecho " the FreeBSD module system. This stub is linked together with the" 147145485Swpaulecho " converted ELF objects to form a FreeBSD kernel module. A static ELF" 148145485Swpaulecho " object (.o) file is also created. This file can be linked into a" 149145485Swpaulecho " static kernel image for those who want/need a fully linked kernel" 150145485Swpaulecho " image (possibly for embedded bootstrap purposes, or just plain old" 151145485Swpaulecho " experimentation)." 152145485Swpaulecho "" 153145485Swpaulecho -n " Press any key to continue... " 154145485Swpaulread KEYPRESS 155145485Swpaul} 156145485Swpaul 157145485Swpaulhelp5 () { 158145485Swpaulheader 159145485Swpaulecho " Prerequisites" 160145485Swpaulecho "" 161145485Swpaulecho " Converting a driver requires the following utilities:" 162145485Swpaulecho "" 163145485Swpaulecho " - The FreeBSD C compiler, cc(1) (part of the base install)." 164145485Swpaulecho " - The FreeBSD linker, ld(1) (part of the base install)." 165145485Swpaulecho " - The objcopy(1) utility (part of the base install)." 166145485Swpaulecho " - The ndiscvt(1) utility (part of the base install)." 167145485Swpaulecho "" 168145485Swpaulecho " If your happen to end up with a .INF file that's in unicode format," 169145485Swpaulecho " then you'll also need:" 170145485Swpaulecho "" 171145485Swpaulecho " - The iconv(1) utility." 172145485Swpaulecho "" 173145485Swpaulecho " If you have installed the X Window system or some sort of desktop" 174145485Swpaulecho " environment, then iconv(1) should already be present. If not, you" 175145485Swpaulecho " will need to install the libiconv package or port." 176145485Swpaulecho "" 177145485Swpaulecho -n " Press any key to continue... " 178145485Swpaulread KEYPRESS 179145485Swpaul} 180145485Swpaul 181145485Swpaulinfconv () { 182145485Swpaulheader 183145485Swpaulecho " INF file validation" 184145485Swpaulecho "" 185145485Swpaulecho "" 186145485Swpaulecho " A .INF file is most often provided as an ASCII file, however" 187145485Swpaulecho " files with multilanguage support are provided in Unicode format." 188145485Swpaulecho " Please type in the path to your .INF file now." 189145485Swpaulecho "" 190145485Swpaulecho -n " > " 191145485Swpaulread INFPATH 192145485Swpaulif [ $INFPATH ] && [ -e $INFPATH ]; 193145485Swpaulthen 194145485Swpaul INFTYPE=`${FILE} ${INFPATH}` 195145485Swpaul 196145485Swpaul case ${INFTYPE} in 197145485Swpaul *ASCII*) 198145485Swpaul echo "" 199145485Swpaul echo " This .INF file appears to be ASCII." 200145485Swpaul echo "" 201145485Swpaul echo -n " Press any key to continue... " 202145485Swpaul read KEYPRESS 203145485Swpaul ;; 204145485Swpaul *text*) 205145485Swpaul echo "" 206145485Swpaul echo " This .INF file appears to be ASCII." 207145485Swpaul echo "" 208145485Swpaul echo -n " Press any key to continue... " 209145485Swpaul read KEYPRESS 210145485Swpaul ;; 211145485Swpaul *nicode*) 212145485Swpaul echo "" 213145485Swpaul echo " This .INF file appears to be Unicode." 214145485Swpaul if [ -e $ICONVPATH ]; 215145485Swpaul then 216145485Swpaul echo " Trying to convert to ASCII..." 217145485Swpaul ${RM} -f /tmp/ascii.inf 218145485Swpaul ${ICONVPATH} -f utf-16 -t utf-8 ${INFPATH} > /tmp/ascii.inf 219145485Swpaul INFPATH=/tmp/ascii.inf 220145485Swpaul echo " Done." 221145485Swpaul echo "" 222145485Swpaul echo -n " Press any key to continue... " 223145485Swpaul read KEYPRESS 224145485Swpaul else 225145485Swpaul echo " The iconv(1) utility does not appear to be installed." 226145485Swpaul echo " Please install this utility or convert the .INF file" 227145485Swpaul echo " to ASCII and run this utility again." 228145485Swpaul echo "" 229145485Swpaul exit 230145485Swpaul fi 231145485Swpaul ;; 232145485Swpaul *) 233145485Swpaul echo "" 234145485Swpaul echo " I don't recognize this file format. It may not be a valid .INF file." 235145485Swpaul echo "" 236145485Swpaul echo -n " Press enter to try again, or ^C to quit. " 237145485Swpaul read KEYPRESS 238145485Swpaul INFPATH="" 239145485Swpaul ;; 240145485Swpaul esac 241145485Swpaulelse 242145485Swpaul echo "" 243145485Swpaul echo " The file '$INFPATH' was not found." 244145485Swpaul echo "" 245145485Swpaul echo -n " Press enter to try again, or ^C to quit. " 246145485Swpaul read KEYPRESS 247145485Swpaul INFPATH="" 248145485Swpaulfi 249145485Swpaul} 250145485Swpaul 251145485Swpaulsysconv() { 252145485Swpaulheader 253145485Swpaulecho " Driver file validation" 254145485Swpaulecho "" 255145485Swpaulecho "" 256145485Swpaulecho " Now you need to specify the name of the Windows(r) driver .SYS" 257145485Swpaulecho " file for your device. Note that if you are running FreeBSD/amd64," 258145485Swpaulecho " then you must provide a driver that has been compiled for the" 259145485Swpaulecho " 64-bit Windows(r) platform. If a 64-bit driver is not available" 260145485Swpaulecho " for your device, you must install FreeBSD/ia32 and use the" 261145485Swpaulecho " 32-bit driver instead." 262145485Swpaulecho "" 263145485Swpaulecho " Please type in the path to the Windows(r) driver .SYS file now." 264145485Swpaulecho "" 265145485Swpaulecho -n " > " 266145485Swpaulread SYSPATH 267145485Swpaulif [ $SYSPATH ] && [ -e $SYSPATH ]; 268145485Swpaulthen 269145485Swpaul SYSTYPE=`${FILE} ${SYSPATH}` 270145485Swpaul 271145485Swpaul case ${SYSTYPE} in 272145485Swpaul *Windows*) 273145485Swpaul echo "" 274145485Swpaul echo " This .SYS file appears to be in Windows(r) PE format." 275145485Swpaul echo "" 276145485Swpaul echo -n " Press any key to continue... " 277145485Swpaul read KEYPRESS 278145485Swpaul SYSBASE=`basename ${SYSPATH} | ${TR} '.' '_'` 279145485Swpaul ;; 280145485Swpaul *) 281145485Swpaul echo "" 282145485Swpaul echo " I don't recognize this file format. It may not be a valid .SYS file." 283145485Swpaul echo "" 284145485Swpaul 285145485Swpaul echo -n " Press enter to try again, or ^C to quit. " 286145485Swpaul read KEYPRESS 287145485Swpaul SYSPATH="" 288145485Swpaul ;; 289145485Swpaul esac 290145485Swpaulelse 291145485Swpaul echo "" 292145485Swpaul echo " The file '$SYSPATH' was not found." 293145485Swpaul echo "" 294145485Swpaul echo -n " Press enter to try again, or ^C to quit. " 295145485Swpaul read KEYPRESS 296145485Swpaul SYSPATH="" 297145485Swpaulfi 298145485Swpaul} 299145485Swpaul 300145485Swpaulndiscvt() { 301145485Swpaulheader 302145485Swpaulecho " Driver file conversion" 303145485Swpaulecho "" 304145485Swpaulecho " The script will now try to convert the .INF and .SYS files" 305145485Swpaulecho " using the ndiscvt(1) utility. This utility can handle most" 306145485Swpaulecho " .INF files, however occasionally it can fail to parse some files" 307145485Swpaulecho " due to subtle syntax issues: the .INF syntax is very complex," 308145485Swpaulecho " and the Windows(r) parser will sometimes allow files with small" 309145485Swpaulecho " syntax errors to be processed correctly which ndiscvt(1) will" 310145485Swpaulecho " not. If the conversion fails, you may have to edit the .INF" 311145485Swpaulecho " file by hand to remove the offending lines." 312145485Swpaulecho "" 313145485Swpaulecho -n " Press enter to try converting the files now: " 314145485Swpaulread KEYPRESS 315145485Swpaulif ! ${NDISCVT} -i ${INFPATH} -s ${SYSPATH} -O -o ${DNAME}.h > /dev/null; then 316145485Swpaul echo "CONVERSION FAILED" 317145485Swpaul exit 318145485Swpaulelse 319145485Swpaul echo "" 320145485Swpaul echo " Conversion was successful." 321145485Swpaul echo "" 322145485Swpaul echo -n " Press enter to continue... " 323145485Swpaul read KEYPRESS 324145485Swpaulfi 325145485Swpaul} 326145485Swpaul 327145485Swpaulfirmcvt() { 328145485Swpaul while : ; do 329145485Swpaulheader 330145485Swpaulecho " Firmware file conversion" 331145485Swpaulecho "" 332145485Swpaulecho " If your driver uses additional firmware files, please list them" 333145485Swpaulecho " below. When you're finished, just press enter to contiue. (If your" 334145485Swpaulecho " driver doesn't need any extra firmware files, just press enter" 335145485Swpaulecho " to move to the next step.)" 336145485Swpaulecho "" 337145485Swpaul echo -n " > " 338145485Swpaul read FIRMPATH 339145485Swpaul 340145485Swpaul if [ $FIRMPATH ] && [ $FIRMPATH != "" ]; then 341145485Swpaul if [ ! -e $FIRMPATH ]; then 342145485Swpaul echo "" 343145485Swpaul echo " The file '$FIRMPATH' was not found" 344145485Swpaul echo "" 345145485Swpaul echo -n " Press enter to try again, or ^C to quit. " 346145485Swpaul read KEYPRESS 347145485Swpaul continue 348145485Swpaul fi 349145485Swpaul if ! ${NDISCVT} -f ${FIRMPATH} > /dev/null; then 350145485Swpaul echo "" 351145485Swpaul echo "CONVERSION FAILED" 352145485Swpaul else 353145485Swpaul echo "" 354145485Swpaul echo " Conversion was successful." 355145485Swpaul echo "" 356145485Swpaul FRMBASE=`basename ${FIRMPATH}` 357145485Swpaul FRMBASE="${FRMBASE}.o" 358145485Swpaul FRMLIST="${FRMLIST} ${FRMBASE}" 359145485Swpaul fi 360145485Swpaul echo -n " Press enter to continue... " 361145485Swpaul read KEYPRESS 362145485Swpaul else 363145485Swpaul break 364145485Swpaul fi 365145485Swpaul done 366145485Swpaul 367145485Swpaulheader 368145485Swpaulecho "" 369145485Swpaulecho " List of files converted firmware files:" 370145485Swpaulecho "" 371145485Swpaulfor i in $FRMLIST 372145485Swpauldo 373145485Swpaul echo " "$i 374145485Swpauldone 375145485Swpaulecho "" 376145485Swpaulecho -n " Press enter to continue... " 377145485Swpaulread KEYPRESS 378145485Swpaul} 379145485Swpaul 380145485Swpauldrvgen () { 381145485Swpaulheader 382145485Swpaulecho " Kernel module generation" 383145485Swpaulecho "" 384145485Swpaulecho "" 385145485Swpaulecho " The script will now try to generate the kernel driver module." 386145485Swpaulecho " This is the last step. Once this module is generated, you should" 387145485Swpaulecho " be able to load it just like any other FreeBSD driver module." 388145485Swpaulecho "" 389145485Swpaulecho " Press enter to compile the stub module and generate the driver" 390145485Swpaulecho -n " module now: " 391145485Swpaulread KEYPRESS 392145485Swpaulecho "" 393145485Swpaultouch bus_if.h 394145485Swpaultouch device_if.h 395145485Swpaulecho -n " Compiling stub... " 396145485Swpaulif ! ${CC} -D_KERNEL -DDRV_DATA_START=${SYSBASE}_drv_data_start -DDRV_NAME=${SYSBASE} -DDRV_DATA_END=${SYSBASE}_drv_data_end -I. ${STUBFILE} -c -o windrv_stub.o; then 397145485Swpaul echo "compilation failed. Exiting." 398145485Swpaul echo "" 399145485Swpaul exit 400145485Swpaulelse 401145485Swpaul echo "done." 402145485Swpaulfi 403145485Swpaulecho -n " Linking loadable kernel module... " 404145485Swpaulif ! ${LD} -Bshareable -d -warn-common -o ${SYSBASE}.ko windrv_stub.o ${FRMLIST} ${DNAME}.o; then 405145485Swpaul echo "linking failed. Exiting." 406145485Swpaul echo "" 407145485Swpaul exit 408145485Swpaulelse 409145485Swpaul echo "done." 410145485Swpaulfi 411145485Swpaulecho -n " Linking static kernel module... " 412145485Swpaulif ! ${LD} -r -d -warn-common -o ${SYSBASE}.o windrv_stub.o ${FRMLIST} ${DNAME}.o; then 413145485Swpaul echo "linking failed. Exiting." 414145485Swpaul echo "" 415145485Swpaul exit 416145485Swpaulelse 417145485Swpaul echo "done." 418145485Swpaulfi 419145485Swpaulecho -n " Cleaning up... " 420145485Swpaul${RM} -f bus_if.h device_if.h windrv_stub.o 421145485Swpaul${RM} -f ${DNAME}.h ${DNAME}.o 422145485Swpaulecho "done." 423145485Swpaulecho "" 424145485Swpaulecho " The file $SYSBASE.ko has been successfully generated." 425145485Swpaulecho " You can kldload this module to get started." 426145485Swpaulecho "" 427145485Swpaulecho -n " Press any key to exit. " 428145485Swpaulread KEYPRESS 429145485Swpaulecho "" 430145485Swpaulecho "" 431145485Swpaul} 432145485Swpaul 433145485Swpaulconvert_driver () { 434145485Swpaul while : ; do 435145485Swpaul infconv 436145485Swpaul if [ $INFPATH ] && [ $INFPATH != "" ]; then 437145485Swpaul break 438145485Swpaul fi 439145485Swpaul done 440145485Swpaul 441145485Swpaul while : ; do 442145485Swpaul sysconv 443145485Swpaul if [ $SYSPATH ] && [ $SYSPATH != "" ]; then 444145485Swpaul break 445145485Swpaul fi 446145485Swpaul done 447145485Swpaul 448145485Swpaul ndiscvt 449145485Swpaul firmcvt 450145485Swpaul drvgen 451145485Swpaul} 452145485Swpaul 453145485SwpaulICONVPATH=/usr/local/bin/iconv 454145485SwpaulNDISCVT=/usr/sbin/ndiscvt 455145485SwpaulSTUBFILE=/usr/share/misc/windrv_stub.c 456145485SwpaulDNAME=windrv 457145485SwpaulOBJCOPY=/usr/bin/objcopy 458145485SwpaulCC=/usr/bin/cc 459145485SwpaulLD=/usr/bin/ld 460145485SwpaulRM=/bin/rm 461145485SwpaulTR=/usr/bin/tr 462145485SwpaulFILE=/usr/bin/file 463145485Swpaul 464145485SwpaulINFPATH="" 465145485SwpaulFRMLIST="" 466145485SwpaulSYSPATH="" 467145485SwpaulSYSBASE="" 468145485SwpaulFRMBASE="" 469145485Swpaul 470145485Swpaulwhile : ; do 471145485Swpaul mainmenu 472145485Swpaul case ${KEYPRESS} in 473145485Swpaul 1) 474145485Swpaul help1 475145485Swpaul help2 476145485Swpaul help3 477145485Swpaul help4 478145485Swpaul help5 479145485Swpaul ;; 480145485Swpaul 2) 481145485Swpaul firmcvt 482145485Swpaul ;; 483145485Swpaul 3) 484145485Swpaul convert_driver 485145485Swpaul ;; 486145485Swpaul 4) 487145485Swpaul header 488145485Swpaul echo "" 489145485Swpaul echo " Be seeing you!" 490145485Swpaul echo "" 491145485Swpaul exit 492145485Swpaul ;; 493145485Swpaul *) 494145485Swpaul header 495145485Swpaul echo "" 496145485Swpaul echo -n " Sorry, I didn't underatand that. Press enter to try again: " 497145485Swpaul read KEYPRESS 498145485Swpaul ;; 499145485Swpaul esac 500145485Swpauldone 501