diff options
author | Mike Isely <isely@pobox.com> | 2010-05-14 23:23:46 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-06-01 00:19:54 -0400 |
commit | 28c4a5e6d32410f7c0b8fa9cc52eac424229f10a (patch) | |
tree | b52fa6a524d75571ea22c4e4e276df1044d78600 /drivers/media/video/pvrusb2 | |
parent | d72baad3f0e59041d68db7524537046e3a4121a2 (diff) |
V4L/DVB: pvrusb2: Fix USB parent device reference count
pvrusb2: Correctly reference count pointer to parent USB device when linked
from sysfs interface. This is technically a pretty nasty problem,
however as far as I know nobody had been getting burned by it (yet).
Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/pvrusb2')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 71f50565f637..bf478510a3b1 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | |||
@@ -511,6 +511,7 @@ static void pvr2_sysfs_release(struct device *class_dev) | |||
511 | 511 | ||
512 | static void class_dev_destroy(struct pvr2_sysfs *sfp) | 512 | static void class_dev_destroy(struct pvr2_sysfs *sfp) |
513 | { | 513 | { |
514 | struct device *dev; | ||
514 | if (!sfp->class_dev) return; | 515 | if (!sfp->class_dev) return; |
515 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC | 516 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC |
516 | pvr2_sysfs_tear_down_debugifc(sfp); | 517 | pvr2_sysfs_tear_down_debugifc(sfp); |
@@ -542,6 +543,9 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp) | |||
542 | } | 543 | } |
543 | pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); | 544 | pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); |
544 | dev_set_drvdata(sfp->class_dev, NULL); | 545 | dev_set_drvdata(sfp->class_dev, NULL); |
546 | dev = sfp->class_dev->parent; | ||
547 | sfp->class_dev->parent = NULL; | ||
548 | put_device(dev); | ||
545 | device_unregister(sfp->class_dev); | 549 | device_unregister(sfp->class_dev); |
546 | sfp->class_dev = NULL; | 550 | sfp->class_dev = NULL; |
547 | } | 551 | } |
@@ -631,10 +635,11 @@ static void class_dev_create(struct pvr2_sysfs *sfp, | |||
631 | pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); | 635 | pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); |
632 | 636 | ||
633 | class_dev->class = &class_ptr->class; | 637 | class_dev->class = &class_ptr->class; |
638 | |||
634 | dev_set_name(class_dev, "%s", | 639 | dev_set_name(class_dev, "%s", |
635 | pvr2_hdw_get_device_identifier(sfp->channel.hdw)); | 640 | pvr2_hdw_get_device_identifier(sfp->channel.hdw)); |
636 | 641 | ||
637 | class_dev->parent = &usb_dev->dev; | 642 | class_dev->parent = get_device(&usb_dev->dev); |
638 | 643 | ||
639 | sfp->class_dev = class_dev; | 644 | sfp->class_dev = class_dev; |
640 | dev_set_drvdata(class_dev, sfp); | 645 | dev_set_drvdata(class_dev, sfp); |
@@ -775,7 +780,8 @@ struct pvr2_sysfs_class *pvr2_sysfs_class_create(void) | |||
775 | struct pvr2_sysfs_class *clp; | 780 | struct pvr2_sysfs_class *clp; |
776 | clp = kzalloc(sizeof(*clp),GFP_KERNEL); | 781 | clp = kzalloc(sizeof(*clp),GFP_KERNEL); |
777 | if (!clp) return clp; | 782 | if (!clp) return clp; |
778 | pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp); | 783 | pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p", |
784 | clp); | ||
779 | clp->class.name = "pvrusb2"; | 785 | clp->class.name = "pvrusb2"; |
780 | clp->class.class_release = pvr2_sysfs_class_release; | 786 | clp->class.class_release = pvr2_sysfs_class_release; |
781 | clp->class.dev_release = pvr2_sysfs_release; | 787 | clp->class.dev_release = pvr2_sysfs_release; |
@@ -791,6 +797,7 @@ struct pvr2_sysfs_class *pvr2_sysfs_class_create(void) | |||
791 | 797 | ||
792 | void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp) | 798 | void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp) |
793 | { | 799 | { |
800 | pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp); | ||
794 | class_unregister(&clp->class); | 801 | class_unregister(&clp->class); |
795 | } | 802 | } |
796 | 803 | ||