0a2dbea03d
* Qualcomm MSM modem: 'rmtfs' support packages * qcom_rmtfs: Server that talks to modem over IPC to allow it read/write data for its persistent storage. This is needed for it to boot, as well as periodically during usage. Added a patch that it expects the storage path symlinks in /etc instead of /boot. * qrtr: IPC library for rmtfs * libqipcrtr4msmipc: adapter library to make qrtr work on kernels with AF_MSM_IPC support. AF_QIPCRTR is the mainline equivalent since Linux ~4.7. * msmipc-dev: Header files for qrtr and libqipcrtr4msmipc. Thanks to Bjorn Andersson <https://github.com/andersson> for rmtfs and qrtr. * libsmdpkt_wrapper: adapter lib for QMI clients The SMD serial packet driver in Qualcomm kernels has, AFAICT, a bug in poll(); this works around it so that qmicli et al can work. * i9195: firmware (modem only right now) * add ofono (with patch for MSM devices) Based on Alpine's package. * i9195: add modem support * move all modem related packages to aports/modem
186 lines
4.3 KiB
Diff
186 lines
4.3 KiB
Diff
From b98442bbfaa0b61963c23c6079055c94515e38dd Mon Sep 17 00:00:00 2001
|
|
From: Joey Hewitt <joey@joeyhewitt.com>
|
|
Date: Mon, 9 Oct 2017 21:41:43 -0700
|
|
Subject: [PATCH] add uio dev support
|
|
|
|
diff --git a/sharedmem.c b/sharedmem.c
|
|
index f788b8a..eead258 100644
|
|
--- a/sharedmem.c
|
|
+++ b/sharedmem.c
|
|
@@ -44,6 +44,37 @@ static int parse_hex_sysattr(struct udev_device *dev, const char *name,
|
|
return 0;
|
|
}
|
|
|
|
+static int parse_hex_sysfsfile(int dir_fd, const char *name,
|
|
+ unsigned long *value)
|
|
+{
|
|
+ unsigned long val;
|
|
+ char buf[32];
|
|
+ char *endptr;
|
|
+ int fd;
|
|
+
|
|
+ fd = openat(dir_fd, name, O_RDONLY);
|
|
+ if (fd < 0) {
|
|
+ return -errno;
|
|
+ }
|
|
+
|
|
+ if (read(fd, buf, sizeof(buf)) < 0) {
|
|
+ close(fd);
|
|
+ return -errno;
|
|
+ }
|
|
+
|
|
+ close(fd);
|
|
+
|
|
+ errno = 0;
|
|
+ val = strtoul(buf, &endptr, 16);
|
|
+ if ((val == LONG_MAX && errno == ERANGE) || endptr == buf) {
|
|
+ return -errno;
|
|
+ }
|
|
+
|
|
+ *value = val;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int rmtfs_mem_open_rfsa(struct rmtfs_mem *rmem, int client_id)
|
|
{
|
|
struct udev_device *dev;
|
|
@@ -114,6 +145,88 @@ err_close_fd:
|
|
return -saved_errno;
|
|
}
|
|
|
|
+static int rmtfs_mem_open_uio(struct rmtfs_mem *rmem)
|
|
+{
|
|
+ int saved_errno;
|
|
+ char path[64];
|
|
+ char buf[32];
|
|
+ int ret;
|
|
+ int dir_fd;
|
|
+ int fd;
|
|
+
|
|
+ for (int uio_index = 0; uio_index < 8; uio_index++) {
|
|
+ snprintf(path, sizeof(path), "/sys/class/uio/uio%d", uio_index);
|
|
+ dir_fd = open(path, O_DIRECTORY);
|
|
+ if (dir_fd < 0) {
|
|
+ saved_errno = errno;
|
|
+ if (errno != ENOENT) {
|
|
+ fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno));
|
|
+ }
|
|
+ goto ret;
|
|
+ }
|
|
+
|
|
+ fd = openat(dir_fd, "name", O_RDONLY);
|
|
+ if (fd < 0) {
|
|
+ saved_errno = errno;
|
|
+ fprintf(stderr, "failed to open %s/name: %s\n", path, strerror(errno));
|
|
+ goto close_dirfd;
|
|
+ }
|
|
+
|
|
+ if (read(fd, buf, sizeof(buf)) < 0) {
|
|
+ saved_errno = errno;
|
|
+ fprintf(stderr, "failed to read %s/name: %s\n", path, strerror(errno));
|
|
+ close(fd);
|
|
+ goto close_dirfd;
|
|
+ }
|
|
+
|
|
+ close(fd);
|
|
+
|
|
+ if (strncmp(buf, "rmtfs\n", 6)) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ ret = parse_hex_sysfsfile(dir_fd, "maps/map0/addr", &rmem->address);
|
|
+ if (ret < 0) {
|
|
+ fprintf(stderr, "failed to parse addr of %s\n", path);
|
|
+ saved_errno = -ret;
|
|
+ goto close_dirfd;
|
|
+ }
|
|
+
|
|
+ ret = parse_hex_sysfsfile(dir_fd, "maps/map0/size", &rmem->size);
|
|
+ if (ret < 0) {
|
|
+ fprintf(stderr, "failed to parse size of %s\n", path);
|
|
+ saved_errno = -ret;
|
|
+ goto close_dirfd;
|
|
+ }
|
|
+
|
|
+ snprintf(path, sizeof(path), "/dev/uio%d", uio_index);
|
|
+ rmem->fd = open(path, O_RDWR);
|
|
+ if (rmem->fd < 0) {
|
|
+ saved_errno = errno;
|
|
+ fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno));
|
|
+ goto close_dirfd;
|
|
+ }
|
|
+
|
|
+ rmem->base = mmap(0, rmem->size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
|
+ if (rmem->base == MAP_FAILED) {
|
|
+ saved_errno = errno;
|
|
+ fprintf(stderr, "failed to mmap: %s\n", strerror(errno));
|
|
+ close(rmem->fd);
|
|
+ goto close_dirfd;
|
|
+ }
|
|
+
|
|
+ saved_errno = 0;
|
|
+ goto close_dirfd;
|
|
+ }
|
|
+
|
|
+ saved_errno = ENOENT;
|
|
+
|
|
+close_dirfd:
|
|
+ close(dir_fd);
|
|
+ret:
|
|
+ return -saved_errno;
|
|
+}
|
|
+
|
|
struct rmtfs_mem *rmtfs_mem_open(void)
|
|
{
|
|
struct rmtfs_mem *rmem;
|
|
@@ -131,26 +244,31 @@ struct rmtfs_mem *rmtfs_mem_open(void)
|
|
if (ret < 0 && ret != -ENOENT) {
|
|
goto err;
|
|
} else if (ret < 0) {
|
|
- fprintf(stderr, "falling back to /dev/mem access\n");
|
|
-
|
|
- ret = rmtfs_mem_enumerate(rmem);
|
|
- if (ret < 0)
|
|
- goto err;
|
|
-
|
|
- fd = open("/dev/mem", O_RDWR|O_SYNC);
|
|
- if (fd < 0) {
|
|
- fprintf(stderr, "failed to open /dev/mem\n");
|
|
+ ret = rmtfs_mem_open_uio(rmem);
|
|
+ if (ret < 0 && ret != -ENOENT) {
|
|
goto err;
|
|
+ } else if (ret < 0) {
|
|
+ fprintf(stderr, "falling back to /dev/mem access\n");
|
|
+
|
|
+ ret = rmtfs_mem_enumerate(rmem);
|
|
+ if (ret < 0)
|
|
+ goto err;
|
|
+
|
|
+ fd = open("/dev/mem", O_RDWR|O_SYNC);
|
|
+ if (fd < 0) {
|
|
+ fprintf(stderr, "failed to open /dev/mem\n");
|
|
+ goto err;
|
|
+ }
|
|
+
|
|
+ base = mmap(0, rmem->size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, rmem->address);
|
|
+ if (base == MAP_FAILED) {
|
|
+ fprintf(stderr, "failed to mmap: %s\n", strerror(errno));
|
|
+ goto err_close_fd;
|
|
+ }
|
|
+
|
|
+ rmem->base = base;
|
|
+ rmem->fd = fd;
|
|
}
|
|
-
|
|
- base = mmap(0, rmem->size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, rmem->address);
|
|
- if (base == MAP_FAILED) {
|
|
- fprintf(stderr, "failed to mmap: %s\n", strerror(errno));
|
|
- goto err_close_fd;
|
|
- }
|
|
-
|
|
- rmem->base = base;
|
|
- rmem->fd = fd;
|
|
}
|
|
|
|
return rmem;
|