diff
+struct hub_ref {
+	struct usb_hub *hub;
+	bool acquired;
+};
+
+static int hub_ref_get(struct hub_ref *href)
+{
+	if (!href->hub)
+		return -ENODEV;
+	hub_get(href->hub);
+	href->acquired = true;
+	return 0;
+}
+
+static void hub_ref_put(struct hub_ref *href)
+{
+	if (href->acquired) {
+		hub_put(href->hub);
+		href->acquired = false;
+	}
+}
+
 static ssize_t disable_show(struct device *dev,
 			      struct device_attribute *attr, char *buf)
 {
+	struct hub_ref href = {0};
     // ... (existing code) ...
-	hub_get(hub);
+	href.hub = hub;
+	if (hub_ref_get(&href) < 0)
+		return -ENODEV;
     // ... (existing code) ...
- out_hdev_lock:
-	usb_unlock_device(hdev);
+ out:
+	if (hdev)
+		usb_unlock_device(hdev);
+	if (kn)
+		sysfs_unbreak_active_protection(kn);
+	if (intf)
+		usb_autopm_put_interface(intf);
+	hub_ref_put(&href);
+	return rc;
 }
