📄 setpci.c
字号:
va_list args; va_start(args, msg); fprintf(stderr, "setpci: "); vfprintf(stderr, msg, args); fprintf(stderr, ".\nTry `setpci --help' for more information.\n"); exit(1);}static intparse_options(int argc, char **argv){ const char opts[] = GENERIC_OPTIONS; int i=1; if (argc == 2) { if (!strcmp(argv[1], "--help")) usage(); if (!strcmp(argv[1], "--version")) { puts("setpci version " PCIUTILS_VERSION); exit(0); } if (!strcmp(argv[1], "--dumpregs")) { dump_registers(); exit(0); } } while (i < argc && argv[i][0] == '-') { char *c = argv[i++] + 1; char *d = c; char *e; while (*c) switch (*c) { case 0: break; case 'v': verbose++; c++; break; case 'f': force++; c++; break; case 'D': demo_mode++; c++; break; default: if (e = strchr(opts, *c)) { char *arg; c++; if (e[1] == ':') { if (*c) arg = c; else if (i < argc) arg = argv[i++]; else parse_err("Option -%c requires an argument", *e); c = ""; } else arg = NULL; if (!parse_generic_option(*e, pacc, arg)) parse_err("Unable to parse option -%c", *e); } else { if (c != d) parse_err("Invalid or misplaced option -%c", *c); return i-1; } } } return i;}static int parse_filter(int argc, char **argv, int i, struct pci_filter *filter){ char *c = argv[i++]; char *d; if (!c[1] || !strchr("sd", c[1])) parse_err("Invalid option -%c", c[1]); if (c[2]) d = (c[2] == '=') ? c+3 : c+2; else if (i < argc) d = argv[i++]; else parse_err("Option -%c requires an argument", c[1]); switch (c[1]) { case 's': if (d = pci_filter_parse_slot(filter, d)) parse_err("Unable to parse filter -s %s", d); break; case 'd': if (d = pci_filter_parse_id(filter, d)) parse_err("Unable to parse filter -d %s", d); break; default: parse_err("Unknown filter option -%c", c[1]); } return i;}static const struct reg_name *parse_reg_name(char *name){ const struct reg_name *r; for (r = pci_reg_names; r->name; r++) if (!strcasecmp(r->name, name)) return r; return NULL;}static int parse_x32(char *c, char **stopp, unsigned int *resp){ char *stop; if (!*c) return -1; errno = 0; unsigned long int l = strtoul(c, &stop, 16); if (errno) return -1; if ((l & ~0U) != l) return -1; *resp = l; if (*stop) { if (stopp) *stopp = stop; return 0; } else { if (stopp) *stopp = NULL; return 1; }}static void parse_register(struct op *op, char *base){ const struct reg_name *r; unsigned int cap; op->cap_type = op->cap_id = 0; if (parse_x32(base, NULL, &op->addr) > 0) return; else if (r = parse_reg_name(base)) { switch (r->cap & 0xff0000) { case 0x10000: op->cap_type = PCI_CAP_NORMAL; break; case 0x20000: op->cap_type = PCI_CAP_EXTENDED; break; } op->cap_id = r->cap & 0xffff; op->addr = r->offset; if (r->width && !op->width) op->width = r->width; return; } else if (!strncasecmp(base, "CAP", 3)) { if (parse_x32(base+3, NULL, &cap) > 0 && cap < 0x100) { op->cap_type = PCI_CAP_NORMAL; op->cap_id = cap; op->addr = 0; return; } } else if (!strncasecmp(base, "ECAP", 4)) { if (parse_x32(base+4, NULL, &cap) > 0 && cap < 0x1000) { op->cap_type = PCI_CAP_EXTENDED; op->cap_id = cap; op->addr = 0; return; } } parse_err("Unknown register \"%s\"", base);}static void parse_op(char *c, struct pci_dev **selected_devices){ char *base, *offset, *width, *value; char *e, *f; int n, j; struct op *op; /* Split the argument */ base = xstrdup(c); if (value = strchr(base, '=')) *value++ = 0; if (width = strchr(base, '.')) *width++ = 0; if (offset = strchr(base, '+')) *offset++ = 0; /* Look for setting of values and count how many */ n = 0; if (value) { if (!*value) parse_err("Missing value"); n++; for (e=value; *e; e++) if (*e == ',') n++; } /* Allocate the operation */ op = xmalloc(sizeof(struct op) + n*sizeof(struct value)); op->dev_vector = selected_devices; op->num_values = n; /* What is the width suffix? */ if (width) { if (width[1]) parse_err("Invalid width \"%s\"", width); switch (*width & 0xdf) { case 'B': op->width = 1; break; case 'W': op->width = 2; break; case 'L': op->width = 4; break; default: parse_err("Invalid width \"%c\"", *width); } } else op->width = 0; /* Find the register */ parse_register(op, base); if (!op->width) parse_err("Missing width"); /* Add offset */ if (offset) { unsigned int off; if (parse_x32(offset, NULL, &off) <= 0 || off >= 0x1000) parse_err("Invalid offset \"%s\"", offset); op->addr += off; } /* Check range */ if (op->addr >= 0x1000 || op->addr + op->width*(n ? n : 1) > 0x1000) parse_err("Register number %02x out of range", op->addr); if (op->addr & (op->width - 1)) parse_err("Unaligned register address %02x", op->addr); /* Parse the values */ for (j=0; j<n; j++) { unsigned int ll, lim; e = strchr(value, ','); if (e) *e++ = 0; if (parse_x32(value, &f, &ll) < 0 || f && *f != ':') parse_err("Invalid value \"%s\"", value); lim = max_values[op->width]; if (ll > lim && ll < ~0UL - lim) parse_err("Value \"%s\" is out of range", value); op->values[j].value = ll; if (f && *f == ':') { if (parse_x32(f+1, NULL, &ll) <= 0) parse_err("Invalid mask \"%s\"", f+1); if (ll > lim && ll < ~0UL - lim) parse_err("Mask \"%s\" is out of range", f+1); op->values[j].mask = ll; op->values[j].value &= ll; } else op->values[j].mask = ~0U; value = e; } *last_op = op; last_op = &op->next; op->next = NULL;}static void parse_ops(int argc, char **argv, int i){ enum { STATE_INIT, STATE_GOT_FILTER, STATE_GOT_OP } state = STATE_INIT; struct pci_filter filter; struct pci_dev **selected_devices = NULL; while (i < argc) { char *c = argv[i++]; if (*c == '-') { if (state != STATE_GOT_FILTER) pci_filter_init(pacc, &filter); i = parse_filter(argc, argv, i-1, &filter); state = STATE_GOT_FILTER; } else { if (state == STATE_INIT) parse_err("Filter specification expected"); if (state == STATE_GOT_FILTER) selected_devices = select_devices(&filter); if (!selected_devices[0] && !force) fprintf(stderr, "setpci: Warning: No devices selected for \"%s\".\n", c); parse_op(c, selected_devices); state = STATE_GOT_OP; } } if (state == STATE_INIT) parse_err("No operation specified");}intmain(int argc, char **argv){ int i; pacc = pci_alloc(); pacc->error = die; i = parse_options(argc, argv); pci_init(pacc); pci_scan_bus(pacc); parse_ops(argc, argv, i); scan_ops(first_op); execute(first_op); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -