devinfo.c revision 87553
175752Smsmith/*-
275752Smsmith * Copyright (c) 2000, 2001 Michael Smith
375752Smsmith * Copyright (c) 2000 BSDi
475752Smsmith * All rights reserved.
575752Smsmith *
675752Smsmith * Redistribution and use in source and binary forms, with or without
775752Smsmith * modification, are permitted provided that the following conditions
875752Smsmith * are met:
975752Smsmith * 1. Redistributions of source code must retain the above copyright
1075752Smsmith *    notice, this list of conditions and the following disclaimer.
1175752Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1275752Smsmith *    notice, this list of conditions and the following disclaimer in the
1375752Smsmith *    documentation and/or other materials provided with the distribution.
1475752Smsmith *
1575752Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1675752Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1775752Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1875752Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1975752Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2075752Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2175752Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2275752Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2375752Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2475752Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2575752Smsmith * SUCH DAMAGE.
2675752Smsmith *
2775752Smsmith *	$FreeBSD: head/usr.sbin/devinfo/devinfo.c 87553 2001-12-09 07:32:55Z mikeh $
2875752Smsmith */
2975752Smsmith
3075752Smsmith/*
3175752Smsmith * Print information about system device configuration.
3275752Smsmith */
3375752Smsmith
3475752Smsmith#include <sys/types.h>
3575752Smsmith#include <err.h>
3675752Smsmith#include <stdio.h>
3775752Smsmith#include <unistd.h>
3875752Smsmith#include "devinfo.h"
3975752Smsmith
4075752Smsmithint	rflag;
4175752Smsmith
4287553Smikehstatic void	print_resource(struct devinfo_res *);
4387553Smikehstatic int	print_device_matching_resource(struct devinfo_res *, void *);
4487553Smikehstatic int	print_device_rman_resources(struct devinfo_rman *, void *);
4587553Smikehstatic int	print_device(struct devinfo_dev *, void *);
4687553Smikehstatic int	print_rman_resource(struct devinfo_res *, void *);
4787553Smikehstatic int	print_rman(struct devinfo_rman *, void *);
4887553Smikeh
4975752Smsmithstruct indent_arg
5075752Smsmith{
5175752Smsmith	int	indent;
5275752Smsmith	void	*arg;
5375752Smsmith};
5475752Smsmith
5575752Smsmith/*
5675752Smsmith * Print a resource.
5775752Smsmith */
5875752Smsmithvoid
5975752Smsmithprint_resource(struct devinfo_res *res)
6075752Smsmith{
6175752Smsmith	struct devinfo_rman	*rman;
6275752Smsmith	int			hexmode;
6375752Smsmith
6475752Smsmith	rman = devinfo_handle_to_rman(res->dr_rman);
6575752Smsmith	hexmode =  (rman->dm_size > 100) || (rman->dm_size == 0);
6675752Smsmith	printf(hexmode ? "0x%lx" : "%lu", res->dr_start);
6775752Smsmith	if (res->dr_size > 1)
6875752Smsmith		printf(hexmode ? "-0x%lx" : "-%lu",
6975752Smsmith		    res->dr_start + res->dr_size - 1);
7075752Smsmith}
7175752Smsmith
7275752Smsmith/*
7375752Smsmith * Print resource information if this resource matches the
7475752Smsmith * given device.
7575752Smsmith *
7675752Smsmith * If the given indent is 0, return an indicator that a matching
7775752Smsmith * resource exists.
7875752Smsmith */
7975752Smsmithint
8075752Smsmithprint_device_matching_resource(struct devinfo_res *res, void *arg)
8175752Smsmith{
8275752Smsmith	struct indent_arg	*ia = (struct indent_arg *)arg;
8375752Smsmith	struct devinfo_dev	*dev = (struct devinfo_dev *)ia->arg;
8475752Smsmith	int			i;
8575752Smsmith
8675752Smsmith	if (devinfo_handle_to_device(res->dr_device) == dev) {
8775752Smsmith		/* in 'detect' mode, found a match */
8875752Smsmith		if (ia->indent == 0)
8975752Smsmith			return(1);
9075752Smsmith		for (i = 0; i < ia->indent; i++)
9175752Smsmith			printf(" ");
9275752Smsmith		print_resource(res);
9375752Smsmith		printf("\n");
9475752Smsmith	}
9575752Smsmith	return(0);
9675752Smsmith}
9775752Smsmith
9875752Smsmith/*
9975752Smsmith * Print resource information for this device and resource manager.
10075752Smsmith */
10175752Smsmithint
10275752Smsmithprint_device_rman_resources(struct devinfo_rman *rman, void *arg)
10375752Smsmith{
10475752Smsmith	struct indent_arg	*ia = (struct indent_arg *)arg;
10575752Smsmith	struct devinfo_dev	*dev;
10675752Smsmith	int			indent, i;
10775752Smsmith
10875752Smsmith	indent = ia->indent;
10975752Smsmith	dev = (struct devinfo_dev *)ia->arg;
11075752Smsmith
11175752Smsmith	/* check whether there are any resources matching this device */
11275752Smsmith	ia->indent = 0;
11375752Smsmith	if (devinfo_foreach_rman_resource(rman,
11475752Smsmith	    print_device_matching_resource, ia) != 0) {
11575752Smsmith
11675752Smsmith		/* there are, print header */
11775752Smsmith		for (i = 0; i < indent; i++)
11875752Smsmith			printf(" ");
11975752Smsmith		printf("%s:\n", rman->dm_desc);
12075752Smsmith
12175752Smsmith		/* print resources */
12275752Smsmith		ia->indent = indent + 4;
12375752Smsmith		devinfo_foreach_rman_resource(rman,
12475752Smsmith		    print_device_matching_resource, ia);
12575752Smsmith	}
12675752Smsmith	ia->indent = indent;
12775752Smsmith	return(0);
12875752Smsmith}
12975752Smsmith
13075752Smsmith/*
13175752Smsmith * Print information about a device.
13275752Smsmith */
13375752Smsmithint
13475752Smsmithprint_device(struct devinfo_dev *dev, void *arg)
13575752Smsmith{
13675752Smsmith	struct indent_arg	ia;
13775752Smsmith	int			i, indent;
13875752Smsmith
13975752Smsmith	if (dev->dd_name[0] != 0) {
14087553Smikeh		indent = (int)(intptr_t)arg;
14175752Smsmith		for (i = 0; i < indent; i++)
14275752Smsmith			printf(" ");
14375752Smsmith		printf("%s\n", dev->dd_name);
14475752Smsmith		if (rflag) {
14575752Smsmith			ia.indent = indent + 4;
14675752Smsmith			ia.arg = dev;
14775752Smsmith			devinfo_foreach_rman(print_device_rman_resources,
14875752Smsmith			    (void *)&ia);
14975752Smsmith		}
15075752Smsmith	}
15175752Smsmith
15275752Smsmith	return(devinfo_foreach_device_child(dev, print_device,
15387553Smikeh	    (void *)((char *)arg + 2)));
15475752Smsmith}
15575752Smsmith
15675752Smsmith/*
15775752Smsmith * Print information about a resource under a resource manager.
15875752Smsmith */
15975752Smsmithint
16087553Smikehprint_rman_resource(struct devinfo_res *res, void *arg __unused)
16175752Smsmith{
16275752Smsmith	struct devinfo_dev	*dev;
16375752Smsmith
16475752Smsmith	printf("    ");
16575752Smsmith	print_resource(res);
16675752Smsmith	dev = devinfo_handle_to_device(res->dr_device);
16775752Smsmith	if ((dev != NULL) && (dev->dd_name[0] != 0)) {
16875752Smsmith		printf(" (%s)", dev->dd_name);
16975752Smsmith	} else {
17075752Smsmith		printf(" ----");
17175752Smsmith	}
17275752Smsmith	printf("\n");
17375752Smsmith	return(0);
17475752Smsmith}
17575752Smsmith
17675752Smsmith/*
17775752Smsmith * Print information about a resource manager.
17875752Smsmith */
17975752Smsmithint
18087553Smikehprint_rman(struct devinfo_rman *rman, void *arg __unused)
18175752Smsmith{
18275752Smsmith	printf("%s:\n", rman->dm_desc);
18375752Smsmith	devinfo_foreach_rman_resource(rman, print_rman_resource, 0);
18475752Smsmith	return(0);
18575752Smsmith}
18675752Smsmith
18775752Smsmithint
18875752Smsmithmain(int argc, char *argv[])
18975752Smsmith{
19075752Smsmith	struct devinfo_dev	*root;
19175752Smsmith	int			c, uflag;
19275752Smsmith
19375752Smsmith	uflag = 0;
19475752Smsmith	while ((c = getopt(argc, argv, "ru")) != -1) {
19575752Smsmith		switch(c) {
19675752Smsmith		case 'r':
19775752Smsmith			rflag++;
19875752Smsmith			break;
19975752Smsmith		case 'u':
20075752Smsmith			uflag++;
20175752Smsmith			break;
20275752Smsmith		default:
20375752Smsmith			errx(1, "usage: %s [-ru]", argv[0]);
20475752Smsmith		}
20575752Smsmith	}
20675752Smsmith
20775752Smsmith	if (devinfo_init())
20875752Smsmith		err(1, "devinfo_init");
20975752Smsmith
21075752Smsmith	if ((root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE)) == NULL)
21175752Smsmith		errx(1, "can't find root device");
21275752Smsmith
21375752Smsmith	/* print resource usage? */
21475752Smsmith	if (uflag) {
21575752Smsmith		devinfo_foreach_rman(print_rman, NULL);
21675752Smsmith	} else {
21775752Smsmith		/* print device hierarchy */
21875752Smsmith		devinfo_foreach_device_child(root, print_device, (void *)0);
21975752Smsmith	}
22075752Smsmith	return(0);
22175752Smsmith}
222