Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08d41808 authored by Mike Isely's avatar Mike Isely Committed by Mauro Carvalho Chehab
Browse files

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: default avatarMike Isely <isely@pobox.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent d94fc9a0
Loading
Loading
Loading
Loading
+50 −12
Original line number Diff line number Diff line
@@ -44,12 +44,16 @@ struct pvr2_sysfs {
	struct kobj_type ktype;
	struct class_device_attribute attr_v4l_minor_number;
	struct class_device_attribute attr_unit_number;
	int v4l_minor_number_created_ok;
	int unit_number_created_ok;
};

#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
struct pvr2_sysfs_debugifc {
	struct class_device_attribute attr_debugcmd;
	struct class_device_attribute attr_debuginfo;
	int debugcmd_created_ok;
	int debuginfo_created_ok;
};
#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */

@@ -67,6 +71,7 @@ struct pvr2_sysfs_ctl_item {
	struct pvr2_sysfs_ctl_item *item_next;
	struct attribute *attr_gen[7];
	struct attribute_group grp;
	int created_ok;
	char name[80];
};

@@ -487,6 +492,7 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
	struct pvr2_sysfs_func_set *fp;
	struct pvr2_ctrl *cptr;
	unsigned int cnt,acnt;
	int ret;

	if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) {
		return;
@@ -589,7 +595,13 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
	cip->grp.name = cip->name;
	cip->grp.attrs = cip->attr_gen;

	sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
	ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
	if (ret) {
		printk(KERN_WARNING "%s: sysfs_create_group error: %d\n",
		       __FUNCTION__, ret);
		return;
	}
	cip->created_ok = !0;
}

#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
@@ -616,22 +628,33 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
	dip->attr_debuginfo.show = debuginfo_show;
	sfp->debugifc = dip;
	ret = class_device_create_file(sfp->class_dev,&dip->attr_debugcmd);
	if (ret < 0)
	if (ret < 0) {
		printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
		       __FUNCTION__, ret);
	} else {
		dip->debugcmd_created_ok = !0;
	}
	ret = class_device_create_file(sfp->class_dev,&dip->attr_debuginfo);
	if (ret < 0)
	if (ret < 0) {
		printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
		       __FUNCTION__, ret);
	} else {
		dip->debuginfo_created_ok = !0;
	}
}


static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
{
	if (!sfp->debugifc) return;
	if (sfp->debugifc->debuginfo_created_ok) {
		class_device_remove_file(sfp->class_dev,
					 &sfp->debugifc->attr_debuginfo);
	class_device_remove_file(sfp->class_dev,&sfp->debugifc->attr_debugcmd);
	}
	if (sfp->debugifc->debugcmd_created_ok) {
		class_device_remove_file(sfp->class_dev,
					 &sfp->debugifc->attr_debugcmd);
	}
	kfree(sfp->debugifc);
	sfp->debugifc = NULL;
}
@@ -653,7 +676,9 @@ static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp)
	struct pvr2_sysfs_ctl_item *cip1,*cip2;
	for (cip1 = sfp->item_first; cip1; cip1 = cip2) {
		cip2 = cip1->item_next;
		if (cip1->created_ok) {
			sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp);
		}
		pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1);
		kfree(cip1);
	}
@@ -683,8 +708,14 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp)
	pvr2_sysfs_tear_down_debugifc(sfp);
#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
	pvr2_sysfs_tear_down_controls(sfp);
	class_device_remove_file(sfp->class_dev,&sfp->attr_v4l_minor_number);
	class_device_remove_file(sfp->class_dev,&sfp->attr_unit_number);
	if (sfp->v4l_minor_number_created_ok) {
		class_device_remove_file(sfp->class_dev,
					 &sfp->attr_v4l_minor_number);
	}
	if (sfp->unit_number_created_ok) {
		class_device_remove_file(sfp->class_dev,
					 &sfp->attr_unit_number);
	}
	pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
	sfp->class_dev->class_data = NULL;
	class_device_unregister(sfp->class_dev);
@@ -756,10 +787,14 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
	sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
	sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
	sfp->attr_v4l_minor_number.store = NULL;
	ret = class_device_create_file(sfp->class_dev,&sfp->attr_v4l_minor_number);
	if (ret < 0)
	ret = class_device_create_file(sfp->class_dev,
				       &sfp->attr_v4l_minor_number);
	if (ret < 0) {
		printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
		       __FUNCTION__, ret);
	} else {
		sfp->v4l_minor_number_created_ok = !0;
	}

	sfp->attr_unit_number.attr.owner = THIS_MODULE;
	sfp->attr_unit_number.attr.name = "unit_number";
@@ -767,9 +802,12 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
	sfp->attr_unit_number.show = unit_number_show;
	sfp->attr_unit_number.store = NULL;
	ret = class_device_create_file(sfp->class_dev,&sfp->attr_unit_number);
	if (ret < 0)
	if (ret < 0) {
		printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
		       __FUNCTION__, ret);
	} else {
		sfp->unit_number_created_ok = !0;
	}

	pvr2_sysfs_add_controls(sfp);
#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC