Index: Makefile =================================================================== --- Makefile +++ Makefile @@ -4,6 +4,7 @@ PROG= pciconf SRCS= pciconf.c cap.c err.c MAN= pciconf.8 +LIBADD= xo WARNS?= 3 Index: pciconf.c =================================================================== --- pciconf.c +++ pciconf.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -86,7 +87,8 @@ static void usage(void) { - fprintf(stderr, "%s\n%s\n%s\n%s\n", + + xo_error("%s\n%s\n%s\n%s\n", "usage: pciconf -l [-bcevV] [device]", " pciconf -a device", " pciconf -r [-b | -h] device addr[:addr2]", @@ -105,6 +107,10 @@ listmode = readmode = writemode = attachedmode = 0; bars = caps = errors = verbose = vpd = byte = isshort = 0; + argc = xo_parse_args(argc, argv); + if (argc < 0) + usage(); + while ((c = getopt(argc, argv, "abcehlrwvV")) != -1) { switch(c) { case 'a': @@ -192,7 +198,7 @@ fd = open(_PATH_DEVPCI, (caps || errors) ? O_RDWR : O_RDONLY, 0); if (fd < 0) - err(1, "%s", _PATH_DEVPCI); + xo_err(1, "%s", _PATH_DEVPCI); bzero(&pc, sizeof(struct pci_conf_io)); pc.match_buf_len = sizeof(conf); @@ -208,9 +214,10 @@ pc.patterns = patterns; } + xo_create(XO_STYLE_TEXT, XOF_CLOSE_FP); do { if (ioctl(fd, PCIOCGETCONF, &pc) == -1) - err(1, "ioctl(PCIOCGETCONF)"); + xo_err(1, "ioctl(PCIOCGETCONF)"); /* * 255 entries should be more than enough for most people, @@ -221,19 +228,20 @@ * not be desirable. */ if (pc.status == PCI_GETCONF_LIST_CHANGED) { - warnx("PCI device list changed, please try again"); + xo_warnx("PCI device list changed, please try again"); exitstatus = 1; close(fd); return; } else if (pc.status == PCI_GETCONF_ERROR) { - warnx("error returned from PCIOCGETCONF ioctl"); + xo_warnx("error returned from PCIOCGETCONF ioctl"); exitstatus = 1; close(fd); return; } for (p = conf; p < &conf[pc.num_matches]; p++) { - printf("%s%d@pci%d:%d:%d:%d:\tclass=0x%06x card=0x%08x " - "chip=0x%08x rev=0x%02x hdr=0x%02x\n", + xo_open_container("device"); + xo_emit("{:device-id/%s%d}@{:bus-id/pci%d:%d:%d:%d}:\tclass={:class-id/0x%06x} card={:card-id/0x%08x} " + "chip={:chip-id/0x%08x} rev={:rev/0x%02x} hdr={:hdr/0x%02x}\n", (p->pd_name && *p->pd_name) ? p->pd_name : "none", (p->pd_name && *p->pd_name) ? (int)p->pd_unit : @@ -254,9 +262,12 @@ list_errors(fd, p); if (vpd) list_vpd(fd, p); + xo_close_container("device"); } } while (pc.status == PCI_GETCONF_MORE_DEVS); + xo_finish(); + xo_destroy(NULL); close(fd); } @@ -282,6 +293,7 @@ return; } +// xo_open_container("bars"); for (i = 0; i <= max; i++) { bar.pbi_sel = p->pc_sel; bar.pbi_reg = PCIR_BAR(i); @@ -311,11 +323,14 @@ } base = bar.pbi_base & ~((uint64_t)0xf); } - printf(" bar [%02x] = type %s, range %2d, base %#jx, ", + xo_open_container("bar"); + xo_emit(" bar [{:addr/%02x}] = type {:type/%s}, range {:range/%2d}, base {:base/%#jx}, ", PCIR_BAR(i), type, range, (uintmax_t)base); - printf("size %ju, %s\n", (uintmax_t)bar.pbi_length, + xo_emit("size {:size/%ju}, {:state/%s}\n", (uintmax_t)bar.pbi_length, bar.pbi_enabled ? "enabled" : "disabled"); + xo_close_container("bar"); } +// xo_close_container("bars"); } static void @@ -325,9 +340,10 @@ struct pci_device_info *di; const char *dp; + xo_open_container("verbose"); TAILQ_FOREACH(vi, &pci_vendors, link) { if (vi->id == p->pc_vendor) { - printf(" vendor = '%s'\n", vi->desc); + xo_emit(" vendor = '{:vendor-name/%s}'\n", vi->desc); break; } } @@ -336,15 +352,16 @@ } else { TAILQ_FOREACH(di, &vi->devs, link) { if (di->id == p->pc_device) { - printf(" device = '%s'\n", di->desc); + xo_emit(" device = '{:device-name/%s}'\n", di->desc); break; } } } if ((dp = guess_class(p)) != NULL) - printf(" class = %s\n", dp); + xo_emit(" class = {:class-name/%s}\n", dp); if ((dp = guess_subclass(p)) != NULL) - printf(" subclass = %s\n", dp); + xo_emit(" subclass = {:subclass-name/%s}\n", dp); + xo_close_container("verbose"); } static void @@ -352,6 +369,7 @@ { struct pci_list_vpd_io list; struct pci_vpd_element *vpd, *end; + char *pve_str; list.plvi_sel = p->pc_sel; list.plvi_len = 0; @@ -367,10 +385,12 @@ vpd = list.plvi_data; end = (struct pci_vpd_element *)((char *)vpd + list.plvi_len); + xo_open_container("vpd"); for (; vpd < end; vpd = PVE_NEXT(vpd)) { if (vpd->pve_flags == PVE_FLAG_IDENT) { - printf(" VPD ident = '%.*s'\n", - (int)vpd->pve_datalen, vpd->pve_data); + strncpy(pve_str, (void*)&vpd->pve_data, vpd->pve_datalen); + xo_emit(" VPD ident = '{:ident/%s}'\n", pve_str); + free(pve_str); continue; } @@ -387,20 +407,27 @@ /* Handle extended capability keyword. */ if (!(vpd->pve_flags & PVE_FLAG_RW) && memcmp(vpd->pve_keyword, "CP", 2) == 0) { - printf(" VPD ro CP = ID %02x in map 0x%x[0x%x]\n", + xo_open_container("capability"); + xo_emit(" VPD {:mode/ro} {:keyword/CP} = ID {:id/%02x} in map {:addr/0x%x}[{:size/0x%x}]\n", (unsigned int)vpd->pve_data[0], PCIR_BAR((unsigned int)vpd->pve_data[1]), (unsigned int)vpd->pve_data[3] << 8 | (unsigned int)vpd->pve_data[2]); + xo_close_container("capability"); continue; } /* Remaining keywords should all have ASCII values. */ - printf(" VPD %s %c%c = '%.*s'\n", + strncpy(pve_str, (void*)&vpd->pve_data, vpd->pve_datalen); + xo_open_container("item"); + xo_emit(" VPD {:mode/%s} {:keyword/%c%c} = '{:value/%s}'\n", vpd->pve_flags & PVE_FLAG_RW ? "rw" : "ro", vpd->pve_keyword[0], vpd->pve_keyword[1], - (int)vpd->pve_datalen, vpd->pve_data); + pve_str); + xo_close_container("item"); + free(pve_str); } + xo_close_container("vpd"); free(list.plvi_data); } @@ -573,13 +600,13 @@ if ((id == 0) || (strlen(str) < 1)) continue; if ((cv = malloc(sizeof(struct pci_vendor_info))) == NULL) { - warn("allocating vendor entry"); + xo_warn("allocating vendor entry"); error = 1; break; } if ((cv->desc = strdup(str)) == NULL) { free(cv); - warn("allocating vendor description"); + xo_warn("allocating vendor description"); error = 1; break; } @@ -594,17 +621,17 @@ if ((id == 0) || (strlen(str) < 1)) continue; if (cv == NULL) { - warnx("device entry with no vendor!"); + xo_warnx("device entry with no vendor!"); continue; } if ((cd = malloc(sizeof(struct pci_device_info))) == NULL) { - warn("allocating device entry"); + xo_warn("allocating device entry"); error = 1; break; } if ((cd->desc = strdup(str)) == NULL) { free(cd); - warn("allocating device description"); + xo_warn("allocating device description"); error = 1; break; } @@ -632,7 +659,7 @@ pi.pi_width = width; if (ioctl(fd, PCIOCREAD, &pi) < 0) - err(1, "ioctl(PCIOCREAD)"); + xo_err(1, "ioctl(PCIOCREAD)"); return (pi.pi_data); } @@ -648,7 +675,7 @@ fd = open(_PATH_DEVPCI, O_RDONLY, 0); if (fd < 0) - err(1, "%s", _PATH_DEVPCI); + xo_err(1, "%s", _PATH_DEVPCI); bzero(&pc, sizeof(struct pci_conf_io)); pc.match_buf_len = sizeof(conf); @@ -662,16 +689,16 @@ * find the start of the unit. */ if (name[0] == '\0') - errx(1, "Empty device name"); + xo_errx(1, "Empty device name"); cp = strchr(name, '\0'); assert(cp != NULL && cp != name); cp--; while (cp != name && isdigit(cp[-1])) cp--; if (cp == name || !isdigit(*cp)) - errx(1, "Invalid device name"); + xo_errx(1, "Invalid device name"); if ((size_t)(cp - name) + 1 > sizeof(patterns[0].pd_name)) - errx(1, "Device name is too long"); + xo_errx(1, "Device name is too long"); memcpy(patterns[0].pd_name, name, cp - name); patterns[0].pd_unit = strtol(cp, &cp, 10); assert(*cp == '\0'); @@ -681,13 +708,13 @@ pc.patterns = patterns; if (ioctl(fd, PCIOCGETCONF, &pc) == -1) - err(1, "ioctl(PCIOCGETCONF)"); + xo_err(1, "ioctl(PCIOCGETCONF)"); if (pc.status != PCI_GETCONF_LAST_DEVICE && pc.status != PCI_GETCONF_MORE_DEVS) - errx(1, "error returned from PCIOCGETCONF ioctl"); + xo_errx(1, "error returned from PCIOCGETCONF ioctl"); close(fd); if (pc.num_matches == 0) - errx(1, "Device not found"); + xo_errx(1, "Device not found"); return (conf[0].pc_sel); } @@ -726,7 +753,7 @@ sel.pc_domain = 0; } if (*ep != '\x0' || ep == epbase) - errx(1, "cannot parse selector %s", str); + xo_errx(1, "cannot parse selector %s", str); return sel; } @@ -748,7 +775,9 @@ readone(int fd, struct pcisel *sel, long reg, int width) { - printf("%0*x", width*2, read_config(fd, sel, reg, width)); + char buf[11]; + snprintf(buf, sizeof(buf), "%0*x", width*2, read_config(fd, sel, reg, width)); + xo_emit("{:cfgdata/%s}", buf); } static void @@ -764,7 +793,7 @@ fd = open(_PATH_DEVPCI, O_RDWR, 0); if (fd < 0) - err(1, "%s", _PATH_DEVPCI); + xo_err(1, "%s", _PATH_DEVPCI); rend = rstart = strtol(reg, &end, 0); if (end && *end == ':') { @@ -796,10 +825,10 @@ fd = open(_PATH_DEVPCI, O_RDWR, 0); if (fd < 0) - err(1, "%s", _PATH_DEVPCI); + xo_err(1, "%s", _PATH_DEVPCI); if (ioctl(fd, PCIOCWRITE, &pi) < 0) - err(1, "ioctl(PCIOCWRITE)"); + xo_err(1, "ioctl(PCIOCWRITE)"); } static void @@ -812,11 +841,11 @@ fd = open(_PATH_DEVPCI, O_RDWR, 0); if (fd < 0) - err(1, "%s", _PATH_DEVPCI); + xo_err(1, "%s", _PATH_DEVPCI); if (ioctl(fd, PCIOCATTACHED, &pi) < 0) - err(1, "ioctl(PCIOCATTACHED)"); + xo_err(1, "ioctl(PCIOCATTACHED)"); + xo_emit("{:name/%s}: {:status/%s%s}\n", name, pi.pi_data == 0 ? "not " : "", "attached"); exitstatus = pi.pi_data ? 0 : 2; /* exit(2), if NOT attached */ - printf("%s: %s%s\n", name, pi.pi_data == 0 ? "not " : "", "attached"); }