aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>2022-09-29 01:01:27 +0200
committerDenis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>2022-09-29 01:02:13 +0200
commitdebee03e694746e181edfa7bf516ad846aaf34bc (patch)
treeb749dd741c1570237d11d572d150c1e84565caf7
parent4ea49129f0236d38fc27a1eb9969beff6852f372 (diff)
downloadhardware_replicant_libsamsung-ipc-replicant-11.tar.gz
hardware_replicant_libsamsung-ipc-replicant-11.tar.bz2
hardware_replicant_libsamsung-ipc-replicant-11.zip
devices: generic: rewrite .poll() to workaround a libsamsung-ril bugreplicant-11-nlnet-eu-grant-825310-replicant-updatereplicant-11-testreplicant-11
The code is based on the xmm626_kernel_smdk4412_poll function with the ioctl code removed. Without this patch, libsamsung-ril fails to receive any data form the modem: eventfd_read returns (-?)EAGAIN and libsamsung-ril wrongly decides that this is an error. While this should be fixed in libsamsung-ril at some point, for now we workaround in order to have something that works with minimal changes needed. Once this works fine we could then cleanup the code and try to avoid regressions along the way. Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
-rw-r--r--samsung-ipc/devices/generic/generic.c70
1 files changed, 36 insertions, 34 deletions
diff --git a/samsung-ipc/devices/generic/generic.c b/samsung-ipc/devices/generic/generic.c
index ca5a295..f38a89d 100644
--- a/samsung-ipc/devices/generic/generic.c
+++ b/samsung-ipc/devices/generic/generic.c
@@ -652,52 +652,54 @@ int generic_poll(__attribute__((unused)) struct ipc_client *client,
__attribute__((unused)) struct timeval *timeout)
{
struct generic_transport_data *transport_data;
+ int fd;
+ fd_set set;
+ int fd_max;
+ unsigned int i;
+ unsigned int count;
int rc;
- struct pollfd fd;
-
- memset(&fd, 0, sizeof(fd));
-#if GENERIC_DEBUG
- ipc_client_log(client, "ENTER %s", __func__);
-#endif
if (data == NULL)
return -1;
transport_data = (struct generic_transport_data *) data;
+ fd = transport_data->fd;
- fd.fd = transport_data->fd;
- // fd.events = POLLRDNORM | POLLIN;
- fd.events = POLLIN;
+ if (fd < 0)
+ return -1;
+
+ FD_ZERO(&set);
+ FD_SET(fd, &set);
-//#if GENERIC_DEBUG
-// ipc_client_log(client, "%s: transport_data->fd: %d", __func__, transport_data->fd);
-//#endif
+ fd_max = fd;
- if (timeout == NULL) {
- rc = poll(&fd, 1, -1);
- ipc_client_log(client, "%s: poll(&fd, 1, -1); => %d", __func__, rc);
-
- } else {
- rc = poll(&fd, 1, (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000));
- ipc_client_log(
- client,
- "%s: poll(&fd, 1, %d); => %d", __func__,
- (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000),
- rc);
- }
- if (rc == -1) {
- rc = errno;
- ipc_client_log(client,
- "%s: poll failed with error %d: %s", __func__,
- rc, strerror(rc));
- return -1;
+ if (fds != NULL && fds->fds != NULL && fds->count > 0) {
+ for (i = 0; i < fds->count; i++) {
+ if (fds->fds[i] >= 0) {
+ FD_SET(fds->fds[i], &set);
+
+ if (fds->fds[i] > fd_max)
+ fd_max = fds->fds[i];
+ }
+ }
}
-#if GENERIC_DEBUG
- ipc_client_log(client, "%s: poll: %d", __func__, rc);
-#endif
+ rc = select(fd_max + 1, &set, NULL, NULL, timeout);
- return 0;
+ if (fds != NULL && fds->fds != NULL && fds->count > 0) {
+ count = fds->count;
+
+ for (i = 0; i < fds->count; i++) {
+ if (!FD_ISSET(fds->fds[i], &set)) {
+ fds->fds[i] = -1;
+ count--;
+ }
+ }
+
+ fds->count = count;
+ }
+
+ return rc;
}
int generic_smdk_poll(__attribute__((unused)) struct ipc_client *client,