diff options
| author | Scott Long <scottl@FreeBSD.org> | 2018-03-12 05:02:22 +0000 |
|---|---|---|
| committer | Scott Long <scottl@FreeBSD.org> | 2018-03-12 05:02:22 +0000 |
| commit | cf6ea6f27a13a3c125610876954cf4fe4fea7efd (patch) | |
| tree | 4f6e027e0792f348d14b5179c947e0f2a9b23bff /sys/dev/mps/mps.c | |
| parent | 054564747d324659ea9ab3900bd587176a4ace90 (diff) | |
Notes
Diffstat (limited to 'sys/dev/mps/mps.c')
| -rw-r--r-- | sys/dev/mps/mps.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/sys/dev/mps/mps.c b/sys/dev/mps/mps.c index 8a1684044386..77353b184a3e 100644 --- a/sys/dev/mps/mps.c +++ b/sys/dev/mps/mps.c @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); #include <sys/endian.h> #include <sys/eventhandler.h> #include <sys/sbuf.h> +#include <sys/priv.h> #include <machine/bus.h> #include <machine/resource.h> @@ -106,6 +107,7 @@ static void mps_enqueue_request(struct mps_softc *sc, struct mps_command *cm); static int mps_get_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts); static int mps_wait_db_ack(struct mps_softc *sc, int timeout, int sleep_flag); static int mps_debug_sysctl(SYSCTL_HANDLER_ARGS); +static int mps_dump_reqs(SYSCTL_HANDLER_ARGS); static void mps_parse_debug(struct mps_softc *sc, char *list); SYSCTL_NODE(_hw, OID_AUTO, mps, CTLFLAG_RD, 0, "MPS Driver Parameters"); @@ -1793,6 +1795,10 @@ mps_setup_sysctl(struct mps_softc *sc) OID_AUTO, "encl_table_dump", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, mps_mapping_encl_dump, "A", "Enclosure Table Dump"); + SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), + OID_AUTO, "dump_reqs", CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_SKIP, sc, 0, + mps_dump_reqs, "I", "Dump Active Requests"); + SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, "use_phy_num", CTLFLAG_RD, &sc->use_phynum, 0, "Use the phy number for enumeration"); @@ -1925,6 +1931,70 @@ mps_parse_debug(struct mps_softc *sc, char *list) return; } +struct mps_dumpreq_hdr { + uint32_t smid; + uint32_t state; + uint32_t numframes; + uint32_t deschi; + uint32_t desclo; +}; + +static int +mps_dump_reqs(SYSCTL_HANDLER_ARGS) +{ + struct mps_softc *sc; + struct mps_chain *chain, *chain1; + struct mps_command *cm; + struct mps_dumpreq_hdr hdr; + struct sbuf *sb; + uint32_t smid, state; + int i, numreqs, error = 0; + + sc = (struct mps_softc *)arg1; + + if ((error = priv_check(curthread, PRIV_DRIVER)) != 0) { + printf("priv check error %d\n", error); + return (error); + } + + state = MPS_CM_STATE_INQUEUE; + smid = 1; + numreqs = sc->num_reqs; + + if (req->newptr != NULL) + return (EINVAL); + + if (smid == 0 || smid > sc->num_reqs) + return (EINVAL); + if (numreqs <= 0 || (numreqs + smid > sc->num_reqs)) + numreqs = sc->num_reqs; + sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); + + /* Best effort, no locking */ + for (i = smid; i < numreqs; i++) { + cm = &sc->commands[i]; + if (cm->cm_state != state) + continue; + hdr.smid = i; + hdr.state = cm->cm_state; + hdr.numframes = 1; + hdr.deschi = cm->cm_desc.Words.High; + hdr.desclo = cm->cm_desc.Words.Low; + TAILQ_FOREACH_SAFE(chain, &cm->cm_chain_list, chain_link, + chain1) + hdr.numframes++; + sbuf_bcat(sb, &hdr, sizeof(hdr)); + sbuf_bcat(sb, cm->cm_req, 128); + TAILQ_FOREACH_SAFE(chain, &cm->cm_chain_list, chain_link, + chain1) + sbuf_bcat(sb, chain->chain, 128); + } + + error = sbuf_finish(sb); + sbuf_delete(sb); + return (error); +} + int mps_attach(struct mps_softc *sc) { |
