예제 #1
0
/* retrieve on-board index number and label from firmware */
static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
        unsigned dev_port = 0;
        size_t l;
        char *s;
        const char *attr;
        int idx;

        /* ACPI _DSM  -- device specific method for naming a PCI or PCI Express device */
        attr = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
        /* SMBIOS type 41 -- Onboard Devices Extended Information */
        if (!attr)
                attr = udev_device_get_sysattr_value(names->pcidev, "index");
        if (!attr)
                return -ENOENT;

        idx = strtoul(attr, NULL, 0);
        if (idx <= 0)
                return -EINVAL;

        /* kernel provided port index for multiple ports on a single PCI function */
        attr = udev_device_get_sysattr_value(dev, "dev_port");
        if (attr)
                dev_port = strtol(attr, NULL, 10);

        s = names->pci_onboard;
        l = sizeof(names->pci_onboard);
        l = strpcpyf(&s, l, "o%d", idx);
        if (dev_port > 0)
                l = strpcpyf(&s, l, "d%d", dev_port);
        if (l == 0)
                names->pci_onboard[0] = '\0';

        names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label");

        return 0;
}
예제 #2
0
static int pretty_boot_time(sd_bus *bus, char **_buf) {
        char ts[FORMAT_TIMESPAN_MAX];
        struct boot_times *t;
        static char buf[4096];
        size_t size;
        char *ptr;
        int r;

        r = acquire_boot_times(bus, &t);
        if (r < 0)
                return r;

        ptr = buf;
        size = sizeof(buf);

        size = strpcpyf(&ptr, size, "Startup finished in ");
        if (t->firmware_time)
                size = strpcpyf(&ptr, size, "%s (firmware) + ", format_timespan(ts, sizeof(ts), t->firmware_time - t->loader_time, USEC_PER_MSEC));
        if (t->loader_time)
                size = strpcpyf(&ptr, size, "%s (loader) + ", format_timespan(ts, sizeof(ts), t->loader_time, USEC_PER_MSEC));
        if (t->kernel_time)
                size = strpcpyf(&ptr, size, "%s (kernel) + ", format_timespan(ts, sizeof(ts), t->kernel_done_time, USEC_PER_MSEC));
        if (t->initrd_time > 0)
                size = strpcpyf(&ptr, size, "%s (initrd) + ", format_timespan(ts, sizeof(ts), t->userspace_time - t->initrd_time, USEC_PER_MSEC));

        size = strpcpyf(&ptr, size, "%s (userspace) ", format_timespan(ts, sizeof(ts), t->finish_time - t->userspace_time, USEC_PER_MSEC));
        if (t->kernel_time > 0)
                strpcpyf(&ptr, size, "= %s", format_timespan(ts, sizeof(ts), t->firmware_time + t->finish_time, USEC_PER_MSEC));
        else
                strpcpyf(&ptr, size, "= %s", format_timespan(ts, sizeof(ts), t->finish_time - t->userspace_time, USEC_PER_MSEC));

        ptr = strdup(buf);
        if (!ptr)
                return log_oom();

        *_buf = ptr;
        return 0;
}
예제 #3
0
static int install_force_release(struct udev_device *dev, const unsigned *release, unsigned release_count) {
        struct udev_device *atkbd;
        const char *cur;
        char codes[4096];
        char *s;
        size_t l;
        unsigned i;
        int ret;

        assert(dev);
        assert(release);

        atkbd = udev_device_get_parent_with_subsystem_devtype(dev, "serio", NULL);
        if (!atkbd)
                return -ENODEV;

        cur = udev_device_get_sysattr_value(atkbd, "force_release");
        if (!cur)
                return -ENODEV;

        s = codes;
        l = sizeof(codes);

        /* copy current content */
        l = strpcpy(&s, l, cur);

        /* append new codes */
        for (i = 0; i < release_count; i++)
                l = strpcpyf(&s, l, ",%u", release[i]);

        log_debug("keyboard: updating force-release list with '%s'", codes);
        ret = udev_device_set_sysattr_value(atkbd, "force_release", codes);
        if (ret < 0)
                log_error_errno(ret, "Error writing force-release attribute: %m");
        return ret;
}
예제 #4
0
static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
        struct udev *udev = udev_device_get_udev(names->pcidev);
        unsigned domain, bus, slot, func, dev_port = 0;
        size_t l;
        char *s;
        const char *attr;
        struct udev_device *pci = NULL;
        char slots[256], str[256];
        _cleanup_closedir_ DIR *dir = NULL;
        struct dirent *dent;
        int hotplug_slot = 0, err = 0;

        if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4)
                return -ENOENT;

        /* kernel provided port index for multiple ports on a single PCI function */
        attr = udev_device_get_sysattr_value(dev, "dev_port");
        if (attr)
                dev_port = strtol(attr, NULL, 10);

        /* compose a name based on the raw kernel's PCI bus, slot numbers */
        s = names->pci_path;
        l = sizeof(names->pci_path);
        if (domain > 0)
                l = strpcpyf(&s, l, "P%u", domain);
        l = strpcpyf(&s, l, "p%us%u", bus, slot);
        if (func > 0 || is_pci_multifunction(names->pcidev))
                l = strpcpyf(&s, l, "f%u", func);
        if (dev_port > 0)
                l = strpcpyf(&s, l, "d%u", dev_port);
        if (l == 0)
                names->pci_path[0] = '\0';

        /* ACPI _SUN  — slot user number */
        pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
        if (!pci) {
                err = -ENOENT;
                goto out;
        }
        xsprintf(slots, "%s/slots", udev_device_get_syspath(pci));
        dir = opendir(slots);
        if (!dir) {
                err = -errno;
                goto out;
        }

        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
                int i;
                char *rest;
                char *address;

                if (dent->d_name[0] == '.')
                        continue;
                i = strtol(dent->d_name, &rest, 10);
                if (rest[0] != '\0')
                        continue;
                if (i < 1)
                        continue;
                xsprintf(str, "%s/%s/address", slots, dent->d_name);
                if (read_one_line_file(str, &address) >= 0) {
                        /* match slot address with device by stripping the function */
                        if (strneq(address, udev_device_get_sysname(names->pcidev), strlen(address)))
                                hotplug_slot = i;
                        free(address);
                }

                if (hotplug_slot > 0)
                        break;
        }

        if (hotplug_slot > 0) {
                s = names->pci_slot;
                l = sizeof(names->pci_slot);
                if (domain > 0)
                        l = strpcpyf(&s, l, "P%d", domain);
                l = strpcpyf(&s, l, "s%d", hotplug_slot);
                if (func > 0 || is_pci_multifunction(names->pcidev))
                        l = strpcpyf(&s, l, "f%d", func);
                if (dev_port > 0)
                        l = strpcpyf(&s, l, "d%d", dev_port);
                if (l == 0)
                        names->pci_slot[0] = '\0';
        }
out:
        udev_device_unref(pci);
        return err;
}