diff options
author | Tom Wai-Hong Tam <waihong@chromium.org> | 2011-06-28 15:16:57 +0800 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2011-08-29 10:39:38 -0700 |
commit | c74acad6927b8c04c980f426ff68d11c4fabf12c (patch) | |
tree | 0176c966fd8528a415c06c86582db2c1293e2893 /lib/vbexport | |
parent | 0fa7ed0cd9d11aca7f9b6a989a7c27ceeffbb4d7 (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/Makefile | 3 | ||||
-rw-r--r-- | lib/vbexport/boot_device.c | 155 |
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; +} |