pciaddr_t rom_base_addr; /* Expansion ROM base address */
pciaddr_t rom_size; /* Expansion ROM size */
struct pci_cap *first_cap; /* List of capabilities */
+ char *phy_slot; /* Physical slot */
/* Fields used internally: */
struct pci_access *access;
#define PCI_FILL_CLASS 32
#define PCI_FILL_CAPS 64
#define PCI_FILL_EXT_CAPS 128
+#define PCI_FILL_PHYS_SLOT 256
#define PCI_FILL_RESCAN 0x10000
void pci_setup_cache(struct pci_dev *, u8 *cache, int len) PCI_ABI;
closedir(dir);
}
+static void
+sysfs_fill_slots(struct pci_dev *d)
+{
+ struct pci_access *a = d->access;
+ char dirname[1024];
+ DIR *dir;
+ struct dirent *entry;
+ int n;
+
+ n = snprintf(dirname, sizeof(dirname), "%s/slots", sysfs_name(a));
+ if (n < 0 || n >= (int) sizeof(dirname))
+ a->error("Directory name too long");
+ dir = opendir(dirname);
+ if (!dir)
+ a->error("Cannot open %s", dirname);
+ while ((entry = readdir(dir)))
+ {
+ char namebuf[OBJNAMELEN], buf[16];
+ FILE *file;
+ unsigned int dom, bus, dev;
+ struct pci_dev *pd;
+ int n = snprintf(namebuf, OBJNAMELEN, "%s/%s/%s", dirname, entry->d_name, "address");
+
+ /* ".", ".." or a special non-device perhaps */
+ if (entry->d_name[0] == '.')
+ continue;
+
+ if (n < 0 || n >= OBJNAMELEN)
+ d->access->error("File name too long");
+ file = fopen(namebuf, "r");
+ if (!file)
+ a->error("Cannot open %s: %s", namebuf, strerror(errno));
+ if (!fgets(buf, sizeof(buf), file))
+ break;
+ if (sscanf(buf, "%x:%x:%x", &dom, &bus, &dev) < 3)
+ a->error("sysfs_scan: Couldn't parse entry address %s", buf);
+ for (pd = a->devices; pd; pd = pd->next)
+ {
+ if (dom == pd->domain && bus == pd->bus && dev == pd->dev && !pd->phy_slot)
+ {
+ pd->phy_slot = pci_malloc(a, strlen(entry->d_name) + 1);
+ sprintf(pd->phy_slot, "%s", entry->d_name);
+ }
+ pd->known_fields |= PCI_FILL_PHYS_SLOT;
+ }
+ fclose(file);
+ }
+ closedir(dir);
+}
+
+static int
+sysfs_fill_info(struct pci_dev *d, int flags)
+{
+ int ret;
+
+ ret = pci_generic_fill_info(d, flags);
+ if (flags & PCI_FILL_PHYS_SLOT && !(d->known_fields & PCI_FILL_PHYS_SLOT))
+ sysfs_fill_slots(d);
+
+ return ret;
+}
+
/* Intent of the sysfs_setup() caller */
enum
{
sysfs_init,
sysfs_cleanup,
sysfs_scan,
- pci_generic_fill_info,
+ sysfs_fill_info,
sysfs_read,
sysfs_write,
sysfs_read_vpd,
d->config_cached += 64;
}
pci_setup_cache(p, d->config, d->config_cached);
- pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES);
+ pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_PHYS_SLOT);
return d;
}
return;
}
+ if (p->phy_slot)
+ printf("\tPhysical Slot: %s\n", p->phy_slot);
+
if (verbose > 1)
{
printf("\tControl: I/O%c Mem%c BusMaster%c SpecCycle%c MemWINV%c VGASnoop%c ParErr%c Stepping%c SERR%c FastB2B%c DisINTx%c\n",
printf("SDevice:\t%s\n",
pci_lookup_name(pacc, sdbuf, sizeof(sdbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id, sv_id, sd_id));
}
+ if (p->phy_slot)
+ printf("PhySlot:\t%s\n", p->phy_slot);
if (c = get_conf_byte(d, PCI_REVISION_ID))
printf("Rev:\t%02x\n", c);
if (c = get_conf_byte(d, PCI_CLASS_PROG))