diff options
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-sysfs.c')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 85 |
1 files changed, 73 insertions, 12 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 6af55a8b6f05..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 { 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 @@ -600,6 +612,8 @@ static ssize_t debugcmd_store(struct class_device *,const char *,size_t count); static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) { struct pvr2_sysfs_debugifc *dip; + int ret; + dip = kmalloc(sizeof(*dip),GFP_KERNEL); if (!dip) return; memset(dip,0,sizeof(*dip)); @@ -613,17 +627,34 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) dip->attr_debuginfo.attr.mode = S_IRUGO; dip->attr_debuginfo.show = debuginfo_show; sfp->debugifc = dip; - class_device_create_file(sfp->class_dev,&dip->attr_debugcmd); - class_device_create_file(sfp->class_dev,&dip->attr_debuginfo); + ret = class_device_create_file(sfp->class_dev,&dip->attr_debugcmd); + 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) { + 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; - 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->debuginfo_created_ok) { + class_device_remove_file(sfp->class_dev, + &sfp->debugifc->attr_debuginfo); + } + if (sfp->debugifc->debugcmd_created_ok) { + class_device_remove_file(sfp->class_dev, + &sfp->debugifc->attr_debugcmd); + } kfree(sfp->debugifc); sfp->debugifc = NULL; } @@ -645,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; - sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp); + 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); } @@ -675,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); @@ -709,6 +748,8 @@ static void class_dev_create(struct pvr2_sysfs *sfp, { struct usb_device *usb_dev; struct class_device *class_dev; + int ret; + usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw); if (!usb_dev) return; class_dev = kmalloc(sizeof(*class_dev),GFP_KERNEL); @@ -733,20 +774,40 @@ static void class_dev_create(struct pvr2_sysfs *sfp, sfp->class_dev = class_dev; class_dev->class_data = sfp; - class_device_register(class_dev); + ret = class_device_register(class_dev); + if (ret) { + printk(KERN_ERR "%s: class_device_register failed\n", + __FUNCTION__); + kfree(class_dev); + return; + } sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE; sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number"; 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; - class_device_create_file(sfp->class_dev,&sfp->attr_v4l_minor_number); + 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"; sfp->attr_unit_number.attr.mode = S_IRUGO; sfp->attr_unit_number.show = unit_number_show; sfp->attr_unit_number.store = NULL; - class_device_create_file(sfp->class_dev,&sfp->attr_unit_number); + ret = class_device_create_file(sfp->class_dev,&sfp->attr_unit_number); + 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 |