Wed Sep 10 08:38:31 2014 UTC ()
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.


(martin)
diff -r1.10 -r1.10.22.1 src/usr.sbin/pcictl/pcictl.8
diff -r1.18 -r1.18.20.1 src/usr.sbin/pcictl/pcictl.c

cvs diff -r1.10 -r1.10.22.1 src/usr.sbin/pcictl/pcictl.8 (expand / switch to unified diff)

--- src/usr.sbin/pcictl/pcictl.8 2011/02/25 21:40:48 1.10
+++ src/usr.sbin/pcictl/pcictl.8 2014/09/10 08:38:31 1.10.22.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1.\" $NetBSD: pcictl.8,v 1.10 2011/02/25 21:40:48 jmcneill Exp $ 1.\" $NetBSD: pcictl.8,v 1.10.22.1 2014/09/10 08:38:31 martin Exp $
2.\" 2.\"
3.\" Copyright 2001 Wasabi Systems, Inc. 3.\" Copyright 2001 Wasabi Systems, Inc.
4.\" All rights reserved. 4.\" All rights reserved.
5.\" 5.\"
6.\" Written by Jason R. Thorpe for Wasabi Systems, Inc. 6.\" Written by Jason R. Thorpe for Wasabi Systems, Inc.
7.\" 7.\"
8.\" Redistribution and use in source and binary forms, with or without 8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions 9.\" modification, are permitted provided that the following conditions
10.\" are met: 10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright 11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer. 12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
@@ -69,25 +69,50 @@ Any locator not specified defaults @@ -69,25 +69,50 @@ Any locator not specified defaults
69to a wildcard, or may be explicitly wildcarded by specifying 69to a wildcard, or may be explicitly wildcarded by specifying
70.Dq any . 70.Dq any .
71.Pp 71.Pp
72.Nm dump 72.Nm dump
73.Op Fl b Ar bus 73.Op Fl b Ar bus
74.Fl d Ar device 74.Fl d Ar device
75.Op Fl f Ar function 75.Op Fl f Ar function
76.Pp 76.Pp
77Dump the PCI configuration space for the specified device located 77Dump the PCI configuration space for the specified device located
78at the specified bus, device, and function. 78at the specified bus, device, and function.
79If the bus is not specified, it defaults to the bus number of the 79If the bus is not specified, it defaults to the bus number of the
80PCI bus specified on the command line. 80PCI bus specified on the command line.
81If the function is not specified, it defaults to 0. 81If the function is not specified, it defaults to 0.
 82.Pp
 83.Nm read
 84.Op Fl b Ar bus
 85.Fl d Ar device
 86.Op Fl f Ar function
 87.Ar reg
 88.Pp
 89Read the specified 32-bit aligned PCI configuration register and print
 90it in hexadecimal to standard output.
 91If the bus is not specified, it defaults to the bus number of the
 92PCI bus specified on the command line.
 93If the function is not specified, it defaults to 0.
 94.Pp
 95.Nm write
 96.Op Fl b Ar bus
 97.Fl d Ar device
 98.Op Fl f Ar function
 99.Ar reg
 100.Ar value
 101.Pp
 102Write the specified value to the specified 32-bit aligned PCI
 103configuration register.
 104If the bus is not specified, it defaults to the bus number of the
 105PCI bus specified on the command line.
 106If the function is not specified, it defaults to 0.
82.Sh FILES 107.Sh FILES
83.Pa /dev/pci* 108.Pa /dev/pci*
84- PCI bus device nodes 109- PCI bus device nodes
85.Sh SEE ALSO 110.Sh SEE ALSO
86.Xr pci 3 , 111.Xr pci 3 ,
87.Xr pci 4 , 112.Xr pci 4 ,
88.Xr drvctl 8 113.Xr drvctl 8
89.Sh HISTORY 114.Sh HISTORY
90The 115The
91.Nm 116.Nm
92command first appeared in 117command first appeared in
93.Nx 1.6 . 118.Nx 1.6 .

cvs diff -r1.18 -r1.18.20.1 src/usr.sbin/pcictl/pcictl.c (expand / switch to unified diff)

