tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: ixg(4) performances



   Date: Tue, 26 Aug 2014 15:40:41 +0000
   From: Taylor R Campbell <riastradh%NetBSD.org@localhost>

   How about the attached patch?  I've been sitting on this for months.

New version with some changes suggested by wiz@.
Index: usr.sbin/pcictl/pcictl.8
===================================================================
RCS file: /cvsroot/src/usr.sbin/pcictl/pcictl.8,v
retrieving revision 1.11
diff -p -u -r1.11 pcictl.8
--- usr.sbin/pcictl/pcictl.8    26 Aug 2014 16:21:15 -0000      1.11
+++ usr.sbin/pcictl/pcictl.8    26 Aug 2014 16:38:36 -0000
@@ -33,7 +33,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd February 25, 2011
+.Dd June 12, 2014
 .Dt PCICTL 8
 .Os
 .Sh NAME
@@ -79,6 +79,31 @@ at the specified bus, device, and functi
 If the bus is not specified, it defaults to the bus number of the
 PCI bus specified on the command line.
 If the function is not specified, it defaults to 0.
+.Pp
+.Cm read
+.Op Fl b Ar bus
+.Fl d Ar device
+.Op Fl f Ar function
+.Ar reg
+.Pp
+Read the specified 32-bit aligned PCI configuration register and print
+it in hexadecimal to standard output.
+If the bus is not specified, it defaults to the bus number of the
+PCI bus specified on the command line.
+If the function is not specified, it defaults to 0.
+.Pp
+.Cm write
+.Op Fl b Ar bus
+.Fl d Ar device
+.Op Fl f Ar function
+.Ar reg
+.Ar value
+.Pp
+Write the specified value to the specified 32-bit aligned PCI
+configuration register.
+If the bus is not specified, it defaults to the bus number of the
+PCI bus specified on the command line.
+If the function is not specified, it defaults to 0.
 .Sh FILES
 .Pa /dev/pci*
 - PCI bus device nodes
Index: usr.sbin/pcictl/pcictl.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/pcictl/pcictl.c,v
retrieving revision 1.18
diff -p -u -r1.18 pcictl.c
--- usr.sbin/pcictl/pcictl.c    30 Aug 2011 20:08:38 -0000      1.18
+++ usr.sbin/pcictl/pcictl.c    26 Aug 2014 16:38:36 -0000
@@ -76,6 +76,8 @@ static int    print_numbers = 0;
 
 static void    cmd_list(int, char *[]);
 static void    cmd_dump(int, char *[]);
+static void    cmd_read(int, char *[]);
+static void    cmd_write(int, char *[]);
 
 static const struct command commands[] = {
        { "list",
@@ -88,10 +90,21 @@ static const struct command commands[] =
          cmd_dump,
          O_RDONLY },
 
+       { "read",
+         "[-b bus] -d device [-f function] reg",
+         cmd_read,
+         O_RDONLY },
+
+       { "write",
+         "[-b bus] -d device [-f function] reg value",
+         cmd_write,
+         O_WRONLY },
+
        { 0, 0, 0, 0 },
 };
 
 static int     parse_bdf(const char *);
+static u_int   parse_reg(const char *);
 
 static void    scan_pci(int, int, int, void (*)(u_int, u_int, u_int));
 
@@ -230,6 +243,91 @@ cmd_dump(int argc, char *argv[])
        scan_pci(bus, dev, func, scan_pci_dump);
 }
 
+static void
+cmd_read(int argc, char *argv[])
+{
+       int bus, dev, func;
+       u_int reg;
+       pcireg_t value;
+       int ch;
+
+       bus = pci_businfo.busno;
+       func = 0;
+       dev = -1;
+
+       while ((ch = getopt(argc, argv, "b:d:f:")) != -1) {
+               switch (ch) {
+               case 'b':
+                       bus = parse_bdf(optarg);
+                       break;
+               case 'd':
+                       dev = parse_bdf(optarg);
+                       break;
+               case 'f':
+                       func = parse_bdf(optarg);
+                       break;
+               default:
+                       usage();
+               }
+       }
+       argv += optind;
+       argc -= optind;
+
+       if (argc != 1)
+               usage();
+       if (dev == -1)
+               errx(EXIT_FAILURE, "read: must specify a device number");
+       reg = parse_reg(argv[0]);
+       if (pcibus_conf_read(pcifd, bus, dev, func, reg, &value) == -1)
+               err(EXIT_FAILURE, "pcibus_conf_read"
+                   "(bus %d dev %d func %d reg %u)", bus, dev, func, reg);
+       if (printf("%08x\n", value) < 0)
+               err(EXIT_FAILURE, "printf");
+}
+
+static void
+cmd_write(int argc, char *argv[])
+{
+       int bus, dev, func;
+       u_int reg;
+       pcireg_t value;
+       int ch;
+
+       bus = pci_businfo.busno;
+       func = 0;
+       dev = -1;
+
+       while ((ch = getopt(argc, argv, "b:d:f:")) != -1) {
+               switch (ch) {
+               case 'b':
+                       bus = parse_bdf(optarg);
+                       break;
+               case 'd':
+                       dev = parse_bdf(optarg);
+                       break;
+               case 'f':
+                       func = parse_bdf(optarg);
+                       break;
+               default:
+                       usage();
+               }
+       }
+       argv += optind;
+       argc -= optind;
+
+       if (argc != 2)
+               usage();
+       if (dev == -1)
+               errx(EXIT_FAILURE, "write: must specify a device number");
+       reg = parse_reg(argv[0]);
+       __CTASSERT(sizeof(value) == sizeof(u_int));
+       value = parse_reg(argv[1]);
+       if (pcibus_conf_write(pcifd, bus, dev, func, reg, value) == -1)
+               err(EXIT_FAILURE, "pcibus_conf_write"
+                   "(bus %d dev %d func %d reg %u value 0x%x)",
+                   bus, dev, func, reg, value);
+}
+
 static int
 parse_bdf(const char *str)
 {
@@ -240,9 +338,32 @@ parse_bdf(const char *str)
            strcmp(str, "any") == 0)
                return (-1);
 
+       errno = 0;
        value = strtol(str, &end, 0);
-       if (*end != '\0') 
+       if ((str[0] == '\0') || (*end != '\0'))
+               errx(EXIT_FAILURE, "\"%s\" is not a number", str);
+       if ((errno == ERANGE) && ((value == LONG_MIN) || (value == LONG_MAX)))
+               errx(EXIT_FAILURE, "out of range: %s", str);
+       if ((value < INT_MIN) || (INT_MAX < value))
+               errx(EXIT_FAILURE, "out of range: %lu", value);
+
+       return value;
+}
+
+static u_int
+parse_reg(const char *str)
+{
+       unsigned long value;
+       char *end;
+
+       errno = 0;
+       value = strtoul(str, &end, 0);
+       if (*end != '\0')
                errx(EXIT_FAILURE, "\"%s\" is not a number", str);
+       if ((errno == ERANGE) && (value == ULONG_MAX))
+               errx(EXIT_FAILURE, "out of range: %s", str);
+       if (UINT_MAX < value)
+               errx(EXIT_FAILURE, "out of range: %lu", value);
 
        return value;
 }


Home | Main Index | Thread Index | Old Index