Commit 6b4baa85 authored by Julius Werner's avatar Julius Werner Committed by chrome-bot
Browse files

vboot: Update block devices from VbExKeyboardRead() to fix SD detection

The problem with SD cards is that you need to keep track of removals and
reinsertions so that you know when you have to fully reinitialize it. In
depthcharge, we do that by maintaining a 'present' member in the MMC
controller object. On every update() call to the controller, we check if
the previously known 'present' state still matches the current
card_detect pin value, and if it doesn't we handle the respective
insertion or removal.

This works fine in recovery mode: vboot keeps checking for new media
automatically every second, so we regularly call update() on all our
removable block device controllers. But in dev mode, vboot only asks us
to do that when it reads an explicit Ctrl+U from the user. This creates
a problem when the user inserts an SD card with an invalid image,
presses Ctrl+U (vboot sees that the image is invalid and beeps),
replaces the SD card with a different one and presses Ctrl+U again. We
only call update() twice on the block device controller in this case,
and in both cases there is a card present. The driver has no chance to
notice that it is no longer the same card and has to be reinitialized.

It's hard to solve this in a good way: we could make it the
responsibility of the individual MMC controller driver to track this
(through some sort of controller-internal hardware latch), but it's
unclear whether all controllers could support that, and it would have to
be fixed in every single controller driver individually. We could also
change the vboot API to add an explicit polling function that tells
depthcharge to update this state, but that seems overkill at a time
where we're thinking about moving away from depthcharge at some point
anyway (towards a solution that probably wouldn't have this problem).

This patch implements the quick and dirty fix of updating removable
block device controllers in the only continuously polled vboot callback
we have in dev mode, which is VbExKeyboardRead(). It's not exactly a
clean solution from a design standpoint, but it'll work. USB storage
devices essentially get the same treatment already because libpayload
unconditionally calls usb_poll() as part of havechar()... so it's not
really any worse than what we already have, just in a different place.

TEST=Boot an Elm, plug in a uSD card without a good image, press Ctrl+U,
replace SD card with one that has a good image, press Ctrl+U again,
watch it boot.

Change-Id: I729a37028140f354478422078804e750079a4c23
Signed-off-by: default avatarJulius Werner <>

Reviewed-by: default avatarAaron Durbin <>
Reviewed-by: default avatarFurquan Shaikh <>
parent c6339008
......@@ -109,6 +109,7 @@ int get_all_bdevs(blockdev_type_t type, ListNode **bdevs)
for (ListNode *node = devs->next; node; node = node->next, count++)
*bdevs = devs;
if (bdevs)
*bdevs = devs;
return count;
......@@ -21,6 +21,7 @@
#include <vboot/util/flag.h>
#include "debug/dev.h"
#include "drivers/storage/blockdev.h"
#define CSI_0 0x1B
#define CSI_1 0x5B
......@@ -40,6 +41,12 @@ uint32_t VbExKeyboardRead(void)
uint64_t timer_start;
// This is the only callback the vboot UI will continuously poll in dev
// mode. We need to update SD storage controllers to detect insertion or
// removal somewhere, and this is the only place we have, so we need to
// do it here even though it doesn't really fit well.
// No input, just give up.
if (!havechar())
return 0;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment