summaryrefslogtreecommitdiff
path: root/lib/vbexport
diff options
context:
space:
mode:
authorTom Wai-Hong Tam <waihong@chromium.org>2011-06-28 15:16:57 +0800
committerSimon Glass <sjg@chromium.org>2011-08-29 10:39:38 -0700
commitc74acad6927b8c04c980f426ff68d11c4fabf12c (patch)
tree0176c966fd8528a415c06c86582db2c1293e2893 /lib/vbexport
parent0fa7ed0cd9d11aca7f9b6a989a7c27ceeffbb4d7 (diff)
CHROMIUM: Implement get and free disk info for vboot_wrapper APIs.
Some notes: - Currently there is a bug when initializing the external SD card, returning "mmc_prepare_data: Unaligned data, using slower bounce buffer". We can't test it in a real hardware. Since it shares the same interface as the internal MMC disk. So supposely it should work. - We now fill "MMC"/"USB" as the optional name string in VbDiskInfo for use in debug. - A manual test is also added for debug. BUG=chromium-os:16543 TEST=Build u-boot and put it in seaboard. Insert 3 USB sticks and run: Tegra2 (SeaBoard) # vbexport_test diskinfo Detecting all fixed disks... Requested clock rate 52000000 not honored (got 48000000) handle byte/lba lba_count f name 3fbcb850 512 15638528 2 MMC Detecting all removable disks... Card did not respond to voltage select! boot_device: Unable to init MMC dev 1. USB: Register 10011 NbrPorts 1 USB EHCI 1.00 scanning bus for devices... 5 USB Device(s) found scanning bus for storage devices... 3 Storage Device(s) found handle byte/lba lba_count f name 3fbcad28 512 31512576 1 USB 3fbcad94 512 31375360 1 USB 3fbcae00 512 30883840 1 USB Change-Id: I40822716d7e48efb321b6d33e61a6bf32e5d81cc Reviewed-on: http://gerrit.chromium.org/gerrit/2835 Tested-by: Tom Wai-Hong Tam <waihong@chromium.org> Reviewed-by: Che-Liang Chiou <clchiou@chromium.org>
Diffstat (limited to 'lib/vbexport')
-rw-r--r--lib/vbexport/Makefile3
-rw-r--r--lib/vbexport/boot_device.c155
2 files changed, 157 insertions, 1 deletions
diff --git a/lib/vbexport/Makefile b/lib/vbexport/Makefile
index ddce655554..5881cc96de 100644
--- a/lib/vbexport/Makefile
+++ b/lib/vbexport/Makefile
@@ -12,8 +12,9 @@ include $(TOPDIR)/config.mk
LIB = $(obj)libvbexport.a
-COBJS-$(CONFIG_VBOOT_WRAPPER) += utility.o
+COBJS-$(CONFIG_VBOOT_WRAPPER) += boot_device.o
COBJS-$(CONFIG_VBOOT_WRAPPER) += tlcl_stub.o
+COBJS-$(CONFIG_VBOOT_WRAPPER) += utility.o
COBJS := $(COBJS-y)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/lib/vbexport/boot_device.c b/lib/vbexport/boot_device.c
new file mode 100644
index 0000000000..f32b34e686
--- /dev/null
+++ b/lib/vbexport/boot_device.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+#include <common.h>
+#include <mmc.h>
+#include <part.h>
+#include <usb.h>
+#include <linux/list.h>
+
+/* Import the header files from vboot_reference. */
+#include <vboot_api.h>
+
+#define PREFIX "boot_device: "
+
+/*
+ * Total number of storage devices, USB + MMC + reserved.
+ * MMC is 2 now. Reserve extra 3 for margin of safety.
+ */
+#define MAX_DISK_INFO (USB_MAX_STOR_DEV + 2 + 3)
+
+static uint32_t get_dev_flags(const block_dev_desc_t *dev)
+{
+ return dev->removable ? VB_DISK_FLAG_REMOVABLE : VB_DISK_FLAG_FIXED;
+}
+
+static const char *get_dev_name(const block_dev_desc_t *dev)
+{
+ /*
+ * See the definitions of IF_TYPE_* in /include/part.h.
+ * 8 is max size of strings, the "UNKNOWN".
+ */
+ static const char all_disk_types[IF_TYPE_MAX][8] = {
+ "UNKNOWN", "IDE", "SCSI", "ATAPI", "USB",
+ "DOC", "MMC", "SD", "SATA"};
+
+ if (dev->if_type >= IF_TYPE_MAX) {
+ return all_disk_types[0];
+ }
+ return all_disk_types[dev->if_type];
+}
+
+static void fill_disk_info(const block_dev_desc_t *dev, VbDiskInfo *info_ptr)
+{
+ info_ptr->handle = (VbExDiskHandle_t)dev;
+ info_ptr->bytes_per_lba = dev->blksz;
+ info_ptr->lba_count = dev->lba;
+ info_ptr->flags = get_dev_flags(dev);
+ info_ptr->name = get_dev_name(dev);
+}
+
+static int add_disk_info(const block_dev_desc_t *dev, VbDiskInfo *infos,
+ uint32_t *count_ptr)
+{
+ if (*count_ptr >= MAX_DISK_INFO) {
+ VbExDebug(PREFIX "Too many storage devices "
+ "registered, > %d.\n", MAX_DISK_INFO);
+ return 1;
+ }
+
+ fill_disk_info(dev, &infos[*count_ptr]);
+ (*count_ptr)++;
+ return 0;
+}
+
+static void init_usb_storage(void)
+{
+ /*
+ * We should stop all USB devices first. Otherwise we can't detect any
+ * new devices.
+ */
+ usb_stop();
+
+ if (usb_init() >= 0)
+ usb_stor_scan(/*mode=*/1);
+}
+
+VbError_t VbExDiskGetInfo(VbDiskInfo** infos_ptr, uint32_t* count,
+ uint32_t disk_flags)
+{
+ VbDiskInfo *infos;
+ struct mmc *m;
+ block_dev_desc_t *d;
+ int i;
+
+ infos = (VbDiskInfo *)VbExMalloc(sizeof(VbDiskInfo) * MAX_DISK_INFO);
+ *infos_ptr = infos;
+ *count = 0;
+
+ /* Detect all SD/MMC devices. */
+ for (i = 0; (m = find_mmc_device(i)) != NULL; i++) {
+ uint32_t flags = get_dev_flags(&m->block_dev);
+
+ /* Skip this entry if the flags are not matched. */
+ if (!(flags & disk_flags))
+ continue;
+
+ /* Skip this entry if it is unable to initialize. */
+ if (mmc_init(m)) {
+ VbExDebug(PREFIX "Unable to init MMC dev %d.\n", i);
+ continue;
+ }
+
+ if (add_disk_info(&m->block_dev, infos, count)) {
+ /*
+ * If too many storage devices registered,
+ * returns as many disk infos as we could
+ * handle.
+ */
+ return 1;
+ }
+ }
+
+ /* To speed up, skip detecting USB if not require removable devices. */
+ if (disk_flags & VB_DISK_FLAG_REMOVABLE) {
+ /* Detect all USB storage devices. */
+ init_usb_storage();
+ for (i = 0; (d = usb_stor_get_dev(i)) != NULL; i++) {
+ uint32_t flags = get_dev_flags(d);
+
+ /* Skip this entry if the flags are not matched. */
+ if (!(flags & disk_flags))
+ continue;
+
+ if (add_disk_info(&m->block_dev, infos, count)) {
+ /*
+ * If too many storage devices registered,
+ * returns as many disk infos as we could
+ * handle.
+ */
+ return 1;
+ }
+ }
+ }
+
+ if (*count == 0) {
+ VbExFree(infos);
+ infos = NULL;
+ }
+
+ return VBERROR_SUCCESS;
+}
+
+VbError_t VbExDiskFreeInfo(VbDiskInfo *infos, VbExDiskHandle_t preserve_handle)
+{
+ /* We do nothing for preserve_handle as we keep all the devices on. */
+ VbExFree(infos);
+ return VBERROR_SUCCESS;
+}