From 061a011ceffc13db3b147dd105d8b7c2edcc3bc8 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 27 Mar 2007 07:56:16 -0700 Subject: [PATCH] Populate device and vendor ID fields at device list creation. --- src/linux_sysfs.c | 74 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c index 6061cc0..8a4bd0f 100644 --- a/src/linux_sysfs.c +++ b/src/linux_sysfs.c @@ -82,7 +82,7 @@ static const struct pci_system_methods linux_sysfs_methods = { #define SYS_BUS_PCI "/sys/bus/pci/devices" -static void populate_entries( struct pci_system * pci_sys ); +static int populate_entries(struct pci_system * pci_sys); /** @@ -103,7 +103,7 @@ pci_system_linux_sysfs_create( void ) pci_sys = calloc( 1, sizeof( struct pci_system ) ); if ( pci_sys != NULL ) { pci_sys->methods = & linux_sysfs_methods; - populate_entries( pci_sys ); + err = populate_entries(pci_sys); } else { err = ENOMEM; @@ -135,12 +135,13 @@ scan_sys_pci_filter( const struct dirent * d ) } -void +int populate_entries( struct pci_system * p ) { struct dirent ** devices; int n; int i; + int err; n = scandir( SYS_BUS_PCI, & devices, scan_sys_pci_filter, alphasort ); @@ -148,20 +149,57 @@ populate_entries( struct pci_system * p ) p->num_devices = n; p->devices = calloc( n, sizeof( struct pci_device_private ) ); + if (p->devices != NULL) { + for (i = 0 ; i < n ; i++) { + uint8_t config[48]; + pciaddr_t bytes; + unsigned dom, bus, dev, func; + struct pci_device_private *device = + (struct pci_device_private *) &p->devices[i]; + + + sscanf(devices[i]->d_name, "%04x:%02x:%02x.%1u", + & dom, & bus, & dev, & func); + + device->base.domain = dom; + device->base.bus = bus; + device->base.dev = dev; + device->base.func = func; + + + err = pci_device_linux_sysfs_read(& device->base, config, 0, + 48, & bytes); + if ((bytes == 48) && !err) { + device->base.vendor_id = (uint16_t)config[0] + + ((uint16_t)config[1] << 8); + device->base.device_id = (uint16_t)config[2] + + ((uint16_t)config[3] << 8); + device->base.device_class = (uint32_t)config[9] + + ((uint32_t)config[10] << 8) + + ((uint32_t)config[11] << 16); + device->base.revision = config[8]; + device->base.subvendor_id = (uint16_t)config[44] + + ((uint16_t)config[45] << 8); + device->base.subdevice_id = (uint16_t)config[46] + + ((uint16_t)config[47] << 8); + } - for ( i = 0 ; i < n ; i++ ) { - unsigned dom, bus, dev, func; - - - sscanf( devices[ i ]->d_name, "%04x:%02x:%02x.%1u", - & dom, & bus, & dev, & func ); - - p->devices[ i ].base.domain = dom; - p->devices[ i ].base.bus = bus; - p->devices[ i ].base.dev = dev; - p->devices[ i ].base.func = func; + if (err) { + break; + } + } } + else { + err = ENOMEM; + } + } + + if (err) { + free(p->devices); + p->devices = NULL; } + + return err; } @@ -181,15 +219,7 @@ pci_device_linux_sysfs_probe( struct pci_device * dev ) if ( bytes >= 64 ) { struct pci_device_private *priv = (struct pci_device_private *) dev; - dev->vendor_id = (uint16_t)config[0] + ((uint16_t)config[1] << 8); - dev->device_id = (uint16_t)config[2] + ((uint16_t)config[3] << 8); - dev->device_class = (uint32_t)config[9] + ((uint32_t)config[10] << 8) - + ((uint32_t)config[11] << 16); - dev->revision = config[8]; - dev->subvendor_id = (uint16_t)config[44] + ((uint16_t)config[45] << 8); - dev->subdevice_id = (uint16_t)config[46] + ((uint16_t)config[47] << 8); dev->irq = config[60]; - priv->header_type = config[14]; -- 2.7.4