Back to index

lshw  02.16
Functions
pci.h File Reference
#include "hw.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

bool scan_pci (hwNode &n)
bool scan_pci_legacy (hwNode &n)

Function Documentation

bool scan_pci ( hwNode n)

Definition at line 1083 of file pci.cc.

{
  bool result = false;
  dirent **devices = NULL;
  int count = 0;
  hwNode *core = n.getChild("core");

  if (!core)
  {
    n.addChild(hwNode("core", hw::bus));
    core = n.getChild("core");
  }

  pcidb_loaded = load_pcidb();

  if(!pushd(SYS_BUS_PCI"/devices"))
    return false;
  count = scandir(".", &devices, selectlink, alphasort);
  if(count>=0)
  {
    int i = 0;
    for(i=0; i<count; i++)
    if(matches(devices[i]->d_name, "^[[:xdigit:]]+:[[:xdigit:]]+:[[:xdigit:]]+\\.[[:xdigit:]]+$"))
    {
      string devicepath = string(devices[i]->d_name)+"/config";
      struct pci_dev d;
      int fd = open(devicepath.c_str(), O_RDONLY);
      if (fd >= 0)
      {
        memset(&d, 0, sizeof(d));
        if(read(fd, d.config, 64) == 64)
        {
          if(read(fd, d.config+64, sizeof(d.config)-64) != sizeof(d.config)-64)
            memset(d.config+64, 0, sizeof(d.config)-64);
        }
        close(fd);
      }

      sscanf(devices[i]->d_name, "%hx:%hx:%hhx.%hhx", &d.domain, &d.bus, &d.dev, &d.func);
      hwNode *device = scan_pci_dev(d, n);

      if(device)
      {
        string resourcename = string(devices[i]->d_name)+"/resource";

        device->setBusInfo(devices[i]->d_name);
        if(exists(string(devices[i]->d_name)+"/driver"))
        {
          string drivername = readlink(string(devices[i]->d_name)+"/driver");
          string modulename = readlink(string(devices[i]->d_name)+"/driver/module");

          device->setConfig("driver", basename(drivername.c_str()));
          if(exists(modulename))
            device->setConfig("module", basename(modulename.c_str()));

          if(exists(string(devices[i]->d_name)+"/rom"))
          {
            device->addCapability("rom", "extension ROM");
          }

          if(exists(string(devices[i]->d_name)+"/irq"))
          {
            long irq = get_number(string(devices[i]->d_name)+"/irq", -1);
            if(irq>=0)
              device->addResource(hw::resource::irq(irq));
          }
          device->claim();
        }

        if(exists(resourcename))
        {
            FILE*resource = fopen(resourcename.c_str(), "r");

            if(resource)
            {
              while(!feof(resource))
              {
                unsigned long long start, end, flags;

                start = end = flags = 0;

                if(fscanf(resource, "%llx %llx %llx", &start, &end, &flags) != 3)
                  break;

                if(flags & 0x101)
                  device->addResource(hw::resource::ioport(start, end));
                else
                if(flags & 0x100)
                  device->addResource(hw::resource::iomem(start, end));
                else
                if(flags & 0x200)
                  device->addResource(hw::resource::mem(start, end, flags & 0x1000));
              }
              fclose(resource);
            }
        }

        result = true;
      }

      free(devices[i]);
    }

    free(devices);
  }
  popd();
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool scan_pci_legacy ( hwNode n)

Definition at line 999 of file pci.cc.

{
  FILE *f;
  hwNode *core = n.getChild("core");
  if (!core)
  {
    n.addChild(hwNode("core", hw::bus));
    core = n.getChild("core");
  }

  if(!pcidb_loaded)
    pcidb_loaded = load_pcidb();

  f = fopen(PROC_BUS_PCI "/devices", "r");
  if (f)
  {
    char buf[512];

    while (fgets(buf, sizeof(buf) - 1, f))
    {
      unsigned int dfn, vend, cnt;
      struct pci_dev d;
      int fd = -1;
      string devicepath = "";
      char devicename[20];
      char businfo[20];
      char driver[50];
      hwNode *device = NULL;

      memset(&d, 0, sizeof(d));
      memset(driver, 0, sizeof(driver));
      cnt = sscanf(buf,
        "%x %x %x %llx %llx %llx %llx %llx %llx %llx %llx %llx %llx %llx %llx %llx %llx %[ -z]s",
        &dfn,
        &vend,
        &d.irq,
        &d.base_addr[0],
        &d.base_addr[1],
        &d.base_addr[2],
        &d.base_addr[3],
        &d.base_addr[4],
        &d.base_addr[5],
        &d.rom_base_addr,
        &d.size[0],
        &d.size[1],
        &d.size[2],
        &d.size[3], &d.size[4], &d.size[5], &d.rom_size, driver);

      if (cnt != 9 && cnt != 10 && cnt != 17 && cnt != 18)
        break;

      d.bus = dfn >> 8;
      d.dev = PCI_SLOT(dfn & 0xff);
      d.func = PCI_FUNC(dfn & 0xff);
      d.vendor_id = vend >> 16;
      d.device_id = vend & 0xffff;

      snprintf(devicename, sizeof(devicename), "%02x/%02x.%x", d.bus, d.dev,
        d.func);
      devicepath = string(PROC_BUS_PCI) + "/" + string(devicename);
      snprintf(businfo, sizeof(businfo), "%02x:%02x.%x", d.bus, d.dev,
        d.func);

      fd = open(devicepath.c_str(), O_RDONLY);
      if (fd >= 0)
      {
        if(read(fd, d.config, sizeof(d.config)) != sizeof(d.config))
          memset(&d.config, 0, sizeof(d.config));
        close(fd);
      }

      device = scan_pci_dev(d, n);
      if(device)
      {
        device->setBusInfo(businfo);
      }

    }
    fclose(f);
  }

  return false;
}

Here is the call graph for this function:

Here is the caller graph for this function: