int usb_emul_control(struct udevice *emul, struct usb_device *udev,
		     unsigned long pipe, void *buffer, int length,
		     struct devrequest *setup)
{
	struct dm_usb_ops *ops = usb_get_emul_ops(emul);
	struct usb_dev_platdata *plat;
	int ret;

	/* We permit getting the descriptor before we are probed */
	plat = dev_get_parent_platdata(emul);
	if (!ops->control)
		return -ENOSYS;
	debug("%s: dev=%s\n", __func__, emul->name);
	if (pipe == usb_rcvctrlpipe(udev, 0)) {
		switch (setup->request) {
		case USB_REQ_GET_DESCRIPTOR: {
			return usb_emul_get_descriptor(plat, setup->value,
						       buffer, length);
		}
		default:
			ret = device_probe(emul);
			if (ret)
				return ret;
			return ops->control(emul, udev, pipe, buffer, length,
					    setup);
		}
	} else if (pipe == usb_snddefctrl(udev)) {
		switch (setup->request) {
		case USB_REQ_SET_ADDRESS:
			debug("   ** set address %s %d\n", emul->name,
			      setup->value);
			plat->devnum = setup->value;
			return 0;
		default:
			debug("requestsend =%x\n", setup->request);
			break;
		}
	} else if (pipe == usb_sndctrlpipe(udev, 0)) {
		switch (setup->request) {
		case USB_REQ_SET_CONFIGURATION:
			plat->configno = setup->value;
			return 0;
		default:
			ret = device_probe(emul);
			if (ret)
				return ret;
			return ops->control(emul, udev, pipe, buffer, length,
					    setup);
		}
	}
	debug("pipe=%lx\n", pipe);

	return -EIO;
}
예제 #2
0
/* Test that we can bind, probe, remove, unbind a driver */
static int dm_test_lifecycle(struct unit_test_state *uts)
{
	struct dm_test_state *dms = uts->priv;
	int op_count[DM_TEST_OP_COUNT];
	struct udevice *dev, *test_dev;
	int pingret;
	int ret;

	memcpy(op_count, dm_testdrv_op_count, sizeof(op_count));

	ut_assertok(device_bind_by_name(dms->root, false, &driver_info_manual,
					&dev));
	ut_assert(dev);
	ut_assert(dm_testdrv_op_count[DM_TEST_OP_BIND]
			== op_count[DM_TEST_OP_BIND] + 1);
	ut_assert(!dev->priv);

	/* Probe the device - it should fail allocating private data */
	dms->force_fail_alloc = 1;
	ret = device_probe(dev);
	ut_assert(ret == -ENOMEM);
	ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE]
			== op_count[DM_TEST_OP_PROBE] + 1);
	ut_assert(!dev->priv);

	/* Try again without the alloc failure */
	dms->force_fail_alloc = 0;
	ut_assertok(device_probe(dev));
	ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE]
			== op_count[DM_TEST_OP_PROBE] + 2);
	ut_assert(dev->priv);

	/* This should be device 3 in the uclass */
	ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev));
	ut_assert(dev == test_dev);

	/* Try ping */
	ut_assertok(test_ping(dev, 100, &pingret));
	ut_assert(pingret == 102);

	/* Now remove device 3 */
	ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]);
	ut_assertok(device_remove(dev));
	ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]);

	ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
	ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]);
	ut_assertok(device_unbind(dev));
	ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
	ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]);

	return 0;
}
예제 #3
0
static void serial_find_console_or_panic(void)
{
#ifdef CONFIG_OF_CONTROL
	int node;

	/* Check for a chosen console */
	node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path");
	if (node < 0)
		node = fdtdec_get_alias_node(gd->fdt_blob, "console");
	if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &cur_dev))
		return;

	/*
	 * If the console is not marked to be bound before relocation, bind
	 * it anyway.
	 */
	if (node > 0 &&
	    !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &cur_dev)) {
		if (!device_probe(cur_dev))
			return;
		cur_dev = NULL;
	}
