示例#1
0
/*
 * Set only flag to suggest that device is suspended. This call is
 * not supported in NetBSD.
 *
 */
int
dm_dev_suspend_ioctl(prop_dictionary_t dm_dict)
{
	dm_dev_t *dmv;
	const char *name, *uuid;
	uint32_t flags, minor;

	name = NULL;
	uuid = NULL;
	flags = 0;

	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);

	if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
		DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
		return ENOENT;
	}
	atomic_set_int(&dmv->flags, DM_SUSPEND_FLAG);

	dm_dbg_print_flags(dmv->flags);

	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt);
	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_FLAGS, dmv->flags);
	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);

	dm_dev_unbusy(dmv);

	/* Add flags to dictionary flag after dmv -> dict copy */
	DM_ADD_FLAG(flags, DM_EXISTS_FLAG);

	return 0;
}
示例#2
0
/*
 * Rename selected devices old name is in struct dm_ioctl.
 * newname is taken from dictionary
 *
 * <key>cmd_data</key>
 *  <array>
 *   <string>...</string>
 *  </array>
 */
int
dm_dev_rename_ioctl(prop_dictionary_t dm_dict)
{
#if 0
	prop_array_t cmd_array;
	dm_dev_t *dmv;

	const char *name, *uuid, *n_name;
	uint32_t flags, minor;

	name = NULL;
	uuid = NULL;
	minor = 0;

	/* Get needed values from dictionary. */
	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);

	dm_dbg_print_flags(flags);

	cmd_array = prop_dictionary_get(dm_dict, DM_IOCTL_CMD_DATA);

	prop_array_get_cstring_nocopy(cmd_array, 0, &n_name);

	if (strlen(n_name) + 1 > DM_NAME_LEN)
		return EINVAL;

	if ((dmv = dm_dev_rem(NULL, name, uuid, minor)) == NULL) {
		DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
		return ENOENT;
	}
	/* change device name */
	/*
	 * XXX How to deal with this change, name only used in
	 * dm_dev_routines, should I add dm_dev_change_name which will run
	 * under the dm_dev_list mutex ?
	 */
	strlcpy(dmv->name, n_name, DM_NAME_LEN);

	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt);
	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
	prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmv->uuid);

	dm_dev_insert(dmv);
#endif

	/*
	 * XXX: the rename is not yet implemented. The main complication
	 *	here is devfs. We'd probably need a new function, rename_dev()
	 *	that would trigger a node rename in devfs.
	 */
	kprintf("dm_dev_rename_ioctl called, but not implemented!\n");
	return 0;
}
static void
awin_fb_attach(device_t parent, device_t self, void *aux)
{
	struct awin_fb_softc *sc = device_private(self);
	struct awinfb_attach_args * const afb = aux;
	prop_dictionary_t cfg = device_properties(self);
	struct genfb_ops ops;

	if (awin_fb_consoledev == NULL)
		awin_fb_consoledev = self;

	sc->sc_gen.sc_dev = self;
	sc->sc_debedev = parent;
	sc->sc_dmat = afb->afb_dmat;
	sc->sc_dmasegs = afb->afb_dmasegs;
	sc->sc_ndmasegs = afb->afb_ndmasegs;
	sc->sc_mpdev = device_find_by_driver_unit("awinmp", 0);

	prop_dictionary_set_uint32(cfg, "width", afb->afb_width);
	prop_dictionary_set_uint32(cfg, "height", afb->afb_height);
	prop_dictionary_set_uint8(cfg, "depth", 32);
	prop_dictionary_set_uint16(cfg, "linebytes", afb->afb_width * 4);
	prop_dictionary_set_uint32(cfg, "address", 0);
	prop_dictionary_set_uint32(cfg, "virtual_address",
	    (uintptr_t)afb->afb_fb);

	genfb_init(&sc->sc_gen);

	if (sc->sc_gen.sc_width == 0 || sc->sc_gen.sc_fbsize == 0) {
		aprint_normal(": disabled\n");
		return;
	}

	pmf_device_register1(self, NULL, NULL, awin_fb_shutdown);

	memset(&ops, 0, sizeof(ops));
	ops.genfb_ioctl = awin_fb_ioctl;
	ops.genfb_mmap = awin_fb_mmap;

	aprint_naive("\n");

	bool is_console = false;
	prop_dictionary_get_bool(cfg, "is_console", &is_console);

	if (is_console)
		aprint_normal(": switching to framebuffer console\n");
	else
		aprint_normal("\n");

	genfb_attach(&sc->sc_gen, &ops);
}
示例#4
0
/*
 * Return actual state of device to libdevmapper.
 */
