pmaports/modem/qcom_rmtfs/support-uio.patch
Joey Hewitt 0a2dbea03d i9195/Qualcomm modem support (#1314)
* 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
2018-03-11 15:59:09 +00:00

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;