static int write_sysfs_str(char *path, enum cxl_sysfs_attr attr, char *str) { char *attr_name; char *attr_path; int fd, count; if (OUT_OF_RANGE(attr)) return -1; if (path == NULL) return -1; attr_name = sysfs_attr_name(attr); if (attr_name == NULL) return -1; attr_path = sysfs_get_path(path, attr_name); if (attr_path == NULL) return -1; fd = open(attr_path, O_WRONLY); free(attr_path); if (fd == -1) return -1; count = write(fd, str, strlen(str)); close(fd); if (count == -1) return -1; return 0; }
static char *sysfs_get_path(char *path, enum cxl_sysfs_attr attr) { char *attr_path = NULL; char *new_path; struct stat sb; char *attr_name; attr_name = sysfs_attr_name(attr); if (attr_name == NULL) return NULL; path = strdup(path); if (path == NULL) return NULL; /* * Try to open the attribute in sysfs. If it doesn't exist, keep * following "device/" path down until we find it. */ while (stat(path, &sb) != -1) { if (asprintf(&attr_path, "%s/%s", path, attr_name) == -1) goto out; if (stat(attr_path, &sb) == 0) { free(path); return attr_path; } if (errno != ENOENT) /* Something unexpected beside it not existing */ goto enodev; /* If it doesn't exist, walk down "device/" link */ if (asprintf(&new_path, "%s/device", path) == -1) goto out; free(path); path = new_path; free(attr_path); } /* Directory doesn't exist */ enodev: errno = ENODEV; out: if (attr_path) free(attr_path); free(path); return NULL; }
static int read_sysfs(char *sysfs_path, enum cxl_sysfs_attr attr, long *majorp, long *minorp) { char *attr_name; char *attr_path; char *buf; int expected, ret; if (OUT_OF_RANGE(attr)) return -1; attr_name = sysfs_attr_name(attr); if (attr_name == NULL) return -1; /* * Hack: * For configuration record attributes, attr_name is a printf * format with one parameter, the configuration record number, * pointed to by minorp. */ switch (attr) { case CR_CLASS: case CR_DEVICE: case CR_VENDOR: if (asprintf(&buf, attr_name, *minorp) == -1) return -1; attr_path = sysfs_get_path(sysfs_path, buf); free(buf); break; default: attr_path = sysfs_get_path(sysfs_path, attr_name); } if (attr_path == NULL) return -1; if ((buf = read_sysfs_str(attr_path)) == NULL) return -1; expected = sysfs_entry[attr].expected_num; ret = scan_sysfs_str(attr, buf, majorp, minorp); free(buf); return (ret == expected) ? 0 : -1; }