#endif
	/*
	 * Failing that, get the device with sequence number 0, or in extremis
	 * just the first serial device we can find. But we insist on having
	 * a console (even if it is silent).
	 */
	if (uclass_get_device_by_seq(UCLASS_SERIAL, 0, &cur_dev) &&
	    (uclass_first_device(UCLASS_SERIAL, &cur_dev) || !cur_dev))
		panic("No serial driver found");
}
예제 #4
0
파일: virtio_pci.c 프로젝트: 2asoft/freebsd
static void
vtpci_probe_and_attach_child(struct vtpci_softc *sc)
{
	device_t dev, child;

	dev = sc->vtpci_dev;
	child = sc->vtpci_child_dev;

	if (child == NULL)
		return;

	if (device_get_state(child) != DS_NOTPRESENT)
		return;

	if (device_probe(child) != 0)
		return;

	vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER);
	if (device_attach(child) != 0) {
		vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_FAILED);
		vtpci_reset(sc);
		vtpci_release_child_resources(sc);
		/* Reset status for future attempt. */
		vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_ACK);
	} else {
		vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER_OK);
		VIRTIO_ATTACH_COMPLETED(child);
	}
}
예제 #5
0
/* Test that the bus ops are called when a child is probed/removed */
static int dm_test_bus_parent_ops(struct dm_test_state *dms)
{
	struct dm_test_parent_data *parent_data;
	struct udevice *bus, *dev;
	struct uclass *uc;

	test_state = dms;
	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
	ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));

	uclass_foreach_dev(dev, uc) {
		/* Ignore these if they are not on this bus */
		if (dev->parent != bus)
			continue;
		ut_asserteq_ptr(NULL, dev_get_parentdata(dev));

		ut_assertok(device_probe(dev));
		parent_data = dev_get_parentdata(dev);
		ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
	}

	uclass_foreach_dev(dev, uc) {
		/* Ignore these if they are not on this bus */
		if (dev->parent != bus)
			continue;
		parent_data = dev_get_parentdata(dev);
		ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
		ut_assertok(device_remove(dev));
		ut_asserteq_ptr(NULL, dev_get_parentdata(dev));
		ut_asserteq_ptr(dms->removed, dev);
	}
	test_state = NULL;

	return 0;
}
예제 #6
0
파일: clk.c 프로젝트: Noltari/u-boot
int __weak soc_clk_dump(void)
{
#if defined(CONFIG_DM) && defined(CONFIG_CLK)
	struct udevice *dev;
	struct uclass *uc;
	struct clk clk;
	int ret;

	/* Device addresses start at 1 */
	ret = uclass_get(UCLASS_CLK, &uc);
	if (ret)
		return ret;

	uclass_foreach_dev(dev, uc) {
		memset(&clk, 0, sizeof(clk));
		ret = device_probe(dev);
		if (ret) {
			printf("%-30.30s : ? Hz\n", dev->name);
			continue;
		}

		ret = clk_request(dev, &clk);
		if (ret) {
			printf("%-30.30s : ? Hz\n", dev->name);
			continue;
		}

		printf("%-30.30s : %lu Hz\n", dev->name, clk_get_rate(&clk));

		clk_free(&clk);
	}
예제 #7
0
/*
 * Test that the bus' uclass' child_pre_probe() is called before the
 * device's probe() method
 */
static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts)
{
	struct udevice *bus, *dev;
	int child_count;

	/*
	 * See testfdt_drv_probe() which effectively checks that the uclass
	 * flag is set before that method is called
	 */
	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
	for (device_find_first_child(bus, &dev), child_count = 0;
	     dev;
	     device_find_next_child(&dev)) {
		struct dm_test_priv *priv = dev_get_priv(dev);

		/* Check that things happened in the right order */
		ut_asserteq_ptr(NULL, priv);
		ut_assertok(device_probe(dev));

		priv = dev_get_priv(dev);
		ut_assert(priv != NULL);
		ut_asserteq(1, priv->uclass_flag);
		ut_asserteq(1, priv->uclass_total);
		child_count++;
	}
	ut_asserteq(3, child_count);

	return 0;
}
예제 #8
0
int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp)
{
	struct udevice *dev;

	debug("%s: Searching bus '%s' for address %02x: ", __func__,
	      bus->name, chip_addr);
	for (device_find_first_child(bus, &dev); dev;
			device_find_next_child(&dev)) {
		struct dm_i2c_chip store;
		struct dm_i2c_chip *chip = dev_get_parentdata(dev);
		int ret;

		if (!chip) {
			chip = &store;
			i2c_chip_ofdata_to_platdata(gd->fdt_blob,
						    dev->of_offset, chip);
		}
		if (chip->chip_addr == chip_addr) {
			ret = device_probe(dev);
			debug("found, ret=%d\n", ret);
			if (ret)
				return ret;
			*devp = dev;
			return 0;
		}
	}
	debug("not found\n");
	return i2c_bind_driver(bus, chip_addr, devp);
}
예제 #9
0
static int syscon_probe_by_ofnode(ofnode node, struct udevice **devp)
{
	struct udevice *dev, *parent;
	int ret;

	/* found node with "syscon" compatible, not bounded to SYSCON UCLASS */
	if (!ofnode_device_is_compatible(node, "syscon")) {
		dev_dbg(dev, "invalid compatible for syscon device\n");
		return -EINVAL;
	}

	/* bound to driver with same ofnode or to root if not found */
	if (device_find_global_by_ofnode(node, &parent))
		parent = dm_root();

	/* force bound to syscon class */
	ret = device_bind_driver_to_node(parent, "syscon",
					 ofnode_get_name(node),
					 node, &dev);
	if (ret) {
		dev_dbg(dev, "unable to bound syscon device\n");
		return ret;
	}
	ret = device_probe(dev);
	if (ret) {
		dev_dbg(dev, "unable to probe syscon device\n");
		return ret;
	}

	*devp = dev;
	return 0;
}
예제 #10
0
int dm_init(void)
{
	int ret;

	if (gd->dm_root) {
		dm_warn("Virtual root driver already exists!\n");
		return -EINVAL;
	}
	INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);

