Commit 95a4eed7 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Bartosz Golaszewski

gpiolib: Never return internal error codes to user space

Currently it's possible that character device interface may return
the error codes which are not supposed to be seen by user space.
In this case it's EPROBE_DEFER.

Wrap it to return -ENODEV instead as sysfs does.

Fixes: d7c51b47 ("gpio: userspace ABI for reading/writing GPIO lines")
Fixes: 61f922db ("gpio: userspace ABI for reading GPIO line events")
Fixes: 3c0d9c63 ("gpiolib: cdev: support GPIO_V2_GET_LINE_IOCTL and GPIO_V2_LINE_GET_VALUES_IOCTL")
Reported-by: default avatarSuresh Balakrishnan <suresh.balakrishnan@intel.com>
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarBartosz Golaszewski <brgl@bgdev.pl>
parent 2cba0545
......@@ -330,7 +330,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
goto out_free_lh;
}
ret = gpiod_request(desc, lh->label);
ret = gpiod_request_user(desc, lh->label);
if (ret)
goto out_free_lh;
lh->descs[i] = desc;
......@@ -1378,7 +1378,7 @@ static int linereq_create(struct gpio_device *gdev, void __user *ip)
goto out_free_linereq;
}
ret = gpiod_request(desc, lr->label);
ret = gpiod_request_user(desc, lr->label);
if (ret)
goto out_free_linereq;
......@@ -1764,7 +1764,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
}
}
ret = gpiod_request(desc, le->label);
ret = gpiod_request_user(desc, le->label);
if (ret)
goto out_free_le;
le->desc = desc;
......
......@@ -475,12 +475,9 @@ static ssize_t export_store(struct class *class,
* they may be undone on its behalf too.
*/
status = gpiod_request(desc, "sysfs");
if (status) {
if (status == -EPROBE_DEFER)
status = -ENODEV;
status = gpiod_request_user(desc, "sysfs");
if (status)
goto done;
}
status = gpiod_set_transitory(desc, false);
if (!status) {
......
......@@ -135,6 +135,18 @@ struct gpio_desc {
int gpiod_request(struct gpio_desc *desc, const char *label);
void gpiod_free(struct gpio_desc *desc);
static inline int gpiod_request_user(struct gpio_desc *desc, const char *label)
{
int ret;
ret = gpiod_request(desc, label);
if (ret == -EPROBE_DEFER)
ret = -ENODEV;
return ret;
}
int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
unsigned long lflags, enum gpiod_flags dflags);
int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment