When the topology of the nested hubs are over 6 layers Send uevent to user space when USB TOPO layer over 6. Let end user more understand what happened. Signed-off-by: Ricky Niu <rickyniu@xxxxxxxxxx> --- drivers/usb/core/hub.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 7f71218cc1e5..e5e924526822 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -55,6 +55,10 @@ static DEFINE_SPINLOCK(device_state_lock); static struct workqueue_struct *hub_wq; static void hub_event(struct work_struct *work); +/* struct to notify userspace of hub events */ +static struct class *hub_class; +static struct device *hub_device; + /* synchronize hub-port add/remove and peering operations */ DEFINE_MUTEX(usb_port_peer_mutex); @@ -1764,6 +1768,13 @@ static bool hub_descriptor_is_sane(struct usb_host_interface *desc) return true; } +static void hub_over_tier(void) +{ + char *envp[2] = { "HUB=OVERTIER", NULL }; + + kobject_uevent_env(&hub_device->kobj, KOBJ_CHANGE, envp); +} + static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_host_interface *desc; @@ -1831,6 +1842,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) if (hdev->level == MAX_TOPO_LEVEL) { dev_err(&intf->dev, "Unsupported bus topology: hub nested too deep\n"); + hub_over_tier(); return -E2BIG; } @@ -5680,6 +5692,13 @@ int usb_hub_init(void) return -1; } + hub_class = class_create(THIS_MODULE, "usb_hub"); + if (IS_ERR(hub_class)) + return PTR_ERR(hub_class); + + hub_device = + device_create(hub_class, NULL, MKDEV(0, 0), NULL, "usb_hub"); + /* * The workqueue needs to be freezable to avoid interfering with * USB-PERSIST port handover. Otherwise it might see that a full-speed @@ -5699,6 +5718,9 @@ int usb_hub_init(void) void usb_hub_cleanup(void) { + if (!IS_ERR(hub_class)) + class_destroy(hub_class); + destroy_workqueue(hub_wq); /* -- 2.30.1.766.gb4fecdf3b7-goog