summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Schiffer <pschiffe@redhat.com>2013-07-16 14:01:35 +0200
committerPeter Schiffer <pschiffe@redhat.com>2013-07-16 14:01:35 +0200
commitec3391938be3058f11036bade813ba4239d7103b (patch)
tree4a0d953557ad6c9aa47730f23c0e11c6f085c8f1
parent607c7feaa11f124b835860a36f9a6f40871ac939 (diff)
downloadopenlmi-providers-ec3391938be3058f11036bade813ba4239d7103b.tar.gz
openlmi-providers-ec3391938be3058f11036bade813ba4239d7103b.tar.xz
openlmi-providers-ec3391938be3058f11036bade813ba4239d7103b.zip
Hardware: Update LMI_PCIDevice provider
LMI_PCIDevice provider was updated to match the rest of the providers in the Hardware, multiple information was added. As main and only source of information is still libpci library, as udev doesn't provide all necessary information and if used, it would have to be combined with libpci anyway.
-rw-r--r--mof/60_LMI_Hardware.mof14
-rw-r--r--src/hardware/LMI_Hardware.h1
-rw-r--r--src/hardware/LMI_PCIDeviceProvider.c259
3 files changed, 225 insertions, 49 deletions
diff --git a/mof/60_LMI_Hardware.mof b/mof/60_LMI_Hardware.mof
index 41e80b8..74b85a2 100644
--- a/mof/60_LMI_Hardware.mof
+++ b/mof/60_LMI_Hardware.mof
@@ -356,15 +356,15 @@ class LMI_PhysicalBatteryContainer: CIM_Container
[ Provider("cmpi:cmpiLMI_PCIDevice") ]
class LMI_PCIDevice: CIM_PCIDevice
{
- [ Description("Name of the subsystem") ]
- string SubsystemName;
-
- [ Description("Name of the subsystem vendor") ]
- string SubsystemVendorName;
+ [ Description("Name of the vendor") ]
+ string VendorName;
[ Description("Name of the device") ]
string PCIDeviceName;
- [ Description("Name of the vendor") ]
- string VendorName;
+ [ Description("Name of the subsystem vendor") ]
+ string SubsystemVendorName;
+
+ [ Description("Name of the subsystem") ]
+ string SubsystemName;
};
diff --git a/src/hardware/LMI_Hardware.h b/src/hardware/LMI_Hardware.h
index 227ca51..1361dd4 100644
--- a/src/hardware/LMI_Hardware.h
+++ b/src/hardware/LMI_Hardware.h
@@ -39,5 +39,6 @@
#define POINTING_DEVICE_CLASS_NAME "PointingDevice"
#define BATTERY_CLASS_NAME "Battery"
#define BATTERY_PHYS_PKG_CLASS_NAME "BatteryPhysicalPackage"
+#define PCI_DEVICE_CLASS_NAME "PCIDevice"
#endif /* LMI_HARDWARE_H_ */
diff --git a/src/hardware/LMI_PCIDeviceProvider.c b/src/hardware/LMI_PCIDeviceProvider.c
index e879484..2daf0a6 100644
--- a/src/hardware/LMI_PCIDeviceProvider.c
+++ b/src/hardware/LMI_PCIDeviceProvider.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2013 Red Hat, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,29 +16,22 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Authors: Tomas Smetana <tsmetana@redhat.com>
- *
+ * Peter Schiffer <pschiffe@redhat.com>
*/
+
#include <konkret/konkret.h>
#include <pci/pci.h>
-
-#include "globals.h"
#include "LMI_PCIDevice.h"
+#include "LMI_Hardware.h"
+#include "globals.h"
-static const CMPIBroker* _cb = NULL;
+#define NAME_BUF_SIZE 128
+#define PCI_DEVID_STR_SIZE 55
-static void get_subid(struct pci_dev *d, u16 *subvp, u16 *subdp)
-{
- u8 htype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f;
+void get_subid(struct pci_dev *d, u16 *subvp, u16 *subdp);
+CMPIUint16 get_capability(const u16 pci_cap);
- if (htype == PCI_HEADER_TYPE_NORMAL) {
- *subvp = pci_read_word(d, PCI_SUBSYSTEM_VENDOR_ID);
- *subdp = pci_read_word(d, PCI_SUBSYSTEM_ID);
- } else if (htype == PCI_HEADER_TYPE_CARDBUS) {
- *subvp = pci_read_word(d, PCI_CB_SUBSYSTEM_VENDOR_ID);
- *subdp = pci_read_word(d, PCI_CB_SUBSYSTEM_ID);
- } else
- *subvp = *subdp = 0xffff;
-}
+static const CMPIBroker* _cb = NULL;
static void LMI_PCIDeviceInitialize()
{
@@ -61,8 +54,6 @@ static CMPIStatus LMI_PCIDeviceEnumInstanceNames(
return KDefaultEnumerateInstanceNames(_cb, mi, cc, cr, cop);
}
-#define NAME_BUF_SIZE 128
-#define PCI_DEVID_STR_SIZE 9
static CMPIStatus LMI_PCIDeviceEnumInstances(
CMPIInstanceMI* mi,
const CMPIContext* cc,
@@ -70,21 +61,26 @@ static CMPIStatus LMI_PCIDeviceEnumInstances(
const CMPIObjectPath* cop,
const char** properties)
{
+ LMI_PCIDevice lmi_dev;
+ const char *ns = KNameSpace(cop);
+ int i;
+ CMPICount count;
+ CMPIUint16 pci_cap;
+ u8 rev, cache_line;
+ u16 svid, subid, status, command_reg;
struct pci_access *acc;
struct pci_dev *dev;
struct pci_cap *cap;
- int i;
- u16 subid, svid;
char vendor_buf[NAME_BUF_SIZE], *vendor_name;
char device_buf[NAME_BUF_SIZE], *device_name;
char subsys_buf[NAME_BUF_SIZE], *subsys_name;
char svendor_buf[NAME_BUF_SIZE], *svendor_name;
char device_id_str[PCI_DEVID_STR_SIZE];
- LMI_PCIDevice lmi_dev;
- const char *ns = KNameSpace(cop);
+ char instance_id[INSTANCE_ID_LEN];
- if (!(acc = pci_alloc()))
- KReturn2(_cb, ERR_FAILED, "Error accessing the PCI bus");
+ if (!(acc = pci_alloc())) {
+ KReturn2(_cb, ERR_FAILED, "Can't access the PCI bus.");
+ }
pci_init(acc);
pci_scan_bus(acc);
@@ -107,45 +103,163 @@ static CMPIStatus LMI_PCIDeviceEnumInstances(
dev->vendor_id, dev->device_id, svid, subid);
svendor_name = pci_lookup_name(acc, svendor_buf, NAME_BUF_SIZE,
PCI_LOOKUP_VENDOR | PCI_LOOKUP_SUBSYSTEM, svid);
+ status = pci_read_word(dev, PCI_STATUS);
+ rev = pci_read_byte(dev, PCI_REVISION_ID);
+ cache_line = pci_read_byte(dev, PCI_CACHE_LINE_SIZE);
+ command_reg = pci_read_word(dev, PCI_COMMAND);
+
+ snprintf(device_id_str, PCI_DEVID_STR_SIZE, "%02x:%02x.%u",
+ dev->bus, dev->dev, dev->func);
+ snprintf(instance_id, INSTANCE_ID_LEN,
+ ORGID ":" ORGID "_" PCI_DEVICE_CLASS_NAME ":%s", device_id_str);
LMI_PCIDevice_Init(&lmi_dev, _cb, ns);
- LMI_PCIDevice_Set_CreationClassName(&lmi_dev, "LMI_PCIDevice");
+
LMI_PCIDevice_Set_SystemCreationClassName(&lmi_dev,
get_system_creation_class_name());
LMI_PCIDevice_Set_SystemName(&lmi_dev, get_system_name());
- snprintf((char *)&device_id_str, PCI_DEVID_STR_SIZE, "%d:%d.%d",
- dev->bus, dev->dev, dev->func);
+ LMI_PCIDevice_Set_CreationClassName(&lmi_dev,
+ ORGID "_" PCI_DEVICE_CLASS_NAME);
+ LMI_PCIDevice_Set_Caption(&lmi_dev,
+ "This object represents one logical PCI device contained in system.");
+
+ LMI_PCIDevice_Set_PrimaryStatus(&lmi_dev,
+ LMI_PCIDevice_PrimaryStatus_Unknown);
+ LMI_PCIDevice_Set_HealthState(&lmi_dev,
+ LMI_PCIDevice_HealthState_Unknown);
+
LMI_PCIDevice_Set_DeviceID(&lmi_dev, device_id_str);
LMI_PCIDevice_Set_BusNumber(&lmi_dev, dev->bus);
LMI_PCIDevice_Set_DeviceNumber(&lmi_dev, dev->dev);
LMI_PCIDevice_Set_FunctionNumber(&lmi_dev, dev->func);
+ LMI_PCIDevice_Set_Name(&lmi_dev, device_name);
+ LMI_PCIDevice_Set_ElementName(&lmi_dev, device_name);
+
LMI_PCIDevice_Set_VendorID(&lmi_dev, dev->vendor_id);
LMI_PCIDevice_Set_PCIDeviceID(&lmi_dev, dev->device_id);
LMI_PCIDevice_Set_PCIDeviceName(&lmi_dev, device_name);
- LMI_PCIDevice_Set_SubsystemID(&lmi_dev, subid);
- LMI_PCIDevice_Set_SubsystemVendorID(&lmi_dev, svid);
+ if (vendor_name) {
+ LMI_PCIDevice_Set_VendorName(&lmi_dev, vendor_name);
+ }
+ if (svid > 0 && svid < 65535) {
+ LMI_PCIDevice_Set_SubsystemVendorID(&lmi_dev, svid);
+ if (svendor_name) {
+ LMI_PCIDevice_Set_SubsystemVendorName(&lmi_dev, svendor_name);
+ }
+ }
+ if (subid > 0 && subid < 65535) {
+ LMI_PCIDevice_Set_SubsystemID(&lmi_dev, subid);
+ if (subsys_name) {
+ LMI_PCIDevice_Set_SubsystemName(&lmi_dev, subsys_name);
+ }
+ }
+
+ if (rev) {
+ LMI_PCIDevice_Set_RevisionID(&lmi_dev, rev);
+ }
+ if (cache_line) {
+ LMI_PCIDevice_Set_CacheLineSize(&lmi_dev, cache_line);
+ }
+ if (command_reg) {
+ LMI_PCIDevice_Set_CommandRegister(&lmi_dev, command_reg);
+ }
+
/* Throw away the lower 8 bits denoting the subclass */
LMI_PCIDevice_Set_ClassCode(&lmi_dev, ((dev->device_class) >> 8));
- if (dev->rom_base_addr)
+
+ if ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_SLOW) {
+ LMI_PCIDevice_Set_DeviceSelectTiming(&lmi_dev,
+ LMI_PCIDevice_DeviceSelectTiming_Slow);
+ } else if ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_MEDIUM) {
+ LMI_PCIDevice_Set_DeviceSelectTiming(&lmi_dev,
+ LMI_PCIDevice_DeviceSelectTiming_Medium);
+ } else if ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_FAST) {
+ LMI_PCIDevice_Set_DeviceSelectTiming(&lmi_dev,
+ LMI_PCIDevice_DeviceSelectTiming_Fast);
+ }
+
+ if (dev->rom_base_addr) {
LMI_PCIDevice_Set_ExpansionROMBaseAddress(&lmi_dev,
dev->rom_base_addr);
- if (vendor_name)
- LMI_PCIDevice_Set_VendorName(&lmi_dev, vendor_name);
- if (subsys_name)
- LMI_PCIDevice_Set_SubsystemName(&lmi_dev, subsys_name);
- if (svendor_name)
- LMI_PCIDevice_Set_SubsystemVendorName(&lmi_dev, svendor_name);
- for (i = 0; i < 6; i++)
+ }
+
+ LMI_PCIDevice_Set_InstanceID(&lmi_dev, instance_id);
+ LMI_PCIDevice_Set_InterruptPin(&lmi_dev,
+ pci_read_byte(dev, PCI_INTERRUPT_PIN));
+ LMI_PCIDevice_Set_LatencyTimer(&lmi_dev,
+ pci_read_byte(dev, PCI_LATENCY_TIMER));
+
+ /* PCI Base Addresses */
+ /* Count them */
+ count = 0;
+ for (i = 0; i < 6; i++) {
if (dev->base_addr[i]) {
+ count++;
+ }
+ }
+ /* Set PCI Base Addresses */
+ if (count > 0) {
+#ifdef PCI_HAVE_64BIT_ADDRESS
+ LMI_PCIDevice_Init_BaseAddress64(&lmi_dev, count);
+#else
+ LMI_PCIDevice_Init_BaseAddress(&lmi_dev, count);
+#endif
+ count = 0;
+ for (i = 0; i < 6; i++) {
+ if (dev->base_addr[i]) {
#ifdef PCI_HAVE_64BIT_ADDRESS
- LMI_PCIDevice_Set_BaseAddress64(&lmi_dev, i, dev->base_addr[i]);
+ LMI_PCIDevice_Set_BaseAddress64(&lmi_dev, count++,
+ dev->base_addr[i]);
#else
- LMI_PCIDevice_Set_BaseAddress(&lmi_dev, i, dev->base_addr[i]);
+ LMI_PCIDevice_Set_BaseAddress(&lmi_dev, count++,
+ dev->base_addr[i]);
#endif
+ }
+ }
+ }
+
+ /* PCI Capabilities */
+ /* Count PCI Capabilities */
+ count = 0;
+ if (status & PCI_STATUS_66MHZ) {
+ count++;
+ }
+ if (status & PCI_STATUS_UDF) {
+ count++;
+ }
+ if (status & PCI_STATUS_FAST_BACK) {
+ count++;
+ }
+ for (cap = dev->first_cap; cap; cap = cap->next) {
+ pci_cap = get_capability(cap->id);
+ if (pci_cap > 1) {
+ count++;
+ }
+ }
+ /* Get PCI Capabilities */
+ if (count > 0) {
+ LMI_PCIDevice_Init_Capabilities(&lmi_dev, count);
+ count = 0;
+ if (status & PCI_STATUS_66MHZ) {
+ LMI_PCIDevice_Set_Capabilities(&lmi_dev, count++,
+ LMI_PCIDevice_Capabilities_Supports_66MHz);
+ }
+ if (status & PCI_STATUS_UDF) {
+ LMI_PCIDevice_Set_Capabilities(&lmi_dev, count++,
+ LMI_PCIDevice_Capabilities_Supports_User_Definable_Features);
+ }
+ if (status & PCI_STATUS_FAST_BACK) {
+ LMI_PCIDevice_Set_Capabilities(&lmi_dev, count++,
+ LMI_PCIDevice_Capabilities_Supports_Fast_Back_to_Back_Transactions);
+ }
+ for (cap = dev->first_cap; cap; cap = cap->next) {
+ pci_cap = get_capability(cap->id);
+ if (pci_cap > 1) {
+ LMI_PCIDevice_Set_Capabilities(&lmi_dev, count++, pci_cap);
+ }
}
- for (cap = dev->first_cap, i = 0; cap; cap = cap->next, i++) {
- LMI_PCIDevice_Set_Capabilities(&lmi_dev, i, cap->type);
}
+
KReturnInstance(cr, lmi_dev);
}
@@ -364,6 +478,67 @@ KUint8 LMI_PCIDevice_BISTExecution(
return result;
}
+void get_subid(struct pci_dev *d, u16 *subvp, u16 *subdp)
+{
+ u8 htype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f;
+
+ if (htype == PCI_HEADER_TYPE_NORMAL) {
+ *subvp = pci_read_word(d, PCI_SUBSYSTEM_VENDOR_ID);
+ *subdp = pci_read_word(d, PCI_SUBSYSTEM_ID);
+ } else if (htype == PCI_HEADER_TYPE_CARDBUS) {
+ *subvp = pci_read_word(d, PCI_CB_SUBSYSTEM_VENDOR_ID);
+ *subdp = pci_read_word(d, PCI_CB_SUBSYSTEM_ID);
+ } else {
+ *subvp = *subdp = 0xffff;
+ }
+}
+
+/*
+ * Get pci capability according to the pci lib.
+ * @param pci_cap from pci lib
+ * @return CIM id of pci capability
+ */
+CMPIUint16 get_capability(const u16 pci_cap)
+{
+ static struct {
+ CMPIUint16 cim_val; /* CIM value */
+ u16 pci_cap; /* pci value */
+ } values[] = {
+ /*
+ {0, "Unknown"},
+ {1, "Other"},
+ {2, "Supports 66MHz"},
+ {3, "Supports User Definable Features"},
+ {4, "Supports Fast Back-to-Back Transactions"},
+ */
+ {5, PCI_CAP_ID_PCIX},
+ {6, PCI_CAP_ID_PM},
+ {7, PCI_CAP_ID_MSI},
+ /*
+ {8, "Parity Error Recovery Capable"},
+ */
+ {9, PCI_CAP_ID_AGP},
+ {10, PCI_CAP_ID_VPD},
+ {11, PCI_CAP_ID_SLOTID},
+ {12, PCI_CAP_ID_HOTPLUG},
+ {13, PCI_CAP_ID_EXP},
+ /*
+ {14, "Supports PCIe Gen 2"},
+ {15, "Supports PCIe Gen 3"},
+ */
+ };
+
+ size_t i, val_length = sizeof(values) / sizeof(values[0]);
+
+ for (i = 0; i < val_length; i++) {
+ if (pci_cap == values[i].pci_cap) {
+ return values[i].cim_val;
+ }
+ }
+
+ return 1; /* Other */
+}
+
KONKRET_REGISTRATION(
"root/cimv2",
"LMI_PCIDevice",