Deleted Added
full compact
32c32
< "$FreeBSD: stable/10/usr.sbin/pciconf/pciconf.c 246632 2013-02-10 19:35:40Z neel $";
---
> "$FreeBSD: stable/10/usr.sbin/pciconf/pciconf.c 261250 2014-01-28 21:56:18Z jhb $";
37a38
> #include <assert.h>
69a71
> static struct pcisel getsel(const char *str);
71c73,74
< static void list_devs(int verbose, int bars, int caps, int errors);
---
> static void list_devs(const char *name, int verbose, int bars, int caps,
> int errors);
86,89c89,92
< "usage: pciconf -l [-bcev]",
< " pciconf -a selector",
< " pciconf -r [-b | -h] selector addr[:addr2]",
< " pciconf -w [-b | -h] selector addr value");
---
> "usage: pciconf -l [-bcev] [device]",
> " pciconf -a device",
> " pciconf -r [-b | -h] device addr[:addr2]",
> " pciconf -w [-b | -h] device addr value");
148c151
< if ((listmode && optind != argc)
---
> if ((listmode && optind >= argc + 1)
155c158,159
< list_devs(verbose, bars, caps, errors);
---
> list_devs(optind + 1 == argc ? argv[optind] : NULL, verbose,
> bars, caps, errors);
172c176
< list_devs(int verbose, int bars, int caps, int errors)
---
> list_devs(const char *name, int verbose, int bars, int caps, int errors)
176a181
> struct pci_match_conf patterns[1];
188a194,203
> if (name != NULL) {
> bzero(&patterns, sizeof(patterns));
> patterns[0].pc_sel = getsel(name);
> patterns[0].flags = PCI_GETCONF_MATCH_DOMAIN |
> PCI_GETCONF_MATCH_BUS | PCI_GETCONF_MATCH_DEV |
> PCI_GETCONF_MATCH_FUNC;
> pc.num_patterns = 1;
> pc.pat_buf_len = sizeof(patterns);
> pc.patterns = patterns;
> }
560c575
< getsel(const char *str)
---
> getdevice(const char *name)
561a577,630
> struct pci_conf_io pc;
> struct pci_conf conf[1];
> struct pci_match_conf patterns[1];
> char *cp;
> int fd;
>
> fd = open(_PATH_DEVPCI, O_RDONLY, 0);
> if (fd < 0)
> err(1, "%s", _PATH_DEVPCI);
>
> bzero(&pc, sizeof(struct pci_conf_io));
> pc.match_buf_len = sizeof(conf);
> pc.matches = conf;
>
> bzero(&patterns, sizeof(patterns));
>
> /*
> * The pattern structure requires the unit to be split out from
> * the driver name. Walk backwards from the end of the name to
> * find the start of the unit.
> */
> if (name[0] == '\0')
> err(1, "Empty device name");
> cp = strchr(name, '\0');
> assert(cp != NULL && cp != name);
> cp--;
> while (cp != name && isdigit(cp[-1]))
> cp--;
> if (cp == name)
> errx(1, "Invalid device name");
> if ((size_t)(cp - name) + 1 > sizeof(patterns[0].pd_name))
> errx(1, "Device name i2s too long");
> memcpy(patterns[0].pd_name, name, cp - name);
> patterns[0].pd_unit = strtol(cp, &cp, 10);
> assert(*cp == '\0');
> patterns[0].flags = PCI_GETCONF_MATCH_NAME | PCI_GETCONF_MATCH_UNIT;
> pc.num_patterns = 1;
> pc.pat_buf_len = sizeof(patterns);
> pc.patterns = patterns;
>
> if (ioctl(fd, PCIOCGETCONF, &pc) == -1)
> err(1, "ioctl(PCIOCGETCONF)");
> if (pc.status != PCI_GETCONF_LAST_DEVICE &&
> pc.status != PCI_GETCONF_MORE_DEVS)
> errx(1, "error returned from PCIOCGETCONF ioctl");
> close(fd);
> if (pc.num_matches == 0)
> errx(1, "Device not found");
> return (conf[0].pc_sel);
> }
>
> static struct pcisel
> parsesel(const char *str)
> {
597a667,680
> static struct pcisel
> getsel(const char *str)
> {
>
> /*
> * No device names contain colons and selectors always contain
> * at least one colon.
> */
> if (strchr(str, ':') == NULL)
> return (getdevice(str));
> else
> return (parsesel(str));
> }
>