All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Stodden <daniel.stodden@gmail.com>
To: Wolfram Sang <wsa@kernel.org>
Cc: linux-i2c@vger.kernel.org, jdelvare@suse.de
Subject: Re: [RFC PATCH] i2c: Support Smbus 3.0 block sizes up to 255 bytes.
Date: Tue, 28 Jul 2020 04:27:30 -0700	[thread overview]
Message-ID: <5AA89168-FF62-4269-912B-A669664F60B9@gmail.com> (raw)
In-Reply-To: <20200728103609.GB980@ninjato>



> On Jul 28, 2020, at 3:36 AM, Wolfram Sang <wsa@kernel.org> wrote:
> 
> 
>>> I thought about this, too, and wondered if this isn't a size regression
>>> in userspace with every i2c_smbus_data getting 8 times the size? But
>>> maybe it is worth if backwards compatibility is maintained in an
>>> otherwise not so intrusive manner? Jean, what do you think?
>> 
>> Yep, exactly. It just made for a nice drop-in replacement for me to
>> focus on i2c-dev.c first.
>> 
>> A lot of clients will stack-allocate these. I suppose i2-tools doesn’t
>> load more than one at a time, but haven’t looked.
> 
> I just checked all in-kernel users and i2c-tools. Never more than one.
> Which is kind of expected because you usually re-use i2c_smbus_data and
> move the buffer contents somewhere else.
> 
>> Retrospectively
>> - i2c_smbus_ioctl_data.data shouldn’t have been a pointer type, but is.
>> - i2c_smbus_data.block should have been pointer, but isn’t
>> 
>> And then the kernel would pass around an 32-bit-only i2c_smbus_data union -- by value.
>> Which would have been much leaner, and leave the right buffer choice
>> entirely to the client.
>> 
>> One could explore this in kernel space. Let me know how you’d like to experiment.
> 
> ? I'd like to keep kernel space and user space in sync. Why should we
> have a different i2c_smbus_data-variant in the kernel space? Or did I
> get you wrong.
> 
>> But in userspace that means we’re looking at a new call number. >:)
> 
> No way! :)

Here’s about what I meant.

Ok, it doesn’t really need a new call slot. Although, when
integrating into the original i2c_smbus_data and I2C_SMBUS, I’m not sure how
confusing this gets, to a casual reader not familiar with the history.

Daniel

diff --git a/include/uapi/linux/i2c-dev.h b/include/uapi/linux/i2c-dev.h
index 85f8047afcf2..38b1ae4d2448 100644
--- a/include/uapi/linux/i2c-dev.h
+++ b/include/uapi/linux/i2c-dev.h
@@ -58,7 +58,10 @@ struct i2c_smbus_ioctl_data {
        __u8 read_write;
        __u8 command;
        __u32 size;
-       union i2c_smbus_data __user *data;
+       union {
+               union i2c_smbus_data __user *data;
+               union i2c_smbus3_data __user u;
+       };
 };

 /* This is the structure as used in the I2C_RDWR ioctl call */
diff --git a/include/uapi/linux/i2c.h b/include/uapi/linux/i2c.h
index f71a1751cacf..87ec2ea321ce 100644
--- a/include/uapi/linux/i2c.h
+++ b/include/uapi/linux/i2c.h
@@ -131,7 +131,9 @@ struct i2c_msg {
 /*
  * Data for SMBus Messages
  */
-#define I2C_SMBUS_BLOCK_MAX    32      /* As specified in SMBus standard */
+#define I2C_SMBUS_BLOCK_MAX    32      /* As specified in SMBus standard <= 3.0 */
+#define I2C_SMBUS3_BLOCK_MAX   255     /* As specified in SMBus 3.0 */
+
 union i2c_smbus_data {
        __u8 byte;
        __u16 word;
@@ -139,20 +141,36 @@ union i2c_smbus_data {
                               /* and one more for user-space compatibility */
 };

+typedef __u8 i2c_smbus_block[I2C_SMBUS_BLOCK_MAX + 2];
+typedef __u8 i2c_smbus3_block[I2C_SMBUS3_BLOCK_MAX + 2];
+
+union i2c_smbus3_data {
+       __u8 byte;
+       __u16 word;
+       i2c_smbus_block *block32;
+       i2c_smbus3_block *block255;
+};
+
 /* i2c_smbus_xfer read or write markers */
 #define I2C_SMBUS_READ 1
 #define I2C_SMBUS_WRITE        0

 /* SMBus transaction types (size parameter in the above functions)
    Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
+
+#define I2C_SMBUS3_BLOCK 0x10
+
 #define I2C_SMBUS_QUICK                    0
 #define I2C_SMBUS_BYTE             1
 #define I2C_SMBUS_BYTE_DATA        2
 #define I2C_SMBUS_WORD_DATA        3
 #define I2C_SMBUS_PROC_CALL        4
 #define I2C_SMBUS_BLOCK_DATA       5
+#define I2C_SMBUS3_BLOCK_DATA      (5|I2C_SMBUS3_BLOCK)
 #define I2C_SMBUS_I2C_BLOCK_BROKEN  6
 #define I2C_SMBUS_BLOCK_PROC_CALL   7          /* SMBus 2.0 */
+#define I2C_SMBUS3_BLOCK_PROC_CALL  (7|I2C_SMBUS3_BLOCK)
 #define I2C_SMBUS_I2C_BLOCK_DATA    8
+#define I2C_SMBUS3_I2C_BLOCK_DATA   (8|I2C_SMBUS3_BLOCK)

 #endif /* _UAPI_LINUX_I2C_H */

— snip —

So:

 - ioctl_data.data would be inline. No more extra pointer derefs
   just to pass a .byte or .word

 - Likewise, kernel code gets to pass a leaner

       i2c_smbus_xfer( .., union i2c_smbus3_data data) {} etc.

   Note the lack of ‘*’ in ‘data’.

 - All clients get to choose between i2c_smbus_block or i2c_smbus3_block,
   depending on slave specs.

 - Similarly, code concerned about (stack) memory gets to pick 
   size = I2C_SMBUS_BLOCK_x vs I2C_SMBUS3_BLOCK_x.
   So we’d keep the old names in place, too.

 - But suffers terrible consequences when mixing I2C_SMBUS3_ transfers
   with i2c_smbus_data buffers.

   Really worth it? Sincerely, if 220-ish extra bytes aren’t
   a big deal, let’s step back and admit it adds not enough value.

 - Above won’t build yet, unless we’re okay with linux/i2c-dev.h 
   including linux/i2c.h.

Hth,
Daniel



  reply	other threads:[~2020-07-28 11:27 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-28  0:47 [RFC PATCH] i2c: Support Smbus 3.0 block sizes up to 255 bytes daniel.stodden
2020-07-28  9:40 ` Wolfram Sang
2020-07-28 10:18   ` Daniel Stodden
2020-07-28 10:36     ` Wolfram Sang
2020-07-28 11:27       ` Daniel Stodden [this message]
2020-07-28 17:04   ` Jean Delvare
2020-07-28 21:16     ` Daniel Stodden
2020-07-29 10:51       ` Wolfram Sang
2020-07-28 11:16 ` Wolfram Sang
2020-07-28 11:40   ` Daniel Stodden
2020-07-28 12:46     ` Daniel Stodden

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=5AA89168-FF62-4269-912B-A669664F60B9@gmail.com \
    --to=daniel.stodden@gmail.com \
    --cc=jdelvare@suse.de \
    --cc=linux-i2c@vger.kernel.org \
    --cc=wsa@kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.