#if defined(CONFIG_NEEDS_MANUAL_RELOC)
	fix_drivers();
	fix_uclass();
#endif

	ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);
	if (ret)
		return ret;
#if CONFIG_IS_ENABLED(OF_CONTROL)
	DM_ROOT_NON_CONST->of_offset = 0;
#endif
	ret = device_probe(DM_ROOT_NON_CONST);
	if (ret)
		return ret;

	return 0;
}
예제 #11
0
/*
 * Find the udevice that either has the name passed in as devname or has an
 * alias named devname.
 */
struct udevice *eth_get_dev_by_name(const char *devname)
{
	int seq = -1;
	char *endp = NULL;
	const char *startp = NULL;
	struct udevice *it;
	struct uclass *uc;
	int len = strlen("eth");

	/* Must be longer than 3 to be an alias */
	if (!strncmp(devname, "eth", len) && strlen(devname) > len) {
		startp = devname + len;
		seq = simple_strtoul(startp, &endp, 10);
	}

	uclass_get(UCLASS_ETH, &uc);
	uclass_foreach_dev(it, uc) {
		/*
		 * We need the seq to be valid, so try to probe it.
		 * If the probe fails, the seq will not match since it will be
		 * -1 instead of what we are looking for.
		 * We don't care about errors from probe here. Either they won't
		 * match an alias or it will match a literal name and we'll pick
		 * up the error when we try to probe again in eth_set_dev().
		 */
		if (device_probe(it))
			continue;
		/* Check for the name or the sequence number to match */
		if (strcmp(it->name, devname) == 0 ||
		    (endp > startp && it->seq == seq))
			return it;
	}

