fs: fix generic save command implementation

Fix a few issues with the generic "save" shell command, and fs_write()
function.

1) fstypes[].write wasn't filled in for some file-systems, and isn't
   checked when used, which could cause crashes/... if executing save
   on e.g. fat/ext filesystems.

2) fs_write() requires the length argument to be non-zero, since it needs
   to know exactly how many bytes to write. Adjust the comments and code
   according to this.

3) fs_write() wasn't prototyped in <fs.h> like other generic functions;
   other code should be able to call this directly rather than invoking
   the "save" shell command.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Simon Glass <sjg@chromium.org>
---
v4: No change.
v3: No change.
v2: No change.
fs: implement infrastructure for an 'exists' function

This could be used in scripts such as:

if test -e mmc 0:1 /boot/boot.scr; then
    load mmc 0:1 ${scriptaddr} /boot/boot.scr
    source ${scriptaddr}
fi

rather than:

if load mmc 0:1 ${scriptaddr} /boot/boot.scr; then
    source ${scriptaddr}
fi

This prevents errors being printed by attempts to load non-existent
files, which can be important when checking for a large set of files,
such as /boot/boot.scr.uimg, /boot/boot.scr, /boot/extlinux.conf,
/boot.scr.uimg, /boot.scr, /extlinux.conf.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Simon Glass <sjg@chromium.org>
---
v4: s/infra-structure/infrastructure/.
v3:
* Remove addition of "exists" command; it's implemented in a separate
  patch later, as an operator in the "test" command.
* Invert return value of fs_exists()/file_exists() so it returns a
  logical value; the mapping to shell command return value is performed
  (later) in the test command.
v2: No change.
fs: don't pass NULL dev_desc to most filesystems

FAT and ext4 expect that the passed in block device descriptor not be
NULL. This causes problems on sandbox, where get_device_and_partition()
succeeds for the "host" device, yet passes back a NULL device descriptor.
Add special handling for this situation, so that the generic filesystem
commands operate as expected on sandbox.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v4: Added comment for struct fstype_info.null_dev_desc_ok member.
v3: New patch.
cmd_test: use table lookup for parsing

do_test() currently uses strcmp() twice to determine which operator is
present; once to determine how many arguments the operator needs, then
a second time to actually decode the operator and implement it.

Rewrite the code so that a table lookup is used to translate the operator
string to an integer, and use a more efficient switch statement to decode
and execute the operator.

This approach also acts as enablement for the following patches.

This patch should introduce no behavioural change.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v4: No change.
v3: New patch.
cmd_test: check for binary operators before unary

This better mirrors the behaviour of bash, for example:

$ if test -z = -z; then echo yes; else echo no; fi
yes

This is parsed as a string comparison of "-z" and "-z", since the check
for the binary "=" operator occurs first. Without this change, the
command would be parsed as a -z test of "-", followed by a syntax error;
a trailing -z without and operand.

This is a behavioural change, but I believe any commands affected were
previously invalid or bizarely formed.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v4: No change.
v3: New patch.
cmd_test: implement ! on sub-expressions

Currently, ! can only be parsed as the first operator in an expression.
This prevents the following from working:

$ if test ! ! 1 -eq 1; then echo yes; else echo no; fi
yes
$ if test ! 1 -eq 2 -a ! 3 -eq 4; then echo yes; else echo no; fi
yes

Fix this by parsing ! like any other operator, and and handling it
similarly to -a and -o.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v4: No change.
v3: New patch.
cmd_test: evaluate to false without any arguments

This emulates bash:
$ if test; then echo yes; else echo no; fi
no

Currently, the code sets expr = -1 in this case, which gets mapped to
0 (true) at the end of do_test() by the logical -> shell exit code
conversion.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v4: No change.
v3: New patch.
cmd_test: implement -e test for file existence

This is much like a regular shell's -e operator, except that it takes
multiple arguments to specify the device type and  device/partition ID
in addition to the usual filename:

if test -e mmc 0:1 /boot/boot.scr; then echo yes; else echo no; fi

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v4: No change.
v3: New patch.
sandbox: implement exists() function

