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]
Date:   Wed, 11 Dec 2019 16:50:31 +0100
From:   Paul Cercueil <paul@...pouillou.net>
To:     Sebastian Reichel <sre@...nel.org>,
        Rob Herring <robh+dt@...nel.org>,
        Mark Rutland <mark.rutland@....com>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc:     od@...c.me, linux-pm@...r.kernel.org, devicetree@...r.kernel.org,
        linux-kernel@...r.kernel.org, linux-usb@...r.kernel.org,
        Paul Cercueil <paul@...pouillou.net>
Subject: [PATCH v2 2/3] usb: roles: Add API to register notifiers

Add usb_role_switch_notifier_register() and
usb_role_switch_notifier_unregister().

The registered notifiers will be called when the USB role is changed.

Signed-off-by: Paul Cercueil <paul@...pouillou.net>
---

Notes:
    v2: New patch

 drivers/usb/roles/class.c | 24 +++++++++++++++++++++++-
 include/linux/usb/role.h  | 20 ++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c
index 8273126ffdf4..9b122b504b98 100644
--- a/drivers/usb/roles/class.c
+++ b/drivers/usb/roles/class.c
@@ -10,6 +10,7 @@
 #include <linux/usb/role.h>
 #include <linux/property.h>
 #include <linux/device.h>
+#include <linux/notifier.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
@@ -19,6 +20,7 @@ static struct class *role_class;
 struct usb_role_switch {
 	struct device dev;
 	struct mutex lock; /* device lock*/
+	struct blocking_notifier_head notifier_chain;
 	enum usb_role role;
 
 	/* From descriptor */
@@ -49,8 +51,11 @@ int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role)
 	mutex_lock(&sw->lock);
 
 	ret = sw->set(sw->dev.parent, role);
-	if (!ret)
+	if (!ret) {
 		sw->role = role;
+		ret = blocking_notifier_call_chain(&sw->notifier_chain,
+						   (long)role, sw);
+	}
 
 	mutex_unlock(&sw->lock);
 
@@ -85,6 +90,22 @@ enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw)
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_get_role);
 
+int
+usb_role_switch_register_notifier(struct usb_role_switch *sw,
+				  struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&sw->notifier_chain, nb);
+}
+EXPORT_SYMBOL_GPL(usb_role_switch_register_notifier);
+
+int
+usb_role_switch_unregister_notifier(struct usb_role_switch *sw,
+				    struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&sw->notifier_chain, nb);
+}
+EXPORT_SYMBOL_GPL(usb_role_switch_unregister_notifier);
+
 static void *usb_role_switch_match(struct device_connection *con, int ep,
 				   void *data)
 {
@@ -317,6 +338,7 @@ usb_role_switch_register(struct device *parent,
 		return ERR_PTR(-ENOMEM);
 
 	mutex_init(&sw->lock);
+	BLOCKING_INIT_NOTIFIER_HEAD(&sw->notifier_chain);
 
 	sw->allow_userspace_control = desc->allow_userspace_control;
 	sw->usb2_port = desc->usb2_port;
diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h
index efac3af83d6b..5f67d42cd28d 100644
--- a/include/linux/usb/role.h
+++ b/include/linux/usb/role.h
@@ -6,6 +6,7 @@
 #include <linux/device.h>
 
 struct usb_role_switch;
+struct notifier_block;
 
 enum usb_role {
 	USB_ROLE_NONE,
@@ -50,6 +51,11 @@ struct usb_role_switch *usb_role_switch_get(struct device *dev);
 struct usb_role_switch *fwnode_usb_role_switch_get(struct fwnode_handle *node);
 void usb_role_switch_put(struct usb_role_switch *sw);
 
+int usb_role_switch_register_notifier(struct usb_role_switch *sw,
+				      struct notifier_block *nb);
+int usb_role_switch_unregister_notifier(struct usb_role_switch *sw,
+					struct notifier_block *nb);
+
 struct usb_role_switch *
 usb_role_switch_find_by_fwnode(const struct fwnode_handle *fwnode);
 
@@ -82,6 +88,20 @@ fwnode_usb_role_switch_get(struct fwnode_handle *node)
 
 static inline void usb_role_switch_put(struct usb_role_switch *sw) { }
 
+static inline int
+usb_role_switch_register_notifier(struct usb_role_switch *sw,
+				  struct notifier_block *nb)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline int
+usb_role_switch_unregister_notifier(struct usb_role_switch *sw,
+				    struct notifier_block *nb)
+{
+	return ERR_PTR(-ENODEV);
+}
+
 static inline struct usb_role_switch *
 usb_role_switch_register(struct device *parent,
 			 const struct usb_role_switch_desc *desc)
-- 
2.24.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