From: wdenk Date: Wed, 17 Oct 2001 20:21:46 +0000 (+0000) Subject: * Extend LWMON keyboard driver to allow for more than one key-coded X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=b6aee9dc435f9d91a6c9f3a8f7eaf2ca418ad4ea;p=users%2Frw%2Fppcboot.git * Extend LWMON keyboard driver to allow for more than one key-coded pre-boot command (we now support an unlimited number of keys) * Added "hush" shell (from Busybox) as alternative command line interpreter, thus enabling powerful command line syntax like if...then...else...fi conditionals or `&&' and '||' constructs ("shell scripts"). * Modified all commands to provide return codes that can be used for conditional command execution --- diff --git a/CHANGELOG b/CHANGELOG index fa9b3cb..8d4c244 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -52,6 +52,21 @@ To do: * "last user address" is set even if bootp is used without parameters (and it uses default address). +====================================================================== +Modifications for 1.1.0: +====================================================================== + +* Extend LWMON keyboard driver to allow for more than one key-coded + pre-boot command (we now support an unlimited number of keys) + +* Added "hush" shell (from Busybox) as alternative command line + interpreter, thus enabling powerful command line syntax like + if...then...else...fi conditionals or `&&' and '||' constructs + ("shell scripts"). + +* Modified all commands to provide return codes that can be used for + conditional command execution + ====================================================================== Modifications for 1.0.6: ====================================================================== diff --git a/README b/README index f2056f5..b436f01 100644 --- a/README +++ b/README @@ -629,6 +629,25 @@ The following options need to be configured: useful during development since you can try to debug the conditions that lead to the situation. +- Command Interpreter: + CFG_HUSH_PARSER + + Define this variable to enable the "hush" shell (from + Busybox) as command line interpreter, thus enabling + powerful command line syntax like + if...then...else...fi conditionals or `&&' and '||' + constructs ("shell scripts"). + + If undefined, you get the old, much simpler behaviour + with a somewhat smapper memory footprint. + + + CFG_PROMPT_HUSH_PS2 + + This defines the secondary prompt string, which is + printed when the command interpreter needs more input + to complete a command. Usually "> ". + Configuration Settings: ----------------------- diff --git a/board/RPXlite/flash.c b/board/RPXlite/flash.c index 89b192e..c137d47 100644 --- a/board/RPXlite/flash.c +++ b/board/RPXlite/flash.c @@ -174,6 +174,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -316,7 +317,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int flag, prot, sect, l_sect; @@ -328,14 +329,14 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -391,7 +392,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) while ((addr[0] & 0x80808080) != 0x80808080) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -406,6 +407,7 @@ DONE: addr[0] = 0xF0F0F0F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/cogent/flash.c b/board/cogent/flash.c index 2726c7f..0154d68 100644 --- a/board/cogent/flash.c +++ b/board/cogent/flash.c @@ -374,6 +374,7 @@ flash_print_info(flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -387,7 +388,7 @@ flash_print_info(flash_info_t *info) * The following code cannot be run from FLASH! */ -void +int flash_erase(flash_info_t *info, int s_first, int s_last) { int prot, sect, haderr; @@ -395,6 +396,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last) void (*erase_init)(flash_info_t *, int); int (*erase_poll)(flash_info_t *, int); void (*reset)(flash_info_t *, int); + int rcode = 0; #ifdef FLASH_DEBUG printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n" @@ -409,7 +411,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } switch (info->flash_id) { @@ -436,7 +438,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last) default: printf ("Flash type %08lx not supported - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -498,8 +500,10 @@ flash_erase(flash_info_t *info, int s_first, int s_last) } } - if (haderr > 0) + if (haderr > 0) { printf (" failed\n"); + rcode = 1; + } else printf (" done\n"); @@ -509,6 +513,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last) (*reset)(info, sect); } } + return rcode; } /*----------------------------------------------------------------------- diff --git a/board/cray/L1/L1.c b/board/cray/L1/L1.c index 2f71af0..0633a71 100644 --- a/board/cray/L1/L1.c +++ b/board/cray/L1/L1.c @@ -194,7 +194,7 @@ u8 thing; /* ------------------------------------------------------------------------- */ -void do_crayL1(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_crayL1(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unsigned long addr, valu,old; u8 thing,need_save=0,only, *ptr; @@ -219,7 +219,7 @@ u8 thing,need_save=0,only, *ptr; for ( thing=0; thing < N_THINGS; thing++) printf ("%s ",Things[thing].envname); printf ("]\n"); - return; + return 1; } else printf ("Update %s\n",Things[only].envname); @@ -274,7 +274,7 @@ u8 thing,need_save=0,only, *ptr; } if (need_save) do_saveenv (NULL,NULL,0,0,NULL); - return; + return 0; } if (strcmp(argv[1], "boot") == 0) // boot ourselves up. @@ -309,18 +309,18 @@ u8 thing,need_save=0,only, *ptr; addr = load_addr; do_bootm (cmdtp, bd, 0, 1, NULL); - return; + return 0; } if (strcmp(argv[1], "regs") == 0) // Dump DCRs { printf("cray regs command..UNIMPLEMENTED.\n"); - return; + return 1; } if (strcmp(argv[1], "mfdcr") == 0) // read a DCR from argv[2] (HEX!) { addr = simple_strtoul(argv[2], NULL, 16); printf("cray mfcdr command: read from DCR 0x%lx UNIMPLEMENTED.\n",addr); - return; + return 1; } if (strcmp(argv[1], "mtdcr") == 0) // write a DCR from argv[2] (HEX!) { @@ -328,11 +328,11 @@ u8 thing,need_save=0,only, *ptr; valu = simple_strtoul(argv[3], NULL, 16); printf("cray mtcdr command: write 0x%lx to DCR 0x%lx UNIMPLEMENTED\n", valu, addr); - return; + return 1; } printf("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } diff --git a/board/cray/L1/flash.c b/board/cray/L1/flash.c index 9f00961..1e0af0e 100644 --- a/board/cray/L1/flash.c +++ b/board/cray/L1/flash.c @@ -270,7 +270,7 @@ int wait_for_DQ7(flash_info_t *info, int sect) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]); volatile FLASH_WORD_SIZE *addr2; @@ -282,12 +282,12 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if (info->flash_id == FLASH_UNKNOWN) { printf ("Can't erase unknown flash type - aborted\n"); - return; + return 1; } prot = 0; @@ -345,6 +345,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/cu824/flash.c b/board/cu824/flash.c index 921c66c..010a5fd 100644 --- a/board/cu824/flash.c +++ b/board/cu824/flash.c @@ -183,12 +183,13 @@ void flash_print_info (flash_info_t *info) printf ("\n"); Done: + return; } /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { int flag, prot, sect; ulong start, now, last; @@ -199,13 +200,13 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK)) { printf ("Can erase only Intel flash types - aborted\n"); - return; + return 1; } prot = 0; @@ -252,7 +253,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) printf ("Timeout\n"); *addr = 0x00B000B0; /* suspend erase */ *addr = 0x00FF00FF; /* to read mode */ - return; + return 1; } /* show that we're waiting */ @@ -266,6 +267,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } } printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/eric/flash.c b/board/eric/flash.c index f688a29..75a507a 100644 --- a/board/eric/flash.c +++ b/board/eric/flash.c @@ -381,6 +381,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } @@ -611,12 +612,13 @@ ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { volatile FLASH_WORD_SIZE *addr=(volatile FLASH_WORD_SIZE*)(info->start[0]); int flag, prot, sect, l_sect, barf; ulong start, now, last; + int rcode = 0; if ((s_first < 0) || (s_first > s_last)) { if (info->flash_id == FLASH_UNKNOWN) { @@ -624,14 +626,14 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || ((info->flash_id > FLASH_AMD_COMP) && ( (info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL ) ) ){ printf ("Can't erase unknown flash type - aborted\n"); - return; + return 1; } prot = 0; @@ -696,7 +698,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -744,6 +746,7 @@ DONE: if((barf & 0x0030) == 0x0020) printf("Block Erase error.\n"); if(barf & 0x0008) printf("Vpp Low error.\n"); + rcode = 1; } else printf("."); l_sect = sect; } @@ -754,6 +757,7 @@ DONE: } printf (" done\n"); + return rcode; } /*----------------------------------------------------------------------- diff --git a/board/esd/common/flash.c b/board/esd/common/flash.c index 4059035..4b4505c 100644 --- a/board/esd/common/flash.c +++ b/board/esd/common/flash.c @@ -154,6 +154,7 @@ void flash_print_info (flash_info_t *info) } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -318,7 +319,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *)(info->start[0]); volatile CFG_FLASH_WORD_SIZE *addr2; @@ -332,12 +333,12 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if (info->flash_id == FLASH_UNKNOWN) { printf ("Can't erase unknown flash type - aborted\n"); - return; + return 1; } prot = 0; @@ -405,7 +406,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) while ((addr[0] & (CFG_FLASH_WORD_SIZE)0x00800080) != (CFG_FLASH_WORD_SIZE)0x00800080) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -420,6 +421,7 @@ DONE: addr[0] = (CFG_FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/esd/dasa_sim/cmd_dasa_sim.c b/board/esd/dasa_sim/cmd_dasa_sim.c index d03bc0c..addb639 100644 --- a/board/esd/dasa_sim/cmd_dasa_sim.c +++ b/board/esd/dasa_sim/cmd_dasa_sim.c @@ -213,31 +213,31 @@ static void clearPci9054(void) /* ------------------------------------------------------------------------- */ - -void do_pci9054(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_pci9054(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { pci9054_init(); if (strcmp(argv[1], "info") == 0) { showPci9054(); - return; + return 0; } if (strcmp(argv[1], "update") == 0) { updatePci9054(); - return; + return 0; } if (strcmp(argv[1], "clear") == 0) { clearPci9054(); - return; + return 0; } printf("Usage:\n%s\n", cmdtp->usage); - return; + return 1; + } /* ------------------------------------------------------------------------- */ diff --git a/board/esteem192e/flash.c b/board/esteem192e/flash.c index 03cc6c3..66dfb32 100644 --- a/board/esteem192e/flash.c +++ b/board/esteem192e/flash.c @@ -336,6 +336,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -650,12 +651,13 @@ ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { volatile FLASH_WORD_SIZE *addr=(volatile FLASH_WORD_SIZE*)(info->start[0]); int flag, prot, sect, l_sect, barf; ulong start, now, last; + int rcode = 0; if ((s_first < 0) || (s_first > s_last)) { if (info->flash_id == FLASH_UNKNOWN) { @@ -663,14 +665,14 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || ((info->flash_id > FLASH_AMD_COMP) && ( (info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL ) ) ){ printf ("Can't erase unknown flash type - aborted\n"); - return; + return 1; } prot = 0; @@ -735,7 +737,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -783,6 +785,7 @@ DONE: if((barf & 0x0030) == 0x0020) printf("Block Erase error.\n"); if(barf & 0x0008) printf("Vpp Low error.\n"); + rcode = 1; } else printf("."); l_sect = sect; } @@ -793,6 +796,7 @@ DONE: } printf (" done\n"); + return rcode; } /*----------------------------------------------------------------------- diff --git a/board/etx094/flash.c b/board/etx094/flash.c index 0728b4f..1aab41d 100644 --- a/board/etx094/flash.c +++ b/board/etx094/flash.c @@ -241,6 +241,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -465,7 +466,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int flag, prot, sect; @@ -480,7 +481,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } /*#ifndef CONFIG_FLASH_16BIT ulong type; @@ -549,7 +550,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) #endif if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -569,6 +570,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) #endif printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/evb64260/flash.c b/board/evb64260/flash.c index abcdd1f..e399c88 100644 --- a/board/evb64260/flash.c +++ b/board/evb64260/flash.c @@ -179,6 +179,7 @@ flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -339,7 +340,7 @@ flash_get_size (int fl_width, vu_long *addr, flash_info_t *info) return (info->size); } -void +int flash_erase (flash_info_t *info, int s_first, int s_last) { volatile unsigned char *addr = (char *)(info->start[0]); @@ -352,14 +353,14 @@ flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -415,7 +416,7 @@ flash_erase (flash_info_t *info, int s_first, int s_last) while ((addr[0] & 0x80) != 0x80) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -430,6 +431,7 @@ DONE: addr[0] = 0xF0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/fads/flash.c b/board/fads/flash.c index 4b9e9eb..9986504 100644 --- a/board/fads/flash.c +++ b/board/fads/flash.c @@ -230,6 +230,7 @@ void flash_print_info (flash_info_t *info) } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -399,7 +400,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int flag, prot, sect, l_sect; @@ -411,13 +412,13 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type - aborted\n"); - return; + return 1; } prot = 0; @@ -490,7 +491,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -509,6 +510,7 @@ DONE: #endif printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/flagadm/flash.c b/board/flagadm/flash.c index 3e09b5c..fe4bf71 100644 --- a/board/flagadm/flash.c +++ b/board/flagadm/flash.c @@ -137,7 +137,7 @@ void flash_print_info (flash_info_t *info) if (info->flash_id == FLASH_UNKNOWN) { printf ("missing or unknown FLASH type\n"); - return; + return ; } switch (info->flash_id & FLASH_VENDMASK) { @@ -165,6 +165,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return ; } /*----------------------------------------------------------------------- @@ -305,11 +306,12 @@ int flash_decode_status_bits(char status) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_short *addr; int flag, prot, sect; ulong start, now, last; + int rcode = 0; if ((s_first < 0) || (s_first > s_last)) { if (info->flash_id == FLASH_UNKNOWN) { @@ -317,13 +319,13 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -368,7 +370,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); *addr = 0xFFFF; /* reset bank */ - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -380,6 +382,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) if(flash_decode_status_bits(tmp|INTEL_FLASH_STATUS_WSMS)==-1 && (tmp & INTEL_FLASH_STATUS_WSMS)) { printf("Error erasing\n"); + rcode++; break; } } @@ -390,6 +393,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) *addr = 0xFFFF; /* reset bank */ printf (" done\n"); + return rcode; } void sector_protect (flash_info_t *info, int on, int s_first, int s_last) diff --git a/board/genietv/flash.c b/board/genietv/flash.c index 492c881..2bbae2d 100644 --- a/board/genietv/flash.c +++ b/board/genietv/flash.c @@ -154,6 +154,7 @@ void flash_print_info (flash_info_t *info) } putc ('\n'); + return; } /*----------------------------------------------------------------------- */ @@ -248,7 +249,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { volatile unsigned char *addr = (volatile unsigned char *)(info->start[0]); int flag, prot, sect, l_sect; @@ -260,13 +261,13 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type - aborted\n"); - return; + return 1; } prot = 0; @@ -324,7 +325,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -340,6 +341,7 @@ DONE: addr[0] = 0xF0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/gth/flash.c b/board/gth/flash.c index 6154234..531b5ef 100644 --- a/board/gth/flash.c +++ b/board/gth/flash.c @@ -241,6 +241,7 @@ void flash_print_info (flash_info_t *info) } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -411,7 +412,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int flag, prot, sect, l_sect; @@ -423,13 +424,13 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type - aborted\n"); - return; + return 1; } prot = 0; @@ -502,7 +503,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -521,6 +522,7 @@ DONE: #endif printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/hermes/flash.c b/board/hermes/flash.c index 7a8c590..6b268fc 100644 --- a/board/hermes/flash.c +++ b/board/hermes/flash.c @@ -162,6 +162,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -304,7 +305,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_char *addr = (vu_char*)(info->start[0]); int flag, prot, sect, l_sect; @@ -316,14 +317,14 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -379,7 +380,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) while ((addr[0] & 0x80) != 0x80) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -394,6 +395,7 @@ DONE: addr[0] = 0xF0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/hymod/bsp.c b/board/hymod/bsp.c index a477931..ac53756 100644 --- a/board/hymod/bsp.c +++ b/board/hymod/bsp.c @@ -140,8 +140,7 @@ done: } /* ------------------------------------------------------------------------- */ - -void +int do_fpga(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { uchar *addr, *save_addr; @@ -166,7 +165,7 @@ do_fpga(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) FPGA_MAIN_PORT_BASE, FPGA_MAIN_PORT_SIZE); printf(" Mezz Configuration: 0x%08x %d\n", FPGA_MEZZ_CFG_BASE, FPGA_MEZZ_CFG_SIZE); - return; + return 0; } break; @@ -183,12 +182,13 @@ do_fpga(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #else result = 0; #endif - - if (result == STORE_SUCCESS) + if (result == STORE_SUCCESS) { printf("SUCCEEDED (%d bytes)\n", addr - save_addr); + return 0; + } else printf("FAILED (%d bytes)\n", addr - save_addr); - return; + return 1; } break; @@ -199,25 +199,27 @@ do_fpga(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (NetLoop(bd, TFTP) == 0) { printf("tftp transfer failed - aborting fgpa load\n"); - return; + return 1; } if (NetBootFileXferSize == 0) { printf("can't determine file size - aborting fpga load\n"); - return; + return 1; } printf("File transfer succeeded - beginning fpga load..."); result = fpga_load(bd, 0, (uchar *)load_addr, NetBootFileXferSize); - - if (result == LOAD_SUCCESS) + if (result == LOAD_SUCCESS) { printf("SUCCEEDED\n"); + return 0; + } else if (result == LOAD_FAIL_NOINIT) printf("FAILED (no INIT)\n"); else printf("FAILED (no DONE)\n"); - return; + return 1; + } /* fall through ... */ @@ -230,7 +232,7 @@ do_fpga(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) mezz = 1; else { printf("FPGA type must be either `main' or `mezz'\n"); - return; + return 1; } arg = 3; } @@ -242,14 +244,15 @@ do_fpga(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) size = (ulong)simple_strtoul(argv[arg], NULL, 16); result = fpga_load(bd, mezz, addr, size); - - if (result == LOAD_SUCCESS) + if (result == LOAD_SUCCESS) { printf("SUCCEEDED\n"); + return 0; + } else if (result == LOAD_FAIL_NOINIT) printf("FAILED (no INIT)\n"); else printf("FAILED (no DONE)\n"); - return; + return 1; } break; @@ -258,16 +261,16 @@ do_fpga(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } printf("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } /* ------------------------------------------------------------------------- */ - -void +int do_eecl(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { uchar data[HYMOD_EEPROM_SIZE]; uint offset; + int rcode = 0; switch (argc) { @@ -288,12 +291,12 @@ do_eecl(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) default: printf("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } - + memset(data, 0, HYMOD_EEPROM_SIZE); - - eeprom_write(offset, data, HYMOD_EEPROM_SIZE); + if (eeprom_write(offset, data, HYMOD_EEPROM_SIZE) != 0) rcode = 1; + return rcode; } #endif /* CFG_CMD_BSP */ diff --git a/board/hymod/flash.c b/board/hymod/flash.c index 0812da1..bc5ccde 100644 --- a/board/hymod/flash.c +++ b/board/hymod/flash.c @@ -408,6 +408,7 @@ flash_print_info(flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -549,11 +550,12 @@ flash_get_size(vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void +int flash_erase(flash_info_t *info, int s_first, int s_last) { int prot, sect, haderr; ulong start, now, last; + int rcode = 0; #ifdef FLASH_DEBUG printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n" @@ -568,7 +570,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } prot = 0; @@ -605,6 +607,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last) if (now - estart > CFG_FLASH_ERASE_TOUT) { printf ("Timeout (sect %d)\n", sect); haderr = 1; + rcode = 1; break; } @@ -620,6 +623,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last) if (sectdone < 0) { haderr = 1; + rcode = 1; break; } @@ -641,6 +645,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last) bank_reset(info, sect); } } + return rcode; } /*----------------------------------------------------------------------- diff --git a/board/icu862/flash.c b/board/icu862/flash.c index 521a305..7721653 100644 --- a/board/icu862/flash.c +++ b/board/icu862/flash.c @@ -386,7 +386,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int flag, prot, sect, l_sect; @@ -398,13 +398,13 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type - aborted\n"); - return; + return 1; } prot = 0; @@ -477,7 +477,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -496,6 +496,7 @@ DONE: #endif printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/ip860/flash.c b/board/ip860/flash.c index 698fb65..97e1f78 100644 --- a/board/ip860/flash.c +++ b/board/ip860/flash.c @@ -165,6 +165,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -250,7 +251,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr; int flag, prot, sect; @@ -262,13 +263,13 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -313,7 +314,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); *addr = 0xFFFFFFFF; /* reset bank */ - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -328,6 +329,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) *addr = 0xFFFFFFFF; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/ivms8/flash.c b/board/ivms8/flash.c index ba1fe49..956414f 100644 --- a/board/ivms8/flash.c +++ b/board/ivms8/flash.c @@ -248,6 +248,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -397,7 +398,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { int flag, prot, sect; ulong start, now, last; @@ -408,12 +409,12 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_MT) { printf ("Can erase only MT flash types - aborted\n"); - return; + return 1; } prot = 0; @@ -456,7 +457,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); *addr = 0x00FF; /* reset to read mode */ - return; + return 1; } /* show that we're waiting */ @@ -470,6 +471,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } } printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/lantec/flash.c b/board/lantec/flash.c index a2a9ce0..f753942 100644 --- a/board/lantec/flash.c +++ b/board/lantec/flash.c @@ -274,6 +274,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -417,7 +418,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int flag, prot, sect, l_sect; @@ -429,14 +430,14 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -492,7 +493,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) while ((addr[0] & 0x00800080) != 0x00800080) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -507,6 +508,7 @@ DONE: addr[0] = 0x00F000F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/lwmon/README.keybd b/board/lwmon/README.keybd new file mode 100644 index 0000000..926b2e6 --- /dev/null +++ b/board/lwmon/README.keybd @@ -0,0 +1,76 @@ + +Tastaturabfrage: + +Die Implementierung / Decodierung beruht auf den Angaben aus dem Do- +kument "PIC LWE-Tastatur" in der Fassung vom 9. 3. 2001, insbesonde- +re Tabelle 3 im Kapitel 4.3 Tastencodes. In PPCBoot werden die vom +Keyboard-Controller gelesenen Daten hexadezimal codiert in der auto- +matisch angelegten Environment-Variablen "keybd" übergeben. Ist kei- +ne Taste gedrückt worden, steht dort: + + keybd=000000000000000000 + +Der decodierte Tastencode ("keybd") kann mit den "bootargs" an den +Linux-Kernel übergeben und dort z. B. in einem Device-Treiber oder +einer Applikation ausgewertet werden. + + + +Sonderfunktionen beim Booten: + +Es lassen sich eine oder mehrere (beliebig viele) Tasten oder Tasten- +kombinationen definieren, die Sonderfunktionen auslösen, wenn diese +Tasten beim Booten (Reset) gedrückt sind. + +Wird eine eingestellte Taste bzw. Tastenkombination erkannt, so wird +in PPCBoot noch vor dem Start des "Countdown" und somit vor jedem +anderen Kommando der Inhalt einer dieser Taste bzw. Tastenkombination +zugeordneten Environment-Variablen ausführen. + + +Die Environment-Variable "magic_keys" wird als Liste von Zeichen ver- +standen, die als Suffix an den Namen "key_magic" angefügt werden und +so die Namen der Environment-Variablen definieren, mit denen die +Tasten (-kombinationen) festgelegt werden: + +Ist "magic_keys" NICHT definiert, so wird nur die in der Environment- +Variablen "key_magic" codierte Tasten (-kombination) geprüft, und +ggf. der Inhalt der Environment-Variablen "key_cmd" ausgeführt. + +Enthält "magic_keys" z. B. die Zeichenkette "0123CB*", so werden +nacheinander folgende Aktionen ausgeführt: + + prüfe Tastencode ggf. führe aus Kommando + in Variable in Variable + ----------------------------------- + key_magic0 ==> key_cmd0 + key_magic1 ==> key_cmd1 + key_magic2 ==> key_cmd2 + key_magic3 ==> key_cmd3 + key_magicC ==> key_cmdC + key_magicB ==> key_cmdB + key_magicA ==> key_cmdA + key_magic* ==> key_cmd* + +Die Codierung der Tasten, die beim Booten gedrückt werden müssen, um +eine Funktion auszulösen, erfolgt nach der Tastaturtabelle. + +Die Definitionen + + => setenv key_magic0 3a+3b + => setenv key_cmd0 setenv bootdelay 30 + +bedeuten dementsprechend, daß die Tasten mit den Codes 0x3A (Taste +"F1") und 0x3B (Taste "F2") gleichzeitig gedrückt werden müssen. Sie +können dort eine beliebige Tastenkombination eintragen (jeweils 2 +Zeichen für die Hex-Codes der Tasten, und '+' als Trennzeichen). + +Wird die eingestellte Tastenkombination erkannt, so wird in PPCBoot +noch vor dem Start des "Countdown" und somit vor jedem anderen Kom- +mando das angebene Kommando ausgeführt und somit ein langes Boot- +Delay eingetragen. + +Praktisch könnten Sie also in PPCBoot "bootdelay" auf 0 setzen und +somit stets ohne jede User-Interaktion automatisch booten, außer, +wenn die beiden Tasten "F1" und "F2" beim Booten gedrückt werden: +dann würde ein Boot-Delay von 30 Sekunden eingefügt. diff --git a/board/lwmon/flash.c b/board/lwmon/flash.c index 2417752..e8a7bfb 100644 --- a/board/lwmon/flash.c +++ b/board/lwmon/flash.c @@ -267,6 +267,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -359,7 +360,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { int flag, prot, sect; ulong start, now, last; @@ -370,12 +371,12 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) { printf ("Can erase only Intel flash types - aborted\n"); - return; + return 1; } prot = 0; @@ -419,7 +420,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) printf ("Timeout\n"); *addr = 0x00B000B0; /* suspend erase */ *addr = 0x00FF00FF; /* reset to read mode */ - return; + return 1; } /* show that we're waiting */ @@ -433,6 +434,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } } printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/lwmon/lwmon.c b/board/lwmon/lwmon.c index dcb851e..e8159d8 100644 --- a/board/lwmon/lwmon.c +++ b/board/lwmon/lwmon.c @@ -27,6 +27,10 @@ #include #include #include +#include + +#include +#include /* for strdup */ /* ------------------------------------------------------------------------- */ @@ -290,17 +294,20 @@ void reset_phy(void) #define KEYBD_VERSIONLEN 2 /* version information */ #define KEYBD_DATALEN 9 /* normal key scan data */ +/* maximum number of "magic" key codes that can be assigned */ + static uchar kbd_addr = CFG_I2C_KEYBD_ADDR; -static uchar kbd_data[KEYBD_DATALEN]; -uchar keybd_env[2*KEYBD_DATALEN+1]; +static uchar kbd_data [KEYBD_DATALEN]; +static uchar keybd_env[2*KEYBD_DATALEN+1]; #ifdef CONFIG_PREBOOT -static int key_match (uchar *); +static uchar *key_match (uchar *); #endif void misc_init_r (bd_t *bd) { uchar val, errcd; + uchar *str; int i; i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); @@ -344,78 +351,122 @@ void misc_init_r (bd_t *bd) setenv ("keybd", keybd_env); #ifdef CONFIG_PREBOOT /* automatically configure "preboot" command on key match */ - if (key_match(kbd_data)) { - char *s = getenv ("key_cmd"); - setenv ("preboot", s); - } else { - setenv ("preboot", NULL); /* delete any existing definition */ + str = strdup (key_match(kbd_data)); + setenv ("preboot", str); /* set or delete definition */ + if (str != NULL) { + free (str); } #endif /* CONFIG_PREBOOT */ } /*----------------------------------------------------------------------- - * Check if pressed key(s) match magic sequence + * Check if pressed key(s) match magic sequence, + * and return the command string associated with that key(s). + * + * Note: the string points to static environment data and must be + * saved before you call any function that modifies the environment. */ #ifdef CONFIG_PREBOOT -static int key_match (uchar *kbd_data) + +static uchar kbd_magic_prefix[] = "key_magic"; +static uchar kbd_command_prefix[] = "key_cmd"; + +static uchar *key_match (uchar *kbd_data) { uchar compare[KEYBD_DATALEN]; + uchar magic[sizeof(kbd_magic_prefix) + 1]; uchar extra; - uchar *str, *nxt; + uchar *str, *nxt, *suffix; + uchar *kbd_magic_keys; int i; - memcpy (compare, kbd_data, KEYBD_DATALEN); + /* + * The following string defines the characters that can pe appended + * to "key_magic" to form the names of environment variables that + * hold "magic" key codes, i. e. such key codes that can cause + * pre-boot actions. If the string is empty (""), then only + * "key_magic" is checked (old behaviour); the string "125" causes + * checks for "key_magic1", "key_magic2" and "key_magic5", etc. + */ + if ((kbd_magic_keys = getenv("magic_keys")) == NULL) + kbd_magic_keys = ""; - extra = 0; + /* loop over all magic keys; + * use '\0' suffix in case of empty string + */ + for (suffix=kbd_magic_keys; *suffix || suffix==kbd_magic_keys; ++suffix) { + sprintf (magic, "%s%c", kbd_magic_prefix, *suffix); +#if 0 + printf ("### Check magic \"%s\"\n", magic); +#endif + memcpy (compare, kbd_data, KEYBD_DATALEN); - for (str=getenv ("key_magic"); str != NULL; str = (*nxt) ? nxt+1 : nxt) { - uchar c; - int k; + extra = 0; - c = (uchar)simple_strtoul(str, (char **)(&nxt), 16); + for (str=getenv (magic); str != NULL; str = (*nxt) ? nxt+1 : nxt) { + uchar c; + int k; - if (str == nxt) { /* invalid character */ - break; + c = (uchar)simple_strtoul(str, (char **)(&nxt), 16); + + if (str == nxt) { /* invalid character */ + break; + } + + /* + * Check if this key matches the input. + * Set matches to zero, so they match only once + * and we can find duplicates or extra keys + */ + for (k=0; k>"); +#endif + return (cmd); + } + } +#if 0 + printf ("### Delete PREBOOT\n"); #endif + return (NULL); +} +#endif /* CONFIG_PREBOOT */ /*----------------------------------------------------------------------- * Board Special Commands: PIC read/write */ #if (CONFIG_COMMANDS & CFG_CMD_BSP) - -void do_pic (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_pic (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { uchar reg, val; @@ -428,7 +479,7 @@ void do_pic (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("PIC read: reg %02x: %02x\n\n", reg, pic_read (reg)); - return; + return 0; case 4: /* PIC write reg val */ if (strcmp(argv[1],"write") != 0) break; @@ -440,14 +491,36 @@ void do_pic (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) reg, val, pic_read (reg)); pic_write (reg, val); printf ("%02x\n\n", pic_read (reg)); - - return; + return 0; default: break; } printf ("Usage:\n%s\n", cmdtp->usage); + return 1; } +/* Read Keyboard status */ +int do_kbd (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + uchar val; + int i; + + i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); + + /* Read keys */ + val = KEYBD_CMD_READ_KEYS; + i2c_write (&kbd_addr, 1, &val, 1); + i2c_read (&kbd_addr, 1, kbd_data, KEYBD_DATALEN); + + puts ("Keys:"); + for (i=0; istart[0]); int flag, prot, sect, l_sect; @@ -219,7 +220,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } prot = 0; @@ -275,7 +276,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) while ((addr[0] & 0x80808080) != 0x80808080) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -290,6 +291,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) addr[0] = 0xF0F0F0F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/mousse/flash.c b/board/mousse/flash.c index 594ce75..4af5ee1 100644 --- a/board/mousse/flash.c +++ b/board/mousse/flash.c @@ -763,7 +763,7 @@ flash_print_info (flash_info_t *info) /* * Erase a range of flash sectors. */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int prot, sect, l_sect; @@ -775,7 +775,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } prot = 0; @@ -807,12 +807,13 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) if(ERROR == flashEraseSector(dev, sect)){ printf("ERROR: could not erase sector %d on FLASH[%s]\n", sect, dev->name); - return; + return 1; } } } } printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/mousse/flash.h b/board/mousse/flash.h index bfd203d..a9b0be2 100644 --- a/board/mousse/flash.h +++ b/board/mousse/flash.h @@ -64,8 +64,8 @@ int flashDiagAll(void); ulong flash_get_size (vu_long *addr, flash_info_t *info); void flash_print_info (flash_info_t *info); -void flash_erase (flash_info_t *info, int s_first, int s_last); -int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt); +int flash_erase (flash_info_t *info, int s_first, int s_last); +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt); /* * Flash info indices. diff --git a/board/mpc8260ads/flash.c b/board/mpc8260ads/flash.c index ab866cc..fd3ce6e 100644 --- a/board/mpc8260ads/flash.c +++ b/board/mpc8260ads/flash.c @@ -257,7 +257,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr; int flag, prot, sect; @@ -269,14 +269,14 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ( ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) && ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_SHARP) ) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -323,7 +323,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); *addr = 0xFFFFFFFF; /* reset bank */ - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -338,6 +338,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) *addr = 0xFFFFFFFF; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/nx823/flash.c b/board/nx823/flash.c index 7ea6718..25c78e5 100644 --- a/board/nx823/flash.c +++ b/board/nx823/flash.c @@ -157,6 +157,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -234,10 +235,11 @@ static ulong flash_get_size (FPW *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { int flag, prot, sect; ulong type, start, now, last; + int rcode = 0; if ((s_first < 0) || (s_first > s_last)) { if (info->flash_id == FLASH_UNKNOWN) { @@ -245,14 +247,14 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } type = (info->flash_id & FLASH_VENDMASK); if ((type != FLASH_MAN_INTEL)) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -296,6 +298,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) printf ("Timeout\n"); *addr = (FPW)0x00B000B0; /* suspend erase */ *addr = (FPW)0x00FF00FF; /* reset to read mode */ + rcode = 1; break; } @@ -310,6 +313,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) printf (" done\n"); } } + return rcode; } /*----------------------------------------------------------------------- diff --git a/board/pip405/cmd_pip405.c b/board/pip405/cmd_pip405.c index 3ff5eb9..1cf651c 100644 --- a/board/pip405/cmd_pip405.c +++ b/board/pip405/cmd_pip405.c @@ -127,7 +127,7 @@ int pip405_prg_image(unsigned long load_addr) /* ------------------------------------------------------------------------- */ -void do_pip405(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_pip405(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong size,src,device,function,load_addr; @@ -141,7 +141,7 @@ void do_pip405(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (strcmp(argv[2], "floppy") == 0) { char *local_args[3]; - extern void do_fdcboot (cmd_tbl_t *, bd_t *, int, int, char *[]); + extern int do_fdcboot (cmd_tbl_t *, bd_t *, int, int, char *[]); printf ("\nupdating bootloader image from floppy\n"); local_args[0] = argv[0]; if(argc==4) { @@ -156,7 +156,7 @@ void do_pip405(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) do_fdcboot(cmdtp, bd, 0, 1, local_args); } pip405_prg_image(load_addr); - return; + return 0; } if (strcmp(argv[2], "mem") == 0) { if(argc==4) { @@ -167,12 +167,12 @@ void do_pip405(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } printf ("\nupdating bootloader image from memory at %lX\n",load_addr); pip405_prg_image(load_addr); - return; + return 0; } if (strcmp(argv[2], "mps") == 0) { printf ("\nupdating bootloader image from MSP\n"); pip405_prg(src,size); - return; + return 0; } } if (strcmp(argv[1], "prg") == 0) @@ -183,13 +183,13 @@ void do_pip405(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf("image size is 0x%lx\n",size); } pip405_prg(src,size); - return; + return 0; } if (strcmp(argv[1], "info") == 0) { printf("argc %d\n",argc); print_pip405_info(); - return; + return 0; } if (strcmp(argv[1], "i2c") == 0) { @@ -198,7 +198,7 @@ void do_pip405(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) i2c[1]=0; i2c[2]=0; i2c_read(&i2c[0],3,(unsigned char *)CFG_LOAD_ADDR,512); - return; + return 0; } if (strcmp(argv[1], "led") == 0) { @@ -209,10 +209,10 @@ void do_pip405(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) user_led0((function==1)); else user_led1((function==1)); - return; + return 0; } printf("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } /* ------------------------------------------------------------------------- */ diff --git a/board/pip405/flash.c b/board/pip405/flash.c index bb16f4d..dc00e79 100644 --- a/board/pip405/flash.c +++ b/board/pip405/flash.c @@ -315,6 +315,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -560,7 +561,7 @@ int intel_wait_for_DQ7(flash_info_t *info, int sect) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]); volatile FLASH_WORD_SIZE *addr2; @@ -573,12 +574,12 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if (info->flash_id == FLASH_UNKNOWN) { printf ("Can't erase unknown flash type - aborted\n"); - return; + return 1; } prot = 0; @@ -669,6 +670,7 @@ DONE: addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ printf (" done\n"); + return 0; } void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt) diff --git a/board/pip405/pci_pip405.c b/board/pip405/pci_pip405.c index 243bdd8..db89efe 100644 --- a/board/pip405/pci_pip405.c +++ b/board/pip405/pci_pip405.c @@ -840,7 +840,7 @@ int PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID) #if (CONFIG_COMMANDS & CFG_CMD_PCI) -void +int do_pciinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { int bus_no = 0; @@ -851,6 +851,7 @@ do_pciinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } pciinfo(bus_no); + return 0; } diff --git a/board/pm826/flash.c b/board/pm826/flash.c index 1f3a501..38bc38f 100644 --- a/board/pm826/flash.c +++ b/board/pm826/flash.c @@ -203,7 +203,7 @@ void flash_print_info (flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { int flag, prot, sect; ulong start, now, last; @@ -217,7 +217,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } prot = 0; @@ -305,7 +305,7 @@ DONE: addr[0] = 0x00FF00FF; addr[1] = 0x00FF00FF; - return; + return 0; } static int write_word (flash_info_t *, volatile unsigned long *, ulong); diff --git a/board/rpxsuper/flash.c b/board/rpxsuper/flash.c index fed7777..7bf0abf 100644 --- a/board/rpxsuper/flash.c +++ b/board/rpxsuper/flash.c @@ -131,6 +131,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /* @@ -217,7 +218,7 @@ out: /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int flag, prot, sect, l_sect; @@ -229,7 +230,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } prot = 0; @@ -293,7 +294,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) (addr[1] & 0x80808080) != 0x80808080) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -309,6 +310,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) addr[1] = 0xF0F0F0F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/rsdproto/flash.c b/board/rsdproto/flash.c index 998215e..201e257 100644 --- a/board/rsdproto/flash.c +++ b/board/rsdproto/flash.c @@ -190,12 +190,13 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { int flag, prot, sect, l_sect; ulong start; @@ -208,7 +209,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } prot = 0; @@ -266,11 +267,12 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) f_command = 0x00F000F000F000F0ULL; ull_write(f_addr, &f_command); printf (" timeout\n"); - return; + return 1; } } while(*f_addr != 0xFFFFFFFFFFFFFFFFULL); printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/sandpoint/early_init.S b/board/sandpoint/early_init.S index 41bbecf..1e31a54 100644 --- a/board/sandpoint/early_init.S +++ b/board/sandpoint/early_init.S @@ -21,7 +21,9 @@ * MA 02111-1307 USA */ -#define __ASSEMBLY__ +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ 1 +#endif #include #include diff --git a/board/sandpoint/flash.c b/board/sandpoint/flash.c index e113289..83acd42 100644 --- a/board/sandpoint/flash.c +++ b/board/sandpoint/flash.c @@ -280,6 +280,7 @@ flash_print_info(flash_info_t *info) } puts("\n"); + return; } #if 0 @@ -438,7 +439,7 @@ flash_get_size (vu_long *addr, flash_info_t *info) #endif -void +int flash_erase(flash_info_t *info, int s_first, int s_last) { volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]); @@ -451,13 +452,13 @@ flash_erase(flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type - aborted\n"); - return; + return 1; } prot = 0; @@ -524,7 +525,7 @@ flash_erase(flash_info_t *info, int s_first, int s_last) while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -539,6 +540,7 @@ DONE: addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/sbc8260/flash.c b/board/sbc8260/flash.c index 3055b0c..cd1e41f 100644 --- a/board/sbc8260/flash.c +++ b/board/sbc8260/flash.c @@ -125,6 +125,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /* @@ -190,7 +191,7 @@ out: /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int flag, prot, sect, l_sect; @@ -202,7 +203,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } prot = 0; @@ -259,7 +260,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) while ((addr[0] & 0x80808080) != 0x80808080) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -274,6 +275,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) addr[0] = 0xF0F0F0F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/siemens/CCM/ccm.c b/board/siemens/CCM/ccm.c index 86f4cf3..14a56c6 100644 --- a/board/siemens/CCM/ccm.c +++ b/board/siemens/CCM/ccm.c @@ -461,7 +461,7 @@ void reset_phy(void) #if (CONFIG_COMMANDS & CFG_CMD_BSP) -void do_puma (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_puma (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong addr, len; @@ -469,7 +469,7 @@ void do_puma (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) case 2: /* PUMA reset */ if (strncmp(argv[1], "stat", 4) == 0) { /* Reset */ puma_status (); - return; + return 0; } break; case 4: /* PUMA load addr len */ @@ -483,11 +483,12 @@ void do_puma (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) addr, len, len); puma_load (addr, len); - return; + return 0; default: break; } printf ("Usage:\n%s\n", cmdtp->usage); + return 1; } #endif /* CFG_CMD_BSP */ diff --git a/board/siemens/CCM/flash.c b/board/siemens/CCM/flash.c index 5127244..f89a923 100644 --- a/board/siemens/CCM/flash.c +++ b/board/siemens/CCM/flash.c @@ -202,6 +202,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -345,7 +346,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int flag, prot, sect, l_sect; @@ -357,14 +358,14 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -420,7 +421,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) while ((addr[0] & 0x00800080) != 0x00800080) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -435,6 +436,7 @@ DONE: addr[0] = 0x00F000F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/siemens/pcu_e/flash.c b/board/siemens/pcu_e/flash.c index e63db12..1c1b7c3 100644 --- a/board/siemens/pcu_e/flash.c +++ b/board/siemens/pcu_e/flash.c @@ -335,6 +335,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -461,7 +462,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_short *addr = (vu_short*)(info->start[0]); int flag, prot, sect, l_sect; @@ -473,14 +474,14 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -536,7 +537,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) while ((addr[0] & 0x0080) != 0x0080) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -551,6 +552,7 @@ DONE: addr[0] = 0x00F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/siemens/pcu_e/pcu_e.c b/board/siemens/pcu_e/pcu_e.c index b42be03..c885b4f 100644 --- a/board/siemens/pcu_e/pcu_e.c +++ b/board/siemens/pcu_e/pcu_e.c @@ -404,7 +404,7 @@ void reset_phy(void) #define PUMA_READ_MODE 0 #define PUMA_LOAD_MODE 1 -void do_puma (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_puma (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong addr, len; @@ -412,7 +412,7 @@ void do_puma (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) case 2: /* PUMA reset */ if (strncmp(argv[1], "stat", 4) == 0) { /* Reset */ puma_status (); - return; + return 0; } break; case 4: /* PUMA load addr len */ @@ -426,11 +426,12 @@ void do_puma (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) addr, len, len); puma_load (addr, len); - return; + return 0; default: break; } printf ("Usage:\n%s\n", cmdtp->usage); + return 1; } #endif /* CFG_CMD_BSP */ diff --git a/board/sixnet/flash.c b/board/sixnet/flash.c index 63adf07..1449599 100644 --- a/board/sixnet/flash.c +++ b/board/sixnet/flash.c @@ -178,6 +178,7 @@ void flash_print_info (flash_info_t *info) } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -254,7 +255,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int flag, prot, sect, l_sect; @@ -266,13 +267,13 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type - aborted\n"); - return; + return 1; } prot = 0; @@ -328,7 +329,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) while ((addr[0] & 0xFFFFFFFF) != 0xFFFFFFFF) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -343,6 +344,7 @@ DONE: addr[0] = 0xF0F0F0F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/spd8xx/flash.c b/board/spd8xx/flash.c index dedb871..107e11f 100644 --- a/board/spd8xx/flash.c +++ b/board/spd8xx/flash.c @@ -48,9 +48,9 @@ void flash_print_info (flash_info_t *info) return; } -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { - return; + return 1; } /*----------------------------------------------------------------------- diff --git a/board/tqm8260/flash.c b/board/tqm8260/flash.c index abc8849..e89df9e 100644 --- a/board/tqm8260/flash.c +++ b/board/tqm8260/flash.c @@ -277,11 +277,12 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { int flag, prot, sect, l_sect; ulong start, now, last; @@ -294,7 +295,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } prot = 0; @@ -362,7 +363,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) @@ -377,6 +378,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) flash_reset (); printf (" done\n"); + return 0; } static int write_dword (flash_info_t *, ulong, unsigned char *); diff --git a/board/tqm8xx/flash.c b/board/tqm8xx/flash.c index 49e72cd..01979d4 100644 --- a/board/tqm8xx/flash.c +++ b/board/tqm8xx/flash.c @@ -221,6 +221,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -362,7 +363,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int flag, prot, sect, l_sect; @@ -374,14 +375,14 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -437,7 +438,7 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) while ((addr[0] & 0x00800080) != 0x00800080) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -452,6 +453,7 @@ DONE: addr[0] = 0x00F000F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/walnut405/flash.c b/board/walnut405/flash.c index 023c258..1260c1e 100644 --- a/board/walnut405/flash.c +++ b/board/walnut405/flash.c @@ -288,6 +288,7 @@ void flash_print_info (flash_info_t *info) ); } printf ("\n"); + return; } /*----------------------------------------------------------------------- @@ -504,7 +505,7 @@ int wait_for_DQ7(flash_info_t *info, int sect) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]); volatile FLASH_WORD_SIZE *addr2; @@ -517,12 +518,12 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if (info->flash_id == FLASH_UNKNOWN) { printf ("Can't erase unknown flash type - aborted\n"); - return; + return 1; } prot = 0; @@ -601,6 +602,7 @@ DONE: addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/board/westel/amx860/flash.c b/board/westel/amx860/flash.c index ea2c21f..f6b486e 100644 --- a/board/westel/amx860/flash.c +++ b/board/westel/amx860/flash.c @@ -429,7 +429,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info) /*----------------------------------------------------------------------- */ -void flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last) { vu_long *addr = (vu_long*)(info->start[0]); int flag, prot, sect, l_sect; @@ -441,14 +441,14 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) } else { printf ("- no sectors to erase\n"); } - return; + return 1; } if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); - return; + return 1; } prot = 0; @@ -501,11 +501,10 @@ void flash_erase (flash_info_t *info, int s_first, int s_last) start = get_timer (0); last = start; addr = (vu_long*)(info->start[l_sect]); -// while ((addr[0] & 0xFFFFFFFF) != 0xFFFFFFFF) { while ((addr[0] & 0x00800080) != 0x00800080) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); - return; + return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ @@ -520,6 +519,7 @@ DONE: addr[0] = 0x00F000F0; /* reset bank */ printf (" done\n"); + return 0; } /*----------------------------------------------------------------------- diff --git a/common/Makefile b/common/Makefile index d9df3bd..7526f4a 100644 --- a/common/Makefile +++ b/common/Makefile @@ -34,7 +34,8 @@ COBJS = board.o main.o command.o \ cmd_fdc.o cmd_scsi.o cmd_autoscript.o \ cmd_bedbug.o bedbug.o s_record.o dlmalloc.o \ kgdb.o console.o lists.o devices.o flash.o cmd_i2c.o \ - cmd_immap.o miiphyutil.o miiphybb.o cmd_mii.o + cmd_immap.o miiphyutil.o miiphybb.o cmd_mii.o \ + hush.o OBJS = $(AOBJS) $(COBJS) diff --git a/common/board.c b/common/board.c index 400b7a1..21c99e9 100644 --- a/common/board.c +++ b/common/board.c @@ -518,7 +518,7 @@ void board_init_r (bd_t *bd, ulong dest_addr) printf ("Command \"%s\": 0x%08lx => 0x%08lx\n", cmdtp->name, (ulong)(cmdtp->cmd), addr); #endif - cmdtp->cmd = (void (*)(struct cmd_tbl_s*,bd_t*,int,int,char*[]))addr; + cmdtp->cmd = (int (*)(struct cmd_tbl_s*,bd_t*,int,int,char*[]))addr; addr = (ulong)(cmdtp->name) + reloc_off; cmdtp->name = (char *)addr; diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c index db3c4aa..da8b52b 100644 --- a/common/cmd_autoscript.c +++ b/common/cmd_autoscript.c @@ -46,21 +46,21 @@ (CONFIG_COMMANDS & CFG_CMD_AUTOSCRIPT) extern image_header_t header; /* from cmd_bootm.c */ - -void +int autoscript(bd_t *bd, ulong addr) { ulong crc, data, len; image_header_t *hdr = &header; ulong *len_ptr; char *cmd; + int rcode = 0; memcpy (hdr, (char *)addr, sizeof(image_header_t)); if (hdr->ih_magic != IH_MAGIC) { printf("Bad magic number\n"); - return; + return 1; } crc = hdr->ih_hcrc; @@ -70,7 +70,7 @@ autoscript(bd_t *bd, ulong addr) if (crc32(0, (char *)data, len) != crc) { printf("Bad header crc\n"); - return; + return 1; } data = addr + sizeof(image_header_t); @@ -78,13 +78,13 @@ autoscript(bd_t *bd, ulong addr) if (crc32(0, (char *)data, len) != hdr->ih_dcrc) { printf("Bad data crc\n"); - return; + return 1; } if (hdr->ih_type != IH_TYPE_SCRIPT) { printf("Bad image type\n"); - return; + return 1; } /* get len of script and make sure cmd is null terminated */ @@ -97,7 +97,7 @@ autoscript(bd_t *bd, ulong addr) cmd = malloc (len + 1); if (!cmd) { - return; + return 1; } while (*len_ptr++); memcpy(cmd,(char *)len_ptr,len); @@ -111,18 +111,19 @@ autoscript(bd_t *bd, ulong addr) } } } - run_command(cmd, bd, 0); + rcode = run_command(cmd, bd, 0); free(cmd); + return rcode; } #endif #if (CONFIG_COMMANDS & CFG_CMD_AUTOSCRIPT) - -void +int do_autoscript (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong addr; + int rcode; if (argc < 2) { @@ -134,9 +135,8 @@ do_autoscript (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } printf("## Executing script at %08lx\n",addr); - - autoscript(bd,addr); - + rcode = autoscript(bd,addr); + return rcode; } #endif diff --git a/common/cmd_bedbug.c b/common/cmd_bedbug.c index 90136ce..9a57024 100644 --- a/common/cmd_bedbug.c +++ b/common/cmd_bedbug.c @@ -77,8 +77,7 @@ void bedbug_init( void ) * Entry point from the interpreter to the disassembler. Repeated calls * will resume from the last disassembled address. * ====================================================================== */ - -void do_bedbug_dis (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, +int do_bedbug_dis (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong addr; /* Address to start disassembly from */ @@ -92,7 +91,7 @@ void do_bedbug_dis (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } if(( flag & CMD_FLAG_REPEAT ) == 0 ) @@ -110,6 +109,7 @@ void do_bedbug_dis (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, dis_last_addr = addr + (len * 4); dis_last_len = len; + return 0; } /* do_bedbug_dis */ @@ -119,8 +119,7 @@ void do_bedbug_dis (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, * instructions in consecutive memory locations until a '.' (period) is * entered on a line by itself. * ====================================================================== */ - -void do_bedbug_asm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, +int do_bedbug_asm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { long mem_addr; /* Address to assemble into */ @@ -128,11 +127,12 @@ void do_bedbug_asm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char prompt[ 15 ]; /* Prompt string for user input */ int asm_err; /* Error code from the assembler*/ /* -------------------------------------------------- */ + int rcode = 0; if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } printf( "\nEnter '.' when done\n" ); @@ -156,6 +156,7 @@ void do_bedbug_asm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, else { printf( "*** Error: %s ***\n", asm_error_str( asm_err )); + rcode = 1; } } else @@ -163,6 +164,7 @@ void do_bedbug_asm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, break; } } + return rcode; } /* do_bedbug_asm */ @@ -172,13 +174,14 @@ void do_bedbug_asm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, * CPU-specific break point set routine. * ====================================================================== */ -void do_bedbug_break (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, +int do_bedbug_break (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { /* -------------------------------------------------- */ - if( bug_ctx.do_break ) (*bug_ctx.do_break)( cmdtp, bd, flag, argc, argv ); + return 0; + } /* do_bedbug_break */ @@ -194,6 +197,8 @@ void do_bedbug_breakpoint( struct pt_regs *regs ) if( bug_ctx.break_isr ) (*bug_ctx.break_isr)( regs ); + + return; } /* do_bedbug_breakpoint */ @@ -262,20 +267,20 @@ void bedbug_main_loop( unsigned long addr, struct pt_regs *regs ) * stopped flag in the context so that the breakpoint routine will * return. * ====================================================================== */ - -void do_bedbug_continue (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, +int do_bedbug_continue (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) + { /* -------------------------------------------------- */ if( ! bug_ctx.stopped ) { printf( "Not at a breakpoint\n" ); - return; + return 1; } bug_ctx.stopped = 0; - return; + return 0; } /* do_bedbug_continue */ @@ -286,8 +291,7 @@ void do_bedbug_continue (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, * the address passes control to the CPU-specific set breakpoint routine * for the current breakpoint number. * ====================================================================== */ - -void do_bedbug_step (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, +int do_bedbug_step (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unsigned long addr; /* Address to stop at */ @@ -296,17 +300,17 @@ void do_bedbug_step (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, if( ! bug_ctx.stopped ) { printf( "Not at a breakpoint\n" ); - return; + return 1; } if( !find_next_address( (unsigned char *)&addr, FALSE, bug_ctx.regs )) - return; + return 1; if( bug_ctx.set ) (*bug_ctx.set)( bug_ctx.current_bp, addr ); bug_ctx.stopped = 0; - return; + return 0; } /* do_bedbug_step */ @@ -317,8 +321,7 @@ void do_bedbug_step (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, * the address passes control to the CPU-specific set breakpoint routine * for the current breakpoint number. * ====================================================================== */ - -void do_bedbug_next (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, +int do_bedbug_next (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unsigned long addr; /* Address to stop at */ @@ -327,17 +330,17 @@ void do_bedbug_next (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, if( ! bug_ctx.stopped ) { printf( "Not at a breakpoint\n" ); - return; + return 1; } if( !find_next_address( (unsigned char *)&addr, TRUE, bug_ctx.regs )) - return; + return 1; if( bug_ctx.set ) (*bug_ctx.set)( bug_ctx.current_bp, addr ); bug_ctx.stopped = 0; - return; + return 0; } /* do_bedbug_next */ @@ -346,8 +349,7 @@ void do_bedbug_next (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, * Interpreter command to print the current stack. This assumes an EABI * architecture, so it starts with GPR R1 and works back up the stack. * ====================================================================== */ - -void do_bedbug_stack (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, +int do_bedbug_stack (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unsigned long sp; /* Stack pointer */ @@ -360,7 +362,7 @@ void do_bedbug_stack (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, if( ! bug_ctx.stopped ) { printf( "Not at a breakpoint\n" ); - return; + return 1; } top = bd->bi_memstart + bd->bi_memsize; @@ -383,8 +385,7 @@ void do_bedbug_stack (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, sp = *(unsigned long *)sp; func = *(unsigned long *)(sp+4); } - - return; + return 0; } /* do_bedbug_stack */ @@ -393,8 +394,7 @@ void do_bedbug_stack (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, * Interpreter command to dump the registers. Calls the CPU-specific * show registers routine. * ====================================================================== */ - -void do_bedbug_rdump (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, +int do_bedbug_rdump (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { /* -------------------------------------------------- */ @@ -402,11 +402,11 @@ void do_bedbug_rdump (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, if( ! bug_ctx.stopped ) { printf( "Not at a breakpoint\n" ); - return; + return 1; } show_regs( bug_ctx.regs ); - return; + return 0; } /* do_bedbug_rdump */ @@ -414,12 +414,12 @@ void do_bedbug_rdump (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, /* ====================================================================== * Interpreter command to boot an arbitrary ELF image from memory. * ====================================================================== */ - -void do_bootelf( cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[] ) +int do_bootelf( cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[] ) { unsigned long addr; /* Address of the ELF image */ unsigned long rc; /* Return value from user code */ /* -------------------------------------------------- */ + int rcode = 0; if (argc < 2) addr = load_addr; @@ -427,7 +427,7 @@ void do_bootelf( cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[] ) addr = simple_strtoul( argv[ 1 ], NULL, 16 ); if( ! valid_elf_image( addr )) - return; + return 1; addr = load_elf_image( addr ); @@ -438,8 +438,10 @@ void do_bootelf( cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[] ) * and all remaining args */ rc = ((ulong (*)(bd_t *, int, char *[]))addr) (bd, --argc, &argv[1]); + if (rc != 0) rcode = 1; printf ("## Application terminated, rc = 0x%lx\n", rc); + return rcode; } /* do_bootelf */ @@ -449,8 +451,7 @@ void do_bootelf( cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[] ) * be either an ELF image or a raw binary. Will attempt to setup the * bootline and other parameters correctly. * ====================================================================== */ - -void do_bootvx( cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[] ) +int do_bootvx( cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[] ) { unsigned long addr; /* Address of image */ unsigned long bootaddr; /* Address to put the bootline */ @@ -471,7 +472,7 @@ void do_bootvx( cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[] ) else { printf( "No load address provided\n" ); - return; + return 1; } /* Check to see if we need to tftp the image ourselves before starting */ @@ -479,8 +480,7 @@ void do_bootvx( cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[] ) if(( argc == 2 ) && ( strcmp( argv[ 1 ], "tftp" ) == 0 )) { if( NetLoop( bd, TFTP ) == 0 ) - return; - + return 1; printf( "Automatic boot of VxWorks image at address 0x%08lx ... \n", addr ); } @@ -560,7 +560,7 @@ void do_bootvx( cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[] ) PPC flavors, the hostname and ipaddr should be ok to just copy */ printf( "No bootargs defined\n" ); - return; + return 1; #endif } @@ -582,6 +582,7 @@ void do_bootvx( cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[] ) ((void (*)(void))addr)(); printf ("## vxWorks terminated\n" ); + return 1; } /* do_bootvx */ diff --git a/common/cmd_boot.c b/common/cmd_boot.c index 6da6af2..eeb2810 100644 --- a/common/cmd_boot.c +++ b/common/cmd_boot.c @@ -43,8 +43,7 @@ static int do_echo = 1; #if (CONFIG_COMMANDS & CFG_CMD_BDI) static void print_num(const char *, ulong); static void print_str(const char *, const char *); - -void do_bdinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_bdinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { int i; char buf[32]; @@ -88,6 +87,7 @@ void do_bdinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) print_num ("free_hdlr", (ulong)bd->bi_mon_fnc->free_hdlr); print_num ("malloc", (ulong)bd->bi_mon_fnc->malloc); print_num ("free", (ulong)bd->bi_mon_fnc->free); + return 0; } static void print_num(const char *name, ulong value) @@ -101,13 +101,14 @@ static void print_str(const char *name, const char *str) } #endif /* CFG_CMD_BDI */ -void do_go (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_go (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong addr, rc; + int rcode = 0; if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } addr = simple_strtoul(argv[1], NULL, 16); @@ -119,12 +120,14 @@ void do_go (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) * and all remaining args */ rc = ((ulong (*)(bd_t *, int, char *[]))addr) (bd, --argc, &argv[1]); + if (rc != 0) rcode = 1; printf ("## Application terminated, rc = 0x%lx\n", rc); + return rcode; } #if (CONFIG_COMMANDS & CFG_CMD_LOADS) -void do_load_serial (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_load_serial (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong offset = 0; ulong addr; @@ -133,6 +136,7 @@ void do_load_serial (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[ #ifdef CFG_LOADS_BAUD_CHANGE int loads_baudrate = bd->bi_baudrate; #endif + int rcode = 0; if (((env_echo = getenv("loads_echo")) != NULL) && (*env_echo == '1')) { do_echo = 1; @@ -188,6 +192,7 @@ void do_load_serial (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[ if (addr == ~0) { printf ("## S-Record download aborted\n"); + rcode = 1; } else { printf ("## Start Addr = 0x%08lx\n", addr); load_addr = addr; @@ -206,6 +211,7 @@ void do_load_serial (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[ } } #endif + return rcode; } static ulong @@ -358,13 +364,13 @@ int his_pad_count; /* number of pad chars he needs */ char his_pad_char; /* pad chars he needs */ char his_quote; /* quote chars he'll use */ - -void do_load_serial_bin (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_load_serial_bin (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong offset = 0; ulong addr; int i; int loadb_baudrate = bd->bi_baudrate; + int rcode = 0; if (argc >= 2) { offset = simple_strtoul(argv[1], NULL, 16); @@ -407,6 +413,7 @@ void do_load_serial_bin (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *a if (addr == ~0) { load_addr = 0; printf ("## Binary (kermit) download aborted\n"); + rcode = 1; } else { printf ("## Start Addr = 0x%08lx\n", addr); load_addr = addr; @@ -430,10 +437,11 @@ void do_load_serial_bin (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *a if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) { printf("Running autoscript at addr 0x%08lX ...\n", load_addr); - autoscript (bd, load_addr); + rcode = autoscript (bd, load_addr); } } #endif + return rcode; } diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 711b341..ebd098b 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -40,7 +40,7 @@ static void *zalloc(void *, unsigned, unsigned); static void zfree(void *, void *, unsigned); #if (CONFIG_COMMANDS & CFG_CMD_IMI) -static void image_info (unsigned long addr); +static int image_info (unsigned long addr); #endif static void print_type (image_header_t *hdr); @@ -63,8 +63,7 @@ static boot_os_Fcn do_bootm_netbsd; image_header_t header; ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ - -void do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong iflag; ulong addr; @@ -94,7 +93,7 @@ void do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (hdr->ih_magic != IH_MAGIC) { printf ("Bad Magic Number\n"); - return; + return 1; } #ifdef CONFIG_HERMES hermes_set_led (2); @@ -108,7 +107,7 @@ void do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (crc32 (0, (char *)data, len) != checksum) { printf ("Bad Header Checksum\n"); - return; + return 1; } #ifdef CONFIG_HERMES hermes_set_led (3); @@ -124,7 +123,7 @@ void do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf (" Verifying Checksum ... "); if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) { printf ("Bad Data CRC\n"); - return; + return 1; } printf ("OK\n"); } @@ -136,7 +135,7 @@ void do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (hdr->ih_arch != IH_CPU_PPC) { printf ("Unsupported Architecture\n"); - return; + return 1; } #ifdef CONFIG_HERMES hermes_set_led (5); @@ -155,7 +154,7 @@ void do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) data += 4; break; default: printf ("Wrong Image Type for %s command\n", cmdtp->name); - return; + return 1; } #ifdef CONFIG_HERMES hermes_set_led (6); @@ -186,7 +185,7 @@ void do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (iflag) enable_interrupts(); printf ("Unimplemented compression type %d\n", hdr->ih_comp); - return; + return 1; } printf ("OK\n"); #ifdef CONFIG_HERMES @@ -210,7 +209,7 @@ void do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (iflag) enable_interrupts(); printf ("Can't boot image type %d\n", hdr->ih_type); - return; + return 1; } #ifdef CONFIG_HERMES hermes_set_led (8); @@ -233,6 +232,7 @@ void do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("\n## Control returned to monitor - resetting...\n"); do_reset (cmdtp, bd, flag, argc, argv); #endif + return 1; } static void @@ -580,31 +580,34 @@ do_bootm_netbsd (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[], } #if (CONFIG_COMMANDS & CFG_CMD_BOOTD) -void do_bootd (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) -{ - run_command (getenv ("bootcmd"), bd, flag); +int do_bootd (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + int rcode = 0; + + if (run_command (getenv ("bootcmd"), bd, flag) == -1) rcode = 1; + return rcode; } #endif - #if (CONFIG_COMMANDS & CFG_CMD_IMI) -void do_iminfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_iminfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { int arg; ulong addr; + int rcode=0; if (argc < 2) { - image_info (load_addr); - return; + return image_info (load_addr); } for (arg=1; arg ih_magic != IH_MAGIC) { printf (" Bad Magic Number\n"); - return; + return 1; } data = (ulong)&header; @@ -627,7 +630,7 @@ static void image_info (ulong addr) if (crc32 (0, (char *)data, len) != checksum) { printf (" Bad Header Checksum\n"); - return; + return 1; } /* for multi-file images we need the data part, too */ @@ -639,9 +642,10 @@ static void image_info (ulong addr) printf (" Verifying Checksum ... "); if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) { printf (" Bad Data CRC\n"); - return; + return 1; } printf ("OK\n"); + return 0; } #endif /* CFG_CMD_IMI */ diff --git a/common/cmd_cache.c b/common/cmd_cache.c index 1abb1bc..376d991 100644 --- a/common/cmd_cache.c +++ b/common/cmd_cache.c @@ -32,7 +32,7 @@ static int on_off (const char *); -void do_icache (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_icache (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { switch (argc) { case 2: /* on / off */ @@ -50,13 +50,15 @@ void do_icache (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) case 1: /* get status */ printf ("Instruction Cache is %s\n", icache_status() ? "ON" : "OFF"); - return; + return 0; default: printf ("Usage:\n%s\n", cmdtp->usage); + return 1; } + return 0; } -void do_dcache (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_dcache (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { switch (argc) { case 2: /* on / off */ @@ -74,10 +76,13 @@ void do_dcache (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) case 1: /* get status */ printf ("Data (writethrough) Cache is %s\n", dcache_status() ? "ON" : "OFF"); - return; + return 0; default: printf ("Usage:\n%s\n", cmdtp->usage); + return 1; } + return 0; + } static int on_off (const char *s) diff --git a/common/cmd_console.c b/common/cmd_console.c index 5f2c711..3300750 100644 --- a/common/cmd_console.c +++ b/common/cmd_console.c @@ -31,8 +31,7 @@ #if (CONFIG_COMMANDS & CFG_CMD_CONSOLE) extern void _do_coninfo (void) ; - -void do_coninfo (cmd_tbl_t *cmd, bd_t *bd, int flag, int argc, char *argv[]) +int do_coninfo (cmd_tbl_t *cmd, bd_t *bd, int flag, int argc, char *argv[]) { int i,l ; @@ -58,6 +57,7 @@ void do_coninfo (cmd_tbl_t *cmd, bd_t *bd, int flag, int argc, char *argv[]) putc('\n'); } + return 0; } #endif /* CFG_CMD_CONSOLE */ diff --git a/common/cmd_date.c b/common/cmd_date.c index 84ac1a2..01f77e9 100644 --- a/common/cmd_date.c +++ b/common/cmd_date.c @@ -36,9 +36,10 @@ const char *weekdays[] = { int mk_date (char *, struct rtc_time *); -void do_date (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_date (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { struct rtc_time tm; + int rcode = 0; switch (argc) { case 2: /* set date & time */ @@ -51,7 +52,7 @@ void do_date (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) /* insert new date & time */ if (mk_date (argv[1], &tm) != 0) { printf ("## Bad date format\n"); - return; + return 1; } /* and write to RTC */ rtc_set (&tm); @@ -66,10 +67,12 @@ void do_date (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) "unknown " : weekdays[tm.tm_wday], tm.tm_hour, tm.tm_min, tm.tm_sec); - return; + return 0; default: printf ("Usage:\n%s\n", cmdtp->usage); + rcode = 1; } + return rcode; } /* diff --git a/common/cmd_eeprom.c b/common/cmd_eeprom.c index 7ab92f9..db1081a 100644 --- a/common/cmd_eeprom.c +++ b/common/cmd_eeprom.c @@ -30,21 +30,22 @@ #if (CONFIG_COMMANDS & CFG_CMD_EEPROM) || defined(CFG_ENV_IS_IN_EEPROM) extern void eeprom_init (void); -extern void eeprom_read (unsigned offset, uchar *buffer, unsigned cnt); -extern void eeprom_write (unsigned offset, uchar *buffer, unsigned cnt); +extern int eeprom_read (unsigned offset, uchar *buffer, unsigned cnt); +extern int eeprom_write (unsigned offset, uchar *buffer, unsigned cnt); #endif /* ------------------------------------------------------------------------- */ #if (CONFIG_COMMANDS & CFG_CMD_EEPROM) - -void do_eeprom (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_eeprom (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { + int rcode = 0; + switch (argc) { default: printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; case 5: /* 4 args */ @@ -59,10 +60,10 @@ void do_eeprom (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #ifndef CONFIG_SPI eeprom_init (); #endif - eeprom_read (off, (uchar *)addr, cnt); + rcode = eeprom_read (off, (uchar *)addr, cnt); printf ("done\n"); - return; + return rcode; } else if (strcmp(argv[1],"write") == 0) { ulong addr = simple_strtoul(argv[2], NULL, 16); @@ -75,16 +76,15 @@ void do_eeprom (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #ifndef CONFIG_SPI eeprom_init (); #endif - eeprom_write(off, (uchar *)addr, cnt); + rcode = eeprom_write(off, (uchar *)addr, cnt); printf ("done\n"); - return; + return rcode; } else { printf ("Usage:\n%s\n", cmdtp->usage); } - - return; + return 1; } } #endif /* CFG_CMD_EEPROM */ @@ -100,10 +100,11 @@ void do_eeprom (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #if (CONFIG_COMMANDS & CFG_CMD_EEPROM) || defined(CFG_ENV_IS_IN_EEPROM) -void eeprom_read (unsigned offset, uchar *buffer, unsigned cnt) +int eeprom_read (unsigned offset, uchar *buffer, unsigned cnt) { unsigned end = offset + cnt; unsigned blk_off; + int rcode = 0; /* Read data until done or would cross a page boundary. * We must write the address again when changing pages @@ -140,15 +141,15 @@ void eeprom_read (unsigned offset, uchar *buffer, unsigned cnt) len = end - offset; if (len > maxlen) len = maxlen; - #ifdef CONFIG_SPI spi_read (addr, alen, buffer, len); #else - i2c_read (addr, alen, buffer, len); + if (i2c_read (addr, alen, buffer, len) != 0) rcode = 1; #endif buffer += len; offset += len; } + return rcode; } /*----------------------------------------------------------------------- @@ -160,10 +161,12 @@ void eeprom_read (unsigned offset, uchar *buffer, unsigned cnt) * 0x00000nxx for EEPROM address selectors and page number at n. */ -void eeprom_write (unsigned offset, uchar *buffer, unsigned cnt) +int eeprom_write (unsigned offset, uchar *buffer, unsigned cnt) { unsigned end = offset + cnt; unsigned blk_off; + int rcode = 0; + /* Write data until done or would cross a write page boundary. * We must write the address again when changing pages @@ -210,11 +213,10 @@ void eeprom_write (unsigned offset, uchar *buffer, unsigned cnt) len = end - offset; if (len > maxlen) len = maxlen; - #ifdef CONFIG_SPI spi_write (addr, alen, buffer, len); #else - i2c_write (addr, alen, buffer, len); + if (i2c_write (addr, alen, buffer, len) != 0) rcode = 1; #endif buffer += len; offset += len; @@ -223,6 +225,7 @@ void eeprom_write (unsigned offset, uchar *buffer, unsigned cnt) udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000); #endif } + return rcode; } /*----------------------------------------------------------------------- diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index e854885..3f56206 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -627,8 +627,7 @@ int fdc_setup(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) /**************************************************************************** * main routine do_fdcboot */ - -void do_fdcboot(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_fdcboot(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type; FDC_COMMAND_STRUCT *pCMD = &cmd; @@ -637,6 +636,7 @@ void do_fdcboot(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) unsigned char boot_drive; int i,nrofblk; char *ep; + int rcode = 0; switch (argc) { case 1: @@ -653,26 +653,26 @@ void do_fdcboot(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) break; default: printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } /* setup FDC and scan for drives */ if(fdc_setup(pCMD,pFG)==FALSE) { printf("\n** Error in setup FDC **\n"); - return; + return 1; } if(fdc_check_drive(pCMD,pFG)==FALSE) { printf("\n** Error in check_drives **\n"); - return; + return 1; } if((pCMD->flags&(1<flags&(0x10<drive=boot_drive; @@ -682,12 +682,12 @@ void do_fdcboot(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf("\nRead error:"); for(i=0;i<7;i++) printf("result%d: 0x%02X\n",i,pCMD->result[i]); - return; + return 1; } hdr = (image_header_t *)addr; if (hdr->ih_magic != IH_MAGIC) { printf ("Bad Magic Number\n"); - return; + return 1; } print_image_hdr(hdr); @@ -702,7 +702,7 @@ void do_fdcboot(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf("\nRead error:"); for(i=0;i<7;i++) printf("result%d: 0x%02X\n",i,pCMD->result[i]); - return; + return 1; } printf("OK %ld Bytes loaded.\n",imsize); /* Loading ok, update default load address */ @@ -712,7 +712,7 @@ void do_fdcboot(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) /* Check if we should attempt an auto-start */ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { char *local_args[2]; - extern void do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]); + extern int do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]); local_args[0] = argv[0]; local_args[1] = NULL; @@ -720,8 +720,10 @@ void do_fdcboot(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); do_bootm (cmdtp, bd, 0, 1, local_args); + rcode ++; } } + return rcode; } diff --git a/common/cmd_flash.c b/common/cmd_flash.c index 9a4b2df..3f8a1ed 100644 --- a/common/cmd_flash.c +++ b/common/cmd_flash.c @@ -91,8 +91,7 @@ abbrev_spec(char *str, flash_info_t **pinfo, int *psf, int *psl) return 1; } - -void do_flinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_flinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong bank; @@ -102,53 +101,54 @@ void do_flinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) flash_print_info (&flash_info[bank]); } - return; + return 0; } bank = simple_strtoul(argv[1], NULL, 16); if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) { printf ("Only FLASH Banks # 1 ... # %d supported\n", CFG_MAX_FLASH_BANKS); - return; + return 1; } printf ("\nBank # %ld: ", bank); flash_print_info (&flash_info[bank-1]); + return 0; } - -void do_flerase(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_flerase(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { flash_info_t *info; ulong bank, addr_first, addr_last; int n, sect_first, sect_last; + int rcode = 0; if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } if (strcmp(argv[1], "all") == 0) { for (bank=1; bank<=CFG_MAX_FLASH_BANKS; ++bank) { printf ("Erase Flash Bank # %ld ", bank); info = &flash_info[bank-1]; - flash_erase (info, 0, info->sector_count-1); + rcode = flash_erase (info, 0, info->sector_count-1); } - return; + return rcode; } if ((n = abbrev_spec(argv[1], &info, §_first, §_last)) != 0) { if (n < 0) { printf("Bad sector specification\n"); - return; + return 1; } printf ("Erase Flash Sectors %d-%d in Bank # %d ", sect_first, sect_last, (info-flash_info)+1); - flash_erase(info, sect_first, sect_last); - return; + rcode = flash_erase(info, sect_first, sect_last); + return rcode; } if (argc != 3) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } if (strcmp(argv[1], "bank") == 0) { @@ -156,12 +156,12 @@ void do_flerase(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) { printf ("Only FLASH Banks # 1 ... # %d supported\n", CFG_MAX_FLASH_BANKS); - return; + return 1; } printf ("Erase Flash Bank # %ld ", bank); info = &flash_info[bank-1]; - flash_erase (info, 0, info->sector_count-1); - return; + rcode = flash_erase (info, 0, info->sector_count-1); + return rcode; } addr_first = simple_strtoul(argv[1], NULL, 16); @@ -169,19 +169,21 @@ void do_flerase(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (addr_first >= addr_last) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } printf ("Erase Flash from 0x%08lx to 0x%08lx ", addr_first, addr_last); - flash_sect_erase(addr_first, addr_last); + rcode = flash_sect_erase(addr_first, addr_last); + return rcode; } -void flash_sect_erase (ulong addr_first, ulong addr_last) +int flash_sect_erase (ulong addr_first, ulong addr_last) { flash_info_t *info; ulong bank; int s_first, s_last; int erased; + int rcode = 0; erased = 0; @@ -220,7 +222,7 @@ void flash_sect_erase (ulong addr_first, ulong addr_last) } if (s_first>=0 && s_first<=s_last) { erased += s_last - s_first + 1; - flash_erase (info, s_first, s_last); + rcode = flash_erase (info, s_first, s_last); } } if (erased) { @@ -228,19 +230,22 @@ void flash_sect_erase (ulong addr_first, ulong addr_last) } else { printf ("Error: start and/or end address" " not on sector boundary\n"); + rcode = 1; } + return rcode; } -void do_protect(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_protect(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { flash_info_t *info; ulong bank, addr_first, addr_last; int i, p, n, sect_first, sect_last; + int rcode = 0; if (argc < 3) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } if (strcmp(argv[1], "off") == 0) @@ -249,7 +254,7 @@ void do_protect(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) p = 1; else { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } if (strcmp(argv[2], "all") == 0) { @@ -265,13 +270,13 @@ void do_protect(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) info->protect[i] = p; } } - return; + return 0; } if ((n = abbrev_spec(argv[2], &info, §_first, §_last)) != 0) { if (n < 0) { printf("Bad sector specification\n"); - return; + return 1; } printf("%sProtect Flash Sectors %d-%d in Bank # %d\n", p ? "" : "Un-", sect_first, sect_last, @@ -279,12 +284,12 @@ void do_protect(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) for (i = sect_first; i <= sect_last; i++) { info->protect[i] = p; } - return; + return 0; } if (argc != 4) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } if (strcmp(argv[2], "bank") == 0) { @@ -292,7 +297,7 @@ void do_protect(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) { printf ("Only FLASH Banks # 1 ... # %d supported\n", CFG_MAX_FLASH_BANKS); - return; + return 1; } printf ("%sProtect Flash Bank # %ld\n", p ? "" : "Un-", bank); @@ -300,12 +305,12 @@ void do_protect(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (info->flash_id == FLASH_UNKNOWN) { printf ("missing or unknown FLASH type\n"); - return; + return 1; } for (i=0; isector_count; ++i) { info->protect[i] = p; } - return; + return 0; } addr_first = simple_strtoul(argv[2], NULL, 16); @@ -313,18 +318,18 @@ void do_protect(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (addr_first >= addr_last) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } - - flash_sect_protect (p, addr_first, addr_last); + rcode = flash_sect_protect (p, addr_first, addr_last); + return rcode; } - -void flash_sect_protect (int p, ulong addr_first, ulong addr_last) +int flash_sect_protect (int p, ulong addr_first, ulong addr_last) { flash_info_t *info; ulong bank; int s_first, s_last; int protected, i; + int rcode = 0; protected = 0; @@ -374,7 +379,9 @@ void flash_sect_protect (int p, ulong addr_first, ulong addr_last) } else { printf ("Error: start and/or end address" " not on sector boundary\n"); + rcode = 1; } + return rcode; } #endif /* CFG_CMD_FLASH */ diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index c9b273f..3b41378 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -43,7 +43,7 @@ /* ------------------------------------------------------------------------- */ -void +int do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unsigned char i2c_addr, sec_addr, *data_addr; @@ -78,7 +78,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) i2c_init (50000, 0xfe); /* use all one's as slave address */ #endif printf ("DONE\n"); - return; + return 0; } break; @@ -97,7 +97,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) i2c_init (speed, 0xfe); /* use all one's as slave address */ #endif printf ("DONE\n"); - return; + return 0; } break; @@ -141,7 +141,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (rc) { printf ("i2c_receive FAILED rc=%d\n", rc); - return; + return 1; } #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ @@ -155,11 +155,11 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (rc) { printf ("i2c_doio FAILED rc=%d\n", rc); - return; + return 1; } printf ("DONE\n"); - return; + return 0; } else if (strncmp(argv[1], "send",4) == 0) { i2c_addr = (unsigned char)simple_strtoul(argv[2], NULL, 16); data_addr = (unsigned char *)simple_strtoul(argv[3], NULL, 16); @@ -189,7 +189,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #endif if (rc) { printf ("i2c_receive FAILED rc=%d\n", rc); - return; + return 1; } #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ @@ -203,11 +203,11 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (rc) { printf ("i2c_doio FAILED rc=%d\n", rc); - return; + return 1; } printf ("DONE\n"); - return; + return 0; } break; @@ -244,7 +244,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (rc) { printf ("i2c_receive FAILED rc=%d\n", rc); - return; + return 1; } #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ @@ -258,11 +258,11 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (rc) { printf ("i2c_doio FAILED rc=%d\n", rc); - return; + return 1; } printf ("DONE\n"); - return; + return 0; } else if (strncmp(argv[1], "snds",4) == 0) { i2c_addr = (unsigned char)simple_strtoul(argv[2], NULL, 16); @@ -295,7 +295,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (rc) { printf ("i2c_send FAILED rc=%d\n", rc); - return; + return 1; } #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ @@ -309,11 +309,11 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (rc) { printf ("i2c_doio FAILED rc=%d\n", rc); - return; + return 1; } printf ("DONE\n"); - return; + return 0; } break; @@ -322,7 +322,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } /* ------------------------------------------------------------------------- */ diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 2e1025f..c04b809 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -157,13 +157,15 @@ static void set_pcmcia_timing (int pmode); /* ------------------------------------------------------------------------- */ -void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { + int rcode = 0; + switch (argc) { case 0: case 1: printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; case 2: if (strncmp(argv[1],"res",3) == 0) { puts ("\nReset IDE" @@ -173,7 +175,7 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) ": "); ide_init(bd); - return; + return 0; } else if (strncmp(argv[1],"inf",3) == 0) { int i; @@ -185,16 +187,16 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("IDE device %d: ", i); dev_print(&ide_dev_desc[i]); } - return; + return 0; } else if (strncmp(argv[1],"dev",3) == 0) { if ((curr_device < 0) || (curr_device >= CFG_IDE_MAXDEVICE)) { puts ("\nno IDE devices available\n"); - return; + return 1; } printf ("\nIDE device %d: ", curr_device); dev_print(&ide_dev_desc[curr_device]); - return; + return 0; } else if (strncmp(argv[1],"part",4) == 0) { int dev, ok; @@ -206,12 +208,14 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) print_part(&ide_dev_desc[dev]); } } - if (!ok) + if (!ok) { puts ("\nno IDE devices available\n"); - return; + rcode ++; + } + return rcode; } printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; case 3: if (strncmp(argv[1],"dev",3) == 0) { int dev = (int)simple_strtoul(argv[2], NULL, 10); @@ -219,20 +223,20 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("\nIDE device %d: ", dev); if (dev >= CFG_IDE_MAXDEVICE) { puts ("unknown device\n"); - return; + return 1; } dev_print(&ide_dev_desc[dev]); /*ide_print (dev);*/ if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { - return; + return 1; } curr_device = dev; puts ("... is now current device\n"); - return; + return 0; } else if (strncmp(argv[1],"part",4) == 0) { int dev = (int)simple_strtoul(argv[2], NULL, 10); @@ -240,8 +244,9 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) print_part(&ide_dev_desc[dev]); } else { printf ("\nIDE device %d not available\n", dev); + rcode = 1; } - return; + return rcode; #if 0 } else if (strncmp(argv[1],"pio",4) == 0) { int mode = (int)simple_strtoul(argv[2], NULL, 10); @@ -259,7 +264,7 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; default: /* at least 4 args */ @@ -277,9 +282,11 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("%ld blocks read: %s\n", n, (n==cnt) ? "OK" : "ERROR"); - - return; - + if (n==cnt) { + return 0; + } else { + return 1; + } } else if (strcmp(argv[1],"write") == 0) { ulong addr = simple_strtoul(argv[2], NULL, 16); ulong blk = simple_strtoul(argv[3], NULL, 16); @@ -293,17 +300,21 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("%ld blocks written: %s\n", n, (n==cnt) ? "OK" : "ERROR"); - - return; + if (n==cnt) { + return 0; + } else { + return 1; + } } else { printf ("Usage:\n%s\n", cmdtp->usage); + rcode = 1; } - return; + return rcode; } } -void do_diskboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_diskboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { char *boot_device = NULL; char *ep; @@ -312,6 +323,7 @@ void do_diskboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) ulong addr; disk_partition_t info; image_header_t *hdr; + int rcode = 0; switch (argc) { case 1: @@ -328,36 +340,36 @@ void do_diskboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) break; default: printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } if (!boot_device) { puts ("\n** No boot device **\n"); - return; + return 1; } dev = simple_strtoul(boot_device, &ep, 16); if (ide_dev_desc[dev].type==DEV_TYPE_UNKNOWN) { printf ("\n** Device %d not available\n", dev); - return; + return 1; } if (*ep) { if (*ep != ':') { puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - return; + return 1; } part = simple_strtoul(++ep, NULL, 16); } if (get_partition_info (&ide_dev_desc[dev], part, &info)) { - return; + return 1; } if (strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) { printf ("\n** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info.type); - return; + return 1; } printf ("\nLoading from IDE device %d, partition %d: " @@ -369,7 +381,7 @@ void do_diskboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (ide_dev_desc[dev].block_read (dev, info.start, 1, (ulong *)addr) != 1) { printf ("** Read error on %d:%d\n", dev, part); - return; + return 1; } hdr = (image_header_t *)addr; @@ -384,13 +396,13 @@ void do_diskboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) cnt -= 1; } else { printf("\n** Bad Magic Number **\n"); - return; + return 1; } if (ide_dev_desc[dev].block_read (dev, info.start+1, cnt, (ulong *)(addr+info.blksz)) != cnt) { printf ("** Read error on %d:%d\n", dev, part); - return; + return 1; } @@ -401,7 +413,7 @@ void do_diskboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) /* Check if we should attempt an auto-start */ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { char *local_args[2]; - extern void do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]); + extern int do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]); local_args[0] = argv[0]; local_args[1] = NULL; @@ -409,7 +421,9 @@ void do_diskboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); do_bootm (cmdtp, bd, 0, 1, local_args); + rcode = 1; } + return rcode; } /* ------------------------------------------------------------------------- */ diff --git a/common/cmd_immap.c b/common/cmd_immap.c index 528ef1f..2f756fb 100644 --- a/common/cmd_immap.c +++ b/common/cmd_immap.c @@ -47,7 +47,7 @@ unimplemented(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) cmdtp->name); } -void +int do_siuinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { volatile immap_t *immap = (immap_t *)CFG_IMMR; @@ -74,9 +74,10 @@ do_siuinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf("PDTEA = %08x PDTEM = %02x\n", sc->sc_pdtea, sc->sc_pdtem); printf("LDTEA = %08x LDTEM = %02x\n", sc->sc_ldtea, sc->sc_ldtem); #endif + return 0; } -void +int do_memcinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { volatile immap_t *immap = (immap_t *)CFG_IMMR; @@ -120,26 +121,30 @@ do_memcinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) memctl->memc_lurt, memctl->memc_lsrt); printf("IMMR = %08x\n", memctl->memc_immr); #endif + return 0; } -void +int do_sitinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unimplemented(cmdtp, bd, flag, argc, argv); + return 0; } #ifdef CONFIG_8260 -void +int do_icinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unimplemented(cmdtp, bd, flag, argc, argv); + return 0; } #endif -void +int do_carinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unimplemented(cmdtp, bd, flag, argc, argv); + return 0; } static int counter; @@ -203,7 +208,7 @@ binary(char *label, uint value, int nbits) #define PD_NBITS 28 #endif -void +int do_iopinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { volatile immap_t *immap = (immap_t *)CFG_IMMR; @@ -265,18 +270,21 @@ do_iopinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #endif header(); + return 0; } -void +int do_dmainfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unimplemented(cmdtp, bd, flag, argc, argv); + return 0; } -void +int do_fccinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unimplemented(cmdtp, bd, flag, argc, argv); + return 0; } static void @@ -334,7 +342,7 @@ prbrg(int n, uint val) putc('\n'); } -void +int do_brginfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { volatile immap_t *immap = (immap_t *)CFG_IMMR; @@ -354,9 +362,10 @@ do_brginfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) while (i <= 8) prbrg(i++, *p++); #endif + return 0; } -void +int do_i2cinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { volatile immap_t *immap = (immap_t *)CFG_IMMR; @@ -396,42 +405,49 @@ do_i2cinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) iip->iic_tbptr, iip->iic_tbc); printf("TXTMP = %08x\n", iip->iic_txtmp); } + return 0; } -void +int do_sccinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unimplemented(cmdtp, bd, flag, argc, argv); + return 0; } -void +int do_smcinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unimplemented(cmdtp, bd, flag, argc, argv); + return 0; } -void +int do_spiinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unimplemented(cmdtp, bd, flag, argc, argv); + return 0; } -void +int do_muxinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unimplemented(cmdtp, bd, flag, argc, argv); + return 0; } -void +int do_siinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unimplemented(cmdtp, bd, flag, argc, argv); + return 0; } -void +int do_mccinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { unimplemented(cmdtp, bd, flag, argc, argv); + return 0; } #endif /* CFG_CMD_IMMAP && (CONFIG_8xx || CONFIG_8260) */ diff --git a/common/cmd_mem.c b/common/cmd_mem.c index cf3bf40..b5d2062 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -32,8 +32,7 @@ #include #if (CONFIG_COMMANDS & CFG_CMD_MEMORY) - -static void mod_mem(cmd_tbl_t *, int, int, int, char *[]); +static int mod_mem(cmd_tbl_t *, int, int, int, char *[]); /* Display values from last command. * Memory modify remembered values are different from display memory. @@ -50,8 +49,7 @@ static ulong base_address = 0; * md{.b, .w, .l} {addr} {len} */ #define DISP_LINE_LEN 16 - -void do_mem_md (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_mem_md (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong addr, size, length; ulong i, nbytes, linebytes; @@ -66,7 +64,7 @@ void do_mem_md (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } if ((flag & CMD_FLAG_REPEAT) == 0) { @@ -134,28 +132,25 @@ void do_mem_md (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) dp_last_addr = addr; dp_last_length = length; dp_last_size = size; + return 0; } - -void do_mem_mm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_mem_mm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { - mod_mem (cmdtp, 1, flag, argc, argv); + return mod_mem (cmdtp, 1, flag, argc, argv); } - - -void do_mem_nm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_mem_nm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { - mod_mem (cmdtp, 0, flag, argc, argv); + return mod_mem (cmdtp, 0, flag, argc, argv); } - -void do_mem_mw (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_mem_mw (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong addr, size, writeval, count; if ((argc < 3) || (argc > 4)) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } /* Check for size specification. @@ -194,16 +189,17 @@ void do_mem_mw (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) *((u_char *)addr) = (u_char)writeval; addr += size; } + return 0; } - -void do_mem_cmp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_mem_cmp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong size, addr1, addr2, count, ngood; + int rcode = 0; if (argc != 4) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } /* Check for size specification. @@ -235,6 +231,7 @@ void do_mem_cmp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf("word at 0x%08lx (0x%08lx) " "!= word at 0x%08lx (0x%08lx)\n", addr1, word1, addr2, word2); + rcode = 1; break; } } @@ -245,6 +242,7 @@ void do_mem_cmp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf("halfword at 0x%08lx (0x%04x) " "!= halfword at 0x%08lx (0x%04x)\n", addr1, hword1, addr2, hword2); + rcode = 1; break; } } @@ -255,6 +253,7 @@ void do_mem_cmp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf("byte at 0x%08lx (0x%02x) " "!= byte at 0x%08lx (0x%02x)\n", addr1, byte1, addr2, byte2); + rcode = 1; break; } } @@ -266,16 +265,16 @@ void do_mem_cmp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf("Total of %ld %s%s were the same\n", ngood, size == 4 ? "word" : size == 2 ? "halfword" : "byte", ngood == 1 ? "" : "s"); + return rcode; } - -void do_mem_cp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_mem_cp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong addr, size, dest, count; if (argc != 4) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } /* Check for size specification. @@ -304,18 +303,18 @@ void do_mem_cp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("Copy to Flash... "); switch (rc = flash_write ((uchar *)addr, dest, count*size)) { case 0: printf ("done\n"); - return; + return 0; case 1: printf ("Timeout writing to Flash\n"); - return; + return 1; case 2: printf ("Flash not Erased\n"); - return; + return 1; case 4: printf ("Can't write to protected Flash sectors\n"); - return; + return 1; case 8: printf ("Outside available Flash\n"); - return; + return 1; default: printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc); - return; + return 1; } } @@ -329,10 +328,10 @@ void do_mem_cp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) addr += size; dest += size; } + return 0; } - -void do_mem_base (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_mem_base (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { if (argc > 1) { /* Set new base address. @@ -342,10 +341,10 @@ void do_mem_base (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) /* Print the current base address. */ printf("Base Address: 0x%08lx\n", base_address); + return 0; } - -void do_mem_loop (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_mem_loop (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong addr, size, length, i, junk; volatile uint *longp; @@ -354,7 +353,7 @@ void do_mem_loop (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (argc < 3) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } /* Check for a size spefication. @@ -422,11 +421,12 @@ void do_mem_loop (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) /* Just a quickie to walk through some memory. */ -void do_mem_mtest (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_mem_mtest (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong *addr, *start, *end; ulong val; ulong pattern; + int rcode = 0; if (argc > 1) { start = (ulong *)simple_strtoul(argv[1], NULL, 16); @@ -451,7 +451,7 @@ void do_mem_mtest (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) for (;;) { if (ctrlc()) { putc ('\n'); - return; + return 1; } printf ("\rPattern %08lX Writing..." @@ -470,6 +470,7 @@ void do_mem_mtest (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("\nMem error @ 0x%08X: " "found %08lX, expected 0x%08lX\n", (uint)addr, *addr, val); + rcode = 1; } val++; } @@ -477,6 +478,8 @@ void do_mem_mtest (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) pattern++; } + return rcode; + } @@ -488,8 +491,7 @@ void do_mem_mtest (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) * mm{.b, .w, .l} {addr} * nm{.b, .w, .l} {addr} */ - -static void +static int mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) { ulong addr, size, i; @@ -498,7 +500,7 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) if (argc != 2) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } #ifdef CONFIG_BOOT_RETRY_TIME @@ -582,16 +584,16 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) mm_last_addr = addr; mm_last_size = size; + return 0; } - -void do_mem_crc (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_mem_crc (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong addr, length; ulong crc; if (argc < 3) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } addr = simple_strtoul(argv[1], NULL, 16); @@ -603,6 +605,7 @@ void do_mem_crc (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("CRC32 for %08lx ... %08lx ==> %08lx\n", addr, addr + length -1, crc); + return 0; } #endif /* CFG_CMD_MEMORY */ diff --git a/common/cmd_mii.c b/common/cmd_mii.c index c7108bf..a84bf1a 100644 --- a/common/cmd_mii.c +++ b/common/cmd_mii.c @@ -48,11 +48,12 @@ uint last_reg; * mii write {addr} {reg} {data} */ -void do_mii (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_mii (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { char op; unsigned char addr, reg; unsigned short data; + int rcode = 0; /* * We use the last specified parameters, unless new ones are @@ -100,19 +101,23 @@ void do_mii (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } else if(op == 'r') { - if(miiphy_read(addr, reg, &data) != 0) + if(miiphy_read(addr, reg, &data) != 0) { printf("Error reading from the PHY\n"); + rcode = 1; + } printf("%04X\n", data & 0x0000FFFF); } else if(op == 'w') { - if(miiphy_write(addr, reg, data) != 0) + if(miiphy_write(addr, reg, data) != 0) { printf("Error writing to the PHY\n"); + rcode = 1; + } } else { printf("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } /* @@ -121,6 +126,8 @@ void do_mii (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) last_op = op; last_addr = addr; last_data = data; + + return rcode; } #endif /* CFG_CMD_MII */ diff --git a/common/cmd_net.c b/common/cmd_net.c index 4aa41d8..64bcd8f 100644 --- a/common/cmd_net.c +++ b/common/cmd_net.c @@ -35,29 +35,29 @@ # include # endif -extern void do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]); +extern int do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]); -static void netboot_common (int, cmd_tbl_t *, bd_t *, int , char *[]); +static int netboot_common (int, cmd_tbl_t *, bd_t *, int , char *[]); -void do_bootp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_bootp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { - netboot_common (BOOTP, cmdtp, bd, argc, argv); + return netboot_common (BOOTP, cmdtp, bd, argc, argv); } -void do_tftpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_tftpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { - netboot_common (TFTP, cmdtp, bd, argc, argv); + return netboot_common (TFTP, cmdtp, bd, argc, argv); } -void do_rarpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_rarpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { - netboot_common (RARP, cmdtp, bd, argc, argv); + return netboot_common (RARP, cmdtp, bd, argc, argv); } #if (CONFIG_COMMANDS & CFG_CMD_DHCP) -void do_dhcp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_dhcp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { - netboot_common(DHCP, cmdtp, bd, argc, argv); + return netboot_common(DHCP, cmdtp, bd, argc, argv); } #endif /* CFG_CMD_DHCP */ @@ -96,11 +96,11 @@ static void netboot_update_env(void) setenv("dnsip", tmp); } } - -static void +static int netboot_common (int proto, cmd_tbl_t *cmdtp, bd_t *bd, int argc, char *argv[]) { char *s; + int rcode = 0; switch (argc) { case 1: @@ -123,11 +123,11 @@ netboot_common (int proto, cmd_tbl_t *cmdtp, bd_t *bd, int argc, char *argv[]) break; default: printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } if (NetLoop(bd, proto) == 0) - return; + return 1; /* NetLoop ok, update environment */ netboot_update_env(); @@ -140,17 +140,16 @@ netboot_common (int proto, cmd_tbl_t *cmdtp, bd_t *bd, int argc, char *argv[]) printf ("Automatic boot of image at addr 0x%08lX ...\n", load_addr); - - do_bootm (cmdtp, bd, 0, 1, local_args); + rcode = do_bootm (cmdtp, bd, 0, 1, local_args); } #ifdef CONFIG_AUTOSCRIPT if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) { printf("Running autoscript at addr 0x%08lX ...\n", load_addr); - autoscript (bd, load_addr); + rcode = autoscript (bd, load_addr); } #endif - + return rcode; } #endif /* CFG_CMD_NET */ diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 1e0b73e..7279ead 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -337,9 +337,10 @@ static uchar get_env_char_eeprom (int index) * Command interface: print one or all environment variables */ -void do_printenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_printenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { int i, j, k, nxt; + int rcode = 0; if (argc == 1) { /* Print all env variables */ for (i=0; get_env_char(i) != '\0'; i=nxt+1) { @@ -351,13 +352,13 @@ void do_printenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (ctrlc()) { printf ("\n ** Abort\n"); - return; + return 1; } } printf("\nEnvironment size: %d/%d bytes\n", i, ENV_SIZE); - return; + return 0; } for (i=1; icrc = crc32(0, env_ptr->data, ENV_SIZE); - return; + return 0; } /* @@ -527,7 +531,7 @@ void _do_setenv (bd_t *bd, int flag, int argc, char *argv[]) } if (len > (&env_data[ENV_SIZE]-env)) { printf ("## Error: environment overflow, \"%s\" deleted\n", name); - return; + return 1; } while ((*env = *name++) != '\0') env++; @@ -557,7 +561,7 @@ void _do_setenv (bd_t *bd, int flag, int argc, char *argv[]) bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0; if (s) s = (*e) ? e+1 : e; } - return; + return 0; } if (strcmp(argv[1],"ipaddr") == 0) { @@ -570,18 +574,19 @@ void _do_setenv (bd_t *bd, int flag, int argc, char *argv[]) bd->bi_ip_addr |= (val & 0xFF); if (s) s = (*e) ? e+1 : e; } - return; + return 0; } if (strcmp(argv[1],"loadaddr") == 0) { load_addr = simple_strtoul(argv[2], NULL, 16); - return; + return 0; } #if (CONFIG_COMMANDS & CFG_CMD_NET) if (strcmp(argv[1],"bootfile") == 0) { copy_filename (BootFile, argv[2], sizeof(BootFile)); - return; + return 0; } #endif /* CFG_CMD_NET */ + return 0; } void setenv (char *varname, char *varvalue) @@ -590,15 +595,15 @@ void setenv (char *varname, char *varvalue) _do_setenv (bd_ptr, 0, 3, argv); } -void do_setenv (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, +int do_setenv (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) { if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } - _do_setenv (bd, flag, argc, argv); + return _do_setenv (bd, flag, argc, argv); } /************************************************************************ @@ -606,7 +611,7 @@ void do_setenv (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, */ #if (CONFIG_COMMANDS & CFG_CMD_ASKENV) -void do_askenv (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, +int do_askenv (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) { extern char console_buffer[CFG_CBSIZE]; @@ -622,13 +627,13 @@ void do_askenv (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } /* Check the syntax */ switch (argc) { case 1: printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; case 2: /* askenv envname */ sprintf (message, "Please enter '%s':", argv[1]); @@ -660,7 +665,7 @@ void do_askenv (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, size = CFG_CBSIZE - 1; if (size <= 0) - return; + return 1; /* prompt for input */ len = readline (message); @@ -675,7 +680,7 @@ void do_askenv (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, } // Continue calling setenv code - _do_setenv (bd, flag, len, local_args); + return _do_setenv (bd, flag, len, local_args); } #endif /* CFG_CMD_ASKENV */ @@ -754,18 +759,21 @@ envmatch (uchar *s1, int i2) #ifdef CFG_ENV_IS_IN_NVRAM -void do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { + int rcode = 0; printf ("Saving Environment to NVRAM...\n"); - memcpy ((char *)CFG_ENV_ADDR, env_ptr, CFG_ENV_SIZE); + if (memcpy ((char *)CFG_ENV_ADDR, env_ptr, CFG_ENV_SIZE) == NULL) + rcode = 1 ; + return rcode; } #elif CFG_ENV_IS_IN_EEPROM -void do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { printf ("Saving Environment to EEPROM...\n"); - eeprom_write (CFG_ENV_OFFSET, (uchar *)env_ptr, CFG_ENV_SIZE); + return eeprom_write (CFG_ENV_OFFSET, (uchar *)env_ptr, CFG_ENV_SIZE); } #else /* !CFG_ENV_IS_IN_NVRAM, !CFG_ENV_IS_IN_EEPROM => Must be flash, then */ @@ -773,7 +781,7 @@ void do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) /* need both ENV and flash */ #if ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH)) -void do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { int len, rc; ulong end_addr; @@ -784,6 +792,7 @@ void do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #else uchar *env_buffer = (char *)env_ptr; #endif /* CFG_ENV_SECT_SIZE */ + int rcode = 0; #if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE) @@ -806,27 +815,35 @@ void do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) end_addr = (ulong)flash_sect_addr + len - 1; - flash_sect_protect (0, (ulong)flash_sect_addr, end_addr); + if (flash_sect_protect (0, (ulong)flash_sect_addr, end_addr)) + return 1; printf ("Erasing Flash..."); - flash_sect_erase ((ulong)flash_sect_addr, end_addr); + if (flash_sect_erase ((ulong)flash_sect_addr, end_addr)) + return 1; printf ("Saving Environment to Flash...\n"); switch (rc = flash_write(env_buffer, (ulong)flash_sect_addr, len)) { case 0: break; case 1: printf ("Timeout writing to Flash\n"); + rcode = 1; break; case 2: printf ("Flash not Erased\n"); + rcode = 1; break; case 4: printf ("Can't write to protected Flash sectors\n"); + rcode = 1; break; case 8: printf ("Outside available Flash\n"); - return; + return 1; default: printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc); + rcode = 1; } - flash_sect_protect (1, (ulong)flash_sect_addr, end_addr); + /* try to re-protect */ + (void) flash_sect_protect (1, (ulong)flash_sect_addr, end_addr); + return rcode; } #endif /* CFG_CMD_ENV + CFG_CMD_FLASH */ diff --git a/common/cmd_pcmcia.c b/common/cmd_pcmcia.c index 53c6a22..902d41b 100644 --- a/common/cmd_pcmcia.c +++ b/common/cmd_pcmcia.c @@ -113,23 +113,24 @@ const char *indent = "\t "; #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) -void do_pinit (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_pinit (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { - + int rcode = 0; + if (argc != 2) { printf ("Usage: pinit {on | off}\n"); - return; + return 1; } if (strcmp(argv[1],"on") == 0) { - pcmcia_on (); + rcode = pcmcia_on (); } else if (strcmp(argv[1],"off") == 0) { - pcmcia_off (); + rcode = pcmcia_off (); } else { printf ("Usage: pinit {on | off}\n"); - return; + return 1; } - return; + return rcode; } #endif /* CFG_CMD_PCMCIA */ @@ -253,6 +254,7 @@ static void pcmcia_off (void) /* disable external hardware */ printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n"); hardware_disable(_slot_); + return 0; } #endif /* CFG_CMD_PCMCIA */ diff --git a/common/cmd_reginfo.c b/common/cmd_reginfo.c index 255bb78..cb32ad1 100644 --- a/common/cmd_reginfo.c +++ b/common/cmd_reginfo.c @@ -31,7 +31,7 @@ #endif #if (CONFIG_COMMANDS & CFG_CMD_REGINFO) -void do_reginfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_reginfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { #if defined(CONFIG_8xx) volatile immap_t *immap = (immap_t *)CFG_IMMR; @@ -173,6 +173,8 @@ mfdcr(dmacr3), mfdcr(dmact3),mfdcr(dmada3), mfdcr(dmasa3), mfdcr(dmasb3) ); printf ("\n\n"); #endif /*(CONFIG_405GP)*/ + + return 0; } #endif /* CONFIG_8xx && CFG_CMD_REGINFO */ diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 05d545c..ec3bbba 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -205,7 +205,7 @@ block_dev_desc_t * scsi_get_dev(int dev) /****************************************************************************** * scsi boot command intepreter. Derived from diskboot */ -void do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { char *boot_device = NULL; char *ep; @@ -214,6 +214,7 @@ void do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) ulong addr; disk_partition_t info; image_header_t *hdr; + int rcode = 0; switch (argc) { case 1: @@ -230,37 +231,37 @@ void do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) break; default: printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } if (!boot_device) { puts ("\n** No boot device **\n"); - return; + return 1; } dev = simple_strtoul(boot_device, &ep, 16); printf("booting from dev %d\n",dev); if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { printf ("\n** Device %d not available\n", dev); - return; + return 1; } if (*ep) { if (*ep != ':') { puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - return; + return 1; } part = simple_strtoul(++ep, NULL, 16); } if (get_partition_info (&scsi_dev_desc[dev], part, &info)) { printf("error reading partinfo\n"); - return; + return 1; } if (strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) { printf ("\n** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info.type); - return; + return 1; } printf ("\nLoading from SCSI device %d, partition %d: " @@ -272,7 +273,7 @@ void do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (scsi_read (dev, info.start, 1, (ulong *)addr) != 1) { printf ("** Read error on %d:%d\n", dev, part); - return; + return 1; } hdr = (image_header_t *)addr; @@ -291,35 +292,36 @@ void do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (scsi_read (dev, info.start+1, cnt, (ulong *)(addr+info.blksz)) != cnt) { printf ("** Read error on %d:%d\n", dev, part); - return; + return 1; } /* Loading ok, update default load address */ load_addr = addr; /* Check if we should attempt an auto-start */ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { char *local_args[2]; - extern void do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]); + extern int do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]); local_args[0] = argv[0]; local_args[1] = NULL; printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); - do_bootm (cmdtp, bd, 0, 1, local_args); + rcode = do_bootm (cmdtp, bd, 0, 1, local_args); } + return rcode; } /********************************************************************************* * scsi command intepreter */ -void do_scsi (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_scsi (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { switch (argc) { case 0: - case 1: printf ("Usage:\n%s\n", cmdtp->usage); return; + case 1: printf ("Usage:\n%s\n", cmdtp->usage); return 1; case 2: if (strncmp(argv[1],"res",3) == 0) { printf("\nReset SCSI\n"); scsi_bus_reset(); scsi_scan(1); - return; + return 0; } if (strncmp(argv[1],"inf",3) == 0) { int i; @@ -329,20 +331,20 @@ void do_scsi (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) printf ("SCSI dev. %d: ", i); dev_print(&scsi_dev_desc[i]); } - return; + return 0; } if (strncmp(argv[1],"dev",3) == 0) { if ((scsi_curr_dev < 0) || (scsi_curr_dev >= CFG_SCSI_MAX_DEVICE)) { printf("\nno SCSI devices available\n"); - return; + return 1; } printf ("\n Device %d: ", scsi_curr_dev); dev_print(&scsi_dev_desc[scsi_curr_dev]); - return; + return 0; } if (strncmp(argv[1],"scan",4) == 0) { scsi_scan(1); - return; + return 0; } if (strncmp(argv[1],"part",4) == 0) { int dev, ok; @@ -357,26 +359,26 @@ void do_scsi (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } if (!ok) printf("\nno SCSI devices available\n"); - return; + return 1; } printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; case 3: if (strncmp(argv[1],"dev",3) == 0) { int dev = (int)simple_strtoul(argv[2], NULL, 10); printf ("\nSCSI device %d: ", dev); if (dev >= CFG_SCSI_MAX_DEVICE) { printf("unknown device\n"); - return; + return 1; } printf ("\n Device %d: ", dev); dev_print(&scsi_dev_desc[dev]); if(scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { - return; + return 1; } scsi_curr_dev = dev; printf("... is now current device\n"); - return; + return 0; } if (strncmp(argv[1],"part",4) == 0) { int dev = (int)simple_strtoul(argv[2], NULL, 10); @@ -386,10 +388,10 @@ void do_scsi (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) else { printf ("\nSCSI device %d not available\n", dev); } - return; + return 1; } printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; default: /* at least 4 args */ if (strcmp(argv[1],"read") == 0) { @@ -401,10 +403,11 @@ void do_scsi (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) scsi_curr_dev, blk, cnt); n = scsi_read(scsi_curr_dev, blk, cnt, (ulong *)addr); printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR"); - return; + return 0; } } /* switch */ printf ("Usage:\n%s\n", cmdtp->usage); + return 1; } /**************************************************************************************** diff --git a/common/command.c b/common/command.c index 69fa07d..2e210e5 100644 --- a/common/command.c +++ b/common/command.c @@ -88,14 +88,15 @@ " - echo args to console; \\c suppresses newline\n" \ ), -void +int do_version (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { extern char version_string[]; printf ("\n%s\n", version_string); + return 0; } -void +int do_echo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { int i, putnl = 1; @@ -116,30 +117,32 @@ do_echo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (putnl) putc('\n'); + return 0; } /* * Use puts() instead of printf() to avoid printf buffer overflow * for long help messages */ -void +int do_help (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { int i; + int rcode = 0; if (argc == 1) { /* print short help (usage) */ for (cmdtp=&cmd_tbl[0]; cmdtp->name; cmdtp++) { /* allow user abort */ if (ctrlc()) - return; + return 1; if (cmdtp->usage == NULL) continue; puts (cmdtp->usage); } - return; + return 0; } /* @@ -155,6 +158,7 @@ do_help (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) puts (cmdtp->help); } else { puts ("- No help available.\n"); + rcode = 1; } putc ('\n'); #else /* no long help available */ @@ -168,8 +172,10 @@ do_help (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) " known commands\n\n", argv[i] ); + rcode = 1; } } + return rcode; } /*************************************************************************** diff --git a/common/hush.c b/common/hush.c new file mode 100644 index 0000000..9a71af9 --- /dev/null +++ b/common/hush.c @@ -0,0 +1,3043 @@ +/* vi: set sw=4 ts=4: */ +/* + * sh.c -- a prototype Bourne shell grammar parser + * Intended to follow the original Thompson and Ritchie + * "small and simple is beautiful" philosophy, which + * incidentally is a good match to today's BusyBox. + * + * Copyright (C) 2000,2001 Larry Doolittle + * + * Credits: + * The parser routines proper are all original material, first + * written Dec 2000 and Jan 2001 by Larry Doolittle. + * The execution engine, the builtins, and much of the underlying + * support has been adapted from busybox-0.49pre's lash, + * which is Copyright (C) 2000 by Lineo, Inc., and + * written by Erik Andersen , . + * That, in turn, is based in part on ladsh.c, by Michael K. Johnson and + * Erik W. Troan, which they placed in the public domain. I don't know + * how much of the Johnson/Troan code has survived the repeated rewrites. + * Other credits: + * simple_itoa() was lifted from boa-0.93.15 + * b_addchr() derived from similar w_addchar function in glibc-2.2 + * setup_redirect(), redirect_opt_num(), and big chunks of main() + * and many builtins derived from contributions by Erik Andersen + * miscellaneous bugfixes from Matt Kraai + * + * There are two big (and related) architecture differences between + * this parser and the lash parser. One is that this version is + * actually designed from the ground up to understand nearly all + * of the Bourne grammar. The second, consequential change is that + * the parser and input reader have been turned inside out. Now, + * the parser is in control, and asks for input as needed. The old + * way had the input reader in control, and it asked for parsing to + * take place as needed. The new way makes it much easier to properly + * handle the recursion implicit in the various substitutions, especially + * across continuation lines. + * + * Bash grammar not implemented: (how many of these were in original sh?) + * $@ (those sure look like weird quoting rules) + * $_ + * ! negation operator for pipes + * &> and >& redirection of stdout+stderr + * Brace Expansion + * Tilde Expansion + * fancy forms of Parameter Expansion + * aliases + * Arithmetic Expansion + * <(list) and >(list) Process Substitution + * reserved words: case, esac, select, function + * Here Documents ( << word ) + * Functions + * Major bugs: + * job handling woefully incomplete and buggy + * reserved word execution woefully incomplete and buggy + * to-do: + * port selected bugfixes from post-0.49 busybox lash - done? + * finish implementing reserved words: for, while, until, do, done + * change { and } from special chars to reserved words + * builtins: break, continue, eval, return, set, trap, ulimit + * test magic exec + * handle children going into background + * clean up recognition of null pipes + * check setting of global_argc and global_argv + * control-C handling, probably with longjmp + * follow IFS rules more precisely, including update semantics + * figure out what to do with backslash-newline + * explain why we use signal instead of sigaction + * propagate syntax errors, die on resource errors? + * continuation lines, both explicit and implicit - done? + * memory leak finding and plugging - done? + * more testing, especially quoting rules and redirection + * document how quoting rules not precisely followed for variable assignments + * maybe change map[] to use 2-bit entries + * (eventually) remove all the printf's + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define __PPCBOOT__ +#ifdef __PPCBOOT__ +#include /* malloc, free, realloc*/ +#include /* isalpha, isdigit */ +#include /* readline */ +#include /* find_cmd */ +#include /* do_bootd */ +#endif +#ifdef CFG_HUSH_PARSER +#ifndef __PPCBOOT__ +#include /* isalpha, isdigit */ +#include /* getpid */ +#include /* getenv, atoi */ +#include /* strchr */ +#include /* popen etc. */ +#include /* glob, of course */ +#include /* va_list */ +#include +#include +#include /* should be pretty obvious */ + +#include /* ulimit */ +#include +#include +#include + +/* #include */ +#define DEBUG_SHELL + +#ifdef BB_VER +#include "busybox.h" +#include "cmdedit.h" +#else +#define applet_name "hush" +#include "standalone.h" +#define hush_main main +#undef BB_FEATURE_SH_FANCY_PROMPT +#endif +#endif + +#ifdef __PPCBOOT__ +#define EXIT_SUCCESS 0 +#define EOF -1 +#define syntax() syntax_err() +#define xstrdup strdup +#define xmalloc malloc +#define xrealloc realloc +#define error_msg printf +#else +typedef enum { + REDIRECT_INPUT = 1, + REDIRECT_OVERWRITE = 2, + REDIRECT_APPEND = 3, + REDIRECT_HEREIS = 4, + REDIRECT_IO = 5 +} redir_type; +/* The descrip member of this structure is only used to make debugging + * output pretty */ +struct {int mode; int default_fd; char *descrip;} redir_table[] = { + { 0, 0, "()" }, + { O_RDONLY, 0, "<" }, + { O_CREAT|O_TRUNC|O_WRONLY, 1, ">" }, + { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" }, + { O_RDONLY, -1, "<<" }, + { O_RDWR, 1, "<>" } +}; +#endif + +typedef enum { + PIPE_SEQ = 1, + PIPE_AND = 2, + PIPE_OR = 3, + PIPE_BG = 4, +} pipe_style; + +/* might eventually control execution */ +typedef enum { + RES_NONE = 0, + RES_IF = 1, + RES_THEN = 2, + RES_ELIF = 3, + RES_ELSE = 4, + RES_FI = 5, + RES_FOR = 6, + RES_WHILE = 7, + RES_UNTIL = 8, + RES_DO = 9, + RES_DONE = 10, + RES_XXXX = 11, + RES_SNTX = 12 +} reserved_style; +#define FLAG_END (1<, but protected with __USE_GNU */ +#endif + +/* "globals" within this file */ +static char *ifs; +static char map[256]; +#ifndef __PPCBOOT__ +static int fake_mode; +static int interactive; +static struct close_me *close_me_head; +static const char *cwd; +static struct pipe *job_list; +static unsigned int last_bg_pid; +static unsigned int last_jobid; +static unsigned int shell_terminal; +static char *PS1; +static char *PS2; +#else +static bd_t *BD; +#endif +struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; +struct variables *top_vars = &shell_ver; + +#define B_CHUNK (100) +#define B_NOSPAC 1 + +typedef struct { + char *data; + int length; + int maxlen; + int quote; + int nonnull; +} o_string; +#define NULL_O_STRING {NULL,0,0,0,0} +/* used for initialization: + o_string foo = NULL_O_STRING; */ + +/* I can almost use ordinary FILE *. Is open_memstream() universally + * available? Where is it documented? */ +struct in_str { + const char *p; +#ifndef __PPCBOOT__ + char peek_buf[2]; +#endif + int __promptme; + int promptmode; +#ifndef __PPCBOOT__ + FILE *file; +#endif + int (*get) (struct in_str *); + int (*peek) (struct in_str *); +}; +#define b_getch(input) ((input)->get(input)) +#define b_peek(input) ((input)->peek(input)) +#ifndef __PPCBOOT__ +#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" +struct built_in_command { + char *cmd; /* name */ + char *descr; /* description */ + int (*function) (struct child_prog *); /* function ptr */ +}; +#endif +/* belongs in busybox.h */ +static inline int max(int a, int b) { + return (a>b)?a:b; +} +/* This should be in utility.c */ + +#ifdef DEBUG_SHELL +#ifndef __PPCBOOT__ +static void debug_printf(const char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + printf(stderr, format, args); + va_end(args); +} +#else +#define debug_printf printf /* ppcboot debug flag */ +#endif +#else +static inline void debug_printf(const char *format, ...) { } +#endif +#define final_printf debug_printf +#ifdef __PPCBOOT__ +static void syntax_err(void) { + printf("syntax error\n"); +} +#else +static void __syntax(char *file, int line) { + error_msg("syntax error %s:%d", file, line); +} +#define syntax() __syntax(__FILE__, __LINE__) +/* Index of subroutines: */ +/* function prototypes for builtins */ +static int builtin_cd(struct child_prog *child); +static int builtin_env(struct child_prog *child); +static int builtin_exec(struct child_prog *child); +static int builtin_exit(struct child_prog *child); +static int builtin_export(struct child_prog *child); +static int builtin_fg_bg(struct child_prog *child); +static int builtin_help(struct child_prog *child); +static int builtin_jobs(struct child_prog *child); +static int builtin_pwd(struct child_prog *child); +static int builtin_read(struct child_prog *child); +static int builtin_set(struct child_prog *child); +static int builtin_shift(struct child_prog *child); +static int builtin_source(struct child_prog *child); +static int builtin_umask(struct child_prog *child); +static int builtin_unset(struct child_prog *child); +static int builtin_not_written(struct child_prog *child); +#endif +/* o_string manipulation: */ +static int b_check_space(o_string *o, int len); +static int b_addchr(o_string *o, int ch); +static void b_reset(o_string *o); +static int b_addqchr(o_string *o, int ch, int quote); +static int b_adduint(o_string *o, unsigned int i); +/* in_str manipulations: */ +static int static_get(struct in_str *i); +static int static_peek(struct in_str *i); +static int file_get(struct in_str *i); +static int file_peek(struct in_str *i); +#ifndef __PPCBOOT__ +static void setup_file_in_str(struct in_str *i, FILE *f); +#else +static void setup_file_in_str(struct in_str *i); +#endif +static void setup_string_in_str(struct in_str *i, const char *s); +#ifndef __PPCBOOT__ +/* close_me manipulations: */ +static void mark_open(int fd); +static void mark_closed(int fd); +static void close_all(); +#endif +/* "run" the final data structures: */ +static char *indenter(int i); +static int free_pipe_list(struct pipe *head, int indent); +static int free_pipe(struct pipe *pi, int indent); +/* really run the final data structures: */ +#ifndef __PPCBOOT__ +static int setup_redirects(struct child_prog *prog, int squirrel[]); +#endif +static int run_list_real(struct pipe *pi); +#ifndef __PPCBOOT__ +static void pseudo_exec(struct child_prog *child) __attribute__ ((noreturn)); +#endif +static int run_pipe_real(struct pipe *pi); +/* extended glob support: */ +#ifndef __PPCBOOT__ +static int globhack(const char *src, int flags, glob_t *pglob); +static int glob_needed(const char *s); +static int xglob(o_string *dest, int flags, glob_t *pglob); +#endif +/* variable assignment: */ +static int is_assignment(const char *s); +/* data structure manipulation: */ +#ifndef __PPCBOOT__ +static int setup_redirect(struct p_context *ctx, int fd, redir_type style, struct in_str *input); +#endif +static void initialize_context(struct p_context *ctx); +static int done_word(o_string *dest, struct p_context *ctx); +static int done_command(struct p_context *ctx); +static int done_pipe(struct p_context *ctx, pipe_style type); +/* primary string parsing: */ +#ifndef __PPCBOOT__ +static int redirect_dup_num(struct in_str *input); +static int redirect_opt_num(o_string *o); +static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, int subst_end); +static int parse_group(o_string *dest, struct p_context *ctx, struct in_str *input, int ch); +#endif +static void lookup_param(o_string *dest, struct p_context *ctx, o_string *src); +static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input); +static int parse_string(o_string *dest, struct p_context *ctx, const char *src); +static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, int end_trigger); +/* setup: */ +static int parse_stream_outer(struct in_str *inp); +#ifndef __PPCBOOT__ +static int parse_string_outer(const char *s); +static int parse_file_outer(FILE *f); +#else +int ppcboot_hush_start(bd_t *bd); +static int parse_file_outer(void); +#endif +#ifndef __PPCBOOT__ +/* job management: */ +static int checkjobs(struct pipe* fg_pipe); +static void insert_bg_job(struct pipe *pi); +static void remove_bg_job(struct pipe *pi); +#endif +/* local variable support */ +static char *get_local_var(const char *var); +#ifndef __PPCBOOT__ +static void unset_local_var(const char *name); +#endif +static int set_local_var(const char *s, int flg_export); +#ifndef __PPCBOOT__ +/* Table of built-in functions. They can be forked or not, depending on + * context: within pipes, they fork. As simple commands, they do not. + * When used in non-forking context, they can change global variables + * in the parent shell process. If forked, of course they can not. + * For example, 'unset foo | whatever' will parse and run, but foo will + * still be set at the end. */ +static struct built_in_command bltins[] = { + {"bg", "Resume a job in the background", builtin_fg_bg}, + {"break", "Exit for, while or until loop", builtin_not_written}, + {"cd", "Change working directory", builtin_cd}, + {"continue", "Continue for, while or until loop", builtin_not_written}, + {"env", "Print all environment variables", builtin_env}, + {"eval", "Construct and run shell command", builtin_not_written}, + {"exec", "Exec command, replacing this shell with the exec'd process", + builtin_exec}, + {"exit", "Exit from shell()", builtin_exit}, + {"export", "Set environment variable", builtin_export}, + {"fg", "Bring job into the foreground", builtin_fg_bg}, + {"jobs", "Lists the active jobs", builtin_jobs}, + {"pwd", "Print current directory", builtin_pwd}, + {"read", "Input environment variable", builtin_read}, + {"return", "Return from a function", builtin_not_written}, + {"set", "Set/unset shell local variables", builtin_set}, + {"shift", "Shift positional parameters", builtin_shift}, + {"trap", "Trap signals", builtin_not_written}, + {"ulimit","Controls resource limits", builtin_not_written}, + {"umask","Sets file creation mask", builtin_umask}, + {"unset", "Unset environment variable", builtin_unset}, + {".", "Source-in and run commands in a file", builtin_source}, + {"help", "List shell built-in commands", builtin_help}, + {NULL, NULL, NULL} +}; + +static const char *set_cwd(void) +{ + if(cwd==unknown) + cwd = NULL; /* xgetcwd(arg) called free(arg) */ + cwd = xgetcwd((char *)cwd); + if (!cwd) + cwd = unknown; + return cwd; +} + + +/* built-in 'cd ' handler */ +static int builtin_cd(struct child_prog *child) +{ + char *newdir; + if (child->argv[1] == NULL) + newdir = getenv("HOME"); + else + newdir = child->argv[1]; + if (chdir(newdir)) { + printf("cd: %s: %s\n", newdir, strerror(errno)); + return EXIT_FAILURE; + } + set_cwd(); + return EXIT_SUCCESS; +} + +/* built-in 'env' handler */ +static int builtin_env(struct child_prog *dummy) +{ + char **e = environ; + if (e == NULL) return EXIT_FAILURE; + for (; *e; e++) { + puts(*e); + } + return EXIT_SUCCESS; +} + +/* built-in 'exec' handler */ +static int builtin_exec(struct child_prog *child) +{ + if (child->argv[1] == NULL) + return EXIT_SUCCESS; /* Really? */ + child->argv++; + pseudo_exec(child); + /* never returns */ +} + +/* built-in 'exit' handler */ +static int builtin_exit(struct child_prog *child) +{ + if (child->argv[1] == NULL) + exit(last_return_code); + exit (atoi(child->argv[1])); +} + +/* built-in 'export VAR=value' handler */ +static int builtin_export(struct child_prog *child) +{ + int res = 0; + char *name = child->argv[1]; + + if (name == NULL) { + return (builtin_env(child)); + } + + name = strdup(name); + + if(name) { + char *value = strchr(name, '='); + + if (!value) { + char *tmp; + /* They are exporting something without an =VALUE */ + + value = get_local_var(name); + if (value) { + size_t ln = strlen(name); + + tmp = realloc(name, ln+strlen(value)+2); + if(tmp==NULL) + res = -1; + else { + sprintf(tmp+ln, "=%s", value); + name = tmp; + } + } else { + /* bash does not return an error when trying to export + * an undefined variable. Do likewise. */ + res = 1; + } + } + } + if (res<0) + perror_msg("export"); + else if(res==0) + res = set_local_var(name, 1); + else + res = 0; + free(name); + return res; +} + +/* built-in 'fg' and 'bg' handler */ +static int builtin_fg_bg(struct child_prog *child) +{ + int i, jobnum; + struct pipe *pi=NULL; + + if (!interactive) + return EXIT_FAILURE; + /* If they gave us no args, assume they want the last backgrounded task */ + if (!child->argv[1]) { + for (pi = job_list; pi; pi = pi->next) { + if (pi->jobid == last_jobid) { + break; + } + } + if (!pi) { + error_msg("%s: no current job", child->argv[0]); + return EXIT_FAILURE; + } + } else { + if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) { + error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]); + return EXIT_FAILURE; + } + for (pi = job_list; pi; pi = pi->next) { + if (pi->jobid == jobnum) { + break; + } + } + if (!pi) { + error_msg("%s: %d: no such job", child->argv[0], jobnum); + return EXIT_FAILURE; + } + } + + if (*child->argv[0] == 'f') { + /* Put the job into the foreground. */ + tcsetpgrp(shell_terminal, pi->pgrp); + } + + /* Restart the processes in the job */ + for (i = 0; i < pi->num_progs; i++) + pi->progs[i].is_stopped = 0; + + if ( (i=kill(- pi->pgrp, SIGCONT)) < 0) { + if (i == ESRCH) { + remove_bg_job(pi); + } else { + perror_msg("kill (SIGCONT)"); + } + } + + pi->stopped_progs = 0; + return EXIT_SUCCESS; +} + +/* built-in 'help' handler */ +static int builtin_help(struct child_prog *dummy) +{ + struct built_in_command *x; + + printf("\nBuilt-in commands:\n"); + printf("-------------------\n"); + for (x = bltins; x->cmd; x++) { + if (x->descr==NULL) + continue; + printf("%s\t%s\n", x->cmd, x->descr); + } + printf("\n\n"); + return EXIT_SUCCESS; +} + +/* built-in 'jobs' handler */ +static int builtin_jobs(struct child_prog *child) +{ + struct pipe *job; + char *status_string; + + for (job = job_list; job; job = job->next) { + if (job->running_progs == job->stopped_progs) + status_string = "Stopped"; + else + status_string = "Running"; + + printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text); + } + return EXIT_SUCCESS; +} + + +/* built-in 'pwd' handler */ +static int builtin_pwd(struct child_prog *dummy) +{ + puts(set_cwd()); + return EXIT_SUCCESS; +} + +/* built-in 'read VAR' handler */ +static int builtin_read(struct child_prog *child) +{ + int res; + + if (child->argv[1]) { + char string[BUFSIZ]; + char *var = 0; + + string[0] = 0; /* In case stdin has only EOF */ + /* read string */ + fgets(string, sizeof(string), stdin); + chomp(string); + var = malloc(strlen(child->argv[1])+strlen(string)+2); + if(var) { + sprintf(var, "%s=%s", child->argv[1], string); + res = set_local_var(var, 0); + } else + res = -1; + if (res) + fprintf(stderr, "read: %m\n"); + free(var); /* So not move up to avoid breaking errno */ + return res; + } else { + do res=getchar(); while(res!='\n' && res!=EOF); + return 0; + } +} + +/* built-in 'set VAR=value' handler */ +static int builtin_set(struct child_prog *child) +{ + char *temp = child->argv[1]; + struct variables *e; + + if (temp == NULL) + for(e = top_vars; e; e=e->next) + printf("%s=%s\n", e->name, e->value); + else + set_local_var(temp, 0); + + return EXIT_SUCCESS; +} + + +/* Built-in 'shift' handler */ +static int builtin_shift(struct child_prog *child) +{ + int n=1; + if (child->argv[1]) { + n=atoi(child->argv[1]); + } + if (n>=0 && nargv[1] == NULL) + return EXIT_FAILURE; + + /* XXX search through $PATH is missing */ + input = fopen(child->argv[1], "r"); + if (!input) { + error_msg("Couldn't open file '%s'", child->argv[1]); + return EXIT_FAILURE; + } + + /* Now run the file */ + /* XXX argv and argc are broken; need to save old global_argv + * (pointer only is OK!) on this stack frame, + * set global_argv=child->argv+1, recurse, and restore. */ + mark_open(fileno(input)); + status = parse_file_outer(input); + mark_closed(fileno(input)); + fclose(input); + return (status); +} + +static int builtin_umask(struct child_prog *child) +{ + mode_t new_umask; + const char *arg = child->argv[1]; + char *end; + if (arg) { + new_umask=strtoul(arg, &end, 8); + if (*end!='\0' || end == arg) { + return EXIT_FAILURE; + } + } else { + printf("%.3o\n", (unsigned int) (new_umask=umask(0))); + } + umask(new_umask); + return EXIT_SUCCESS; +} + +/* built-in 'unset VAR' handler */ +static int builtin_unset(struct child_prog *child) +{ + /* bash returned already true */ + unset_local_var(child->argv[1]); + return EXIT_SUCCESS; +} + +static int builtin_not_written(struct child_prog *child) +{ + printf("builtin_%s not written\n",child->argv[0]); + return EXIT_FAILURE; +} +#endif +static int b_check_space(o_string *o, int len) +{ + /* It would be easy to drop a more restrictive policy + * in here, such as setting a maximum string length */ + if (o->length + len > o->maxlen) { + char *old_data = o->data; + /* assert (data == NULL || o->maxlen != 0); */ + o->maxlen += max(2*len, B_CHUNK); + o->data = realloc(o->data, 1 + o->maxlen); + if (o->data == NULL) { + free(old_data); + } + } + return o->data == NULL; +} + +static int b_addchr(o_string *o, int ch) +{ + debug_printf("b_addchr: %c %d %p\n", ch, o->length, o); + if (b_check_space(o, 1)) return B_NOSPAC; + o->data[o->length] = ch; + o->length++; + o->data[o->length] = '\0'; + return 0; +} + +static void b_reset(o_string *o) +{ + o->length = 0; + o->nonnull = 0; + if (o->data != NULL) *o->data = '\0'; +} + +static void b_free(o_string *o) +{ + b_reset(o); + if (o->data != NULL) free(o->data); + o->data = NULL; + o->maxlen = 0; +} + +/* My analysis of quoting semantics tells me that state information + * is associated with a destination, not a source. + */ +static int b_addqchr(o_string *o, int ch, int quote) +{ + if (quote && strchr("*?[\\",ch)) { + int rc; + rc = b_addchr(o, '\\'); + if (rc) return rc; + } + return b_addchr(o, ch); +} + +/* belongs in utility.c */ +char *simple_itoa(unsigned int i) +{ + /* 21 digits plus null terminator, good for 64-bit or smaller ints */ + static char local[22]; + char *p = &local[21]; + *p-- = '\0'; + do { + *p-- = '0' + i % 10; + i /= 10; + } while (i > 0); + return p + 1; +} + +static int b_adduint(o_string *o, unsigned int i) +{ + int r; + char *p = simple_itoa(i); + /* no escape checking necessary */ + do r=b_addchr(o, *p++); while (r==0 && *p); + return r; +} + +static int static_get(struct in_str *i) +{ + int ch=*i->p++; + if (ch=='\0') return EOF; + return ch; +} + +static int static_peek(struct in_str *i) +{ + return *i->p; +} +#ifndef __PPCBOOT__ +static inline void cmdedit_set_initial_prompt(void) +{ +#ifndef BB_FEATURE_SH_FANCY_PROMPT + PS1 = NULL; +#else + PS1 = getenv("PS1"); + if(PS1==0) + PS1 = "\\w \\$ "; +#endif +} + +static inline void setup_prompt_string(int promptmode, char **prompt_str) +{ + debug_printf("setup_prompt_string %d ",promptmode); +#ifndef BB_FEATURE_SH_FANCY_PROMPT + /* Set up the prompt */ + if (promptmode == 1) { + if (PS1) + free(PS1); + PS1=xmalloc(strlen(cwd)+4); + sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# "); + *prompt_str = PS1; + } else { + *prompt_str = PS2; + } +#else + *prompt_str = (promptmode==1)? PS1 : PS2; +#endif + debug_printf("result %s\n",*prompt_str); +} +#endif +static void get_user_input(struct in_str *i) +{ + +#ifndef __PPCBOOT__ + char *prompt_str; + static char the_command[BUFSIZ]; + + setup_prompt_string(i->promptmode, &prompt_str); +#ifdef BB_FEATURE_COMMAND_EDITING + /* + ** enable command line editing only while a command line + ** is actually being read; otherwise, we'll end up bequeathing + ** atexit() handlers and other unwanted stuff to our + ** child processes (rob@sysgo.de) + */ + cmdedit_read_input(prompt_str, the_command); +#else + fputs(prompt_str, stdout); + fflush(stdout); + the_command[0]=fgetc(i->file); + the_command[1]='\0'; +#endif + fflush(stdout); + i->p = the_command; +#else + extern char console_buffer[CFG_CBSIZE]; + int n; + static int flag_repeat = 0; + static char the_command[CFG_CBSIZE]; + + if (i->promptmode == 1) { + readline(CFG_PROMPT); + } else { + readline(CFG_PROMPT_HUSH_PS2); + } + n = strlen(console_buffer); + console_buffer[n] = '\n'; + console_buffer[n+1]= '\0'; + if (i->promptmode == 1) { + if (console_buffer[0] == '\n'&& flag_repeat == 0) { + i->p = console_buffer; + } + else { + if (console_buffer[0] != '\n') { + strcpy(the_command,console_buffer); + flag_repeat = 1; + } + else { + flag_repeat = 0; + } + i->p = the_command; + } + } + else { + if (console_buffer[0] != '\n') { + if (strlen(the_command) + strlen(console_buffer) + < CFG_CBSIZE) { + n = strlen(the_command); + the_command[n-1] = ' '; + strcpy(&the_command[n],console_buffer); + } + else { + the_command[0] = '\n'; + the_command[1] = '\0'; + } + } + i->p = console_buffer; + } +#endif +} + +/* This is the magic location that prints prompts + * and gets data back from the user */ +static int file_get(struct in_str *i) +{ + int ch; + ch = 0; + + /* If there is data waiting, eat it up */ + if (i->p && *i->p) { + ch=*i->p++; + } else { + /* need to double check i->file because we might be doing something + * more complicated by now, like sourcing or substituting. */ +#ifndef __PPCBOOT__ + if (i->__promptme && interactive && i->file == stdin) { + while(! i->p || (interactive && strlen(i->p)==0) ) { +#else + while(! i->p || strlen(i->p)==0 ) { +#endif + get_user_input(i); + } + i->promptmode=2; + i->__promptme = 0; + if (i->p && *i->p) { + ch=*i->p++; + } +#ifndef __PPCBOOT__ + } else { + ch = fgetc(i->file); + } +#endif + debug_printf("b_getch: got a %d\n", ch); + } + if (ch == '\n') i->__promptme=1; + return ch; +} + +/* All the callers guarantee this routine will never be + * used right after a newline, so prompting is not needed. + */ +static int file_peek(struct in_str *i) +{ +#ifndef __PPCBOOT__ + if (i->p && *i->p) { +#endif + return *i->p; +#ifndef __PPCBOOT__ + } else { + i->peek_buf[0] = fgetc(i->file); + i->peek_buf[1] = '\0'; + i->p = i->peek_buf; + debug_printf("b_peek: got a %d\n", *i->p); + return *i->p; + } +#endif +} +#ifndef __PPCBOOT__ +static void setup_file_in_str(struct in_str *i, FILE *f) +#else +static void setup_file_in_str(struct in_str *i) +#endif +{ + i->peek = file_peek; + i->get = file_get; + i->__promptme=1; + i->promptmode=1; +#ifndef __PPCBOOT__ + i->file = f; +#endif + i->p = NULL; +} + +static void setup_string_in_str(struct in_str *i, const char *s) +{ + i->peek = static_peek; + i->get = static_get; + i->__promptme=1; + i->promptmode=1; + i->p = s; +} +#ifndef __PPCBOOT__ +static void mark_open(int fd) +{ + struct close_me *new = xmalloc(sizeof(struct close_me)); + new->fd = fd; + new->next = close_me_head; + close_me_head = new; +} + +static void mark_closed(int fd) +{ + struct close_me *tmp; + if (close_me_head == NULL || close_me_head->fd != fd) + error_msg_and_die("corrupt close_me"); + tmp = close_me_head; + close_me_head = close_me_head->next; + free(tmp); +} + +static void close_all() +{ + struct close_me *c; + for (c=close_me_head; c; c=c->next) { + close(c->fd); + } + close_me_head = NULL; +} +/* squirrel != NULL means we squirrel away copies of stdin, stdout, + * and stderr if they are redirected. */ +static int setup_redirects(struct child_prog *prog, int squirrel[]) +{ + int openfd, mode; + struct redir_struct *redir; + + for (redir=prog->redirects; redir; redir=redir->next) { + if (redir->dup == -1 && redir->word.gl_pathv == NULL) { + /* something went wrong in the parse. Pretend it didn't happen */ + continue; + } + if (redir->dup == -1) { + mode=redir_table[redir->type].mode; + openfd = open(redir->word.gl_pathv[0], mode, 0666); + if (openfd < 0) { + /* this could get lost if stderr has been redirected, but + bash and ash both lose it as well (though zsh doesn't!) */ + perror_msg("error opening %s", redir->word.gl_pathv[0]); + return 1; + } + } else { + openfd = redir->dup; + } + + if (openfd != redir->fd) { + if (squirrel && redir->fd < 3) { + squirrel[redir->fd] = dup(redir->fd); + } + if (openfd == -3) { + close(openfd); + } else { + dup2(openfd, redir->fd); + if (redir->dup == -1) + close (openfd); + } + } + } + return 0; +} + +static void restore_redirects(int squirrel[]) +{ + int i, fd; + for (i=0; i<3; i++) { + fd = squirrel[i]; + if (fd != -1) { + /* No error checking. I sure wouldn't know what + * to do with an error if I found one! */ + dup2(fd, i); + close(fd); + } + } +} + +/* never returns */ +/* XXX no exit() here. If you don't exec, use _exit instead. + * The at_exit handlers apparently confuse the calling process, + * in particular stdin handling. Not sure why? */ +static void pseudo_exec(struct child_prog *child) +{ + int i, rcode; + struct built_in_command *x; + if (child->argv) { + for (i=0; is_assignment(child->argv[i]); i++) { + debug_printf("pid %d environment modification: %s\n",getpid(),child->argv[i]); + putenv(strdup(child->argv[i])); + } + child->argv+=i; /* XXX this hack isn't so horrible, since we are about + to exit, and therefore don't need to keep data + structures consistent for free() use. */ + /* If a variable is assigned in a forest, and nobody listens, + * was it ever really set? + */ + if (child->argv[0] == NULL) { + _exit(EXIT_SUCCESS); + } + + /* + * Check if the command matches any of the builtins. + * Depending on context, this might be redundant. But it's + * easier to waste a few CPU cycles than it is to figure out + * if this is one of those cases. + */ + for (x = bltins; x->cmd; x++) { + if (strcmp(child->argv[0], x->cmd) == 0 ) { + debug_printf("builtin exec %s\n", child->argv[0]); + rcode = x->function(child); + fflush(stdout); + _exit(rcode); + } + } + + /* Check if the command matches any busybox internal commands + * ("applets") here. + * FIXME: This feature is not 100% safe, since + * BusyBox is not fully reentrant, so we have no guarantee the things + * from the .bss are still zeroed, or that things from .data are still + * at their defaults. We could exec ourself from /proc/self/exe, but I + * really dislike relying on /proc for things. We could exec ourself + * from global_argv[0], but if we are in a chroot, we may not be able + * to find ourself... */ +#ifdef BB_FEATURE_SH_STANDALONE_SHELL + { + int argc_l; + char** argv_l=child->argv; + char *name = child->argv[0]; + +#ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN + /* Following discussions from November 2000 on the busybox mailing + * list, the default configuration, (without + * get_last_path_component()) lets the user force use of an + * external command by specifying the full (with slashes) filename. + * If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then applets + * _aways_ override external commands, so if you want to run + * /bin/cat, it will use BusyBox cat even if /bin/cat exists on the + * filesystem and is _not_ busybox. Some systems may want this, + * most do not. */ + name = get_last_path_component(name); +#endif + /* Count argc for use in a second... */ + for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++); + optind = 1; + debug_printf("running applet %s\n", name); + run_applet_by_name(name, argc_l, child->argv); + } +#endif + debug_printf("exec of %s\n",child->argv[0]); + execvp(child->argv[0],child->argv); + perror_msg("couldn't exec: %s",child->argv[0]); + _exit(1); + } else if (child->group) { + debug_printf("runtime nesting to group\n"); + interactive=0; /* crucial!!!! */ + rcode = run_list_real(child->group); + /* OK to leak memory by not calling free_pipe_list, + * since this process is about to exit */ + _exit(rcode); + } else { + /* Can happen. See what bash does with ">foo" by itself. */ + debug_printf("trying to pseudo_exec null command\n"); + _exit(EXIT_SUCCESS); + } +} + +static void insert_bg_job(struct pipe *pi) +{ + struct pipe *thejob; + + /* Linear search for the ID of the job to use */ + pi->jobid = 1; + for (thejob = job_list; thejob; thejob = thejob->next) + if (thejob->jobid >= pi->jobid) + pi->jobid = thejob->jobid + 1; + + /* add thejob to the list of running jobs */ + if (!job_list) { + thejob = job_list = xmalloc(sizeof(*thejob)); + } else { + for (thejob = job_list; thejob->next; thejob = thejob->next) /* nothing */; + thejob->next = xmalloc(sizeof(*thejob)); + thejob = thejob->next; + } + + /* physically copy the struct job */ + memcpy(thejob, pi, sizeof(struct pipe)); + thejob->next = NULL; + thejob->running_progs = thejob->num_progs; + thejob->stopped_progs = 0; + thejob->text = xmalloc(BUFSIZ); /* cmdedit buffer size */ + + //if (pi->progs[0] && pi->progs[0].argv && pi->progs[0].argv[0]) + { + char *bar=thejob->text; + char **foo=pi->progs[0].argv; + while(foo && *foo) { + bar += sprintf(bar, "%s ", *foo++); + } + } + + /* we don't wait for background thejobs to return -- append it + to the list of backgrounded thejobs and leave it alone */ + printf("[%d] %d\n", thejob->jobid, thejob->progs[0].pid); + last_bg_pid = thejob->progs[0].pid; + last_jobid = thejob->jobid; +} + +/* remove a backgrounded job */ +static void remove_bg_job(struct pipe *pi) +{ + struct pipe *prev_pipe; + + if (pi == job_list) { + job_list = pi->next; + } else { + prev_pipe = job_list; + while (prev_pipe->next != pi) + prev_pipe = prev_pipe->next; + prev_pipe->next = pi->next; + } + if (job_list) + last_jobid = job_list->jobid; + else + last_jobid = 0; + + pi->stopped_progs = 0; + free_pipe(pi, 0); + free(pi); +} + +/* Checks to see if any processes have exited -- if they + have, figure out why and see if a job has completed */ +static int checkjobs(struct pipe* fg_pipe) +{ + int attributes; + int status; + int prognum = 0; + struct pipe *pi; + pid_t childpid; + + attributes = WUNTRACED; + if (fg_pipe==NULL) { + attributes |= WNOHANG; + } + + while ((childpid = waitpid(-1, &status, attributes)) > 0) { + if (fg_pipe) { + int i, rcode = 0; + for (i=0; i < fg_pipe->num_progs; i++) { + if (fg_pipe->progs[i].pid == childpid) { + if (i==fg_pipe->num_progs-1) + rcode=WEXITSTATUS(status); + (fg_pipe->num_progs)--; + return(rcode); + } + } + } + + for (pi = job_list; pi; pi = pi->next) { + prognum = 0; + while (prognum < pi->num_progs && pi->progs[prognum].pid != childpid) { + prognum++; + } + if (prognum < pi->num_progs) + break; + } + + if(pi==NULL) { + debug_printf("checkjobs: pid %d was not in our list!\n", childpid); + continue; + } + + if (WIFEXITED(status) || WIFSIGNALED(status)) { + /* child exited */ + pi->running_progs--; + pi->progs[prognum].pid = 0; + + if (!pi->running_progs) { + printf(JOB_STATUS_FORMAT, pi->jobid, "Done", pi->text); + remove_bg_job(pi); + } + } else { + /* child stopped */ + pi->stopped_progs++; + pi->progs[prognum].is_stopped = 1; + +#if 0 + /* Printing this stuff is a pain, since it tends to + * overwrite the prompt an inconveinient moments. So + * don't do that. */ + if (pi->stopped_progs == pi->num_progs) { + printf("\n"JOB_STATUS_FORMAT, pi->jobid, "Stopped", pi->text); + } +#endif + } + } + + if (childpid == -1 && errno != ECHILD) + perror_msg("waitpid"); + + /* move the shell to the foreground */ + //if (interactive && tcsetpgrp(shell_terminal, getpgid(0))) + // perror_msg("tcsetpgrp-2"); + return -1; +} + +/* Figure out our controlling tty, checking in order stderr, + * stdin, and stdout. If check_pgrp is set, also check that + * we belong to the foreground process group associated with + * that tty. The value of shell_terminal is needed in order to call + * tcsetpgrp(shell_terminal, ...); */ +void controlling_tty(int check_pgrp) +{ + pid_t curpgrp; + + if ((curpgrp = tcgetpgrp(shell_terminal = 2)) < 0 + && (curpgrp = tcgetpgrp(shell_terminal = 0)) < 0 + && (curpgrp = tcgetpgrp(shell_terminal = 1)) < 0) + goto shell_terminal_error; + + if (check_pgrp && curpgrp != getpgid(0)) + goto shell_terminal_error; + + return; + +shell_terminal_error: + shell_terminal = -1; + return; +} +#endif +/* run_pipe_real() starts all the jobs, but doesn't wait for anything + * to finish. See checkjobs(). + * + * return code is normally -1, when the caller has to wait for children + * to finish to determine the exit status of the pipe. If the pipe + * is a simple builtin command, however, the action is done by the + * time run_pipe_real returns, and the exit code is provided as the + * return value. + * + * The input of the pipe is always stdin, the output is always + * stdout. The outpipe[] mechanism in BusyBox-0.48 lash is bogus, + * because it tries to avoid running the command substitution in + * subshell, when that is in fact necessary. The subshell process + * now has its stdout directed to the input of the appropriate pipe, + * so this routine is noticeably simpler. + */ + +static int run_pipe_real(struct pipe *pi) +{ + + int i; +#ifndef __PPCBOOT__ + int nextin, nextout; + int pipefds[2]; /* pipefds[0] is for reading */ + struct child_prog *child; + struct built_in_command *x; +#else + int nextin; + int flag = 0; + struct child_prog *child; + cmd_tbl_t *cmdtp; +#endif + + nextin = 0; +#ifndef __PPCBOOT__ + pi->pgrp = -1; +#endif + /* Check if this is a simple builtin (not part of a pipe). + * Builtins within pipes have to fork anyway, and are handled in + * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. + */ + if (pi->num_progs == 1) child = & (pi->progs[0]); +#ifndef __PPCBOOT__ + if (pi->num_progs == 1 && child->group && child->subshell == 0) { + int squirrel[] = {-1, -1, -1}; + int rcode; + debug_printf("non-subshell grouping\n"); + setup_redirects(child, squirrel); + /* XXX could we merge code with following builtin case, + * by creating a pseudo builtin that calls run_list_real? */ + rcode = run_list_real(child->group); + restore_redirects(squirrel); +#else + if (pi->num_progs == 1 && child->group) { + int rcode; + debug_printf("non-subshell grouping\n"); + rcode = run_list_real(child->group); +#endif + return rcode; + } else if (pi->num_progs == 1 && pi->progs[0].argv != NULL) { + for (i=0; is_assignment(child->argv[i]); i++) { /* nothing */ } + if (i!=0 && child->argv[i]==NULL) { + /* assignments, but no command: set the local environment */ + for (i=0; child->argv[i]!=NULL; i++) { + /* Ok, this case is tricky. We have to decide if this is a + * local variable, or an already exported variable. If it is + * already exported, we have to export the new value. If it is + * not exported, we need only set this as a local variable. + * This junk is all to decide whether or not to export this + * variable. */ + int export_me=0; + char *name, *value; + name = xstrdup(child->argv[i]); + debug_printf("Local environment set: %s\n", name); + value = strchr(name, '='); + if (value) + *value=0; + if ( get_local_var(name)) { + export_me=1; + } + free(name); + set_local_var(child->argv[i], export_me); + } + return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */ + } +#ifndef __PPCBOOT__ + for (x = bltins; x->cmd; x++) { + if (strcmp(child->argv[i], x->cmd) == 0 ) { + + int squirrel[] = {-1, -1, -1}; + int rcode; + if (x->function == builtin_exec && child->argv[i+1]==NULL) { + debug_printf("magic exec\n"); + setup_redirects(child,NULL); + return EXIT_SUCCESS; + } + debug_printf("builtin inline %s\n", child->argv[0]); + /* XXX setup_redirects acts on file descriptors, not FILEs. + * This is perfect for work that comes after exec(). + * Is it really safe for inline use? Experimentally, + * things seem to work with glibc. */ + setup_redirects(child, squirrel); +#else + /* Look up command in command table */ + if ((cmdtp = find_cmd(child->argv[i])) == NULL) { + printf ("Unknown command '%s' - try 'help'\n", child->argv[i]); + return 1; /* give up after bad command */ + } else { + int rcode; +#if (CONFIG_COMMANDS & CFG_CMD_BOOTD) + /* avoid "bootd" recursion */ + if (cmdtp->cmd == do_bootd) { + if (flag & CMD_FLAG_BOOTD) { + printf ("'bootd' recursion detected\n"); + return 1; + } + else + flag |= CMD_FLAG_BOOTD; + } +#endif /* CFG_CMD_BOOTD */ + /* found - check max args */ + if ((child->argc - i) > cmdtp->maxargs) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } +#endif + for (i=0; is_assignment(child->argv[i]); i++) { +#ifndef __PPCBOOT__ + putenv(strdup(child->argv[i])); +#else + set_local_var(child->argv[i], 0); +#endif + } + child->argv+=i; /* XXX horrible hack */ +#ifndef __PPCBOOT__ + rcode = x->function(child); +#else + /* OK - call function to do the command */ + rcode = (cmdtp->cmd) + (cmdtp, BD, flag,child->argc-i,&child->argv[i]); +#endif + child->argv-=i; /* XXX restore hack so free() can work right */ +#ifndef __PPCBOOT__ + restore_redirects(squirrel); +#endif + return rcode; + } + } +#ifndef __PPCBOOT__ + } + + for (i = 0; i < pi->num_progs; i++) { + child = & (pi->progs[i]); + + /* pipes are inserted between pairs of commands */ + if ((i + 1) < pi->num_progs) { + if (pipe(pipefds)<0) perror_msg_and_die("pipe"); + nextout = pipefds[1]; + } else { + nextout=1; + pipefds[0] = -1; + } + + /* XXX test for failed fork()? */ + if (!(child->pid = fork())) { + /* Set the handling for job control signals back to the default. */ + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGTSTP, SIG_DFL); + signal(SIGTTIN, SIG_DFL); + signal(SIGTTOU, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + + close_all(); + + if (nextin != 0) { + dup2(nextin, 0); + close(nextin); + } + if (nextout != 1) { + dup2(nextout, 1); + close(nextout); + } + if (pipefds[0]!=-1) { + close(pipefds[0]); /* opposite end of our output pipe */ + } + + /* Like bash, explicit redirects override pipes, + * and the pipe fd is available for dup'ing. */ + setup_redirects(child,NULL); + + if (interactive && pi->followup!=PIPE_BG) { + /* If we (the child) win the race, put ourselves in the process + * group whose leader is the first process in this pipe. */ + if (pi->pgrp < 0) { + pi->pgrp = getpid(); + } + if (setpgid(0, pi->pgrp) == 0) { + tcsetpgrp(2, pi->pgrp); + } + } + + pseudo_exec(child); + } + + + /* put our child in the process group whose leader is the + first process in this pipe */ + if (pi->pgrp < 0) { + pi->pgrp = child->pid; + } + /* Don't check for errors. The child may be dead already, + * in which case setpgid returns error code EACCES. */ + setpgid(child->pid, pi->pgrp); + + if (nextin != 0) + close(nextin); + if (nextout != 1) + close(nextout); + + /* If there isn't another process, nextin is garbage + but it doesn't matter */ + nextin = pipefds[0]; + } +#endif + return -1; +} + +static int run_list_real(struct pipe *pi) +{ + int rcode=0; + int if_code=0, next_if_code=0; /* need double-buffer to handle elif */ + reserved_style rmode, skip_more_in_this_rmode=RES_XXXX; + for (;pi;pi=pi->next) { + rmode = pi->r_mode; + debug_printf("rmode=%d if_code=%d next_if_code=%d skip_more=%d\n", rmode, if_code, next_if_code, skip_more_in_this_rmode); + if (rmode == skip_more_in_this_rmode) continue; + skip_more_in_this_rmode = RES_XXXX; + if (rmode == RES_THEN || rmode == RES_ELSE) if_code = next_if_code; + if (rmode == RES_THEN && if_code) continue; + if (rmode == RES_ELSE && !if_code) continue; + if (rmode == RES_ELIF && !if_code) continue; + if (pi->num_progs == 0) continue; + rcode = run_pipe_real(pi); + debug_printf("run_pipe_real returned %d\n",rcode); +#ifndef __PPCBOOT__ + if (rcode!=-1) { + /* We only ran a builtin: rcode was set by the return value + * of run_pipe_real(), and we don't need to wait for anything. */ + } else if (pi->followup==PIPE_BG) { + /* XXX check bash's behavior with nontrivial pipes */ + /* XXX compute jobid */ + /* XXX what does bash do with attempts to background builtins? */ + insert_bg_job(pi); + rcode = EXIT_SUCCESS; + } else { + if (interactive) { + /* move the new process group into the foreground */ + if (tcsetpgrp(shell_terminal, pi->pgrp) && errno != ENOTTY) + perror_msg("tcsetpgrp-3"); + rcode = checkjobs(pi); + /* move the shell to the foreground */ + if (tcsetpgrp(shell_terminal, getpgid(0)) && errno != ENOTTY) + perror_msg("tcsetpgrp-4"); + } else { + rcode = checkjobs(pi); + } + debug_printf("checkjobs returned %d\n",rcode); + } +#endif + last_return_code=rcode; + if ( rmode == RES_IF || rmode == RES_ELIF ) + next_if_code=rcode; /* can be overwritten a number of times */ + if ( (rcode==EXIT_SUCCESS && pi->followup==PIPE_OR) || + (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) ) + skip_more_in_this_rmode=rmode; +#ifndef __PPCBOOT__ + checkjobs(NULL); +#endif + } + return rcode; +} + +/* broken, of course, but OK for testing */ +static char *indenter(int i) +{ + static char blanks[]=" "; + return &blanks[sizeof(blanks)-i-1]; +} + +/* return code is the exit status of the pipe */ +static int free_pipe(struct pipe *pi, int indent) +{ + char **p; + struct child_prog *child; +#ifndef __PPCBOOT__ + struct redir_struct *r, *rnext; +#endif + int a, i, ret_code=0; + char *ind = indenter(indent); +#ifndef __PPCBOOT__ + if (pi->stopped_progs > 0) + return ret_code; + final_printf("%s run pipe: (pid %d)\n",ind,getpid()); +#endif + for (i=0; inum_progs; i++) { + child = &pi->progs[i]; + final_printf("%s command %d:\n",ind,i); + if (child->argv) { + for (a=0,p=child->argv; *p; a++,p++) { + final_printf("%s argv[%d] = %s\n",ind,a,*p); + } +#ifndef __PPCBOOT__ + globfree(&child->glob_result); +#else + for (a = child->argc;a >= 0;a--) { + free(child->argv[a]); + } + free(child->argv); + child->argc = 0; +#endif + child->argv=NULL; + } else if (child->group) { +#ifndef __PPCBOOT__ + final_printf("%s begin group (subshell:%d)\n",ind, child->subshell); +#endif + ret_code = free_pipe_list(child->group,indent+3); + final_printf("%s end group\n",ind); + } else { + final_printf("%s (nil)\n",ind); + } +#ifndef __PPCBOOT__ + for (r=child->redirects; r; r=rnext) { + + final_printf("%s redirect %d%s", ind, r->fd, redir_table[r->type].descrip); + + if (r->dup == -1) { + /* guard against the case >$FOO, where foo is unset or blank */ + if (r->word.gl_pathv) { + final_printf(" %s\n", *r->word.gl_pathv); + globfree(&r->word); + } + } else { + final_printf("&%d\n", r->dup); + } + rnext=r->next; + free(r); + } + child->redirects=NULL; +#endif + } + free(pi->progs); /* children are an array, they get freed all at once */ + pi->progs=NULL; + return ret_code; +} + +static int free_pipe_list(struct pipe *head, int indent) +{ + int rcode=0; /* if list has no members */ + struct pipe *pi, *next; + char *ind = indenter(indent); + for (pi=head; pi; pi=next) { + final_printf("%s pipe reserved mode %d\n", ind, pi->r_mode); + rcode = free_pipe(pi, indent); + final_printf("%s pipe followup code %d\n", ind, pi->followup); + next=pi->next; + pi->next=NULL; + free(pi); + } + return rcode; +} + +/* Select which version we will use */ +static int run_list(struct pipe *pi) +{ + int rcode=0; +#ifndef __PPCBOOT__ + if (fake_mode==0) { +#endif + rcode = run_list_real(pi); +#ifndef __PPCBOOT__ + } +#endif + /* free_pipe_list has the side effect of clearing memory + * In the long run that function can be merged with run_list_real, + * but doing that now would hobble the debugging effort. */ + free_pipe_list(pi,0); + return rcode; +} + +/* The API for glob is arguably broken. This routine pushes a non-matching + * string into the output structure, removing non-backslashed backslashes. + * If someone can prove me wrong, by performing this function within the + * original glob(3) api, feel free to rewrite this routine into oblivion. + * Return code (0 vs. GLOB_NOSPACE) matches glob(3). + * XXX broken if the last character is '\\', check that before calling. + */ +#ifndef __PPCBOOT__ +static int globhack(const char *src, int flags, glob_t *pglob) +{ + int cnt=0, pathc; + const char *s; + char *dest; + for (cnt=1, s=src; s && *s; s++) { + if (*s == '\\') s++; + cnt++; + } + dest = malloc(cnt); + if (!dest) return GLOB_NOSPACE; + if (!(flags & GLOB_APPEND)) { + pglob->gl_pathv=NULL; + pglob->gl_pathc=0; + pglob->gl_offs=0; + pglob->gl_offs=0; + } + pathc = ++pglob->gl_pathc; + pglob->gl_pathv = realloc(pglob->gl_pathv, (pathc+1)*sizeof(*pglob->gl_pathv)); + if (pglob->gl_pathv == NULL) return GLOB_NOSPACE; + pglob->gl_pathv[pathc-1]=dest; + pglob->gl_pathv[pathc]=NULL; + for (s=src; s && *s; s++, dest++) { + if (*s == '\\') s++; + *dest = *s; + } + *dest='\0'; + return 0; +} + +/* XXX broken if the last character is '\\', check that before calling */ +static int glob_needed(const char *s) +{ + for (; *s; s++) { + if (*s == '\\') s++; + if (strchr("*[?",*s)) return 1; + } + return 0; +} + +#if 0 +static void globprint(glob_t *pglob) +{ + int i; + debug_printf("glob_t at %p:\n", pglob); + debug_printf(" gl_pathc=%d gl_pathv=%p gl_offs=%d gl_flags=%d\n", + pglob->gl_pathc, pglob->gl_pathv, pglob->gl_offs, pglob->gl_flags); + for (i=0; igl_pathc; i++) + debug_printf("pglob->gl_pathv[%d] = %p = %s\n", i, + pglob->gl_pathv[i], pglob->gl_pathv[i]); +} +#endif +static int xglob(o_string *dest, int flags, glob_t *pglob) +{ + int gr; + + /* short-circuit for null word */ + /* we can code this better when the debug_printf's are gone */ + if (dest->length == 0) { + if (dest->nonnull) { + /* bash man page calls this an "explicit" null */ + gr = globhack(dest->data, flags, pglob); + debug_printf("globhack returned %d\n",gr); + } else { + return 0; + } + } else if (glob_needed(dest->data)) { + gr = glob(dest->data, flags, NULL, pglob); + debug_printf("glob returned %d\n",gr); + if (gr == GLOB_NOMATCH) { + /* quote removal, or more accurately, backslash removal */ + gr = globhack(dest->data, flags, pglob); + debug_printf("globhack returned %d\n",gr); + } + } else { + gr = globhack(dest->data, flags, pglob); + debug_printf("globhack returned %d\n",gr); + } + if (gr == GLOB_NOSPACE) + error_msg_and_die("out of memory during glob"); + if (gr != 0) { /* GLOB_ABORTED ? */ + error_msg("glob(3) error %d",gr); + } + /* globprint(glob_target); */ + return gr; +} +#endif +/* This is used to get/check local shell variables */ +static char *get_local_var(const char *s) +{ + struct variables *cur; + + if (!s) + return NULL; + for (cur = top_vars; cur; cur=cur->next) + if(strcmp(cur->name, s)==0) + return cur->value; + return NULL; +} + +/* This is used to set local shell variables + flg_export==0 if only local (not exporting) variable + flg_export==1 if "new" exporting environ + flg_export>1 if current startup environ (not call putenv()) */ +static int set_local_var(const char *s, int flg_export) +{ + char *name, *value; + int result=0; + struct variables *cur; + + name=strdup(s); + + /* Assume when we enter this function that we are already in + * NAME=VALUE format. So the first order of business is to + * split 's' on the '=' into 'name' and 'value' */ + value = strchr(name, '='); + if (value==0 && ++value==0) { + free(name); + return -1; + } + *value++ = 0; + + for(cur = top_vars; cur; cur = cur->next) { + if(strcmp(cur->name, name)==0) + break; + } + + if(cur) { + if(strcmp(cur->value, value)==0) { + if(flg_export>0 && cur->flg_export==0) + cur->flg_export=flg_export; + else + result++; + } else { + if(cur->flg_read_only) { + error_msg("%s: readonly variable", name); + result = -1; + } else { + if(flg_export>0 || cur->flg_export>1) + cur->flg_export=1; + free(cur->value); + + cur->value = strdup(value); + } + } + } else { + cur = malloc(sizeof(struct variables)); + if(!cur) { + result = -1; + } else { + cur->name = strdup(name); + if(cur->name == 0) { + free(cur); + result = -1; + } else { + struct variables *bottom = top_vars; + cur->value = strdup(value); + cur->next = 0; + cur->flg_export = flg_export; + cur->flg_read_only = 0; + while(bottom->next) bottom=bottom->next; + bottom->next = cur; + } + } + } +#ifndef __PPCBOOT__ + if(result==0 && cur->flg_export==1) { + *(value-1) = '='; + result = putenv(name); + } else { +#endif + free(name); +#ifndef __PPCBOOT__ + if(result>0) /* equivalent to previous set */ + result = 0; + } +#endif + return result; +} +#ifndef __PPCBOOT__ +static void unset_local_var(const char *name) +{ + struct variables *cur; + + if (name) { + for (cur = top_vars; cur; cur=cur->next) { + if(strcmp(cur->name, name)==0) + break; + } + if(cur!=0) { + struct variables *next = top_vars; + if(cur->flg_read_only) { + error_msg("%s: readonly variable", name); + return; + } else { + if(cur->flg_export) + unsetenv(cur->name); + free(cur->name); + free(cur->value); + while (next->next != cur) + next = next->next; + next->next = cur->next; + } + free(cur); + } + } +} +#endif +static int is_assignment(const char *s) +{ + if (s==NULL || !isalpha(*s)) return 0; + ++s; + while(isalnum(*s) || *s=='_') ++s; + return *s=='='; +} +#ifndef __PPCBOOT__ +/* the src parameter allows us to peek forward to a possible &n syntax + * for file descriptor duplication, e.g., "2>&1". + * Return code is 0 normally, 1 if a syntax error is detected in src. + * Resource errors (in xmalloc) cause the process to exit */ +static int setup_redirect(struct p_context *ctx, int fd, redir_type style, + struct in_str *input) +{ + struct child_prog *child=ctx->child; + struct redir_struct *redir = child->redirects; + struct redir_struct *last_redir=NULL; + + /* Create a new redir_struct and drop it onto the end of the linked list */ + while(redir) { + last_redir=redir; + redir=redir->next; + } + redir = xmalloc(sizeof(struct redir_struct)); + redir->next=NULL; + redir->word.gl_pathv=NULL; + if (last_redir) { + last_redir->next=redir; + } else { + child->redirects=redir; + } + + redir->type=style; + redir->fd= (fd==-1) ? redir_table[style].default_fd : fd ; + + debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip); + + /* Check for a '2>&1' type redirect */ + redir->dup = redirect_dup_num(input); + if (redir->dup == -2) return 1; /* syntax error */ + if (redir->dup != -1) { + /* Erik had a check here that the file descriptor in question + * is legit; I postpone that to "run time" + * A "-" representation of "close me" shows up as a -3 here */ + debug_printf("Duplicating redirect '%d>&%d'\n", redir->fd, redir->dup); + } else { + /* We do _not_ try to open the file that src points to, + * since we need to return and let src be expanded first. + * Set ctx->pending_redirect, so we know what to do at the + * end of the next parsed word. + */ + ctx->pending_redirect = redir; + } + return 0; +} +#endif +struct pipe *new_pipe(void) { + struct pipe *pi; + pi = xmalloc(sizeof(struct pipe)); + pi->num_progs = 0; + pi->progs = NULL; + pi->next = NULL; + pi->followup = 0; /* invalid */ + return pi; +} + +static void initialize_context(struct p_context *ctx) +{ + ctx->pipe=NULL; +#ifndef __PPCBOOT__ + ctx->pending_redirect=NULL; +#endif + ctx->child=NULL; + ctx->list_head=new_pipe(); + ctx->pipe=ctx->list_head; + ctx->w=RES_NONE; + ctx->stack=NULL; +#ifdef __PPCBOOT__ + ctx->old_flag=0; +#endif + done_command(ctx); /* creates the memory for working child */ +} + +/* normal return is 0 + * if a reserved word is found, and processed, return 1 + * should handle if, then, elif, else, fi, for, while, until, do, done. + * case, function, and select are obnoxious, save those for later. + */ +int reserved_word(o_string *dest, struct p_context *ctx) +{ + struct reserved_combo { + char *literal; + int code; + long flag; + }; + /* Mostly a list of accepted follow-up reserved words. + * FLAG_END means we are done with the sequence, and are ready + * to turn the compound list into a command. + * FLAG_START means the word must start a new compound list. + */ + static struct reserved_combo reserved_list[] = { + { "if", RES_IF, FLAG_THEN | FLAG_START }, + { "then", RES_THEN, FLAG_ELIF | FLAG_ELSE | FLAG_FI }, + { "elif", RES_ELIF, FLAG_THEN }, + { "else", RES_ELSE, FLAG_FI }, + { "fi", RES_FI, FLAG_END }, +#ifndef __PPCBOOT__ + { "for", RES_FOR, FLAG_DO | FLAG_START }, + { "while", RES_WHILE, FLAG_DO | FLAG_START }, + { "until", RES_UNTIL, FLAG_DO | FLAG_START }, + { "do", RES_DO, FLAG_DONE }, + { "done", RES_DONE, FLAG_END } +#endif + }; + struct reserved_combo *r; + for (r=reserved_list; +#define NRES sizeof(reserved_list)/sizeof(struct reserved_combo) + rdata, r->literal) == 0) { + debug_printf("found reserved word %s, code %d\n",r->literal,r->code); + if (r->flag & FLAG_START) { + struct p_context *new = xmalloc(sizeof(struct p_context)); + debug_printf("push stack\n"); + *new = *ctx; /* physical copy */ + initialize_context(ctx); + ctx->stack=new; + } else if ( ctx->w == RES_NONE || ! (ctx->old_flag & (1<code))) { + syntax(); + ctx->w = RES_SNTX; + b_reset (dest); + return 1; + } + ctx->w=r->code; + ctx->old_flag = r->flag; + if (ctx->old_flag & FLAG_END) { + struct p_context *old; + debug_printf("pop stack\n"); + old = ctx->stack; + old->child->group = ctx->list_head; +#ifndef __PPCBOOT__ + old->child->subshell = 0; +#endif + *ctx = *old; /* physical copy */ + free(old); + } + b_reset (dest); + return 1; + } + } + return 0; +} + +/* normal return is 0. + * Syntax or xglob errors return 1. */ +static int done_word(o_string *dest, struct p_context *ctx) +{ + struct child_prog *child=ctx->child; +#ifndef __PPCBOOT__ + glob_t *glob_target; + int gr, flags = 0; +#else + char *str; + int argc; +#endif + + debug_printf("done_word: %s %p\n", dest->data, child); + if (dest->length == 0 && !dest->nonnull) { + debug_printf(" true null, ignored\n"); + return 0; + } +#ifndef __PPCBOOT__ + if (ctx->pending_redirect) { + glob_target = &ctx->pending_redirect->word; + } else { +#endif + if (child->group) { + syntax(); + return 1; /* syntax error, groups and arglists don't mix */ + } + if (!child->argv) { + debug_printf("checking %s for reserved-ness\n",dest->data); + if (reserved_word(dest,ctx)) return ctx->w==RES_SNTX; + } +#ifndef __PPCBOOT__ + glob_target = &child->glob_result; + if (child->argv) flags |= GLOB_APPEND; +#else + str = malloc((strlen(dest->data) + 1)); + if (!str) return 1; + if ( child->argv == NULL) { + child->argc=0; + } + argc = ++child->argc; + child->argv = realloc(child->argv, (argc+1)*sizeof(*child->argv)); + if (child->argv == NULL) return 1; + child->argv[argc-1]=str; + child->argv[argc]=NULL; + strcpy(str,dest->data); +#endif +#ifndef __PPCBOOT__ + } + gr = xglob(dest, flags, glob_target); + if (gr != 0) return 1; +#endif + b_reset(dest); +#ifndef __PPCBOOT__ + if (ctx->pending_redirect) { + ctx->pending_redirect=NULL; + if (glob_target->gl_pathc != 1) { + error_msg("ambiguous redirect"); + return 1; + } + } else { + child->argv = glob_target->gl_pathv; + } +#endif + return 0; +} + +/* The only possible error here is out of memory, in which case + * xmalloc exits. */ +static int done_command(struct p_context *ctx) +{ + /* The child is really already in the pipe structure, so + * advance the pipe counter and make a new, null child. + * Only real trickiness here is that the uncommitted + * child structure, to which ctx->child points, is not + * counted in pi->num_progs. */ + struct pipe *pi=ctx->pipe; + struct child_prog *prog=ctx->child; + + if (prog && prog->group == NULL + && prog->argv == NULL +#ifndef __PPCBOOT__ + && prog->redirects == NULL) { +#else + ) { +#endif + debug_printf("done_command: skipping null command\n"); + return 0; + } else if (prog) { + pi->num_progs++; + debug_printf("done_command: num_progs incremented to %d\n",pi->num_progs); + } else { + debug_printf("done_command: initializing\n"); + } + pi->progs = xrealloc(pi->progs, sizeof(*pi->progs) * (pi->num_progs+1)); + prog = pi->progs + pi->num_progs; +#ifndef __PPCBOOT__ + prog->redirects = NULL; +#endif + prog->argv = NULL; +#ifndef __PPCBOOT__ + prog->is_stopped = 0; +#endif + prog->group = NULL; +#ifndef __PPCBOOT__ + prog->glob_result.gl_pathv = NULL; + prog->family = pi; +#endif + ctx->child=prog; + /* but ctx->pipe and ctx->list_head remain unchanged */ + return 0; +} + +static int done_pipe(struct p_context *ctx, pipe_style type) +{ + struct pipe *new_p; + done_command(ctx); /* implicit closure of previous command */ + debug_printf("done_pipe, type %d\n", type); + ctx->pipe->followup = type; + ctx->pipe->r_mode = ctx->w; + new_p=new_pipe(); + ctx->pipe->next = new_p; + ctx->pipe = new_p; + ctx->child = NULL; + done_command(ctx); /* set up new pipe to accept commands */ + return 0; +} +#ifndef __PPCBOOT__ +/* peek ahead in the in_str to find out if we have a "&n" construct, + * as in "2>&1", that represents duplicating a file descriptor. + * returns either -2 (syntax error), -1 (no &), or the number found. + */ +static int redirect_dup_num(struct in_str *input) +{ + int ch, d=0, ok=0; + ch = b_peek(input); + if (ch != '&') return -1; + + b_getch(input); /* get the & */ + ch=b_peek(input); + if (ch == '-') { + b_getch(input); + return -3; /* "-" represents "close me" */ + } + while (isdigit(ch)) { + d = d*10+(ch-'0'); + ok=1; + b_getch(input); + ch = b_peek(input); + } + if (ok) return d; + + error_msg("ambiguous redirect"); + return -2; +} + +/* If a redirect is immediately preceded by a number, that number is + * supposed to tell which file descriptor to redirect. This routine + * looks for such preceding numbers. In an ideal world this routine + * needs to handle all the following classes of redirects... + * echo 2>foo # redirects fd 2 to file "foo", nothing passed to echo + * echo 49>foo # redirects fd 49 to file "foo", nothing passed to echo + * echo -2>foo # redirects fd 1 to file "foo", "-2" passed to echo + * echo 49x>foo # redirects fd 1 to file "foo", "49x" passed to echo + * A -1 output from this program means no valid number was found, so the + * caller should use the appropriate default for this redirection. + */ +static int redirect_opt_num(o_string *o) +{ + int num; + + if (o->length==0) return -1; + for(num=0; numlength; num++) { + if (!isdigit(*(o->data+num))) { + return -1; + } + } + /* reuse num (and save an int) */ + num=atoi(o->data); + b_reset(o); + return num; +} + +FILE *generate_stream_from_list(struct pipe *head) +{ + FILE *pf; +#if 1 + int pid, channel[2]; + if (pipe(channel)<0) perror_msg_and_die("pipe"); + pid=fork(); + if (pid<0) { + perror_msg_and_die("fork"); + } else if (pid==0) { + close(channel[0]); + if (channel[1] != 1) { + dup2(channel[1],1); + close(channel[1]); + } +#if 0 +#define SURROGATE "surrogate response" + write(1,SURROGATE,sizeof(SURROGATE)); + _exit(run_list(head)); +#else + _exit(run_list_real(head)); /* leaks memory */ +#endif + } + debug_printf("forked child %d\n",pid); + close(channel[1]); + pf = fdopen(channel[0],"r"); + debug_printf("pipe on FILE *%p\n",pf); +#else + free_pipe_list(head,0); + pf=popen("echo surrogate response","r"); + debug_printf("started fake pipe on FILE *%p\n",pf); +#endif + return pf; +} + +/* this version hacked for testing purposes */ +/* return code is exit status of the process that is run. */ +static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, int subst_end) +{ + int retcode; + o_string result=NULL_O_STRING; + struct p_context inner; + FILE *p; + struct in_str pipe_str; + initialize_context(&inner); + + /* recursion to generate command */ + retcode = parse_stream(&result, &inner, input, subst_end); + if (retcode != 0) return retcode; /* syntax error or EOF */ + done_word(&result, &inner); + done_pipe(&inner, PIPE_SEQ); + b_free(&result); + + p=generate_stream_from_list(inner.list_head); + if (p==NULL) return 1; + mark_open(fileno(p)); + setup_file_in_str(&pipe_str, p); + + /* now send results of command back into original context */ + retcode = parse_stream(dest, ctx, &pipe_str, '\0'); + /* XXX In case of a syntax error, should we try to kill the child? + * That would be tough to do right, so just read until EOF. */ + if (retcode == 1) { + while (b_getch(&pipe_str)!=EOF) { /* discard */ }; + } + + debug_printf("done reading from pipe, pclose()ing\n"); + /* This is the step that wait()s for the child. Should be pretty + * safe, since we just read an EOF from its stdout. We could try + * to better, by using wait(), and keeping track of background jobs + * at the same time. That would be a lot of work, and contrary + * to the KISS philosophy of this program. */ + mark_closed(fileno(p)); + retcode=pclose(p); + free_pipe_list(inner.list_head,0); + debug_printf("pclosed, retcode=%d\n",retcode); + /* XXX this process fails to trim a single trailing newline */ + return retcode; +} + +static int parse_group(o_string *dest, struct p_context *ctx, + struct in_str *input, int ch) +{ + int rcode, endch=0; + struct p_context sub; + struct child_prog *child = ctx->child; + if (child->argv) { + syntax(); + return 1; /* syntax error, groups and arglists don't mix */ + } + initialize_context(&sub); + switch(ch) { + case '(': endch=')'; child->subshell=1; break; + case '{': endch='}'; break; + default: syntax(); /* really logic error */ + } + rcode=parse_stream(dest,&sub,input,endch); + done_word(dest,&sub); /* finish off the final word in the subcontext */ + done_pipe(&sub, PIPE_SEQ); /* and the final command there, too */ + child->group = sub.list_head; + return rcode; + /* child remains "open", available for possible redirects */ +} +#endif + +/* basically useful version until someone wants to get fancier, + * see the bash man page under "Parameter Expansion" */ +static void lookup_param(o_string *dest, struct p_context *ctx, o_string *src) +{ + const char *p=NULL; +#ifndef __PPCBOOT__ + if (src->data) { + p = getenv(src->data); + if (!p) +#endif + p = get_local_var(src->data); +#ifndef __PPCBOOT__ + } +#endif + if (p) parse_string(dest, ctx, p); /* recursion */ + b_free(src); +} + +/* return code: 0 for OK, 1 for syntax error */ +static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input) +{ +#ifndef __PPCBOOT__ + int i, advance=0; +#else + int advance=0; +#endif + o_string alt=NULL_O_STRING; +#ifndef __PPCBOOT__ + char sep[]=" "; +#endif + int ch = input->peek(input); /* first character after the $ */ + debug_printf("handle_dollar: ch=%c\n",ch); + if (isalpha(ch)) { + while(ch=b_peek(input),isalnum(ch) || ch=='_') { + b_getch(input); + b_addchr(&alt,ch); + } + lookup_param(dest, ctx, &alt); +#ifndef __PPCBOOT__ + } else if (isdigit(ch)) { + i = ch-'0'; /* XXX is $0 special? */ + if (i 0) b_adduint(dest, last_bg_pid); + advance = 1; + break; +#endif + case '?': + b_adduint(dest,last_return_code); + advance = 1; + break; +#ifndef __PPCBOOT__ + case '#': + b_adduint(dest,global_argc ? global_argc-1 : 0); + advance = 1; + break; +#endif + case '{': + b_getch(input); + /* XXX maybe someone will try to escape the '}' */ + while(ch=b_getch(input),ch!=EOF && ch!='}') { + b_addchr(&alt,ch); + } + if (ch != '}') { + syntax(); + return 1; + } + lookup_param(dest, ctx, &alt); + break; +#ifndef __PPCBOOT__ + case '(': + b_getch(input); + process_command_subs(dest, ctx, input, ')'); + break; + case '*': + sep[0]=ifs[0]; + for (i=1; iquote); + } + /* Eat the character if the flag was set. If the compiler + * is smart enough, we could substitute "b_getch(input);" + * for all the "advance = 1;" above, and also end up with + * a nice size-optimized program. Hah! That'll be the day. + */ + if (advance) b_getch(input); + return 0; +} + +int parse_string(o_string *dest, struct p_context *ctx, const char *src) +{ + struct in_str foo; + setup_string_in_str(&foo, src); + return parse_stream(dest, ctx, &foo, '\0'); +} + +/* return code is 0 for normal exit, 1 for syntax error */ +int parse_stream(o_string *dest, struct p_context *ctx, + struct in_str *input, int end_trigger) +{ + unsigned int ch, m; +#ifndef __PPCBOOT__ + int redir_fd; + redir_type redir_style; +#endif + int next; + + /* Only double-quote state is handled in the state variable dest->quote. + * A single-quote triggers a bypass of the main loop until its mate is + * found. When recursing, quote state is passed in via dest->quote. */ + + debug_printf("parse_stream, end_trigger=%d\n",end_trigger); + while ((ch=b_getch(input))!=EOF) { + m = map[ch]; + next = (ch == '\n') ? 0 : b_peek(input); + debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d\n", + ch,ch,m,dest->quote); + if (m==0 || ((m==1 || m==2) && dest->quote)) { + b_addqchr(dest, ch, dest->quote); + } else { + if (m==2) { /* unquoted IFS */ +#ifndef __PPCBOOT__ + done_word(dest, ctx); +#else + if (done_word(dest, ctx)) { + return 1; + } +#endif + /* If we aren't performing a substitution, treat a newline as a + * command separator. */ + if (end_trigger != '\0' && ch=='\n') + done_pipe(ctx,PIPE_SEQ); + } + if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) { + debug_printf("leaving parse_stream (triggered)\n"); + return 0; + } +#if 0 + if (ch=='\n') { + /* Yahoo! Time to run with it! */ + done_pipe(ctx,PIPE_SEQ); + run_list(ctx->list_head); + initialize_context(ctx); + } +#endif + if (m!=2) switch (ch) { + case '#': + if (dest->length == 0 && !dest->quote) { + while(ch=b_peek(input),ch!=EOF && ch!='\n') { b_getch(input); } + } else { + b_addqchr(dest, ch, dest->quote); + } + break; +#ifndef __PPCBOOT__ + case '\\': + if (next == EOF) { + syntax(); + return 1; + } + b_addqchr(dest, '\\', dest->quote); + b_addqchr(dest, b_getch(input), dest->quote); + break; +#endif + case '$': + if (handle_dollar(dest, ctx, input)!=0) return 1; + break; +#ifndef __PPCBOOT__ + case '\'': + dest->nonnull = 1; + while(ch=b_getch(input),ch!=EOF && ch!='\'') { + b_addchr(dest,ch); + } + if (ch==EOF) { + syntax(); + return 1; + } + break; +#endif + case '"': + dest->nonnull = 1; + dest->quote = !dest->quote; + break; +#ifndef __PPCBOOT__ + case '`': + process_command_subs(dest, ctx, input, '`'); + break; + case '>': + redir_fd = redirect_opt_num(dest); + done_word(dest, ctx); + redir_style=REDIRECT_OVERWRITE; + if (next == '>') { + redir_style=REDIRECT_APPEND; + b_getch(input); + } else if (next == '(') { + syntax(); /* until we support >(list) Process Substitution */ + return 1; + } + setup_redirect(ctx, redir_fd, redir_style, input); + break; + case '<': + redir_fd = redirect_opt_num(dest); + done_word(dest, ctx); + redir_style=REDIRECT_INPUT; + if (next == '<') { + redir_style=REDIRECT_HEREIS; + b_getch(input); + } else if (next == '>') { + redir_style=REDIRECT_IO; + b_getch(input); + } else if (next == '(') { + syntax(); /* until we support <(list) Process Substitution */ + return 1; + } + setup_redirect(ctx, redir_fd, redir_style, input); + break; +#endif + case ';': + done_word(dest, ctx); + done_pipe(ctx,PIPE_SEQ); + break; + case '&': + done_word(dest, ctx); + if (next=='&') { + b_getch(input); + done_pipe(ctx,PIPE_AND); + } else { +#ifndef __PPCBOOT__ + done_pipe(ctx,PIPE_BG); +#else + syntax_err(); + return 1; + +#endif + } + break; + case '|': + done_word(dest, ctx); + if (next=='|') { + b_getch(input); + done_pipe(ctx,PIPE_OR); + } else { + /* we could pick up a file descriptor choice here + * with redirect_opt_num(), but bash doesn't do it. + * "echo foo 2| cat" yields "foo 2". */ +#ifndef __PPCBOOT__ + done_command(ctx); +#else + syntax_err(); + return 1; +#endif + } + break; +#ifndef __PPCBOOT__ + case '(': + case '{': + if (parse_group(dest, ctx, input, ch)!=0) return 1; + break; + case ')': + case '}': + syntax(); /* Proper use of this character caught by end_trigger */ + return 1; + break; +#endif + default: + syntax(); /* this is really an internal logic error */ + return 1; + } + } + } + /* complain if quote? No, maybe we just finished a command substitution + * that was quoted. Example: + * $ echo "`cat foo` plus more" + * and we just got the EOF generated by the subshell that ran "cat foo" + * The only real complaint is if we got an EOF when end_trigger != '\0', + * that is, we were really supposed to get end_trigger, and never got + * one before the EOF. Can't use the standard "syntax error" return code, + * so that parse_stream_outer can distinguish the EOF and exit smoothly. */ + debug_printf("leaving parse_stream (EOF)\n"); + if (end_trigger != '\0') return -1; + return 0; +} + +void mapset(const unsigned char *set, int code) +{ + const unsigned char *s; + for (s=set; *s; s++) map[*s] = code; +} + +void update_ifs_map(void) +{ + /* char *ifs and char map[256] are both globals. */ + ifs = getenv("IFS"); + if (ifs == NULL) ifs=" \t\n"; + /* Precompute a list of 'flow through' behavior so it can be treated + * quickly up front. Computation is necessary because of IFS. + * Special case handling of IFS == " \t\n" is not implemented. + * The map[] array only really needs two bits each, and on most machines + * that would be faster because of the reduced L1 cache footprint. + */ + memset(map,0,sizeof(map)); /* most characters flow through always */ +#ifndef __PPCBOOT__ + mapset("\\$'\"`", 3); /* never flow through */ + mapset("<>;&|(){}#", 1); /* flow through if quoted */ +#else + mapset("$'\"", 3); /* never flow through */ + mapset(";&|#", 1); /* flow through if quoted */ +#endif + mapset(ifs, 2); /* also flow through if quoted */ +} + +/* most recursion does not come through here, the exeception is + * from builtin_source() */ +int parse_stream_outer(struct in_str *inp) +{ + + struct p_context ctx; + o_string temp=NULL_O_STRING; + int rcode; + do { + initialize_context(&ctx); + update_ifs_map(); + inp->promptmode=1; + rcode = parse_stream(&temp, &ctx, inp, '\n'); +#ifdef __PPCBOOT__ + if (rcode != 1) { +#endif + done_word(&temp, &ctx); + done_pipe(&ctx,PIPE_SEQ); + run_list(ctx.list_head); + b_free(&temp); +#ifdef __PPCBOOT__ + } else { + if (ctx.old_flag != 0) { + free(ctx.stack); + b_reset(&temp); + } + inp->p = NULL; + free_pipe_list(ctx.list_head,0); + b_free(&temp); + } +#endif + } while (rcode != -1); /* loop on syntax errors, return on EOF */ + return 0; +} +#ifndef __PPCBOOT__ +static int parse_string_outer(const char *s) +{ + struct in_str input; + setup_string_in_str(&input, s); + return parse_stream_outer(&input); +} +#endif +#ifndef __PPCBOOT__ +static int parse_file_outer(FILE *f) +#else +static int parse_file_outer(void) +#endif +{ + int rcode; + struct in_str input; +#ifndef __PPCBOOT__ + setup_file_in_str(&input, f); +#else + setup_file_in_str(&input); +#endif + rcode = parse_stream_outer(&input); + return rcode; +} +#ifdef __PPCBOOT__ + +int ppcboot_hush_start(bd_t *bd) +{ + extern bd_t *BD; + + BD = bd; + parse_file_outer(); + return 1; +} +#endif +#ifndef __PPCBOOT__ +/* Make sure we have a controlling tty. If we get started under a job + * aware app (like bash for example), make sure we are now in charge so + * we don't fight over who gets the foreground */ +static void setup_job_control() +{ + static pid_t shell_pgrp; + /* Loop until we are in the foreground. */ + while (tcgetpgrp (shell_terminal) != (shell_pgrp = getpgrp ())) + kill (- shell_pgrp, SIGTTIN); + + /* Ignore interactive and job-control signals. */ + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGTERM, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + signal(SIGCHLD, SIG_IGN); + + /* Put ourselves in our own process group. */ + setsid(); + shell_pgrp = getpid (); + setpgid (shell_pgrp, shell_pgrp); + + /* Grab control of the terminal. */ + tcsetpgrp(shell_terminal, shell_pgrp); +} + +int hush_main(int argc, char **argv) +{ + int opt; + FILE *input; + char **e = environ; + + /* XXX what should these be while sourcing /etc/profile? */ + global_argc = argc; + global_argv = argv; + + /* (re?) initialize globals. Sometimes hush_main() ends up calling + * hush_main(), therefore we cannot rely on the BSS to zero out this + * stuff. Reset these to 0 every time. */ + ifs = NULL; + /* map[] is taken care of with call to update_ifs_map() */ + fake_mode = 0; + interactive = 0; + close_me_head = NULL; + last_bg_pid = 0; + job_list = NULL; + last_jobid = 0; + + /* Initialize some more globals to non-zero values */ + set_cwd(); +#ifdef BB_FEATURE_COMMAND_EDITING + cmdedit_set_initial_prompt(); +#else + PS1 = NULL; +#endif + PS2 = "> "; + + /* initialize our shell local variables with the values + * currently living in the environment */ + if (e) { + for (; *e; e++) + set_local_var(*e, 2); /* without call putenv() */ + } + + last_return_code=EXIT_SUCCESS; + + + if (argv[0] && argv[0][0] == '-') { + debug_printf("\nsourcing /etc/profile\n"); + if ((input = fopen("/etc/profile", "r")) != NULL) { + mark_open(fileno(input)); + parse_file_outer(input); + mark_closed(fileno(input)); + fclose(input); + } + } + input=stdin; + + while ((opt = getopt(argc, argv, "c:xif")) > 0) { + switch (opt) { + case 'c': + { + global_argv = argv+optind; + global_argc = argc-optind; + opt = parse_string_outer(optarg); + goto final_return; + } + break; + case 'i': + interactive++; + break; + case 'f': + fake_mode++; + break; + default: +#ifndef BB_VER + fprintf(stderr, "Usage: sh [FILE]...\n" + " or: sh -c command [args]...\n\n"); + exit(EXIT_FAILURE); +#else + show_usage(); +#endif + } + } + /* A shell is interactive if the `-i' flag was given, or if all of + * the following conditions are met: + * no -c command + * no arguments remaining or the -s flag given + * standard input is a terminal + * standard output is a terminal + * Refer to Posix.2, the description of the `sh' utility. */ + if (argv[optind]==NULL && input==stdin && + isatty(fileno(stdin)) && isatty(fileno(stdout))) { + interactive++; + } + + debug_printf("\ninteractive=%d\n", interactive); + if (interactive) { + /* Looks like they want an interactive shell */ + fprintf(stdout, "\nhush -- the humble shell v0.01 (testing)\n\n"); + setup_job_control(); + } + + if (argv[optind]==NULL) { + opt=parse_file_outer(stdin); + goto final_return; + } + + debug_printf("\nrunning script '%s'\n", argv[optind]); + global_argv = argv+optind; + global_argc = argc-optind; + input = xfopen(argv[optind], "r"); + opt = parse_file_outer(input); + +#ifdef BB_FEATURE_CLEAN_UP + fclose(input); + if (cwd && cwd != unknown) + free((char*)cwd); + { + struct variables *cur, *tmp; + for(cur = top_vars; cur; cur = tmp) { + tmp = cur->next; + if (!cur->flg_read_only) { + free(cur->name); + free(cur->value); + free(cur); + } + } + } +#endif + +final_return: + return(opt?opt:last_return_code); +} +#endif +#endif /* CFG_HUSH_PARSER */ +/****************************************************************************/ diff --git a/common/kgdb.c b/common/kgdb.c index 0cb3760..9a7dfad 100644 --- a/common/kgdb.c +++ b/common/kgdb.c @@ -564,12 +564,13 @@ breakpoint(void) kgdb_breakpoint(bd_ptr, 0, 0); } -void +int do_kgdb(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { printf("Entering KGDB mode via exception handler...\n\n"); kgdb_breakpoint(bd, argc - 1, argv + 1); printf("\nReturned from KGDB mode\n"); + return 0; } #else diff --git a/common/main.c b/common/main.c index d084316..c575202 100644 --- a/common/main.c +++ b/common/main.c @@ -29,6 +29,10 @@ #include /* for do_reset() prototype */ #endif +#ifdef CFG_HUSH_PARSER +int ppcboot_hush_start(bd_t *bd); +#endif + static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen); static int parse_line (char *, char *[]); #if (CONFIG_BOOTDELAY >= 0) @@ -188,10 +192,12 @@ static __inline__ int abortboot(int bootdelay) void main_loop(bd_t *bd) { +#ifndef CFG_HUSH_PARSER static char lastcommand[CFG_CBSIZE] = { 0, }; int len; int rc = 1; int flag; +#endif #if (CONFIG_BOOTDELAY >= 0) char *s; @@ -247,6 +253,11 @@ void main_loop(bd_t *bd) /* * Main Loop for Monitor Command Processing */ +#ifdef CFG_HUSH_PARSER + ppcboot_hush_start(bd); + /* This point is never reached */ + for (;;); +#else for (;;) { #ifdef CONFIG_BOOT_RETRY_TIME if (rc >= 0) { @@ -287,6 +298,7 @@ void main_loop(bd_t *bd) lastcommand[0] = 0; } } +#endif /*CFG_HUSH_PARSER*/ } /*************************************************************************** @@ -687,17 +699,20 @@ int run_command (const char *cmd, bd_t *bd, int flag) /****************************************************************************/ #if (CONFIG_COMMANDS & CFG_CMD_RUN) -void do_run (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) +int do_run (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) { int i; + int rcode = 1; if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); - return; + return 1; } for (i=1; i= TOUT_LOOP) ? I2CERR_TIMEOUT : 0; } -void +int i2c_read(uchar *addr, int alen, uchar *buffer, int len) { i2c_state_t state; @@ -523,23 +523,24 @@ i2c_read(uchar *addr, int alen, uchar *buffer, int len) rc = i2c_send(&state, *addr, 0, I2CF_START_COND, alen - 1, addr + 1); if (rc != 0) { printf("i2c_read: i2c_send failed (%d)\n", rc); - return; + return 1; } rc = i2c_receive(&state, *addr, 0, I2CF_STOP_COND, len, buffer); if (rc != 0) { printf("i2c_read: i2c_receive failed (%d)\n", rc); - return; + return 1; } rc = i2c_doio(&state); if (rc != 0) { printf("i2c_read: i2c_doio failed (%d)\n", rc); - return; + return 1; } + return 0; } -void +int i2c_write(uchar *addr, int alen, uchar *buffer, int len) { i2c_state_t state; @@ -550,20 +551,21 @@ i2c_write(uchar *addr, int alen, uchar *buffer, int len) rc = i2c_send(&state, *addr, 0, I2CF_START_COND, alen - 1, addr + 1); if (rc != 0) { printf("i2c_write: first i2c_send failed (%d)\n", rc); - return; + return 1; } rc = i2c_send(&state, 0, 0, I2CF_STOP_COND, len, buffer); if (rc != 0) { printf("i2c_write: second i2c_send failed (%d)\n", rc); - return; + return 1; } rc = i2c_doio(&state); if (rc != 0) { printf("i2c_write: i2c_doio failed (%d)\n", rc); - return; + return 1; } + return 0; } uchar diff --git a/cpu/mpc8260/soft_i2c.c b/cpu/mpc8260/soft_i2c.c index c4a561c..b724269 100644 --- a/cpu/mpc8260/soft_i2c.c +++ b/cpu/mpc8260/soft_i2c.c @@ -317,7 +317,7 @@ void i2c_init (int speed, int slaveaddr) * capable of reading `len' sequential bytes; no * checking is doen here */ -void i2c_read (uchar *addr, int alen, uchar *buffer, int len) +int i2c_read (uchar *addr, int alen, uchar *buffer, int len) { uchar *ap = addr; @@ -332,9 +332,10 @@ void i2c_read (uchar *addr, int alen, uchar *buffer, int len) *buffer++ = read_byte (len==0); } send_stop (); + return (0); /* No error handling yet */ } -void i2c_write (uchar *addr, int alen, uchar *buffer, int len) +int i2c_write (uchar *addr, int alen, uchar *buffer, int len) { uchar *ap = addr; @@ -347,6 +348,7 @@ void i2c_write (uchar *addr, int alen, uchar *buffer, int len) write_byte (*buffer++); } send_stop (); + return (0); /* No error handling yet */ } uchar i2c_reg_read (uchar i2c_addr, uchar reg) diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c index 8925648..eff8538 100644 --- a/cpu/mpc8xx/cpu.c +++ b/cpu/mpc8xx/cpu.c @@ -385,7 +385,7 @@ void upmconfig(uint upm, uint *table, uint size) /* ------------------------------------------------------------------------- */ -void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { ulong msr, addr; @@ -415,7 +415,7 @@ void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) addr = CFG_MONITOR_BASE - sizeof (ulong); #endif ((void (*)(void ))addr)(); - + return 1; } /* ------------------------------------------------------------------------- */ diff --git a/cpu/mpc8xx/i2c.c b/cpu/mpc8xx/i2c.c index 53d81b7..3d3528c 100644 --- a/cpu/mpc8xx/i2c.c +++ b/cpu/mpc8xx/i2c.c @@ -548,7 +548,7 @@ int i2c_doio(i2c_state_t *state) return (j >= TOUT_LOOP) ? I2CERR_TIMEOUT : 0; } -void +int i2c_read(uchar *addr, int alen, uchar *buffer, int len) { i2c_state_t state; @@ -559,23 +559,24 @@ i2c_read(uchar *addr, int alen, uchar *buffer, int len) rc = i2c_send(&state, *addr, 0, I2CF_START_COND, alen - 1, addr + 1); if (rc != 0) { printf("i2c_read: i2c_send failed (%d)\n", rc); - return; + return 1; } rc = i2c_receive(&state, *addr, 0, I2CF_STOP_COND, len, buffer); if (rc != 0) { printf("i2c_read: i2c_receive failed (%d)\n", rc); - return; + return 1; } rc = i2c_doio(&state); if (rc != 0) { printf("i2c_read: i2c_doio failed (%d)\n", rc); - return; + return 1; } + return 0; } -void +int i2c_write(uchar *addr, int alen, uchar *buffer, int len) { i2c_state_t state; @@ -586,20 +587,21 @@ i2c_write(uchar *addr, int alen, uchar *buffer, int len) rc = i2c_send(&state, *addr, 0, I2CF_START_COND, alen - 1, addr + 1); if (rc != 0) { printf("i2c_write: first i2c_send failed (%d)\n", rc); - return; + return 1; } rc = i2c_send(&state, 0, 0, I2CF_STOP_COND, len, buffer); if (rc != 0) { printf("i2c_write: second i2c_send failed (%d)\n", rc); - return; + return 1; } rc = i2c_doio(&state); if (rc != 0) { printf("i2c_write: i2c_doio failed (%d)\n", rc); - return; + return 1; } + return 0; } uchar diff --git a/cpu/mpc8xx/soft_i2c.c b/cpu/mpc8xx/soft_i2c.c index 9d8b81a..79e2881 100644 --- a/cpu/mpc8xx/soft_i2c.c +++ b/cpu/mpc8xx/soft_i2c.c @@ -309,7 +309,7 @@ void i2c_init (int speed, int slaveaddr) * capable of reading `len' sequential bytes; no * checking is done here */ -void i2c_read (uchar *addr, int alen, uchar *buffer, int len) +int i2c_read (uchar *addr, int alen, uchar *buffer, int len) { uchar *ap = addr; @@ -324,9 +324,10 @@ void i2c_read (uchar *addr, int alen, uchar *buffer, int len) *buffer++ = read_byte (len==0); } send_stop (); + return (0); /* No error handling yet */ } -void i2c_write (uchar *addr, int alen, uchar *buffer, int len) +int i2c_write (uchar *addr, int alen, uchar *buffer, int len) { uchar *ap = addr; @@ -339,6 +340,7 @@ void i2c_write (uchar *addr, int alen, uchar *buffer, int len) write_byte (*buffer++); } send_stop (); + return (0); /* No error handling yet */ } uchar i2c_reg_read (uchar i2c_addr, uchar reg) diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c index 076390c..8cc3ddd 100644 --- a/cpu/ppc4xx/405gp_pci.c +++ b/cpu/ppc4xx/405gp_pci.c @@ -721,7 +721,7 @@ int PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID) #if (CONFIG_COMMANDS & CFG_CMD_PCI) -void +int do_pciinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { int bus_no = 0; @@ -732,6 +732,7 @@ do_pciinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } pciinfo(bus_no); + return 0; } diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index a6d7f3d..26967c2 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -132,13 +132,14 @@ int checkcpu(long clock) /* ------------------------------------------------------------------------- */ -void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { /* * Initiate system reset in debug control register DBCR */ __asm__ __volatile__(" lis 3, 0x3000 mtspr 0x3f2, 3"); + return 1; } diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c index 481a3bc..420fa67 100644 --- a/cpu/ppc4xx/i2c.c +++ b/cpu/ppc4xx/i2c.c @@ -268,21 +268,23 @@ int i2c_send(unsigned char address, } -void i2c_read (uchar *addr, int alen, uchar *buffer, int len) +int i2c_read (uchar *addr, int alen, uchar *buffer, int len) { - + int rcode = 0; + if ((alen != 2) && (alen != 3)) { printf ("I2C read: addr len %d not supported\n", alen); - return; + return 1; } - i2c_send (addr[0] << 1, alen-1, addr+1); - i2c_receive ((addr[0] << 1) | 0x01, len, buffer); + if (i2c_send (addr[0] << 1, alen-1, addr+1) != 0) rcode = 1; + if (i2c_receive ((addr[0] << 1) | 0x01, len, buffer) != 0) rcode = 1; + return rcode; } #ifndef CFG_EEPROM_PAGE_WRITE_ENABLE -void i2c_write (uchar *addr, int alen, uchar *buffer, int len) +int i2c_write (uchar *addr, int alen, uchar *buffer, int len) { uchar xbuf[3]; unsigned short paddr; @@ -297,7 +299,7 @@ void i2c_write (uchar *addr, int alen, uchar *buffer, int len) udelay(100); } } - return; + return 0; } paddr=(addr[1]<<8)+addr[2]; @@ -314,15 +316,16 @@ void i2c_write (uchar *addr, int alen, uchar *buffer, int len) udelay(100); } } - return; + return 0; } printf ("I2C write: addr len %d not supported\n", alen); + return 1; } #else /* CFG_EEPROM_PAGE_WRITE_ENABLE */ -void i2c_write (uchar *addr, int alen, uchar *buffer, int len) +int i2c_write (uchar *addr, int alen, uchar *buffer, int len) { /* buffer for one page + addresses */ uchar wbuffer[(1< - read MII PHY register \n\ mii write - write MII PHY register \n" \ ), -void do_mii (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_mii (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #else #define CMD_TBL_MII diff --git a/include/cmd_misc.h b/include/cmd_misc.h index 142c794..e3afb05 100644 --- a/include/cmd_misc.h +++ b/include/cmd_misc.h @@ -37,7 +37,7 @@ ), /* Implemented in $(BOARD)/pci.c */ -void do_pciinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_pciinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #else #define CMD_TBL_PCIINFO @@ -52,7 +52,7 @@ void do_pciinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); ), /* Implemented in $(CPU)/interrupts.c */ -void do_irqinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_irqinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #else #define CMD_TBL_IRQINFO diff --git a/include/cmd_net.h b/include/cmd_net.h index b08fdc3..1e4ba73 100644 --- a/include/cmd_net.h +++ b/include/cmd_net.h @@ -33,9 +33,7 @@ "bootp - boot image via network using BootP/TFTP protocol\n", \ "[loadAddress] [bootfilename]\n" \ ), - -void do_bootp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); - +int do_bootp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #define CMD_TBL_TFTPB MK_CMD_TBL_ENTRY( \ "tftpboot", 4, 3, 1, do_tftpb, \ "tftpboot- boot image via network using TFTP protocol\n" \ @@ -43,8 +41,7 @@ void do_bootp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); "[loadAddress] [bootfilename]\n" \ ), - -void do_tftpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_tftpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #define CMD_TBL_RARPB MK_CMD_TBL_ENTRY( \ @@ -53,8 +50,7 @@ void do_tftpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); "[loadAddress] [bootfilename]\n" \ ), - -void do_rarpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_rarpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #if (CONFIG_COMMANDS & CFG_CMD_DHCP) #define CMD_TBL_DHCP MK_CMD_TBL_ENTRY( \ @@ -63,8 +59,7 @@ void do_rarpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); "\n" \ ), - -void do_dhcp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_dhcp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #else #define CMD_TBL_DHCP #endif /* CFG_CMD_DHCP */ diff --git a/include/cmd_nvedit.h b/include/cmd_nvedit.h index a970051..d6f3c6b 100644 --- a/include/cmd_nvedit.h +++ b/include/cmd_nvedit.h @@ -34,7 +34,7 @@ "printenv name ...\n" \ " - print value of environment variable 'name'\n" \ ), -void do_printenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_printenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #define CMD_TBL_SETENV MK_CMD_TBL_ENTRY( \ "setenv", 6, CFG_MAXARGS, 0, do_setenv, \ @@ -44,7 +44,7 @@ void do_printenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); "setenv name\n" \ " - delete environment variable 'name'\n" \ ), -void do_setenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_setenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #if ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH)) #define CMD_TBL_SAVEENV MK_CMD_TBL_ENTRY( \ @@ -52,7 +52,7 @@ void do_setenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); "saveenv - save environment variables to persistent storage\n", \ NULL \ ), -void do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #else #define CMD_TBL_SAVEENV #endif /* CFG_CMD_ENV */ @@ -71,7 +71,7 @@ void do_saveenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); " - display 'message' string and get environment variable 'name'" \ "from stdin (max 'size' chars)\n" \ ), -void do_askenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_askenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #else #define CMD_TBL_ASKENV #endif /* CFG_CMD_ASKENV */ @@ -83,7 +83,7 @@ void do_askenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); "var [...]\n" \ " - run the commands in the environment variable(s) 'var'\n" \ ), -void do_run (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_run (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #else #define CMD_TBL_RUN #endif /* CFG_CMD_RUN */ diff --git a/include/cmd_pcmcia.h b/include/cmd_pcmcia.h index 3f733ea..54100e4 100644 --- a/include/cmd_pcmcia.h +++ b/include/cmd_pcmcia.h @@ -35,7 +35,7 @@ "pinit off - power off PCMCIA socket\n" \ ), -void do_pinit (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_pinit (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #else #define CMD_TBL_PINIT #endif diff --git a/include/cmd_reginfo.h b/include/cmd_reginfo.h index 7784445..4da4336 100644 --- a/include/cmd_reginfo.h +++ b/include/cmd_reginfo.h @@ -31,7 +31,7 @@ "reginfo - print register information\n", \ ), -void do_reginfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_reginfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #else #define CMD_TBL_REGINFO diff --git a/include/cmd_rtc.h b/include/cmd_rtc.h index bc899c8..f956fc4 100644 --- a/include/cmd_rtc.h +++ b/include/cmd_rtc.h @@ -37,7 +37,7 @@ " - with argument: set the system date & time\n" \ ), -void do_date (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_date (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #else diff --git a/include/cmd_scsi.h b/include/cmd_scsi.h index ec75d26..b269ddf 100644 --- a/include/cmd_scsi.h +++ b/include/cmd_scsi.h @@ -49,8 +49,8 @@ "loadAddr dev:part\n" \ ), -void do_scsi (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); -void do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_scsi (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +int do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #else diff --git a/include/command.h b/include/command.h index 8386e9a..03897ee 100644 --- a/include/command.h +++ b/include/command.h @@ -42,7 +42,7 @@ struct cmd_tbl_s { int maxargs; /* maximum number of arguments */ int repeatable; /* autorepeat allowed? */ /* Implementation function */ - void (*cmd)(struct cmd_tbl_s *, bd_t *, int, int, char *[]); + int (*cmd)(struct cmd_tbl_s *, bd_t *, int, int, char *[]); char *usage; /* Usage message (short) */ #ifdef CFG_LONGHELP char *help; /* Help message (long) */ diff --git a/include/config_MBX.h b/include/config_MBX.h index 8bedfcf..674b02d 100644 --- a/include/config_MBX.h +++ b/include/config_MBX.h @@ -73,6 +73,10 @@ */ #define CFG_LONGHELP /* undef to save memory */ #define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#define CFG_HUSH_PARSER /* Hush parse for ppcboot */ +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#endif #if (CONFIG_COMMANDS & CFG_CMD_KGDB) #define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ #else diff --git a/include/config_TQM860L.h b/include/config_TQM860L.h index 0274c57..ef056cb 100644 --- a/include/config_TQM860L.h +++ b/include/config_TQM860L.h @@ -87,14 +87,20 @@ * Miscellaneous configurable options */ #define CFG_LONGHELP /* undef to save memory */ -#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ + +#define CFG_HUSH_PARSER +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#endif + #if (CONFIG_COMMANDS & CFG_CMD_KGDB) -#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ #else -#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ #endif #define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ -#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_MAXARGS 16 /* max number of command args */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ #define CFG_MEMTEST_START 0x0400000 /* memtest works on */ @@ -102,7 +108,7 @@ #define CFG_LOAD_ADDR 0x100000 /* default load address */ -#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } diff --git a/include/config_lwmon.h b/include/config_lwmon.h index b8cb9cc..d823153 100644 --- a/include/config_lwmon.h +++ b/include/config_lwmon.h @@ -106,6 +106,12 @@ */ #define CFG_LONGHELP /* undef to save memory */ #define CFG_PROMPT "=> " /* Monitor Command Prompt */ + +#undef CFG_HUSH_PARSER /* enable "hush" shell */ +#ifdef CFG_HUSH_PARSER +#define CFG_PROMPT_HUSH_PS2 "> " +#endif + #if (CONFIG_COMMANDS & CFG_CMD_KGDB) #define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ #else diff --git a/include/flash.h b/include/flash.h index 9917aae..65b332f 100644 --- a/include/flash.h +++ b/include/flash.h @@ -37,10 +37,10 @@ typedef struct { /* Prototypes */ unsigned long flash_init (void); -void flash_print_info (flash_info_t *); -void flash_erase (flash_info_t *, int, int); -void flash_sect_erase (ulong addr_first, ulong addr_last); -void flash_sect_protect (int flag, ulong addr_first, ulong addr_last); +void flash_print_info (flash_info_t *); +int flash_erase (flash_info_t *, int, int); +int flash_sect_erase (ulong addr_first, ulong addr_last); +int flash_sect_protect (int flag, ulong addr_first, ulong addr_last); /* common/flash.c */ void flash_protect (int flag, ulong from, ulong to, flash_info_t *info); diff --git a/include/i2c.h b/include/i2c.h index e7bc0fd..0c4875f 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -9,8 +9,8 @@ #ifndef _I2C_H_ #define _I2C_H_ -void i2c_read (uchar *addr, int alen, uchar *buffer, int len); -void i2c_write (uchar *addr, int alen, uchar *buffer, int len); +int i2c_read (uchar *addr, int alen, uchar *buffer, int len); +int i2c_write (uchar *addr, int alen, uchar *buffer, int len); #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) || \ diff --git a/include/linux/string.h b/include/linux/string.h index e23d498..e5d57dc 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -56,6 +56,9 @@ extern __kernel_size_t strlen(const char *); #ifndef __HAVE_ARCH_STRNLEN extern __kernel_size_t strnlen(const char *,__kernel_size_t); #endif +#ifndef __HAVE_ARCH_STRDUP +extern char * strdup(const char *); +#endif #ifndef __HAVE_ARCH_MEMSET extern void * memset(void *,int,__kernel_size_t); diff --git a/include/ppcboot.h b/include/ppcboot.h index 8bf9eb6..fa86d43 100644 --- a/include/ppcboot.h +++ b/include/ppcboot.h @@ -249,8 +249,8 @@ void reset_phy (void); defined(CONFIG_HYMOD) /* $(BOARD)/eeprom.c */ void eeprom_init (void); -void eeprom_read (unsigned offset, uchar *buffer, unsigned cnt); -void eeprom_write (unsigned offset, uchar *buffer, unsigned cnt); +int eeprom_read (unsigned offset, uchar *buffer, unsigned cnt); +int eeprom_write (unsigned offset, uchar *buffer, unsigned cnt); # ifdef CONFIG_LWMON extern uchar pic_read (uchar reg); extern void pic_write (uchar reg, uchar val); diff --git a/include/version.h b/include/version.h index 40220e7..77b56a8 100644 --- a/include/version.h +++ b/include/version.h @@ -24,6 +24,6 @@ #ifndef __VERSION_H__ #define __VERSION_H__ -#define PPCBOOT_VERSION "PPCBoot 1.0.6" +#define PPCBOOT_VERSION "PPCBoot 1.1.0" #endif /* __VERSION_H__ */ diff --git a/ppc/string.c b/ppc/string.c index 2d1b2e6..c78da6c 100644 --- a/ppc/string.c +++ b/ppc/string.c @@ -13,6 +13,7 @@ #include #include +#include #define __HAVE_ARCH_BCOPY #define __HAVE_ARCH_MEMCMP @@ -157,6 +158,21 @@ size_t strnlen(const char * s, size_t count) } #endif +#ifndef __HAVE_ARCH_STRDUP +char * strdup(const char *s) +{ + char *new; + + if ((s == NULL) || + ((new = malloc (strlen(s) + 1)) == NULL) ) { + return NULL; + } + + strcpy (new, s); + return new; +} +#endif + #ifndef __HAVE_ARCH_STRSPN size_t strspn(const char *s, const char *accept) {