int
dm_dev_status_ioctl(prop_dictionary_t dm_dict)
{
	dm_dev_t *dmv;
	const char *name, *uuid;
	uint32_t flags, j, minor;

	name = NULL;
	uuid = NULL;
	flags = 0;
	j = 0;

	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);

	if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
		DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
		return ENOENT;
	}
	dm_dbg_print_flags(dmv->flags);

	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt);
	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
	prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmv->uuid);

	if (dmv->flags & DM_SUSPEND_FLAG)
		DM_ADD_FLAG(flags, DM_SUSPEND_FLAG);

	/*
	 * Add status flags for tables I have to check both active and
	 * inactive tables.
	 */
	if ((j = dm_table_get_target_count(&dmv->table_head, DM_TABLE_ACTIVE))) {
		DM_ADD_FLAG(flags, DM_ACTIVE_PRESENT_FLAG);
	} else
		DM_REMOVE_FLAG(flags, DM_ACTIVE_PRESENT_FLAG);

	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_TARGET_COUNT, j);

	if (dm_table_get_target_count(&dmv->table_head, DM_TABLE_INACTIVE))
		DM_ADD_FLAG(flags, DM_INACTIVE_PRESENT_FLAG);
	else
		DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG);

	dm_dev_unbusy(dmv);

	return 0;
}
示例#5
0
static void
tegra_genfb_attach(device_t parent, device_t self, void *aux)
{
	struct tegra_genfb_softc * const sc = device_private(self);
	struct tegrafb_attach_args * const tfb = aux;
	prop_dictionary_t prop = device_properties(self);
	const bool is_console = tfb->tfb_console;
	struct genfb_ops ops;

	sc->sc_gen.sc_dev = self;
	sc->sc_dmat = tfb->tfb_dmat;
	sc->sc_dmamap = tfb->tfb_dmamap;

	prop_dictionary_set_bool(prop, "is_console", is_console);
	prop_dictionary_set_uint32(prop, "width", tfb->tfb_width);
	prop_dictionary_set_uint32(prop, "height", tfb->tfb_height);
	prop_dictionary_set_uint8(prop, "depth", tfb->tfb_depth);
	prop_dictionary_set_uint32(prop, "linebytes", tfb->tfb_stride);
	prop_dictionary_set_uint64(prop, "address", 0);
	prop_dictionary_set_uint64(prop, "virtual_address",
	    (uintptr_t)tfb->tfb_dmap);

	genfb_init(&sc->sc_gen);
	if (sc->sc_gen.sc_width == 0 || sc->sc_gen.sc_fbsize == 0) {
		aprint_error(": disabled\n");
		return;
	}

	pmf_device_register1(self, NULL, NULL, tegra_genfb_shutdown);

	aprint_naive("\n");
	if (is_console) {
		aprint_normal(": switching to framebuffer console\n");
	} else {
		aprint_normal("\n");
	}

	memset(&ops, 0, sizeof(ops));
	ops.genfb_ioctl = tegra_genfb_ioctl;
	ops.genfb_mmap = tegra_genfb_mmap;
	genfb_attach(&sc->sc_gen, &ops);

#if defined(DDB)
	if (is_console) {
		tegra_genfb_consoledev = self;
		db_trap_callback = tegra_genfb_ddb_trap_callback;
	}
#endif

}
示例#6
0
/*
 * Rename selected devices old name is in struct dm_ioctl.
 * newname is taken from dictionary
 *
 * <key>cmd_data</key>
 *  <array>
 *   <string>...</string>
 *  </array>
 */
