diff options
author | Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> | 2022-09-29 01:01:27 +0200 |
---|---|---|
committer | Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org> | 2022-09-29 01:02:13 +0200 |
commit | debee03e694746e181edfa7bf516ad846aaf34bc (patch) | |
tree | b749dd741c1570237d11d572d150c1e84565caf7 | |
parent | 4ea49129f0236d38fc27a1eb9969beff6852f372 (diff) | |
download | hardware_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.c | 70 |
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, |