This hooks into the generic "file exists" support added in an earlier
patch, and provides an implementation for the sandbox test environment.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Simon Glass <sjg@chromium.org>
---
v4: No change.
v3:
* Remove "sb exists" command; it's part of "test" now.
* Invert return value of exists(), per change to previous patch.
v2: No change.
sandbox: enable CONFIG_CMD_FS_GENERIC

Since the generic ls command no longer segfaults sandbox, enable it.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Simon Glass <sjg@chromium.org>
---
v4: No change.
v3: New patch.
ext4: implement exists() for ext4fs

This hooks into the generic "file exists" support added in an earlier
patch, and provides an implementation for the ext4 filesystem.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Simon Glass <sjg@chromium.org>
---
v4: No change.
v3: Invert return value of exists(), per change to previous patch.
v2: No change.
fat: implement exists() for FAT fs

This hooks into the generic "file exists" support added in an earlier
patch, and provides an implementation for the FAT filesystem.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Simon Glass <sjg@chromium.org>
---
v4: No change.
v3:
* s/ext/fat/ in the commit description too:-(
* Invert return value of exists(), per change to previous patch.
v2: s/ext/fat/ in the commit subject.
unit-test: fix 'env default' invocation

"env default -f" doesn't work any more; replace it with
"env default -f -a". This avoids the following when running the ut
command:

do_ut_cmd: Testing commands
env - environment handling commands

Usage:
env default [-f] -a - [forcibly] reset default environment
...

Signed-off-by: Stephen Warren <swarren@nvidia.com>
unit-test: add lots of tests for the Hush 'test' command

I recently re-wrote cmd_test() to add new features. Add a bunch of unit-
tests to make sure I didn't break anything.

Suggested-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
This patch depends on my 12-entry patch series that implements "test -e",
since it tests that new feature.
ARM: tegra: set env vars to indicate Cardhu A04 support

The U-Boot "cardhu" build supports only revision 4 of the Cardhu board
and later compatible revisions. Hence, set $board_name in the default
environment to "cardhu-a04" rather than just "cardhu".

The Linux kernel has separate DTs for Cardhu A02 and A04, although the
former isn't really supported any more. Consequently, the kernel DT file
that matches the U-Boot cardhu build is "tegra30-cardhu-a04.dtb" rather
than "tegra30-cardhu.dtb". Set the $fdtfile default environment variable
to reflect this.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v3: No change.
v2: New patch.

Note that this series depends on:
* Dennis' series to add config_distro_defaults.h.
* My series that implements "test -e".
ARM: tegra: convert tegra to use distro defaults

Modify all Tegra boards to include the "distro defaults" header, so that
all the config options distros expect are enabled. Remove any #defines
that enable the same options from the Tegra files.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v3: No change.
v2: No change.
ARM: tegra: rework boot scripts

Update the common Tegra boot scripts in the default environment to

a) Make use of the new "exists" shell command to avoid some error
   messges.

b) Allow booting using the sysboot command and extlinux.conf. This
   allows easy creation of boot menus, and provides a simple interface
   for distros to parameterize/configure the boot process.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v3: s/exists/test -e/ in shell commands.
v2: No change.
ARM: tegra: implement bootcmd_pxe

This retrieves a PXE config file over the network, and executes it. This
allows an extlinux config file  to be retrieved over the network and
executed, whereas the existing bootcmd_dhcp retrieves a U-Boot script.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v3: No change.
v2: No change.
README: document CONFIG_CMD_FS_GENERIC

This enables generic filesystem commands such as load and ls, which
automatically work with multiple filesystem types, without having to
be told which is present, unlike e.g. ext2load, fatls.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
ARM: tegra: clear $usb_need_init each boot

$usb_need_init prevents "usb start" from being run multiple times for
each boot attempt, i.e. once for USB storage, another for PXE, and
another for DHCP. However, the flag that's used to determine when to run
"usb start" is never cleared, so a subsequent "boot" command will never
probe for a freshly plugged in USB device. Fix this so that new USB
devices will be probed once per boot attempt.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
v2: New patch