aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2006-07-22 20:26:30 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-07-29 16:22:37 -0400
commit08d41808362a3663c0856c9720ad940a61156fb5 (patch)
treeec0da5edd1cb3351b0dd253baad83aac7f9958a3
parentd94fc9a08e51432d0d5fc0f74a4f705d7b49c251 (diff)
V4L/DVB (4373): Correctly handle sysfs error leg file removal in pvrusb2
Take note of which sysfs files / groups that the pvrusb2 successfully creates and only delete those specific items when tearing things down. (Previously we just blindly tore everything down every time.) Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c62
1 files changed, 50 insertions, 12 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index ef46d4f40cff..d1dda5caf406 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -44,12 +44,16 @@ struct pvr2_sysfs {
44 struct kobj_type ktype; 44 struct kobj_type ktype;
45 struct class_device_attribute attr_v4l_minor_number; 45 struct class_device_attribute attr_v4l_minor_number;
46 struct class_device_attribute attr_unit_number; 46 struct class_device_attribute attr_unit_number;
47 int v4l_minor_number_created_ok;
48 int unit_number_created_ok;
47}; 49};
48 50
49#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 51#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
50struct pvr2_sysfs_debugifc { 52struct pvr2_sysfs_debugifc {
51 struct class_device_attribute attr_debugcmd; 53 struct class_device_attribute attr_debugcmd;
52 struct class_device_attribute attr_debuginfo; 54 struct class_device_attribute attr_debuginfo;
55 int debugcmd_created_ok;
56 int debuginfo_created_ok;
53}; 57};
54#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ 58#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
55 59
@@ -67,6 +71,7 @@ struct pvr2_sysfs_ctl_item {
67 struct pvr2_sysfs_ctl_item *item_next; 71 struct pvr2_sysfs_ctl_item *item_next;
68 struct attribute *attr_gen[7]; 72 struct attribute *attr_gen[7];
69 struct attribute_group grp; 73 struct attribute_group grp;
74 int created_ok;
70 char name[80]; 75 char name[80];
71}; 76};
72 77
@@ -487,6 +492,7 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
487 struct pvr2_sysfs_func_set *fp; 492 struct pvr2_sysfs_func_set *fp;
488 struct pvr2_ctrl *cptr; 493 struct pvr2_ctrl *cptr;
489 unsigned int cnt,acnt; 494 unsigned int cnt,acnt;
495 int ret;
490 496
491 if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) { 497 if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) {
492 return; 498 return;
@@ -589,7 +595,13 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
589 cip->grp.name = cip->name; 595 cip->grp.name = cip->name;
590 cip->grp.attrs = cip->attr_gen; 596 cip->grp.attrs = cip->attr_gen;
591 597
592 sysfs_create_group(&sfp->class_dev->kobj,&cip->grp); 598 ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
599 if (ret) {
600 printk(KERN_WARNING "%s: sysfs_create_group error: %d\n",
601 __FUNCTION__, ret);
602 return;
603 }
604 cip->created_ok = !0;
593} 605}
594 606
595#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 607#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
@@ -616,22 +628,33 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
616 dip->attr_debuginfo.show = debuginfo_show; 628 dip->attr_debuginfo.show = debuginfo_show;
617 sfp->debugifc = dip; 629 sfp->debugifc = dip;
618 ret = class_device_create_file(sfp->class_dev,&dip->attr_debugcmd); 630 ret = class_device_create_file(sfp->class_dev,&dip->attr_debugcmd);
619 if (ret < 0) 631 if (ret < 0) {
620 printk(KERN_WARNING "%s: class_device_create_file error: %d\n", 632 printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
621 __FUNCTION__, ret); 633 __FUNCTION__, ret);
634 } else {
635 dip->debugcmd_created_ok = !0;
636 }
622 ret = class_device_create_file(sfp->class_dev,&dip->attr_debuginfo); 637 ret = class_device_create_file(sfp->class_dev,&dip->attr_debuginfo);
623 if (ret < 0) 638 if (ret < 0) {
624 printk(KERN_WARNING "%s: class_device_create_file error: %d\n", 639 printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
625 __FUNCTION__, ret); 640 __FUNCTION__, ret);
641 } else {
642 dip->debuginfo_created_ok = !0;
643 }
626} 644}
627 645
628 646
629static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp) 647static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
630{ 648{
631 if (!sfp->debugifc) return; 649 if (!sfp->debugifc) return;
632 class_device_remove_file(sfp->class_dev, 650 if (sfp->debugifc->debuginfo_created_ok) {
633 &sfp->debugifc->attr_debuginfo); 651 class_device_remove_file(sfp->class_dev,
634 class_device_remove_file(sfp->class_dev,&sfp->debugifc->attr_debugcmd); 652 &sfp->debugifc->attr_debuginfo);
653 }
654 if (sfp->debugifc->debugcmd_created_ok) {
655 class_device_remove_file(sfp->class_dev,
656 &sfp->debugifc->attr_debugcmd);
657 }
635 kfree(sfp->debugifc); 658 kfree(sfp->debugifc);
636 sfp->debugifc = NULL; 659 sfp->debugifc = NULL;
637} 660}
@@ -653,7 +676,9 @@ static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp)
653 struct pvr2_sysfs_ctl_item *cip1,*cip2; 676 struct pvr2_sysfs_ctl_item *cip1,*cip2;
654 for (cip1 = sfp->item_first; cip1; cip1 = cip2) { 677 for (cip1 = sfp->item_first; cip1; cip1 = cip2) {
655 cip2 = cip1->item_next; 678 cip2 = cip1->item_next;
656 sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp); 679 if (cip1->created_ok) {
680 sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp);
681 }
657 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1); 682 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1);
658 kfree(cip1); 683 kfree(cip1);
659 } 684 }
@@ -683,8 +708,14 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp)
683 pvr2_sysfs_tear_down_debugifc(sfp); 708 pvr2_sysfs_tear_down_debugifc(sfp);
684#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ 709#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
685 pvr2_sysfs_tear_down_controls(sfp); 710 pvr2_sysfs_tear_down_controls(sfp);
686 class_device_remove_file(sfp->class_dev,&sfp->attr_v4l_minor_number); 711 if (sfp->v4l_minor_number_created_ok) {
687 class_device_remove_file(sfp->class_dev,&sfp->attr_unit_number); 712 class_device_remove_file(sfp->class_dev,
713 &sfp->attr_v4l_minor_number);
714 }
715 if (sfp->unit_number_created_ok) {
716 class_device_remove_file(sfp->class_dev,
717 &sfp->attr_unit_number);
718 }
688 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); 719 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
689 sfp->class_dev->class_data = NULL; 720 sfp->class_dev->class_data = NULL;
690 class_device_unregister(sfp->class_dev); 721 class_device_unregister(sfp->class_dev);
@@ -756,10 +787,14 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
756 sfp->attr_v4l_minor_number.attr.mode = S_IRUGO; 787 sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
757 sfp->attr_v4l_minor_number.show = v4l_minor_number_show; 788 sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
758 sfp->attr_v4l_minor_number.store = NULL; 789 sfp->attr_v4l_minor_number.store = NULL;
759 ret = class_device_create_file(sfp->class_dev,&sfp->attr_v4l_minor_number); 790 ret = class_device_create_file(sfp->class_dev,
760 if (ret < 0) 791 &sfp->attr_v4l_minor_number);
792 if (ret < 0) {
761 printk(KERN_WARNING "%s: class_device_create_file error: %d\n", 793 printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
762 __FUNCTION__, ret); 794 __FUNCTION__, ret);
795 } else {
796 sfp->v4l_minor_number_created_ok = !0;
797 }
763 798
764 sfp->attr_unit_number.attr.owner = THIS_MODULE; 799 sfp->attr_unit_number.attr.owner = THIS_MODULE;
765 sfp->attr_unit_number.attr.name = "unit_number"; 800 sfp->attr_unit_number.attr.name = "unit_number";
@@ -767,9 +802,12 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
767 sfp->attr_unit_number.show = unit_number_show; 802 sfp->attr_unit_number.show = unit_number_show;
768 sfp->attr_unit_number.store = NULL; 803 sfp->attr_unit_number.store = NULL;
769 ret = class_device_create_file(sfp->class_dev,&sfp->attr_unit_number); 804 ret = class_device_create_file(sfp->class_dev,&sfp->attr_unit_number);
770 if (ret < 0) 805 if (ret < 0) {
771 printk(KERN_WARNING "%s: class_device_create_file error: %d\n", 806 printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
772 __FUNCTION__, ret); 807 __FUNCTION__, ret);
808 } else {
809 sfp->unit_number_created_ok = !0;
810 }
773 811
774 pvr2_sysfs_add_controls(sfp); 812 pvr2_sysfs_add_controls(sfp);
775#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 813#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC