diff options
author | Bjørn Mork <bjorn@mork.no> | 2013-03-13 13:57:38 +0100 |
---|---|---|
committer | Bjørn Mork <bjorn@mork.no> | 2013-03-13 13:57:38 +0100 |
commit | 730ddba7219ed86e9d1037b2511a6323f73a283a (patch) | |
tree | 274a16efbb9cd7e4c2b6f0939ec79804b92e1bd0 /src | |
parent | 4d11edcf9b0cb2bd5d8b0d1ed5e44c9f8946d976 (diff) |
cuseqmi: stripping unnecessary code
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Diffstat (limited to 'src')
-rw-r--r-- | src/cuseqmi.c | 149 | ||||
-rw-r--r-- | src/fioc.h | 32 |
2 files changed, 12 insertions, 169 deletions
diff --git a/src/cuseqmi.c b/src/cuseqmi.c index a84267b..d6814c7 100644 --- a/src/cuseqmi.c +++ b/src/cuseqmi.c @@ -24,6 +24,16 @@ * Building it: * gcc -Wall `pkg-config fuse --cflags --libs` cuseqmi.c -o cuseqmi * + * + + +TODO: + +- allow specifying a single QMI device, automatically creating + the dummy usbX interface and /dev/qcqmiX +- open /dev/cdc-wdmY on startup, verify QMI, start reader thread +- demux all read data into a list of connected clients +- enforce the client registrations ioctls */ #define FUSE_USE_VERSION 29 @@ -37,8 +47,6 @@ #include <unistd.h> #include <errno.h> -#include "fioc.h" - static void *cuseqmi_buf; static size_t cuseqmi_size; @@ -52,33 +60,6 @@ static const char *usage = " --name=NAME|-n NAME device name (mandatory)\n" "\n"; -static int cuseqmi_resize(size_t new_size) -{ - void *new_buf; - - if (new_size == cuseqmi_size) - return 0; - - new_buf = realloc(cuseqmi_buf, new_size); - if (!new_buf && new_size) - return -ENOMEM; - - if (new_size > cuseqmi_size) - memset(new_buf + cuseqmi_size, 0, new_size - cuseqmi_size); - - cuseqmi_buf = new_buf; - cuseqmi_size = new_size; - - return 0; -} - -static int cuseqmi_expand(size_t new_size) -{ - if (new_size > cuseqmi_size) - return cuseqmi_resize(new_size); - return 0; -} - static void cuseqmi_open(fuse_req_t req, struct fuse_file_info *fi) { fuse_reply_open(req, fi); @@ -102,130 +83,24 @@ static void cuseqmi_write(fuse_req_t req, const char *buf, size_t size, { (void)fi; - if (cuseqmi_expand(off + size)) { - fuse_reply_err(req, ENOMEM); - return; - } - - memcpy(cuseqmi_buf + off, buf, size); fuse_reply_write(req, size); } -static void fioc_do_rw(fuse_req_t req, void *addr, const void *in_buf, - size_t in_bufsz, size_t out_bufsz, int is_read) -{ - const struct fioc_rw_arg *arg; - struct iovec in_iov[2], out_iov[3], iov[3]; - size_t cur_size; - - /* read in arg */ - in_iov[0].iov_base = addr; - in_iov[0].iov_len = sizeof(*arg); - if (!in_bufsz) { - fuse_reply_ioctl_retry(req, in_iov, 1, NULL, 0); - return; - } - arg = in_buf; - in_buf += sizeof(*arg); - in_bufsz -= sizeof(*arg); - - /* prepare size outputs */ - out_iov[0].iov_base = - addr + (unsigned long)&(((struct fioc_rw_arg *)0)->prev_size); - out_iov[0].iov_len = sizeof(arg->prev_size); - - out_iov[1].iov_base = - addr + (unsigned long)&(((struct fioc_rw_arg *)0)->new_size); - out_iov[1].iov_len = sizeof(arg->new_size); - - /* prepare client buf */ - if (is_read) { - out_iov[2].iov_base = arg->buf; - out_iov[2].iov_len = arg->size; - if (!out_bufsz) { - fuse_reply_ioctl_retry(req, in_iov, 1, out_iov, 3); - return; - } - } else { - in_iov[1].iov_base = arg->buf; - in_iov[1].iov_len = arg->size; - if (arg->size && !in_bufsz) { - fuse_reply_ioctl_retry(req, in_iov, 2, out_iov, 2); - return; - } - } - - /* we're all set */ - cur_size = cuseqmi_size; - iov[0].iov_base = &cur_size; - iov[0].iov_len = sizeof(cur_size); - - iov[1].iov_base = &cuseqmi_size; - iov[1].iov_len = sizeof(cuseqmi_size); - - if (is_read) { - size_t off = arg->offset; - size_t size = arg->size; - - if (off >= cuseqmi_size) - off = cuseqmi_size; - if (size > cuseqmi_size - off) - size = cuseqmi_size - off; - - iov[2].iov_base = cuseqmi_buf + off; - iov[2].iov_len = size; - fuse_reply_ioctl_iov(req, size, iov, 3); - } else { - if (cuseqmi_expand(arg->offset + in_bufsz)) { - fuse_reply_err(req, ENOMEM); - return; - } - - memcpy(cuseqmi_buf + arg->offset, in_buf, in_bufsz); - fuse_reply_ioctl_iov(req, in_bufsz, iov, 2); - } -} static void cuseqmi_ioctl(fuse_req_t req, int cmd, void *arg, struct fuse_file_info *fi, unsigned flags, const void *in_buf, size_t in_bufsz, size_t out_bufsz) { - int is_read = 0; - (void)fi; + fprintf(stderr, "%s: here\n", __func__); + if (flags & FUSE_IOCTL_COMPAT) { fuse_reply_err(req, ENOSYS); return; } switch (cmd) { - case FIOC_GET_SIZE: - if (!out_bufsz) { - struct iovec iov = { arg, sizeof(size_t) }; - - fuse_reply_ioctl_retry(req, NULL, 0, &iov, 1); - } else - fuse_reply_ioctl(req, 0, &cuseqmi_size, - sizeof(cuseqmi_size)); - break; - - case FIOC_SET_SIZE: - if (!in_bufsz) { - struct iovec iov = { arg, sizeof(size_t) }; - - fuse_reply_ioctl_retry(req, &iov, 1, NULL, 0); - } else { - cuseqmi_resize(*(size_t *)in_buf); - fuse_reply_ioctl(req, 0, NULL, 0); - } - break; - - case FIOC_READ: - is_read = 1; - case FIOC_WRITE: - fioc_do_rw(req, arg, in_buf, in_bufsz, out_bufsz, is_read); - break; default: fuse_reply_err(req, EINVAL); diff --git a/src/fioc.h b/src/fioc.h deleted file mode 100644 index ec1a39d..0000000 --- a/src/fioc.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - FUSE-ioctl: ioctl support for FUSE - Copyright (C) 2008 SUSE Linux Products GmbH - Copyright (C) 2008 Tejun Heo <teheo@suse.de> - - This program can be distributed under the terms of the GNU GPL. - See the file COPYING. -*/ - -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/ioctl.h> - -enum { - FIOC_GET_SIZE = _IOR('E', 0, size_t), - FIOC_SET_SIZE = _IOW('E', 1, size_t), - - /* - * The following two ioctls don't follow usual encoding rules - * and transfer variable amount of data. - */ - FIOC_READ = _IO('E', 2), - FIOC_WRITE = _IO('E', 3), -}; - -struct fioc_rw_arg { - off_t offset; - void *buf; - size_t size; - size_t prev_size; /* out param for previous total size */ - size_t new_size; /* out param for new total size */ -}; |