⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setpci.c

📁 linux下的pci设备浏览工具
💻 C
📖 第 1 页 / 共 2 页
字号:
  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 + -