return 0;
}
-static bool line_bulk_is_requested(struct gpiod_line_bulk *bulk)
+static bool line_bulk_same_chip(struct gpiod_line_bulk *bulk)
{
- struct gpiod_line *line, **lineptr;
+ struct gpiod_line *first_line, *line;
+ struct gpiod_chip *first_chip, *chip;
+ unsigned int i;
- gpiod_line_bulk_foreach_line(bulk, line, lineptr) {
- if (!gpiod_line_is_requested(line))
+ if (bulk->num_lines == 1)
+ return true;
+
+ first_line = gpiod_line_bulk_get_line(bulk, 0);
+ first_chip = gpiod_line_get_chip(first_line);
+
+ for (i = 1; i < bulk->num_lines; i++) {
+ line = bulk->lines[i];
+ chip = gpiod_line_get_chip(line);
+
+ if (first_chip != chip) {
+ errno = EINVAL;
return false;
+ }
}
return true;
}
-static bool verify_line_bulk(struct gpiod_line_bulk *bulk)
+static bool line_bulk_all_requested(struct gpiod_line_bulk *bulk)
{
- struct gpiod_line *line;
- struct gpiod_chip *chip;
- unsigned int off;
-
- chip = gpiod_line_get_chip(gpiod_line_bulk_get_line(bulk, 0));
+ struct gpiod_line *line, **lineptr;
- gpiod_line_bulk_foreach_line_off(bulk, line, off) {
- if (off > 0 && chip != gpiod_line_get_chip(line)) {
- errno = EINVAL;
+ gpiod_line_bulk_foreach_line(bulk, line, lineptr) {
+ if (!gpiod_line_is_requested(line)) {
+ errno = EPERM;
return false;
}
+ }
+ return true;
+}
+
+static bool line_bulk_all_free(struct gpiod_line_bulk *bulk)
+{
+ struct gpiod_line *line, **lineptr;
+
+ gpiod_line_bulk_foreach_line(bulk, line, lineptr) {
if (!gpiod_line_is_free(line)) {
errno = EBUSY;
return false;
const struct gpiod_line_request_config *config,
const int *default_vals)
{
- if (!verify_line_bulk(bulk))
+ if (!line_bulk_same_chip(bulk) || !line_bulk_all_free(bulk))
return -1;
if (line_request_is_direction(config->request_type)) {
unsigned int i;
int status, fd;
- first = gpiod_line_bulk_get_line(bulk, 0);
-
- if (!line_bulk_is_requested(bulk)) {
- errno = EPERM;
+ if (!line_bulk_same_chip(bulk) || !line_bulk_all_requested(bulk))
return -1;
- }
+
+ first = gpiod_line_bulk_get_line(bulk, 0);
memset(&data, 0, sizeof(data));
unsigned int i;
int status;
- if (!line_bulk_is_requested(bulk)) {
- errno = EPERM;
+ if (!line_bulk_same_chip(bulk) || !line_bulk_all_requested(bulk))
return -1;
- }
memset(&data, 0, sizeof(data));
struct gpiod_line *line;
int rv;
+ if (!line_bulk_same_chip(bulk) || !line_bulk_all_requested(bulk))
+ return -1;
+
memset(fds, 0, sizeof(fds));
num_lines = gpiod_line_bulk_num_lines(bulk);
int gpiod_line_event_read(struct gpiod_line *line,
struct gpiod_line_event *event)
{
+ if (line->state != LINE_REQUESTED_EVENTS) {
+ errno = EPERM;
+ return -1;
+ }
+
return gpiod_line_event_read_fd(line->fd, event);
}
int gpiod_line_event_get_fd(struct gpiod_line *line)
{
if (line->state != LINE_REQUESTED_EVENTS) {
- errno = EINVAL;
+ errno = EPERM;
return -1;
}
fd = gpiod_line_event_get_fd(line);
TEST_ASSERT_EQ(fd, -1);
- TEST_ASSERT_ERRNO_IS(EINVAL);
+ TEST_ASSERT_ERRNO_IS(EPERM);
}
TEST_DEFINE(event_get_fd_when_values_requested,
"events - gpiod_line_event_get_fd(): line requested for values",
"gpiod_line_set_value() - good",
0, { 8 });
+static void line_get_value_different_chips(void)
+{
+ TEST_CLEANUP(test_close_chip) struct gpiod_chip *chipA = NULL;
+ TEST_CLEANUP(test_close_chip) struct gpiod_chip *chipB = NULL;
+ struct gpiod_line *lineA1, *lineA2, *lineB1, *lineB2;
+ struct gpiod_line_bulk bulkA, bulkB, bulk;
+ int rv, vals[4];
+
+ chipA = gpiod_chip_open(test_chip_path(0));
+ TEST_ASSERT_NOT_NULL(chipA);
+
+ chipB = gpiod_chip_open(test_chip_path(1));
+ TEST_ASSERT_NOT_NULL(chipB);
+
+ lineA1 = gpiod_chip_get_line(chipA, 3);
+ lineA2 = gpiod_chip_get_line(chipA, 4);
+ lineB1 = gpiod_chip_get_line(chipB, 5);
+ lineB2 = gpiod_chip_get_line(chipB, 6);
+ TEST_ASSERT_NOT_NULL(lineA1);
+ TEST_ASSERT_NOT_NULL(lineA2);
+ TEST_ASSERT_NOT_NULL(lineB1);
+ TEST_ASSERT_NOT_NULL(lineB2);
+
+ gpiod_line_bulk_init(&bulkA);
+ gpiod_line_bulk_init(&bulkB);
+ gpiod_line_bulk_init(&bulk);
+
+ gpiod_line_bulk_add(&bulk, lineA1);
+ gpiod_line_bulk_add(&bulk, lineA2);
+ gpiod_line_bulk_add(&bulk, lineB1);
+ gpiod_line_bulk_add(&bulk, lineB2);
+
+ gpiod_line_bulk_add(&bulkA, lineA1);
+ gpiod_line_bulk_add(&bulkA, lineA2);
+ gpiod_line_bulk_add(&bulkB, lineB1);
+ gpiod_line_bulk_add(&bulkB, lineB2);
+ gpiod_line_bulk_add(&bulk, lineA1);
+ gpiod_line_bulk_add(&bulk, lineA2);
+ gpiod_line_bulk_add(&bulk, lineB1);
+ gpiod_line_bulk_add(&bulk, lineB2);
+
+ rv = gpiod_line_request_bulk_input(&bulkA, TEST_CONSUMER);
+ TEST_ASSERT_RET_OK(rv);
+
+ rv = gpiod_line_request_bulk_input(&bulkB, TEST_CONSUMER);
+ TEST_ASSERT_RET_OK(rv);
+
+ rv = gpiod_line_get_value_bulk(&bulk, vals);
+ TEST_ASSERT_EQ(rv, -1);
+ TEST_ASSERT_ERRNO_IS(EINVAL);
+}
+TEST_DEFINE(line_get_value_different_chips,
+ "gpiod_line_get_value_bulk() - different chips",
+ 0, { 8, 8 });
+
static void line_get_good(void)
{
TEST_CLEANUP(test_line_close_chip) struct gpiod_line *line = NULL;