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

📄 lspci.c

📁 linux~{OBOTJ>KySP~}pci~{Ih18~}
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *	$Id: lspci.c,v 1.43 2002/12/26 20:24:50 mj Exp $ * *	Linux PCI Utilities -- List All PCI Devices * *	Copyright (c) 1997--2002 Martin Mares <mj@ucw.cz> * *	Can be freely distributed and used under the terms of the GNU GPL. */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include "pciutils.h"/* Options */static int verbose;			/* Show detailed information */static int buscentric_view;		/* Show bus addresses/IRQ's instead of CPU-visible ones */static int show_hex;			/* Show contents of config space as hexadecimal numbers */static struct pci_filter filter;	/* Device filter */static int show_tree;			/* Show bus tree */static int machine_readable;		/* Generate machine-readable output */static int map_mode;			/* Bus mapping mode enabled */static char options[] = "nvbxs:d:ti:mgM" GENERIC_OPTIONS ;static char help_msg[] = "\Usage: lspci [<switches>]\n\\n\-v\t\tBe verbose\n\-n\t\tShow numeric ID's\n\-b\t\tBus-centric view (PCI addresses and IRQ's instead of those seen by the CPU)\n\-x\t\tShow hex-dump of the standard portion of config space\n\-xxx\t\tShow hex-dump of the whole config space (dangerous; root only)\n\-s [[<bus>]:][<slot>][.[<func>]]\tShow only devices in selected slots\n\-d [<vendor>]:[<device>]\tShow only selected devices\n\-t\t\tShow bus tree\n\-m\t\tProduce machine-readable output\n\-i <file>\tUse specified ID database instead of %s\n\-M\t\tEnable `bus mapping' mode (dangerous; root only)\n"GENERIC_HELP;/* Communication with libpci */static struct pci_access *pacc;/* Format strings used for IRQ numbers and memory addresses */#ifdef ARCH_SPARC64#define IRQ_FORMAT "%08x"#else#define IRQ_FORMAT "%d"#endif#ifdef HAVE_64BIT_ADDRESS#ifdef HAVE_LONG_ADDRESS#define ADDR_FORMAT "%016Lx"#else#define ADDR_FORMAT "%016lx"#endif#else#define ADDR_FORMAT "%08lx"#endif#ifdef ARCH_SPARC64#define IO_FORMAT "%016Lx"#elif defined(HAVE_LONG_ADDRESS)#define IO_FORMAT "%04Lx"#else#define IO_FORMAT "%04lx"#endif/* *  If we aren't being compiled by GCC, use malloc() instead of alloca(). *  This increases our memory footprint, but only slightly since we don't *  use alloca() much. */#ifndef __GNUC__#define alloca malloc#endif/* Our view of the PCI bus */struct device {  struct device *next;  struct pci_dev *dev;  unsigned int config_cnt;  byte config[256];};static struct device *first_dev;static struct device *scan_device(struct pci_dev *p){  int how_much = (show_hex > 2) ? 256 : 64;  struct device *d;  if (!pci_filter_match(&filter, p))    return NULL;  d = xmalloc(sizeof(struct device));  bzero(d, sizeof(*d));  d->dev = p;  if (!pci_read_block(p, 0, d->config, how_much))    die("Unable to read %d bytes of configuration space.", how_much);  if (how_much < 128 && (d->config[PCI_HEADER_TYPE] & 0x7f) == PCI_HEADER_TYPE_CARDBUS)    {      /* For cardbus bridges, we need to fetch 64 bytes more to get the full standard header... */      if (!pci_read_block(p, 64, d->config+64, 64))	die("Unable to read cardbus bridge extension data.");      how_much = 128;    }  d->config_cnt = how_much;  pci_setup_cache(p, d->config, d->config_cnt);  pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES);  return d;}static voidscan_devices(void){  struct device *d;  struct pci_dev *p;  pci_scan_bus(pacc);  for(p=pacc->devices; p; p=p->next)    if (d = scan_device(p))      {	d->next = first_dev;	first_dev = d;      }}static intcheck_root(void){  static int is_root = -1;  if (is_root < 0)    is_root = !geteuid();  return is_root;}static intconfig_fetch(struct device *d, unsigned int pos, unsigned int len){  if (pos + len < d->config_cnt)    return 1;  if (pacc->method != PCI_ACCESS_DUMP && !check_root())    return 0;  return pci_read_block(d->dev, pos, d->config + pos, len);}/* Config space accesses */static inline byteget_conf_byte(struct device *d, unsigned int pos){  return d->config[pos];}static wordget_conf_word(struct device *d, unsigned int pos){  return d->config[pos] | (d->config[pos+1] << 8);}static u32get_conf_long(struct device *d, unsigned int pos){  return d->config[pos] |    (d->config[pos+1] << 8) |    (d->config[pos+2] << 16) |    (d->config[pos+3] << 24);}/* Sorting */static intcompare_them(const void *A, const void *B){  const struct pci_dev *a = (*(const struct device **)A)->dev;  const struct pci_dev *b = (*(const struct device **)B)->dev;  if (a->bus < b->bus)    return -1;  if (a->bus > b->bus)    return 1;  if (a->dev < b->dev)    return -1;  if (a->dev > b->dev)    return 1;  if (a->func < b->func)    return -1;  if (a->func > b->func)    return 1;  return 0;}static voidsort_them(void){  struct device **index, **h, **last_dev;  int cnt;  struct device *d;  cnt = 0;  for(d=first_dev; d; d=d->next)    cnt++;  h = index = alloca(sizeof(struct device *) * cnt);  for(d=first_dev; d; d=d->next)    *h++ = d;  qsort(index, cnt, sizeof(struct device *), compare_them);  last_dev = &first_dev;  h = index;  while (cnt--)    {      *last_dev = *h;      last_dev = &(*h)->next;      h++;    }  *last_dev = NULL;}/* Normal output */#define FLAG(x,y) ((x & y) ? '+' : '-')static voidshow_terse(struct device *d){  int c;  struct pci_dev *p = d->dev;  byte classbuf[128], devbuf[128];  printf("%02x:%02x.%x %s: %s",	 p->bus,	 p->dev,	 p->func,	 pci_lookup_name(pacc, classbuf, sizeof(classbuf),			 PCI_LOOKUP_CLASS,			 get_conf_word(d, PCI_CLASS_DEVICE), 0, 0, 0),	 pci_lookup_name(pacc, devbuf, sizeof(devbuf),			 PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,			 p->vendor_id, p->device_id, 0, 0));  if (c = get_conf_byte(d, PCI_REVISION_ID))    printf(" (rev %02x)", c);  if (verbose)    {      char *x;      c = get_conf_byte(d, PCI_CLASS_PROG);      x = pci_lookup_name(pacc, devbuf, sizeof(devbuf),			  PCI_LOOKUP_PROGIF,			  get_conf_word(d, PCI_CLASS_DEVICE), c, 0, 0);      if (c || x)	{	  printf(" (prog-if %02x", c);	  if (x)	    printf(" [%s]", x);	  putchar(')');	}    }  putchar('\n');}static voidshow_size(pciaddr_t x){  if (!x)    return;  printf(" [size=");  if (x < 1024)    printf("%d", (int) x);  else if (x < 1048576)    printf("%dK", (int)(x / 1024));  else if (x < 0x80000000)    printf("%dM", (int)(x / 1048576));  else    printf(ADDR_FORMAT, x);  putchar(']');}static voidshow_bases(struct device *d, int cnt){  struct pci_dev *p = d->dev;  word cmd = get_conf_word(d, PCI_COMMAND);  int i;  for(i=0; i<cnt; i++)    {      pciaddr_t pos = p->base_addr[i];      pciaddr_t len = (p->known_fields & PCI_FILL_SIZES) ? p->size[i] : 0;      u32 flg = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4*i);      if (flg == 0xffffffff)	flg = 0;      if (!pos && !flg && !len)	continue;      if (verbose > 1)	printf("\tRegion %d: ", i);      else	putchar('\t');      if (pos && !flg)			/* Reported by the OS, but not by the device */	{	  printf("[virtual] ");	  flg = pos;	}      if (flg & PCI_BASE_ADDRESS_SPACE_IO)	{	  pciaddr_t a = pos & PCI_BASE_ADDRESS_IO_MASK;	  printf("I/O ports at ");	  if (a)	    printf(IO_FORMAT, a);	  else if (flg & PCI_BASE_ADDRESS_IO_MASK)	    printf("<ignored>");	  else	    printf("<unassigned>");	  if (!(cmd & PCI_COMMAND_IO))	    printf(" [disabled]");	}      else	{	  int t = flg & PCI_BASE_ADDRESS_MEM_TYPE_MASK;	  pciaddr_t a = pos & PCI_ADDR_MEM_MASK;	  int done = 0;	  u32 z = 0;	  printf("Memory at ");	  if (t == PCI_BASE_ADDRESS_MEM_TYPE_64)	    {	      if (i >= cnt - 1)		{		  printf("<invalid-64bit-slot>");		  done = 1;		}	      else		{		  i++;		  z = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4*i);		  if (buscentric_view)		    {		      if (a || z)			printf("%08x" ADDR_FORMAT, z, a);		      else			printf("<unassigned>");		      done = 1;		    }		}	    }	  if (!done)	    {	      if (a)		printf(ADDR_FORMAT, a);	      else		printf(((flg & PCI_BASE_ADDRESS_MEM_MASK) || z) ? "<ignored>" : "<unassigned>");	    }	  printf(" (%s, %sprefetchable)",		 (t == PCI_BASE_ADDRESS_MEM_TYPE_32) ? "32-bit" :		 (t == PCI_BASE_ADDRESS_MEM_TYPE_64) ? "64-bit" :		 (t == PCI_BASE_ADDRESS_MEM_TYPE_1M) ? "low-1M" : "type 3",		 (flg & PCI_BASE_ADDRESS_MEM_PREFETCH) ? "" : "non-");	  if (!(cmd & PCI_COMMAND_MEMORY))	    printf(" [disabled]");	}      show_size(len);      putchar('\n');    }}static voidshow_pm(struct device *d, int where, int cap){  int t, b;  static int pm_aux_current[8] = { 0, 55, 100, 160, 220, 270, 320, 375 };  printf("Power Management version %d\n", cap & PCI_PM_CAP_VER_MASK);  if (verbose < 2)    return;  printf("\t\tFlags: PMEClk%c DSI%c D1%c D2%c AuxCurrent=%dmA PME(D0%c,D1%c,D2%c,D3hot%c,D3cold%c)\n",	 FLAG(cap, PCI_PM_CAP_PME_CLOCK),	 FLAG(cap, PCI_PM_CAP_DSI),	 FLAG(cap, PCI_PM_CAP_D1),	 FLAG(cap, PCI_PM_CAP_D2),	 pm_aux_current[(cap >> 6) & 7],	 FLAG(cap, PCI_PM_CAP_PME_D0),	 FLAG(cap, PCI_PM_CAP_PME_D1),	 FLAG(cap, PCI_PM_CAP_PME_D2),	 FLAG(cap, PCI_PM_CAP_PME_D3_HOT),	 FLAG(cap, PCI_PM_CAP_PME_D3_COLD));  config_fetch(d, where + PCI_PM_CTRL, PCI_PM_SIZEOF - PCI_PM_CTRL);  t = get_conf_word(d, where + PCI_PM_CTRL);  printf("\t\tStatus: D%d PME-Enable%c DSel=%d DScale=%d PME%c\n",	 t & PCI_PM_CTRL_STATE_MASK,	 FLAG(t, PCI_PM_CTRL_PME_ENABLE),	 (t & PCI_PM_CTRL_DATA_SEL_MASK) >> 9,	 (t & PCI_PM_CTRL_DATA_SCALE_MASK) >> 13,	 FLAG(t, PCI_PM_CTRL_PME_STATUS));  b = get_conf_byte(d, where + PCI_PM_PPB_EXTENSIONS);  if (b)    printf("\t\tBridge: PM%c B3%c\n",	   FLAG(t, PCI_PM_BPCC_ENABLE),	   FLAG(~t, PCI_PM_PPB_B2_B3));}static voidformat_agp_rate(int rate, char *buf, int agp3){  char *c = buf;  int i;  for(i=0; i<=2; i++)    if (rate & (1 << i))      {	if (c != buf)	  *c++ = ',';	*c++ = 'x';	*c++ = '0' + (1 << (i + 2*agp3));      }  if (c != buf)    *c = 0;  else    strcpy(buf, "<none>");}static voidshow_agp(struct device *d, int where, int cap){  u32 t;  char rate[8];  int ver, rev;  int agp3 = 0;  ver = (cap >> 4) & 0x0f;  rev = cap & 0x0f;  printf("AGP version %x.%x\n", ver, rev);  if (verbose < 2)    return;  config_fetch(d, where + PCI_AGP_STATUS, PCI_AGP_SIZEOF - PCI_AGP_STATUS);  t = get_conf_long(d, where + PCI_AGP_STATUS);  if (ver >= 3 && (t & PCI_AGP_STATUS_AGP3))    agp3 = 1;  format_agp_rate(t & 7, rate, agp3);  printf("\t\tStatus: RQ=%d Iso%c ArqSz=%d Cal=%d SBA%c ITACoh%c GART64%c HTrans%c 64bit%c FW%c AGP3%c Rate=%s\n",	 ((t & PCI_AGP_STATUS_RQ_MASK) >> 24U) + 1,	 FLAG(t, PCI_AGP_STATUS_ISOCH),	 ((t & PCI_AGP_STATUS_ARQSZ_MASK) >> 13),	 ((t & PCI_AGP_STATUS_CAL_MASK) >> 10),	 FLAG(t, PCI_AGP_STATUS_SBA),	 FLAG(t, PCI_AGP_STATUS_ITA_COH),	 FLAG(t, PCI_AGP_STATUS_GART64),	 FLAG(t, PCI_AGP_STATUS_HTRANS),	 FLAG(t, PCI_AGP_STATUS_64BIT),	 FLAG(t, PCI_AGP_STATUS_FW),	 FLAG(t, PCI_AGP_STATUS_AGP3),	 rate);  t = get_conf_long(d, where + PCI_AGP_COMMAND);  format_agp_rate(t & 7, rate, agp3);  printf("\t\tCommand: RQ=%d ArqSz=%d Cal=%d SBA%c AGP%c GART64%c 64bit%c FW%c Rate=%s\n",	 ((t & PCI_AGP_COMMAND_RQ_MASK) >> 24U) + 1,	 ((t & PCI_AGP_COMMAND_ARQSZ_MASK) >> 13),	 ((t & PCI_AGP_COMMAND_CAL_MASK) >> 10),	 FLAG(t, PCI_AGP_COMMAND_SBA),	 FLAG(t, PCI_AGP_COMMAND_AGP),	 FLAG(t, PCI_AGP_COMMAND_GART64),	 FLAG(t, PCI_AGP_COMMAND_64BIT),	 FLAG(t, PCI_AGP_COMMAND_FW),	 rate);}static voidshow_pcix_nobridge(struct device *d, int where){  u16 command = get_conf_word(d, where + PCI_PCIX_COMMAND);  u32 status = get_conf_long(d, where + PCI_PCIX_STATUS);  printf("PCI-X non-bridge device.\n");  if (verbose < 2)    return;  printf("\t\tCommand: DPERE%c ERO%c RBC=%d OST=%d\n",	 FLAG(command, PCI_PCIX_COMMAND_DPERE),	 FLAG(command, PCI_PCIX_COMMAND_ERO),	 ((command & PCI_PCIX_COMMAND_MAX_MEM_READ_BYTE_COUNT) >> 2U),	 ((command & PCI_PCIX_COMMAND_MAX_OUTSTANDING_SPLIT_TRANS) >> 4U));  printf("\t\tStatus: Bus=%u Dev=%u Func=%u 64bit%c 133MHz%c SCD%c USC%c, DC=%s, DMMRBC=%u, DMOST=%u, DMCRS=%u, RSCEM%c",	 ((status >> 8) & 0xffU), // bus	 ((status >> 3) & 0x1fU), // dev	 (status & PCI_PCIX_BRIDGE_STATUS_FUNCTION), // function	 FLAG(status, PCI_PCIX_STATUS_64BIT),	 FLAG(status, PCI_PCIX_STATUS_133MHZ),	 FLAG(status, PCI_PCIX_STATUS_SC_DISCARDED),	 FLAG(status, PCI_PCIX_STATUS_UNEXPECTED_SC),	 ((status & PCI_PCIX_STATUS_DEVICE_COMPLEXITY) ? "bridge" : "simple"),	 ((status >> 21) & 3U),	 ((status >> 23) & 7U),	 ((status >> 26) & 7U),	 FLAG(status, PCI_PCIX_STATUS_RCVD_SC_ERR_MESS));}static voidshow_pcix_bridge(struct device *d, int where){  u16 secstatus;  u32 status, upstcr, downstcr;  printf("PCI-X bridge device.\n");  if (verbose < 2)    return;  secstatus = get_conf_word(d, where + PCI_PCIX_BRIDGE_SEC_STATUS);  printf("\t\tSecondary Status: 64bit%c, 133MHz%c, SCD%c, USC%c, SCO%c, SRD%c Freq=%d\n",	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_64BIT),	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_133MHZ),	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SC_DISCARDED),	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_UNEXPECTED_SC),	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SC_OVERRUN),	 FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SPLIT_REQUEST_DELAYED),	 ((secstatus >> 6) & 7));  status = get_conf_long(d, where + PCI_PCIX_BRIDGE_STATUS);  printf("\t\tStatus: Bus=%u Dev=%u Func=%u 64bit%c 133MHz%c SCD%c USC%c, SCO%c, SRD%c\n", 	 ((status >> 8) & 0xff), // bus

⌨️ 快捷键说明

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