1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-01 00:51:24 +03:00

udev: use uint32_t for hotplug_slot

This also makes function id is parsed as uint64_t. Kernel internally
uses uint32_t for function id (see the definition of 'struct zpci_dev),
but it maybe extended in the future.
This commit is contained in:
Yu Watanabe 2021-04-07 19:17:23 +09:00
parent fa28023c0f
commit c304cb0146

View File

@ -263,10 +263,11 @@ static bool is_pci_bridge(sd_device *dev) {
return strneq(p + 2, "04", 2);
}
static int parse_hotplug_slot_from_function_id(sd_device *dev, const char *slots, int *ret) {
static int parse_hotplug_slot_from_function_id(sd_device *dev, const char *slots, uint32_t *ret) {
uint64_t function_id;
char path[PATH_MAX];
const char *attr;
int function_id, r;
int r;
/* The <sysname>/function_id attribute is unique to the s390 PCI driver. If present, we know
* that the slot's directory name for this device is /sys/bus/pci/XXXXXXXX/ where XXXXXXXX is
@ -286,32 +287,36 @@ static int parse_hotplug_slot_from_function_id(sd_device *dev, const char *slots
if (sd_device_get_sysattr_value(dev, "function_id", &attr) < 0)
return 0;
r = safe_atoi(attr, &function_id);
r = safe_atou64(attr, &function_id);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to parse function_id, ignoring: %s", attr);
if (!snprintf_ok(path, sizeof path, "%s/%08x/", slots, function_id))
return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ENAMETOOLONG), "PCI slot path is too long, ignoring.");
if (function_id <= 0 || function_id > UINT32_MAX)
return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EINVAL),
"Invalid function id (0x%"PRIx64"), ignoring.",
function_id);
if (!snprintf_ok(path, sizeof path, "%s/%08"PRIx64, slots, function_id))
return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ENAMETOOLONG),
"PCI slot path is too long, ignoring.");
if (access(path, F_OK) < 0)
return log_device_debug_errno(dev, errno, "Cannot access %s, ignoring: %m", path);
*ret = function_id;
*ret = (uint32_t) function_id;
return 1;
}
static int dev_pci_slot(sd_device *dev, struct netnames *names) {
unsigned long dev_port = 0;
unsigned domain, bus, slot, func;
int hotplug_slot = -1;
size_t l;
char *s;
const char *sysname, *attr, *port_name = NULL, *syspath;
_cleanup_(sd_device_unrefp) sd_device *pci = NULL;
sd_device *hotplug_slot_dev;
char slots[PATH_MAX];
_cleanup_closedir_ DIR *dir = NULL;
struct dirent *dent;
unsigned domain, bus, slot, func;
sd_device *hotplug_slot_dev;
unsigned long dev_port = 0;
uint32_t hotplug_slot = 0;
char slots[PATH_MAX], *s;
size_t l;
int r;
r = sd_device_get_sysname(names->pcidev, &sysname);
@ -380,6 +385,8 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
hotplug_slot_dev = names->pcidev;
while (hotplug_slot_dev) {
struct dirent *dent;
r = parse_hotplug_slot_from_function_id(hotplug_slot_dev, slots, &hotplug_slot);
if (r < 0)
return 0;
@ -392,14 +399,14 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
continue;
FOREACH_DIRENT_ALL(dent, dir, break) {
int i;
char str[PATH_MAX];
_cleanup_free_ char *address = NULL;
char str[PATH_MAX];
uint32_t i;
if (dot_or_dot_dot(dent->d_name))
continue;
r = safe_atoi(dent->d_name, &i);
r = safe_atou32(dent->d_name, &i);
if (r < 0 || i <= 0)
continue;
@ -419,7 +426,7 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
break;
}
}
if (hotplug_slot >= 0)
if (hotplug_slot > 0)
break;
if (sd_device_get_parent_with_subsystem_devtype(hotplug_slot_dev, "pci", NULL, &hotplug_slot_dev) < 0)
break;
@ -431,7 +438,7 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
l = sizeof(names->pci_slot);
if (domain > 0)
l = strpcpyf(&s, l, "P%d", domain);
l = strpcpyf(&s, l, "s%d", hotplug_slot);
l = strpcpyf(&s, l, "s%"PRIu32, hotplug_slot);
if (func > 0 || is_pci_multifunction(names->pcidev))
l = strpcpyf(&s, l, "f%d", func);
if (port_name)