int
dm_dev_rename_ioctl(prop_dictionary_t dm_dict)
{
	prop_array_t cmd_array;
	dm_dev_t *dmv;

	const char *name, *uuid, *n_name;
	uint32_t flags, minor;

	name = NULL;
	uuid = NULL;
	minor = 0;

	/* Get needed values from dictionary. */
	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);

	dm_dbg_print_flags(flags);

	cmd_array = prop_dictionary_get(dm_dict, DM_IOCTL_CMD_DATA);

	prop_array_get_cstring_nocopy(cmd_array, 0, &n_name);

	if (strlen(n_name) + 1 > DM_NAME_LEN)
		return EINVAL;

	if ((dmv = dm_dev_rem(name, uuid, minor)) == NULL) {
		DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
		return ENOENT;
	}
	/* change device name */
	/*
	 * XXX How to deal with this change, name only used in
	 * dm_dev_routines, should I add dm_dev_change_name which will run
	 * under the dm_dev_list mutex ?
	 */
	strlcpy(dmv->name, n_name, DM_NAME_LEN);

	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt);
	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
	prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmv->uuid);

	dm_dev_insert(dmv);

	return 0;
}
示例#7
0
int
npf_nat_setalgo(nl_nat_t *nt, u_int algo)
{
	prop_dictionary_t rldict = nt->nrl_dict;
	prop_dictionary_set_uint32(rldict, "translation-algo", algo);
	return 0;
}
示例#8
0
nl_rule_t *
npf_rule_create(const char *name, uint32_t attr, const char *ifname)
{
	prop_dictionary_t rldict;
	nl_rule_t *rl;

	rl = malloc(sizeof(*rl));
	if (rl == NULL) {
		return NULL;
	}
	rldict = prop_dictionary_create();
	if (rldict == NULL) {
		free(rl);
		return NULL;
	}
	if (name) {
		prop_dictionary_set_cstring(rldict, "name", name);
	}
	prop_dictionary_set_uint32(rldict, "attributes", attr);

	if (ifname) {
		prop_dictionary_set_cstring(rldict, "interface", ifname);
	}
	rl->nrl_dict = rldict;
	return rl;
}
示例#9
0
static void
_npf_ruleset_transform1(prop_array_t rlset, prop_array_t rules)
{
	prop_object_iterator_t it;
	prop_dictionary_t rldict;
	prop_array_t subrlset;

	it = prop_array_iterator(rules);
	while ((rldict = prop_object_iterator_next(it)) != NULL) {
		unsigned idx;

		/* Add rules to the array (reference is retained). */
		prop_array_add(rlset, rldict);

		subrlset = prop_dictionary_get(rldict, "subrules");
		if (subrlset) {
			/* Process subrules recursively. */
			_npf_ruleset_transform1(rlset, subrlset);
			/* Add the skip-to position. */
			idx = prop_array_count(rlset);
			prop_dictionary_set_uint32(rldict, "skip-to", idx);
			prop_dictionary_remove(rldict, "subrules");
		}
	}
	prop_object_iterator_release(it);
}
示例#10
0
nl_table_t *
npf_table_create(const char *name, u_int id, int type)
{
	prop_dictionary_t tldict;
	prop_array_t tblents;
	nl_table_t *tl;

	tl = malloc(sizeof(*tl));
	if (tl == NULL) {
		return NULL;
	}
	tldict = prop_dictionary_create();
	if (tldict == NULL) {
		free(tl);
		return NULL;
	}
	prop_dictionary_set_cstring(tldict, "name", name);
	prop_dictionary_set_uint32(tldict, "id", id);
	prop_dictionary_set_int32(tldict, "type", type);

	tblents = prop_array_create();
	if (tblents == NULL) {
		prop_object_release(tldict);
		free(tl);
		return NULL;
	}
	prop_dictionary_set(tldict, "entries", tblents);
	prop_object_release(tblents);

	tl->ntl_dict = tldict;
	return tl;
}
示例#11
0
void
zynq7000_device_register(device_t self, void *aux)
{
	prop_dictionary_t dict = device_properties(self);

	if (device_is_a(self, "armperiph")
	    && device_is_a(device_parent(self), "mainbus")) {
		/*
		 * XXX KLUDGE ALERT XXX
		 * The iot mainbus supplies is completely wrong since it scales
		 * addresses by 2.  The simpliest remedy is to replace with our
		 * bus space used for the armcore registers (which armperiph uses).
		 */
		struct mainbus_attach_args * const mb = aux;
		mb->mb_iot = zynq7000_armcore_bst;
		return;
	}

	/*
	 * We need to tell the A9 Global/Watchdog Timer
	 * what frequency it runs at.
	 */
	if (device_is_a(self, "a9tmr") || device_is_a(self, "a9wdt")) {
		prop_dictionary_set_uint32(dict, "frequency",
		    666666666 / PERIPHCLK_N);
		return;
	}
}
示例#12
0
文件: fd.c 项目: lacombar/netbsd-alc
static void
fd_set_properties(struct fd_softc *fd)
{
	prop_dictionary_t disk_info, odisk_info, geom;
	const struct fd_type *fdt;
	int secsize;

	fdt = fd->sc_type;
	if (fdt == NULL) {
		fdt = fd->sc_deftype;
		if (fdt == NULL)
			return;
	}

	disk_info = prop_dictionary_create();

	geom = prop_dictionary_create();

	prop_dictionary_set_uint64(geom, "sectors-per-unit",
	    fdt->size);

	switch (fdt->secsize) {
	case 2:
		secsize = 512;
		break;
	case 3:
		secsize = 1024;
		break;
	default:
		secsize = 0;
	}

	prop_dictionary_set_uint32(geom, "sector-size",
	    secsize);

	prop_dictionary_set_uint16(geom, "sectors-per-track",
	    fdt->sectrac);

	prop_dictionary_set_uint16(geom, "tracks-per-cylinder",
	    fdt->heads);

	prop_dictionary_set_uint64(geom, "cylinders-per-unit",
	    fdt->cyls);

	prop_dictionary_set(disk_info, "geometry", geom);
	prop_object_release(geom);

	prop_dictionary_set(device_properties(fd->sc_dev),
	    "disk-info", disk_info);

	/*
	 * Don't release disk_info here; we keep a reference to it.
	 * disk_detach() will release it when we go away.
	 */

	odisk_info = fd->sc_dk.dk_info;
	fd->sc_dk.dk_info = disk_info;
	if (odisk_info)
		prop_object_release(odisk_info);
}
void
vexpress_device_register(device_t self, void *aux)
{
	prop_dictionary_t dict = device_properties(self);

	if (device_is_a(self, "armperiph")
	    && device_is_a(device_parent(self), "mainbus")) {
		/*
		 * XXX KLUDGE ALERT XXX
		 * The iot mainbus supplies is completely wrong since it scales
		 * addresses by 2.  The simpliest remedy is to replace with our
		 * bus space used for the armcore regisers (which armperiph uses).
		 */
		struct mainbus_attach_args *const mb = aux;
		mb->mb_iot = &vexpress_bs_tag;
		return;
	}
#if defined(CPU_CORTEXA7) || defined(CPU_CORTEXA15)
	if (device_is_a(self, "armgtmr")) {
		/*
		 * The frequency of the generic timer is the reference
		 * frequency.
		 */
		prop_dictionary_set_uint32(dict, "frequency", VEXPRESS_REF_FREQ);
		return;
	}
#endif
}
示例#14
0
int
_npf_ruleset_list(int fd, const char *rname, nl_config_t *ncf)
{
	prop_dictionary_t rldict, ret;
	int error;

	rldict = prop_dictionary_create();
	if (rldict == NULL) {
		return ENOMEM;
	}
	prop_dictionary_set_cstring(rldict, "ruleset-name", rname);
	prop_dictionary_set_uint32(rldict, "command", NPF_CMD_RULE_LIST);
	error = prop_dictionary_sendrecv_ioctl(rldict, fd, IOC_NPF_RULE, &ret);
	if (!error) {
		prop_array_t rules;

		rules = prop_dictionary_get(ret, "rules");
		if (rules == NULL) {
			return EINVAL;
		}
		prop_object_release(ncf->ncf_rules_list);
		ncf->ncf_rules_list = rules;
	}
	return error;
}
示例#15
0
nl_nat_t *
npf_nat_create(int type, u_int flags, const char *ifname,
    int af, npf_addr_t *addr, npf_netmask_t mask, in_port_t port)
{
	nl_rule_t *rl;
	prop_dictionary_t rldict;
	prop_data_t addrdat;
	uint32_t attr;
	size_t sz;

	if (af == AF_INET) {
		sz = sizeof(struct in_addr);
	} else if (af == AF_INET6) {
		sz = sizeof(struct in6_addr);
	} else {
		return NULL;
	}

	attr = NPF_RULE_PASS | NPF_RULE_FINAL |
	    (type == NPF_NATOUT ? NPF_RULE_OUT : NPF_RULE_IN);

	/* Create a rule for NAT policy.  Next, will add translation data. */
	rl = npf_rule_create(NULL, attr, ifname);
	if (rl == NULL) {
		return NULL;
	}
	rldict = rl->nrl_dict;

	/* Translation type and flags. */
	prop_dictionary_set_int32(rldict, "type", type);
	prop_dictionary_set_uint32(rldict, "flags", flags);

	/* Translation IP and mask. */
	addrdat = prop_data_create_data(addr, sz);
	if (addrdat == NULL) {
		npf_rule_destroy(rl);
		return NULL;
	}
	prop_dictionary_set(rldict, "translation-ip", addrdat);
	prop_dictionary_set_uint32(rldict, "translation-mask", mask);
	prop_object_release(addrdat);

	/* Translation port (for redirect case). */
	prop_dictionary_set_uint16(rldict, "translation-port", port);

	return (nl_nat_t *)rl;
}
示例#16
0
/*
 * Simulate Linux behaviour better and switch tables here and not in
 * dm_table_load_ioctl.
 */
