Source-Changes-HG archive

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

[src/netbsd-7]: src/usr.sbin/pcictl Pull up following revision(s) (requested ...



details:   https://anonhg.NetBSD.org/src/rev/9b2f1fbc33aa
branches:  netbsd-7
changeset: 798331:9b2f1fbc33aa
user:      martin <martin%NetBSD.org@localhost>
date:      Wed Sep 10 08:38:31 2014 +0000

description:
Pull up following revision(s) (requested by manu in ticket #77):
        usr.sbin/pcictl/pcictl.c: revision 1.21
        usr.sbin/pcictl/pcictl.8: revision 1.14
Read and write commands for pcictl, from riastradh@ and wiz@,
as discussed on tech-kern.

diffstat:

 usr.sbin/pcictl/pcictl.8 |   27 ++++++++++-
 usr.sbin/pcictl/pcictl.c |  121 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 145 insertions(+), 3 deletions(-)

diffs (203 lines):

diff -r ea6f34df2857 -r 9b2f1fbc33aa usr.sbin/pcictl/pcictl.8
--- a/usr.sbin/pcictl/pcictl.8  Mon Sep 08 19:17:59 2014 +0000
+++ b/usr.sbin/pcictl/pcictl.8  Wed Sep 10 08:38:31 2014 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: pcictl.8,v 1.10 2011/02/25 21:40:48 jmcneill Exp $
+.\"    $NetBSD: pcictl.8,v 1.10.22.1 2014/09/10 08:38:31 martin Exp $
 .\"
 .\" Copyright 2001 Wasabi Systems, Inc.
 .\" All rights reserved.
@@ -79,6 +79,31 @@
 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
+.Nm 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
+.Nm 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
diff -r ea6f34df2857 -r 9b2f1fbc33aa usr.sbin/pcictl/pcictl.c
--- a/usr.sbin/pcictl/pcictl.c  Mon Sep 08 19:17:59 2014 +0000
+++ b/usr.sbin/pcictl/pcictl.c  Wed Sep 10 08:38:31 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pcictl.c,v 1.18 2011/08/30 20:08:38 joerg Exp $        */
+/*     $NetBSD: pcictl.c,v 1.18.20.1 2014/09/10 08:38:31 martin Exp $  */
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -76,6 +76,8 @@
 
 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 @@
          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,87 @@
        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();
+       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();
+       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 +334,32 @@
            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