[media] V4L: fix incorrect refcounting

Both radio-keene and dsbr100 did one v4l2_device_get too many. Thus the refcount
never became 0 and that causes a memory leak.

Also updated the V4L2 framework documentation accordingly.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Hans Verkuil 2012-04-19 12:27:56 -03:00 committed by Mauro Carvalho Chehab
parent aa6d5f2953
commit ee71e7b3ae
3 changed files with 9 additions and 7 deletions

View File

@ -182,11 +182,11 @@ static int __devinit drv_probe(struct pci_dev *pdev,
} }
If you have multiple device nodes then it can be difficult to know when it is If you have multiple device nodes then it can be difficult to know when it is
safe to unregister v4l2_device. For this purpose v4l2_device has refcounting safe to unregister v4l2_device for hotpluggable devices. For this purpose
support. The refcount is increased whenever video_register_device is called and v4l2_device has refcounting support. The refcount is increased whenever
it is decreased whenever that device node is released. When the refcount reaches video_register_device is called and it is decreased whenever that device node
zero, then the v4l2_device release() callback is called. You can do your final is released. When the refcount reaches zero, then the v4l2_device release()
cleanup there. callback is called. You can do your final cleanup there.
If other device nodes (e.g. ALSA) are created, then you can increase and If other device nodes (e.g. ALSA) are created, then you can increase and
decrease the refcount manually as well by calling: decrease the refcount manually as well by calling:
@ -197,6 +197,10 @@ or:
int v4l2_device_put(struct v4l2_device *v4l2_dev); int v4l2_device_put(struct v4l2_device *v4l2_dev);
Since the initial refcount is 1 you also need to call v4l2_device_put in the
disconnect() callback (for USB devices) or in the remove() callback (for e.g.
PCI devices), otherwise the refcount will never reach 0.
struct v4l2_subdev struct v4l2_subdev
------------------ ------------------

View File

@ -481,7 +481,6 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
{ {
struct dsbr100_device *radio = usb_get_intfdata(intf); struct dsbr100_device *radio = usb_get_intfdata(intf);
v4l2_device_get(&radio->v4l2_dev);
mutex_lock(&radio->v4l2_lock); mutex_lock(&radio->v4l2_lock);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
video_unregister_device(&radio->videodev); video_unregister_device(&radio->videodev);

View File

@ -148,7 +148,6 @@ static void usb_keene_disconnect(struct usb_interface *intf)
{ {
struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf)); struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf));
v4l2_device_get(&radio->v4l2_dev);
mutex_lock(&radio->lock); mutex_lock(&radio->lock);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
video_unregister_device(&radio->vdev); video_unregister_device(&radio->vdev);