/*
- * Linux PCI Utilities -- Manipulate PCI Configuration Registers
+ * The PCI Utilities -- Manipulate PCI Configuration Registers
*
- * Copyright (c) 1998--2003 Martin Mares <mj@ucw.cz>
+ * Copyright (c) 1998--2006 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
static int verbose; /* Verbosity level */
static int demo_mode; /* Only show */
+const char program_name[] = "setpci";
+
static struct pci_access *pacc;
struct value {
{
if (verbose)
printf(" = ");
- if (!demo_mode)
+ switch (width)
{
- switch (width)
- {
- case 1:
- x = pci_read_byte(dev, addr);
- break;
- case 2:
- x = pci_read_word(dev, addr);
- break;
- default:
- x = pci_read_long(dev, addr);
- break;
- }
- printf(formats[width], x);
+ case 1:
+ x = pci_read_byte(dev, addr);
+ break;
+ case 2:
+ x = pci_read_word(dev, addr);
+ break;
+ default:
+ x = pci_read_long(dev, addr);
+ break;
}
- else
- putchar('?');
+ printf(formats[width], x);
putchar('\n');
}
}
}
struct reg_name {
- int offset;
- int width;
+ unsigned int offset;
+ unsigned int width;
const char *name;
};
{ 0x00, 0, NULL }
};
-static void usage(void) __attribute__((noreturn));
-
-static void
-usage(void)
+static void NONRET
+usage(char *msg, ...)
{
+ va_list args;
+ va_start(args, msg);
+ if (msg)
+ {
+ fprintf(stderr, "setpci: ");
+ vfprintf(stderr, msg, args);
+ fprintf(stderr, "\n\n");
+ }
fprintf(stderr,
"Usage: setpci [<options>] (<device>+ <reg>[=<values>]*)*\n\
-f\t\tDon't complain if there's nothing to do\n\
-v\t\tBe verbose\n\
-D\t\tList changes, don't commit them\n"
GENERIC_HELP
-"<device>:\t-s [[<bus>]:][<slot>][.[<func>]]\n"
+"<device>:\t-s [[[<domain>]:][<bus>]:][<slot>][.[<func>]]\n"
"\t|\t-d [<vendor>]:[<device>]\n"
"<reg>:\t\t<number>[.(B|W|L)]\n"
" |\t\t<name>\n"
argc--; argv++;
}
else
- usage();
+ usage(NULL);
c = "";
}
else
arg = NULL;
if (!parse_generic_option(*e, pacc, arg))
- usage();
+ usage(NULL);
}
else
{
if (c != d)
- usage();
+ usage(NULL);
goto next;
}
}
if (*c == '-')
{
if (!c[1] || !strchr("sd", c[1]))
- usage();
+ usage(NULL);
if (c[2])
d = (c[2] == '=') ? c+3 : c+2;
else if (argc > 1)
d = argv[0];
}
else
- usage();
+ usage(NULL);
if (state != STATE_GOT_FILTER)
{
pci_filter_init(pacc, &filter);
die("-d: %s", d);
break;
default:
- usage();
+ usage(NULL);
}
}
else if (state == STATE_INIT)
- usage();
+ usage(NULL);
else
{
if (state == STATE_GOT_FILTER)
{
*d++ = 0;
if (!*d)
- usage();
+ usage("Missing value");
for(e=d, n=1; *e; e++)
if (*e == ',')
n++;
{
*e++ = 0;
if (e[1])
- usage();
+ usage("Missing width");
switch (*e & 0xdf)
{
case 'B':
case 'L':
op->width = 4; break;
default:
- usage();
+ usage("Invalid width \"%c\"", *e);
}
}
else
for(r = pci_reg_names; r->name; r++)
if (!strcasecmp(r->name, c))
break;
- if (!r->name || e)
- usage();
+ if (!r->name)
+ usage("Unknown register \"%s\"", c);
+ if (e && op->width != r->width)
+ usage("Explicit width doesn't correspond with the named register \"%s\"", c);
ll = r->offset;
op->width = r->width;
}
- if (ll > 0x100 || ll + op->width*((n < 0) ? 1 : n) > 0x100)
+ if (ll > 0x1000 || ll + op->width*((n < 0) ? 1 : n) > 0x1000)
die("Register number out of range!");
if (ll & (op->width - 1))
die("Unaligned register address!");
*e++ = 0;
ll = strtoul(d, &f, 16);
lim = max_values[op->width];
- if (f && *f && (*f != ':') ||
- (ll > lim && ll < ~0UL - lim))
- {
- fprintf(stderr, "bad value \"%s\"\n\n", d);
- usage();
- }
+ if (f && *f && *f != ':')
+ usage("Invalid value \"%s\"", d);
+ if (ll > lim && ll < ~0UL - lim)
+ usage("Value \"%s\" is out of range", d);
+ op->values[i].value = ll;
if (f && *f == ':')
{
- op->values[i].value = ll;
d = ++f;
ll = strtoul(d, &f, 16);
- if (f && *f ||
- (ll > lim && ll < ~0UL - lim))
- {
- fprintf(stderr, "bad value:mask pair \"%s\"\n\n", d);
- usage();
- }
+ if (f && *f)
+ usage("Invalid mask \"%s\"", d);
+ if (ll > lim && ll < ~0UL - lim)
+ usage("Mask \"%s\" is out of range", d);
op->values[i].mask = ll;
- op->values[i].value &= op->values[i].mask;
+ op->values[i].value &= ll;
}
else
- {
- op->values[i].value = ll;
- op->values[i].mask = ~0U;
- }
+ op->values[i].mask = ~0U;
d = e;
}
*last_op = op;
argv++;
}
if (state == STATE_INIT)
- usage();
+ usage("No operation specified");
scan_ops(first_op);
execute(first_op);