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

📄 lspci.c

📁 linux~{OBOTJ>KySP~}pci~{Ih18~}
💻 C
📖 第 1 页 / 共 3 页
字号:
	printf(" \"\" \"\"");      putchar('\n');    }}static voidshow_device(struct device *d){  if (machine_readable)    show_machine(d);  else if (verbose)    show_verbose(d);  else    show_terse(d);  if (show_hex)    show_hex_dump(d);  if (verbose || show_hex)    putchar('\n');}static voidshow(void){  struct device *d;  for(d=first_dev; d; d=d->next)    show_device(d);}/* Tree output */struct bridge {  struct bridge *chain;			/* Single-linked list of bridges */  struct bridge *next, *child;		/* Tree of bridges */  struct bus *first_bus;		/* List of busses connected to this bridge */  unsigned int primary, secondary, subordinate;	/* Bus numbers */  struct device *br_dev;};struct bus {  unsigned int number;  struct bus *sibling;  struct device *first_dev, **last_dev;};static struct bridge host_bridge = { NULL, NULL, NULL, NULL, ~0, 0, ~0, NULL };static struct bus *find_bus(struct bridge *b, unsigned int n){  struct bus *bus;  for(bus=b->first_bus; bus; bus=bus->sibling)    if (bus->number == n)      break;  return bus;}static struct bus *new_bus(struct bridge *b, unsigned int n){  struct bus *bus = xmalloc(sizeof(struct bus));  bus = xmalloc(sizeof(struct bus));  bus->number = n;  bus->sibling = b->first_bus;  bus->first_dev = NULL;  bus->last_dev = &bus->first_dev;  b->first_bus = bus;  return bus;}static voidinsert_dev(struct device *d, struct bridge *b){  struct pci_dev *p = d->dev;  struct bus *bus;  if (! (bus = find_bus(b, p->bus)))    {      struct bridge *c;      for(c=b->child; c; c=c->next)	if (c->secondary <= p->bus && p->bus <= c->subordinate)          {            insert_dev(d, c);            return;          }      bus = new_bus(b, p->bus);    }  /* Simple insertion at the end _does_ guarantee the correct order as the   * original device list was sorted by (bus, devfn) lexicographically   * and all devices on the new list have the same bus number.   */  *bus->last_dev = d;  bus->last_dev = &d->next;  d->next = NULL;}static voidgrow_tree(void){  struct device *d, *d2;  struct bridge **last_br, *b;  /* Build list of bridges */  last_br = &host_bridge.chain;  for(d=first_dev; d; d=d->next)    {      word class = get_conf_word(d, PCI_CLASS_DEVICE);      byte ht = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f;      if (class == PCI_CLASS_BRIDGE_PCI &&	  (ht == PCI_HEADER_TYPE_BRIDGE || ht == PCI_HEADER_TYPE_CARDBUS))	{	  b = xmalloc(sizeof(struct bridge));	  if (ht == PCI_HEADER_TYPE_BRIDGE)	    {	      b->primary = get_conf_byte(d, PCI_CB_PRIMARY_BUS);	      b->secondary = get_conf_byte(d, PCI_CB_CARD_BUS);	      b->subordinate = get_conf_byte(d, PCI_CB_SUBORDINATE_BUS);	    }	  else	    {	      b->primary = get_conf_byte(d, PCI_PRIMARY_BUS);	      b->secondary = get_conf_byte(d, PCI_SECONDARY_BUS);	      b->subordinate = get_conf_byte(d, PCI_SUBORDINATE_BUS);	    }	  *last_br = b;	  last_br = &b->chain;	  b->next = b->child = NULL;	  b->first_bus = NULL;	  b->br_dev = d;	}    }  *last_br = NULL;  /* Create a bridge tree */  for(b=&host_bridge; b; b=b->chain)    {      struct bridge *c, *best;      best = NULL;      for(c=&host_bridge; c; c=c->chain)	if (c != b && b->primary >= c->secondary && b->primary <= c->subordinate &&	    (!best || best->subordinate - best->primary > c->subordinate - c->primary))	  best = c;      if (best)	{	  b->next = best->child;	  best->child = b;	}    }  /* Insert secondary bus for each bridge */  for(b=&host_bridge; b; b=b->chain)    if (!find_bus(b, b->secondary))      new_bus(b, b->secondary);  /* Create bus structs and link devices */  for(d=first_dev; d;)    {      d2 = d->next;      insert_dev(d, &host_bridge);      d = d2;    }}static voidprint_it(byte *line, byte *p){  *p++ = '\n';  *p = 0;  fputs(line, stdout);  for(p=line; *p; p++)    if (*p == '+' || *p == '|')      *p = '|';    else      *p = ' ';}static void show_tree_bridge(struct bridge *, byte *, byte *);static voidshow_tree_dev(struct device *d, byte *line, byte *p){  struct pci_dev *q = d->dev;  struct bridge *b;  char namebuf[256];  p += sprintf(p, "%02x.%x", q->dev, q->func);  for(b=&host_bridge; b; b=b->chain)    if (b->br_dev == d)      {	if (b->secondary == b->subordinate)	  p += sprintf(p, "-[%02x]-", b->secondary);	else	  p += sprintf(p, "-[%02x-%02x]-", b->secondary, b->subordinate);        show_tree_bridge(b, line, p);        return;      }  if (verbose)    p += sprintf(p, "  %s",		 pci_lookup_name(pacc, namebuf, sizeof(namebuf),				 PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,				 q->vendor_id, q->device_id, 0, 0));  print_it(line, p);}static voidshow_tree_bus(struct bus *b, byte *line, byte *p){  if (!b->first_dev)    print_it(line, p);  else if (!b->first_dev->next)    {      *p++ = '-';      *p++ = '-';      show_tree_dev(b->first_dev, line, p);    }  else    {      struct device *d = b->first_dev;      while (d->next)	{	  p[0] = '+';	  p[1] = '-';	  show_tree_dev(d, line, p+2);	  d = d->next;	}      p[0] = '\\';      p[1] = '-';      show_tree_dev(d, line, p+2);    }}static voidshow_tree_bridge(struct bridge *b, byte *line, byte *p){  *p++ = '-';  if (!b->first_bus->sibling)    {      if (b == &host_bridge)        p += sprintf(p, "[%02x]-", b->first_bus->number);      show_tree_bus(b->first_bus, line, p);    }  else    {      struct bus *u = b->first_bus;      byte *k;      while (u->sibling)        {          k = p + sprintf(p, "+-[%02x]-", u->number);          show_tree_bus(u, line, k);          u = u->sibling;        }      k = p + sprintf(p, "\\-[%02x]-", u->number);      show_tree_bus(u, line, k);    }}static voidshow_forest(void){  char line[256];  grow_tree();  show_tree_bridge(&host_bridge, line, line);}/* Bus mapping mode */struct bus_bridge {  struct bus_bridge *next;  byte this, dev, func, first, last, bug;};struct bus_info {  byte exists;  byte guestbook;  struct bus_bridge *bridges, *via;};static struct bus_info *bus_info;static voidmap_bridge(struct bus_info *bi, struct device *d, int np, int ns, int nl){  struct bus_bridge *b = xmalloc(sizeof(struct bus_bridge));  struct pci_dev *p = d->dev;  b->next = bi->bridges;  bi->bridges = b;  b->this = get_conf_byte(d, np);  b->dev = p->dev;  b->func = p->func;  b->first = get_conf_byte(d, ns);  b->last = get_conf_byte(d, nl);  printf("## %02x.%02x:%d is a bridge from %02x to %02x-%02x\n",	 p->bus, p->dev, p->func, b->this, b->first, b->last);  if (b->this != p->bus)    printf("!!! Bridge points to invalid primary bus.\n");  if (b->first > b->last)    {      printf("!!! Bridge points to invalid bus range.\n");      b->last = b->first;    }}static voiddo_map_bus(int bus){  int dev, func;  int verbose = pacc->debugging;  struct bus_info *bi = bus_info + bus;  struct device *d;  if (verbose)    printf("Mapping bus %02x\n", bus);  for(dev = 0; dev < 32; dev++)    if (filter.slot < 0 || filter.slot == dev)      {	int func_limit = 1;	for(func = 0; func < func_limit; func++)	  if (filter.func < 0 || filter.func == func)	    {	      struct pci_dev *p = pci_get_dev(pacc, bus, dev, func);	      u16 vendor = pci_read_word(p, PCI_VENDOR_ID);	      if (vendor && vendor != 0xffff)		{		  if (!func && (pci_read_byte(p, PCI_HEADER_TYPE) & 0x80))		    func_limit = 8;		  if (verbose)		    printf("Discovered device %02x:%02x.%d\n", bus, dev, func);		  bi->exists = 1;		  if (d = scan_device(p))		    {		      show_device(d);		      switch (get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f)			{			case PCI_HEADER_TYPE_BRIDGE:			  map_bridge(bi, d, PCI_PRIMARY_BUS, PCI_SECONDARY_BUS, PCI_SUBORDINATE_BUS);			  break;			case PCI_HEADER_TYPE_CARDBUS:			  map_bridge(bi, d, PCI_CB_PRIMARY_BUS, PCI_CB_CARD_BUS, PCI_CB_SUBORDINATE_BUS);			  break;			}		      free(d);		    }		  else if (verbose)		    printf("But it was filtered out.\n");		}	      pci_free_dev(p);	    }      }}static voiddo_map_bridges(int bus, int min, int max){  struct bus_info *bi = bus_info + bus;  struct bus_bridge *b;  bi->guestbook = 1;  for(b=bi->bridges; b; b=b->next)    {      if (bus_info[b->first].guestbook)	b->bug = 1;      else if (b->first < min || b->last > max)	b->bug = 2;      else	{	  bus_info[b->first].via = b;	  do_map_bridges(b->first, b->first, b->last);	}    }}static voidmap_bridges(void){  int i;  printf("\nSummary of buses:\n\n");  for(i=0; i<256; i++)    if (bus_info[i].exists && !bus_info[i].guestbook)      do_map_bridges(i, 0, 255);  for(i=0; i<256; i++)    {      struct bus_info *bi = bus_info + i;      struct bus_bridge *b = bi->via;      if (bi->exists)	{	  printf("%02x: ", i);	  if (b)	    printf("Entered via %02x:%02x.%d\n", b->this, b->dev, b->func);	  else if (!i)	    printf("Primary host bus\n");	  else	    printf("Secondary host bus (?)\n");	}      for(b=bi->bridges; b; b=b->next)	{	  printf("\t%02x.%d Bridge to %02x-%02x", b->dev, b->func, b->first, b->last);	  switch (b->bug)	    {	    case 1:	      printf(" <overlap bug>");	      break;	    case 2:	      printf(" <crossing bug>");	      break;	    }	  putchar('\n');	}    }}static voidmap_the_bus(void){  if (pacc->method == PCI_ACCESS_PROC_BUS_PCI ||      pacc->method == PCI_ACCESS_DUMP)    printf("WARNING: Bus mapping can be reliable only with direct hardware access enabled.\n\n");  else if (!check_root())    die("Only root can map the bus.");  bus_info = xmalloc(sizeof(struct bus_info) * 256);  bzero(bus_info, sizeof(struct bus_info) * 256);  if (filter.bus >= 0)    do_map_bus(filter.bus);  else    {      int bus;      for(bus=0; bus<256; bus++)	do_map_bus(bus);    }  map_bridges();}/* Main */intmain(int argc, char **argv){  int i;  char *msg;  if (argc == 2 && !strcmp(argv[1], "--version"))    {      puts("lspci version " PCIUTILS_VERSION);      return 0;    }  pacc = pci_alloc();  pacc->error = die;  pci_filter_init(pacc, &filter);  while ((i = getopt(argc, argv, options)) != -1)    switch (i)      {      case 'n':	pacc->numeric_ids = 1;	break;      case 'v':	verbose++;	break;      case 'b':	pacc->buscentric = 1;	buscentric_view = 1;	break;      case 's':	if (msg = pci_filter_parse_slot(&filter, optarg))	  die("-f: %s", msg);	break;      case 'd':	if (msg = pci_filter_parse_id(&filter, optarg))	  die("-d: %s", msg);	break;      case 'x':	show_hex++;	break;      case 't':	show_tree++;	break;      case 'i':	pacc->id_file_name = optarg;	break;      case 'm':	machine_readable++;	break;      case 'M':	map_mode++;	break;      default:	if (parse_generic_option(i, pacc, optarg))	  break;      bad:	fprintf(stderr, help_msg, pacc->id_file_name);	return 1;      }  if (optind < argc)    goto bad;  pci_init(pacc);  if (map_mode)    map_the_bus();  else    {      scan_devices();      sort_them();      if (show_tree)	show_forest();      else	show();    }  pci_cleanup(pacc);  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -