mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Lars-Peter Clausen <lars@metafoo.de>
To: Aniroop Mathur <aniroop.mathur@gmail.com>,
	"jic23@kernel.org" <jic23@kernel.org>
Cc: a.mathur@samsung.com, "cpgs ." <cpgs@samsung.com>,
	linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org,
	p.shailesh@samsung.com, r.mahale@samsung.com,
	vidushi.koul@samsung.com, narendra.m1@samsung.com
Subject: Re: [PATCH 1/1] IIO: Added write function in iio_buffer_fileops
Date: Wed, 13 Aug 2014 16:48:57 +0200	[thread overview]
Message-ID: <53EB7AD9.9010602@metafoo.de> (raw)
In-Reply-To: <CADYu309nTht96H077D6YGvhRYz6Xfux7Qri5Hi7dfgQMtOz-Pg@mail.gmail.com>

On 08/13/2014 03:42 PM, Aniroop Mathur wrote:
> On Wed, Aug 13, 2014 at 2:38 PM, Lars-Peter Clausen <lars@metafoo.de> wrote:
>> On 08/13/2014 08:29 AM, a.mathur@samsung.com wrote:
>>>
>>> From: Aniroop Mathur <a.mathur@samsung.com>
>>>
>>> Earlier, user space can only read from iio device node but cannot write to
>>> it.
>>> This patch adds write function in iio buffer file operations,
>>> which will allow user-space applications/HAL to write the data
>>> to iio device node.
>>> So now there will be two way communication between IIO subsystem
>>> and user space. (userspace <--> kernel)
>>>
>>> It can be used by HAL or any user-space application which wants to
>>> write data to iio device node/buffer upon receiving some data from it.
>>> As an example,
>>> It is useful for iio device simulator application which need to record
>>> the data by reading from iio device node and replay the recorded data
>>> by writing back to iio device node.
>>>
>>
>> I'm not convinced that this is something that should be added to the kernel.
>> I'm wondering why can't this be done in userspace, e.g. by having a
>> simulator mode for the application or by using LD_PRELOAD. Having this in
>> userspace will be much more flexible and will be easier to implement
>> correctly and you'll most likely want to simulate more than just buffer
>> access, for example setting/getting properties of the device or channel. For
>> the libiio[1] we are planning to implement a test backend that when
>> activated will allow to simulate a whole device rather than just buffer
>> support.
>>
>> [1] https://github.com/analogdevicesinc/libiio
>>
>>
>
> In normal Input Subsystem, there is two way communication between
> kernel and userpace. It has both read and write functionality. :)
> Why there is only one way communication in case of IIO ?

I've not seen a compelling reason yet why this must be implemented in kernel 
space. In my opinion, as outlined above, userspace if both easier and more 
flexible.

>
> For Input devices, I completed simulation just by reading and writing at
> input device node /dev/input/eventX.
> But for IIO devices, I am stuck as there is no write function available
> for iio device node /dev/iio:device0.
>
> As per my understanding, if we do the simulation in userspace
> then we need to create one more buffer in userpace. This will lead to
> extra memory usage. With write functionality in IIO just like
> in Input subsystem, we can avoid extra memory space. :)

No, you don't actually have to create a additional buffer. Just return the 
data that you'd otherwise have passed to write().