	return NULL;
}
예제 #12
0
/* Test that the bus can store data about each child */
static int test_bus_parent_data(struct unit_test_state *uts)
{
	struct dm_test_parent_data *parent_data;
	struct udevice *bus, *dev;
	struct uclass *uc;
	int value;

	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));

	/* Check that parent data is allocated */
	ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
	ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
	ut_assertok(device_get_child_by_seq(bus, 0, &dev));
	parent_data = dev_get_parent_priv(dev);
	ut_assert(NULL != parent_data);

	/* Check that it starts at 0 and goes away when device is removed */
	parent_data->sum += 5;
	ut_asserteq(5, parent_data->sum);
	device_remove(dev);
	ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));

	/* Check that we can do this twice */
	ut_assertok(device_get_child_by_seq(bus, 0, &dev));
	parent_data = dev_get_parent_priv(dev);
	ut_assert(NULL != parent_data);
	parent_data->sum += 5;
	ut_asserteq(5, parent_data->sum);

	/* Add parent data to all children */
	ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
	value = 5;
	uclass_foreach_dev(dev, uc) {
		/* Ignore these if they are not on this bus */
		if (dev->parent != bus) {
			ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
			continue;
		}
		ut_assertok(device_probe(dev));
		parent_data = dev_get_parent_priv(dev);

		parent_data->sum = value;
		value += 5;
	}

	/* Check it is still there */
	value = 5;
	uclass_foreach_dev(dev, uc) {
		/* Ignore these if they are not on this bus */
		if (dev->parent != bus)
			continue;
		parent_data = dev_get_parent_priv(dev);

		ut_asserteq(value, parent_data->sum);
		value += 5;
	}

	return 0;
}
예제 #13
0
/**
 * connman_device_register:
 * @device: device structure
 *
 * Register device with the system
 */
int connman_device_register(struct connman_device *device)
{
	__connman_storage_load_device(device);

	device->offlinemode = __connman_profile_get_offlinemode();

	return device_probe(device);
}
예제 #14
0
int axi_sandbox_get_emul(struct udevice *bus, ulong address,
			 enum axi_size_t size, struct udevice **emulp)
{
	struct udevice *dev;
	u32 reg[2];
	uint offset;

	switch (size) {
	case AXI_SIZE_8:
		offset = 1;
		break;
	case AXI_SIZE_16:
		offset = 2;
		break;
	case AXI_SIZE_32:
		offset = 4;
		break;
	default:
		debug("%s: Unknown AXI transfer size '%d'", bus->name, size);
		offset = 0;
	}

	/*
	 * Note: device_find_* don't activate the devices; they're activated
	 *	 as-needed below.
	 */
	for (device_find_first_child(bus, &dev);
	     dev;
	     device_find_next_child(&dev)) {
		int ret;

		ret = dev_read_u32_array(dev, "reg", reg, ARRAY_SIZE(reg));
		if (ret) {
			debug("%s: Could not read 'reg' property of %s\n",
			      bus->name, dev->name);
			continue;
		}

		/*
		 * Does the transfer's address fall into this device's address
		 * space?
		 */
		if (address >= reg[0] && address <= reg[0] + reg[1] - offset) {
			/* If yes, activate it... */
			if (device_probe(dev)) {
				debug("%s: Could not activate %s\n",
				      bus->name, dev->name);
				return -ENODEV;
			}

			/* ...and return it */
			*emulp = dev;
			return 0;
		}
	}

	return -ENODEV;
}
예제 #15
0
/*
 * Typically this will just store a device pointer.
 * In case it was not probed, we will attempt to do so.
 * dev may be NULL to unset the active device.
 */
void eth_set_dev(struct udevice *dev)
{
	if (dev && !device_active(dev)) {
		eth_errno = device_probe(dev);
		if (eth_errno)
			dev = NULL;
	}

	eth_get_uclass_priv()->current = dev;
}
예제 #16
0
int mp_init_cpu(struct udevice *cpu, void *unused)
{
	/*
	 * Multiple APs are brought up simultaneously and they may get the same
	 * seq num in the uclass_resolve_seq() during device_probe(). To avoid
	 * this, set req_seq to the reg number in the device tree in advance.
	 */
	cpu->req_seq = fdtdec_get_int(gd->fdt_blob, cpu->of_offset, "reg", -1);

	return device_probe(cpu);
}
예제 #17
0
/**
 * _rproc_probe_dev() - iteration helper to probe a rproc device
 * @dev:	device to probe
 * @uc_pdata:	uclass data allocated for the device
 * @data:	unused
 *
 * Return: 0 if all ok, else appropriate error value.
 */
