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