The nbdkit plugin is undiscoverable without documentation. Describe how to
build it with meson (including the nbdkit development dependency) and walk
through serving a LUN end to end: starting nbdkit, confirming the export
with nbdinfo, attaching it to /dev/nbdN with nbd-client, and reading it,
plus a warning that writes go straight to the device's flash.
The walkthrough lives in docs/nbd.md to keep the ever growing README lean;
the README gets a short section pointing to it, and the markdown-lint
wrapper now lints everything under docs/ so future documents are covered
automatically.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
Inspecting or editing a device's flash previously meant dumping partitions
to files and reflashing them; there was no way to treat the live storage as
a random-access block device. Exposing a LUN over nbdkit lets ordinary host
tools - parted, mount, dd, imaging tools - operate on it directly.
Add an nbdkit plugin that uploads the firehose programmer and serves a
physical partition (LUN) as a read/write block device:
$ modprobe nbd
$ nbdkit -fv ./nbdkit-qdl-plugin.so programmer=prog_firehose_ddr.elf lun=0
meson builds it only when the nbdkit dependency is present (pass
-Dnbdkit=enabled to require it), producing nbdkit-qdl-plugin.so from the
shared qdl sources; the qdl binary is unaffected.
An EDL device can only be programmed once per session - uploading the
programmer is a one-shot transition and a reset reboots it out of firehose
- but nbdkit calls .open/.close several times per client (NBD_OPT_INFO to
probe, then NBD_OPT_GO to transfer). Programming per open and resetting per
close therefore made the first close reboot the board and every later open
time out. To solve this the plugin sets the device up once, on the first
open, keeps it configured across connections, and resets it only when the
plugin unloads.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
The firehose layer only drives file-oriented flashing: <program>/<read>
operations described by XML and executed as an op list. Nothing let an
in-process consumer configure the programmer on its own, learn how large a
LUN is, or read and write arbitrary sector ranges to and from memory
buffers.
The upcoming nbdkit plugin needs exactly that - random-access block I/O
against a live device - so add the missing primitives:
- firehose_open() configure the programmer without running any ops
- firehose_getsize() report a LUN's sector size and count, parsed from
the <getstorageinfo> JSON response
- firehose_pread() read a sector range into a buffer, reusing the
chunked read path
- firehose_pwrite() write a buffer to a sector range, streaming it in
max_payload_size chunks
- firehose_reset() made non-static, out-of-tree callers can reuse it
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
Per user request, use pkg-config instead of xml2-config when generating
cflags and ldflags.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Assumed to be a remnant of early development lead to a recent transition
of "start_sector" from being represented as a string to an integer. But
it turns out that "start_sector" might be an expression, e.g. to write
something at the end of the disk.
So transition back to carry "start_sector" as a string.
Fixes: b6e0ea31d7 ("program: Make start_sector unsigned in")
Reported-by: Julien Robin
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
On db410c writes sometimes fails becasue the device had more log entries
to read after the <response> and refuses writes until these are drained.
Deal with this by attempting a read when write fails with a timeout.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
WIth the transition from qcserial to USBFS we no longer receive multiple
messages in a single read, so we can remove the code that decode the
buffer piecemeal.
While reworking this, also introduce a mechanism so that the parsers can
pass values back to the caller of the read.
And modify the timeout handling so that the caller always has to pass a
timeout, and bump the timeouts slightly, as they are all fatal anyways.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
qdl_write() is always called with eot=true, so drop the parameter.
As a length of 0 means we're not entering the loop and we're now always
entering the conditonal block at the end we can remove the first chunk.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
NAND based devices comes with a few minor tweaks to the program tag and
an additional erase tag, split the program code and add the handling of
the erase tag.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Remove the dummy sleep and reliance on USB read timeout while waiting
for the firehose payload to launch by rolling our own timeout handling
in firehose_read. While at it extend the firehose program timeouts, to
avoid issues seen when these operations for some reason takes a little
bit longer to return.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
The SDX55 shows up with bInterfaceProtocol of 17, so allow this to get
past the USB filtering routine.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
The downstream tool has a 3 second delay to allow the firehose payload
to boot. Adding the same makes db820c successfully enter firehose mode.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Upon booting the firehose payload some platforms will issue log messages
others won't. Rather than waiting for 10 seconds on the ones that
doesn't wait only for a second.
Hopefully this is long enough, but the firmware synchronization and
handling of incoming log messages should be reviewed further.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
It's perfectly normal to "poll" for incoming messages, so silence the
warning printout in the usb accessor functions.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
On db410c the target sends log entries after the response and refuse to
serve any subsequent requests until these are consumed, so continue
reading log entries until we get a timeout.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
A full build will contain both xbl_a and xbl_b, so matching on the
prefix of "xbl" will find two entries which we consider invalid.
Explicitly search for "xbl_a" instead.
Fixes: 5ea1e20c01 ("program: Match xbl in a/b scenarios")
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Add support back for waiting for an EDL device to appear. This is useful
when paired with some automation scripts that introduces "arbitrary"
delays in the process of entering EDL mode.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
The nop was added to mitigate the fact that there's a rather long delay
in the response when sending out the first command. Increasing the write
timeout removes this problem and it's possible to just send the
configure as the first command without issues.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
On devices implementing a/b updates the xbl partiiton will be named
xbl_a and xbl_b, extend the match for finding the bootable partition to
support this.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
It was assumed that we should send all the data following a "program"
request to the device, before sending a ZLP. But on SDM845 it's seen
that not sending a ZLP after each chunk sometimes causes the
communication to stall.
Given that the "program" request already carries the information about
how much data will be transferred there should be no issues with sending
additional ZLPs, so do this.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
On some newer platforms the device ignore the configure request to
disable ZLP, causing the Firehose program request to stall, when the
device is waiting for a ZLP to end a transfer.
Mitigate this by circumventing the qcserial driver and drive the USB
traffic directly using USBFS. The tool will attempt to detach qcserial
from the device, in case it's already attached, so no changes are needed
in the kernel or system configuration.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
In the case that we find a "data" tag, but not a "program" or "ufs"
child node type might have been left unitialized. Fix this by
initializing type.
Also fix up the styling of the multiline blocks.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Follow the behavior of the other flash tools and skip partitions with no
filename, instead of filling them with zeros. This reduces the flash
time considerably for some set of xml files.
Also clean up firehose_program() as we no longer need to support calling
this function with an invalid fd.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
When the host propose a larger payload size than the device accepts the
device will respond with a NACK, containing the maximum payload size.
Similarily the ACK will contain the supported max if the host requests a
lower value than the device supports.
In both cases we pick the largest possible value and send a second
configure message to select this payload size.
Reported-by: Kirill Kapranov <c_kkapra@qti.qualcomm.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
The max payload size is negotiated through the configure and configure
response messages. Update the max payload size based on the
configuration response value, if present.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
During program it's recommended to reduce the num_sectors to only cover
the sectors containing data to be written and not write zero-block in
the rest. This reduce the time spent sending unnecessary blocks of
zeros.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Reduce the number of write operations by batching up sectors in a
max_payload_size sized buffer and write them in one chunk. Using the
qcserial driver will still chop up the USB traffic in 4kB chunks, so no
measurable perfomance improvement is seen.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
The MaxPayloadSizeToTargetInBytes parameter of the configure command is
supposed to set the maximum size of the transfer unit. This size is
however limited by the use of the in-kernel qcserial driver and the use
of sector-sized writes. Yet increasing it, drastically bumps the
transfer speed, so leave it high.
NB. The max payload size supported by the device is part of the
configure response, if the device supports a value less than the
requested size - which we just ignore today.
Suggested-by: Kirill Kapranov <c_kkapra@qti.qualcomm.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This bootable device is not always partition number 1. Search the
program entries for an entry that has the label xbl or sbl1 and use the
partition number to mark the boot partition bootable.
Reported-by: Kirill Kapranov <kkapra@codeaurora.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
The DONE message contains a return code denoting if the firmware is done
(1) requesting files from the host, or if there are more requests to
come (0). Unfortunately on some platforms the ROM code sends 0
regardless, so we just have to assume that we're done.
This assumes that there is only ever one image to transfer.
Reported-by: Kirill Kapranov <kkapra@codeaurora.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Rename "buf" to "path" to clarify things and increase the size to
PATH_MAX in order to silence a compile time warning the snprintf() in
find_qdl_tty() might be truncated.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Two assert incorrectly assigned the desired values rather than verify
that they where correct, fix this.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Remove some left over functions from development, they can be added back
as needed in the future.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Not all program XML tags contain the readback attribute and as we don't
care about the value at this point lets just stop caring about it for
now.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This adds a license header to all files and updates the README with
information on building the project.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Unsolicited log messages are put in the device buffer as independant xml
documents and upon reading the response packet we might get a multiple
of xml documents in one go; we must feed them to the parser one by one.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Failures to apply program or patch operations are silently ignored,
forcing the user to inspect the logs to conclude if the flashing
succeded. Instead make the operations halt execution.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>