From owner-p4-projects@FreeBSD.ORG Sat Jan 18 23:13:14 2014 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 73A54A25; Sat, 18 Jan 2014 23:13:14 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 358C0A23 for ; Sat, 18 Jan 2014 23:13:14 +0000 (UTC) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:1900:2254:2068::682:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 15E4D191F for ; Sat, 18 Jan 2014 23:13:14 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.7/8.14.7) with ESMTP id s0INDD7o036844 for ; Sat, 18 Jan 2014 23:13:13 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.7/8.14.7/Submit) id s0INDDAT036841 for perforce@freebsd.org; Sat, 18 Jan 2014 23:13:13 GMT (envelope-from jhb@freebsd.org) Date: Sat, 18 Jan 2014 23:13:13 GMT Message-Id: <201401182313.s0INDDAT036841@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin Subject: PERFORCE change 1190148 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.17 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 18 Jan 2014 23:13:14 -0000 http://p4web.freebsd.org/@@1190148?ac=10 Change 1190148 by jhb@jhb_pippin on 2014/01/18 23:12:19 Allow PCI devices that are attached to a driver to be identified by their device name in addition to the selector. Affected files ... .. //depot/projects/pci/usr.sbin/pciconf/pciconf.8#3 edit .. //depot/projects/pci/usr.sbin/pciconf/pciconf.c#3 edit Differences ... ==== //depot/projects/pci/usr.sbin/pciconf/pciconf.8#3 (text+ko) ==== @@ -33,13 +33,13 @@ .Nd diagnostic utility for the PCI bus .Sh SYNOPSIS .Nm -.Fl l Oo Fl bcevV Oc Op Ar selector +.Fl l Oo Fl bcevV Oc Op Ar device .Nm -.Fl a Ar selector +.Fl a Ar device .Nm -.Fl r Oo Fl b | h Oc Ar selector addr Ns Op : Ns Ar addr2 +.Fl r Oo Fl b | h Oc Ar device addr Ns Op : Ns Ar addr2 .Nm -.Fl w Oo Fl b | h Oc Ar selector addr value +.Fl w Oo Fl b | h Oc Ar device addr value .Sh DESCRIPTION The .Nm @@ -67,16 +67,14 @@ .Ed .Pp The first column gives the -device name, unit number, and -.Ar selector . +device name, unit number, and selector . If there is no device configured in the kernel for the .Tn PCI device in question, the device name will be .Dq none . Unit numbers for unconfigured devices start at zero and are incremented for each unconfigured device that is encountered. -The -.Ar selector +The selector is in a form which may directly be used for the other forms of the command. The second column is the class code, with the class byte printed as two hex digits, followed by the sub-class and the interface bytes. @@ -207,7 +205,7 @@ usually an ASCII string. .Pp If the optional -.Ar selector +.Ar device argument is given with the .Fl l flag, @@ -219,13 +217,23 @@ except for .Fl l require a -.Ar selector -of the form +.Ar device . +The device can be identified either by a device name if the device is +attached to a driver or by a selector. +Selectors identify a PCI device by its address in PCI config space and +can take one of the following forms: +.Pp +.Bl -bullet -offset indent -compact +.It .Li pci Ns Va domain Ns \&: Ns Va bus Ns \&: Ns Va device Ns \&: \ -Ns Va function Ns , -.Li pci Ns Va bus Ns \&: Ns Va device Ns \&: Ns Va function Ns , or -.Li pci Ns Va bus Ns \&: Ns Va device Ns . -In case of an abridged form, omitted selector components are assumed to be 0. +Ns Va function Ns +.It +.Li pci Ns Va bus Ns \&: Ns Va device Ns \&: Ns Va function Ns +.It +.Li pci Ns Va bus Ns \&: Ns Va device Ns +.El +.Pp +In the case of an abridged form, omitted selector components are assumed to be 0. An optional leading device name followed by @ and an optional final colon will be ignored; this is so that the first column in the output of .Nm ==== //depot/projects/pci/usr.sbin/pciconf/pciconf.c#3 (text+ko) ==== @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -636,7 +637,61 @@ } static struct pcisel -getsel(const char *str) +getdevice(const char *name) +{ + 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) { char *ep = strchr(str, '@'); char *epbase; @@ -674,6 +729,20 @@ return sel; } +static struct pcisel +getsel(const char *str) +{ + + /* + * No device names contain colons and raw selectors always + * contain at least one colon. + */ + if (strchr(str, ':') == NULL) + return (getdevice(str)); + else + return (parsesel(str)); +} + static void readone(int fd, struct pcisel *sel, long reg, int width) {