static int _rproc_probe_dev(struct udevice *dev,
			    struct dm_rproc_uclass_pdata *uc_pdata,
			    const void *data)
{
	int ret;

	ret = device_probe(dev);

	if (ret)
		debug("%s: Failed to initialize - %d\n", dev->name, ret);
	return ret;
}
예제 #18
0
/*
 * Create a block device for a handle
 *
 * @handle	handle
 * @interface	block io protocol
 * @return	0 = success
 */
static int efi_bl_bind(efi_handle_t handle, void *interface)
{
	struct udevice *bdev, *parent = dm_root();
	int ret, devnum;
	char *name;
	struct efi_object *obj = efi_search_obj(handle);
	struct efi_block_io *io = interface;
	int disks;
	struct efi_blk_priv *priv;

	EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, io);

	if (!obj)
		return -ENOENT;

	devnum = blk_find_max_devnum(IF_TYPE_EFI);
	if (devnum == -ENODEV)
		devnum = 0;
	else if (devnum < 0)
		return devnum;

	name = calloc(1, 18); /* strlen("efiblk#2147483648") + 1 */
	if (!name)
		return -ENOMEM;
	sprintf(name, "efiblk#%d", devnum);

	/* Create driver model udevice for the EFI block io device */
	ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI, devnum,
				io->media->block_size,
				(lbaint_t)io->media->last_block, &bdev);
	if (ret)
		return ret;
	if (!bdev)
		return -ENOENT;
	/* Allocate priv */
	ret = device_probe(bdev);
	if (ret)
		return ret;
	EFI_PRINT("%s: block device '%s' created\n", __func__, bdev->name);

	priv = bdev->priv;
	priv->handle = handle;
	priv->io = interface;

	ret = blk_prepare_device(bdev);

	/* Create handles for the partions of the block device */
	disks = efi_bl_bind_partitions(handle, bdev);
	EFI_PRINT("Found %d partitions\n", disks);

	return 0;
}
int usb_emul_bulk(struct udevice *emul, struct usb_device *udev,
		  unsigned long pipe, void *buffer, int length)
{
	struct dm_usb_ops *ops = usb_get_emul_ops(emul);
	int ret;

	/* We permit getting the descriptor before we are probed */
	if (!ops->bulk)
		return -ENOSYS;
	debug("%s: dev=%s\n", __func__, emul->name);
	ret = device_probe(emul);
	if (ret)
		return ret;
	return ops->bulk(emul, udev, pipe, buffer, length);
}
예제 #20
0
파일: mp_init.c 프로젝트: OpenNoah/u-boot
int mp_init_cpu(struct udevice *cpu, void *unused)
{
	struct cpu_platdata *plat = dev_get_parent_platdata(cpu);

	/*
	 * Multiple APs are brought up simultaneously and they may get the same
	 * seq num in the uclass_resolve_seq() during device_probe(). To avoid
	 * this, set req_seq to the reg number in the device tree in advance.
	 */
	cpu->req_seq = fdtdec_get_int(gd->fdt_blob, dev_of_offset(cpu), "reg",
				      -1);
	plat->ucode_version = microcode_read_rev();
	plat->device_id = gd->arch.x86_device;

	return device_probe(cpu);
}
예제 #21
0
static void serial_find_console_or_panic(void)
{
	struct udevice *dev;

#ifdef CONFIG_OF_CONTROL
	int node;

	/* Check for a chosen console */
	node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path");
	if (node < 0)
		node = fdt_path_offset(gd->fdt_blob, "console");
	if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &dev)) {
		gd->cur_serial_dev = dev;
		return;
	}

	/*
	 * If the console is not marked to be bound before relocation, bind
	 * it anyway.
	 */
	if (node > 0 &&
	    !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &dev)) {
		if (!device_probe(dev)) {
			gd->cur_serial_dev = dev;
			return;
		}
	}
