diff options
Diffstat (limited to 'drivers/net/ethernet/sfc/mcdi_mon.c')
-rw-r--r-- | drivers/net/ethernet/sfc/mcdi_mon.c | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/drivers/net/ethernet/sfc/mcdi_mon.c b/drivers/net/ethernet/sfc/mcdi_mon.c index d72ad4f..4cc5d95 100644 --- a/drivers/net/ethernet/sfc/mcdi_mon.c +++ b/drivers/net/ethernet/sfc/mcdi_mon.c @@ -139,10 +139,17 @@ static int efx_mcdi_mon_update(struct efx_nic *efx) return rc; } +static ssize_t efx_mcdi_mon_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%s\n", KBUILD_MODNAME); +} + static int efx_mcdi_mon_get_entry(struct device *dev, unsigned int index, efx_dword_t *entry) { - struct efx_nic *efx = dev_get_drvdata(dev->parent); + struct efx_nic *efx = dev_get_drvdata(dev); struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); int rc; @@ -256,7 +263,7 @@ static ssize_t efx_mcdi_mon_show_label(struct device *dev, efx_mcdi_sensor_type[mon_attr->type].label); } -static void +static int efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name, ssize_t (*reader)(struct device *, struct device_attribute *, char *), @@ -265,6 +272,7 @@ efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name, { struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); struct efx_mcdi_mon_attribute *attr = &hwmon->attrs[hwmon->n_attrs]; + int rc; strlcpy(attr->name, name, sizeof(attr->name)); attr->index = index; @@ -278,7 +286,10 @@ efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name, attr->dev_attr.attr.name = attr->name; attr->dev_attr.attr.mode = S_IRUGO; attr->dev_attr.show = reader; - hwmon->group.attrs[hwmon->n_attrs++] = &attr->dev_attr.attr; + rc = device_create_file(&efx->pci_dev->dev, &attr->dev_attr); + if (rc == 0) + ++hwmon->n_attrs; + return rc; } int efx_mcdi_mon_probe(struct efx_nic *efx) @@ -327,22 +338,26 @@ int efx_mcdi_mon_probe(struct efx_nic *efx) efx_mcdi_mon_update(efx); /* Allocate space for the maximum possible number of - * attributes for this set of sensors: + * attributes for this set of sensors: name of the driver plus * value, min, max, crit, alarm and label for each sensor. */ - n_attrs = 6 * n_sensors; + n_attrs = 1 + 6 * n_sensors; hwmon->attrs = kcalloc(n_attrs, sizeof(*hwmon->attrs), GFP_KERNEL); if (!hwmon->attrs) { rc = -ENOMEM; goto fail; } - hwmon->group.attrs = kcalloc(n_attrs + 1, sizeof(struct attribute *), - GFP_KERNEL); - if (!hwmon->group.attrs) { - rc = -ENOMEM; + + hwmon->device = hwmon_device_register(&efx->pci_dev->dev); + if (IS_ERR(hwmon->device)) { + rc = PTR_ERR(hwmon->device); goto fail; } + rc = efx_mcdi_mon_add_attr(efx, "name", efx_mcdi_mon_show_name, 0, 0, 0); + if (rc) + goto fail; + for (i = 0, j = -1, type = -1; ; i++) { enum efx_hwmon_type hwmon_type; const char *hwmon_prefix; @@ -357,7 +372,7 @@ int efx_mcdi_mon_probe(struct efx_nic *efx) page = type / 32; j = -1; if (page == n_pages) - goto hwmon_register; + return 0; MCDI_SET_DWORD(inbuf, SENSOR_INFO_EXT_IN_PAGE, page); @@ -438,22 +453,28 @@ int efx_mcdi_mon_probe(struct efx_nic *efx) if (min1 != max1) { snprintf(name, sizeof(name), "%s%u_input", hwmon_prefix, hwmon_index); - efx_mcdi_mon_add_attr( + rc = efx_mcdi_mon_add_attr( efx, name, efx_mcdi_mon_show_value, i, type, 0); + if (rc) + goto fail; if (hwmon_type != EFX_HWMON_POWER) { snprintf(name, sizeof(name), "%s%u_min", hwmon_prefix, hwmon_index); - efx_mcdi_mon_add_attr( + rc = efx_mcdi_mon_add_attr( efx, name, efx_mcdi_mon_show_limit, i, type, min1); + if (rc) + goto fail; } snprintf(name, sizeof(name), "%s%u_max", hwmon_prefix, hwmon_index); - efx_mcdi_mon_add_attr( + rc = efx_mcdi_mon_add_attr( efx, name, efx_mcdi_mon_show_limit, i, type, max1); + if (rc) + goto fail; if (min2 != max2) { /* Assume max2 is critical value. @@ -461,38 +482,32 @@ int efx_mcdi_mon_probe(struct efx_nic *efx) */ snprintf(name, sizeof(name), "%s%u_crit", hwmon_prefix, hwmon_index); - efx_mcdi_mon_add_attr( + rc = efx_mcdi_mon_add_attr( efx, name, efx_mcdi_mon_show_limit, i, type, max2); + if (rc) + goto fail; } } snprintf(name, sizeof(name), "%s%u_alarm", hwmon_prefix, hwmon_index); - efx_mcdi_mon_add_attr( + rc = efx_mcdi_mon_add_attr( efx, name, efx_mcdi_mon_show_alarm, i, type, 0); + if (rc) + goto fail; if (type < ARRAY_SIZE(efx_mcdi_sensor_type) && efx_mcdi_sensor_type[type].label) { snprintf(name, sizeof(name), "%s%u_label", hwmon_prefix, hwmon_index); - efx_mcdi_mon_add_attr( + rc = efx_mcdi_mon_add_attr( efx, name, efx_mcdi_mon_show_label, i, type, 0); + if (rc) + goto fail; } } -hwmon_register: - hwmon->groups[0] = &hwmon->group; - hwmon->device = hwmon_device_register_with_groups(&efx->pci_dev->dev, - KBUILD_MODNAME, NULL, - hwmon->groups); - if (IS_ERR(hwmon->device)) { - rc = PTR_ERR(hwmon->device); - goto fail; - } - - return 0; - fail: efx_mcdi_mon_remove(efx); return rc; @@ -501,11 +516,14 @@ fail: void efx_mcdi_mon_remove(struct efx_nic *efx) { struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); + unsigned int i; + for (i = 0; i < hwmon->n_attrs; i++) + device_remove_file(&efx->pci_dev->dev, + &hwmon->attrs[i].dev_attr); + kfree(hwmon->attrs); if (hwmon->device) hwmon_device_unregister(hwmon->device); - kfree(hwmon->attrs); - kfree(hwmon->group.attrs); efx_nic_free_buffer(efx, &hwmon->dma_buf); } |