diff options
author | Robert Mustacchi <rm@joyent.com> | 2019-07-08 15:04:29 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2019-08-19 17:40:33 +0000 |
commit | e386d4dde2e66dfdb5d0ac143d970d0a77af2786 (patch) | |
tree | 60f74a5e083e333c254b8f9ce5965955cfe9f9f6 | |
parent | 33756ae2c166200412098dda3daab64de55214ab (diff) | |
download | illumos-joyent-e386d4dde2e66dfdb5d0ac143d970d0a77af2786.tar.gz |
11372 Want PCIe dcmds and walkers
Reviewed by: Jon Anderson <jon.anderson@joyent.com>
Reviewed by: Rob Johnston <rob.johnston@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Paul Winder <Paul.Winder@wdc.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
-rw-r--r-- | usr/src/cmd/mdb/common/modules/genunix/Makefile.files | 3 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/modules/genunix/devinfo.c | 74 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/modules/genunix/devinfo.h | 7 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/modules/genunix/genunix.c | 13 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/modules/genunix/hotplug.c | 2 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/modules/genunix/pci.c | 79 | ||||
-rw-r--r-- | usr/src/cmd/mdb/common/modules/genunix/pci.h | 40 |
7 files changed, 203 insertions, 15 deletions
diff --git a/usr/src/cmd/mdb/common/modules/genunix/Makefile.files b/usr/src/cmd/mdb/common/modules/genunix/Makefile.files index c78f42e7cb..9ddaec24c9 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/Makefile.files +++ b/usr/src/cmd/mdb/common/modules/genunix/Makefile.files @@ -21,7 +21,7 @@ # # Copyright 2011 Nexenta Systems, Inc. All rights reserved. # Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright (c) 2019, Joyent, Inc. +# Copyright 2019, Joyent, Inc. # Copyright (c) 2013 by Delphix. All rights reserved. # @@ -69,6 +69,7 @@ GENUNIX_SRCS = \ net.c \ netstack.c \ nvpair.c \ + pci.c \ pg.c \ rctl.c \ sobj.c \ diff --git a/usr/src/cmd/mdb/common/modules/genunix/devinfo.c b/usr/src/cmd/mdb/common/modules/genunix/devinfo.c index 61bb29777a..9578cd9079 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/devinfo.c +++ b/usr/src/cmd/mdb/common/modules/genunix/devinfo.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2019 Joyent, Inc. + * Copyright 2019, Joyent, Inc. */ #include <sys/types.h> @@ -41,6 +41,7 @@ #include <mdb/mdb_ks.h> #include "nvpair.h" +#include "pci.h" #include "devinfo.h" #define DEVINFO_TREE_INDENT 4 /* Indent for devs one down in tree */ @@ -78,15 +79,22 @@ prtconf_help(void) " -v be verbose - print device property lists\n" " -p only print the ancestors of the given node\n" " -c only print the children of the given node\n" - " -d driver only print instances of driver\n"); + " -d driver only print instances of driver\n" + " -i inst only print if the driver instance number is inst\n"); } void devinfo_help(void) { mdb_printf("Switches:\n" - " -q be quiet - don't print device property lists\n" - " -s print summary of dev_info structures\n"); + " -b type print bus of device if it matches type\n" + " -d print device private data\n" + " -q be quiet - don't print device property lists\n" + " -s print summary of dev_info structures\n" + "\n" + "The following types are supported for -b:\n" + "\n" + " * pcie print the PCI Express bus (pcie_bus_t)\n"); } @@ -995,6 +1003,11 @@ devinfo_print(uintptr_t addr, struct dev_info *dev, devinfo_cb_data_t *data) return (WALK_NEXT); } + if (data->di_instance != UINT64_MAX && + data->di_instance != (uint64_t)dev->devi_instance) { + return (WALK_NEXT); + } + /* * If we are output to a pipe, we only print the address of the * devinfo_t. @@ -1048,12 +1061,14 @@ prtconf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) data.di_flags = DEVINFO_PARENT | DEVINFO_CHILD; data.di_filter = NULL; + data.di_instance = UINT64_MAX; if (flags & DCMD_PIPE_OUT) data.di_flags |= DEVINFO_PIPE; if (mdb_getopts(argc, argv, 'd', MDB_OPT_STR, &data.di_filter, + 'i', MDB_OPT_UINT64, &data.di_instance, 'v', MDB_OPT_SETBITS, DEVINFO_VERBOSE, &data.di_flags, 'p', MDB_OPT_CLRBITS, DEVINFO_CHILD, &data.di_flags, 'c', MDB_OPT_CLRBITS, DEVINFO_PARENT, &data.di_flags, NULL) != argc) @@ -1113,6 +1128,7 @@ devinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) struct dev_info devi; devinfo_node_t din; devinfo_cb_data_t data; + char *bus = NULL; static const mdb_bitmask_t devi_state_masks[] = { { "DEVICE_OFFLINE", DEVI_DEVICE_OFFLINE, DEVI_DEVICE_OFFLINE }, @@ -1155,20 +1171,64 @@ devinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) data.di_flags = DEVINFO_VERBOSE; data.di_base = addr; data.di_filter = NULL; + data.di_instance = UINT64_MAX; if (mdb_getopts(argc, argv, + 'b', MDB_OPT_STR, &bus, + 'd', MDB_OPT_SETBITS, DEVINFO_DRIVER, &data.di_flags, 'q', MDB_OPT_CLRBITS, DEVINFO_VERBOSE, &data.di_flags, 's', MDB_OPT_SETBITS, DEVINFO_SUMMARY, &data.di_flags, NULL) != argc) return (DCMD_USAGE); + if (bus != NULL && data.di_flags != DEVINFO_VERBOSE) { + mdb_warn("the -b option cannot be used with other options\n"); + return (DCMD_USAGE); + } + + if ((data.di_flags & DEVINFO_DRIVER) != 0 && + data.di_flags != (DEVINFO_DRIVER | DEVINFO_VERBOSE)) { + mdb_warn("the -d option cannot be used with other options\n"); + return (DCMD_USAGE); + } + if ((flags & DCMD_ADDRSPEC) == 0) { mdb_warn( "devinfo doesn't give global information (try prtconf)\n"); return (DCMD_ERR); } - if (DCMD_HDRSPEC(flags) && data.di_flags & DEVINFO_SUMMARY) + if (mdb_vread(&devi, sizeof (devi), addr) == -1) { + mdb_warn("failed to read device"); + return (DCMD_ERR); + } + + if (bus != NULL) { + if (strcmp(bus, "pcie") == 0) { + uintptr_t bus_addr; + if (pcie_bus_match(&devi, &bus_addr)) { + mdb_printf("%p\n", bus_addr); + return (DCMD_OK); + } else { + mdb_warn("%p does not have a PCIe bus\n", + addr); + } + } + + mdb_warn("unknown bus type: %s\n", bus); + return (DCMD_ERR); + } + + if ((data.di_flags & DEVINFO_DRIVER) != 0) { + if ((flags & DCMD_PIPE_OUT) != 0 && + devi.devi_driver_data == NULL) { + return (DCMD_OK); + } + mdb_printf("%p\n", devi.devi_driver_data); + return (DCMD_OK); + } + + if (DCMD_HDRSPEC(flags) && data.di_flags & DEVINFO_SUMMARY) { mdb_printf( "%-?s %5s %?s %-20s %-s\n" "%-?s %5s %?s %-20s %-s\n" @@ -1176,10 +1236,6 @@ devinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) "DEVINFO", "MAJ", "REFCNT", "NODENAME", "NODESTATE", "", "INST", "CIRCULAR", "BINDNAME", "STATE", "", "", "THREAD", "", "FLAGS"); - - if (mdb_vread(&devi, sizeof (devi), addr) == -1) { - mdb_warn("failed to read device"); - return (DCMD_ERR); } if (data.di_flags & DEVINFO_SUMMARY) { diff --git a/usr/src/cmd/mdb/common/modules/genunix/devinfo.h b/usr/src/cmd/mdb/common/modules/genunix/devinfo.h index 438fc2268f..f8ddc6b046 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/devinfo.h +++ b/usr/src/cmd/mdb/common/modules/genunix/devinfo.h @@ -22,6 +22,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2019, Joyent, Inc. */ #ifndef _DEVINFO_H @@ -43,11 +44,13 @@ extern "C" { #define DEVINFO_SUMMARY 0x10 #define DEVINFO_HP_PHYSICAL 0x20 #define DEVINFO_PIPE 0x40 +#define DEVINFO_DRIVER 0x80 typedef struct devinfo_cb_data { uintptr_t di_base; uint_t di_flags; - char *di_filter; + char *di_filter; + uint64_t di_instance; } devinfo_cb_data_t; extern int devinfo_walk_init(mdb_walk_state_t *); @@ -88,6 +91,7 @@ extern int devt(uintptr_t, uint_t, int, const mdb_arg_t *); extern int softstate(uintptr_t, uint_t, int, const mdb_arg_t *); extern int devinfo_fm(uintptr_t, uint_t, int, const mdb_arg_t *); extern int devinfo_fmce(uintptr_t, uint_t, int, const mdb_arg_t *); +extern int devinfo2bus(uintptr_t, uint_t, int, const mdb_arg_t *); extern int soft_state_walk_init(mdb_walk_state_t *); extern int soft_state_walk_step(mdb_walk_state_t *); @@ -120,6 +124,7 @@ extern int minornodes(uintptr_t, uint_t, int, const mdb_arg_t *); extern void prtconf_help(void); extern void devinfo_help(void); +extern void devinfo2bus_help(void); #ifdef __cplusplus } diff --git a/usr/src/cmd/mdb/common/modules/genunix/genunix.c b/usr/src/cmd/mdb/common/modules/genunix/genunix.c index fb57328e65..9813cca26c 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/genunix.c +++ b/usr/src/cmd/mdb/common/modules/genunix/genunix.c @@ -95,6 +95,7 @@ #include "net.h" #include "netstack.h" #include "nvpair.h" +#include "pci.h" #include "pg.h" #include "rctl.h" #include "sobj.h" @@ -4121,8 +4122,8 @@ static const mdb_dcmd_t dcmds[] = { { "devbindings", "?[-qs] [device-name | major-num]", "print devinfo nodes bound to device-name or major-num", devbindings, devinfo_help }, - { "devinfo", ":[-qs]", "detailed devinfo of one node", devinfo, - devinfo_help }, + { "devinfo", ":[-qsd] [-b bus]", "detailed devinfo of one node", + devinfo, devinfo_help }, { "devinfo_audit", ":[-v]", "devinfo configuration audit record", devinfo_audit }, { "devinfo_audit_log", "?[-v]", "system wide devinfo configuration log", @@ -4146,8 +4147,8 @@ static const mdb_dcmd_t dcmds[] = { modctl2devinfo }, { "name2major", "<dev-name>", "convert dev name to major number", name2major }, - { "prtconf", "?[-vpc] [-d driver]", "print devinfo tree", prtconf, - prtconf_help }, + { "prtconf", "?[-vpc] [-d driver] [-i inst]", "print devinfo tree", + prtconf, prtconf_help }, { "softstate", ":<instance>", "retrieve soft-state pointer", softstate }, { "devinfo_fm", ":", "devinfo fault managment configuration", @@ -4708,6 +4709,10 @@ static const mdb_walker_t walkers[] = { { NVPAIR_WALKER_NAME, NVPAIR_WALKER_DESCR, nvpair_walk_init, nvpair_walk_step, NULL }, + /* from pci.c */ + { "pcie_bus", "walk all pcie_bus_t's", pcie_bus_walk_init, + pcie_bus_walk_step, NULL }, + /* from rctl.c */ { "rctl_dict_list", "walk all rctl_dict_entry_t's from rctl_lists", rctl_dict_walk_init, rctl_dict_walk_step, NULL }, diff --git a/usr/src/cmd/mdb/common/modules/genunix/hotplug.c b/usr/src/cmd/mdb/common/modules/genunix/hotplug.c index 725a44eb7d..f44b5218de 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/hotplug.c +++ b/usr/src/cmd/mdb/common/modules/genunix/hotplug.c @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2019, Joyent, Inc. */ #include <sys/mdb_modapi.h> @@ -115,6 +116,7 @@ hotplug(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) data.di_flags = 0; data.di_filter = NULL; + data.di_instance = UINT64_MAX; if (mdb_getopts(argc, argv, 'p', MDB_OPT_SETBITS, DEVINFO_HP_PHYSICAL, &data.di_flags, NULL) != argc) diff --git a/usr/src/cmd/mdb/common/modules/genunix/pci.c b/usr/src/cmd/mdb/common/modules/genunix/pci.c new file mode 100644 index 0000000000..075ce8f284 --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/genunix/pci.c @@ -0,0 +1,79 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019, Joyent, Inc. + */ + +/* + * PCIe related dcmds + */ + +#include <mdb/mdb_modapi.h> +#include <sys/dditypes.h> +#include <sys/ddi_impldefs.h> +#include <sys/pcie_impl.h> + +boolean_t +pcie_bus_match(const struct dev_info *devi, uintptr_t *bus_p) +{ + if (devi->devi_bus.port_up.info.port.type == DEVI_PORT_TYPE_PCI) { + *bus_p = (uintptr_t)devi->devi_bus.port_up.priv_p; + } else if (devi->devi_bus.port_down.info.port.type == + DEVI_PORT_TYPE_PCI) { + *bus_p = (uintptr_t)devi->devi_bus.port_down.priv_p; + } else { + return (B_FALSE); + } + + return (B_TRUE); +} + +int +pcie_bus_walk_init(mdb_walk_state_t *wsp) +{ + if (wsp->walk_addr != 0) { + mdb_warn("pcie_bus walker doesn't support non-global walks\n"); + return (WALK_ERR); + } + + if (mdb_layered_walk("devinfo", wsp) == -1) { + mdb_warn("couldn't walk \"devinfo\""); + return (WALK_ERR); + } + + return (WALK_NEXT); +} + +int +pcie_bus_walk_step(mdb_walk_state_t *wsp) +{ + const struct dev_info *devi; + uintptr_t bus_addr; + struct pcie_bus bus; + + if (wsp->walk_layer == NULL) { + mdb_warn("missing layered walk info\n"); + return (WALK_ERR); + } + + devi = wsp->walk_layer; + if (!pcie_bus_match(devi, &bus_addr)) { + return (WALK_NEXT); + } + + if (mdb_vread(&bus, sizeof (bus), bus_addr) == -1) { + mdb_warn("failed to read pcie_bus_t at %p", bus_addr); + return (WALK_NEXT); + } + + return (wsp->walk_callback(bus_addr, &bus, wsp->walk_cbdata)); +} diff --git a/usr/src/cmd/mdb/common/modules/genunix/pci.h b/usr/src/cmd/mdb/common/modules/genunix/pci.h new file mode 100644 index 0000000000..ee14a4619b --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/genunix/pci.h @@ -0,0 +1,40 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019, Joyent, Inc. + */ + +#ifndef _MDB_PCI_H +#define _MDB_PCI_H + +/* + * genunix PCI dcmds and walkers. + */ + +#include <mdb/mdb_modapi.h> +#include <sys/dditypes.h> +#include <sys/ddi_impldefs.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern int pcie_bus_walk_init(mdb_walk_state_t *); +extern int pcie_bus_walk_step(mdb_walk_state_t *); + +extern boolean_t pcie_bus_match(const struct dev_info *, uintptr_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* _MDB_PCI_H */ |