>
>>> Signed-off-by: Aniroop Mathur <a.mathur@samsung.com>
>>> ---
>>>    drivers/iio/iio_core.h            |    5 ++++-
>>>    drivers/iio/industrialio-buffer.c |   34
>>> ++++++++++++++++++++++++++++++++++
>>>    drivers/iio/industrialio-core.c   |    1 +
>>>    3 files changed, 39 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h
>>> index 5f0ea77..ba3fe53 100644
>>> --- a/drivers/iio/iio_core.h
>>> +++ b/drivers/iio/iio_core.h
>>> @@ -47,10 +47,12 @@ unsigned int iio_buffer_poll(struct file *filp,
>>>                               struct poll_table_struct *wait);
>>>    ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user
>>> *buf,
>>>                                        size_t n, loff_t *f_ps);
>>> -
>>> +ssize_t iio_buffer_write_first_n_outer(struct file *filp,
>>> +                            const char __user *buf, size_t n, loff_t
>>> *f_ps);
>>>
>>>    #define iio_buffer_poll_addr (&iio_buffer_poll)
>>>    #define iio_buffer_read_first_n_outer_addr
>>> (&iio_buffer_read_first_n_outer)
>>> +#define iio_buffer_write_first_n_outer_addr
>>> (&iio_buffer_write_first_n_outer)
>>>
>>>    void iio_disable_all_buffers(struct iio_dev *indio_dev);
>>>    void iio_buffer_wakeup_poll(struct iio_dev *indio_dev);
>>> @@ -59,6 +61,7 @@ void iio_buffer_wakeup_poll(struct iio_dev *indio_dev);
>>>
>>>    #define iio_buffer_poll_addr NULL
>>>    #define iio_buffer_read_first_n_outer_addr NULL
>>> +#define iio_buffer_write_first_n_outer_addr NULL
>>>
>>>    static inline void iio_disable_all_buffers(struct iio_dev *indio_dev) {}
>>>    static inline void iio_buffer_wakeup_poll(struct iio_dev *indio_dev) {}
>>> diff --git a/drivers/iio/industrialio-buffer.c
>>> b/drivers/iio/industrialio-buffer.c
>>> index 9f1a140..ef889af 100644
>>> --- a/drivers/iio/industrialio-buffer.c
>>> +++ b/drivers/iio/industrialio-buffer.c
>>> @@ -21,6 +21,7 @@
>>>    #include <linux/slab.h>
>>>    #include <linux/poll.h>
>>>    #include <linux/sched.h>
>>> +#include <asm/uaccess.h>
>>
>>
>> linux/uaccess.h
>>
>>
>>>
>>>    #include <linux/iio/iio.h>
>>>    #include "iio_core.h"
>>> @@ -87,6 +88,39 @@ ssize_t iio_buffer_read_first_n_outer(struct file
>>> *filp, char __user *buf,
>>>    }
>>>
>>>    /**
>>> + * iio_buffer_write_first_n_outer() - chrdev write to buffer
>>> + *
>>> + * This function pushes the user space data to kernel iio buffer
>>> + **/
>>> +ssize_t iio_buffer_write_first_n_outer(struct file *filp,
>>> +                               const char __user *buf, size_t n, loff_t
>>> *f_ps)
>>> +{
>>> +       struct iio_dev *indio_dev = filp->private_data;
>>> +       struct iio_buffer *rb = indio_dev->buffer;
>>> +       int ret = -1;
>>> +       unsigned char *data = NULL;
>>> +
>>> +       if (!indio_dev->info)
>>> +               return -ENODEV;
>>> +
>>> +       if (n != 1)
>>> +               return -EINVAL;
>>> +
>>> +       data = kzalloc(1, GFP_KERNEL);
>>> +       if (!data)
>>> +               return -ENOMEM;
>>> +
>>> +       if (copy_from_user(data, buf, 1)) {
>>> +               kfree(data);
>>> +               return -EFAULT;
>>> +       }
>>> +
>>> +       ret = iio_push_to_buffer(rb, data);
>>
>>
>> Are you sure that this works? iio_push_to_buffer() expects a data buffer of
>> size rb->bytes_per_datum bytes. On the other hand rb->bytes_per_datum is
>> only valid when the buffer is enabled, so for this to work the buffer would
>> need to be enabled. Which means you'd inject the fake data in the middle of
>> the real data stream.
>>
>>
>
> Yes, It works :)
> In one patch, bytes_per_datum has been removed from kifo_in.
> Patch - iio:kfifo_buf Take advantage of the fixed record size used in IIO
> commit c559afbfb08c7eac215ba417251225d3a8e01062
> - ret = kfifo_in(&kf->kf, data, r->bytes_per_datum);
> + ret = kfifo_in(&kf->kf, data, 1);
> So, I think we can now write only one byte of data.

No, we need to write 1 record and the size of one record is bytes_per_datum. 
If you only write one byte you'll cause a out of bounds access.

>
> Initially, I wrote the code for write functionality in kernel version 3.6
> using bytes_per_datum instead of fixed size of 1 byte.
> It worked fine. :)
> For this, we just need to replace size 1 by r->bytes_per_datum.
>
> We are not injecting data in middle of real data stream.
> When we inject the recorded data, we disabled the hardware chip,
> so no new/real data is pushed to the buffer during that time.
>
> To record, we enabled the buffer, read the real data and save it.
> To replay, we disabled the hardware chip and injected saved data by
> writing back to iio device node.
> So, Buffer is still enabled at time of writing to iio device node. :)

How do you disable the hardware without disabling the buffer?

- Lars

  reply	other threads:[~2014-08-13 14:49 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-13  6:29 a.mathur
2014-08-13  9:08 ` Lars-Peter Clausen
2014-08-13 13:42   ` Aniroop Mathur
2014-08-13 14:48     ` Lars-Peter Clausen [this message]
2014-08-13 16:33       ` Aniroop Mathur
2014-08-14  9:41         ` Lars-Peter Clausen
2014-08-14 14:38           ` Jonathan Cameron
2014-08-14 19:10             ` Aniroop Mathur
2014-08-18 15:29             ` Aniroop Mathur
2014-08-19 19:27               ` Jonathan Cameron
     [not found]             ` <CADYu308GLWp1u4XUYTm+W5mF3bCdfq=km8VgYBMN5xc2P3GDdQ@mail.gmail.com>
2014-08-22 18:28               ` Jonathan Cameron
2014-08-23 18:26                 ` Aniroop Mathur

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53EB7AD9.9010602@metafoo.de \
    --to=lars@metafoo.de \
    --cc=a.mathur@samsung.com \
    --cc=aniroop.mathur@gmail.com \
    --cc=cpgs@samsung.com \
    --cc=jic23@kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=narendra.m1@samsung.com \
    --cc=p.shailesh@samsung.com \
    --cc=r.mahale@samsung.com \
    --cc=vidushi.koul@samsung.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome