hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/gpio/gpiolib-cdev.c
....@@ -197,16 +197,18 @@
197197 void __user *ip = (void __user *)arg;
198198 struct gpiohandle_data ghd;
199199 DECLARE_BITMAP(vals, GPIOHANDLES_MAX);
200
- int i;
200
+ unsigned int i;
201
+ int ret;
201202
202
- if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
203
- /* NOTE: It's ok to read values of output lines. */
204
- int ret = gpiod_get_array_value_complex(false,
205
- true,
206
- lh->num_descs,
207
- lh->descs,
208
- NULL,
209
- vals);
203
+ if (!lh->gdev->chip)
204
+ return -ENODEV;
205
+
206
+ switch (cmd) {
207
+ case GPIOHANDLE_GET_LINE_VALUES_IOCTL:
208
+ /* NOTE: It's okay to read values of output lines */
209
+ ret = gpiod_get_array_value_complex(false, true,
210
+ lh->num_descs, lh->descs,
211
+ NULL, vals);
210212 if (ret)
211213 return ret;
212214
....@@ -218,7 +220,7 @@
218220 return -EFAULT;
219221
220222 return 0;
221
- } else if (cmd == GPIOHANDLE_SET_LINE_VALUES_IOCTL) {
223
+ case GPIOHANDLE_SET_LINE_VALUES_IOCTL:
222224 /*
223225 * All line descriptors were created at once with the same
224226 * flags so just check if the first one is really output.
....@@ -240,10 +242,11 @@
240242 lh->descs,
241243 NULL,
242244 vals);
243
- } else if (cmd == GPIOHANDLE_SET_CONFIG_IOCTL) {
245
+ case GPIOHANDLE_SET_CONFIG_IOCTL:
244246 return linehandle_set_config(lh, ip);
247
+ default:
248
+ return -EINVAL;
245249 }
246
- return -EINVAL;
247250 }
248251
249252 #ifdef CONFIG_COMPAT
....@@ -1165,14 +1168,19 @@
11651168 struct linereq *lr = file->private_data;
11661169 void __user *ip = (void __user *)arg;
11671170
1168
- if (cmd == GPIO_V2_LINE_GET_VALUES_IOCTL)
1169
- return linereq_get_values(lr, ip);
1170
- else if (cmd == GPIO_V2_LINE_SET_VALUES_IOCTL)
1171
- return linereq_set_values(lr, ip);
1172
- else if (cmd == GPIO_V2_LINE_SET_CONFIG_IOCTL)
1173
- return linereq_set_config(lr, ip);
1171
+ if (!lr->gdev->chip)
1172
+ return -ENODEV;
11741173
1175
- return -EINVAL;
1174
+ switch (cmd) {
1175
+ case GPIO_V2_LINE_GET_VALUES_IOCTL:
1176
+ return linereq_get_values(lr, ip);
1177
+ case GPIO_V2_LINE_SET_VALUES_IOCTL:
1178
+ return linereq_set_values(lr, ip);
1179
+ case GPIO_V2_LINE_SET_CONFIG_IOCTL:
1180
+ return linereq_set_config(lr, ip);
1181
+ default:
1182
+ return -EINVAL;
1183
+ }
11761184 }
11771185
11781186 #ifdef CONFIG_COMPAT
....@@ -1188,6 +1196,9 @@
11881196 {
11891197 struct linereq *lr = file->private_data;
11901198 __poll_t events = 0;
1199
+
1200
+ if (!lr->gdev->chip)
1201
+ return EPOLLHUP | EPOLLERR;
11911202
11921203 poll_wait(file, &lr->wait, wait);
11931204
....@@ -1207,6 +1218,9 @@
12071218 struct gpio_v2_line_event le;
12081219 ssize_t bytes_read = 0;
12091220 int ret;
1221
+
1222
+ if (!lr->gdev->chip)
1223
+ return -ENODEV;
12101224
12111225 if (count < sizeof(le))
12121226 return -EINVAL;
....@@ -1473,6 +1487,9 @@
14731487 struct lineevent_state *le = file->private_data;
14741488 __poll_t events = 0;
14751489
1490
+ if (!le->gdev->chip)
1491
+ return EPOLLHUP | EPOLLERR;
1492
+
14761493 poll_wait(file, &le->wait, wait);
14771494
14781495 if (!kfifo_is_empty_spinlocked_noirqsave(&le->events, &le->wait.lock))
....@@ -1507,6 +1524,9 @@
15071524 ssize_t bytes_read = 0;
15081525 ssize_t ge_size;
15091526 int ret;
1527
+
1528
+ if (!le->gdev->chip)
1529
+ return -ENODEV;
15101530
15111531 /*
15121532 * When compatible system call is being used the struct gpioevent_data,
....@@ -1585,6 +1605,9 @@
15851605 struct lineevent_state *le = file->private_data;
15861606 void __user *ip = (void __user *)arg;
15871607 struct gpiohandle_data ghd;
1608
+
1609
+ if (!le->gdev->chip)
1610
+ return -ENODEV;
15881611
15891612 /*
15901613 * We can get the value for an event line but not set it,
....@@ -2095,28 +2118,30 @@
20952118 return -ENODEV;
20962119
20972120 /* Fill in the struct and pass to userspace */
2098
- if (cmd == GPIO_GET_CHIPINFO_IOCTL) {
2121
+ switch (cmd) {
2122
+ case GPIO_GET_CHIPINFO_IOCTL:
20992123 return chipinfo_get(cdev, ip);
21002124 #ifdef CONFIG_GPIO_CDEV_V1
2101
- } else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) {
2125
+ case GPIO_GET_LINEHANDLE_IOCTL:
21022126 return linehandle_create(gdev, ip);
2103
- } else if (cmd == GPIO_GET_LINEEVENT_IOCTL) {
2127
+ case GPIO_GET_LINEEVENT_IOCTL:
21042128 return lineevent_create(gdev, ip);
2105
- } else if (cmd == GPIO_GET_LINEINFO_IOCTL ||
2106
- cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) {
2107
- return lineinfo_get_v1(cdev, ip,
2108
- cmd == GPIO_GET_LINEINFO_WATCH_IOCTL);
2129
+ case GPIO_GET_LINEINFO_IOCTL:
2130
+ return lineinfo_get_v1(cdev, ip, false);
2131
+ case GPIO_GET_LINEINFO_WATCH_IOCTL:
2132
+ return lineinfo_get_v1(cdev, ip, true);
21092133 #endif /* CONFIG_GPIO_CDEV_V1 */
2110
- } else if (cmd == GPIO_V2_GET_LINEINFO_IOCTL ||
2111
- cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL) {
2112
- return lineinfo_get(cdev, ip,
2113
- cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL);
2114
- } else if (cmd == GPIO_V2_GET_LINE_IOCTL) {
2134
+ case GPIO_V2_GET_LINEINFO_IOCTL:
2135
+ return lineinfo_get(cdev, ip, false);
2136
+ case GPIO_V2_GET_LINEINFO_WATCH_IOCTL:
2137
+ return lineinfo_get(cdev, ip, true);
2138
+ case GPIO_V2_GET_LINE_IOCTL:
21152139 return linereq_create(gdev, ip);
2116
- } else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) {
2140
+ case GPIO_GET_LINEINFO_UNWATCH_IOCTL:
21172141 return lineinfo_unwatch(cdev, ip);
2142
+ default:
2143
+ return -EINVAL;
21182144 }
2119
- return -EINVAL;
21202145 }
21212146
21222147 #ifdef CONFIG_COMPAT
....@@ -2164,6 +2189,9 @@
21642189 struct gpio_chardev_data *cdev = file->private_data;
21652190 __poll_t events = 0;
21662191
2192
+ if (!cdev->gdev->chip)
2193
+ return EPOLLHUP | EPOLLERR;
2194
+
21672195 poll_wait(file, &cdev->wait, pollt);
21682196
21692197 if (!kfifo_is_empty_spinlocked_noirqsave(&cdev->events,
....@@ -2182,6 +2210,9 @@
21822210 int ret;
21832211 size_t event_size;
21842212
2213
+ if (!cdev->gdev->chip)
2214
+ return -ENODEV;
2215
+
21852216 #ifndef CONFIG_GPIO_CDEV_V1
21862217 event_size = sizeof(struct gpio_v2_line_info_changed);
21872218 if (count < event_size)