--- src/usr.sbin/pcictl/pcictl.c 2011/08/30 20:08:38 1.18
+++ src/usr.sbin/pcictl/pcictl.c 2014/09/10 08:38:31 1.18.20.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pcictl.c,v 1.18 2011/08/30 20:08:38 joerg Exp $ */ 1/* $NetBSD: pcictl.c,v 1.18.20.1 2014/09/10 08:38:31 martin Exp $ */
2 2
3/* 3/*
4 * Copyright 2001 Wasabi Systems, Inc. 4 * Copyright 2001 Wasabi Systems, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -66,42 +66,55 @@ struct command { @@ -66,42 +66,55 @@ struct command {
66__dead static void usage(void); 66__dead static void usage(void);
67 67
68static int pcifd; 68static int pcifd;
69 69
70static struct pciio_businfo pci_businfo; 70static struct pciio_businfo pci_businfo;
71 71
72static const char *dvname; 72static const char *dvname;
73static char dvname_store[MAXPATHLEN]; 73static char dvname_store[MAXPATHLEN];
74static const char *cmdname; 74static const char *cmdname;
75static int print_numbers = 0; 75static int print_numbers = 0;
76 76
77static void cmd_list(int, char *[]); 77static void cmd_list(int, char *[]);
78static void cmd_dump(int, char *[]); 78static void cmd_dump(int, char *[]);
 79static void cmd_read(int, char *[]);
 80static void cmd_write(int, char *[]);
79 81
80static const struct command commands[] = { 82static const struct command commands[] = {
81 { "list", 83 { "list",
82 "[-n] [-b bus] [-d device] [-f function]", 84 "[-n] [-b bus] [-d device] [-f function]",
83 cmd_list, 85 cmd_list,
84 O_RDONLY }, 86 O_RDONLY },
85 87
86 { "dump", 88 { "dump",
87 "[-b bus] -d device [-f function]", 89 "[-b bus] -d device [-f function]",
88 cmd_dump, 90 cmd_dump,
89 O_RDONLY }, 91 O_RDONLY },
90 92
 93 { "read",
 94 "[-b bus] -d device [-f function] reg",
 95 cmd_read,
 96 O_RDONLY },
 97
 98 { "write",
 99 "[-b bus] -d device [-f function] reg value",
 100 cmd_write,
 101 O_WRONLY },
 102
91 { 0, 0, 0, 0 }, 103 { 0, 0, 0, 0 },
92}; 104};
93 105
94static int parse_bdf(const char *); 106static int parse_bdf(const char *);
 107static u_int parse_reg(const char *);
95 108
96static void scan_pci(int, int, int, void (*)(u_int, u_int, u_int)); 109static void scan_pci(int, int, int, void (*)(u_int, u_int, u_int));
97 110
98static void scan_pci_list(u_int, u_int, u_int); 111static void scan_pci_list(u_int, u_int, u_int);
99static void scan_pci_dump(u_int, u_int, u_int); 112static void scan_pci_dump(u_int, u_int, u_int);
100 113
101int 114int
102main(int argc, char *argv[]) 115main(int argc, char *argv[])
103{ 116{
104 int i; 117 int i;
105 118
106 /* Must have at least: device command */ 119 /* Must have at least: device command */
107 if (argc < 3) 120 if (argc < 3)
@@ -220,39 +233,143 @@ cmd_dump(int argc, char *argv[]) @@ -220,39 +233,143 @@ cmd_dump(int argc, char *argv[])
220 if (argc != 0) 233 if (argc != 0)
221 usage(); 234 usage();
222 235
223 if (bus == -1) 236 if (bus == -1)
224 errx(EXIT_FAILURE, "dump: wildcard bus number not permitted"); 237 errx(EXIT_FAILURE, "dump: wildcard bus number not permitted");
225 if (dev == -1) 238 if (dev == -1)
226 errx(EXIT_FAILURE, "dump: must specify a device number"); 239 errx(EXIT_FAILURE, "dump: must specify a device number");
227 if (func == -1) 240 if (func == -1)
228 errx(EXIT_FAILURE, "dump: wildcard function number not permitted"); 241 errx(EXIT_FAILURE, "dump: wildcard function number not permitted");
229 242
230 scan_pci(bus, dev, func, scan_pci_dump); 243 scan_pci(bus, dev, func, scan_pci_dump);
231} 244}
232 245
 246static void
 247cmd_read(int argc, char *argv[])
 248{
 249 int bus, dev, func;
 250 u_int reg;
 251 pcireg_t value;
 252 int ch;
 253
 254 bus = pci_businfo.busno;
 255 func = 0;
 256 dev = -1;
 257
 258 while ((ch = getopt(argc, argv, "b:d:f:")) != -1) {
 259 switch (ch) {
 260 case 'b':
 261 bus = parse_bdf(optarg);
 262 break;
 263 case 'd':
 264 dev = parse_bdf(optarg);
 265 break;
 266 case 'f':
 267 func = parse_bdf(optarg);
 268 break;
 269 default:
 270 usage();
 271 }
 272 }
 273 argv += optind;
 274 argc -= optind;
 275
 276 if (argc != 1)
 277 usage();
 278 reg = parse_reg(argv[0]);
 279 if (pcibus_conf_read(pcifd, bus, dev, func, reg, &value) == -1)
 280 err(EXIT_FAILURE, "pcibus_conf_read"
 281 "(bus %d dev %d func %d reg %u)", bus, dev, func, reg);
 282 if (printf("%08x\n", value) < 0)
 283 err(EXIT_FAILURE, "printf");
 284}
 285
 286static void
 287cmd_write(int argc, char *argv[])
 288{
 289 int bus, dev, func;
 290 u_int reg;
 291 pcireg_t value;
 292 int ch;
 293
 294 bus = pci_businfo.busno;
 295 func = 0;
 296 dev = -1;
 297
 298 while ((ch = getopt(argc, argv, "b:d:f:")) != -1) {
 299 switch (ch) {
 300 case 'b':
 301 bus = parse_bdf(optarg);
 302 break;
 303 case 'd':
 304 dev = parse_bdf(optarg);
 305 break;
 306 case 'f':
 307 func = parse_bdf(optarg);
 308 break;
 309 default:
 310 usage();
 311 }
 312 }
 313 argv += optind;
 314 argc -= optind;
 315
 316 if (argc != 2)
 317 usage();
 318 reg = parse_reg(argv[0]);
 319 __CTASSERT(sizeof(value) == sizeof(u_int));
 320 value = parse_reg(argv[1]);
 321 if (pcibus_conf_write(pcifd, bus, dev, func, reg, value) == -1)
 322 err(EXIT_FAILURE, "pcibus_conf_write"
 323 "(bus %d dev %d func %d reg %u value 0x%x)",
 324 bus, dev, func, reg, value);
 325}
 326
