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 2875752Smsmith/* 2975752Smsmith * Print information about system device configuration. 3075752Smsmith */ 3175752Smsmith 32124128Scharnier#include <sys/cdefs.h> 33124128Scharnier__FBSDID("$FreeBSD$"); 34124128Scharnier 3575752Smsmith#include <sys/types.h> 3675752Smsmith#include <err.h> 3775752Smsmith#include <stdio.h> 38162799Sru#include <stdlib.h> 3975752Smsmith#include <unistd.h> 4075752Smsmith#include "devinfo.h" 4175752Smsmith 42227252Sedstatic int rflag; 43227252Sedstatic int vflag; 4475752Smsmith 4587553Smikehstatic void print_resource(struct devinfo_res *); 4687553Smikehstatic int print_device_matching_resource(struct devinfo_res *, void *); 4787553Smikehstatic int print_device_rman_resources(struct devinfo_rman *, void *); 4887553Smikehstatic int print_device(struct devinfo_dev *, void *); 4987553Smikehstatic int print_rman_resource(struct devinfo_res *, void *); 5087553Smikehstatic int print_rman(struct devinfo_rman *, void *); 5187553Smikeh 5275752Smsmithstruct indent_arg 5375752Smsmith{ 5475752Smsmith int indent; 5575752Smsmith void *arg; 5675752Smsmith}; 5775752Smsmith 5875752Smsmith/* 5975752Smsmith * Print a resource. 6075752Smsmith */ 6175752Smsmithvoid 6275752Smsmithprint_resource(struct devinfo_res *res) 6375752Smsmith{ 6475752Smsmith struct devinfo_rman *rman; 6575752Smsmith int hexmode; 6675752Smsmith 6775752Smsmith rman = devinfo_handle_to_rman(res->dr_rman); 68173057Sjhb hexmode = (rman->dm_size > 1000) || (rman->dm_size == 0); 6975752Smsmith printf(hexmode ? "0x%lx" : "%lu", res->dr_start); 7075752Smsmith if (res->dr_size > 1) 7175752Smsmith printf(hexmode ? "-0x%lx" : "-%lu", 7275752Smsmith res->dr_start + res->dr_size - 1); 7375752Smsmith} 7475752Smsmith 7575752Smsmith/* 7675752Smsmith * Print resource information if this resource matches the 7775752Smsmith * given device. 7875752Smsmith * 7975752Smsmith * If the given indent is 0, return an indicator that a matching 8075752Smsmith * resource exists. 8175752Smsmith */ 8275752Smsmithint 8375752Smsmithprint_device_matching_resource(struct devinfo_res *res, void *arg) 8475752Smsmith{ 8575752Smsmith struct indent_arg *ia = (struct indent_arg *)arg; 8675752Smsmith struct devinfo_dev *dev = (struct devinfo_dev *)ia->arg; 8775752Smsmith int i; 8875752Smsmith 8975752Smsmith if (devinfo_handle_to_device(res->dr_device) == dev) { 9075752Smsmith /* in 'detect' mode, found a match */ 9175752Smsmith if (ia->indent == 0) 9275752Smsmith return(1); 9375752Smsmith for (i = 0; i < ia->indent; i++) 9475752Smsmith printf(" "); 9575752Smsmith print_resource(res); 9675752Smsmith printf("\n"); 9775752Smsmith } 9875752Smsmith return(0); 9975752Smsmith} 10075752Smsmith 10175752Smsmith/* 10275752Smsmith * Print resource information for this device and resource manager. 10375752Smsmith */ 10475752Smsmithint 10575752Smsmithprint_device_rman_resources(struct devinfo_rman *rman, void *arg) 10675752Smsmith{ 10775752Smsmith struct indent_arg *ia = (struct indent_arg *)arg; 10875752Smsmith int indent, i; 10975752Smsmith 11075752Smsmith indent = ia->indent; 11175752Smsmith 11275752Smsmith /* check whether there are any resources matching this device */ 11375752Smsmith ia->indent = 0; 11475752Smsmith if (devinfo_foreach_rman_resource(rman, 11575752Smsmith print_device_matching_resource, ia) != 0) { 11675752Smsmith 11775752Smsmith /* there are, print header */ 11875752Smsmith for (i = 0; i < indent; i++) 11975752Smsmith printf(" "); 12075752Smsmith printf("%s:\n", rman->dm_desc); 12175752Smsmith 12275752Smsmith /* print resources */ 12375752Smsmith ia->indent = indent + 4; 12475752Smsmith devinfo_foreach_rman_resource(rman, 12575752Smsmith print_device_matching_resource, ia); 12675752Smsmith } 12775752Smsmith ia->indent = indent; 12875752Smsmith return(0); 12975752Smsmith} 13075752Smsmith 13175752Smsmith/* 13275752Smsmith * Print information about a device. 13375752Smsmith */ 13475752Smsmithint 13575752Smsmithprint_device(struct devinfo_dev *dev, void *arg) 13675752Smsmith{ 13775752Smsmith struct indent_arg ia; 13875752Smsmith int i, indent; 13975752Smsmith 140199291Sattilio if (vflag || (dev->dd_name[0] != 0 && dev->dd_state >= DS_ATTACHED)) { 14187553Smikeh indent = (int)(intptr_t)arg; 14275752Smsmith for (i = 0; i < indent; i++) 14375752Smsmith printf(" "); 144111046Simp printf("%s", dev->dd_name[0] ? dev->dd_name : "unknown"); 145111046Simp if (vflag && *dev->dd_pnpinfo) 146111046Simp printf(" pnpinfo %s", dev->dd_pnpinfo); 147111046Simp if (vflag && *dev->dd_location) 148111046Simp printf(" at %s", dev->dd_location); 149111046Simp printf("\n"); 15075752Smsmith if (rflag) { 15175752Smsmith ia.indent = indent + 4; 15275752Smsmith ia.arg = dev; 15375752Smsmith devinfo_foreach_rman(print_device_rman_resources, 15475752Smsmith (void *)&ia); 15575752Smsmith } 15675752Smsmith } 15775752Smsmith 15875752Smsmith return(devinfo_foreach_device_child(dev, print_device, 15987553Smikeh (void *)((char *)arg + 2))); 16075752Smsmith} 16175752Smsmith 16275752Smsmith/* 16375752Smsmith * Print information about a resource under a resource manager. 16475752Smsmith */ 16575752Smsmithint 16687553Smikehprint_rman_resource(struct devinfo_res *res, void *arg __unused) 16775752Smsmith{ 16875752Smsmith struct devinfo_dev *dev; 16975752Smsmith 17075752Smsmith printf(" "); 17175752Smsmith print_resource(res); 17275752Smsmith dev = devinfo_handle_to_device(res->dr_device); 17375752Smsmith if ((dev != NULL) && (dev->dd_name[0] != 0)) { 17475752Smsmith printf(" (%s)", dev->dd_name); 17575752Smsmith } else { 17675752Smsmith printf(" ----"); 17775752Smsmith } 17875752Smsmith printf("\n"); 17975752Smsmith return(0); 18075752Smsmith} 18175752Smsmith 18275752Smsmith/* 18375752Smsmith * Print information about a resource manager. 18475752Smsmith */ 18575752Smsmithint 18687553Smikehprint_rman(struct devinfo_rman *rman, void *arg __unused) 18775752Smsmith{ 18875752Smsmith printf("%s:\n", rman->dm_desc); 18975752Smsmith devinfo_foreach_rman_resource(rman, print_rman_resource, 0); 19075752Smsmith return(0); 19175752Smsmith} 19275752Smsmith 19375752Smsmithint 19475752Smsmithmain(int argc, char *argv[]) 19575752Smsmith{ 19675752Smsmith struct devinfo_dev *root; 19775752Smsmith int c, uflag; 19875752Smsmith 19975752Smsmith uflag = 0; 200103663Simp while ((c = getopt(argc, argv, "ruv")) != -1) { 20175752Smsmith switch(c) { 20275752Smsmith case 'r': 20375752Smsmith rflag++; 20475752Smsmith break; 20575752Smsmith case 'u': 20675752Smsmith uflag++; 20775752Smsmith break; 208103663Simp case 'v': 209103663Simp vflag++; 210103663Simp break; 21175752Smsmith default: 212162799Sru fprintf(stderr, "%s\n%s\n", 213162799Sru "usage: devinfo [-rv]", 214162799Sru " devinfo -u"); 215162799Sru exit(1); 21675752Smsmith } 21775752Smsmith } 21875752Smsmith 21975752Smsmith if (devinfo_init()) 22075752Smsmith err(1, "devinfo_init"); 22175752Smsmith 22275752Smsmith if ((root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE)) == NULL) 22375752Smsmith errx(1, "can't find root device"); 22475752Smsmith 22575752Smsmith /* print resource usage? */ 22675752Smsmith if (uflag) { 22775752Smsmith devinfo_foreach_rman(print_rman, NULL); 22875752Smsmith } else { 22975752Smsmith /* print device hierarchy */ 23075752Smsmith devinfo_foreach_device_child(root, print_device, (void *)0); 23175752Smsmith } 23275752Smsmith return(0); 23375752Smsmith} 234