summaryrefslogtreecommitdiffstats
path: root/src
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 /src
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.
Diffstat (limited to 'src')
-rw-r--r--src/hardware/LMI_Hardware.h1
-rw-r--r--src/hardware/LMI_PCIDeviceProvider.c259
2 files changed, 218 insertions, 42 deletions
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",