DF-2314 / pnphctl.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | /* * pnphctl.c -- userland driver for the pnp.c verification harness * (/dev/pnph0). Runs scenarios and prints results. * * Build: cc -O -Wall -o pnphctl pnphctl.c * Run: ./pnphctl <scenario#> [arg] */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <err.h> #include "pnph.h" static void hexdump_desc(const struct pnph_req *r) { int i; printf(" desc len=%u child=%s\n", r->o_desc_len, r->o_child); printf(" desc ascii: <%s>\n", r->o_desc); printf(" desc hex :"); for (i = 0; i < (int)sizeof(r->o_desc) && r->o_desc[i]; i++) { if (i && (i % 32) == 0) printf("\n "); printf(" %02x", (unsigned char)r->o_desc[i]); } printf("\n"); } static void dump_2315(const struct pnph_req *r) { printf(" nport: before=%u after=%#x\n", r->o_nport0, r->o_nportF); printf(" irqmask before/after: {%#x,%#x} -> {%#x,%#x}\n", r->o_irqmask0[0], r->o_irqmask0[1], r->o_irqmaskF[0], r->o_irqmaskF[1]); printf(" drqmask before/after: {%#x,%#x} -> {%#x,%#x}\n", r->o_drqmask0[0], r->o_drqmask0[1], r->o_drqmaskF[0], r->o_drqmaskF[1]); printf(" counters(nmem,nport,nirq,ndrq) before: {%#x,%#x,%#x,%#x}\n", r->o_cnt0[0], r->o_cnt0[1], r->o_cnt0[2], r->o_cnt0[3]); printf(" counters(nmem,nport,nirq,ndrq) after : {%#x,%#x,%#x,%#x}\n", r->o_cntF[0], r->o_cntF[1], r->o_cntF[2], r->o_cntF[3]); if (r->o_alloc_size) printf(" configs alloc=%u bytes, last quirk write " "ic_port[%u]=configs+%u -> escape=%s\n", r->o_alloc_size, r->o_max_index, r->o_max_off, r->o_max_off >= r->o_alloc_size ? "YES" : "no"); } int main(int argc, char **argv) { struct pnph_req r; int fd, sc; const char *what; if (argc < 2) errx(1, "usage: %s <scenario#> [arg]", argv[0]); sc = atoi(argv[1]); fd = open("/dev/pnph0", O_RDWR); if (fd < 0) err(1, "open /dev/pnph0"); memset(&r, 0, sizeof(r)); r.scenario = (uint32_t)sc; if (argc > 2) r.arg = (uint32_t)atoi(argv[2]); if (ioctl(fd, PNPHIOC_RUN, &r) < 0) err(1, "ioctl"); switch (sc) { case PNPH_SC_LAYOUT: what = "layout"; break; case PNPH_SC_2314_WALK: what = "DF-2314 walk (groomed 0x20 stack residue, len-0 ANSI)"; break; case PNPH_SC_2314_CTRL: what = "DF-2314 control (non-space residue)"; break; case PNPH_SC_2314_SANE: what = "DF-2314 sanity (normal ANSI string)"; break; case PNPH_SC_2315_D49: case PNPH_SC_2315_D50: case PNPH_SC_2315_P17: case PNPH_SC_2315_P18: case PNPH_SC_2315_PN: what = "DF-2315"; break; default: what = "?"; } printf("== scenario %d (%s) rc=%u\n", sc, what, r.o_rc); if ((sc >= 1 && sc <= 3) || sc == 10) hexdump_desc(&r); if (sc >= 4 && sc <= 8) dump_2315(&r); if (sc == PNPH_SC_2314_WALK || sc == 10) printf(" tries=%u nul_found=%u nul at pad+%lld " "(kva %p; pad [%p,%p))\n", r.o_tries, r.o_nul_found, (long long)r.o_nul_off, (void *)r.o_nul_addr, (void *)r.o_pad_lo, (void *)r.o_pad_hi); return (0); } |