X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=setpci.c;h=3ebbaeedeaed127bcb78fdd22bb1a81e726db000;hb=daf2ef4e78d6559bd7a3242113b082134b9f2ea7;hp=a3415073e459375cc0e00dff5d6d7086f14354b6;hpb=b7351143a18cdcc60f1a1b3efef94864b0f61e9c;p=pciutils.git diff --git a/setpci.c b/setpci.c index a341507..3ebbaee 100644 --- a/setpci.c +++ b/setpci.c @@ -1,7 +1,7 @@ /* - * Linux PCI Utilities -- Manipulate PCI Configuration Registers + * The PCI Utilities -- Manipulate PCI Configuration Registers * - * Copyright (c) 1998--2003 Martin Mares + * Copyright (c) 1998--2008 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -12,12 +12,15 @@ #include #include +#define PCIUTILS_SETPCI #include "pciutils.h" static int force; /* Don't complain if no devices match */ static int verbose; /* Verbosity level */ static int demo_mode; /* Only show */ +const char program_name[] = "setpci"; + static struct pci_access *pacc; struct value { @@ -124,24 +127,19 @@ exec_op(struct op *op, struct pci_dev *dev) { 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'); } } @@ -176,8 +174,8 @@ scan_ops(struct op *op) } struct reg_name { - int offset; - int width; + unsigned int offset; + unsigned int width; const char *name; }; @@ -249,18 +247,30 @@ static const struct reg_name pci_reg_names[] = { { 0x00, 0, NULL } }; -static void usage(void) __attribute__((noreturn)); - -static void -usage(void) +static void NONRET PCI_PRINTF(1,2) +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 [] (+ [=]*)*\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" +"Usage: setpci [] (+ [=]*)*\n" +"\n" +"General options:\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" +"\n" +"PCI access options:\n" GENERIC_HELP -":\t-s [[]:][][.[]]\n" +"\n" +"Setting commands:\n" +":\t-s [[[]:][]:][][.[]]\n" "\t|\t-d []:[]\n" ":\t\t[.(B|W|L)]\n" " |\t\t\n" @@ -326,18 +336,18 @@ main(int argc, char **argv) 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; } } @@ -361,7 +371,7 @@ 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) @@ -371,7 +381,7 @@ next: d = argv[0]; } else - usage(); + usage(NULL); if (state != STATE_GOT_FILTER) { pci_filter_init(pacc, &filter); @@ -388,11 +398,11 @@ next: die("-d: %s", d); break; default: - usage(); + usage(NULL); } } else if (state == STATE_INIT) - usage(); + usage(NULL); else { if (state == STATE_GOT_FILTER) @@ -406,7 +416,7 @@ next: { *d++ = 0; if (!*d) - usage(); + usage("Missing value"); for(e=d, n=1; *e; e++) if (*e == ',') n++; @@ -424,7 +434,7 @@ next: { *e++ = 0; if (e[1]) - usage(); + usage("Missing width"); switch (*e & 0xdf) { case 'B': @@ -434,7 +444,7 @@ next: case 'L': op->width = 4; break; default: - usage(); + usage("Invalid width \"%c\"", *e); } } else @@ -446,12 +456,14 @@ next: 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!"); @@ -464,31 +476,24 @@ next: *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; @@ -499,7 +504,7 @@ next: argv++; } if (state == STATE_INIT) - usage(); + usage("No operation specified"); scan_ops(first_op); execute(first_op);