Source-Changes-HG archive

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

[src/trunk]: src/usr.sbin/pcictl read and write commands for pcictl, from ria...



details:   https://anonhg.NetBSD.org/src/rev/50593d0544c9
branches:  trunk
changeset: 331932:50593d0544c9
user:      manu <manu%NetBSD.org@localhost>
date:      Mon Sep 01 07:11:19 2014 +0000

description:
read and write commands for pcictl, from riastradh@ and wiz@
http://mail-index.netbsd.org/tech-kern/2014/08/26/msg017572.html

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 277d84ce0d55 -r 50593d0544c9 usr.sbin/pcictl/pcictl.8
--- a/usr.sbin/pcictl/pcictl.8  Mon Sep 01 06:38:35 2014 +0000
+++ b/usr.sbin/pcictl/pcictl.8  Mon Sep 01 07:11:19 2014 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: pcictl.8,v 1.13 2014/08/31 09:59:08 wiz Exp $
+.\"    $NetBSD: pcictl.8,v 1.14 2014/09/01 07:11:19 manu Exp $
 .\"
 .\" Copyright 2001 Wasabi Systems, Inc.
 .\" All rights reserved.
@@ -83,6 +83,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 277d84ce0d55 -r 50593d0544c9 usr.sbin/pcictl/pcictl.c
--- a/usr.sbin/pcictl/pcictl.c  Mon Sep 01 06:38:35 2014 +0000
+++ b/usr.sbin/pcictl/pcictl.c  Mon Sep 01 07:11:19 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pcictl.c,v 1.20 2014/08/31 09:59:08 wiz Exp $  */
+/*     $NetBSD: pcictl.c,v 1.21 2014/09/01 07:11:19 manu Exp $ */
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -77,6 +77,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",
@@ -89,10 +91,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));
 
@@ -234,6 +247,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)
 {
@@ -244,9 +338,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