On Mon, Jan 29, 2024 at 05:37:39PM +0800, Xu Yang wrote: > There is a possibility that usb_role_switch device is unregistered before > the user put usb_role_switch. In this case, the user may still want to > get/set_role() since the user can't sense the changes of usb_role_switch. > > This will add a flag to show if usb_role_switch is already registered and > avoid unwanted behaviors. > > Fixes: fde0aa6c175a ("usb: common: Small class for USB role switches") > cc: <stable@xxxxxxxxxxxxxxx> > Signed-off-by: Xu Yang <xu.yang_2@xxxxxxx> Acked-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx> > --- > Changes in v2: > - new patch during test patch 1 > - add registered flag > Changes in v3: > - add fix tag and stable list > --- > drivers/usb/roles/class.c | 12 ++++++++++-- > 1 file changed, 10 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c > index 2bad038fb9ad..70165dd86b5d 100644 > --- a/drivers/usb/roles/class.c > +++ b/drivers/usb/roles/class.c > @@ -23,6 +23,7 @@ struct usb_role_switch { > struct mutex lock; /* device lock*/ > struct module *module; /* the module this device depends on */ > enum usb_role role; > + bool registered; > > /* From descriptor */ > struct device *usb2_port; > @@ -49,6 +50,9 @@ int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role) > if (IS_ERR_OR_NULL(sw)) > return 0; > > + if (!sw->registered) > + return -EOPNOTSUPP; > + > mutex_lock(&sw->lock); > > ret = sw->set(sw, role); > @@ -74,7 +78,7 @@ enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw) > { > enum usb_role role; > > - if (IS_ERR_OR_NULL(sw)) > + if (IS_ERR_OR_NULL(sw) || !sw->registered) > return USB_ROLE_NONE; > > mutex_lock(&sw->lock); > @@ -357,6 +361,8 @@ usb_role_switch_register(struct device *parent, > return ERR_PTR(ret); > } > > + sw->registered = true; > + > /* TODO: Symlinks for the host port and the device controller. */ > > return sw; > @@ -371,8 +377,10 @@ EXPORT_SYMBOL_GPL(usb_role_switch_register); > */ > void usb_role_switch_unregister(struct usb_role_switch *sw) > { > - if (!IS_ERR_OR_NULL(sw)) > + if (!IS_ERR_OR_NULL(sw)) { > + sw->registered = false; > device_unregister(&sw->dev); > + } > } > EXPORT_SYMBOL_GPL(usb_role_switch_unregister); > > -- > 2.34.1 -- heikki