#endif
	/*
	 * Try to use CONFIG_CONS_INDEX if available (it is numbered from 1!).
	 *
	 * Failing that, get the device with sequence number 0, or in extremis
	 * just the first serial device we can find. But we insist on having
	 * a console (even if it is silent).
	 */
#ifdef CONFIG_CONS_INDEX
#define INDEX (CONFIG_CONS_INDEX - 1)
#else
#define INDEX 0
#endif
	if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) &&
	    uclass_get_device(UCLASS_SERIAL, INDEX, &dev) &&
	    (uclass_first_device(UCLASS_SERIAL, &dev) || !dev))
		panic("No serial driver found");
#undef INDEX
	gd->cur_serial_dev = dev;
}
예제 #22
0
파일: eth.c 프로젝트: Noltari/u-boot
/**
 * This test case is trying to test the following scenario:
 *	- All ethernet devices are not probed
 *	- "ethaddr" for all ethernet devices are not set
 *	- "ethact" is set to a valid ethernet device name
 *
 * With Sandbox default test configuration, all ethernet devices are
 * probed after power-up, so we have to manually create such scenario:
 *	- Remove all ethernet devices
 *	- Remove all "ethaddr" environment variables
 *	- Set "ethact" to the first ethernet device
 *
 * Do a ping test to see if anything goes wrong.
 */
