On Wed, Nov 22, 2023 at 5:58 AM Raag Jadav <raag.jadav@xxxxxxxxx> wrote: > > On Tue, Nov 21, 2023 at 08:25:20PM +0100, Rafael J. Wysocki wrote: > > On Tue, Nov 21, 2023 at 11:38 AM Raag Jadav <raag.jadav@xxxxxxxxx> wrote: > > > > > > According to ACPI specification, a _UID object can evaluate to either > > > a numeric value or a string. Update acpi_dev_uid_match() helper to > > > support _UID matching for both integer and string types. > > > > > > Suggested-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> > > > Suggested-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx> > > > Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > > > > You need to be careful with using this. There are some things below > > that go beyond what I have suggested. > > I think we all suggested some bits and pieces so I included everyone. > We can drop if there are any objections. There are, from me and from Andy. [cut] > > Up to this point it is all fine IMV. > > > > > +/** > > > + * acpi_dev_uid_match - Match device by supplied UID > > > + * @adev: ACPI device to match. > > > + * @uid2: Unique ID of the device. > > > + * > > > + * Matches UID in @adev with given @uid2. > > > + * > > > + * Returns: %true if matches, %false otherwise. > > > + */ > > > + > > > +/* Treat uid as a string for array and pointer types, treat as an integer otherwise */ > > > +#define get_uid_type(x) \ > > > + (__builtin_choose_expr(is_array_or_pointer_type(x), (const char *)0, (u64)0)) > > > > But I wouldn't use the above. > > > > It is far more elaborate than needed for this use case and may not > > actually work as expected. For instance, why would a pointer to a > > random struct type be a good candidate for a string? > > Such case will not compile, since its data type will not match with > acpi_str_uid_match() prototype. The compiler does a very good job of > qualifing only the compatible string types here, which is exactly what > we want. > > error: passing argument 2 of 'acpi_str_uid_match' from incompatible pointer type [-Werror=incompatible-pointer-types] > if (acpi_dev_uid_match(adev, adev)) { > ^ > ./include/acpi/acpi_bus.h:870:20: note: expected 'const char *' but argument is of type 'struct acpi_device *' > static inline bool acpi_str_uid_match(struct acpi_device *adev, const char *uid2) You are right, it won't compile, but that's not my point. Why would it be matched with acpi_str_uid_match() in the first place? > > > + > > > +#define acpi_dev_uid_match(adev, uid2) \ > > > + _Generic(get_uid_type(uid2), \ > > > + const char *: acpi_str_uid_match, \ > > > + u64: acpi_int_uid_match)(adev, uid2) > > > + > > > > Personally, I would just do something like the following > > > > #define acpi_dev_uid_match(adev, uid2) \ > > _Generic((uid2), \ > > const char *: acpi_str_uid_match, \ > > char *: acpi_str_uid_match, \ > > const void *: acpi_str_uid_match, \ > > void *: acpi_str_uid_match, \ > > default: acpi_int_uid_match)(adev, uid2) > > > > which doesn't require compiler.h to be fiddled with and is rather > > straightforward to follow. > > > > If I'm to apply the patches, this is about the level of complexity you > > need to target. > > Understood, however this will limit the type support to only a handful > of types, Indeed. > and will not satisfy a few of the existing users, which, for > example are passing signed or unsigned pointer or an array of u8. Fair enough, so those types would need to be added to the list. > Listing every possible type manually for _Generic() looks a bit verbose > for something that can be simply achieved by __builtin functions in my > opinion. But then you don't even need _Generic(), do you? Wouldn't something like the below work? #define acpi_dev_uid_match(adev, uid2) \ (__builtin_choose_expr(is_array_or_pointer_type((uid2)),acpi_str_uid_match(adev, uid2), acpi_int_uid_match(adev, uid2)) In any case, I'm not particularly convinced about the is_array_or_pointer_type() thing and so I'm not going to apply the series as is.