mirror of
				https://source.denx.de/u-boot/u-boot.git
				synced 2025-11-03 18:01:41 +01:00 
			
		
		
		
	uclass_find_first_device() may return NULL if no device for the uclass
exists. Handle this case gracefully.
Addresses-Coverity: CID 356244 ("Null pointer dereferences (FORWARD_NULL)")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
		
	
			
		
			
				
	
	
		
			120 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// SPDX-License-Identifier: GPL-2.0
 | 
						|
/*
 | 
						|
 * Verified Boot for Embedded (VBE) access functions
 | 
						|
 *
 | 
						|
 * Copyright 2022 Google LLC
 | 
						|
 * Written by Simon Glass <sjg@chromium.org>
 | 
						|
 */
 | 
						|
 | 
						|
#include <common.h>
 | 
						|
#include <bootmeth.h>
 | 
						|
#include <bootstd.h>
 | 
						|
#include <dm.h>
 | 
						|
#include <image.h>
 | 
						|
#include <vbe.h>
 | 
						|
#include <dm/uclass-internal.h>
 | 
						|
 | 
						|
/**
 | 
						|
 * is_vbe() - Check if a device is a VBE method
 | 
						|
 *
 | 
						|
 * @dev: Device to check
 | 
						|
 * @return true if this is a VBE bootmth device, else false
 | 
						|
 */
 | 
						|
static bool is_vbe(struct udevice *dev)
 | 
						|
{
 | 
						|
	return !strncmp("vbe", dev->driver->name, 3);
 | 
						|
}
 | 
						|
 | 
						|
int vbe_find_next_device(struct udevice **devp)
 | 
						|
{
 | 
						|
	for (uclass_find_next_device(devp);
 | 
						|
	     *devp;
 | 
						|
	     uclass_find_next_device(devp)) {
 | 
						|
		if (is_vbe(*devp))
 | 
						|
			return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int vbe_find_first_device(struct udevice **devp)
 | 
						|
{
 | 
						|
	uclass_find_first_device(UCLASS_BOOTMETH, devp);
 | 
						|
	if (!*devp || is_vbe(*devp))
 | 
						|
		return 0;
 | 
						|
 | 
						|
	return vbe_find_next_device(devp);
 | 
						|
}
 | 
						|
 | 
						|
int vbe_list(void)
 | 
						|
{
 | 
						|
	struct bootstd_priv *std;
 | 
						|
	struct udevice *dev;
 | 
						|
	int ret;
 | 
						|
 | 
						|
	ret = bootstd_get_priv(&std);
 | 
						|
	if (ret)
 | 
						|
		return ret;
 | 
						|
 | 
						|
	printf("%3s  %-3s  %-15s  %-15s %s\n", "#", "Sel", "Device", "Driver",
 | 
						|
	       "Description");
 | 
						|
	printf("%3s  %-3s  %-15s  %-15s %s\n", "---", "---", "--------------",
 | 
						|
	       "--------------", "-----------");
 | 
						|
	for (ret = vbe_find_first_device(&dev); dev;
 | 
						|
	     ret = vbe_find_next_device(&dev)) {
 | 
						|
		const struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
 | 
						|
 | 
						|
		printf("%3d  %-3s  %-15s  %-15s %s\n", dev_seq(dev),
 | 
						|
		       std->vbe_bootmeth == dev ? "*" : "", dev->name,
 | 
						|
		       dev->driver->name, plat->desc);
 | 
						|
	}
 | 
						|
	printf("%3s  %-3s  %-15s  %-15s %s\n", "---", "---", "--------------",
 | 
						|
	       "--------------", "-----------");
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int vbe_select(struct udevice *dev)
 | 
						|
{
 | 
						|
	struct bootstd_priv *std;
 | 
						|
	int ret;
 | 
						|
 | 
						|
	ret = bootstd_get_priv(&std);
 | 
						|
	if (ret)
 | 
						|
		return ret;
 | 
						|
	std->vbe_bootmeth = dev;
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int vbe_find_by_any(const char *name, struct udevice **devp)
 | 
						|
{
 | 
						|
	struct udevice *dev;
 | 
						|
	int ret, seq;
 | 
						|
	char *endp;
 | 
						|
 | 
						|
	seq = simple_strtol(name, &endp, 16);
 | 
						|
 | 
						|
	/* Select by name */
 | 
						|
	if (*endp) {
 | 
						|
		ret = uclass_get_device_by_name(UCLASS_BOOTMETH, name, &dev);
 | 
						|
		if (ret) {
 | 
						|
			printf("Cannot probe VBE bootmeth '%s' (err=%d)\n", name,
 | 
						|
			       ret);
 | 
						|
			return ret;
 | 
						|
		}
 | 
						|
 | 
						|
	/* select by number */
 | 
						|
	} else {
 | 
						|
		ret = uclass_get_device_by_seq(UCLASS_BOOTMETH, seq, &dev);
 | 
						|
		if (ret) {
 | 
						|
			printf("Cannot find '%s' (err=%d)\n", name, ret);
 | 
						|
			return ret;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	*devp = dev;
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 |