static int dm_test_eth_act(struct unit_test_state *uts)
{
	struct udevice *dev[DM_TEST_ETH_NUM];
	const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000",
						"sbe5", "eth@10004000"};
	const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr",
						 "eth3addr", "eth1addr"};
	char ethaddr[DM_TEST_ETH_NUM][18];
	int i;

	memset(ethaddr, '\0', sizeof(ethaddr));
	net_ping_ip = string_to_ip("1.1.2.2");

	/* Prepare the test scenario */
	for (i = 0; i < DM_TEST_ETH_NUM; i++) {
		ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
						       ethname[i], &dev[i]));
		ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));

		/* Invalidate MAC address */
		strncpy(ethaddr[i], env_get(addrname[i]), 17);
		/* Must disable access protection for ethaddr before clearing */
		env_set(".flags", addrname[i]);
		env_set(addrname[i], NULL);
	}

	/* Set ethact to "eth@10002000" */
	env_set("ethact", ethname[0]);

	/* Segment fault might happen if something is wrong */
	ut_asserteq(-ENODEV, net_loop(PING));

	for (i = 0; i < DM_TEST_ETH_NUM; i++) {
		/* Restore the env */
		env_set(".flags", addrname[i]);
		env_set(addrname[i], ethaddr[i]);

		/* Probe the device again */
		ut_assertok(device_probe(dev[i]));
	}
	env_set(".flags", NULL);
	env_set("ethact", NULL);

	return 0;
}
예제 #23
0
int syscon_get_by_driver_data(ulong driver_data, struct udevice **devp)
{
	struct udevice *dev;
	struct uclass *uc;
	int ret;

	*devp = NULL;
	ret = uclass_get(UCLASS_SYSCON, &uc);
	if (ret)
		return ret;
	uclass_foreach_dev(dev, uc) {
		if (dev->driver_data == driver_data) {
			*devp = dev;
			return device_probe(dev);
		}
	}

	return -ENODEV;
}
예제 #24
0
static int serial_check_stdout(const void *blob, struct udevice **devp)
{
	int node;

	/* Check for a chosen console */
	node = fdtdec_get_chosen_node(blob, "stdout-path");
	if (node < 0) {
		const char *str, *p, *name;

		/*
		 * Deal with things like
		 *	stdout-path = "serial0:115200n8";
		 *
		 * We need to look up the alias and then follow it to the
		 * correct node.
		 */
		str = fdtdec_get_chosen_prop(blob, "stdout-path");
		if (str) {
			p = strchr(str, ':');
			name = fdt_get_alias_namelen(blob, str,
					p ? p - str : strlen(str));
			if (name)
				node = fdt_path_offset(blob, name);
		}
	}
	if (node < 0)
		node = fdt_path_offset(blob, "console");
	if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, devp))
		return 0;

	/*
	 * If the console is not marked to be bound before relocation, bind it
	 * anyway.
	 */
	if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
					devp)) {
		if (!device_probe(*devp))
			return 0;
	}

	return -ENODEV;
}
예제 #25
0
int notrace dm_timer_init(void)
{
	__maybe_unused const void *blob = gd->fdt_blob;
	struct udevice *dev = NULL;
	int node = -ENOENT;
	int ret;

	if (gd->timer)
		return 0;

#if !CONFIG_IS_ENABLED(OF_PLATDATA)
	/* Check for a chosen timer to be used for tick */
	node = fdtdec_get_chosen_node(blob, "tick-timer");
#endif
	if (node < 0) {
		/* No chosen timer, trying first available timer */
		ret = uclass_first_device_err(UCLASS_TIMER, &dev);
		if (ret)
			return ret;
	} else {
		if (uclass_get_device_by_of_offset(UCLASS_TIMER, node, &dev)) {
			/*
			 * If the timer is not marked to be bound before
			 * relocation, bind it anyway.
			 */
			if (node > 0 &&
			    !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
					    &dev)) {
				ret = device_probe(dev);
				if (ret)
					return ret;
			}
		}
	}

	if (dev) {
		gd->timer = dev;
		return 0;
	}

	return -ENODEV;
}
예제 #26
0
파일: scsi.c 프로젝트: frawang/u-boot
int scsi_scan_dev(struct udevice *dev, bool verbose)
{
	struct scsi_platdata *uc_plat; /* scsi controller platdata */
	int ret;
	int i;
	int lun;

	/* probe SCSI controller driver */
	ret = device_probe(dev);
	if (ret)
		return ret;

	/* Get controller platdata */
	uc_plat = dev_get_uclass_platdata(dev);

	for (i = 0; i < uc_plat->max_id; i++)
		for (lun = 0; lun < uc_plat->max_lun; lun++)
			do_scsi_scan_one(dev, i, lun, verbose);

	return 0;
}
예제 #27
0
파일: root.c 프로젝트: jhendrix/deg-uboot
int dm_init(void)
{
	int ret;

	if (gd->dm_root) {
		dm_warn("Virtual root driver already exists!\n");
		return -EINVAL;
	}
	INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);

	ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);
	if (ret)
		return ret;
#ifdef CONFIG_OF_CONTROL
	DM_ROOT_NON_CONST->of_offset = 0;
#endif
	ret = device_probe(DM_ROOT_NON_CONST);
	if (ret)
		return ret;

	return 0;
}
예제 #28
0
파일: blk-uclass.c 프로젝트: hallor/u-boot
int blk_get_device(int if_type, int devnum, struct udevice **devp)
{
    struct uclass *uc;
    struct udevice *dev;
    int ret;

    ret = uclass_get(UCLASS_BLK, &uc);
    if (ret)
        return ret;
    uclass_foreach_dev(dev, uc) {
        struct blk_desc *desc = dev_get_uclass_platdata(dev);

        debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
              if_type, devnum, dev->name, desc->if_type, desc->devnum);
        if (desc->if_type == if_type && desc->devnum == devnum) {
            *devp = dev;
            return device_probe(dev);
        }
    }

    return -ENODEV;
}
예제 #29
0
파일: i2c-uclass.c 프로젝트: Noltari/u-boot
static int i2c_bind_driver(struct udevice *bus, uint chip_addr, uint offset_len,
			   struct udevice **devp)
{
	struct dm_i2c_chip *chip;
	char name[30], *str;
	struct udevice *dev;
	int ret;

