Skip to content

Commit b787a3e

Browse files
Xu Yanggregkh
authored andcommitted
usb: roles: don't get/set_role() when usb_role_switch is unregistered
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: fde0aa6 ("usb: common: Small class for USB role switches") cc: stable@vger.kernel.org Signed-off-by: Xu Yang <xu.yang_2@nxp.com> Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Link: https://lore.kernel.org/r/20240129093739.2371530-2-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 1c9be13 commit b787a3e

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

drivers/usb/roles/class.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct usb_role_switch {
2323
struct mutex lock; /* device lock*/
2424
struct module *module; /* the module this device depends on */
2525
enum usb_role role;
26+
bool registered;
2627

2728
/* From descriptor */
2829
struct device *usb2_port;
@@ -49,6 +50,9 @@ int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role)
4950
if (IS_ERR_OR_NULL(sw))
5051
return 0;
5152

53+
if (!sw->registered)
54+
return -EOPNOTSUPP;
55+
5256
mutex_lock(&sw->lock);
5357

5458
ret = sw->set(sw, role);
@@ -74,7 +78,7 @@ enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw)
7478
{
7579
enum usb_role role;
7680

77-
if (IS_ERR_OR_NULL(sw))
81+
if (IS_ERR_OR_NULL(sw) || !sw->registered)
7882
return USB_ROLE_NONE;
7983

8084
mutex_lock(&sw->lock);
@@ -357,6 +361,8 @@ usb_role_switch_register(struct device *parent,
357361
return ERR_PTR(ret);
358362
}
359363

364+
sw->registered = true;
365+
360366
/* TODO: Symlinks for the host port and the device controller. */
361367

362368
return sw;
@@ -371,8 +377,10 @@ EXPORT_SYMBOL_GPL(usb_role_switch_register);
371377
*/
372378
void usb_role_switch_unregister(struct usb_role_switch *sw)
373379
{
374-
if (!IS_ERR_OR_NULL(sw))
380+
if (!IS_ERR_OR_NULL(sw)) {
381+
sw->registered = false;
375382
device_unregister(&sw->dev);
383+
}
376384
}
377385
EXPORT_SYMBOL_GPL(usb_role_switch_unregister);
378386

0 commit comments

Comments
 (0)