int
dm_dev_resume_ioctl(prop_dictionary_t dm_dict)
{
	dm_dev_t *dmv;
	const char *name, *uuid;
	uint32_t flags, minor;

	name = NULL;
	uuid = NULL;
	flags = 0;

	/*
	 * char *xml; xml = prop_dictionary_externalize(dm_dict);
	 * printf("%s\n",xml);
	 */

	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);

	/* Remove device from global device list */
	if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
		DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
		return ENOENT;
	}
	atomic_clear_int(&dmv->flags, (DM_SUSPEND_FLAG | DM_INACTIVE_PRESENT_FLAG));
	atomic_set_int(&dmv->flags, DM_ACTIVE_PRESENT_FLAG);

	dm_table_switch_tables(&dmv->table_head);

	DM_ADD_FLAG(flags, DM_EXISTS_FLAG);

	dmsetdiskinfo(dmv->diskp, &dmv->table_head);

	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_OPEN, dmv->table_head.io_cnt);
	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_FLAGS, flags);
	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);

	dm_dev_unbusy(dmv);

	/* Destroy inactive table after resume. */
	dm_table_destroy(&dmv->table_head, DM_TABLE_INACTIVE);

	return 0;
}
示例#17
0
/*
 * Get list of physical devices for active table.
 * Get dev_t from pdev vnode and insert it into cmd_array.
 *
 * XXX. This function is called from lvm2tools to get information
 *      about physical devices, too e.g. during vgcreate.
 */
int
dm_table_deps_ioctl(prop_dictionary_t dm_dict)
{
	dm_dev_t *dmv;
	dm_table_t *tbl;
	dm_table_entry_t *table_en;

	prop_array_t cmd_array;
	const char *name, *uuid;
	uint32_t flags, minor;

	int table_type;

	name = NULL;
	uuid = NULL;
	dmv = NULL;
	flags = 0;

	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor);

	/* create array for dev_t's */
	cmd_array = prop_array_create();

	if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) {
		DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG);
		return ENOENT;
	}
	prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
	prop_dictionary_set_cstring(dm_dict, DM_IOCTL_NAME, dmv->name);
	prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmv->uuid);

	aprint_debug("Getting table deps for device: %s\n", dmv->name);

	/*
	 * if DM_QUERY_INACTIVE_TABLE_FLAG is passed we need to query
	 * INACTIVE TABLE
	 */
	if (flags & DM_QUERY_INACTIVE_TABLE_FLAG)
		table_type = DM_TABLE_INACTIVE;
	else
		table_type = DM_TABLE_ACTIVE;

	tbl = dm_table_get_entry(&dmv->table_head, table_type);

	SLIST_FOREACH(table_en, tbl, next)
	    table_en->target->deps(table_en, cmd_array);

	dm_table_release(&dmv->table_head, table_type);
	dm_dev_unbusy(dmv);

	prop_dictionary_set(dm_dict, DM_IOCTL_CMD_DATA, cmd_array);
	prop_object_release(cmd_array);

	return 0;
}
示例#18
0
int
npf_config_submit(nl_config_t *ncf, int fd)
{
	const char *plist = ncf->ncf_plist;
	prop_dictionary_t npf_dict;
	prop_array_t rlset;
	int error = 0;

	npf_dict = prop_dictionary_create();
	if (npf_dict == NULL) {
		return ENOMEM;
	}
	prop_dictionary_set_uint32(npf_dict, "version", NPF_VERSION);

	rlset = _npf_ruleset_transform(ncf->ncf_rules_list);
	if (rlset == NULL) {
		prop_object_release(npf_dict);
		return ENOMEM;
	}
	prop_object_release(ncf->ncf_rules_list);
	ncf->ncf_rules_list = rlset;

	prop_dictionary_set(npf_dict, "rules", ncf->ncf_rules_list);
	prop_dictionary_set(npf_dict, "algs", ncf->ncf_alg_list);
	prop_dictionary_set(npf_dict, "rprocs", ncf->ncf_rproc_list);
	prop_dictionary_set(npf_dict, "tables", ncf->ncf_table_list);
	prop_dictionary_set(npf_dict, "translation", ncf->ncf_nat_list);
	prop_dictionary_set_bool(npf_dict, "flush", ncf->ncf_flush);
	if (ncf->ncf_debug) {
		prop_dictionary_set(npf_dict, "debug", ncf->ncf_debug);
	}

	if (plist) {
		if (!prop_dictionary_externalize_to_file(npf_dict, plist)) {
			error = errno;
		}
		prop_object_release(npf_dict);
		return error;
	}
	if (fd) {
		error = prop_dictionary_sendrecv_ioctl(npf_dict, fd,
		    IOC_NPF_RELOAD, &ncf->ncf_err);
		if (error) {
			prop_object_release(npf_dict);
			assert(ncf->ncf_err == NULL);
			return error;
		}
		prop_dictionary_get_int32(ncf->ncf_err, "errno", &error);
	}
	prop_object_release(npf_dict);
	return error;
}
示例#19
0
void
copy_disp_props(struct device *dev, int node, prop_dictionary_t dict)
{
	uint32_t temp;
	char typestr[32];

	memset(typestr, 0, sizeof(typestr));
	OF_getprop(console_node, "device_type", typestr, sizeof(typestr));
	if (strcmp(typestr, "serial") != 0) {
		/* this is our console, when we don't have a serial console */
		prop_dictionary_set_bool(dict, "is_console", 1);
	}

	if (!of_to_uint32_prop(dict, node, "width", "width")) {

		OF_interpret("screen-width", 0, 1, &temp);
		prop_dictionary_set_uint32(dict, "width", temp);
	}
	if (!of_to_uint32_prop(dict, node, "height", "height")) {

		OF_interpret("screen-height", 0, 1, &temp);
		prop_dictionary_set_uint32(dict, "height", temp);
	}
	of_to_uint32_prop(dict, node, "linebytes", "linebytes");
	if (!of_to_uint32_prop(dict, node, "depth", "depth")) {
		/*
		 * XXX we should check linebytes vs. width but those
		 * FBs that don't have a depth property ( /chaos/control... )
		 * won't have linebytes either
		 */
		prop_dictionary_set_uint32(dict, "depth", 8);
	}
	if (!of_to_uint32_prop(dict, node, "address", "address")) {
		uint32_t fbaddr = 0;
			OF_interpret("frame-buffer-adr", 0, 1, &fbaddr);
		if (fbaddr != 0)
			prop_dictionary_set_uint32(dict, "address", fbaddr);
	}
}
示例#20
0
int
npf_ruleset_flush(int fd, const char *rname)
{
	prop_dictionary_t rldict;

	rldict = prop_dictionary_create();
	if (rldict == NULL) {
		return ENOMEM;
	}
	prop_dictionary_set_cstring(rldict, "ruleset-name", rname);
	prop_dictionary_set_uint32(rldict, "command", NPF_CMD_RULE_FLUSH);
	return prop_dictionary_send_ioctl(rldict, fd, IOC_NPF_RULE);
}
示例#21
0
int
npf_ruleset_remove(int fd, const char *rname, uint64_t id)
{
	prop_dictionary_t rldict;

	rldict = prop_dictionary_create();
	if (rldict == NULL) {
		return ENOMEM;
	}
	prop_dictionary_set_cstring(rldict, "ruleset-name", rname);
	prop_dictionary_set_uint32(rldict, "command", NPF_CMD_RULE_REMOVE);
	prop_dictionary_set_uint64(rldict, "id", id);
	return prop_dictionary_send_ioctl(rldict, fd, IOC_NPF_RULE);
}
示例#22
0
int
npf_ruleset_add(int fd, const char *rname, nl_rule_t *rl, uint64_t *id)
{
	prop_dictionary_t rldict = rl->nrl_dict;
	prop_dictionary_t ret;
	int error;

	prop_dictionary_set_cstring(rldict, "ruleset-name", rname);
	prop_dictionary_set_uint32(rldict, "command", NPF_CMD_RULE_ADD);
	error = prop_dictionary_sendrecv_ioctl(rldict, fd, IOC_NPF_RULE, &ret);
	if (!error) {
		prop_dictionary_get_uint64(ret, "id", id);
	}
	return error;
}
示例#23
0
void
_npf_debug_addif(nl_config_t *ncf, const char *ifname)
{
	prop_dictionary_t ifdict, dbg = _npf_debug_initonce(ncf);
	prop_array_t iflist = prop_dictionary_get(dbg, "interfaces");
	u_int if_idx = if_nametoindex(ifname);

	if (_npf_prop_array_lookup(iflist, "name", ifname)) {
		return;
	}
	ifdict = prop_dictionary_create();
	prop_dictionary_set_cstring(ifdict, "name", ifname);
	prop_dictionary_set_uint32(ifdict, "index", if_idx);
	prop_array_add(iflist, ifdict);
	prop_object_release(ifdict);
}
static void _dm_rename_kern(struct dm_task *dmt)
{
	prop_dictionary_t dm_dict_in, dm_dict_out;

	dm_dict_in = prop_dictionary_create(); /* Dictionary send to kernel */

	/* Set command name to dictionary */
	prop_dictionary_set_cstring(dm_dict_in, DM_IOCTL_COMMAND,
	    "nrename");
	prop_dictionary_set_cstring(dm_dict_in, "dev_name", dmt->dev_name);
	prop_dictionary_set_cstring(dm_dict_in, "new_name", dmt->newname);

	/* Set flags to dictionary. */
	prop_dictionary_set_uint32(dm_dict_in,DM_IOCTL_FLAGS,0);

	if (prop_dictionary_sendrecv_ioctl(dm_dict_in,_control_fd,
		NETBSD_DM_IOCTL,&dm_dict_out) != 0) {
		log_error("rename failed");
	}
}
示例#25
0
int
npf_rule_setcode(nl_rule_t *rl, int type, const void *code, size_t len)
{
	prop_dictionary_t rldict = rl->nrl_dict;
	prop_data_t cdata;

	switch (type) {
	case NPF_CODE_NC:
	case NPF_CODE_BPF:
		break;
	default:
		return ENOTSUP;
	}
	prop_dictionary_set_uint32(rldict, "code-type", type);
	if ((cdata = prop_data_create_data(code, len)) == NULL) {
		return ENOMEM;
	}
	prop_dictionary_set(rldict, "code", cdata);
	prop_object_release(cdata);
	return 0;
}
示例#26
0
int
npf_ruleset_remkey(int fd, const char *rname, const void *key, size_t len)
{
	prop_dictionary_t rldict;
	prop_data_t keyobj;

	rldict = prop_dictionary_create();
	if (rldict == NULL) {
		return ENOMEM;
	}
	prop_dictionary_set_cstring(rldict, "ruleset-name", rname);
	prop_dictionary_set_uint32(rldict, "command", NPF_CMD_RULE_REMKEY);

	keyobj = prop_data_create_data(key, len);
	if (keyobj == NULL) {
		prop_object_release(rldict);
		return ENOMEM;
	}
	prop_dictionary_set(rldict, "key", keyobj);
	prop_object_release(keyobj);

	return prop_dictionary_send_ioctl(rldict, fd, IOC_NPF_RULE);
}
示例#27
0
/*
 * Create in-kernel entry for device. Device attributes such as name, uuid are
 * taken from proplib dictionary.
 *
 */
