Sahara end-of-image and done packets report compact status values from
the target. Including protocol-defined end-of-image descriptions and
the done transfer state alongside the numeric values makes
authentication, hash verification, and transfer-completion results
easier to identify from logs.
Add descriptions for Sahara status codes when logging end-of-image
results, and print done status as pending or complete.
Signed-off-by: Veera, Bhavya <bveera@qti.qualcomm.com>
Some UFS programmers reset the device right after committing the
configuration descriptor, dropping the USB link before sending the
ACK, so qdl reports a failure although provisioning succeeded.
Map LIBUSB_ERROR_NO_DEVICE to -ENODEV in usb_read() and, when the
device disappears after commit=1, treat it as success and skip the
final reset. Any real descriptor error would already have been
NAKed during the earlier exchange. A disconnect during the commit=0
dry run remains a hard error.
Signed-off-by: Zhirong Chen <zhirongc@qti.qualcomm.com>
With qdl_parse_args() self-contained, move it plus print_usage() and
the shared long-option ids into cli.c, out of main()'s compilation
unit, so unit tests can link the option parser directly.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
qdl_flash() mixed three concerns in 330 lines: option decoding, the
positional-argument walk and the device session. Split them into
qdl_parse_args() (filling struct qdl_opts), qdl_build_op_list() and a
plain session sequence, so each can be reasoned about - and tested -
alone. Options, messages and run order are unchanged; the op-list
builder takes the options mutably because the reset verb overrides
skip-reset.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
patch_load_xml() and read_op_load() turn XML into firehose op lists
and had no direct coverage. Add a cmocka suite (linking util.c for
the real attribute accessors and stubbing the device/ux layers) that
checks a valid entry produces the expected op, that an unrecognized
child tag is skipped, and - locking in the recently fixed error
propagation - that a malformed entry or a missing file makes the
loader return an error instead of reporting success.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
Sahara and Firehose traces carry a "SAHARA: " or "FIREHOSE: " tag, but
most VIP messages have none and the few that do mix "VIP:" with a bare
"VIP TABLE DIGESTS" or a Firehose-tagged packet digest.
Prefix every message from vip.c and the VIP negotiation in firehose.c
with "VIP: ", drop the now redundant "VIP" from message bodies, and
move the packet digest trace under the VIP tag since it belongs to
table generation. The sim's own "sim: VIP ..." messages keep their
prefix.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
All diagnostics go through the ux_warn()/ux_die() helpers now, so the
err(3)-style shims and the <err.h> include are dead code.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
Sahara diagnostics are now tagged "SAHARA: ", while the Firehose
traces use a mix of "FIREHOSE READ:", "FIREHOSE WRITE:" and a bare
"LOG:" for device log lines, so the two stages do not line up in a
debug log.
Use "FIREHOSE: <TAG>: " for every Firehose trace, including device
logs and raw binary writes, so all protocol output
follows the same "<STAGE>: " format.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
Firehose traces are tagged FIREHOSE READ/WRITE, but Sahara messages
such as "HELLO version" or "READ image" carry no hint of where they
come from, and only a few had an ad-hoc "Sahara:" prefix. In a
timestamped debug log this makes the two protocol stages hard to tell
apart.
Prefix every message emitted by sahara.c with "SAHARA: ", fold the
existing ad-hoc prefixes into it, and drop the now redundant "Sahara"
from message bodies. The chipinfo report table is command output
rather than a diagnostic and is left unchanged.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
libxml2 dumps a document with a newline after the declaration and at
the end, and some devices terminate their responses the same way. With
timestamped debug output every FIREHOSE WRITE therefore spans two lines
and is followed by a blank one, which makes the trace hard to scan.
Strip newlines from the XML before printing so each read and write is
one line, matching how devices format their responses.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
USB warnings, Sahara ramdump failures, fatal CLI and archive errors,
and packet hex dumps bypass the ux helpers, so they never get a
--debug timestamp and leave gaps in the protocol timeline.
Route them through shared logging via new warn and die helpers that
keep the program-name prefix, errno text, and exit status. Output
without --debug is unchanged and hex dumps stay visible in both modes.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
The error prefix comes from __progname, a BSD-ism that glibc and the
Apple libc export but Windows lacks, so qdl.c and every unit test that
links util.c define their own copy. The nbdkit plugin links neither.
Keep the name in ux.c with a "qdl" default and set it through
ux_set_progname(): from argv[0] in main() and from the plugin's load
hook. Move print_version() into qdl.c, its only caller, so util.c and
the tests no longer need the symbol.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
Debug logs give no indication of when a message was emitted, which
makes stalls and timeouts hard to pin down and host activity hard to
correlate with device logs.
Prefix every message with the local time at millisecond resolution
when --debug is enabled. Keep multi-line messages aligned and track
partial lines per stream so split messages stay readable. Output
without --debug is unchanged.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
UFS provisioning drives the programmer with three <ufs> tags: a common
tag, one or more body tags, and an epilogue. The epilogue is sent twice
- first with commit=0 to validate the requested layout, then with
commit=1 to actually write the UFS configuration descriptor to the
device. All of these tags went through firehose_send_single_tag(),
which waited only 5s for the <response value="ACK"/>.
The commit=1 epilogue is the only expensive step: it makes the
programmer write the configuration descriptor to the device, which can
take considerably longer than 5s. When it does, the device emits its
"Calling handler for ufs" log but has not answered with an ACK yet, so
firehose_read() times out, firehose_send_single_tag() reports the tag
as failed, and provisioning is aborted even though the device is still
working. The program/erase write-back paths already use a 120s timeout
for exactly this reason; the UFS commit needs the same treatment.
Thread a timeout into firehose_send_single_tag() and use a short 5s
wait for the cheap common/body/validation tags while giving the commit
epilogue a 120s window. The commit=0 validation pass keeps the short
timeout.
Observed failure before the fix:
$ qdl --storage ufs prog_firehose_ddr.elf provision_ufs31.xml --debug
...
FIREHOSE WRITE: <?xml version="1.0"?>
<data><ufs LUNtoGrow="0" commit="1"/></data>
FIREHOSE READ: <?xml version="1.0" encoding="UTF-8" ?>
<data>
<log value="INFO: Calling handler for ufs" /></data>
LOG: INFO: Calling handler for ufs
ufs request failed
failed to apply ufs epilogue
UFS provisioning failed
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
How a positional argument is classified - verb, rawprogram, patch,
read, ufs or contents document - decides the whole shape of a flashing
run, yet the logic lived as private helpers of the CLI front-end where
no test could reach it, and misclassification bugs (an erase-only
rawprogram failing as "unknown file type") could only be found by
flashing. Give the classification its own module so it can be tested
directly. The contents.xml sniff used by the sahara-archive subcommand
is the same kind of decision and moves along with it.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
decode_backend() (a --backend value to enum) and qdl_split_specifier()
(splitting "<file>::<selector>") were static string parsers trapped in
qdl.c, which cannot be unit-tested because qdl.c defines main(). Move
them to util.c alongside the other argument parsers (parse_storage_
address, decode_storage_type) and declare them in qdl.h. Pure code
move, no behaviour change.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
The archive decoder parses an untrusted blob with hand-rolled bounds
checks, and the audit found real holes there - unvalidated image ids
and entry names among them. Those hardened paths could previously only
be exercised by handing qdl a corrupt archive on the command line.
With the decoder extracted into its own module, craft newc archives in
memory and pin the contract: a valid archive maps its images, and a
truncated header, an out-of-range or zero image id and an unterminated
name are each rejected without touching the image table.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
qdl.c has grown into the tool's junk drawer, and the Sahara programmer
plumbing is its largest self-contained tenant: the specifier-to-image
mapping, the CPIO archive decoder and, since the sahara-archive
subcommand arrived, the matching writer. None of it depends on the CLI
front-end it lives in, but burying it there couples it to main()'s
compilation unit, keeps the decoder and writer of the same format at
opposite ends of a 1500-line file, and puts the logic out of unit
tests' reach. Move the lot into programmer.c, where the format has one
home and the front-end shrinks to argument handling.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
The loader's failure handling is exactly what the context refactor
changed, and nothing exercised it before - the module globals made
the loader untestable, so its error paths could only be reached with
a malformed provisioning XML in a real flashing session. Pin the new
contract while it is fresh: a malformed document must leave the
context empty rather than half-populated, cleanup must be safe to
repeat, and under ASAN the error paths must leak nothing.
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>