lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <YgOecxgyaMN+/3sN@kuha.fi.intel.com>
Date:   Wed, 9 Feb 2022 12:58:59 +0200
From:   Heikki Krogerus <heikki.krogerus@...ux.intel.com>
To:     Samuel Holland <samuel@...lland.org>
Cc:     Guenter Roeck <linux@...ck-us.net>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        Rob Herring <robh+dt@...nel.org>, devicetree@...r.kernel.org,
        linux-usb@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v2 3/4] usb: typec: Factor out non-PD fwnode properties

Hi,

On Wed, Feb 02, 2022 at 04:19:46PM -0600, Samuel Holland wrote:
> Basic programmable non-PD Type-C port controllers do not need the full
> TCPM library, but they share the same devicetree binding and the same
> typec_capability structure. Factor out a helper for parsing those
> properties which map to fields in struct typec_capability, so the code
> can be shared between TCPM and basic non-TCPM drivers.
> 
> Signed-off-by: Samuel Holland <samuel@...lland.org>
> ---
> 
> Changes in v2:
>  - Always put the return values from typec_find_* in a signed variable
>    for error checking.
> 
>  drivers/usb/typec/class.c     | 52 +++++++++++++++++++++++++++++++++++
>  drivers/usb/typec/tcpm/tcpm.c | 32 +--------------------
>  include/linux/usb/typec.h     |  3 ++
>  3 files changed, 56 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
> index 45a6f0c807cb..b67ba9478c82 100644
> --- a/drivers/usb/typec/class.c
> +++ b/drivers/usb/typec/class.c
> @@ -1894,6 +1894,58 @@ void *typec_get_drvdata(struct typec_port *port)
>  }
>  EXPORT_SYMBOL_GPL(typec_get_drvdata);
>  
> +int typec_get_fw_cap(struct typec_capability *cap,
> +		     struct fwnode_handle *fwnode)
> +{
> +	const char *cap_str;
> +	int ret;
> +
> +	/*
> +	 * This fwnode has a "compatible" property, but is never populated as a
> +	 * struct device. Instead we simply parse it to read the properties.
> +	 * This it breaks fw_devlink=on. To maintain backward compatibility
> +	 * with existing DT files, we work around this by deleting any
> +	 * fwnode_links to/from this fwnode.
> +	 */
> +	fw_devlink_purge_absent_suppliers(fwnode);

Let's not put that call here. That function is broken. I think it in
practice assumes that there can only be one device linked to fwnode,
but that's not true. The fwnodes can be, and are, shared. So by using
it we may end up doing things to some completely wrong devices.

So let's keep that call in the drivers that really have to have it for
now. I think that function - fw_devlink_purge_absent_suppliers() -
needs some serious rethinking.

There is some deeper problem. I have a feeling that all the functions
that rely on the fwnode->dev member are broken. We need a proper
reverce search mechanism that can be used to find the devices linked
to fwnodes. But I have no idea how to that could be done.

> +	cap->fwnode = fwnode;
> +
> +	ret = fwnode_property_read_string(fwnode, "power-role", &cap_str);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = typec_find_port_power_role(cap_str);
> +	if (ret < 0)
> +		return ret;
> +	cap->type = ret;
> +
> +	/* USB data support is optional */
> +	ret = fwnode_property_read_string(fwnode, "data-role", &cap_str);
> +	if (ret == 0) {
> +		ret = typec_find_port_data_role(cap_str);
> +		if (ret < 0)
> +			return ret;
> +		cap->data = ret;
> +	}
> +
> +	/* Get the preferred power role for a DRP */
> +	if (cap->type == TYPEC_PORT_DRP) {
> +		cap->prefer_role = TYPEC_NO_PREFERRED_ROLE;
> +
> +		ret = fwnode_property_read_string(fwnode, "try-power-role", &cap_str);
> +		if (ret == 0) {
> +			ret = typec_find_power_role(cap_str);
> +			if (ret < 0)
> +				return ret;
> +			cap->prefer_role = ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(typec_get_fw_cap);

thanks,

-- 
heikki

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