int
dm_dev_create_ioctl(prop_dictionary_t dm_dict)
{
	dm_dev_t *dmv;
	const char *name, *uuid;
	int r, flags;

	r = 0;
	flags = 0;
	name = NULL;
	uuid = NULL;

	/* Get needed values from dictionary. */
	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name);
	prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid);
	prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags);

	dm_dbg_print_flags(flags);

	/* Lookup name and uuid if device already exist quit. */
	if ((dmv = dm_dev_lookup(name, uuid, -1)) != NULL) {
		DM_ADD_FLAG(flags, DM_EXISTS_FLAG);	/* Device already exists */
		dm_dev_unbusy(dmv);
		return EEXIST;
	}

	r = dm_dev_create(&dmv, name, uuid, flags);
	
	if (r == 0) {
		prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor);
		DM_ADD_FLAG(flags, DM_EXISTS_FLAG);
		DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG);
	}

	return r;
}
示例#28
0
/*
 * npfctl_save: export the config dictionary as it was submitted,
 * including the current snapshot of the connections.  Additionally,
 * indicate whether the ruleset is currently active.
 */
int
npfctl_save(u_long cmd, void *data)
{
	struct plistref *pref = data;
	prop_array_t rulelist, natlist, tables, rprocs, conlist;
	prop_dictionary_t npf_dict = NULL;
	int error;

	rulelist = prop_array_create();
	natlist = prop_array_create();
	tables = prop_array_create();
	rprocs = prop_array_create();
	conlist = prop_array_create();

	/*
	 * Serialise the connections and NAT policies.
	 */
	npf_config_enter();
	error = npf_conndb_export(conlist);
	if (error) {
		goto out;
	}
	error = npf_ruleset_export(npf_config_ruleset(), rulelist);
	if (error) {
		goto out;
	}
	error = npf_ruleset_export(npf_config_natset(), natlist);
	if (error) {
		goto out;
	}
	error = npf_tableset_export(npf_config_tableset(), tables);
	if (error) {
		goto out;
	}
	error = npf_rprocset_export(npf_config_rprocs(), rprocs);
	if (error) {
		goto out;
	}
	prop_array_t alglist = npf_alg_export();

	npf_dict = prop_dictionary_create();
	prop_dictionary_set_uint32(npf_dict, "version", NPF_VERSION);
	prop_dictionary_set_and_rel(npf_dict, "algs", alglist);
	prop_dictionary_set_and_rel(npf_dict, "rules", rulelist);
	prop_dictionary_set_and_rel(npf_dict, "nat", natlist);
	prop_dictionary_set_and_rel(npf_dict, "tables", tables);
	prop_dictionary_set_and_rel(npf_dict, "rprocs", rprocs);
	prop_dictionary_set_and_rel(npf_dict, "conn-list", conlist);
	prop_dictionary_set_bool(npf_dict, "active", npf_pfil_registered_p());
	error = prop_dictionary_copyout_ioctl(pref, cmd, npf_dict);
out:
	npf_config_exit();

	if (!npf_dict) {
		prop_object_release(rulelist);
		prop_object_release(natlist);
		prop_object_release(tables);
		prop_object_release(rprocs);
		prop_object_release(conlist);
	} else {
		prop_object_release(npf_dict);
	}
	return error;
}
示例#29
0
void
disk_set_info(device_t dev, struct disk *dk, const char *type)
{
	struct disk_geom *dg = &dk->dk_geom;

	if (dg->dg_secsize == 0) {
#ifdef DIAGNOSTIC
		printf("%s: fixing 0 sector size\n", dk->dk_name);
#endif
		dg->dg_secsize = DEV_BSIZE;
	}

	dk->dk_blkshift = DK_BSIZE2BLKSHIFT(dg->dg_secsize);
	dk->dk_byteshift = DK_BSIZE2BYTESHIFT(dg->dg_secsize);

	if (dg->dg_secperunit == 0 && dg->dg_ncylinders == 0) {
#ifdef DIAGNOSTIC
		printf("%s: secperunit and ncylinders are zero\n", dk->dk_name);
#endif
		return;
	}

	if (dg->dg_secperunit == 0) {
		if (dg->dg_nsectors == 0 || dg->dg_ntracks == 0) {
#ifdef DIAGNOSTIC
			printf("%s: secperunit and (sectors or tracks) "
			    "are zero\n", dk->dk_name);
#endif
			return;
		}
		dg->dg_secperunit = (int64_t) dg->dg_nsectors *
		    dg->dg_ntracks * dg->dg_ncylinders;
	}

	if (dg->dg_ncylinders == 0) {
		if (dg->dg_ntracks && dg->dg_nsectors)
			dg->dg_ncylinders = dg->dg_secperunit /
			    (dg->dg_ntracks * dg->dg_nsectors);
	}

	prop_dictionary_t disk_info, odisk_info, geom;

	disk_info = prop_dictionary_create();
	geom = prop_dictionary_create();

	prop_dictionary_set_uint64(geom, "sectors-per-unit",
	    dg->dg_secperunit);

	prop_dictionary_set_uint32(geom, "sector-size", dg->dg_secsize);

	if (dg->dg_nsectors)
		prop_dictionary_set_uint16(geom, "sectors-per-track",
		    dg->dg_nsectors);

	if (dg->dg_ntracks)
		prop_dictionary_set_uint16(geom, "tracks-per-cylinder",
		    dg->dg_ntracks);

	if (dg->dg_ncylinders)
		prop_dictionary_set_uint64(geom, "cylinders-per-unit",
		    dg->dg_ncylinders);

	prop_dictionary_set(disk_info, "geometry", geom);

	if (type)
		prop_dictionary_set_cstring_nocopy(disk_info, "type", type);

	prop_object_release(geom);

	odisk_info = dk->dk_info;
	dk->dk_info = disk_info;

	if (dev)
		prop_dictionary_set(device_properties(dev), "disk-info",
		    disk_info);

	/*
	 * Don't release disk_info here; we keep a reference to it.
	 * disk_detach() will release it when we go away.
	 */
	if (odisk_info)
		prop_object_release(odisk_info);
}
示例#30
0
/*
 * Called back during autoconfiguration for each device found
 */
