Index: usb-devel/drivers/media/usb/usbvision/usbvision-video.c =================================================================== --- usb-devel.orig/drivers/media/usb/usbvision/usbvision-video.c +++ usb-devel/drivers/media/usb/usbvision/usbvision-video.c @@ -314,6 +314,10 @@ static int usbvision_v4l2_open(struct fi if (mutex_lock_interruptible(&usbvision->v4l2_lock)) return -ERESTARTSYS; + if (usbvision->remove_pending) { + err_code = -ENODEV; + goto unlock; + } if (usbvision->user) { err_code = -EBUSY; } else { @@ -377,6 +381,7 @@ unlock: static int usbvision_v4l2_close(struct file *file) { struct usb_usbvision *usbvision = video_drvdata(file); + int r; PDEBUG(DBG_IO, "close"); @@ -391,9 +396,10 @@ static int usbvision_v4l2_close(struct f usbvision_scratch_free(usbvision); usbvision->user--; + r = usbvision->remove_pending; mutex_unlock(&usbvision->v4l2_lock); - if (usbvision->remove_pending) { + if (r) { printk(KERN_INFO "%s: Final disconnect\n", __func__); usbvision_release(usbvision); return 0; @@ -453,6 +459,9 @@ static int vidioc_querycap(struct file * { struct usb_usbvision *usbvision = video_drvdata(file); + if (!usbvision->dev) + return -ENODEV; + strscpy(vc->driver, "USBVision", sizeof(vc->driver)); strscpy(vc->card, usbvision_device_data[usbvision->dev_model].model_string, @@ -1073,6 +1082,11 @@ static int usbvision_radio_open(struct f if (mutex_lock_interruptible(&usbvision->v4l2_lock)) return -ERESTARTSYS; + + if (usbvision->remove_pending) { + err_code = -ENODEV; + goto out; + } err_code = v4l2_fh_open(file); if (err_code) goto out; @@ -1105,21 +1119,24 @@ out: static int usbvision_radio_close(struct file *file) { struct usb_usbvision *usbvision = video_drvdata(file); + int r; PDEBUG(DBG_IO, ""); mutex_lock(&usbvision->v4l2_lock); /* Set packet size to 0 */ usbvision->iface_alt = 0; - usb_set_interface(usbvision->dev, usbvision->iface, + if (usbvision->dev) + usb_set_interface(usbvision->dev, usbvision->iface, usbvision->iface_alt); usbvision_audio_off(usbvision); usbvision->radio = 0; usbvision->user--; + r = usbvision->remove_pending; mutex_unlock(&usbvision->v4l2_lock); - if (usbvision->remove_pending) { + if (r) { printk(KERN_INFO "%s: Final disconnect\n", __func__); v4l2_fh_release(file); usbvision_release(usbvision); @@ -1236,7 +1253,9 @@ static void usbvision_unregister_video(s if (video_is_registered(&usbvision->rdev)) { PDEBUG(DBG_PROBE, "unregister %s [v4l2]", video_device_node_name(&usbvision->rdev)); + dev_info(&usbvision->rdev.dev, "Unregister\n"); video_unregister_device(&usbvision->rdev); + printk(KERN_INFO "Unregister done\n"); } /* Video Device: */ @@ -1551,6 +1570,7 @@ err_usb: static void usbvision_disconnect(struct usb_interface *intf) { struct usb_usbvision *usbvision = to_usbvision(usb_get_intfdata(intf)); + int u; PDEBUG(DBG_PROBE, ""); @@ -1567,13 +1587,14 @@ static void usbvision_disconnect(struct v4l2_device_disconnect(&usbvision->v4l2_dev); usbvision_i2c_unregister(usbvision); usbvision->remove_pending = 1; /* Now all ISO data will be ignored */ + u = usbvision->user; usb_put_dev(usbvision->dev); usbvision->dev = NULL; /* USB device is no more */ mutex_unlock(&usbvision->v4l2_lock); - if (usbvision->user) { + if (u) { printk(KERN_INFO "%s: In use, disconnect pending\n", __func__); wake_up_interruptible(&usbvision->wait_frame); Index: usb-devel/fs/sysfs/group.c =================================================================== --- usb-devel.orig/fs/sysfs/group.c +++ usb-devel/fs/sysfs/group.c @@ -125,6 +125,12 @@ static int internal_create_group(struct } kobject_get_ownership(kobj, &uid, &gid); if (grp->name) { + const char *kname = kobject_name(kobj); + + if (strcmp(grp->name, "power") == 0 && + strncmp(kname, "radio", 5) == 0) + pr_info("Adding '%s' to '%s'\n", grp->name, kname); + if (update) { kn = kernfs_find_and_get(kobj->sd, grp->name); if (!kn) { @@ -273,6 +279,12 @@ void sysfs_remove_group(struct kobject * struct kernfs_node *kn; if (grp->name) { + const char *kname = kobject_name(kobj); + + if (strcmp(grp->name, "power") == 0 && + strncmp(kname, "radio", 5) == 0) + pr_info("Removing '%s' from '%s'\n", grp->name, kname); + kn = kernfs_find_and_get(parent, grp->name); if (!kn) { WARN(!kn, KERN_WARNING Index: usb-devel/drivers/base/power/sysfs.c =================================================================== --- usb-devel.orig/drivers/base/power/sysfs.c +++ usb-devel/drivers/base/power/sysfs.c @@ -642,14 +642,18 @@ static const struct attribute_group pm_q int dpm_sysfs_add(struct device *dev) { int rc; + int m = !strncmp(dev_name(dev), "radio", 5); /* No need to create PM sysfs if explicitly disabled. */ if (device_pm_not_required(dev)) return 0; + if (m) dev_info(dev, "Registering 'power' group\n"); rc = sysfs_create_group(&dev->kobj, &pm_attr_group); - if (rc) + if (rc) { + if (m) dev_info(dev, "Registration failed\n"); return rc; + } if (pm_runtime_callbacks_present(dev)) { rc = sysfs_merge_group(&dev->kobj, &pm_runtime_attr_group); @@ -674,6 +678,7 @@ int dpm_sysfs_add(struct device *dev) err_runtime: sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group); err_out: + if (m) dev_info(dev, "Undo registration\n"); sysfs_remove_group(&dev->kobj, &pm_attr_group); return rc; }