source: SVN/rincon/u-boot/common/cmd_flash.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 19.2 KB
Line 
1/*
2 * (C) Copyright 2000
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/*
25 * FLASH support
26 */
27#include <common.h>
28#include <command.h>
29
30#ifdef CONFIG_HAS_DATAFLASH
31#include <dataflash.h>
32#endif
33
34#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
35#include <jffs2/jffs2.h>
36
37/* parition handling routines */
38int mtdparts_init(void);
39int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num);
40int find_dev_and_part(const char *id, struct mtd_device **dev,
41                u8 *part_num, struct part_info **part);
42#endif
43
44#ifndef CFG_NO_FLASH
45extern flash_info_t flash_info[];       /* info for FLASH chips */
46
47/*
48 * The user interface starts numbering for Flash banks with 1
49 * for historical reasons.
50 */
51
52/*
53 * this routine looks for an abbreviated flash range specification.
54 * the syntax is B:SF[-SL], where B is the bank number, SF is the first
55 * sector to erase, and SL is the last sector to erase (defaults to SF).
56 * bank numbers start at 1 to be consistent with other specs, sector numbers
57 * start at zero.
58 *
59 * returns:     1       - correct spec; *pinfo, *psf and *psl are
60 *                        set appropriately
61 *              0       - doesn't look like an abbreviated spec
62 *              -1      - looks like an abbreviated spec, but got
63 *                        a parsing error, a number out of range,
64 *                        or an invalid flash bank.
65 */
66static int
67abbrev_spec (char *str, flash_info_t ** pinfo, int *psf, int *psl)
68{
69        flash_info_t *fp;
70        int bank, first, last;
71        char *p, *ep;
72
73        if ((p = strchr (str, ':')) == NULL)
74                return 0;
75        *p++ = '\0';
76
77        bank = simple_strtoul (str, &ep, 10);
78        if (ep == str || *ep != '\0' ||
79                bank < 1 || bank > CFG_MAX_FLASH_BANKS ||
80                (fp = &flash_info[bank - 1])->flash_id == FLASH_UNKNOWN)
81                return -1;
82
83        str = p;
84        if ((p = strchr (str, '-')) != NULL)
85                *p++ = '\0';
86
87        first = simple_strtoul (str, &ep, 10);
88        if (ep == str || *ep != '\0' || first >= fp->sector_count)
89                return -1;
90
91        if (p != NULL) {
92                last = simple_strtoul (p, &ep, 10);
93                if (ep == p || *ep != '\0' ||
94                        last < first || last >= fp->sector_count)
95                        return -1;
96        } else {
97                last = first;
98        }
99
100        *pinfo = fp;
101        *psf = first;
102        *psl = last;
103
104        return 1;
105}
106
107/*
108 * This function computes the start and end addresses for both
109 * erase and protect commands. The range of the addresses on which
110 * either of the commands is to operate can be given in two forms:
111 * 1. <cmd> start end - operate on <'start',  'end')
112 * 2. <cmd> start +length - operate on <'start', start + length)
113 * If the second form is used and the end address doesn't fall on the
114 * sector boundary, than it will be adjusted to the next sector boundary.
115 * If it isn't in the flash, the function will fail (return -1).
116 * Input:
117 *    arg1, arg2: address specification (i.e. both command arguments)
118 * Output:
119 *    addr_first, addr_last: computed address range
120 * Return:
121 *    1: success
122 *   -1: failure (bad format, bad address).
123*/
124static int
125addr_spec(char *arg1, char *arg2, ulong *addr_first, ulong *addr_last)
126{
127        char *ep;
128        char len_used; /* indicates if the "start +length" form used */
129        char found;
130        ulong bank;
131
132        *addr_first = simple_strtoul(arg1, &ep, 16);
133        if (ep == arg1 || *ep != '\0')
134                return -1;
135
136        len_used = 0;
137        if (arg2 && *arg2 == '+'){
138                len_used = 1;
139                ++arg2;
140        }
141
142        *addr_last = simple_strtoul(arg2, &ep, 16);
143        if (ep == arg2 || *ep != '\0')
144                return -1;
145
146        if (len_used){
147                /*
148                 * *addr_last has the length, compute correct *addr_last
149                 * XXX watch out for the integer overflow! Right now it is
150                 * checked for in both the callers.
151                 */
152                *addr_last = *addr_first + *addr_last - 1;
153
154                /*
155                 * It may happen that *addr_last doesn't fall on the sector
156                 * boundary. We want to round such an address to the next
157                 * sector boundary, so that the commands don't fail later on.
158                 */
159
160                /* find the end addr of the sector where the *addr_last is */
161                found = 0;
162                for (bank = 0; bank < CFG_MAX_FLASH_BANKS && !found; ++bank){
163                        int i;
164                        flash_info_t *info = &flash_info[bank];
165                        for (i = 0; i < info->sector_count && !found; ++i){
166                                /* get the end address of the sector */
167                                ulong sector_end_addr;
168                                if (i == info->sector_count - 1){
169                                        sector_end_addr =
170                                                info->start[0] + info->size - 1;
171                                } else {
172                                        sector_end_addr =
173                                                info->start[i+1] - 1;
174                                }
175                                if (*addr_last <= sector_end_addr &&
176                                                *addr_last >= info->start[i]){
177                                        /* sector found */
178                                        found = 1;
179                                        /* adjust *addr_last if necessary */
180                                        if (*addr_last < sector_end_addr){
181                                                *addr_last = sector_end_addr;
182                                        }
183                                }
184                        } /* sector */
185                } /* bank */
186                if (!found){
187                        /* error, addres not in flash */
188                        printf("Error: end address (0x%08lx) not in flash!\n",
189                                                                *addr_last);
190                        return -1;
191                }
192        } /* "start +length" from used */
193
194        return 1;
195}
196
197static int
198flash_fill_sect_ranges (ulong addr_first, ulong addr_last,
199                        int *s_first, int *s_last,
200                        int *s_count )
201{
202        flash_info_t *info;
203        ulong bank;
204        int rcode = 0;
205
206        *s_count = 0;
207
208        for (bank=0; bank < CFG_MAX_FLASH_BANKS; ++bank) {
209                s_first[bank] = -1;     /* first sector to erase        */
210                s_last [bank] = -1;     /* last  sector to erase        */
211        }
212
213        for (bank=0,info = &flash_info[0];
214             (bank < CFG_MAX_FLASH_BANKS) && (addr_first <= addr_last);
215             ++bank, ++info) {
216                ulong b_end;
217                int sect;
218                short s_end;
219
220                if (info->flash_id == FLASH_UNKNOWN) {
221                        continue;
222                }
223
224                b_end = info->start[0] + info->size - 1;        /* bank end addr */
225                s_end = info->sector_count - 1;                 /* last sector   */
226
227
228                for (sect=0; sect < info->sector_count; ++sect) {
229                        ulong end;      /* last address in current sect */
230
231                        end = (sect == s_end) ? b_end : info->start[sect + 1] - 1;
232
233                        if (addr_first > end)
234                                continue;
235                        if (addr_last < info->start[sect])
236                                continue;
237
238                        if (addr_first == info->start[sect]) {
239                                s_first[bank] = sect;
240                        }
241                        if (addr_last  == end) {
242                                s_last[bank]  = sect;
243                        }
244                }
245                if (s_first[bank] >= 0) {
246                        if (s_last[bank] < 0) {
247                                if (addr_last > b_end) {
248                                        s_last[bank] = s_end;
249                                } else {
250                                        puts ("Error: end address"
251                                                " not on sector boundary\n");
252                                        rcode = 1;
253                                        break;
254                                }
255                        }
256                        if (s_last[bank] < s_first[bank]) {
257                                puts ("Error: end sector"
258                                        " precedes start sector\n");
259                                rcode = 1;
260                                break;
261                        }
262                        sect = s_last[bank];
263                        addr_first = (sect == s_end) ? b_end + 1: info->start[sect + 1];
264                        (*s_count) += s_last[bank] - s_first[bank] + 1;
265                } else if (addr_first >= info->start[0] && addr_first < b_end) {
266                        puts ("Error: start address not on sector boundary\n");
267                        rcode = 1;
268                        break;
269                } else if (s_last[bank] >= 0) {
270                        puts ("Error: cannot span across banks when they are"
271                               " mapped in reverse order\n");
272                        rcode = 1;
273                        break;
274                }
275        }
276
277        return rcode;
278}
279#endif /* CFG_NO_FLASH */
280
281int do_flinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
282{
283#ifndef CFG_NO_FLASH
284        ulong bank;
285#endif
286
287#ifdef CONFIG_HAS_DATAFLASH
288        dataflash_print_info();
289#endif
290
291#ifndef CFG_NO_FLASH
292        if (argc == 1) {        /* print info for all FLASH banks */
293                for (bank=0; bank <CFG_MAX_FLASH_BANKS; ++bank) {
294                        printf ("\nBank # %ld: ", bank+1);
295
296                        flash_print_info (&flash_info[bank]);
297                }
298                return 0;
299        }
300
301        bank = simple_strtoul(argv[1], NULL, 16);
302        if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) {
303                printf ("Only FLASH Banks # 1 ... # %d supported\n",
304                        CFG_MAX_FLASH_BANKS);
305                return 1;
306        }
307        printf ("\nBank # %ld: ", bank);
308        flash_print_info (&flash_info[bank-1]);
309#endif /* CFG_NO_FLASH */
310        return 0;
311}
312
313int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
314{
315#ifndef CFG_NO_FLASH
316        flash_info_t *info;
317        ulong bank, addr_first, addr_last;
318        int n, sect_first, sect_last;
319#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
320        struct mtd_device *dev;
321        struct part_info *part;
322        u8 dev_type, dev_num, pnum;
323#endif
324        int rcode = 0;
325
326        if (argc < 2) {
327                printf ("Usage:\n%s\n", cmdtp->usage);
328                return 1;
329        }
330
331        if (strcmp(argv[1], "all") == 0) {
332                for (bank=1; bank<=CFG_MAX_FLASH_BANKS; ++bank) {
333                        printf ("Erase Flash Bank # %ld ", bank);
334                        info = &flash_info[bank-1];
335                        rcode = flash_erase (info, 0, info->sector_count-1);
336                }
337                return rcode;
338        }
339
340        if ((n = abbrev_spec(argv[1], &info, &sect_first, &sect_last)) != 0) {
341                if (n < 0) {
342                        puts ("Bad sector specification\n");
343                        return 1;
344                }
345                printf ("Erase Flash Sectors %d-%d in Bank # %zu ",
346                        sect_first, sect_last, (info-flash_info)+1);
347                rcode = flash_erase(info, sect_first, sect_last);
348                return rcode;
349        }
350
351#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
352        /* erase <part-id> - erase partition */
353        if ((argc == 2) && (id_parse(argv[1], NULL, &dev_type, &dev_num) == 0)) {
354                mtdparts_init();
355                if (find_dev_and_part(argv[1], &dev, &pnum, &part) == 0) {
356                        if (dev->id->type == MTD_DEV_TYPE_NOR) {
357                                bank = dev->id->num;
358                                info = &flash_info[bank];
359                                addr_first = part->offset + info->start[0];
360                                addr_last = addr_first + part->size - 1;
361
362                                printf ("Erase Flash Parition %s, "
363                                                "bank %ld, 0x%08lx - 0x%08lx ",
364                                                argv[1], bank, addr_first,
365                                                addr_last);
366
367                                rcode = flash_sect_erase(addr_first, addr_last);
368                                return rcode;
369                        }
370
371                        printf("cannot erase, not a NOR device\n");
372                        return 1;
373                }
374        }
375#endif
376
377        if (argc != 3) {
378                printf ("Usage:\n%s\n", cmdtp->usage);
379                return 1;
380        }
381
382        if (strcmp(argv[1], "bank") == 0) {
383                bank = simple_strtoul(argv[2], NULL, 16);
384                if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) {
385                        printf ("Only FLASH Banks # 1 ... # %d supported\n",
386                                CFG_MAX_FLASH_BANKS);
387                        return 1;
388                }
389                printf ("Erase Flash Bank # %ld ", bank);
390                info = &flash_info[bank-1];
391                rcode = flash_erase (info, 0, info->sector_count-1);
392                return rcode;
393        }
394
395        if (addr_spec(argv[1], argv[2], &addr_first, &addr_last) < 0){
396                printf ("Bad address format\n");
397                return 1;
398        }
399
400        if (addr_first >= addr_last) {
401                printf ("Usage:\n%s\n", cmdtp->usage);
402                return 1;
403        }
404
405        rcode = flash_sect_erase(addr_first, addr_last);
406        return rcode;
407#else
408        return 0;
409#endif /* CFG_NO_FLASH */
410}
411
412#ifndef CFG_NO_FLASH
413int flash_sect_erase (ulong addr_first, ulong addr_last)
414{
415        flash_info_t *info;
416        ulong bank;
417#ifdef CFG_MAX_FLASH_BANKS_DETECT
418        int s_first[CFG_MAX_FLASH_BANKS_DETECT], s_last[CFG_MAX_FLASH_BANKS_DETECT];
419#else
420        int s_first[CFG_MAX_FLASH_BANKS], s_last[CFG_MAX_FLASH_BANKS];
421#endif
422        int erased = 0;
423        int planned;
424        int rcode = 0;
425
426        rcode = flash_fill_sect_ranges (addr_first, addr_last,
427                                        s_first, s_last, &planned );
428
429        if (planned && (rcode == 0)) {
430                for (bank=0,info = &flash_info[0];
431                     (bank < CFG_MAX_FLASH_BANKS) && (rcode == 0);
432                     ++bank, ++info) {
433                        if (s_first[bank]>=0) {
434                                erased += s_last[bank] - s_first[bank] + 1;
435                                debug ("Erase Flash from 0x%08lx to 0x%08lx "
436                                        "in Bank # %ld ",
437                                        info->start[s_first[bank]],
438                                        (s_last[bank] == info->sector_count) ?
439                                                info->start[0] + info->size - 1:
440                                                info->start[s_last[bank]+1] - 1,
441                                        bank+1);
442                                rcode = flash_erase (info, s_first[bank], s_last[bank]);
443                        }
444                }
445                printf ("Erased %d sectors\n", erased);
446        } else if (rcode == 0) {
447                puts ("Error: start and/or end address"
448                        " not on sector boundary\n");
449                rcode = 1;
450        }
451        return rcode;
452}
453#endif /* CFG_NO_FLASH */
454
455int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
456{
457#ifndef CFG_NO_FLASH
458        flash_info_t *info;
459        ulong bank;
460        int i, n, sect_first, sect_last;
461#endif /* CFG_NO_FLASH */
462        ulong addr_first, addr_last;
463        int p;
464#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
465        struct mtd_device *dev;
466        struct part_info *part;
467        u8 dev_type, dev_num, pnum;
468#endif
469        int rcode = 0;
470#ifdef CONFIG_HAS_DATAFLASH
471        int status;
472#endif
473
474        if (argc < 3) {
475                printf ("Usage:\n%s\n", cmdtp->usage);
476                return 1;
477        }
478
479        if (strcmp(argv[1], "off") == 0) {
480                p = 0;
481        } else if (strcmp(argv[1], "on") == 0) {
482                p = 1;
483        } else {
484                printf ("Usage:\n%s\n", cmdtp->usage);
485                return 1;
486        }
487
488#ifdef CONFIG_HAS_DATAFLASH
489        if ((strcmp(argv[2], "all") != 0) && (strcmp(argv[2], "bank") != 0)) {
490                addr_first = simple_strtoul(argv[2], NULL, 16);
491                addr_last  = simple_strtoul(argv[3], NULL, 16);
492
493                if (addr_dataflash(addr_first) && addr_dataflash(addr_last)) {
494                        status = dataflash_real_protect(p,addr_first,addr_last);
495                        if (status < 0){
496                                puts ("Bad DataFlash sector specification\n");
497                                return 1;
498                        }
499                        printf("%sProtect %d DataFlash Sectors\n",
500                                p ? "" : "Un-", status);
501                        return 0;
502                }
503        }
504#endif
505
506#ifndef CFG_NO_FLASH
507        if (strcmp(argv[2], "all") == 0) {
508                for (bank=1; bank<=CFG_MAX_FLASH_BANKS; ++bank) {
509                        info = &flash_info[bank-1];
510                        if (info->flash_id == FLASH_UNKNOWN) {
511                                continue;
512                        }
513                        printf ("%sProtect Flash Bank # %ld\n",
514                                p ? "" : "Un-", bank);
515
516                        for (i=0; i<info->sector_count; ++i) {
517#if defined(CFG_FLASH_PROTECTION)
518                                if (flash_real_protect(info, i, p))
519                                        rcode = 1;
520                                putc ('.');
521#else
522                                info->protect[i] = p;
523#endif  /* CFG_FLASH_PROTECTION */
524                        }
525#if defined(CFG_FLASH_PROTECTION)
526                        if (!rcode) puts (" done\n");
527#endif  /* CFG_FLASH_PROTECTION */
528                }
529                return rcode;
530        }
531
532        if ((n = abbrev_spec(argv[2], &info, &sect_first, &sect_last)) != 0) {
533                if (n < 0) {
534                        puts ("Bad sector specification\n");
535                        return 1;
536                }
537                printf("%sProtect Flash Sectors %d-%d in Bank # %zu\n",
538                        p ? "" : "Un-", sect_first, sect_last,
539                        (info-flash_info)+1);
540                for (i = sect_first; i <= sect_last; i++) {
541#if defined(CFG_FLASH_PROTECTION)
542                        if (flash_real_protect(info, i, p))
543                                rcode =  1;
544                        putc ('.');
545#else
546                        info->protect[i] = p;
547#endif  /* CFG_FLASH_PROTECTION */
548                }
549
550#if defined(CFG_FLASH_PROTECTION)
551                if (!rcode) puts (" done\n");
552#endif  /* CFG_FLASH_PROTECTION */
553
554                return rcode;
555        }
556
557#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
558        /* protect on/off <part-id> */
559        if ((argc == 3) && (id_parse(argv[2], NULL, &dev_type, &dev_num) == 0)) {
560                mtdparts_init();
561                if (find_dev_and_part(argv[2], &dev, &pnum, &part) == 0) {
562                        if (dev->id->type == MTD_DEV_TYPE_NOR) {
563                                bank = dev->id->num;
564                                info = &flash_info[bank];
565                                addr_first = part->offset + info->start[0];
566                                addr_last = addr_first + part->size - 1;
567
568                                printf ("%sProtect Flash Parition %s, "
569                                                "bank %ld, 0x%08lx - 0x%08lx\n",
570                                                p ? "" : "Un", argv[1],
571                                                bank, addr_first, addr_last);
572
573                                rcode = flash_sect_protect (p, addr_first, addr_last);
574                                return rcode;
575                        }
576
577                        printf("cannot %sprotect, not a NOR device\n",
578                                        p ? "" : "un");
579                        return 1;
580                }
581        }
582#endif
583
584        if (argc != 4) {
585                printf ("Usage:\n%s\n", cmdtp->usage);
586                return 1;
587        }
588
589        if (strcmp(argv[2], "bank") == 0) {
590                bank = simple_strtoul(argv[3], NULL, 16);
591                if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) {
592                        printf ("Only FLASH Banks # 1 ... # %d supported\n",
593                                CFG_MAX_FLASH_BANKS);
594                        return 1;
595                }
596                printf ("%sProtect Flash Bank # %ld\n",
597                        p ? "" : "Un-", bank);
598                info = &flash_info[bank-1];
599
600                if (info->flash_id == FLASH_UNKNOWN) {
601                        puts ("missing or unknown FLASH type\n");
602                        return 1;
603                }
604                for (i=0; i<info->sector_count; ++i) {
605#if defined(CFG_FLASH_PROTECTION)
606                        if (flash_real_protect(info, i, p))
607                                rcode =  1;
608                        putc ('.');
609#else
610                        info->protect[i] = p;
611#endif  /* CFG_FLASH_PROTECTION */
612                }
613
614#if defined(CFG_FLASH_PROTECTION)
615                if (!rcode) puts (" done\n");
616#endif  /* CFG_FLASH_PROTECTION */
617
618                return rcode;
619        }
620
621        if (addr_spec(argv[2], argv[3], &addr_first, &addr_last) < 0){
622                printf("Bad address format\n");
623                return 1;
624        }
625
626        if (addr_first >= addr_last) {
627                printf ("Usage:\n%s\n", cmdtp->usage);
628                return 1;
629        }
630        rcode = flash_sect_protect (p, addr_first, addr_last);
631#endif /* CFG_NO_FLASH */
632        return rcode;
633}
634
635#ifndef CFG_NO_FLASH
636int flash_sect_protect (int p, ulong addr_first, ulong addr_last)
637{
638        flash_info_t *info;
639        ulong bank;
640#ifdef CFG_MAX_FLASH_BANKS_DETECT
641        int s_first[CFG_MAX_FLASH_BANKS_DETECT], s_last[CFG_MAX_FLASH_BANKS_DETECT];
642#else
643        int s_first[CFG_MAX_FLASH_BANKS], s_last[CFG_MAX_FLASH_BANKS];
644#endif
645        int protected, i;
646        int planned;
647        int rcode;
648
649        rcode = flash_fill_sect_ranges( addr_first, addr_last, s_first, s_last, &planned );
650
651        protected = 0;
652
653        if (planned && (rcode == 0)) {
654                for (bank=0,info = &flash_info[0]; bank < CFG_MAX_FLASH_BANKS; ++bank, ++info) {
655                        if (info->flash_id == FLASH_UNKNOWN) {
656                                continue;
657                        }
658
659                        if (s_first[bank]>=0 && s_first[bank]<=s_last[bank]) {
660                                debug ("%sProtecting sectors %d..%d in bank %ld\n",
661                                        p ? "" : "Un-",
662                                        s_first[bank], s_last[bank], bank+1);
663                                protected += s_last[bank] - s_first[bank] + 1;
664                                for (i=s_first[bank]; i<=s_last[bank]; ++i) {
665#if defined(CFG_FLASH_PROTECTION)
666                                        if (flash_real_protect(info, i, p))
667                                                rcode = 1;
668                                        putc ('.');
669#else
670                                        info->protect[i] = p;
671#endif  /* CFG_FLASH_PROTECTION */
672                                }
673                        }
674                }
675#if defined(CFG_FLASH_PROTECTION)
676                puts (" done\n");
677#endif  /* CFG_FLASH_PROTECTION */
678
679                printf ("%sProtected %d sectors\n",
680                        p ? "" : "Un-", protected);
681        } else if (rcode == 0) {
682                puts ("Error: start and/or end address"
683                        " not on sector boundary\n");
684                rcode = 1;
685        }
686        return rcode;
687}
688#endif /* CFG_NO_FLASH */
689
690
691/**************************************************/
692#if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
693# define TMP_ERASE      "erase <part-id>\n    - erase partition\n"
694# define TMP_PROT_ON    "protect on <part-id>\n    - protect partition\n"
695# define TMP_PROT_OFF   "protect off <part-id>\n    - make partition writable\n"
696#else
697# define TMP_ERASE      /* empty */
698# define TMP_PROT_ON    /* empty */
699# define TMP_PROT_OFF   /* empty */
700#endif
701
702U_BOOT_CMD(
703        flinfo,    2,    1,    do_flinfo,
704        "flinfo  - print FLASH memory information\n",
705        "\n    - print information for all FLASH memory banks\n"
706        "flinfo N\n    - print information for FLASH memory bank # N\n"
707);
708
709U_BOOT_CMD(
710        erase,   3,   0,  do_flerase,
711        "erase   - erase FLASH memory\n",
712        "start end\n"
713        "    - erase FLASH from addr 'start' to addr 'end'\n"
714        "erase start +len\n"
715        "    - erase FLASH from addr 'start' to the end of sect "
716        "w/addr 'start'+'len'-1\n"
717        "erase N:SF[-SL]\n    - erase sectors SF-SL in FLASH bank # N\n"
718        "erase bank N\n    - erase FLASH bank # N\n"
719        TMP_ERASE
720        "erase all\n    - erase all FLASH banks\n"
721);
722
723U_BOOT_CMD(
724        protect,  4,  0,   do_protect,
725        "protect - enable or disable FLASH write protection\n",
726        "on  start end\n"
727        "    - protect FLASH from addr 'start' to addr 'end'\n"
728        "protect on start +len\n"
729        "    - protect FLASH from addr 'start' to end of sect "
730        "w/addr 'start'+'len'-1\n"
731        "protect on  N:SF[-SL]\n"
732        "    - protect sectors SF-SL in FLASH bank # N\n"
733        "protect on  bank N\n    - protect FLASH bank # N\n"
734        TMP_PROT_ON
735        "protect on  all\n    - protect all FLASH banks\n"
736        "protect off start end\n"
737        "    - make FLASH from addr 'start' to addr 'end' writable\n"
738        "protect off start +len\n"
739        "    - make FLASH from addr 'start' to end of sect "
740        "w/addr 'start'+'len'-1 wrtable\n"
741        "protect off N:SF[-SL]\n"
742        "    - make sectors SF-SL writable in FLASH bank # N\n"
743        "protect off bank N\n    - make FLASH bank # N writable\n"
744        TMP_PROT_OFF
745        "protect off all\n    - make all FLASH banks writable\n"
746);
747
748#undef  TMP_ERASE
749#undef  TMP_PROT_ON
750#undef  TMP_PROT_OFF
Note: See TracBrowser for help on using the repository browser.