233static int 327static int
234parse_bdf(const char *str) 328parse_bdf(const char *str)
235{ 329{
236 long value; 330 long value;
237 char *end; 331 char *end;
238 332
239 if (strcmp(str, "all") == 0 || 333 if (strcmp(str, "all") == 0 ||
240 strcmp(str, "any") == 0) 334 strcmp(str, "any") == 0)
241 return (-1); 335 return (-1);
242 336
 337 errno = 0;
243 value = strtol(str, &end, 0); 338 value = strtol(str, &end, 0);
244 if (*end != '\0')  339 if ((str[0] == '\0') || (*end != '\0'))
 340 errx(EXIT_FAILURE, "\"%s\" is not a number", str);
 341 if ((errno == ERANGE) && ((value == LONG_MIN) || (value == LONG_MAX)))
 342 errx(EXIT_FAILURE, "out of range: %s", str);
 343 if ((value < INT_MIN) || (INT_MAX < value))
 344 errx(EXIT_FAILURE, "out of range: %lu", value);
 345
 346 return value;
 347}
 348
 349static u_int
 350parse_reg(const char *str)
 351{
 352 unsigned long value;
 353 char *end;
 354
 355 errno = 0;
 356 value = strtoul(str, &end, 0);
 357 if (*end != '\0')
245 errx(EXIT_FAILURE, "\"%s\" is not a number", str); 358 errx(EXIT_FAILURE, "\"%s\" is not a number", str);
 359 if ((errno == ERANGE) && (value == ULONG_MAX))
 360 errx(EXIT_FAILURE, "out of range: %s", str);
 361 if (UINT_MAX < value)
 362 errx(EXIT_FAILURE, "out of range: %lu", value);
246 363
247 return value; 364 return value;
248} 365}
249 366
250static void 367static void
251scan_pci(int busarg, int devarg, int funcarg, void (*cb)(u_int, u_int, u_int)) 368scan_pci(int busarg, int devarg, int funcarg, void (*cb)(u_int, u_int, u_int))
252{ 369{
253 u_int busmin, busmax; 370 u_int busmin, busmax;
254 u_int devmin, devmax; 371 u_int devmin, devmax;
255 u_int funcmin, funcmax; 372 u_int funcmin, funcmax;
256 u_int bus, dev, func; 373 u_int bus, dev, func;
257 pcireg_t id, bhlcr; 374 pcireg_t id, bhlcr;
258 375