void
device_register(device_t dev, void *aux)
{
	device_t busdev = device_parent(dev);
	int ofnode = 0;

	/*
	 * We don't know the type of 'aux' - it depends on the
	 * bus this device attaches to. We are only interested in
	 * certain bus types, this only is used to find the boot
	 * device.
	 */
	if (busdev == NULL) {
		/*
		 * Ignore mainbus0 itself, it certainly is not a boot
		 * device.
		 */
	} else if (device_is_a(busdev, "mainbus")) {
		struct mainbus_attach_args *ma = aux;

		ofnode = ma->ma_node;
	} else if (device_is_a(busdev, "pci")) {
		struct pci_attach_args *pa = aux;

		ofnode = PCITAG_NODE(pa->pa_tag);
	} else if (device_is_a(busdev, "sbus") || device_is_a(busdev, "dma")
	    || device_is_a(busdev, "ledma")) {
		struct sbus_attach_args *sa = aux;

		ofnode = sa->sa_node;
	} else if (device_is_a(busdev, "ebus")) {
		struct ebus_attach_args *ea = aux;

		ofnode = ea->ea_node;
	} else if (device_is_a(busdev, "iic")) {
		struct i2c_attach_args *ia = aux;

		if (ia->ia_name == NULL)	/* indirect config */
			return;

		ofnode = (int)ia->ia_cookie;
	} else if (device_is_a(dev, "sd") || device_is_a(dev, "cd")) {
		struct scsipibus_attach_args *sa = aux;
		struct scsipi_periph *periph = sa->sa_periph;
		int off = 0;

		/*
		 * There are two "cd" attachments:
		 *   atapibus -> atabus -> controller
		 *   scsibus -> controller
		 * We want the node of the controller.
		 */
		if (device_is_a(busdev, "atapibus")) {
			busdev = device_parent(busdev);
			/*
			 * if the atapibus is connected to the secondary
			 * channel of the atabus, we need an offset of 2
			 * to match OF's idea of the target number.
			 * (i.e. on U5/U10 "cdrom" and "disk2" have the
			 * same target encoding, though different names)
			 */
			if (periph->periph_channel->chan_channel == 1)
				off = 2;
		}
		ofnode = device_ofnode(device_parent(busdev));
		dev_path_drive_match(dev, ofnode, periph->periph_target + off,
		    0, periph->periph_lun);
		return;
	} else if (device_is_a(dev, "wd")) {
		struct ata_device *adev = aux;

		ofnode = device_ofnode(device_parent(busdev));
		dev_path_drive_match(dev, ofnode, adev->adev_channel*2+
		    adev->adev_drv_data->drive, 0, 0);
		return;
	}

	if (busdev == NULL)
		return;

	if (ofnode != 0) {
		uint8_t eaddr[ETHER_ADDR_LEN];
		char tmpstr[32];
		char tmpstr2[32];
		int node;
		uint32_t id = 0;
		uint64_t nwwn = 0, pwwn = 0;
		prop_dictionary_t dict;
		prop_data_t blob;
		prop_number_t pwwnd = NULL, nwwnd = NULL;
		prop_number_t idd = NULL;

		device_setofnode(dev, ofnode);
		dev_path_exact_match(dev, ofnode);

		if (OF_getprop(ofnode, "name", tmpstr, sizeof(tmpstr)) <= 0)
			tmpstr[0] = 0;
		if (OF_getprop(ofnode, "device_type", tmpstr2, sizeof(tmpstr2)) <= 0)
			tmpstr2[0] = 0;

		/*
		 * If this is a network interface, note the
		 * mac address.
		 */
		if (strcmp(tmpstr, "network") == 0
		   || strcmp(tmpstr, "ethernet") == 0
		   || strcmp(tmpstr2, "network") == 0
		   || strcmp(tmpstr2, "ethernet") == 0
		   || OF_getprop(ofnode, "mac-address", &eaddr, sizeof(eaddr))
		      >= ETHER_ADDR_LEN
		   || OF_getprop(ofnode, "local-mac-address", &eaddr, sizeof(eaddr))
		      >= ETHER_ADDR_LEN) {

			dict = device_properties(dev);

			/*
			 * Is it a network interface with FCode?
			 */
			if (strcmp(tmpstr, "network") == 0 ||
			    strcmp(tmpstr2, "network") == 0) {
				prop_dictionary_set_bool(dict,
				    "without-seeprom", true);
				prom_getether(ofnode, eaddr);
			} else {
				if (!prom_get_node_ether(ofnode, eaddr))
					goto noether;
			}
			blob = prop_data_create_data(eaddr, ETHER_ADDR_LEN);
			prop_dictionary_set(dict, "mac-address", blob);
			prop_object_release(blob);
			of_to_dataprop(dict, ofnode, "shared-pins",
			    "shared-pins");
		}
noether:

		/* is this a FC node? */
		if (strcmp(tmpstr, "scsi-fcp") == 0) {

			dict = device_properties(dev);

			if (OF_getprop(ofnode, "port-wwn", &pwwn, sizeof(pwwn))
			    == sizeof(pwwn)) {
				pwwnd = 
				    prop_number_create_unsigned_integer(pwwn);
				prop_dictionary_set(dict, "port-wwn", pwwnd);
				prop_object_release(pwwnd);
			}

			if (OF_getprop(ofnode, "node-wwn", &nwwn, sizeof(nwwn))
			    == sizeof(nwwn)) {
				nwwnd = 
				    prop_number_create_unsigned_integer(nwwn);
				prop_dictionary_set(dict, "node-wwn", nwwnd);
				prop_object_release(nwwnd);
			}
		}

		/* is this an spi device?  look for scsi-initiator-id */
		if (strcmp(tmpstr2, "scsi") == 0 ||
		    strcmp(tmpstr2, "scsi-2") == 0) {

			dict = device_properties(dev);

			for (node = ofnode; node != 0; node = OF_parent(node)) {
				if (OF_getprop(node, "scsi-initiator-id", &id,
				    sizeof(id)) <= 0)
					continue;

				idd = prop_number_create_unsigned_integer(id);
				prop_dictionary_set(dict,
						    "scsi-initiator-id", idd);
				prop_object_release(idd);
				break;
			}
		}
	}

	/*
	 * Check for I2C busses and add data for their direct configuration.
	 */
	if (device_is_a(dev, "iic")) {
		int busnode = device_ofnode(busdev);

		if (busnode) {
			prop_dictionary_t props = device_properties(busdev);
			prop_object_t cfg = prop_dictionary_get(props,
				"i2c-child-devices");
			if (!cfg) {
				int node;
				const char *name;

				/*
				 * pmu's i2c devices are under the "i2c" node,
				 * so find it out.
				 */
				name = prom_getpropstring(busnode, "name");
				if (strcmp(name, "pmu") == 0) {
					for (node = OF_child(busnode);
					     node != 0; node = OF_peer(node)) {
						name = prom_getpropstring(node,
						    "name");
						if (strcmp(name, "i2c") == 0) {
							busnode = node;
							break;
						}
					}
				}

				of_enter_i2c_devs(props, busnode,
				    sizeof(cell_t));
			}
		}

		/*
		 * Add SPARCle spdmem devices (0x50 and 0x51) that the
		 * firmware does not know about.
		 */
		if (!strcmp(machine_model, "TAD,SPARCLE")) {
			prop_dictionary_t props = device_properties(busdev);
			prop_array_t cfg = prop_array_create();
			int i;

			DPRINTF(ACDB_PROBE, ("\nAdding spdmem for SPARCle "));
			for (i = 0x50; i <= 0x51; i++) {
				prop_dictionary_t spd =
				    prop_dictionary_create();
				prop_dictionary_set_cstring(spd, "name",
				    "dimm-spd");
				prop_dictionary_set_uint32(spd, "addr", i);
				prop_dictionary_set_uint64(spd, "cookie", 0);
				prop_array_add(cfg, spd);
				prop_object_release(spd);
			}
			prop_dictionary_set(props, "i2c-child-devices", cfg);
			prop_object_release(cfg);
			
		}
	}

	/* set properties for PCI framebuffers */
	if (device_is_a(busdev, "pci")) {
		/* see if this is going to be console */
		struct pci_attach_args *pa = aux;
		prop_dictionary_t dict;
		int sub;
		int console = 0;

		dict = device_properties(dev);

		/* we only care about display devices from here on */
		if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
			return;

		console = (ofnode == console_node);

		if (!console) {
			/*
			 * see if any child matches since OF attaches
			 * nodes for each head and /chosen/stdout
			 * points to the head rather than the device
			 * itself in this case
			 */
			sub = OF_child(ofnode);
			while ((sub != 0) && (sub != console_node)) {
				sub = OF_peer(sub);
			}
			if (sub == console_node) {
				console = true;
			}
		}

		copyprops(busdev, ofnode, dict, console);

		if (console) {
			uint64_t cmap_cb;
			prop_dictionary_set_uint32(dict,
			    "instance_handle", console_instance);

			gfb_cb.gcc_cookie = 
			    (void *)(intptr_t)console_instance;
			gfb_cb.gcc_set_mapreg = of_set_palette;
			cmap_cb = (uint64_t)(uintptr_t)&gfb_cb;
			prop_dictionary_set_uint64(dict,
			    "cmap_callback", cmap_cb);
		}
#ifdef notyet 
		else {
			int width;

			/*
			 * the idea is to 'open' display devices with no useful
			 * properties, in the hope that the firmware will
			 * properly initialize them and we can run things like
			 * genfb on them
			 */
			if (OF_getprop(node, "width", &width, sizeof(width))
			    != 4) {
				instance = OF_open(name);
#endif
	}
}

/*
 * Called back after autoconfiguration of a device is done
 */
void
device_register_post_config(device_t dev, void *aux)
{
	if (booted_device == NULL && device_is_a(dev, "sd")) {
		struct scsipibus_attach_args *sa = aux;
		struct scsipi_periph *periph = sa->sa_periph;
		uint64_t wwn = 0;
		int ofnode;

		/*
		 * If this is a FC-AL drive it will have
		 * aquired its WWN device property by now,
		 * so we can properly match it.
		 */
		if (prop_dictionary_get_uint64(device_properties(dev),
		    "port-wwn", &wwn)) {
			/*
			 * Different to what we do in device_register,
			 * we do not pass the "controller" ofnode,
			 * because FC-AL devices attach below a "fp" node,
			 * E.g.: /pci/SUNW,qlc@4/fp@0,0/disk
			 * and we need the parent of "disk" here.
			 */
			ofnode = device_ofnode(
			    device_parent(device_parent(dev)));
			for (ofnode = OF_child(ofnode);
			    ofnode != 0 && booted_device == NULL;
			    ofnode = OF_peer(ofnode)) {
				dev_path_drive_match(dev, ofnode,
				    periph->periph_target,
				    wwn, periph->periph_lun);
			}
		}
	}
}

static void
copyprops(device_t busdev, int node, prop_dictionary_t dict, int is_console)
{
	device_t cntrlr;
	prop_dictionary_t psycho;
	paddr_t fbpa, mem_base = 0;
	uint32_t temp, fboffset;
	uint32_t fbaddr = 0;
	int options;
	char output_device[256];
	char *pos;

	cntrlr = device_parent(busdev);
	if (cntrlr != NULL) {
		psycho = device_properties(cntrlr);
		prop_dictionary_get_uint64(psycho, "mem_base", &mem_base);
	}

	if (is_console)
		prop_dictionary_set_bool(dict, "is_console", 1);

	of_to_uint32_prop(dict, node, "width", "width");
	of_to_uint32_prop(dict, node, "height", "height");
	of_to_uint32_prop(dict, node, "linebytes", "linebytes");
	if (!of_to_uint32_prop(dict, node, "depth", "depth") &&
	    /* Some cards have an extra space in the property name */
	    !of_to_uint32_prop(dict, node, "depth ", "depth")) {
		/*
		 * XXX we should check linebytes vs. width but those
		 * FBs that don't have a depth property ( /chaos/control... )
		 * won't have linebytes either
		 */
		prop_dictionary_set_uint32(dict, "depth", 8);
	}

	OF_getprop(node, "address", &fbaddr, sizeof(fbaddr));
	if (fbaddr != 0) {
	
		pmap_extract(pmap_kernel(), fbaddr, &fbpa);
#ifdef DEBUG
		printf("membase: %lx fbpa: %lx\n", (unsigned long)mem_base,
		    (unsigned long)fbpa);
#endif
		if (mem_base == 0) {
			/* XXX this is guesswork */
			fboffset = (uint32_t)(fbpa & 0xffffffff);
		}
			fboffset = (uint32_t)(fbpa - mem_base);
		prop_dictionary_set_uint32(dict, "address", fboffset);
	}

	if (!of_to_dataprop(dict, node, "EDID", "EDID"))
		of_to_dataprop(dict, node, "edid", "EDID");

	temp = 0;
	if (OF_getprop(node, "ATY,RefCLK", &temp, sizeof(temp)) != 4) {

		OF_getprop(OF_parent(node), "ATY,RefCLK", &temp,
		    sizeof(temp));
	}
	if (temp != 0)
		prop_dictionary_set_uint32(dict, "refclk", temp / 10);

	/*
	 * finally, let's see if there's a video mode specified in
	 * output-device and pass it on so drivers like radeonfb
	 * can do their thing
	 */

	if (!is_console)
		return;

	options = OF_finddevice("/options");
	if ((options == 0) || (options == -1))
		return;
	if (OF_getprop(options, "output-device", output_device, 256) == 0)
		return;
	/* find the mode string if there is one */
	pos = strstr(output_device, ":r");
	if (pos == NULL)
		return;
	prop_dictionary_set_cstring(dict, "videomode", pos + 2);
}

static void
of_set_palette(void *cookie, int index, int r, int g, int b)
{
	int ih = (int)((intptr_t)cookie);

	OF_call_method_1("color!", ih, 4, r, g, b, index);
}