	snprintf(name, sizeof(name), "generic_%x", chip_addr);
	str = strdup(name);
	if (!str)
		return -ENOMEM;
	ret = device_bind_driver(bus, "i2c_generic_chip_drv", str, &dev);
	debug("%s:  device_bind_driver: ret=%d\n", __func__, ret);
	if (ret)
		goto err_bind;

	/* Tell the device what we know about it */
	chip = dev_get_parent_platdata(dev);
	chip->chip_addr = chip_addr;
	chip->offset_len = offset_len;
	ret = device_probe(dev);
	debug("%s:  device_probe: ret=%d\n", __func__, ret);
	if (ret)
		goto err_probe;

	*devp = dev;
	return 0;

err_probe:
	/*
	 * If the device failed to probe, unbind it. There is nothing there
	 * on the bus so we don't want to leave it lying around
	 */
	device_unbind(dev);
err_bind:
	free(str);
	return ret;
}
예제 #30
0
static int dm_test_children(struct unit_test_state *uts)
{
	struct dm_test_state *dms = uts->priv;
	struct udevice *top[NODE_COUNT];
	struct udevice *child[NODE_COUNT];
	struct udevice *grandchild[NODE_COUNT];
	struct udevice *dev;
	int total;
	int ret;
	int i;

	/* We don't care about the numbering for this test */
	dms->skip_post_probe = 1;

	ut_assert(NODE_COUNT > 5);

	/* First create 10 top-level children */
	ut_assertok(create_children(uts, dms->root, NODE_COUNT, 0, top));

	/* Now a few have their own children */
	ut_assertok(create_children(uts, top[2], NODE_COUNT, 2, NULL));
	ut_assertok(create_children(uts, top[5], NODE_COUNT, 5, child));

	/* And grandchildren */
	for (i = 0; i < NODE_COUNT; i++)
		ut_assertok(create_children(uts, child[i], NODE_COUNT, 50 * i,
					    i == 2 ? grandchild : NULL));

	/* Check total number of devices */
	total = NODE_COUNT * (3 + NODE_COUNT);
	ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_BIND]);

	/* Try probing one of the grandchildren */
	ut_assertok(uclass_get_device(UCLASS_TEST,
				      NODE_COUNT * 3 + 2 * NODE_COUNT, &dev));
	ut_asserteq_ptr(grandchild[0], dev);

	/*
	 * This should have probed the child and top node also, for a total
	 * of 3 nodes.
	 */
	ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PROBE]);

	/* Probe the other grandchildren */
	for (i = 1; i < NODE_COUNT; i++)
		ut_assertok(device_probe(grandchild[i]));

	ut_asserteq(2 + NODE_COUNT, dm_testdrv_op_count[DM_TEST_OP_PROBE]);

	/* Probe everything */
	for (ret = uclass_first_device(UCLASS_TEST, &dev);
	     dev;
	     ret = uclass_next_device(&dev))
		;
	ut_assertok(ret);

	ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_PROBE]);

	/* Remove a top-level child and check that the children are removed */
	ut_assertok(device_remove(top[2]));
	ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_REMOVE]);
	dm_testdrv_op_count[DM_TEST_OP_REMOVE] = 0;

	/* Try one with grandchildren */
	ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev));
	ut_asserteq_ptr(dev, top[5]);
	ut_assertok(device_remove(dev));
	ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT),
		    dm_testdrv_op_count[DM_TEST_OP_REMOVE]);

	/* Try the same with unbind */
	ut_assertok(device_unbind(top[2]));
	ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
	dm_testdrv_op_count[DM_TEST_OP_UNBIND] = 0;

	/* Try one with grandchildren */
	ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev));
	ut_asserteq_ptr(dev, top[6]);
	ut_assertok(device_unbind(top[5]));
	ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT),
		    dm_testdrv_op_count[DM_TEST_OP_UNBIND]);

	return 0;
}