From: Jean Delvare <jdelvare@suse.de>
To: "Pali Rohár" <pali@kernel.org>
Cc: Heiner Kallweit <hkallweit1@gmail.com>, linux-i2c@vger.kernel.org
Subject: Re: [PATCH 05/10] i2c: i801: Improve is_dell_system_with_lis3lv02d
Date: Fri, 6 Aug 2021 11:55:19 +0200 [thread overview]
Message-ID: <20210806115519.3d9c58cf@endymion> (raw)
In-Reply-To: <20210805230818.mmgybd4ybr2savyk@pali>
Hi Pali, Heiner,
On Fri, 6 Aug 2021 01:08:18 +0200, Pali Rohár wrote:
> On Thursday 05 August 2021 21:42:23 Heiner Kallweit wrote:
> > On 05.08.2021 21:11, Pali Rohár wrote:
> > > On Thursday 05 August 2021 11:51:56 Jean Delvare wrote:
> > >> On Sun, 01 Aug 2021 16:20:19 +0200, Heiner Kallweit wrote:
> > >>> Replace the ugly cast of the return_value pointer with proper usage.
> > >>> In addition use dmi_match() instead of open-coding it.
> > >>
> > >> Pali, would you be able to test this patch?
> > >
> > > Tested now on Latitude E6440 and patch is working fine (no difference).
Thank you for joining the discussion and testing.
> > >>> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
> > >>> ---
> > >>> drivers/i2c/busses/i2c-i801.c | 13 ++++---------
> > >>> 1 file changed, 4 insertions(+), 9 deletions(-)
> > >>>
> > >>> diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
> > >>> index d971ee20c..a6287c520 100644
> > >>> --- a/drivers/i2c/busses/i2c-i801.c
> > >>> +++ b/drivers/i2c/busses/i2c-i801.c
> > >>> @@ -1191,7 +1191,7 @@ static acpi_status check_acpi_smo88xx_device(acpi_handle obj_handle,
> > >>>
> > >>> kfree(info);
> > >>>
> > >>> - *((bool *)return_value) = true;
> > >>> + *return_value = obj_handle;
> > >
> > > You are missing a cast here. "obj_handle" is of unknown typedef type
> > > acpi_handle and *return_value is of type void*. So this can generate a
> > > compile warning (either now or in future).
> >
> > acpi_handle is defined as: typedef void *acpi_handle;
> > Therefore compiler is happy (as long as acpi_handle is any pointer type).
>
> But point of this typedefing is to hide real type and let user to use
> this "unknown" type without excepting any specific type.
>
> "Therefore compiler is happy" here is there just a "hack" which
> currently mute casting warning. But I think it is not something which
> should be used as it is against how API / code of specific function was
> designed.
But you can't respect that "unknown type" and still code cleanly. The
definition of acpi_handle hides the fact that this is a pointer type.
And you can't code cleanly if you need to manipulate an "object" but
have no idea whether it's a pointer, a scalar value or a structure.
(Well, you *could* with an API which does all the manipulation for you.
But that's not what we have here.)
In my opinion, the only value of "acpi_handle" as it is currently
defined is to let people know what type of data is found behind that
pointer. But I would much prefer real structure and an explicit pointer
to it.
> For me this situation looks like: Somebody created API and specified how
> to use it. It was realized that specified usage is not ideal for some
> operations. And then people started "hacking" this API to look better
> in these special cases.
>
> But solution for this issue is to fix API (or create a new API which
> better for this purpose), not hacking or workarounding it to looks
> better by hiding / workarounding other important details.
The practical issue here is that we are talking about ACPICA, which is
partly developed outside / independently of the rest of the kernel. If
you can convince the ACPICA developers to implement a better
alternative to acpi_get_devices(), and/or make acpi_handle a better
type, I'll be more than happy to use that in the i2c-i801 driver. But I
don't see that happening any time soon, if ever, and for the time
being, we have to live with the poor API we are given.
> > > So you need to write it something like this:
> > >
> > > *((acpi_handle *)return_value) = obj_handle;
> > >
> > > But what is benefit of this change? Is not usage of explicit true and
> > > false values better than some acpi_handle type of undefined value stored
> > > in obj_handle?
> >
> > From a logical perspective I agree. My motivation is that I see explicit
> > casts as a last resort and try to avoid them as far as possible.
I tend to agree with that, FWIW.
> But in this case you really should not avoid casting. It is different
> pointer type of unknown (or rather hidden) type. Currently it does not
> throw warning (maybe because compiler is not smart enough). But it does
> not mean that code is really semantically correct or that in future
> compiler (or its new version) does not throw warning.
It's not about the smartness of the compiler. acpi_handle is equal to
void *, and Heiner's code is perfectly valid for a void *. No cast
needed with any compiler or on any platform.
Of course, things would break if the definition of acpi_handle ever
changes. Which would be great new actually, as I wrote above. And we
can revisit the code then.
> Syntactically code looks better, but only until reader start studding
> what code is really doing.
I have to admit I got pretty confused when reading it at first. On the
other hand, I was equally confused by the code that it attempts to
replace ^^
> > The current code abuses a void* variable to store a bool. This makes the
> > implicit assumption that a pointer variable is always big enough to
> > store a bool.
>
> I understand your concerns and also your motivation. API is not ideal
> for usage. But both current and your proposed solution is just a hack to
> workaround this API usage.
>
> I think that according to C standard it is possible to cast between
> pointer and non-pointer (integer-like) types only via uintptr_t (or
> intptr_t) type...
>
> So compliant C code could look like this?
>
> void func(void **ret) {
> *ret = (void *)(uintptr_t)1;
> }
>
> bool test(void) {
> void *found = (uintptr_t)0;
> func(&found);
> return (uintptr_t)found;
> }
>
> or test() function may be simplified:
>
> bool test(void) {
> void *found = NULL;
> func(&found);
> return found;
> }
>
> (but for me it looks strange if I'm reading _word_ NULL when used as a
> false value in 2-state logic variable)
I don't like this and I'm not even sure if that is allowed in the kernel.
> > With regard to "acpi_handle of undefined value": I'm just interested
> > in the information whether handle is NULL or not. That's the normal
> > implicit cast to bool like in every if(pointer) clause.
>
> Yes, of course, this is fully valid.
> (...)
> > > Anyway, it looks strange to use name "found" for object handle
> > > variable. I would expect that something named "found" is storing
> > > something which refers to 2-state logic and not some handle value.
It's actually a rather common pattern for lookup functions, returning
NULL when the expected item wasn't found, or a pointer to the item if
found. What makes things a bit weird here is that we don't actually
care about acpi_handle. All we need is a pointer to pretty much
anything, to differentiate between the found and not found cases.
Therefore I would propose the following alternative:
--- linux-5.13.orig/drivers/i2c/busses/i2c-i801.c 2021-08-06 11:11:44.275200299 +0200
+++ linux-5.13/drivers/i2c/busses/i2c-i801.c 2021-08-06 11:18:19.847469822 +0200
@@ -1194,7 +1194,7 @@ static acpi_status check_acpi_smo88xx_de
kfree(info);
- *((bool *)return_value) = true;
+ *return_value = hid; /* Could be any address, used as true value */
return AE_CTRL_TERMINATE;
smo88xx_not_found:
@@ -1204,13 +1204,10 @@ static acpi_status check_acpi_smo88xx_de
static bool is_dell_system_with_lis3lv02d(void)
{
- bool found;
- const char *vendor;
+ acpi_handle found = NULL;
- vendor = dmi_get_system_info(DMI_SYS_VENDOR);
- if (!vendor || strcmp(vendor, "Dell Inc."))
+ if (!dmi_match(DMI_SYS_VENDOR, "Dell Inc."))
return false;
-
/*
* Check that ACPI device SMO88xx is present and is functioning.
* Function acpi_get_devices() already filters all ACPI devices
@@ -1219,9 +1216,7 @@ static bool is_dell_system_with_lis3lv02
* accelerometer but unfortunately ACPI does not provide any other
* information (like I2C address).
*/
- found = false;
- acpi_get_devices(NULL, check_acpi_smo88xx_device, NULL,
- (void **)&found);
+ acpi_get_devices(NULL, check_acpi_smo88xx_device, NULL, &found);
return found;
}
Basically, it's Heiner's patch except for one line, the idea is to
return the HID string pointer (which has type char *) instead of the
acpi_handle. That way we don't depend on an opaque ACPI type. (I first
tried with the matching acpi_smo8800_ids entry but compiler complained
about incompatible pointer types due to the const).
Actually, I think we could use pretty much ANY pointer. Heck, that
would work too:
*return_value = &disable_features; /* Could be any address, used as true value */
Would be kinda confusing, but the comment is supposed to address that.
In fact we could even do:
*return_value = &i; /* Could be any address, used as true value */
That's the address of a local variable on the stack, which will no
longer exist by the time we check it, but that's still a non-NULL
pointer so it would work :-D Seriously, let's not do that, simply
because static code analyzers would possibly complain.
--
Jean Delvare
SUSE L3 Support
next prev parent reply other threads:[~2021-08-06 9:55 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-01 14:15 [PATCH 00/10] i2c: i801: Series with improvements Heiner Kallweit
2021-08-01 14:16 ` [PATCH 01/10] i2c: i801: Don't call pm_runtime_allow Heiner Kallweit
2021-08-02 12:53 ` Jean Delvare
2021-08-02 16:31 ` Heiner Kallweit
2021-08-04 13:36 ` Jarkko Nikula
2021-08-04 14:06 ` Rafael J. Wysocki
2021-08-04 19:02 ` Heiner Kallweit
2021-08-05 8:31 ` Jean Delvare
2021-08-06 14:11 ` Rafael J. Wysocki
2021-08-06 13:52 ` Rafael J. Wysocki
2021-08-06 18:34 ` Heiner Kallweit
2021-08-01 14:17 ` [PATCH 02/10] i2c: i801: Improve disabling runtime pm Heiner Kallweit
2021-08-05 8:39 ` Jean Delvare
2021-08-01 14:18 ` [PATCH 03/10] i2c: i801: Make p2sb_spinlock a mutex Heiner Kallweit
2021-08-05 8:49 ` Jean Delvare
2021-08-05 12:19 ` Mika Westerberg
2021-08-01 14:19 ` [PATCH 04/10] i2c: i801: Remove not needed debug message Heiner Kallweit
2021-08-05 8:53 ` Jean Delvare
2021-08-01 14:20 ` [PATCH 05/10] i2c: i801: Improve is_dell_system_with_lis3lv02d Heiner Kallweit
2021-08-05 9:51 ` Jean Delvare
2021-08-05 19:11 ` Pali Rohár
2021-08-05 19:42 ` Heiner Kallweit
2021-08-05 23:08 ` Pali Rohár
2021-08-06 9:55 ` Jean Delvare [this message]
2021-08-06 10:47 ` Pali Rohár
2021-08-06 11:26 ` Jean Delvare
2021-08-01 14:21 ` [PATCH 06/10] i2c: i801: Remove not needed check for PCI_COMMAND_INTX_DISABLE Heiner Kallweit
2021-08-05 10:41 ` Jean Delvare
2021-08-05 20:04 ` Heiner Kallweit
2021-08-06 8:46 ` Jean Delvare
2021-08-01 14:21 ` [PATCH 07/10] i2c: i801: Improve i801_acpi_probe/remove functions Heiner Kallweit
2021-08-05 13:38 ` Jean Delvare
2021-08-05 14:24 ` Mika Westerberg
2021-08-01 14:22 ` [PATCH 08/10] i2c: i801: Improve i801_add_mux Heiner Kallweit
2021-08-05 13:43 ` Jean Delvare
2021-08-01 14:23 ` [PATCH 09/10] i2c: i801: Improve register_dell_lis3lv02d_i2c_device Heiner Kallweit
2021-08-05 14:23 ` Jean Delvare
2021-08-06 20:49 ` Heiner Kallweit
2021-08-09 13:33 ` Jean Delvare
2021-08-09 19:11 ` Heiner Kallweit
2021-08-01 14:24 ` [PATCH 10/10] i2c: i801: Improve handling platform data for tco device Heiner Kallweit
2021-08-05 18:32 ` Jean Delvare
2021-08-05 19:44 ` Heiner Kallweit
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=20210806115519.3d9c58cf@endymion \
--to=jdelvare@suse.de \
--cc=hkallweit1@gmail.com \
--cc=linux-i2c@vger.kernel.org \
--cc=pali@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox