summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@joyent.com>2019-07-08 15:04:29 +0000
committerRobert Mustacchi <rm@joyent.com>2019-08-19 17:40:33 +0000
commite386d4dde2e66dfdb5d0ac143d970d0a77af2786 (patch)
tree60f74a5e083e333c254b8f9ce5965955cfe9f9f6
parent33756ae2c166200412098dda3daab64de55214ab (diff)
downloadillumos-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.files3
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/devinfo.c74
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/devinfo.h7
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/genunix.c13
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/hotplug.c2
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/pci.c79
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/pci.h40
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 */