Добавление собственной группы атрибутов устройства sysfs в существующие стандартные атрибуты класса устройства - PullRequest
0 голосов
/ 13 сентября 2018

Одна из задач учебных курсов по ядру Linux - добавить поддержку sysfs к одному из ранее написанных драйверов устройств. Я выбираю драйвер ds1307 rtc и хочу добавить атрибуты устройства, а не драйвера.

Но я не уверен, что мое решение верное.

В тот момент, когда функция зонда вызывается, клиентское устройство i2c уже создано, поэтому любые манипуляции с атрибутами устройства вызовут состояние гонки. Поэтому я решаю добавить свои атрибуты на устройство rtc перед регистрацией устройства. Я просто считаю группы атрибутов rtc по умолчанию, выделяю новый массив с одной дополнительной позицией для моей группы атрибутов и заменяю указатель групп устройств rtc выделенным массивом.

static int ds1307x_probe(struct i2c_client *client,
    const struct i2c_device_id *id)
{
    struct device *dev;
    const struct attribute_group **grp, **ngrp;
    struct rtc_device *rtc;
    int ret, cnt;

    /* device presence check code skipped */

    dev = &client->dev;
    rtc = devm_rtc_allocate_device(dev);
    if (!rtc)
        return -ENOMEM;

    dev = &rtc->dev;
    grp = dev->groups;
    if (!grp) {
        /* no default groups, just use own groups array */
        dev->groups = ds1307x_groups;
    } else {
        /* copy rtc groups array, add own group at end */
        cnt = 0;
        while (grp[cnt])
            ++cnt;

        ngrp = devm_kmalloc(&rtc->dev, (cnt+2) * sizeof(*ngrp),
                            GFP_KERNEL);
        if (!ngrp)
            return -ENOMEM;

        memcpy(ngrp, grp, cnt * sizeof(*ngrp));
        ngrp[cnt] = &ds1307x_group;
        ngrp[cnt+1] = NULL;
        dev->groups = ngrp;
    }

    rtc->uie_unsupported = 1;
    rtc->ops = &ds1307x_ops;

    ret = rtc_register_device(rtc);

    /* remaining of code skipped */
}

Группа атрибутов ds1307x_control с атрибутами clock_halt и out_ctrl появляется в каталоге устройств rtc0 среди стандартных атрибутов класса rtc:

~ # ls /sys/class/rtc/rtc0/
date             ds1307x_control  name             subsystem
dev              hctosys          power            time
device           max_user_freq    since_epoch      uevent
~ # ls /sys/class/rtc/rtc0/ds1307x_control/
clock_halt  out_ctrl

Это решение работает для меня, и я надеюсь, что оно достаточно хорошо для учебных курсов.

Но как насчет реальной жизни? Есть ли скрытые проблемы?

...